From 36dd0b74c87c6353863ffad5ba7ed657ea1dadef Mon Sep 17 00:00:00 2001 From: wirano Date: Wed, 24 Jul 2024 16:31:36 +0800 Subject: [PATCH] add GD32H7xx library --- .../CMSIS/GD/GD32H7xx/Include/gd32h7xx.h | 406 ++ .../GD/GD32H7xx/Include/system_gd32h7xx.h | 50 + .../GD/GD32H7xx/Source/ARM/startup_gd32h7xx.s | 729 +++ .../GD/GD32H7xx/Source/GCC/startup_gd32h7xx.s | 517 +++ .../GD/GD32H7xx/Source/IAR/startup_gd32h7xx.s | 1158 +++++ .../GD/GD32H7xx/Source/system_gd32h7xx.c | 716 +++ .../CMSIS/LICENSE.TXT | 201 + .../CMSIS/cachel1_armv7.h | 441 ++ .../CMSIS/cmsis_armcc.h | 894 ++++ .../CMSIS/cmsis_armclang.h | 1510 ++++++ .../CMSIS/cmsis_armclang_ltm.h | 1934 ++++++++ .../CMSIS/cmsis_compiler.h | 303 ++ .../CMSIS/cmsis_gcc.h | 2217 +++++++++ .../CMSIS/cmsis_version.h | 39 + .../CMSIS/core_cm7.h | 2407 ++++++++++ .../CMSIS/mpu_armv7.h | 275 ++ .../Include/gd32h7xx_adc.h | 623 +++ .../Include/gd32h7xx_axiim.h | 226 + .../Include/gd32h7xx_can.h | 1278 ++++++ .../Include/gd32h7xx_cau.h | 322 ++ .../Include/gd32h7xx_cmp.h | 220 + .../Include/gd32h7xx_cpdm.h | 104 + .../Include/gd32h7xx_crc.h | 122 + .../Include/gd32h7xx_ctc.h | 184 + .../Include/gd32h7xx_dac.h | 321 ++ .../Include/gd32h7xx_dbg.h | 187 + .../Include/gd32h7xx_dci.h | 276 ++ .../Include/gd32h7xx_dma.h | 1015 +++++ .../Include/gd32h7xx_edout.h | 110 + .../Include/gd32h7xx_efuse.h | 259 ++ .../Include/gd32h7xx_enet.h | 1677 +++++++ .../Include/gd32h7xx_exmc.h | 638 +++ .../Include/gd32h7xx_exti.h | 413 ++ .../Include/gd32h7xx_fac.h | 268 ++ .../Include/gd32h7xx_fmc.h | 534 +++ .../Include/gd32h7xx_fwdgt.h | 117 + .../Include/gd32h7xx_gpio.h | 442 ++ .../Include/gd32h7xx_hau.h | 223 + .../Include/gd32h7xx_hpdf.h | 760 +++ .../Include/gd32h7xx_hwsem.h | 365 ++ .../Include/gd32h7xx_i2c.h | 408 ++ .../Include/gd32h7xx_ipa.h | 479 ++ .../Include/gd32h7xx_lpdts.h | 195 + .../Include/gd32h7xx_mdio.h | 236 + .../Include/gd32h7xx_mdma.h | 480 ++ .../Include/gd32h7xx_misc.h | 200 + .../Include/gd32h7xx_ospi.h | 802 ++++ .../Include/gd32h7xx_ospim.h | 125 + .../Include/gd32h7xx_pmu.h | 279 ++ .../Include/gd32h7xx_rameccmu.h | 181 + .../Include/gd32h7xx_rcu.h | 2097 +++++++++ .../Include/gd32h7xx_rspdif.h | 326 ++ .../Include/gd32h7xx_rtc.h | 729 +++ .../Include/gd32h7xx_rtdec.h | 166 + .../Include/gd32h7xx_sai.h | 541 +++ .../Include/gd32h7xx_sdio.h | 534 +++ .../Include/gd32h7xx_spi.h | 693 +++ .../Include/gd32h7xx_syscfg.h | 633 +++ .../Include/gd32h7xx_timer.h | 1265 +++++ .../Include/gd32h7xx_tli.h | 374 ++ .../Include/gd32h7xx_tmu.h | 177 + .../Include/gd32h7xx_trigsel.h | 338 ++ .../Include/gd32h7xx_trng.h | 218 + .../Include/gd32h7xx_usart.h | 683 +++ .../Include/gd32h7xx_vref.h | 90 + .../Include/gd32h7xx_wwdgt.h | 86 + .../Source/gd32h7xx_adc.c | 1300 ++++++ .../Source/gd32h7xx_can.c | 1910 ++++++++ .../Source/gd32h7xx_cau.c | 733 +++ .../Source/gd32h7xx_cau_aes.c | 917 ++++ .../Source/gd32h7xx_cau_des.c | 183 + .../Source/gd32h7xx_cau_tdes.c | 198 + .../Source/gd32h7xx_cmp.c | 577 +++ .../Source/gd32h7xx_cpdm.c | 246 + .../Source/gd32h7xx_crc.c | 247 + .../Source/gd32h7xx_ctc.c | 390 ++ .../Source/gd32h7xx_dac.c | 750 +++ .../Source/gd32h7xx_dbg.c | 168 + .../Source/gd32h7xx_dci.c | 448 ++ .../Source/gd32h7xx_dma.c | 1710 +++++++ .../Source/gd32h7xx_edout.c | 207 + .../Source/gd32h7xx_efuse.c | 514 +++ .../Source/gd32h7xx_enet.c | 3773 +++++++++++++++ .../Source/gd32h7xx_exmc.c | 942 ++++ .../Source/gd32h7xx_exti.c | 254 ++ .../Source/gd32h7xx_fac.c | 659 +++ .../Source/gd32h7xx_fmc.c | 1755 +++++++ .../Source/gd32h7xx_fwdgt.c | 250 + .../Source/gd32h7xx_gpio.c | 492 ++ .../Source/gd32h7xx_hau.c | 398 ++ .../Source/gd32h7xx_hau_sha_md5.c | 422 ++ .../Source/gd32h7xx_hpdf.c | 1722 +++++++ .../Source/gd32h7xx_hwsem.c | 286 ++ .../Source/gd32h7xx_i2c.c | 968 ++++ .../Source/gd32h7xx_ipa.c | 823 ++++ .../Source/gd32h7xx_lpdts.c | 332 ++ .../Source/gd32h7xx_mdio.c | 404 ++ .../Source/gd32h7xx_mdma.c | 1018 +++++ .../Source/gd32h7xx_misc.c | 257 ++ .../Source/gd32h7xx_ospi.c | 1641 +++++++ .../Source/gd32h7xx_ospim.c | 206 + .../Source/gd32h7xx_pmu.c | 583 +++ .../Source/gd32h7xx_rameccmu.c | 395 ++ .../Source/gd32h7xx_rcu.c | 2755 +++++++++++ .../Source/gd32h7xx_rspdif.c | 582 +++ .../Source/gd32h7xx_rtc.c | 1265 +++++ .../Source/gd32h7xx_rtdec.c | 384 ++ .../Source/gd32h7xx_sai.c | 792 ++++ .../Source/gd32h7xx_sdio.c | 1032 +++++ .../Source/gd32h7xx_spi.c | 1487 ++++++ .../Source/gd32h7xx_syscfg.c | 645 +++ .../Source/gd32h7xx_timer.c | 4055 +++++++++++++++++ .../Source/gd32h7xx_tli.c | 598 +++ .../Source/gd32h7xx_tmu.c | 236 + .../Source/gd32h7xx_trigsel.c | 513 +++ .../Source/gd32h7xx_trng.c | 426 ++ .../Source/gd32h7xx_usart.c | 1534 +++++++ .../Source/gd32h7xx_vref.c | 153 + .../Source/gd32h7xx_wwdgt.c | 131 + .../device/class/audio/Include/audio_core.h | 320 ++ .../class/audio/Include/audio_out_itf.h | 49 + .../device/class/audio/Source/audio_core.c | 959 ++++ .../device/class/audio/Source/audio_out_itf.c | 168 + .../device/class/cdc/Include/cdc_acm_core.h | 66 + .../device/class/cdc/Source/cdc_acm_core.c | 514 +++ .../device/class/dfu/Include/dfu_core.h | 176 + .../device/class/dfu/Include/dfu_mal.h | 83 + .../device/class/dfu/Source/dfu_core.c | 642 +++ .../device/class/dfu/Source/dfu_mal.c | 218 + .../class/hid/Include/custom_hid_core.h | 66 + .../class/hid/Include/standard_hid_core.h | 70 + .../class/hid/Include/std_hid_mouse_core.h | 71 + .../device/class/hid/Source/custom_hid_core.c | 463 ++ .../class/hid/Source/standard_hid_core.c | 488 ++ .../class/hid/Source/std_hid_mouse_core.c | 385 ++ .../device/class/iap/Include/usb_iap_core.h | 91 + .../device/class/iap/Source/usb_iap_core.c | 553 +++ .../device/class/msc/Include/usbd_msc_bbb.h | 102 + .../device/class/msc/Include/usbd_msc_core.h | 59 + .../device/class/msc/Include/usbd_msc_data.h | 49 + .../device/class/msc/Include/usbd_msc_efs.h | 57 + .../device/class/msc/Include/usbd_msc_mem.h | 59 + .../device/class/msc/Include/usbd_msc_scsi.h | 50 + .../device/class/msc/Source/usbd_msc_bbb.c | 286 ++ .../device/class/msc/Source/usbd_msc_core.c | 393 ++ .../device/class/msc/Source/usbd_msc_data.c | 73 + .../device/class/msc/Source/usbd_msc_efs.c | 92 + .../device/class/msc/Source/usbd_msc_scsi.c | 724 +++ .../class/printer/Include/printer_core.h | 78 + .../class/printer/Source/printer_core.c | 302 ++ .../device/core/Include/usbd_core.h | 103 + .../device/core/Include/usbd_enum.h | 105 + .../device/core/Include/usbd_transc.h | 56 + .../device/core/Source/usbd_core.c | 311 ++ .../device/core/Source/usbd_enum.c | 817 ++++ .../device/core/Source/usbd_transc.c | 270 ++ .../driver/Include/drv_usb_core.h | 355 ++ .../driver/Include/drv_usb_dev.h | 211 + .../driver/Include/drv_usb_host.h | 117 + .../driver/Include/drv_usb_hw.h | 65 + .../driver/Include/drv_usb_regs.h | 748 +++ .../driver/Include/drv_usbd_int.h | 52 + .../driver/Include/drv_usbh_int.h | 56 + .../driver/Source/drv_usb_core.c | 396 ++ .../driver/Source/drv_usb_dev.c | 697 +++ .../driver/Source/drv_usb_host.c | 451 ++ .../driver/Source/drv_usbd_int.c | 692 +++ .../driver/Source/drv_usbh_int.c | 617 +++ .../host/class/cdc/Include/usbh_cdc_core.h | 152 + .../host/class/cdc/Source/usbh_cdc_core.c | 647 +++ .../host/class/hid/Include/usbh_hid_core.h | 223 + .../host/class/hid/Include/usbh_hid_keybd.h | 304 ++ .../host/class/hid/Include/usbh_hid_mouse.h | 60 + .../host/class/hid/Include/usbh_hid_parser.h | 61 + .../host/class/hid/Include/usbh_hid_usage.h | 138 + .../host/class/hid/Source/usbh_hid_core.c | 675 +++ .../host/class/hid/Source/usbh_hid_keybd.c | 398 ++ .../host/class/hid/Source/usbh_hid_mouse.c | 217 + .../host/class/hid/Source/usbh_hid_parser.c | 148 + .../host/class/msc/Include/usbh_msc_bbb.h | 150 + .../host/class/msc/Include/usbh_msc_core.h | 124 + .../host/class/msc/Include/usbh_msc_scsi.h | 100 + .../host/class/msc/Source/usbh_msc_bbb.c | 355 ++ .../host/class/msc/Source/usbh_msc_core.c | 555 +++ .../host/class/msc/Source/usbh_msc_fatfs.c | 234 + .../host/class/msc/Source/usbh_msc_scsi.c | 399 ++ .../host/core/Include/usbh_core.h | 280 ++ .../host/core/Include/usbh_enum.h | 71 + .../host/core/Include/usbh_pipe.h | 99 + .../host/core/Include/usbh_transc.h | 51 + .../host/core/Source/usbh_core.c | 722 +++ .../host/core/Source/usbh_enum.c | 691 +++ .../host/core/Source/usbh_pipe.c | 183 + .../host/core/Source/usbh_transc.c | 371 ++ .../ustd/class/cdc/usb_cdc.h | 180 + .../ustd/class/hid/usb_hid.h | 83 + .../ustd/class/msc/msc_bbb.h | 69 + .../ustd/class/msc/msc_scsi.h | 117 + .../ustd/class/msc/usb_msc.h | 68 + .../ustd/common/usb_ch9_std.h | 243 + .../GD32H7xx_Firmware_Library/SConscript | 69 + bsp/gd32/arm/libraries/Kconfig | 5 + 202 files changed, 103549 insertions(+) create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/gd32h7xx.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/system_gd32h7xx.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/ARM/startup_gd32h7xx.s create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/GCC/startup_gd32h7xx.s create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/IAR/startup_gd32h7xx.s create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/system_gd32h7xx.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/LICENSE.TXT create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cachel1_armv7.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armcc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang_ltm.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_compiler.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_gcc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_version.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/core_cm7.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/mpu_armv7.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_adc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_axiim.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_can.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cau.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cmp.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cpdm.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_crc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ctc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dac.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dbg.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dci.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dma.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_edout.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_efuse.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_enet.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exmc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exti.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fac.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fmc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fwdgt.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_gpio.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hau.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hpdf.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hwsem.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_i2c.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ipa.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_lpdts.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdio.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdma.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_misc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospi.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospim.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_pmu.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rameccmu.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rcu.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rspdif.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtdec.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sai.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sdio.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_spi.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_syscfg.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_timer.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tli.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tmu.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trigsel.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trng.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_usart.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_vref.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_wwdgt.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_adc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_can.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_aes.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_des.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_tdes.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cmp.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cpdm.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_crc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ctc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dac.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dbg.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dci.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dma.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_edout.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_efuse.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_enet.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exmc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exti.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fac.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fmc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fwdgt.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_gpio.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau_sha_md5.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hpdf.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hwsem.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_i2c.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ipa.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_lpdts.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdio.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdma.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_misc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospi.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospim.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_pmu.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rameccmu.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rcu.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rspdif.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtdec.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sai.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sdio.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_spi.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_syscfg.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_timer.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tli.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tmu.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trigsel.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trng.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_usart.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_vref.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_wwdgt.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_out_itf.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_out_itf.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Include/cdc_acm_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Source/cdc_acm_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_mal.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_mal.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/custom_hid_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/standard_hid_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/std_hid_mouse_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/custom_hid_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/standard_hid_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/std_hid_mouse_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Include/usb_iap_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Source/usb_iap_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_bbb.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_data.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_efs.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_mem.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_scsi.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_bbb.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_data.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_efs.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_scsi.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Include/printer_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Source/printer_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_enum.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_transc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_enum.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_transc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_dev.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_host.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_hw.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_regs.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbd_int.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbh_int.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_dev.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_host.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbd_int.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbh_int.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Include/usbh_cdc_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Source/usbh_cdc_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_keybd.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_mouse.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_parser.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_usage.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_keybd.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_mouse.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_parser.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_bbb.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_scsi.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_bbb.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_fatfs.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_scsi.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_core.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_enum.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_pipe.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_transc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_core.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_enum.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_pipe.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_transc.c create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/cdc/usb_cdc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/hid/usb_hid.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_bbb.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_scsi.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/usb_msc.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/common/usb_ch9_std.h create mode 100644 bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/SConscript diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/gd32h7xx.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/gd32h7xx.h new file mode 100644 index 0000000000..2f68fadfbb --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/gd32h7xx.h @@ -0,0 +1,406 @@ +/*! + \file gd32h7xx.h + \brief general definitions for GD32H7xx + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * Copyright (c) 2024, GigaDevice Semiconductor Inc. + * + * 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. + */ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#ifndef GD32H7XX_H +#define GD32H7XX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined (GD32H7XX) +#error "Please select the target GD32H7XX device used in your application (in gd32h7xx.h file)" +#endif /* undefine GD32H7XX tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined (HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)25000000) +#endif /* high speed crystal oscillator value */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0FFFF) +#endif /* high speed crystal oscillator startup timeout */ + +/* define value of internal 64MHz RC oscillator (IRC64M) in Hz */ +#if !defined (IRC64M_VALUE) +#define IRC64M_VALUE ((uint32_t)64000000) +#endif /* internal 64MHz RC oscillator value */ + +/* define startup timeout value of internal 64MHz RC oscillator (IRC64M) */ +#if !defined (IRC64M_STARTUP_TIMEOUT) +#define IRC64M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 64MHz RC oscillator startup timeout */ + +/* define value of Low Power Internal 4Mhz RC oscillator (LPIRC4M) in Hz */ +#if !defined (LPIRC4M_VALUE) +#define LPIRC4M_VALUE ((uint32_t)4000000) +#endif /* Low Power Internal 4Mhz RC oscillator value */ + +/* define startup timeout value of internal Low Power Internal 4Mhz RC oscillator (LPIRC4M) */ +#if !defined (LPIRC4M_STARTUP_TIMEOUT) +#define LPIRC4M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* Low Power Internal 4Mhz RC oscillator startup timeout */ + +/* define value of internal 48MHz RC oscillator (IRC48M) in Hz */ +#if !defined (IRC48M_VALUE) +#define IRC48M_VALUE ((uint32_t)48000000) +#endif /* internal 48MHz RC oscillator value */ + +/* define startup timeout value of internal 48MHz RC oscillator (IRC48M) */ +#if !defined (IRC48M_STARTUP_TIMEOUT) +#define IRC48M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 48MHz RC oscillator startup timeout */ + +/* define value of internal 32KHz RC oscillator(IRC32K) in Hz */ +#if !defined (IRC32K_VALUE) +#define IRC32K_VALUE ((uint32_t)32000) +#endif /* internal 32KHz RC oscillator value */ + +/* define startup timeout value of internal 32KHz RC oscillator (IRC32K) */ +#if !defined (IRC32K_STARTUP_TIMEOUT) +#define IRC32K_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 32KHz RC oscillator startup timeout */ + +/* define value of low speed crystal oscillator (LXTAL)in Hz */ +#if !defined (LXTAL_VALUE) +#define LXTAL_VALUE ((uint32_t)32768) +#endif /* low speed crystal oscillator value */ + +/* define startup timeout value of low speed crystal oscillator (LXTAL) */ +#if !defined (LXTAL_STARTUP_TIMEOUT) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x0FFFFFFF) +#endif /* low speed crystal oscillator startup timeout */ + +/* GD32H7xx firmware library version number V1.0 */ +#define __GD32H7XX_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __GD32H7XX_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32H7XX_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32H7XX_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32H7XX_STDPERIPH_VERSION ((__GD32H7XX_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32H7XX_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32H7XX_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32H7XX_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M7 processor and core peripherals */ +#define __CM7_REV 0x0102U /*!< Cortex-M7 revision r1p2 */ +#define __MPU_PRESENT 1 /*!< CM7 provides an MPU */ +#define __NVIC_PRIO_BITS 4 /*!< CM7 uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /*!< FPU present */ +#define __ICACHE_PRESENT 1 /*!< CM7 instruction cache present */ +#define __DCACHE_PRESENT 1 /*!< CM7 data cache present */ + +/* define interrupt number */ +typedef enum IRQn { + /* Cortex-M7 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< non mask-able interrupt */ + HardFault_IRQn = -13, /*!< hard-fault interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M7 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M7 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M7 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M7 sv call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M7 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M7 pend sv interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M7 system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + AVD_LVD_OVD_IRQn = 1, /*!< AVD/LVD/OVD through EXTI line detect interrupt */ + TAMPER_STAMP_LXTAL_IRQn = 2, /*!< RTC tamper and timestamp interrupt/LXTAL clock stuck interrupt */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt */ + FMC_IRQn = 4, /*!< FMC interrupt */ + RCU_IRQn = 5, /*!< RCU interrupt */ + EXTI0_IRQn = 6, /*!< EXTI line 0 */ + EXTI1_IRQn = 7, /*!< EXTI line 1 */ + EXTI2_IRQn = 8, /*!< EXTI line 2 */ + EXTI3_IRQn = 9, /*!< EXTI line 3 */ + EXTI4_IRQn = 10, /*!< EXTI line 4 */ + DMA0_Channel0_IRQn = 11, /*!< DMA0 channel 0 interrupt */ + DMA0_Channel1_IRQn = 12, /*!< DMA0 channel 1 interrupt */ + DMA0_Channel2_IRQn = 13, /*!< DMA0 channel 2 interrupt */ + DMA0_Channel3_IRQn = 14, /*!< DMA0 channel 3 interrupt */ + DMA0_Channel4_IRQn = 15, /*!< DMA0 channel 4 interrupt */ + DMA0_Channel5_IRQn = 16, /*!< DMA0 channel 5 interrupt */ + DMA0_Channel6_IRQn = 17, /*!< DMA0 channel 6 interrupt */ + ADC0_1_IRQn = 18, /*!< ADC0 and ADC1 */ + EXTI5_9_IRQn = 23, /*!< EXTI line 5 to 9 */ + TIMER0_BRK_IRQn = 24, /*!< TIMER0 break interrupt */ + TIMER0_UP_IRQn = 25, /*!< TIMER0 update interrupt */ + TIMER0_TRG_CMT_IRQn = 26, /*!< TIMER0 trigger/commutation interrupt */ + TIMER0_Channel_IRQn = 27, /*!< TIMER0 capture/compare interrupt */ + TIMER1_IRQn = 28, /*!< TIMER1 interrupt */ + TIMER2_IRQn = 29, /*!< TIMER2 interrupt */ + TIMER3_IRQn = 30, /*!< TIMER3 interrupt */ + I2C0_EV_IRQn = 31, /*!< I2C0 event interrupt */ + I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ + I2C1_EV_IRQn = 33, /*!< I2C1 event interrupt */ + I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ + SPI0_IRQn = 35, /*!< SPI0 interrupt */ + SPI1_IRQn = 36, /*!< SPI1 interrupt */ + USART0_IRQn = 37, /*!< USART0 global and wakeup interrupt */ + USART1_IRQn = 38, /*!< USART1 global and wakeup interrupt */ + USART2_IRQn = 39, /*!< USART2 global and wakeup interrupt */ + EXTI10_15_IRQn = 40, /*!< EXTI line 10 to 15 */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm interrupt */ + TIMER7_BRK_IRQn = 43, /*!< TIMER7 Break global interrupt */ + TIMER7_UP_IRQn = 44, /*!< TIMER7 Update global interrupt */ + TIMER7_TRG_CMT_IRQn = 45, /*!< TIMER7 Trigger and Commutation global interrupt */ + TIMER7_Channel_IRQn = 46, /*!< TIMER7 Capture Compare interrupt */ + DMA0_Channel7_IRQn = 47, /*!< DMA0 channel 7 interrupt */ + EXMC_IRQn = 48, /*!< EXMC interrupt */ + SDIO0_IRQn = 49, /*!< SDMMC0 interrupt */ + TIMER4_IRQn = 50, /*!< TIMER4 interrupt */ + SPI2_IRQn = 51, /*!< SPI2 interrupt */ + UART3_IRQn = 52, /*!< UART3 interrupt */ + UART4_IRQn = 53, /*!< UART4 interrupt */ + TIMER5_DAC_UDR_IRQn = 54, /*!< TIMER5 global interrupt and DAC1/DAC0 underrun */ + TIMER6_IRQn = 55, /*!< TIMER6 interrupt */ + DMA1_Channel0_IRQn = 56, /*!< DMA1 channel0 interrupt */ + DMA1_Channel1_IRQn = 57, /*!< DMA1 channel1 interrupt */ + DMA1_Channel2_IRQn = 58, /*!< DMA1 channel2 interrupt */ + DMA1_Channel3_IRQn = 59, /*!< DMA1 channel3 interrupt */ + DMA1_Channel4_IRQn = 60, /*!< DMA1 channel4 interrupt */ + ENET0_IRQn = 61, /*!< ENET 0 interrupt */ + ENET0_WKUP_IRQn = 62, /*!< ENET 0 wakeup through EXTI line interrupt */ + DMA1_Channel5_IRQn = 68, /*!< DMA1 channel 5 interrupt */ + DMA1_Channel6_IRQn = 69, /*!< DMA1 channel 6 interrupt */ + DMA1_Channel7_IRQn = 70, /*!< DMA1 channel 7 interrupt */ + USART5_IRQn = 71, /*!< UART5 global and wakeup interrupt */ + I2C2_EV_IRQn = 72, /*!< I2C2 event interrupt */ + I2C2_ER_IRQn = 73, /*!< I2C2 error interrupt */ + USBHS0_EP1_OUT_IRQn = 74, /*!< USBHS0 endpoint 1 out interrupt */ + USBHS0_EP1_IN_IRQn = 75, /*!< USBHS0 endpoint 1 in interrupt */ + USBHS0_WKUP_IRQn = 76, /*!< USBHS0 wakeup through EXTI line interrupt */ + USBHS0_IRQn = 77, /*!< USBHS0 interrupt */ + DCI_IRQn = 78, /*!< DCI interrupt */ + CAU_IRQn = 79, /*!< CAU interrupt */ + HAU_TRNG_IRQn = 80, /*!< HAU and TRNG interrupt */ + FPU_IRQn = 81, /*!< FPU interrupt */ + UART6_IRQn = 82, /*!< UART6 interrupt */ + UART7_IRQn = 83, /*!< UART7 interrupt */ + SPI3_IRQn = 84, /*!< SPI3 interrupt */ + SPI4_IRQn = 85, /*!< SPI4 interrupt */ + SPI5_IRQn = 86, /*!< SPI5 interrupt */ + SAI0_IRQn = 87, /*!< SAI0 interrupt */ + TLI_IRQn = 88, /*!< TLI interrupt */ + TLI_ER_IRQn = 89, /*!< TLI error interrupt */ + IPA_IRQn = 90, /*!< IPA interrupt */ + SAI1_IRQn = 91, /*!< SAI1 interrupt */ + OSPI0_IRQn = 92, /*!< OSPI0 global interrupt */ + I2C3_EV_IRQn = 95, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 96, /*!< I2C3 error interrupt */ + RSPDIF_IRQn = 97, /*!< RSPDIF global interrupt */ + DMAMUX_OVR_IRQn = 102, /*!< DMAMUX overrun interrupt */ + HPDF_INT0_IRQn = 110, /*!< HPDF filiter 0 interrupt */ + HPDF_INT1_IRQn = 111, /*!< HPDF filiter 1 interrupt */ + HPDF_INT2_IRQn = 112, /*!< HPDF filiter 2 interrupt */ + HPDF_INT3_IRQn = 113, /*!< HPDF filiter 3 interrupt */ + SAI2_IRQn = 114, /*!< SAI2 interrupt */ + TIMER14_IRQn = 116, /*!< TIMER14 interrupt */ + TIMER15_IRQn = 117, /*!< TIMER15 interrupt */ + TIMER16_IRQn = 118, /*!< TIMER16 interrupt */ + MDIO_IRQn = 120, /*!< MDIO interrupt */ + MDMA_IRQn = 122, /*!< MDMA interrupt */ + SDIO1_IRQn = 124, /*!< SDIO1 interrupt */ + HWSEM_IRQn = 125, /*!< HWSEM interrupt */ + ADC2_IRQn = 127, /*!< ADC2 interrupt */ + CMP0_1_IRQn = 137, /*!< CMP0 and CMP1 interrupt */ + CTC_IRQn = 144, /*!< CTC interrupt */ + RAMECCMU_IRQn = 145, /*!< RAMECCMU interrupt */ + OSPI1_IRQn = 150, /*!< OSPI1 interrupt */ + RTDEC0_IRQn = 151, /*!< RTDEC0 interrupt */ + RTDEC1_IRQn = 152, /*!< RTDEC1 interrupt */ + FAC_IRQn = 153, /*!< FAC interrupt */ + TMU_IRQn = 154, /*!< TMU interrupt */ + TIMER22_IRQn = 161, /*!< TIMER22 interrupt */ + TIMER23_IRQn = 162, /*!< TIMER23 interrupt */ + TIMER30_IRQn = 163, /*!< TIMER30 interrupt */ + TIMER31_IRQn = 164, /*!< TIMER31 interrupt */ + TIMER40_IRQn = 165, /*!< TIMER40 interrupt */ + TIMER41_IRQn = 166, /*!< TIMER41 interrupt */ + TIMER42_IRQn = 167, /*!< TIMER42 interrupt */ + TIMER43_IRQn = 168, /*!< TIMER43 interrupt */ + TIMER44_IRQn = 169, /*!< TIMER44 interrupt */ + TIMER50_IRQn = 170, /*!< TIMER50 interrupt */ + TIMER51_IRQn = 171, /*!< TIMER51 interrupt */ + USBHS1_EP1_OUT_IRQn = 172, /*!< USBHS1 endpoint 1 out interrupt */ + USBHS1_EP1_IN_IRQn = 173, /*!< USBHS1 endpoint 1 in interrupt */ + USBHS1_WKUP_IRQn = 174, /*!< USBHS1 wakeup through EXTI line interrupt */ + USBHS1_IRQn = 175, /*!< USBHS1 interrupt */ + ENET1_IRQn = 176, /*!< ENET1 interrupt */ + ENET1_WKUP_IRQn = 177, /*!< ENET1 wakeup through EXTI line interrupt */ + CAN0_WKUP_IRQn = 179, /*!< CAN 0 wakeup through EXTI line interrupt */ + CAN0_Message_IRQn = 180, /*!< CAN 0 message buffer interrupt */ + CAN0_Busoff_IRQn = 181, /*!< CAN 0 bus off / bus off done interrupt */ + CAN0_Error_IRQn = 182, /*!< CAN 0 error interrupt */ + CAN0_FastError_IRQn = 183, /*!< CAN 0 error in fast transmission interrupt */ + CAN0_TEC_IRQn = 184, /*!< CAN 0 transmit warning interrupt */ + CAN0_REC_IRQn = 185, /*!< CAN 0 receive warning interrupt */ + CAN1_WKUP_IRQn = 186, /*!< CAN 1 wakeup through EXTI line interrupt */ + CAN1_Message_IRQn = 187, /*!< CAN 1 message buffer interrupt */ + CAN1_Busoff_IRQn = 188, /*!< CAN 1 bus off / bus off done interrupt */ + CAN1_Error_IRQn = 189, /*!< CAN 1 error interrupt */ + CAN1_FastError_IRQn = 190, /*!< CAN 1 error in fast transmission interrupt */ + CAN1_TEC_IRQn = 191, /*!< CAN 1 transmit warning interrupt */ + CAN1_REC_IRQn = 192, /*!< CAN 1 receive warning interrupt */ + CAN2_WKUP_IRQn = 193, /*!< CAN 2 wakeup through EXTI line interrupt */ + CAN2_Message_IRQn = 194, /*!< CAN 2 message buffer interrupt */ + CAN2_Busoff_IRQn = 195, /*!< CAN 2 bus off / bus off done interrupt */ + CAN2_Error_IRQn = 196, /*!< CAN 2 error interrupt */ + CAN2_FastError_IRQn = 197, /*!< CAN 2 error in fast transmission interrupt */ + CAN2_TEC_IRQn = 198, /*!< CAN 2 transmit warning interrupt */ + CAN2_REC_IRQn = 199, /*!< CAN 2 receive warning interrupt */ + EFUSE_IRQn = 200, /*!< EFUSE interrupt */ + I2C0_WKUP_IRQn = 201, /*!< I2C 0 wakeup through EXTI line interrupt */ + I2C1_WKUP_IRQn = 202, /*!< I2C 1 wakeup through EXTI line interrupt */ + I2C2_WKUP_IRQn = 203, /*!< I2C 2 wakeup through EXTI line interrupt */ + I2C3_WKUP_IRQn = 204, /*!< I2C 3 wakeup through EXTI line interrupt */ + LPDTS_IRQn = 205, /*!< LPDTS interrupt */ + LPDTS_WKUP_IRQn = 206, /*!< LPDTS wakeup through EXTI line interrupt */ + TIMER0_DEC_IRQn = 207, /*!< TIMER0 DEC interrupt */ + TIMER7_DEC_IRQn = 208, /*!< TIMER7 DEC interrupt */ + TIMER1_DEC_IRQn = 209, /*!< TIMER1 DEC interrupt */ + TIMER2_DEC_IRQn = 210, /*!< TIMER2 DEC interrupt */ + TIMER3_DEC_IRQn = 211, /*!< TIMER3 DEC interrupt */ + TIMER4_DEC_IRQn = 212, /*!< TIMER4 DEC interrupt */ + TIMER22_DEC_IRQn = 213, /*!< TIMER22 DEC interrupt */ + TIMER23_DEC_IRQn = 214, /*!< TIMER23 DEC interrupt */ + TIMER30_DEC_IRQn = 215, /*!< TIMER30 DEC interrupt */ + TIMER31_DEC_IRQn = 216, /*!< TIMER31 DEC interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm7.h" +#include "system_gd32h7xx.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG64(addr) (*(volatile uint64_t *)(uint32_t)(addr)) +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#define BIT(x) ((uint32_t)((uint32_t)0x01U << (x))) +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define SRAM_BASE ((uint32_t)0x24000000U) /*!< SRAM base address */ +/* SRAM and peripheral base bit-band region */ +#define SRAM_BB_BASE ((uint32_t)0x22000000U) /*!< SRAM bit-band base address */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000U) /*!< peripheral bit-band base address */ +/* peripheral memory map */ +#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ +#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ +#define APB3_BUS_BASE ((uint32_t)0x50000000U) /*!< apb3 base address */ +#define APB4_BUS_BASE ((uint32_t)0x58000000U) /*!< apb4 base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */ +#define AHB3_BUS_BASE ((uint32_t)0x51000000U) /*!< ahb3 base address */ +#define AHB4_BUS_BASE ((uint32_t)0x58020000U) /*!< ahb4 base address */ +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define RSPDIF_BASE (APB1_BUS_BASE + 0x00004000U) /*!< RSPDIF base address */ +#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ +#define CTC_BASE (APB1_BUS_BASE + 0x00008400U) /*!< CTC base address */ +#define MDIO_BASE (APB1_BUS_BASE + 0x00009400U) /*!< MDIO base address */ +/* advanced peripheral bus 2 memory map */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */ +#define SAI_BASE (APB2_BUS_BASE + 0x00005800U) /*!< SAI base address */ +#define HPDF_BASE (APB2_BUS_BASE + 0x00007000U) /*!< HPDF base address */ +#define TRIGSEL_BASE (APB2_BUS_BASE + 0x00008400U) /*!< TRIGSEL base address */ +#define EDOUT_BASE (APB2_BUS_BASE + 0x00008800U) /*!< EDOUT base address */ +#define CAN_BASE (APB2_BUS_BASE + 0x0000A000U) /*!< CAN base address */ +/* advanced peripheral bus 3 memory map */ +#define TLI_BASE (APB3_BUS_BASE + 0x00001000U) /*!< TLI base address */ +#define WWDGT_BASE (APB3_BUS_BASE + 0x00003000U) /*!< WWDGT base address */ +/* advanced peripheral bus 4 memory map */ +#define EXTI_BASE (APB4_BUS_BASE + 0x00000000U) /*!< EXTI base address */ +#define SYSCFG_BASE (APB4_BUS_BASE + 0x00000400U) /*!< SYSCFG base address */ +#define CMP_BASE (APB4_BUS_BASE + 0x00003800U) /*!< CMP base address */ +#define VREF_BASE (APB4_BUS_BASE + 0x00003C00U) /*!< VREF base address */ +#define RTC_BASE (APB4_BUS_BASE + 0x00004000U) /*!< CMP base address */ +#define FWDGT_BASE (APB4_BUS_BASE + 0x00004800U) /*!< FWDGT base address */ +#define PMU_BASE (APB4_BUS_BASE + 0x00005800U) /*!< PMU base address */ +#define LPDTS_BASE (APB4_BUS_BASE + 0x00006800U) /*!< LPDTS base address */ +/* advanced high performance bus 1 memory map */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ +#define DMAMUX_BASE (AHB1_BUS_BASE + 0x00000800U) /*!< DMAMUX base address */ +#define EFUSE_BASE (AHB1_BUS_BASE + 0x00002800U) /*!< EFUSE base address */ +#define ENET_BASE (AHB1_BUS_BASE + 0x00008000U) /*!< ENET base address */ +#define USBHS_BASE (AHB1_BUS_BASE + 0x00020000U) /*!< USBHS base address */ +/* advanced high performance bus 2 memory map */ +#define DCI_BASE (AHB2_BUS_BASE + 0x00020000U) /*!< DCI base address */ +#define CAU_BASE (AHB2_BUS_BASE + 0x00021000U) /*!< CAU base address */ +#define HAU_BASE (AHB2_BUS_BASE + 0x00021400U) /*!< HAU base address */ +#define TRNG_BASE (AHB2_BUS_BASE + 0x00021800U) /*!< TRNG base address */ +#define SDIO_BASE (AHB2_BUS_BASE + 0x00022400U) /*!< SDIO base address */ +#define CPDM_BASE (AHB2_BUS_BASE + 0x00022800U) /*!< CPDM base address */ +#define RAMECCMU_BASE (AHB2_BUS_BASE + 0x00023000U) /*!< RAMECCMU base address */ +#define TMU_BASE (AHB2_BUS_BASE + 0x00024400U) /*!< TMU base address */ +#define FAC_BASE (AHB2_BUS_BASE + 0x00024800U) /*!< FAC base address */ +/* advanced high performance bus 3 memory map */ +#define AXIM_BASE (AHB3_BUS_BASE + 0x00000000U) /*!< AXIM base address */ +#define MDMA_BASE (AHB3_BUS_BASE + 0x01000000U) /*!< MDMA base address */ +#define IPA_BASE (AHB3_BUS_BASE + 0x01001000U) /*!< IPA base address */ +#define FMC_BASE (AHB3_BUS_BASE + 0x01002000U) /*!< FMC base address */ +#define FLEXRAMC_BASE (AHB3_BUS_BASE + 0x01003000U) /*!< FLEXRAMC base address */ +#define EXMC_BASE (AHB3_BUS_BASE + 0x01004000U) /*!< EXMC base address */ +#define OSPI_BASE (AHB3_BUS_BASE + 0x01005000U) /*!< OSPI base address */ +#define OSPM_BASE (AHB3_BUS_BASE + 0x0100B400U) /*!< OSPM base address */ +#define RTDEC_BASE (AHB3_BUS_BASE + 0x0100B800U) /*!< RTDEC base address */ +/* advanced high performance bus 4 memory map */ +#define GPIO_BASE (AHB4_BUS_BASE + 0x00000000U) /*!< GPIO base address */ +#define RCU_BASE (AHB4_BUS_BASE + 0x00004400U) /*!< RCU base address */ +#define CRC_BASE (AHB4_BUS_BASE + 0x00004C00U) /*!< CRC base address */ +#define HWSEM_BASE (AHB4_BUS_BASE + 0x00006400U) /*!< HWSEM base address */ +/* option byte and debug memory map */ +#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */ +#define DBG_BASE ((uint32_t)0xE00E1000U) /*!< DBG base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32h7xx_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef __cplusplus +} +#endif + +#endif /* GD32H7XX_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/system_gd32h7xx.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/system_gd32h7xx.h new file mode 100644 index 0000000000..7bedb4f8b3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Include/system_gd32h7xx.h @@ -0,0 +1,50 @@ +/*! + \file system_gd32h7xx.h + \brief CMSIS Cortex-M7 Device Peripheral Access Layer Header File for + gd32h7xx Device Series +*/ + +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * Copyright (c) 2024, GigaDevice Semiconductor Inc. + * + * 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. + */ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#ifndef SYSTEM_GD32H7XX_H +#define SYSTEM_GD32H7XX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* system clock frequency (core clock) */ +extern uint32_t SystemCoreClock; + +/* function declarations */ +/* initialize the system and update the SystemCoreClock variable */ +extern void SystemInit (void); +/* update the SystemCoreClock with current core clock retrieved from cpu registers */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_GD32H7XX_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/ARM/startup_gd32h7xx.s b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/ARM/startup_gd32h7xx.s new file mode 100644 index 0000000000..ca4d1131de --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/ARM/startup_gd32h7xx.s @@ -0,0 +1,729 @@ +;/*! +; \file startup_gd32h7xx.s +; \brief start up file + +; \version 2024-01-05, V1.2.0, firmware for GD32H7xx +;*/ + +;/* +; * Copyright (c) 2009-2018 Arm Limited. All rights reserved. +; * Copyright (c) 2024, GigaDevice Semiconductor Inc. +; * +; * 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. +; */ + +;/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00001000 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x000000800 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; /* reset Vector Mapped to at Address 0 */ + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD AVD_LVD_OVD_IRQHandler ; 17:AVD/LVD/OVD through EXTI Line detect + DCD TAMPER_STAMP_LXTAL_IRQHandler ; 18:RTC Tamper and TimeStamp through EXTI Line detect, LXTAL clock security system interrupt + DCD RTC_WKUP_IRQHandler ; 19:RTC Wakeup from EXTI interrupt + DCD FMC_IRQHandler ; 20:FMC global interrupt + DCD RCU_IRQHandler ; 21:RCU global interrupt + DCD EXTI0_IRQHandler ; 22:EXTI Line 0 + DCD EXTI1_IRQHandler ; 23:EXTI Line 1 + DCD EXTI2_IRQHandler ; 24:EXTI Line 2 + DCD EXTI3_IRQHandler ; 25:EXTI Line 3 + DCD EXTI4_IRQHandler ; 26:EXTI Line 4 + DCD DMA0_Channel0_IRQHandler ; 27:DMA0 Channel 0 + DCD DMA0_Channel1_IRQHandler ; 28:DMA0 Channel 1 + DCD DMA0_Channel2_IRQHandler ; 29:DMA0 Channel 2 + DCD DMA0_Channel3_IRQHandler ; 30:DMA0 Channel 3 + DCD DMA0_Channel4_IRQHandler ; 31:DMA0 Channel 4 + DCD DMA0_Channel5_IRQHandler ; 32:DMA0 Channel 5 + DCD DMA0_Channel6_IRQHandler ; 33:DMA0 Channel 6 + DCD ADC0_1_IRQHandler ; 34:ADC0 and ADC1 interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD EXTI5_9_IRQHandler ; 39:EXTI5 to EXTI9 + DCD TIMER0_BRK_IRQHandler ; 40:TIMER0 Break + DCD TIMER0_UP_IRQHandler ; 41:TIMER0 Update + DCD TIMER0_TRG_CMT_IRQHandler ; 42:TIMER0 Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 43:TIMER0 Capture Compare + DCD TIMER1_IRQHandler ; 44:TIMER1 + DCD TIMER2_IRQHandler ; 45:TIMER2 + DCD TIMER3_IRQHandler ; 46:TIMER3 + DCD I2C0_EV_IRQHandler ; 47:I2C0 Event + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD I2C1_EV_IRQHandler ; 49:I2C1 Event + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD SPI0_IRQHandler ; 51:SPI0 + DCD SPI1_IRQHandler ; 52:SPI1 + DCD USART0_IRQHandler ; 53:USART0 global and wakeup + DCD USART1_IRQHandler ; 54:USART1 global and wakeup + DCD USART2_IRQHandler ; 55:USART2 global and wakeup + DCD EXTI10_15_IRQHandler ; 56:EXTI10 to EXTI15 + DCD RTC_Alarm_IRQHandler ; 57:RTC Alarm + DCD 0 ; Reserved + DCD TIMER7_BRK_IRQHandler ; 59:TIMER7 Break + DCD TIMER7_UP_IRQHandler ; 60:TIMER7 Update + DCD TIMER7_TRG_CMT_IRQHandler ; 61:TIMER7 Trigger and Commutation + DCD TIMER7_Channel_IRQHandler ; 62:TIMER7 Channel Capture Compare + DCD DMA0_Channel7_IRQHandler ; 63:DMA0 Channel 7 + DCD EXMC_IRQHandler ; 64:EXMC + DCD SDIO0_IRQHandler ; 65:SDIO0 + DCD TIMER4_IRQHandler ; 66:TIMER4 + DCD SPI2_IRQHandler ; 67:SPI2 + DCD UART3_IRQHandler ; 68:UART3 + DCD UART4_IRQHandler ; 69:UART4 + DCD TIMER5_DAC_UDR_IRQHandler ; 70:TIMER5 global interrupt and DAC1/DAC0 underrun error + DCD TIMER6_IRQHandler ; 71:TIMER6 + DCD DMA1_Channel0_IRQHandler ; 72:DMA1 Channel0 + DCD DMA1_Channel1_IRQHandler ; 73:DMA1 Channel1 + DCD DMA1_Channel2_IRQHandler ; 74:DMA1 Channel2 + DCD DMA1_Channel3_IRQHandler ; 75:DMA1 Channel3 + DCD DMA1_Channel4_IRQHandler ; 76:DMA1 Channel4 + DCD ENET0_IRQHandler ; 77:Ethernet0 + DCD ENET0_WKUP_IRQHandler ; 78:Ethernet0 Wakeup through EXTI Line + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DMA1_Channel5_IRQHandler ; 84:DMA1 Channel5 + DCD DMA1_Channel6_IRQHandler ; 85:DMA1 Channel6 + DCD DMA1_Channel7_IRQHandler ; 86:DMA1 Channel7 + DCD USART5_IRQHandler ; 87:USART5 global and wakeup + DCD I2C2_EV_IRQHandler ; 88:I2C2 Event + DCD I2C2_ER_IRQHandler ; 89:I2C2 Error + DCD USBHS0_EP1_OUT_IRQHandler ; 90:USBHS0 Endpoint 1 Out + DCD USBHS0_EP1_IN_IRQHandler ; 91:USBHS0 Endpoint 1 in + DCD USBHS0_WKUP_IRQHandler ; 92:USBHS0 Wakeup through EXTI Line + DCD USBHS0_IRQHandler ; 93:USBHS0 + DCD DCI_IRQHandler ; 94:DCI + DCD CAU_IRQHandler ; 95:CAU + DCD HAU_TRNG_IRQHandler ; 96:HAU and TRNG + DCD FPU_IRQHandler ; 97:FPU + DCD UART6_IRQHandler ; 98:UART6 + DCD UART7_IRQHandler ; 99:UART7 + DCD SPI3_IRQHandler ; 100:SPI3 + DCD SPI4_IRQHandler ; 101:SPI4 + DCD SPI5_IRQHandler ; 102:SPI5 + DCD SAI0_IRQHandler ; 103:SAI0 + DCD TLI_IRQHandler ; 104:TLI + DCD TLI_ER_IRQHandler ; 105:TLI Error + DCD IPA_IRQHandler ; 106:IPA + DCD SAI1_IRQHandler ; 107:SAI1 + DCD OSPI0_IRQHandler ; 108:OSPI0 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C3_EV_IRQHandler ; 111:I2C3 Event + DCD I2C3_ER_IRQHandler ; 112:I2C3 Error + DCD RSPDIF_IRQHandler ; 113:RSPDIF + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DMAMUX_OVR_IRQHandler ; 118:DMAMUX Overrun interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HPDF_INT0_IRQHandler ; 126:HPDF global interrupt 0 + DCD HPDF_INT1_IRQHandler ; 127:HPDF global interrupt 1 + DCD HPDF_INT2_IRQHandler ; 128:HPDF global interrupt 2 + DCD HPDF_INT3_IRQHandler ; 129:HPDF global interrupt 3 + DCD SAI2_IRQHandler ; 130:SAI2 global interrupt + DCD 0 ; Reserved + DCD TIMER14_IRQHandler ; 132:TIMER14 + DCD TIMER15_IRQHandler ; 133:TIMER15 + DCD TIMER16_IRQHandler ; 134:TIMER16 + DCD 0 ; Reserved + DCD MDIO_IRQHandler ; 136:MDIO + DCD 0 ; Reserved + DCD MDMA_IRQHandler ; 138:MDMA + DCD 0 ; Reserved + DCD SDIO1_IRQHandler ; 140:SDIO1 + DCD HWSEM_IRQHandler ; 141:HWSEM + DCD 0 ; Reserved + DCD ADC2_IRQHandler ; 143:ADC2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CMP0_1_IRQHandler ; 153:CMP0 and CMP1 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CTC_IRQHandler ; 160:Clock Recovery System + DCD RAMECCMU_IRQHandler ; 161:RAMECCMU + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD OSPI1_IRQHandler ; 166:OSPI1 + DCD RTDEC0_IRQHandler ; 167:RTDEC0 + DCD RTDEC1_IRQHandler ; 168:RTDEC1 + DCD FAC_IRQHandler ; 169:FAC + DCD TMU_IRQHandler ; 170:TMU + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TIMER22_IRQHandler ; 177:TIMER22 + DCD TIMER23_IRQHandler ; 178:TIMER23 + DCD TIMER30_IRQHandler ; 179:TIMER30 + DCD TIMER31_IRQHandler ; 180:TIMER31 + DCD TIMER40_IRQHandler ; 181:TIMER40 + DCD TIMER41_IRQHandler ; 182:TIMER41 + DCD TIMER42_IRQHandler ; 183:TIMER42 + DCD TIMER43_IRQHandler ; 184:TIMER43 + DCD TIMER44_IRQHandler ; 185:TIMER44 + DCD TIMER50_IRQHandler ; 186:TIMER50 + DCD TIMER51_IRQHandler ; 187:TIMER51 + DCD USBHS1_EP1_OUT_IRQHandler ; 188:USBHS1 endpoint 1 out + DCD USBHS1_EP1_IN_IRQHandler ; 189:USBHS1 endpoint 1 in + DCD USBHS1_WKUP_IRQHandler ; 190:USBHS1 wakeup + DCD USBHS1_IRQHandler ; 191:USBHS1 + DCD ENET1_IRQHandler ; 192:Ethernet1 + DCD ENET1_WKUP_IRQHandler ; 193:Ethernet1 wakeup + DCD 0 ; Reserved + DCD CAN0_WKUP_IRQHandler ; 195:CAN0 wakeup + DCD CAN0_Message_IRQHandler ; 196:CAN0 interrupt for message buffer + DCD CAN0_Busoff_IRQHandler ; 197:CAN0 interrupt for Bus off / Bus off done + DCD CAN0_Error_IRQHandler ; 198:CAN0 interrupt for Error + DCD CAN0_FastError_IRQHandler ; 199:CAN0 interrupt for Error in fast transmission + DCD CAN0_TEC_IRQHandler ; 200:CAN0 interrupt for Transmit warning + DCD CAN0_REC_IRQHandler ; 201:CAN0 interrupt for Receive warning + DCD CAN1_WKUP_IRQHandler ; 202:CAN1 wakeup + DCD CAN1_Message_IRQHandler ; 203:CAN1 interrupt for message buffer + DCD CAN1_Busoff_IRQHandler ; 204:CAN1 interrupt for Bus off / Bus off done + DCD CAN1_Error_IRQHandler ; 205:CAN1 interrupt for Error + DCD CAN1_FastError_IRQHandler ; 206:CAN1 interrupt for Error in fast transmission + DCD CAN1_TEC_IRQHandler ; 207:CAN1 interrupt for Transmit warning + DCD CAN1_REC_IRQHandler ; 208:CAN1 interrupt for Receive warning + DCD CAN2_WKUP_IRQHandler ; 209:CAN2 wakeup + DCD CAN2_Message_IRQHandler ; 210:CAN2 interrupt for message buffer + DCD CAN2_Busoff_IRQHandler ; 211:CAN2 interrupt for Bus off / Bus off done + DCD CAN2_Error_IRQHandler ; 212:CAN2 interrupt for Error + DCD CAN2_FastError_IRQHandler ; 213:CAN2 interrupt for Error in fast transmission + DCD CAN2_TEC_IRQHandler ; 214:CAN2 interrupt for Transmit warning + DCD CAN2_REC_IRQHandler ; 215:CAN2 interrupt for Receive warning + DCD EFUSE_IRQHandler ; 216:EFUSE + DCD I2C0_WKUP_IRQHandler ; 217:I2C0 wakeup + DCD I2C1_WKUP_IRQHandler ; 218:I2C1 wakeup + DCD I2C2_WKUP_IRQHandler ; 219:I2C2 wakeup + DCD I2C3_WKUP_IRQHandler ; 220:I2C3 wakeup + DCD LPDTS_IRQHandler ; 221:LPDTS + DCD LPDTS_WKUP_IRQHandler ; 222:LPDTS wakeup + DCD TIMER0_DEC_IRQHandler ; 223:TIMER0 DEC + DCD TIMER7_DEC_IRQHandler ; 224:TIMER7 DEC + DCD TIMER1_DEC_IRQHandler ; 225:TIMER1 DEC + DCD TIMER2_DEC_IRQHandler ; 226:TIMER2 DEC + DCD TIMER3_DEC_IRQHandler ; 227:TIMER3 DEC + DCD TIMER4_DEC_IRQHandler ; 228:TIMER4 DEC + DCD TIMER22_DEC_IRQHandler ; 229:TIMER22 DEC + DCD TIMER23_DEC_IRQHandler ; 230:TIMER23 DEC + DCD TIMER30_DEC_IRQHandler ; 231:TIMER30 DEC + DCD TIMER31_DEC_IRQHandler ; 232:TIMER31 DEC + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +;/* reset Handler */ +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + IMPORT |Image$$RW_IRAM1$$RW$$Base| + + LDR R0, =|Image$$RW_IRAM1$$RW$$Base| + ADD R1, R0, #0x8000 + LDR R2, =0x0 +MEM_INIT STRD R2, R2, [ R0 ] , #8 + CMP R0, R1 + BNE MEM_INIT + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +;/* dummy Exception Handlers */ +NMI_Handler\ + PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC +; /* external interrupts handler */ + EXPORT WWDGT_IRQHandler [WEAK] + EXPORT AVD_LVD_OVD_IRQHandler [WEAK] + EXPORT TAMPER_STAMP_LXTAL_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT RCU_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA0_Channel0_IRQHandler [WEAK] + EXPORT DMA0_Channel1_IRQHandler [WEAK] + EXPORT DMA0_Channel2_IRQHandler [WEAK] + EXPORT DMA0_Channel3_IRQHandler [WEAK] + EXPORT DMA0_Channel4_IRQHandler [WEAK] + EXPORT DMA0_Channel5_IRQHandler [WEAK] + EXPORT DMA0_Channel6_IRQHandler [WEAK] + EXPORT ADC0_1_IRQHandler [WEAK] + EXPORT EXTI5_9_IRQHandler [WEAK] + EXPORT TIMER0_BRK_IRQHandler [WEAK] + EXPORT TIMER0_UP_IRQHandler [WEAK] + EXPORT TIMER0_TRG_CMT_IRQHandler [WEAK] + EXPORT TIMER0_Channel_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT I2C0_EV_IRQHandler [WEAK] + EXPORT I2C0_ER_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT SPI0_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT USART0_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT EXTI10_15_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT TIMER7_BRK_IRQHandler [WEAK] + EXPORT TIMER7_UP_IRQHandler [WEAK] + EXPORT TIMER7_TRG_CMT_IRQHandler [WEAK] + EXPORT TIMER7_Channel_IRQHandler [WEAK] + EXPORT DMA0_Channel7_IRQHandler [WEAK] + EXPORT EXMC_IRQHandler [WEAK] + EXPORT SDIO0_IRQHandler [WEAK] + EXPORT TIMER4_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT UART3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT TIMER5_DAC_UDR_IRQHandler [WEAK] + EXPORT TIMER6_IRQHandler [WEAK] + EXPORT DMA1_Channel0_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT ENET0_IRQHandler [WEAK] + EXPORT ENET0_WKUP_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT USART5_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT USBHS0_EP1_OUT_IRQHandler [WEAK] + EXPORT USBHS0_EP1_IN_IRQHandler [WEAK] + EXPORT USBHS0_WKUP_IRQHandler [WEAK] + EXPORT USBHS0_IRQHandler [WEAK] + EXPORT DCI_IRQHandler [WEAK] + EXPORT CAU_IRQHandler [WEAK] + EXPORT HAU_TRNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT UART6_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT SAI0_IRQHandler [WEAK] + EXPORT TLI_IRQHandler [WEAK] + EXPORT TLI_ER_IRQHandler [WEAK] + EXPORT IPA_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT OSPI0_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT RSPDIF_IRQHandler [WEAK] + EXPORT DMAMUX_OVR_IRQHandler [WEAK] + EXPORT HPDF_INT0_IRQHandler [WEAK] + EXPORT HPDF_INT1_IRQHandler [WEAK] + EXPORT HPDF_INT2_IRQHandler [WEAK] + EXPORT HPDF_INT3_IRQHandler [WEAK] + EXPORT SAI2_IRQHandler [WEAK] + EXPORT TIMER14_IRQHandler [WEAK] + EXPORT TIMER15_IRQHandler [WEAK] + EXPORT TIMER16_IRQHandler [WEAK] + EXPORT MDIO_IRQHandler [WEAK] + EXPORT MDMA_IRQHandler [WEAK] + EXPORT SDIO1_IRQHandler [WEAK] + EXPORT HWSEM_IRQHandler [WEAK] + EXPORT ADC2_IRQHandler [WEAK] + EXPORT CMP0_1_IRQHandler [WEAK] + EXPORT CTC_IRQHandler [WEAK] + EXPORT RAMECCMU_IRQHandler [WEAK] + EXPORT OSPI1_IRQHandler [WEAK] + EXPORT RTDEC0_IRQHandler [WEAK] + EXPORT RTDEC1_IRQHandler [WEAK] + EXPORT FAC_IRQHandler [WEAK] + EXPORT TMU_IRQHandler [WEAK] + EXPORT TIMER22_IRQHandler [WEAK] + EXPORT TIMER23_IRQHandler [WEAK] + EXPORT TIMER30_IRQHandler [WEAK] + EXPORT TIMER31_IRQHandler [WEAK] + EXPORT TIMER40_IRQHandler [WEAK] + EXPORT TIMER41_IRQHandler [WEAK] + EXPORT TIMER42_IRQHandler [WEAK] + EXPORT TIMER43_IRQHandler [WEAK] + EXPORT TIMER44_IRQHandler [WEAK] + EXPORT TIMER50_IRQHandler [WEAK] + EXPORT TIMER51_IRQHandler [WEAK] + EXPORT USBHS1_EP1_OUT_IRQHandler [WEAK] + EXPORT USBHS1_EP1_IN_IRQHandler [WEAK] + EXPORT USBHS1_WKUP_IRQHandler [WEAK] + EXPORT USBHS1_IRQHandler [WEAK] + EXPORT ENET1_IRQHandler [WEAK] + EXPORT ENET1_WKUP_IRQHandler [WEAK] + EXPORT CAN0_WKUP_IRQHandler [WEAK] + EXPORT CAN0_Message_IRQHandler [WEAK] + EXPORT CAN0_Busoff_IRQHandler [WEAK] + EXPORT CAN0_Error_IRQHandler [WEAK] + EXPORT CAN0_FastError_IRQHandler [WEAK] + EXPORT CAN0_TEC_IRQHandler [WEAK] + EXPORT CAN0_REC_IRQHandler [WEAK] + EXPORT CAN1_WKUP_IRQHandler [WEAK] + EXPORT CAN1_Message_IRQHandler [WEAK] + EXPORT CAN1_Busoff_IRQHandler [WEAK] + EXPORT CAN1_Error_IRQHandler [WEAK] + EXPORT CAN1_FastError_IRQHandler [WEAK] + EXPORT CAN1_TEC_IRQHandler [WEAK] + EXPORT CAN1_REC_IRQHandler [WEAK] + EXPORT CAN2_WKUP_IRQHandler [WEAK] + EXPORT CAN2_Message_IRQHandler [WEAK] + EXPORT CAN2_Busoff_IRQHandler [WEAK] + EXPORT CAN2_Error_IRQHandler [WEAK] + EXPORT CAN2_FastError_IRQHandler [WEAK] + EXPORT CAN2_TEC_IRQHandler [WEAK] + EXPORT CAN2_REC_IRQHandler [WEAK] + EXPORT EFUSE_IRQHandler [WEAK] + EXPORT I2C0_WKUP_IRQHandler [WEAK] + EXPORT I2C1_WKUP_IRQHandler [WEAK] + EXPORT I2C2_WKUP_IRQHandler [WEAK] + EXPORT I2C3_WKUP_IRQHandler [WEAK] + EXPORT LPDTS_IRQHandler [WEAK] + EXPORT LPDTS_WKUP_IRQHandler [WEAK] + EXPORT TIMER0_DEC_IRQHandler [WEAK] + EXPORT TIMER7_DEC_IRQHandler [WEAK] + EXPORT TIMER1_DEC_IRQHandler [WEAK] + EXPORT TIMER2_DEC_IRQHandler [WEAK] + EXPORT TIMER3_DEC_IRQHandler [WEAK] + EXPORT TIMER4_DEC_IRQHandler [WEAK] + EXPORT TIMER22_DEC_IRQHandler [WEAK] + EXPORT TIMER23_DEC_IRQHandler [WEAK] + EXPORT TIMER30_DEC_IRQHandler [WEAK] + EXPORT TIMER31_DEC_IRQHandler [WEAK] + +;/* external interrupts handler */ +WWDGT_IRQHandler +AVD_LVD_OVD_IRQHandler +TAMPER_STAMP_LXTAL_IRQHandler +RTC_WKUP_IRQHandler +FMC_IRQHandler +RCU_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA0_Channel0_IRQHandler +DMA0_Channel1_IRQHandler +DMA0_Channel2_IRQHandler +DMA0_Channel3_IRQHandler +DMA0_Channel4_IRQHandler +DMA0_Channel5_IRQHandler +DMA0_Channel6_IRQHandler +ADC0_1_IRQHandler +EXTI5_9_IRQHandler +TIMER0_BRK_IRQHandler +TIMER0_UP_IRQHandler +TIMER0_TRG_CMT_IRQHandler +TIMER0_Channel_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +TIMER3_IRQHandler +I2C0_EV_IRQHandler +I2C0_ER_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +SPI0_IRQHandler +SPI1_IRQHandler +USART0_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +EXTI10_15_IRQHandler +RTC_Alarm_IRQHandler +TIMER7_BRK_IRQHandler +TIMER7_UP_IRQHandler +TIMER7_TRG_CMT_IRQHandler +TIMER7_Channel_IRQHandler +DMA0_Channel7_IRQHandler +EXMC_IRQHandler +SDIO0_IRQHandler +TIMER4_IRQHandler +SPI2_IRQHandler +UART3_IRQHandler +UART4_IRQHandler +TIMER5_DAC_UDR_IRQHandler +TIMER6_IRQHandler +DMA1_Channel0_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +ENET0_IRQHandler +ENET0_WKUP_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +USART5_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +USBHS0_EP1_OUT_IRQHandler +USBHS0_EP1_IN_IRQHandler +USBHS0_WKUP_IRQHandler +USBHS0_IRQHandler +DCI_IRQHandler +CAU_IRQHandler +HAU_TRNG_IRQHandler +FPU_IRQHandler +UART6_IRQHandler +UART7_IRQHandler +SPI3_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +SAI0_IRQHandler +TLI_IRQHandler +TLI_ER_IRQHandler +IPA_IRQHandler +SAI1_IRQHandler +OSPI0_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +RSPDIF_IRQHandler +DMAMUX_OVR_IRQHandler +HPDF_INT0_IRQHandler +HPDF_INT1_IRQHandler +HPDF_INT2_IRQHandler +HPDF_INT3_IRQHandler +SAI2_IRQHandler +TIMER14_IRQHandler +TIMER15_IRQHandler +TIMER16_IRQHandler +MDIO_IRQHandler +MDMA_IRQHandler +SDIO1_IRQHandler +HWSEM_IRQHandler +ADC2_IRQHandler +CMP0_1_IRQHandler +CTC_IRQHandler +RAMECCMU_IRQHandler +OSPI1_IRQHandler +RTDEC0_IRQHandler +RTDEC1_IRQHandler +FAC_IRQHandler +TMU_IRQHandler +TIMER22_IRQHandler +TIMER23_IRQHandler +TIMER30_IRQHandler +TIMER31_IRQHandler +TIMER40_IRQHandler +TIMER41_IRQHandler +TIMER42_IRQHandler +TIMER43_IRQHandler +TIMER44_IRQHandler +TIMER50_IRQHandler +TIMER51_IRQHandler +USBHS1_EP1_OUT_IRQHandler +USBHS1_EP1_IN_IRQHandler +USBHS1_WKUP_IRQHandler +USBHS1_IRQHandler +ENET1_IRQHandler +ENET1_WKUP_IRQHandler +CAN0_WKUP_IRQHandler +CAN0_Message_IRQHandler +CAN0_Busoff_IRQHandler +CAN0_Error_IRQHandler +CAN0_FastError_IRQHandler +CAN0_TEC_IRQHandler +CAN0_REC_IRQHandler +CAN1_WKUP_IRQHandler +CAN1_Message_IRQHandler +CAN1_Busoff_IRQHandler +CAN1_Error_IRQHandler +CAN1_FastError_IRQHandler +CAN1_TEC_IRQHandler +CAN1_REC_IRQHandler +CAN2_WKUP_IRQHandler +CAN2_Message_IRQHandler +CAN2_Busoff_IRQHandler +CAN2_Error_IRQHandler +CAN2_FastError_IRQHandler +CAN2_TEC_IRQHandler +CAN2_REC_IRQHandler +EFUSE_IRQHandler +I2C0_WKUP_IRQHandler +I2C1_WKUP_IRQHandler +I2C2_WKUP_IRQHandler +I2C3_WKUP_IRQHandler +LPDTS_IRQHandler +LPDTS_WKUP_IRQHandler +TIMER0_DEC_IRQHandler +TIMER7_DEC_IRQHandler +TIMER1_DEC_IRQHandler +TIMER2_DEC_IRQHandler +TIMER3_DEC_IRQHandler +TIMER4_DEC_IRQHandler +TIMER22_DEC_IRQHandler +TIMER23_DEC_IRQHandler +TIMER30_DEC_IRQHandler +TIMER31_DEC_IRQHandler + + B . + + ENDP + + ALIGN + +; user Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/GCC/startup_gd32h7xx.s b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/GCC/startup_gd32h7xx.s new file mode 100644 index 0000000000..533bab9c12 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/GCC/startup_gd32h7xx.s @@ -0,0 +1,517 @@ +;/* +; * Copyright (c) 2006-2024, RT-Thread Development Team +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Change Logs: +; * Date Author Notes +; * 2024-04-18 Astrozen first implementation +; */ + +.syntax unified +.cpu cortex-m7 +.fpu softvfp +.thumb + +.global g_pfnVectors +.global Default_Handler + + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + +g_pfnVectors: + .word _estack // Top of Stack + .word Reset_Handler // Reset Handler + .word NMI_Handler // NMI Handler + .word HardFault_Handler // Hard Fault Handler + .word MemManage_Handler // MPU Fault Handler + .word BusFault_Handler // Bus Fault Handler + .word UsageFault_Handler // Usage Fault Handler + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word SVC_Handler // SVCall Handler + .word DebugMon_Handler // Debug Monitor Handler + .word 0 // Reserved + .word PendSV_Handler // PendSV Handler + .word SysTick_Handler // SysTick Handler + + // external interrupts handler + .word WWDGT_IRQHandler // 16:Window Watchdog Timer + .word AVD_LVD_OVD_IRQHandler // 17:AVD/LVD/OVD through EXTI Line detect + .word TAMPER_STAMP_IRQHandler // 18:Tamper and TimeStamp through EXTI Line detect + .word RTC_WKUP_IRQHandler // 19:RTC Wakeup through EXTI Line + .word FMC_IRQHandler // 20:FMC + .word RCU_CTC_IRQHandler // 21:RCU and CTC + .word EXTI0_IRQHandler // 22:EXTI Line 0 + .word EXTI1_IRQHandler // 23:EXTI Line 1 + .word EXTI2_IRQHandler // 24:EXTI Line 2 + .word EXTI3_IRQHandler // 25:EXTI Line 3 + .word EXTI4_IRQHandler // 26:EXTI Line 4 + .word DMA0_Channel0_IRQHandler // 27:DMA0 Channel0 + .word DMA0_Channel1_IRQHandler // 28:DMA0 Channel1 + .word DMA0_Channel2_IRQHandler // 29:DMA0 Channel2 + .word DMA0_Channel3_IRQHandler // 30:DMA0 Channel3 + .word DMA0_Channel4_IRQHandler // 31:DMA0 Channel4 + .word DMA0_Channel5_IRQHandler // 32:DMA0 Channel5 + .word DMA0_Channel6_IRQHandler // 33:DMA0 Channel6 + .word ADC0_1_IRQHandler // 34:ADC0 and ADC1 interrupt + .word 0 // 35:Reserved + .word 0 // 36:Reserved + .word 0 // 37:Reserved + .word 0 // 38:Reserved + .word EXTI5_9_IRQHandler // 39:EXTI5 to EXTI9 + .word TIMER0_BRK_IRQHandler // 40:TIMER0 Break + .word TIMER0_UP_IRQHandler // 41:TIMER0 Update + .word TIMER0_TRG_CMT_IRQHandler // 42:TIMER0 Trigger and Commutation + .word TIMER0_Channel_IRQHandler // 43:TIMER0 Capture Compare + .word TIMER1_IRQHandler // 44:TIMER1 + .word TIMER2_IRQHandler // 45:TIMER2 + .word TIMER3_IRQHandler // 46:TIMER3 + .word I2C0_EV_IRQHandler // 47:I2C0 Event + .word I2C0_ER_IRQHandler // 48:I2C0 Error + .word I2C1_EV_IRQHandler // 49:I2C1 Event + .word I2C1_ER_IRQHandler // 50:I2C1 Error + .word SPI0_IRQHandler // 51:SPI0 + .word SPI1_IRQHandler // 52:SPI1 + .word USART0_IRQHandler // 53:USART0 global and wakeup + .word USART1_IRQHandler // 54:USART1 global and wakeup + .word USART2_IRQHandler // 55:USART2 global and wakeup + .word EXTI10_15_IRQHandler // 56:EXTI10 to EXTI15 + .word RTC_Alarm_IRQHandler // 57:RTC Alarm + .word 0 // Reserved + .word TIMER7_BRK_IRQHandler // 59:TIMER7 Break + .word TIMER7_UP_IRQHandler // 60:TIMER7 Update + .word TIMER7_TRG_CMT_IRQHandler // 61:TIMER7 Trigger and Commutation + .word TIMER7_Channel_IRQHandler // 62:TIMER7 Channel Capture Compare + .word DMA0_Channel7_IRQHandler // 63:DMA0 Channel 7 + .word EXMC_IRQHandler // 64:EXMC + .word SDIO0_IRQHandler // 65:SDIO0 + .word TIMER4_IRQHandler // 66:TIMER4 + .word SPI2_IRQHandler // 67:SPI2 + .word UART3_IRQHandler // 68:UART3 + .word UART4_IRQHandler // 69:UART4 + .word TIMER5_DAC_UDR_IRQHandler // 70:TIMER5 global interrupt and DAC1/DAC0 underrun error + .word TIMER6_IRQHandler // 71:TIMER6 + .word DMA1_Channel0_IRQHandler // 72:DMA1 Channel0 + .word DMA1_Channel1_IRQHandler // 73:DMA1 Channel1 + .word DMA1_Channel2_IRQHandler // 74:DMA1 Channel2 + .word DMA1_Channel3_IRQHandler // 75:DMA1 Channel3 + .word DMA1_Channel4_IRQHandler // 76:DMA1 Channel4 + .word ENET0_IRQHandler // 77:Ethernet0 + .word ENET0_WKUP_IRQHandler // 78:Ethernet0 Wakeup through EXTI Line + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word DMA1_Channel5_IRQHandler // 84:DMA1 Channel5 + .word DMA1_Channel6_IRQHandler // 85:DMA1 Channel6 + .word DMA1_Channel7_IRQHandler // 86:DMA1 Channel7 + .word USART5_IRQHandler // 87:USART5 global and wakeup + .word I2C2_EV_IRQHandler // 88:I2C2 Event + .word I2C2_ER_IRQHandler // 89:I2C2 Error + .word USBHS0_EP1_OUT_IRQHandler // 90:USBHS0 Endpoint 1 Out + .word USBHS0_EP1_IN_IRQHandler // 91:USBHS0 Endpoint 1 in + .word USBHS0_WKUP_IRQHandler // 92:USBHS0 Wakeup through EXTI Line + .word USBHS0_IRQHandler // 93:USBHS0 + .word DCI_IRQHandler // 94:DCI + .word CAU_IRQHandler // 95:CAU + .word HAU_TRNG_IRQHandler // 96:HAU and TRNG + .word FPU_IRQHandler // 97:FPU + .word UART6_IRQHandler // 98:UART6 + .word UART7_IRQHandler // 99:UART7 + .word SPI3_IRQHandler // 100:SPI3 + .word SPI4_IRQHandler // 101:SPI4 + .word SPI5_IRQHandler // 102:SPI5 + .word SAI0_IRQHandler // 103:SAI0 + .word TLI_IRQHandler // 104:TLI + .word TLI_ER_IRQHandler // 105:TLI Error + .word IPA_IRQHandler // 106:IPA + .word SAI1_IRQHandler // 107:SAI1 + .word OSPI0_IRQHandler // 108:OSPI0 + .word 0 // Reserved + .word 0 // Reserved + .word I2C3_EV_IRQHandler // 111:I2C3 Event + .word I2C3_ER_IRQHandler // 112:I2C3 Error + .word RSPDIF_IRQHandler // 113:RSPDIF + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word DMAMUX_OVR_IRQHandler // 118:DMAMUX Overrun interrupt + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word HPDF_INT0_IRQHandler // 126:HPDF global interrupt 0 + .word HPDF_INT1_IRQHandler // 127:HPDF global interrupt 1 + .word HPDF_INT2_IRQHandler // 128:HPDF global interrupt 2 + .word HPDF_INT3_IRQHandler // 129:HPDF global interrupt 3 + .word SAI2_IRQHandler // 130:SAI2 global interrupt + .word 0 // Reserved + .word TIMER14_IRQHandler // 132:TIMER14 + .word TIMER15_IRQHandler // 133:TIMER15 + .word TIMER16_IRQHandler // 134:TIMER16 + .word 0 // Reserved + .word MDIO_IRQHandler // 136:MDIO + .word 0 // Reserved + .word MDMA_IRQHandler // 138:MDMA + .word 0 // Reserved + .word SDIO1_IRQHandler // 140:SDIO1 + .word HWSEM_IRQHandler // 141:HWSEM + .word 0 // Reserved + .word ADC2_IRQHandler // 143:ADC2 + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word CMP0_1_IRQHandler // 153:CMP0 and CMP1 + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word CTC_IRQHandler // 160:Clock Recovery System + .word RAMECCMU_IRQHandler // 161:RAMECCMU + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word OSPI1_IRQHandler // 166:OSPI1 + .word RTDEC0_IRQHandler // 167:RTDEC0 + .word RTDEC1_IRQHandler // 168:RTDEC1 + .word FAC_IRQHandler // 169:FAC + .word TMU_IRQHandler // 170:TMU + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word TIMER22_IRQHandler // 177:TIMER22 + .word TIMER23_IRQHandler // 178:TIMER23 + .word TIMER30_IRQHandler // 179:TIMER30 + .word TIMER31_IRQHandler // 180:TIMER31 + .word TIMER40_IRQHandler // 181:TIMER40 + .word TIMER41_IRQHandler // 182:TIMER41 + .word TIMER42_IRQHandler // 183:TIMER42 + .word TIMER43_IRQHandler // 184:TIMER43 + .word TIMER44_IRQHandler // 185:TIMER44 + .word TIMER50_IRQHandler // 186:TIMER50 + .word TIMER51_IRQHandler // 187:TIMER51 + .word USBHS1_EP1_OUT_IRQHandler // 188:USBHS1 endpoint 1 out + .word USBHS1_EP1_IN_IRQHandler // 189:USBHS1 endpoint 1 in + .word USBHS1_WKUP_IRQHandler // 190:USBHS1 wakeup + .word USBHS1_IRQHandler // 191:USBHS1 + .word ENET1_IRQHandler // 192:Ethernet1 + .word ENET1_WKUP_IRQHandler // 193:Ethernet1 wakeup + .word 0 // Reserved + .word CAN0_WKUP_IRQHandler // 195:CAN0 wakeup + .word CAN0_Message_IRQHandler // 196:CAN0 interrupt for message buffer + .word CAN0_Busoff_IRQHandler // 197:CAN0 interrupt for Bus off / Bus off done + .word CAN0_Error_IRQHandler // 198:CAN0 interrupt for Error + .word CAN0_FastError_IRQHandler // 199:CAN0 interrupt for Error in fast transmission + .word CAN0_TEC_IRQHandler // 200:CAN0 interrupt for Transmit warning + .word CAN0_REC_IRQHandler // 201:CAN0 interrupt for Receive warning + .word CAN1_WKUP_IRQHandler // 202:CAN1 wakeup + .word CAN1_Message_IRQHandler // 203:CAN1 interrupt for message buffer + .word CAN1_Busoff_IRQHandler // 204:CAN1 interrupt for Bus off / Bus off done + .word CAN1_Error_IRQHandler // 205:CAN1 interrupt for Error + .word CAN1_FastError_IRQHandler // 206:CAN1 interrupt for Error in fast transmission + .word CAN1_TEC_IRQHandler // 207:CAN1 interrupt for Transmit warning + .word CAN1_REC_IRQHandler // 208:CAN1 interrupt for Receive warning + .word CAN2_WKUP_IRQHandler // 209:CAN2 wakeup + .word CAN2_Message_IRQHandler // 210:CAN2 interrupt for message buffer + .word CAN2_Busoff_IRQHandler // 211:CAN2 interrupt for Bus off / Bus off done + .word CAN2_Error_IRQHandler // 212:CAN2 interrupt for Error + .word CAN2_FastError_IRQHandler // 213:CAN2 interrupt for Error in fast transmission + .word CAN2_TEC_IRQHandler // 214:CAN2 interrupt for Transmit warning + .word CAN2_REC_IRQHandler // 215:CAN2 interrupt for Receive warning + .word EFUSE_IRQHandler // 216:EFUSE + .word I2C0_WKUP_IRQHandler // 217:I2C0 wakeup + .word I2C1_WKUP_IRQHandler // 218:I2C1 wakeup + .word I2C2_WKUP_IRQHandler // 219:I2C2 wakeup + .word I2C3_WKUP_IRQHandler // 220:I2C3 wakeup + .word LPDTS_IRQHandler // 221:LPDTS + .word LPDTS_WKUP_IRQHandler // 222:LPDTS wakeup + .word TIMER0_DEC_IRQHandler // 223:TIMER0 DEC + .word TIMER7_DEC_IRQHandler // 224:TIMER7 DEC + .word TIMER1_DEC_IRQHandler // 225:TIMER1 DEC + .word TIMER2_DEC_IRQHandler // 226:TIMER2 DEC + .word TIMER3_DEC_IRQHandler // 227:TIMER3 DEC + .word TIMER4_DEC_IRQHandler // 228:TIMER4 DEC + .word TIMER22_DEC_IRQHandler // 229:TIMER22 DEC + .word TIMER23_DEC_IRQHandler // 230:TIMER23 DEC + .word TIMER30_DEC_IRQHandler // 231:TIMER30 DEC + .word TIMER31_DEC_IRQHandler // 232:TIMER31 DEC + + .size g_pfnVectors, .-g_pfnVectors + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r1, =_sidata + ldr r2, =_sdata + ldr r3, =_edata + + subs r3, r2 + ble fill_bss_start + +loop_copy_data: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt loop_copy_data + +fill_bss_start: + ldr r1, =__bss_start + ldr r2, =__bss_end + movs r0, 0 + subs r2, r1 + ble startup_enter + +loop_fill_bss: + subs r2, #4 + str r0, [r1, r2] + bgt loop_fill_bss + +startup_enter: + bl SystemInit + bl entry + + /* Exception Handlers */ + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + .weak MemManage_Handler + .type MemManage_Handler, %function +MemManage_Handler: + b . + .size MemManage_Handler, . - MemManage_Handler + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + .size BusFault_Handler, . - BusFault_Handler + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + .size UsageFault_Handler, . - UsageFault_Handler + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + /* IQR Handler */ + .section .text.Default_Handler,"ax",%progbits + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ WWDGT_IRQHandler + IRQ AVD_LVD_OVD_IRQHandler + IRQ TAMPER_STAMP_IRQHandler + IRQ RTC_WKUP_IRQHandler + IRQ FMC_IRQHandler + IRQ RCU_CTC_IRQHandler + IRQ EXTI0_IRQHandler + IRQ EXTI1_IRQHandler + IRQ EXTI2_IRQHandler + IRQ EXTI3_IRQHandler + IRQ EXTI4_IRQHandler + IRQ DMA0_Channel0_IRQHandler + IRQ DMA0_Channel1_IRQHandler + IRQ DMA0_Channel2_IRQHandler + IRQ DMA0_Channel3_IRQHandler + IRQ DMA0_Channel4_IRQHandler + IRQ DMA0_Channel5_IRQHandler + IRQ DMA0_Channel6_IRQHandler + IRQ ADC0_1_IRQHandler + IRQ EXTI5_9_IRQHandler + IRQ TIMER0_BRK_IRQHandler + IRQ TIMER0_UP_IRQHandler + IRQ TIMER0_TRG_CMT_IRQHandler + IRQ TIMER0_Channel_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ TIMER3_IRQHandler + IRQ I2C0_EV_IRQHandler + IRQ I2C0_ER_IRQHandler + IRQ I2C1_EV_IRQHandler + IRQ I2C1_ER_IRQHandler + IRQ SPI0_IRQHandler + IRQ SPI1_IRQHandler + IRQ USART0_IRQHandler + IRQ USART1_IRQHandler + IRQ USART2_IRQHandler + IRQ EXTI10_15_IRQHandler + IRQ RTC_Alarm_IRQHandler + IRQ TIMER7_BRK_IRQHandler + IRQ TIMER7_UP_IRQHandler + IRQ TIMER7_TRG_CMT_IRQHandler + IRQ TIMER7_Channel_IRQHandler + IRQ DMA0_Channel7_IRQHandler + IRQ EXMC_IRQHandler + IRQ SDIO0_IRQHandler + IRQ TIMER4_IRQHandler + IRQ SPI2_IRQHandler + IRQ UART3_IRQHandler + IRQ UART4_IRQHandler + IRQ TIMER5_DAC_UDR_IRQHandler + IRQ TIMER6_IRQHandler + IRQ DMA1_Channel0_IRQHandler + IRQ DMA1_Channel1_IRQHandler + IRQ DMA1_Channel2_IRQHandler + IRQ DMA1_Channel3_IRQHandler + IRQ DMA1_Channel4_IRQHandler + IRQ ENET0_IRQHandler + IRQ ENET0_WKUP_IRQHandler + IRQ DMA1_Channel5_IRQHandler + IRQ DMA1_Channel6_IRQHandler + IRQ DMA1_Channel7_IRQHandler + IRQ USART5_IRQHandler + IRQ I2C2_EV_IRQHandler + IRQ I2C2_ER_IRQHandler + IRQ USBHS0_EP1_OUT_IRQHandler + IRQ USBHS0_EP1_IN_IRQHandler + IRQ USBHS0_WKUP_IRQHandler + IRQ USBHS0_IRQHandler + IRQ DCI_IRQHandler + IRQ CAU_IRQHandler + IRQ HAU_TRNG_IRQHandler + IRQ FPU_IRQHandler + IRQ UART6_IRQHandler + IRQ UART7_IRQHandler + IRQ SPI3_IRQHandler + IRQ SPI4_IRQHandler + IRQ SPI5_IRQHandler + IRQ SAI0_IRQHandler + IRQ TLI_IRQHandler + IRQ TLI_ER_IRQHandler + IRQ IPA_IRQHandler + IRQ SAI1_IRQHandler + IRQ OSPI0_IRQHandler + IRQ I2C3_EV_IRQHandler + IRQ I2C3_ER_IRQHandler + IRQ RSPDIF_IRQHandler + IRQ DMAMUX_OVR_IRQHandler + IRQ HPDF_INT0_IRQHandler + IRQ HPDF_INT1_IRQHandler + IRQ HPDF_INT2_IRQHandler + IRQ HPDF_INT3_IRQHandler + IRQ SAI2_IRQHandler + IRQ TIMER14_IRQHandler + IRQ TIMER15_IRQHandler + IRQ TIMER16_IRQHandler + IRQ MDIO_IRQHandler + IRQ MDMA_IRQHandler + IRQ SDIO1_IRQHandler + IRQ HWSEM_IRQHandler + IRQ ADC2_IRQHandler + IRQ CMP0_1_IRQHandler + IRQ CTC_IRQHandler + IRQ RAMECCMU_IRQHandler + IRQ OSPI1_IRQHandler + IRQ RTDEC0_IRQHandler + IRQ RTDEC1_IRQHandler + IRQ FAC_IRQHandler + IRQ TMU_IRQHandler + IRQ TIMER22_IRQHandler + IRQ TIMER23_IRQHandler + IRQ TIMER30_IRQHandler + IRQ TIMER31_IRQHandler + IRQ TIMER40_IRQHandler + IRQ TIMER41_IRQHandler + IRQ TIMER42_IRQHandler + IRQ TIMER43_IRQHandler + IRQ TIMER44_IRQHandler + IRQ TIMER50_IRQHandler + IRQ TIMER51_IRQHandler + IRQ USBHS1_EP1_OUT_IRQHandler + IRQ USBHS1_EP1_IN_IRQHandler + IRQ USBHS1_WKUP_IRQHandler + IRQ USBHS1_IRQHandler + IRQ ENET1_IRQHandler + IRQ ENET1_WKUP_IRQHandler + IRQ CAN0_WKUP_IRQHandler + IRQ CAN0_Message_IRQHandler + IRQ CAN0_Busoff_IRQHandler + IRQ CAN0_Error_IRQHandler + IRQ CAN0_FastError_IRQHandler + IRQ CAN0_TEC_IRQHandler + IRQ CAN0_REC_IRQHandler + IRQ CAN1_WKUP_IRQHandler + IRQ CAN1_Message_IRQHandler + IRQ CAN1_Busoff_IRQHandler + IRQ CAN1_Error_IRQHandler + IRQ CAN1_FastError_IRQHandler + IRQ CAN1_TEC_IRQHandler + IRQ CAN1_REC_IRQHandler + IRQ CAN2_WKUP_IRQHandler + IRQ CAN2_Message_IRQHandler + IRQ CAN2_Busoff_IRQHandler + IRQ CAN2_Error_IRQHandler + IRQ CAN2_FastError_IRQHandler + IRQ CAN2_TEC_IRQHandler + IRQ CAN2_REC_IRQHandler + IRQ EFUSE_IRQHandler + IRQ I2C0_WKUP_IRQHandler + IRQ I2C1_WKUP_IRQHandler + IRQ I2C2_WKUP_IRQHandler + IRQ I2C3_WKUP_IRQHandler + IRQ LPDTS_IRQHandler + IRQ LPDTS_WKUP_IRQHandler + IRQ TIMER0_DEC_IRQHandler + IRQ TIMER7_DEC_IRQHandler + IRQ TIMER1_DEC_IRQHandler + IRQ TIMER2_DEC_IRQHandler + IRQ TIMER3_DEC_IRQHandler + IRQ TIMER4_DEC_IRQHandler + IRQ TIMER22_DEC_IRQHandler + IRQ TIMER23_DEC_IRQHandler + IRQ TIMER30_DEC_IRQHandler + IRQ TIMER31_DEC_IRQHandler diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/IAR/startup_gd32h7xx.s b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/IAR/startup_gd32h7xx.s new file mode 100644 index 0000000000..a62e0e688f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/IAR/startup_gd32h7xx.s @@ -0,0 +1,1158 @@ +;/*! +; \file startup_gd32h7xx.s +; \brief start up file + +; \version 2024-01-05, V1.2.0, firmware for GD32H7xx +;*/ + +;/* +; * Copyright (c) 2009-2018 Arm Limited. All rights reserved. +; * Copyright (c) 2024, GigaDevice Semiconductor Inc. +; * +; * 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. +; */ + +;/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) ; top of stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD AVD_LVD_OVD_IRQHandler ; 17:AVD/LVD/OVD through EXTI Line detect + DCD TAMPER_STAMP_LXTAL_IRQHandler ; 18:RTC Tamper and TimeStamp through EXTI Line detect, LXTAL clock security system interrupt + DCD RTC_WKUP_IRQHandler ; 19:RTC Wakeup from EXTI interrupt + DCD FMC_IRQHandler ; 20:FMC global interrupt + DCD RCU_IRQHandler ; 21:RCU global interrupt + DCD EXTI0_IRQHandler ; 22:EXTI Line 0 + DCD EXTI1_IRQHandler ; 23:EXTI Line 1 + DCD EXTI2_IRQHandler ; 24:EXTI Line 2 + DCD EXTI3_IRQHandler ; 25:EXTI Line 3 + DCD EXTI4_IRQHandler ; 26:EXTI Line 4 + DCD DMA0_Channel0_IRQHandler ; 27:DMA0 Channel 0 + DCD DMA0_Channel1_IRQHandler ; 28:DMA0 Channel 1 + DCD DMA0_Channel2_IRQHandler ; 29:DMA0 Channel 2 + DCD DMA0_Channel3_IRQHandler ; 30:DMA0 Channel 3 + DCD DMA0_Channel4_IRQHandler ; 31:DMA0 Channel 4 + DCD DMA0_Channel5_IRQHandler ; 32:DMA0 Channel 5 + DCD DMA0_Channel6_IRQHandler ; 33:DMA0 Channel 6 + DCD ADC0_1_IRQHandler ; 34:ADC0 and ADC1 interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD EXTI5_9_IRQHandler ; 39:EXTI5 to EXTI9 + DCD TIMER0_BRK_IRQHandler ; 40:TIMER0 Break + DCD TIMER0_UP_IRQHandler ; 41:TIMER0 Update + DCD TIMER0_TRG_CMT_IRQHandler ; 42:TIMER0 Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 43:TIMER0 Capture Compare + DCD TIMER1_IRQHandler ; 44:TIMER1 + DCD TIMER2_IRQHandler ; 45:TIMER2 + DCD TIMER3_IRQHandler ; 46:TIMER3 + DCD I2C0_EV_IRQHandler ; 47:I2C0 Event + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD I2C1_EV_IRQHandler ; 49:I2C1 Event + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD SPI0_IRQHandler ; 51:SPI0 + DCD SPI1_IRQHandler ; 52:SPI1 + DCD USART0_IRQHandler ; 53:USART0 global and wakeup + DCD USART1_IRQHandler ; 54:USART1 global and wakeup + DCD USART2_IRQHandler ; 55:USART2 global and wakeup + DCD EXTI10_15_IRQHandler ; 56:EXTI10 to EXTI15 + DCD RTC_Alarm_IRQHandler ; 57:RTC Alarm + DCD 0 ; Reserved + DCD TIMER7_BRK_IRQHandler ; 59:TIMER7 Break + DCD TIMER7_UP_IRQHandler ; 60:TIMER7 Update + DCD TIMER7_TRG_CMT_IRQHandler ; 61:TIMER7 Trigger and Commutation + DCD TIMER7_Channel_IRQHandler ; 62:TIMER7 Channel Capture Compare + DCD DMA0_Channel7_IRQHandler ; 63:DMA0 Channel 7 + DCD EXMC_IRQHandler ; 64:EXMC + DCD SDIO0_IRQHandler ; 65:SDIO0 + DCD TIMER4_IRQHandler ; 66:TIMER4 + DCD SPI2_IRQHandler ; 67:SPI2 + DCD UART3_IRQHandler ; 68:UART3 + DCD UART4_IRQHandler ; 69:UART4 + DCD TIMER5_DAC_UDR_IRQHandler ; 70:TIMER5 global interrupt and DAC1/DAC0 underrun error + DCD TIMER6_IRQHandler ; 71:TIMER6 + DCD DMA1_Channel0_IRQHandler ; 72:DMA1 Channel0 + DCD DMA1_Channel1_IRQHandler ; 73:DMA1 Channel1 + DCD DMA1_Channel2_IRQHandler ; 74:DMA1 Channel2 + DCD DMA1_Channel3_IRQHandler ; 75:DMA1 Channel3 + DCD DMA1_Channel4_IRQHandler ; 76:DMA1 Channel4 + DCD ENET0_IRQHandler ; 77:Ethernet0 + DCD ENET0_WKUP_IRQHandler ; 78:Ethernet0 Wakeup through EXTI Line + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DMA1_Channel5_IRQHandler ; 84:DMA1 Channel5 + DCD DMA1_Channel6_IRQHandler ; 85:DMA1 Channel6 + DCD DMA1_Channel7_IRQHandler ; 86:DMA1 Channel7 + DCD USART5_IRQHandler ; 87:USART5 global and wakeup + DCD I2C2_EV_IRQHandler ; 88:I2C2 Event + DCD I2C2_ER_IRQHandler ; 89:I2C2 Error + DCD USBHS0_EP1_OUT_IRQHandler ; 90:USBHS0 Endpoint 1 Out + DCD USBHS0_EP1_IN_IRQHandler ; 91:USBHS0 Endpoint 1 in + DCD USBHS0_WKUP_IRQHandler ; 92:USBHS0 Wakeup through EXTI Line + DCD USBHS0_IRQHandler ; 93:USBHS0 + DCD DCI_IRQHandler ; 94:DCI + DCD CAU_IRQHandler ; 95:CAU + DCD HAU_TRNG_IRQHandler ; 96:HAU and TRNG + DCD FPU_IRQHandler ; 97:FPU + DCD UART6_IRQHandler ; 98:UART6 + DCD UART7_IRQHandler ; 99:UART7 + DCD SPI3_IRQHandler ; 100:SPI3 + DCD SPI4_IRQHandler ; 101:SPI4 + DCD SPI5_IRQHandler ; 102:SPI5 + DCD SAI0_IRQHandler ; 103:SAI0 + DCD TLI_IRQHandler ; 104:TLI + DCD TLI_ER_IRQHandler ; 105:TLI Error + DCD IPA_IRQHandler ; 106:IPA + DCD SAI1_IRQHandler ; 107:SAI1 + DCD OSPI0_IRQHandler ; 108:OSPI0 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C3_EV_IRQHandler ; 111:I2C3 Event + DCD I2C3_ER_IRQHandler ; 112:I2C3 Error + DCD RSPDIF_IRQHandler ; 113:RSPDIF + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DMAMUX_OVR_IRQHandler ; 118:DMAMUX Overrun interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HPDF_INT0_IRQHandler ; 126:HPDF global interrupt 0 + DCD HPDF_INT1_IRQHandler ; 127:HPDF global interrupt 1 + DCD HPDF_INT2_IRQHandler ; 128:HPDF global interrupt 2 + DCD HPDF_INT3_IRQHandler ; 129:HPDF global interrupt 3 + DCD SAI2_IRQHandler ; 130:SAI2 global interrupt + DCD 0 ; Reserved + DCD TIMER14_IRQHandler ; 132:TIMER14 + DCD TIMER15_IRQHandler ; 133:TIMER15 + DCD TIMER16_IRQHandler ; 134:TIMER16 + DCD 0 ; Reserved + DCD MDIO_IRQHandler ; 136:MDIO + DCD 0 ; Reserved + DCD MDMA_IRQHandler ; 138:MDMA + DCD 0 ; Reserved + DCD SDIO1_IRQHandler ; 140:SDIO1 + DCD HWSEM_IRQHandler ; 141:HWSEM + DCD 0 ; Reserved + DCD ADC2_IRQHandler ; 143:ADC2 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CMP0_1_IRQHandler ; 153:CMP0 and CMP1 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CTC_IRQHandler ; 160:Clock Recovery System + DCD RAMECCMU_IRQHandler ; 161:RAMECCMU + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD OSPI1_IRQHandler ; 166:OSPI1 + DCD RTDEC0_IRQHandler ; 167:RTDEC0 + DCD RTDEC1_IRQHandler ; 168:RTDEC1 + DCD FAC_IRQHandler ; 169:FAC + DCD TMU_IRQHandler ; 170:TMU + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TIMER22_IRQHandler ; 177:TIMER22 + DCD TIMER23_IRQHandler ; 178:TIMER23 + DCD TIMER30_IRQHandler ; 179:TIMER30 + DCD TIMER31_IRQHandler ; 180:TIMER31 + DCD TIMER40_IRQHandler ; 181:TIMER40 + DCD TIMER41_IRQHandler ; 182:TIMER41 + DCD TIMER42_IRQHandler ; 183:TIMER42 + DCD TIMER43_IRQHandler ; 184:TIMER43 + DCD TIMER44_IRQHandler ; 185:TIMER44 + DCD TIMER50_IRQHandler ; 186:TIMER50 + DCD TIMER51_IRQHandler ; 187:TIMER51 + DCD USBHS1_EP1_OUT_IRQHandler ; 188:USBHS1 endpoint 1 out + DCD USBHS1_EP1_IN_IRQHandler ; 189:USBHS1 endpoint 1 in + DCD USBHS1_WKUP_IRQHandler ; 190:USBHS1 wakeup + DCD USBHS1_IRQHandler ; 191:USBHS1 + DCD ENET1_IRQHandler ; 192:Ethernet1 + DCD ENET1_WKUP_IRQHandler ; 193:Ethernet1 wakeup + DCD 0 ; Reserved + DCD CAN0_WKUP_IRQHandler ; 195:CAN0 wakeup + DCD CAN0_Message_IRQHandler ; 196:CAN0 interrupt for message buffer + DCD CAN0_Busoff_IRQHandler ; 197:CAN0 interrupt for Bus off / Bus off done + DCD CAN0_Error_IRQHandler ; 198:CAN0 interrupt for Error + DCD CAN0_FastError_IRQHandler ; 199:CAN0 interrupt for Error in fast transmission + DCD CAN0_TEC_IRQHandler ; 200:CAN0 interrupt for Transmit warning + DCD CAN0_REC_IRQHandler ; 201:CAN0 interrupt for Receive warning + DCD CAN1_WKUP_IRQHandler ; 202:CAN1 wakeup + DCD CAN1_Message_IRQHandler ; 203:CAN1 interrupt for message buffer + DCD CAN1_Busoff_IRQHandler ; 204:CAN1 interrupt for Bus off / Bus off done + DCD CAN1_Error_IRQHandler ; 205:CAN1 interrupt for Error + DCD CAN1_FastError_IRQHandler ; 206:CAN1 interrupt for Error in fast transmission + DCD CAN1_TEC_IRQHandler ; 207:CAN1 interrupt for Transmit warning + DCD CAN1_REC_IRQHandler ; 208:CAN1 interrupt for Receive warning + DCD CAN2_WKUP_IRQHandler ; 209:CAN2 wakeup + DCD CAN2_Message_IRQHandler ; 210:CAN2 interrupt for message buffer + DCD CAN2_Busoff_IRQHandler ; 211:CAN2 interrupt for Bus off / Bus off done + DCD CAN2_Error_IRQHandler ; 212:CAN2 interrupt for Error + DCD CAN2_FastError_IRQHandler ; 213:CAN2 interrupt for Error in fast transmission + DCD CAN2_TEC_IRQHandler ; 214:CAN2 interrupt for Transmit warning + DCD CAN2_REC_IRQHandler ; 215:CAN2 interrupt for Receive warning + DCD EFUSE_IRQHandler ; 216:EFUSE + DCD I2C0_WKUP_IRQHandler ; 217:I2C0 wakeup + DCD I2C1_WKUP_IRQHandler ; 218:I2C1 wakeup + DCD I2C2_WKUP_IRQHandler ; 219:I2C2 wakeup + DCD I2C3_WKUP_IRQHandler ; 220:I2C3 wakeup + DCD LPDTS_IRQHandler ; 221:LPDTS + DCD LPDTS_WKUP_IRQHandler ; 222:LPDTS wakeup + DCD TIMER0_DEC_IRQHandler ; 223:TIMER0 DEC + DCD TIMER7_DEC_IRQHandler ; 224:TIMER7 DEC + DCD TIMER1_DEC_IRQHandler ; 225:TIMER1 DEC + DCD TIMER2_DEC_IRQHandler ; 226:TIMER2 DEC + DCD TIMER3_DEC_IRQHandler ; 227:TIMER3 DEC + DCD TIMER4_DEC_IRQHandler ; 228:TIMER4 DEC + DCD TIMER22_DEC_IRQHandler ; 229:TIMER22 DEC + DCD TIMER23_DEC_IRQHandler ; 230:TIMER23 DEC + DCD TIMER30_DEC_IRQHandler ; 231:TIMER30 DEC + DCD TIMER31_DEC_IRQHandler ; 232:TIMER31 DEC +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + + LDR R0, = 0x24000000 + ADD R1, R0, #0x8000 + LDR R2, =0x0 +MEM_INIT STRD R2, R2, [ R0 ] , #8 + CMP R0, R1 + BNE MEM_INIT + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDGT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDGT_IRQHandler + B WWDGT_IRQHandler + + PUBWEAK AVD_LVD_OVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AVD_LVD_OVD_IRQHandler + B AVD_LVD_OVD_IRQHandler + + PUBWEAK TAMPER_STAMP_LXTAL_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMPER_STAMP_LXTAL_IRQHandler + B TAMPER_STAMP_LXTAL_IRQHandler + + PUBWEAK RTC_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_WKUP_IRQHandler + B RTC_WKUP_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK RCU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCU_IRQHandler + B RCU_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK DMA0_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel0_IRQHandler + B DMA0_Channel0_IRQHandler + + PUBWEAK DMA0_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel1_IRQHandler + B DMA0_Channel1_IRQHandler + + PUBWEAK DMA0_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel2_IRQHandler + B DMA0_Channel2_IRQHandler + + PUBWEAK DMA0_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel3_IRQHandler + B DMA0_Channel3_IRQHandler + + PUBWEAK DMA0_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel4_IRQHandler + B DMA0_Channel4_IRQHandler + + PUBWEAK DMA0_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel5_IRQHandler + B DMA0_Channel5_IRQHandler + + PUBWEAK DMA0_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel6_IRQHandler + B DMA0_Channel6_IRQHandler + + PUBWEAK ADC0_1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC0_1_IRQHandler + B ADC0_1_IRQHandler + + PUBWEAK EXTI5_9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_9_IRQHandler + B EXTI5_9_IRQHandler + + PUBWEAK TIMER0_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_BRK_IRQHandler + B TIMER0_BRK_IRQHandler + + PUBWEAK TIMER0_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_UP_IRQHandler + B TIMER0_UP_IRQHandler + + PUBWEAK TIMER0_TRG_CMT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_TRG_CMT_IRQHandler + B TIMER0_TRG_CMT_IRQHandler + + PUBWEAK TIMER0_Channel_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_Channel_IRQHandler + B TIMER0_Channel_IRQHandler + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER1_IRQHandler + B TIMER1_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER3_IRQHandler + B TIMER3_IRQHandler + + PUBWEAK I2C0_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_EV_IRQHandler + B I2C0_EV_IRQHandler + + PUBWEAK I2C0_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_ER_IRQHandler + B I2C0_ER_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK SPI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI0_IRQHandler + B SPI0_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK USART0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART0_IRQHandler + B USART0_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK EXTI10_15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_15_IRQHandler + B EXTI10_15_IRQHandler + + PUBWEAK RTC_Alarm_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Alarm_IRQHandler + B RTC_Alarm_IRQHandler + + PUBWEAK TIMER7_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_BRK_IRQHandler + B TIMER7_BRK_IRQHandler + + PUBWEAK TIMER7_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_UP_IRQHandler + B TIMER7_UP_IRQHandler + + PUBWEAK TIMER7_TRG_CMT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_TRG_CMT_IRQHandler + B TIMER7_TRG_CMT_IRQHandler + + PUBWEAK TIMER7_Channel_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_Channel_IRQHandler + B TIMER7_Channel_IRQHandler + + PUBWEAK DMA0_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel7_IRQHandler + B DMA0_Channel7_IRQHandler + + PUBWEAK EXMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXMC_IRQHandler + B EXMC_IRQHandler + + PUBWEAK SDIO0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDIO0_IRQHandler + B SDIO0_IRQHandler + + PUBWEAK TIMER4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER4_IRQHandler + B TIMER4_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK UART3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART3_IRQHandler + B UART3_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK TIMER5_DAC_UDR_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER5_DAC_UDR_IRQHandler + B TIMER5_DAC_UDR_IRQHandler + + PUBWEAK TIMER6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER6_IRQHandler + B TIMER6_IRQHandler + + PUBWEAK DMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel0_IRQHandler + B DMA1_Channel0_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel2_IRQHandler + B DMA1_Channel2_IRQHandler + + PUBWEAK DMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel3_IRQHandler + B DMA1_Channel3_IRQHandler + + PUBWEAK DMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel4_IRQHandler + B DMA1_Channel4_IRQHandler + + PUBWEAK ENET0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET0_IRQHandler + B ENET0_IRQHandler + + PUBWEAK ENET0_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET0_WKUP_IRQHandler + B ENET0_WKUP_IRQHandler + + PUBWEAK DMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel5_IRQHandler + B DMA1_Channel5_IRQHandler + + PUBWEAK DMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel6_IRQHandler + B DMA1_Channel6_IRQHandler + + PUBWEAK DMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel7_IRQHandler + B DMA1_Channel7_IRQHandler + + PUBWEAK USART5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART5_IRQHandler + B USART5_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK USBHS0_EP1_OUT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS0_EP1_OUT_IRQHandler + B USBHS0_EP1_OUT_IRQHandler + + PUBWEAK USBHS0_EP1_IN_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS0_EP1_IN_IRQHandler + B USBHS0_EP1_IN_IRQHandler + + PUBWEAK USBHS0_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS0_WKUP_IRQHandler + B USBHS0_WKUP_IRQHandler + + PUBWEAK USBHS0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS0_IRQHandler + B USBHS0_IRQHandler + + PUBWEAK DCI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCI_IRQHandler + B DCI_IRQHandler + + PUBWEAK CAU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAU_IRQHandler + B CAU_IRQHandler + + PUBWEAK HAU_TRNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HAU_TRNG_IRQHandler + B HAU_TRNG_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK UART6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART6_IRQHandler + B UART6_IRQHandler + + PUBWEAK UART7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART7_IRQHandler + B UART7_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK SPI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI4_IRQHandler + B SPI4_IRQHandler + + PUBWEAK SPI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI5_IRQHandler + B SPI5_IRQHandler + + PUBWEAK SAI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI0_IRQHandler + B SAI0_IRQHandler + + PUBWEAK TLI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TLI_IRQHandler + B TLI_IRQHandler + + PUBWEAK TLI_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TLI_ER_IRQHandler + B TLI_ER_IRQHandler + + PUBWEAK IPA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPA_IRQHandler + B IPA_IRQHandler + + PUBWEAK SAI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI1_IRQHandler + B SAI1_IRQHandler + + PUBWEAK OSPI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OSPI0_IRQHandler + B OSPI0_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK RSPDIF_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RSPDIF_IRQHandler + B RSPDIF_IRQHandler + + PUBWEAK DMAMUX_OVR_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMAMUX_OVR_IRQHandler + B DMAMUX_OVR_IRQHandler + + PUBWEAK HPDF_INT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDF_INT0_IRQHandler + B HPDF_INT0_IRQHandler + + PUBWEAK HPDF_INT1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDF_INT1_IRQHandler + B HPDF_INT1_IRQHandler + + PUBWEAK HPDF_INT2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDF_INT2_IRQHandler + B HPDF_INT2_IRQHandler + + PUBWEAK HPDF_INT3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HPDF_INT3_IRQHandler + B HPDF_INT3_IRQHandler + + PUBWEAK SAI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI2_IRQHandler + B SAI2_IRQHandler + + PUBWEAK TIMER14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER14_IRQHandler + B TIMER14_IRQHandler + + PUBWEAK TIMER15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER15_IRQHandler + B TIMER15_IRQHandler + + PUBWEAK TIMER16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER16_IRQHandler + B TIMER16_IRQHandler + + PUBWEAK MDIO_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +MDIO_IRQHandler + B MDIO_IRQHandler + + PUBWEAK MDMA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +MDMA_IRQHandler + B MDMA_IRQHandler + + PUBWEAK SDIO1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDIO1_IRQHandler + B SDIO1_IRQHandler + + PUBWEAK HWSEM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HWSEM_IRQHandler + B HWSEM_IRQHandler + + PUBWEAK ADC2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC2_IRQHandler + B ADC2_IRQHandler + + PUBWEAK CMP0_1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CMP0_1_IRQHandler + B CMP0_1_IRQHandler + + PUBWEAK CTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CTC_IRQHandler + B CTC_IRQHandler + + PUBWEAK RAMECCMU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RAMECCMU_IRQHandler + B RAMECCMU_IRQHandler + + PUBWEAK OSPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OSPI1_IRQHandler + B OSPI1_IRQHandler + + PUBWEAK RTDEC0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTDEC0_IRQHandler + B RTDEC0_IRQHandler + + PUBWEAK RTDEC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTDEC1_IRQHandler + B RTDEC1_IRQHandler + + PUBWEAK FAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FAC_IRQHandler + B FAC_IRQHandler + + PUBWEAK TMU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TMU_IRQHandler + B TMU_IRQHandler + + PUBWEAK TIMER22_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER22_IRQHandler + B TIMER22_IRQHandler + + PUBWEAK TIMER23_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER23_IRQHandler + B TIMER23_IRQHandler + + PUBWEAK TIMER30_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER30_IRQHandler + B TIMER30_IRQHandler + + PUBWEAK TIMER31_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER31_IRQHandler + B TIMER31_IRQHandler + + PUBWEAK TIMER40_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER40_IRQHandler + B TIMER40_IRQHandler + + PUBWEAK TIMER41_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER41_IRQHandler + B TIMER41_IRQHandler + + PUBWEAK TIMER42_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER42_IRQHandler + B TIMER42_IRQHandler + + PUBWEAK TIMER43_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER43_IRQHandler + B TIMER43_IRQHandler + + PUBWEAK TIMER44_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER44_IRQHandler + B TIMER44_IRQHandler + + PUBWEAK TIMER50_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER50_IRQHandler + B TIMER50_IRQHandler + + PUBWEAK TIMER51_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER51_IRQHandler + B TIMER51_IRQHandler + + PUBWEAK USBHS1_EP1_OUT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS1_EP1_OUT_IRQHandler + B USBHS1_EP1_OUT_IRQHandler + + PUBWEAK USBHS1_EP1_IN_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS1_EP1_IN_IRQHandler + B USBHS1_EP1_IN_IRQHandler + + PUBWEAK USBHS1_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS1_WKUP_IRQHandler + B USBHS1_WKUP_IRQHandler + + PUBWEAK USBHS1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS1_IRQHandler + B USBHS1_IRQHandler + + PUBWEAK ENET1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET1_IRQHandler + B ENET1_IRQHandler + + PUBWEAK ENET1_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET1_WKUP_IRQHandler + B ENET1_WKUP_IRQHandler + + PUBWEAK CAN0_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_WKUP_IRQHandler + B CAN0_WKUP_IRQHandler + + PUBWEAK CAN0_Message_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_Message_IRQHandler + B CAN0_Message_IRQHandler + + PUBWEAK CAN0_Busoff_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_Busoff_IRQHandler + B CAN0_Busoff_IRQHandler + + PUBWEAK CAN0_Error_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_Error_IRQHandler + B CAN0_Error_IRQHandler + + PUBWEAK CAN0_FastError_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_FastError_IRQHandler + B CAN0_FastError_IRQHandler + + PUBWEAK CAN0_TEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_TEC_IRQHandler + B CAN0_TEC_IRQHandler + + PUBWEAK CAN0_REC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_REC_IRQHandler + B CAN0_REC_IRQHandler + + PUBWEAK CAN1_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_WKUP_IRQHandler + B CAN1_WKUP_IRQHandler + + PUBWEAK CAN1_Message_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_Message_IRQHandler + B CAN1_Message_IRQHandler + + PUBWEAK CAN1_Busoff_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_Busoff_IRQHandler + B CAN1_Busoff_IRQHandler + + PUBWEAK CAN1_Error_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_Error_IRQHandler + B CAN1_Error_IRQHandler + + PUBWEAK CAN1_FastError_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_FastError_IRQHandler + B CAN1_FastError_IRQHandler + + PUBWEAK CAN1_TEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_TEC_IRQHandler + B CAN1_TEC_IRQHandler + + PUBWEAK CAN1_REC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_REC_IRQHandler + B CAN1_REC_IRQHandler + + PUBWEAK CAN2_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_WKUP_IRQHandler + B CAN2_WKUP_IRQHandler + + PUBWEAK CAN2_Message_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_Message_IRQHandler + B CAN2_Message_IRQHandler + + PUBWEAK CAN2_Busoff_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_Busoff_IRQHandler + B CAN2_Busoff_IRQHandler + + PUBWEAK CAN2_Error_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_Error_IRQHandler + B CAN2_Error_IRQHandler + + PUBWEAK CAN2_FastError_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_FastError_IRQHandler + B CAN2_FastError_IRQHandler + + PUBWEAK CAN2_TEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_TEC_IRQHandler + B CAN2_TEC_IRQHandler + + PUBWEAK CAN2_REC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN2_REC_IRQHandler + B CAN2_REC_IRQHandler + + PUBWEAK EFUSE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EFUSE_IRQHandler + B EFUSE_IRQHandler + + PUBWEAK I2C0_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_WKUP_IRQHandler + B I2C0_WKUP_IRQHandler + + PUBWEAK I2C1_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_WKUP_IRQHandler + B I2C1_WKUP_IRQHandler + + PUBWEAK I2C2_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_WKUP_IRQHandler + B I2C2_WKUP_IRQHandler + + PUBWEAK I2C3_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_WKUP_IRQHandler + B I2C3_WKUP_IRQHandler + + PUBWEAK LPDTS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPDTS_IRQHandler + B LPDTS_IRQHandler + + PUBWEAK LPDTS_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPDTS_WKUP_IRQHandler + B LPDTS_WKUP_IRQHandler + + PUBWEAK TIMER0_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_DEC_IRQHandler + B TIMER0_DEC_IRQHandler + + PUBWEAK TIMER7_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_DEC_IRQHandler + B TIMER7_DEC_IRQHandler + + PUBWEAK TIMER1_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER1_DEC_IRQHandler + B TIMER1_DEC_IRQHandler + + PUBWEAK TIMER2_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER2_DEC_IRQHandler + B TIMER2_DEC_IRQHandler + + PUBWEAK TIMER3_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER3_DEC_IRQHandler + B TIMER3_DEC_IRQHandler + + PUBWEAK TIMER4_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER4_DEC_IRQHandler + B TIMER4_DEC_IRQHandler + + PUBWEAK TIMER22_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER22_DEC_IRQHandler + B TIMER22_DEC_IRQHandler + + PUBWEAK TIMER23_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER23_DEC_IRQHandler + B TIMER23_DEC_IRQHandler + + PUBWEAK TIMER30_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER30_DEC_IRQHandler + B TIMER30_DEC_IRQHandler + + PUBWEAK TIMER31_DEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER31_DEC_IRQHandler + B TIMER31_DEC_IRQHandler + + END diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/system_gd32h7xx.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/system_gd32h7xx.c new file mode 100644 index 0000000000..719733e6fa --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/GD/GD32H7xx/Source/system_gd32h7xx.c @@ -0,0 +1,716 @@ +/*! + \file system_gd32h7xx.c + \brief CMSIS Cortex-M7 Device Peripheral Access Layer Source File for + gd32h7xx Device Series +*/ + +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * Copyright (c) 2024, GigaDevice Semiconductor Inc. + * + * 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. + */ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#include "gd32h7xx.h" + +/* system frequency define */ +#define __IRC64M (IRC64M_VALUE) /* internal 64 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __LPIRC4M (LPIRC4M_VALUE) /* low power internal 4 MHz RC oscillator frequency */ +#define __SYS_OSC_CLK (__IRC64M) /* main oscillator frequency */ + +#define VECT_TAB_OFFSET (uint32_t)0x00 /* vector table base offset */ +#define RCU_APB4EN_SYSCFG (uint32_t)0x01 /* enable SYSCFG clk */ + +/* select a system clock by uncommenting the following line */ +/* use IRC64M */ +//#define __SYSTEM_CLOCK_IRC64M (__IRC64M) +//#define __SYSTEM_CLOCK_600M_PLL0_IRC64M (uint32_t)(600000000) + +/* use LPIRC4M */ +//#define __SYSTEM_CLOCK_LPIRC4M (__LPIRC4M) + +/* use HXTAL(CK_HXTAL = 25M) */ +//#define __SYSTEM_CLOCK_HXTAL (__HXTAL) +//#define __SYSTEM_CLOCK_200M_PLL0_HXTAL (uint32_t)(200000000) +//#define __SYSTEM_CLOCK_400M_PLL0_HXTAL (uint32_t)(400000000) +#define __SYSTEM_CLOCK_600M_PLL0_HXTAL (uint32_t)(600000000) + +/* +Note: the power mode need to match the mcu selection and external power supply circuit. + for iar project: + for 100-pin mcu, need to define macro GD32H7XXV. + for 144-pin mcu, need to define macro GD32H7XXZ. + for 176-pin mcu, need to define macro GD32H7XXI. + for keil project: + do not need to define these macros extra. + + according to the selected mcu and external power supply circuit to uncomment +the following macro SEL_PMU_SMPS_MODE. +*/ +#if defined(GD32H7XXI) +//#define SEL_PMU_SMPS_MODE PMU_LDO_SUPPLY +//#define SEL_PMU_SMPS_MODE PMU_DIRECT_SMPS_SUPPLY +//#define SEL_PMU_SMPS_MODE PMU_SMPS_1V8_SUPPLIES_LDO +//#define SEL_PMU_SMPS_MODE PMU_SMPS_2V5_SUPPLIES_LDO +//#define SEL_PMU_SMPS_MODE PMU_SMPS_1V8_SUPPLIES_EXT_AND_LDO +//#define SEL_PMU_SMPS_MODE PMU_SMPS_2V5_SUPPLIES_EXT_AND_LDO +//#define SEL_PMU_SMPS_MODE PMU_SMPS_1V8_SUPPLIES_EXT +//#define SEL_PMU_SMPS_MODE PMU_SMPS_2V5_SUPPLIES_EXT +#define SEL_PMU_SMPS_MODE PMU_BYPASS +#elif defined(GD32H7XXZ) | defined(GD32H7XXV) +//#define SEL_PMU_SMPS_MODE PMU_LDO_SUPPLY +//#define SEL_PMU_SMPS_MODE PMU_BYPASS +#endif + +#define SEL_IRC64MDIV 0x00U +#define SEL_HXTAL 0x01U +#define SEL_LPIRC4M 0x02U +#define SEL_PLL0P 0x03U + +#define PLL0PSC_REG_OFFSET 0U +#define PLL0N_REG_OFFSET 6U +#define PLL0P_REG_OFFSET 16U +#define PLL0Q_REG_OFFSET 0U +#define PLL0R_REG_OFFSET 24U + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_IRC64M +uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC64M; +static void system_clock_64m_irc64m(void); +#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M) +#define PLL0PSC 16U +#define PLL0N (150U - 1U) +#define PLL0P (1U - 1U) +#define PLL0Q (2U - 1U) +#define PLL0R (2U - 1U) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_IRC64M; +static void system_clock_600m_irc64m(void); + +#elif defined (__SYSTEM_CLOCK_LPIRC4M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_LPIRC4M; +static void system_clock_4m_lpirc4m(void); + +#elif defined (__SYSTEM_CLOCK_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL; +static void system_clock_hxtal(void); +#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL) +#define PLL0PSC 5U +#define PLL0N (40U - 1U) +#define PLL0P (1U - 1U) +#define PLL0Q (2U - 1U) +#define PLL0R (2U - 1U) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL0_HXTAL; +static void system_clock_200m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL) +#define PLL0PSC 5U +#define PLL0N (80U - 1U) +#define PLL0P (1U - 1U) +#define PLL0Q (2U - 1U) +#define PLL0R (2U - 1U) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_400M_PLL0_HXTAL; +static void system_clock_400m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL) +#define PLL0PSC 5U +#define PLL0N (120U - 1U) +#define PLL0P (1U - 1U) +#define PLL0Q (2U - 1U) +#define PLL0R (2U - 1U) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_HXTAL; +static void system_clock_600m_hxtal(void); +#endif /* __SYSTEM_CLOCK_IRC64M */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief setup the microcontroller system, initialize the system + \param[in] none + \param[out] none + \retval none +*/ +void SystemInit(void) +{ + /* FPU settings */ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1U) + /* set CP10 and CP11 Full Access */ + SCB->CPACR |= (uint32_t)((0x03U << 10U * 2U) | (0x03U << 11U * 2U)); +#endif + + /* enable IRC64M */ + RCU_CTL |= RCU_CTL_IRC64MEN; + while(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) { + } + + /* no TCM wait state */ + RCU_APB4EN |= RCU_APB4EN_SYSCFG; + SYSCFG_SRAMCFG1 &= ~SYSCFG_SRAMCFG1_TCM_WAITSTATE; + + RCU_CFG0 &= ~RCU_CFG0_SCS; + + /* reset RCU */ + /* reset HXTALEN, CKMEN, PLL0EN, PLL1EN, PLL2EN, PLLUSB0 and PLLUSB1 bits */ + RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLL0EN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_HXTALBPS); + RCU_ADDCTL1 &= ~(RCU_ADDCTL1_PLLUSBHS0EN | RCU_ADDCTL1_PLLUSBHS1EN | RCU_ADDCTL1_LPIRC4MEN); + /* reset CFG0, CFG1, CFG2, CFG3 registers */ + RCU_CFG0 &= ~(RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_APB3PSC | RCU_CFG0_APB4PSC | RCU_CFG0_AHBPSC | + RCU_CFG0_I2C0SEL | RCU_CFG0_SCS | RCU_CFG0_RTCDIV); + RCU_CFG1 &= ~(RCU_CFG1_HPDFSEL | RCU_CFG1_TIMERSEL | RCU_CFG1_PERSEL | + RCU_CFG1_RSPDIFSEL | RCU_CFG1_USART0SEL | RCU_CFG1_USART1SEL | RCU_CFG1_USART2SEL | RCU_CFG1_USART5SEL | RCU_CFG1_PLL2RDIV); + RCU_CFG2 &= ~(RCU_CFG2_SAI2B1SEL | RCU_CFG2_SAI2B0SEL | RCU_CFG2_SAI1SEL | RCU_CFG2_SAI0SEL | + RCU_CFG2_CKOUT0SEL | RCU_CFG2_CKOUT1SEL | RCU_CFG2_CKOUT0DIV | RCU_CFG2_CKOUT1DIV); + RCU_CFG3 &= ~(RCU_CFG3_ADC01SEL | RCU_CFG3_ADC2SEL | RCU_CFG3_SDIO1SEL + | RCU_CFG3_I2C3SEL | RCU_CFG3_I2C2SEL | RCU_CFG3_I2C1SEL); + RCU_CFG4 &= ~(RCU_CFG4_EXMCSEL | RCU_CFG4_SDIO0SEL); + RCU_CFG5 &= ~(RCU_CFG5_SPI0SEL | RCU_CFG5_SPI1SEL | RCU_CFG5_SPI2SEL | + RCU_CFG5_SPI3SEL | RCU_CFG5_SPI4SEL | RCU_CFG5_SPI5SEL); + /* disable all interrupts */ + RCU_INT = 0x14FF0000U; + RCU_ADDINT = 0x00700000U; + /* reset all PLL0 parameter */ + RCU_PLL0 = 0x01002020U; + RCU_PLL1 = 0x01012020U; + RCU_PLL2 = 0x01012020U; + RCU_PLLALL = 0x00000000U; + RCU_PLLADDCTL = 0x00010101U; + RCU_PLLUSBCFG = 0x00000000U; + RCU_PLL0FRA = 0x00000000U; + RCU_PLL1FRA = 0x00000000U; + RCU_PLL2FRA = 0x00000000U; + +#if defined (SEL_PMU_SMPS_MODE) + /* power supply config */ + pmu_smps_ldo_supply_config(SEL_PMU_SMPS_MODE); +#endif + + /* configure system clock */ + system_clock_config(); + +#ifdef VECT_TAB_SRAM + nvic_vector_table_set(NVIC_VECTTAB_RAM, VECT_TAB_OFFSET); +#else + nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET); +#endif +} + +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_IRC64M + system_clock_64m_irc64m(); +#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M) + system_clock_600m_irc64m(); + +#elif defined (__SYSTEM_CLOCK_LPIRC4M) + system_clock_4m_lpirc4m(); + +#elif defined (__SYSTEM_CLOCK_HXTAL) + system_clock_hxtal(); +#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL) + system_clock_200m_hxtal(); +#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL) + system_clock_400m_hxtal(); +#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL) + system_clock_600m_hxtal(); +#endif /* __SYSTEM_CLOCK_IRC64M */ +} + +#ifdef __SYSTEM_CLOCK_IRC64M +/*! + \brief configure the system clock to 64M by IRC64M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_64m_irc64m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC64M */ + RCU_CTL |= RCU_CTL_IRC64MEN; + + /* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB); + } while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) { + while(1) { + } + } + + /* AHB = SYSCLK / 1 */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB4 = AHB / 1 */ + RCU_CFG0 |= RCU_APB4_CKAHB_DIV1; + /* APB3 = AHB / 1 */ + RCU_CFG0 |= RCU_APB3_CKAHB_DIV1; + /* APB2 = AHB / 1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB / 1 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* configure IRC64M div */ + RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV); + RCU_ADDCTL1 |= RCU_IRC64M_DIV1; + + /* select IRC64M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC64MDIV; + + /* wait until IRC64M is selected as system clock */ + while(RCU_SCSS_IRC64MDIV != (RCU_CFG0 & RCU_CFG0_SCSS)) { + } +} + +#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M) +/*! + \brief configure the system clock to 600M by PLL0 which selects IRC64M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_600m_irc64m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC64M */ + RCU_CTL |= RCU_CTL_IRC64MEN; + + /* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB); + } while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) { + while(1) { + } + } + + /* insert TCM wait state at 600MHz */ + RCU_APB4EN |= RCU_APB4EN_SYSCFG; + SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; + + /* IRC64M is already stable */ + /* AHB = SYSCLK / 2 */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; + /* APB4 = AHB / 2 */ + RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; + /* APB3 = AHB / 2 */ + RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; + /* APB2 = AHB / 1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB / 2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* PLL0 select IRC64MDIV, config IRC64MDIV as IRC64M, PLL0 input and output range */ + RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV); + RCU_ADDCTL1 |= RCU_IRC64M_DIV1; + RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); + RCU_PLLALL |= (RCU_PLLSRC_IRC64MDIV | RCU_PLL0RNG_4M_8M); + + /* PLL0P = IRC64MDIV / 16 * 150 / 1 = 600 MHz */ + RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); + RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); + RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); + RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); + + /* enable PLL0P, PLL0Q, PLL0R */ + RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; + + /* enable PLL0 */ + RCU_CTL |= RCU_CTL_PLL0EN; + + /* wait until PLL0 is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { + } + + /* select PLL0 as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; + + /* wait until PLL0 is selected as system clock */ + while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { + } +} + +#elif defined (__SYSTEM_CLOCK_LPIRC4M) +/*! + \brief configure the system clock to LPIRC4M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_4m_lpirc4m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable LPIRC4M */ + RCU_ADDCTL1 |= RCU_ADDCTL1_LPIRC4MEN; + + /* wait until LPIRC4M is stable or the startup time is longer than LPIRC4M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB); + } while((0U == stab_flag) && (LPIRC4M_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB)) { + while(1) { + } + } + + /* LPIRC4M is stable */ + /* AHB = SYSCLK / 1*/ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB4 = AHB / 1 */ + RCU_CFG0 |= RCU_APB4_CKAHB_DIV1; + /* APB3 = AHB / 1 */ + RCU_CFG0 |= RCU_APB3_CKAHB_DIV1; + /* APB2 = AHB / 1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB / 1 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select LPIRC4M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_LPIRC4M; + + /* wait until LPIRC4M is selected as system clock */ + while(RCU_SCSS_LPIRC4M != (RCU_CFG0 & RCU_CFG0_SCSS)) { + } +} + +#elif defined (__SYSTEM_CLOCK_HXTAL) +/*! + \brief configure the system clock to HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK / 1*/ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB4 = AHB / 1 */ + RCU_CFG0 |= RCU_APB4_CKAHB_DIV1; + /* APB3 = AHB / 1 */ + RCU_CFG0 |= RCU_APB3_CKAHB_DIV1; + /* APB2 = AHB / 1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB / 1 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while(RCU_SCSS_HXTAL != (RCU_CFG0 & RCU_CFG0_SCSS)) { + } +} + +#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL) +/*! + \brief configure the system clock to 200M by PLL0 which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_200m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK / 1 */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB4 = AHB / 2 */ + RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; + /* APB3 = AHB / 2 */ + RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; + /* APB2 = AHB / 1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB / 2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* PLL0 select HXTAL, configure PLL0 input and output range */ + RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); + RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M); + + /* PLL0P = HXTAL / 5 * 40 = 200 MHz */ + RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); + RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); + RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); + RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); + + /* enable PLL0P, PLL0Q, PLL0R */ + RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; + + /* enable PLL0 */ + RCU_CTL |= RCU_CTL_PLL0EN; + + /* wait until PLL0 is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { + } + + /* select PLL0 as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; + + /* wait until PLL0 is selected as system clock */ + while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { + } +} + +#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL) +/*! + \brief configure the system clock to 400M by PLL0 which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_400m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + /* insert TCM wait state at 400MHz */ + RCU_APB4EN |= RCU_APB4EN_SYSCFG; + SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; + + /* HXTAL is stable */ + /* AHB = SYSCLK / 1 */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; + /* APB4 = AHB / 2 */ + RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; + /* APB3 = AHB / 2 */ + RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; + /* APB2 = AHB / 1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB / 2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* PLL0 select HXTAL, configure PLL0 input and output range */ + RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); + RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M); + + /* PLL0P = HXTAL / 5 * 80 = 400 MHz */ + RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); + RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); + RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); + RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); + + /* enable PLL0P, PLL0Q, PLL0R */ + RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLL0EN; + + /* wait until PLL0 is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { + } + + /* select PLL0 as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; + + /* wait until PLL0 is selected as system clock */ + while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { + } +} + +#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL) +/*! + \brief configure the system clock to 600M by PLL0 which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_600m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + /* insert TCM wait state at 600MHz */ + RCU_APB4EN |= RCU_APB4EN_SYSCFG; + SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; + + /* HXTAL is stable */ + /* AHB = SYSCLK / 2 */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; + /* APB4 = AHB / 2 */ + RCU_CFG0 |= RCU_APB4_CKAHB_DIV2; + /* APB3 = AHB / 2 */ + RCU_CFG0 |= RCU_APB3_CKAHB_DIV2; + /* APB2 = AHB / 1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB / 2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* PLL select HXTAL, configure PLL input and output range */ + RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG); + RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLL0RNG_4M_8M); + + /* PLL0P = HXTAL / 5 * 120 = 600 MHz */ + RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC); + RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET)); + RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q); + RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET); + + /* enable PLL0P, PLL0Q, PLL0R */ + RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN; + + /* enable PLL0 */ + RCU_CTL |= RCU_CTL_PLL0EN; + + /* wait until PLL0 is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) { + } + + /* select PLL0 as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL0P; + + /* wait until PLL0 is selected as system clock */ + while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) { + } +} + +#endif /* __SYSTEM_CLOCK_IRC64M */ + +/*! + \brief update the SystemCoreClock with current core clock retrieved from cpu registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate(void) +{ + uint32_t sws = 0U; + uint32_t irc64div = 0U; + uint32_t pllpsc = 0U, plln = 0U, pllp = 0U, pllsel = 0U; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws) { + /* IRC64M is selected as CK_SYS */ + case SEL_IRC64MDIV: + irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17)); + SystemCoreClock = IRC64M_VALUE / irc64div; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_LPIRC4M: + SystemCoreClock = LPIRC4M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLL0P is selected as CK_SYS */ + case SEL_PLL0P: + /* get the value of PLL0PSC[0,5], PLL0N[6,14], PLL0P[16,22] */ + pllpsc = GET_BITS(RCU_PLL0, 0, 5); + plln = GET_BITS(RCU_PLL0, 6, 14) + 1U; + pllp = GET_BITS(RCU_PLL0, 16, 22) + 1U; + + /* PLL clock source selection, HXTAL or IRC64M_VALUE or LPIRC4M_VALUE */ + pllsel = GET_BITS(RCU_PLLALL, 16, 17); + if(0U == pllsel) { + irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17)); + SystemCoreClock = (IRC64M_VALUE / irc64div / pllpsc) * plln / pllp; + } else if(1U == pllsel) { + SystemCoreClock = (LPIRC4M_VALUE / pllpsc) * plln / pllp; + } else { + SystemCoreClock = (HXTAL_VALUE / pllpsc) * plln / pllp; + } + break; + default: + /* should not be here */ + break; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/LICENSE.TXT b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/LICENSE.TXT new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/LICENSE.TXT @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cachel1_armv7.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cachel1_armv7.h new file mode 100644 index 0000000000..13215e223b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cachel1_armv7.h @@ -0,0 +1,441 @@ +/****************************************************************************** + * @file cachel1_armv7.h + * @brief CMSIS Level 1 Cache API for Armv7-M and later + * @version V1.0.3 + * @date 17. March 2023 + ******************************************************************************/ +/* + * Copyright (c) 2020-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_CACHEL1_ARMV7_H +#define ARM_CACHEL1_ARMV7_H + +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + +#ifndef __SCB_DCACHE_LINE_SIZE +#define __SCB_DCACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +#ifndef __SCB_ICACHE_LINE_SIZE +#define __SCB_ICACHE_LINE_SIZE 32U /*!< Cortex-M7 cache line size is fixed to 32 bytes (8 words). See also register SCB_CCSIDR */ +#endif + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if (SCB->CCR & SCB_CCR_IC_Msk) return; /* return if ICache is already enabled */ + + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief I-Cache Invalidate by address + \details Invalidates I-Cache for the given address. + I-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + I-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] isize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateICache_by_Addr (volatile void *addr, int32_t isize) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + if ( isize > 0 ) { + int32_t op_size = isize + (((uint32_t)addr) & (__SCB_ICACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_ICACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->ICIMVAU = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_ICACHE_LINE_SIZE; + op_size -= __SCB_ICACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_FORCEINLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + if (SCB->CCR & SCB_CCR_DC_Msk) return; /* return if DCache is already enabled */ + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_FORCEINLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + struct { + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + } locals + #if ((defined(__GNUC__) || defined(__clang__)) && !defined(__OPTIMIZE__)) + __ALIGNED(__SCB_DCACHE_LINE_SIZE) + #endif + ; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + #if !defined(__OPTIMIZE__) + /* + * For the endless loop issue with no optimization builds. + * More details, see https://github.com/ARM-software/CMSIS_5/issues/620 + * + * The issue only happens when local variables are in stack. If + * local variables are saved in general purpose register, then the function + * is OK. + * + * When local variables are in stack, after disabling the cache, flush the + * local variables cache line for data consistency. + */ + /* Clean and invalidate the local variable cache. */ + #if defined(__ICCARM__) + /* As we can't align the stack to the cache line size, invalidate each of the variables */ + SCB->DCCIMVAC = (uint32_t)&locals.sets; + SCB->DCCIMVAC = (uint32_t)&locals.ways; + SCB->DCCIMVAC = (uint32_t)&locals.ccsidr; + #else + SCB->DCCIMVAC = (uint32_t)&locals; + #endif + __DSB(); + __ISB(); + #endif + + locals.ccsidr = SCB->CCSIDR; + /* clean & invalidate D-Cache */ + locals.sets = (uint32_t)(CCSIDR_SETS(locals.ccsidr)); + do { + locals.ways = (uint32_t)(CCSIDR_WAYS(locals.ccsidr)); + do { + SCB->DCCISW = (((locals.sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((locals.ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (locals.ways-- != 0U); + } while(locals.sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /* select Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address. + D-Cache is invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are invalidated. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + D-Cache is cleaned starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned. + \param[in] addr address + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + D-Cache is cleaned and invalidated starting from a 32 byte aligned address in 32 byte granularity. + D-Cache memory blocks which are part of given address + given size are cleaned and invalidated. + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_FORCEINLINE void SCB_CleanInvalidateDCache_by_Addr (volatile void *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + if ( dsize > 0 ) { + int32_t op_size = dsize + (((uint32_t)addr) & (__SCB_DCACHE_LINE_SIZE - 1U)); + uint32_t op_addr = (uint32_t)addr /* & ~(__SCB_DCACHE_LINE_SIZE - 1U) */; + + __DSB(); + + do { + SCB->DCCIMVAC = op_addr; /* register accepts only 32byte aligned values, only bits 31..5 are valid */ + op_addr += __SCB_DCACHE_LINE_SIZE; + op_size -= __SCB_DCACHE_LINE_SIZE; + } while ( op_size > 0 ); + + __DSB(); + __ISB(); + } + #endif +} + +/*@} end of CMSIS_Core_CacheFunctions */ + +#endif /* ARM_CACHEL1_ARMV7_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armcc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armcc.h new file mode 100644 index 0000000000..2edff5af55 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armcc.h @@ -0,0 +1,894 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.4.0 + * @date 20. January 2023 + ******************************************************************************/ +/* + * Copyright (c) 2009-2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + /* __ARM_ARCH_8_1M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif +#ifndef __NO_INIT + #define __NO_INIT __attribute__ ((section (".bss.noinit"), zero_init)) +#endif +#ifndef __ALIAS + #define __ALIAS(x) __attribute__ ((alias(x))) +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; + __ISB(); +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang.h new file mode 100644 index 0000000000..139923dab2 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang.h @@ -0,0 +1,1510 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.5.0 + * @date 20. January 2023 + ******************************************************************************/ +/* + * Copyright (c) 2009-2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif +#ifndef __NO_INIT + #define __NO_INIT __attribute__ ((section (".bss.noinit"))) +#endif +#ifndef __ALIAS + #define __ALIAS(x) __attribute__ ((alias(x))) +#endif + + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** @}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(fpscr) ((void)(fpscr)) +#endif + + +/** @} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/** @} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang_ltm.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang_ltm.h new file mode 100644 index 0000000000..477136e848 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_armclang_ltm.h @@ -0,0 +1,1934 @@ +/**************************************************************************//** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.6.0 + * @date 20. January 2023 + ******************************************************************************/ +/* + * Copyright (c) 2018-2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif +#ifndef __NO_INIT + #define __NO_INIT __attribute__ ((section (".bss.noinit"))) +#endif +#ifndef __ALIAS + #define __ALIAS(x) __attribute__ ((alias(x))) +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL Image$$STACKSEAL$$ZI$$Base +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} +#endif + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +#ifndef __ARM_COMPAT_H +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} +#endif + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#define __SXTAB16_RORn(ARG1, ARG2, ARG3) __SXTAB16(ARG1, __ROR(ARG2, ARG3)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_compiler.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_compiler.h new file mode 100644 index 0000000000..192f9b7c93 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_compiler.h @@ -0,0 +1,303 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.3.0 + * @date 04. April 2023 + ******************************************************************************/ +/* + * Copyright (c) 2009-2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + +/* + * TI Arm Clang Compiler (tiarmclang) + */ +#elif defined (__ti__) + #include "cmsis_tiarmclang.h" + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler (armcl) + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + #ifndef __NO_INIT + #define __NO_INIT __attribute__ ((section (".bss.noinit"))) + #endif + #ifndef __ALIAS + #define __ALIAS(x) __attribute__ ((alias(x))) + #endif + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + #ifndef __NO_INIT + #define __NO_INIT __attribute__ ((section (".bss.noinit"))) + #endif + #ifndef __ALIAS + #define __ALIAS(x) __attribute__ ((alias(x))) + #endif + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + #ifndef __NO_INIT + #define __NO_INIT __attribute__ ((section (".bss.noinit"))) + #endif + #ifndef __ALIAS + #define __ALIAS(x) __attribute__ ((alias(x))) + #endif + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_gcc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_gcc.h new file mode 100644 index 0000000000..4f0762d6dc --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_gcc.h @@ -0,0 +1,2217 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.4.2 + * @date 17. December 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2021 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif +#ifndef __NO_INIT + #define __NO_INIT __attribute__ ((section (".bss.noinit"))) +#endif +#ifndef __ALIAS + #define __ALIAS(x) __attribute__ ((alias(x))) +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct __copy_table { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct __zero_table { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#ifndef __STACK_SEAL +#define __STACK_SEAL __StackSeal +#endif + +#ifndef __TZ_STACK_SEAL_SIZE +#define __TZ_STACK_SEAL_SIZE 8U +#endif + +#ifndef __TZ_STACK_SEAL_VALUE +#define __TZ_STACK_SEAL_VALUE 0xFEF5EDA5FEF5EDA5ULL +#endif + + +__STATIC_FORCEINLINE void __TZ_set_STACKSEAL_S (uint32_t* stackTop) { + *((uint64_t *)stackTop) = __TZ_STACK_SEAL_VALUE; +} +#endif + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting special-purpose register PRIMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); + __ISB(); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); + __ISB(); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting special-purpose register FAULTMASK. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + } else { + result = __SXTB16(__ROR(op1, rotate)) ; + } + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16_RORn(uint32_t op1, uint32_t op2, uint32_t rotate) +{ + uint32_t result; + if (__builtin_constant_p(rotate) && ((rotate == 8U) || (rotate == 16U) || (rotate == 24U))) { + __ASM volatile ("sxtab16 %0, %1, %2, ROR %3" : "=r" (result) : "r" (op1) , "r" (op2) , "i" (rotate)); + } else { + result = __SXTAB16(op1, __ROR(op2, rotate)); + } + return result; +} + + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +#define __PKHBT(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_version.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_version.h new file mode 100644 index 0000000000..8b4765f186 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.5 + * @date 02. February 2022 + ******************************************************************************/ +/* + * Copyright (c) 2009-2022 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 6U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/core_cm7.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/core_cm7.h new file mode 100644 index 0000000000..7ba4daa2ab --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/core_cm7.h @@ -0,0 +1,2407 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.2.0 + * @date 04. April 2023 + ******************************************************************************/ +/* + * Copyright (c) 2009-2023 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ti__) + #if defined (__ARM_FP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + __OM uint32_t BPIALL; /*!< Offset: 0x278 ( /W) Branch Predictor Invalidate All */ + uint32_t RESERVED7[5U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_CFSR_MEMFAULTSR_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_CFSR_MEMFAULTSR_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_CFSR_MEMFAULTSR_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< \deprecated SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< \deprecated SCB CACR: ECCEN Mask */ + +#define SCB_CACR_ECCDIS_Pos 1U /*!< SCB CACR: ECCDIS Position */ +#define SCB_CACR_ECCDIS_Msk (1UL << SCB_CACR_ECCDIS_Pos) /*!< SCB CACR: ECCDIS Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBSCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBSCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBSCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISDYNADD_Pos 26U /*!< ACTLR: DISDYNADD Position */ +#define SCnSCB_ACTLR_DISDYNADD_Msk (1UL << SCnSCB_ACTLR_DISDYNADD_Pos) /*!< ACTLR: DISDYNADD Mask */ + +#define SCnSCB_ACTLR_DISISSCH1_Pos 21U /*!< ACTLR: DISISSCH1 Position */ +#define SCnSCB_ACTLR_DISISSCH1_Msk (0x1FUL << SCnSCB_ACTLR_DISISSCH1_Pos) /*!< ACTLR: DISISSCH1 Mask */ + +#define SCnSCB_ACTLR_DISDI_Pos 16U /*!< ACTLR: DISDI Position */ +#define SCnSCB_ACTLR_DISDI_Msk (0x1FUL << SCnSCB_ACTLR_DISDI_Pos) /*!< ACTLR: DISDI Mask */ + +#define SCnSCB_ACTLR_DISCRITAXIRUR_Pos 15U /*!< ACTLR: DISCRITAXIRUR Position */ +#define SCnSCB_ACTLR_DISCRITAXIRUR_Msk (1UL << SCnSCB_ACTLR_DISCRITAXIRUR_Pos) /*!< ACTLR: DISCRITAXIRUR Mask */ + +#define SCnSCB_ACTLR_DISBTACALLOC_Pos 14U /*!< ACTLR: DISBTACALLOC Position */ +#define SCnSCB_ACTLR_DISBTACALLOC_Msk (1UL << SCnSCB_ACTLR_DISBTACALLOC_Pos) /*!< ACTLR: DISBTACALLOC Mask */ + +#define SCnSCB_ACTLR_DISBTACREAD_Pos 13U /*!< ACTLR: DISBTACREAD Position */ +#define SCnSCB_ACTLR_DISBTACREAD_Msk (1UL << SCnSCB_ACTLR_DISBTACREAD_Pos) /*!< ACTLR: DISBTACREAD Mask */ + +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_BYTEACC_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_BYTEACC_Msk (1UL << ITM_LSR_BYTEACC_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_ACCESS_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_ACCESS_Msk (1UL << ITM_LSR_ACCESS_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_PRESENT_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_PRESENT_Msk (1UL /*<< ITM_LSR_PRESENT_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_register_aliases Backwards Compatibility Aliases + \brief Register alias definitions for backwards compatibility. + @{ + */ + +/* Capitalize ITM_TCR Register Definitions */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_TraceBusID_Pos (ITM_TCR_TRACEBUSID_Pos) /*!< \deprecated ITM_TCR_TraceBusID_Pos */ +#define ITM_TCR_TraceBusID_Msk (ITM_TCR_TRACEBUSID_Msk) /*!< \deprecated ITM_TCR_TraceBusID_Msk */ + +#define ITM_TCR_TSPrescale_Pos (ITM_TCR_TSPRESCALE_Pos) /*!< \deprecated ITM_TCR_TSPrescale_Pos */ +#define ITM_TCR_TSPrescale_Msk (ITM_TCR_TSPRESCALE_Msk) /*!< \deprecated ITM_TCR_TSPrescale_Msk */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos (ITM_LSR_BYTEACC_Pos) /*!< \deprecated ITM_LSR_ByteAcc_Pos */ +#define ITM_LSR_ByteAcc_Msk (ITM_LSR_BYTEACC_Msk) /*!< \deprecated ITM_LSR_ByteAcc_Msk */ + +#define ITM_LSR_Access_Pos (ITM_LSR_ACCESS_Pos) /*!< \deprecated ITM_LSR_Access_Pos */ +#define ITM_LSR_Access_Msk (ITM_LSR_ACCESS_Msk) /*!< \deprecated ITM_LSR_Access_Msk */ + +#define ITM_LSR_Present_Pos (ITM_LSR_PRESENT_Pos) /*!< \deprecated ITM_LSR_Present_Pos */ +#define ITM_LSR_Present_Msk (ITM_LSR_PRESENT_Msk) /*!< \deprecated ITM_LSR_Present_Msk */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + __DSB(); +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + +/*@} end of CMSIS_Core_FpuFunctions */ + + +/* ########################## Cache functions #################################### */ + +#if ((defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)) || \ + (defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U))) +#include "cachel1_armv7.h" +#endif + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/mpu_armv7.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/mpu_armv7.h new file mode 100644 index 0000000000..d9eedf81a6 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/CMSIS/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/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_adc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_adc.h new file mode 100644 index 0000000000..a0b99cbefa --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_adc.h @@ -0,0 +1,623 @@ +/*! + \file gd32h7xx_adc.h + \brief definitions for the ADC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_ADC_H +#define GD32H7XX_ADC_H + +#include "gd32h7xx.h" + +/* ADC definitions */ +#define ADC0 ADC_BASE /*!< ADC0 base address */ +#define ADC1 (ADC_BASE + 0x00000400U) /*!< ADC1 base address */ +#define ADC2 (ADC_BASE + 0x00000800U) /*!< ADC2 base address */ + +/* registers definitions */ +#define ADC_STAT(adcx) REG32((adcx) + 0x00000000U) /*!< ADC status register */ +#define ADC_CTL0(adcx) REG32((adcx) + 0x00000004U) /*!< ADC control register 0 */ +#define ADC_CTL1(adcx) REG32((adcx) + 0x00000008U) /*!< ADC control register 1 */ +#define ADC_IOFF0(adcx) REG32((adcx) + 0x0000000CU) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1(adcx) REG32((adcx) + 0x00000010U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2(adcx) REG32((adcx) + 0x00000014U) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3(adcx) REG32((adcx) + 0x00000018U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT0(adcx) REG32((adcx) + 0x0000001CU) /*!< ADC watchdog high threshold register 0 */ +#define ADC_WDLT0(adcx) REG32((adcx) + 0x00000020U) /*!< ADC watchdog low threshold register 0 */ +#define ADC_RSQ0(adcx) REG32((adcx) + 0x00000024U) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1(adcx) REG32((adcx) + 0x00000028U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2(adcx) REG32((adcx) + 0x0000002CU) /*!< ADC regular sequence register 2 */ +#define ADC_RSQ3(adcx) REG32((adcx) + 0x00000030U) /*!< ADC regular sequence register 3 */ +#define ADC_RSQ4(adcx) REG32((adcx) + 0x00000034U) /*!< ADC regular sequence register 4 */ +#define ADC_RSQ5(adcx) REG32((adcx) + 0x00000038U) /*!< ADC regular sequence register 5 */ +#define ADC_RSQ6(adcx) REG32((adcx) + 0x0000003CU) /*!< ADC regular sequence register 6 */ +#define ADC_RSQ7(adcx) REG32((adcx) + 0x00000040U) /*!< ADC regular sequence register 7 */ +#define ADC_RSQ8(adcx) REG32((adcx) + 0x00000044U) /*!< ADC regular sequence register 8 */ +#define ADC_ISQ0(adcx) REG32((adcx) + 0x00000048U) /*!< ADC inserted sequence register 0 */ +#define ADC_ISQ1(adcx) REG32((adcx) + 0x0000004CU) /*!< ADC inserted sequence register 1 */ +#define ADC_ISQ2(adcx) REG32((adcx) + 0x00000050U) /*!< ADC inserted sequence register 2 */ +#define ADC_IDATA0(adcx) REG32((adcx) + 0x00000054U) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1(adcx) REG32((adcx) + 0x00000058U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2(adcx) REG32((adcx) + 0x0000005CU) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3(adcx) REG32((adcx) + 0x00000060U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA(adcx) REG32((adcx) + 0x00000064U) /*!< ADC regular data register */ +#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x00000080U) /*!< ADC oversampling control register */ +#define ADC_WD1SR(adcx) REG32((adcx) + 0x000000A0U) /*!< ADC watchdog 1 channel selection register */ +#define ADC_WD2SR(adcx) REG32((adcx) + 0x000000A4U) /*!< ADC watchdog 2 channel selection register */ +#define ADC_WDHT1(adcx) REG32((adcx) + 0x000000A8U) /*!< ADC watchdog high threshold register 1 */ +#define ADC_WDLT1(adcx) REG32((adcx) + 0x000000ACU) /*!< ADC watchdog low threshold register 1 */ +#define ADC_WDHT2(adcx) REG32((adcx) + 0x000000B0U) /*!< ADC watchdog high threshold register 2 */ +#define ADC_WDLT2(adcx) REG32((adcx) + 0x000000B4U) /*!< ADC watchdog low threshold register 2 */ +#define ADC_DIFCTL(adcx) REG32((adcx) + 0x000000B8U) /*!< ADC differential mode control register */ +#define ADC_SSTAT REG32((ADC0) + 0x00000300U) /*!< ADC summary status register */ +#define ADC_SYNCCTL(adcx) REG32((adcx) + 0x00000304U) /*!< ADC sync control register */ +#define ADC_SYNCDATA0 REG32((ADC0) + 0x00000308U) /*!< ADC sync regular data register 0 */ +#define ADC_SYNCDATA1 REG32((ADC0) + 0x0000030CU) /*!< ADC sync regular data register 1 */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE0 BIT(0) /*!< analog watchdog 0 event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of group conversion flag */ +#define ADC_STAT_EOIC BIT(2) /*!< end of inserted group conversion flag */ +#define ADC_STAT_STIC BIT(3) /*!< start flag of inserted channel group */ +#define ADC_STAT_STRC BIT(4) /*!< start flag of regular channel group */ +#define ADC_STAT_ROVF BIT(5) /*!< regular data register overflow */ +#define ADC_STAT_WDE1 BIT(30) /*!< analog watchdog 1 event flag */ +#define ADC_STAT_WDE2 BIT(31) /*!< analog watchdog 2 event flag */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WD0CHSEL BITS(0,4) /*!< analog watchdog channel select */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDE0IE BIT(6) /*!< interrupt enable for WDE0 */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for EOIC */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WD0SC BIT(9) /*!< when in scan mode, analog watchdog 0 is effective on a single channel */ +#define ADC_CTL0_ICA BIT(10) /*!< inserted channel group convert automatically */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< number of conversions in discontinuous mode */ +#define ADC_CTL0_IWD0EN BIT(22) /*!< inserted channel analog watchdog 0 enable */ +#define ADC_CTL0_RWD0EN BIT(23) /*!< regular channel analog watchdog 0 enable */ +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ +#define ADC_CTL0_ROVFIE BIT(26) /*!< interrupt enable for ROVF */ +#define ADC_CTL0_WDE1IE BIT(30) /*!< interrupt enable for WDE1 */ +#define ADC_CTL0_WDE2IE BIT(31) /*!< interrupt enable for WDE2 */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous mode */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_CALNUM BITS(4,6) /*!< ADC calibration times */ +#define ADC_CTL1_DMA BIT(8) /*!< DMA request enable */ +#define ADC_CTL1_DDM BIT(9) /*!< DMA disable mode */ +#define ADC_CTL1_EOCM BIT(10) /*!< end of conversion mode */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_HPDFCFG BIT(12) /*!< HPDF mode configuration */ +#define ADC_CTL1_ETMIC BITS(20,21) /*!< external trigger mode for inserted channels */ +#define ADC_CTL1_SWICST BIT(22) /*!< software start on inserted channel */ +#define ADC_CTL1_TSVEN1 BIT(23) /*!< temperature sensor channel enable */ +#define ADC_CTL1_INREFEN BIT(24) /*!< vrefint channel enable */ +#define ADC_CTL1_VBATEN BIT(25) /*!< vbat channel enable */ +#define ADC_CTL1_CALMOD BIT(27) /*!< ADC calibration mode */ +#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger mode for regular channels */ +#define ADC_CTL1_SWRCST BIT(30) /*!< software start on regular channel. */ +#define ADC_CTL1_TSVEN2 BIT(31) /*!< high-precision temperature sensor channel enable */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0,23) /*!< data offset for inserted channel x */ + +/* ADC_WDHT0 */ +#define ADC_WDHT0_WDHT0 BITS(0,23) /*!< high threshold for analog watchdog 0 */ + +/* ADC_WDLT0 */ +#define ADC_WDLT0_WDLT0 BITS(0,23) /*!< low threshold for analog watchdog 0 */ + +/* ADC_RSQx x=0..8 */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< nth conversion channel number in the regular channel group */ +#define ADC_RSQX_RSMPN BITS(5,14) /*!< nth conversion sample time in the regular channel group */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel group length */ + +/* ADC_ISQx x=0..2 */ +#define ADC_ISQX_ISQN BITS(0,4) /*!< nth conversion channel number in the inserted channel group */ +#define ADC_ISQX_ISMPN BITS(5,14) /*!< nth conversion sample time in the inserted channel group */ +#define ADC_ISQ0_IL BITS(20,21) /*!< inserted channel group length */ + +/* ADC_IDATAx x=0..3 */ +#define ADC_IDATAX_IDATAN BITS(0,31) /*!< Inserted number n conversion data */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0,31) /*!< regular channel data */ + +/* ADC_OVSAMPCTL */ +#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ +#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ +#define ADC_OVSAMPCTL_OVSR BITS(16,25) /*!< oversampling ratio */ + +/* ADC_WD1SR */ +#define ADC_WD1SR_AWD1CS BITS(0,21) /*!< analog watchdog 1 channel selection */ + +/* ADC_WD2SR */ +#define ADC_WD2SR_AWD2CS BITS(0,21) /*!< analog watchdog 2 channel selection */ + +/* ADC_WDHT1 */ +#define ADC_WDHT1_WDHT1 BITS(0,23) /*!< high threshold for analog watchdog 1 */ + +/* ADC_WDHT1 */ +#define ADC_WDLT1_WDLT1 BITS(0,23) /*!< low threshold for analog watchdog 1 */ + +/* ADC_WDHT2 */ +#define ADC_WDHT2_WDHT2 BITS(0,23) /*!< high threshold for analog watchdog 2 */ + +/* ADC_WDHT2 */ +#define ADC_WDLT2_WDLT2 BITS(0,23) /*!< low threshold for analog watchdog 2 */ + +/* ADC_DIFCTL */ +#define ADC_DIFCTL_DIFCTL BITS(0,21) /*!< Differential mode for channel 0..21 */ + +/* ADC_SSTAT */ +#define ADC_SSTAT_ADC0_WDE0 BIT(0) /*!< the bit is mirror image of the WDE0 bit of ADC0 */ +#define ADC_SSTAT_ADC0_WDE1 BIT(1) /*!< the bit is mirror image of the WDE1 bit of ADC0 */ +#define ADC_SSTAT_ADC0_WDE2 BIT(2) /*!< the bit is mirror image of the WDE2 bit of ADC0 */ +#define ADC_SSTAT_ADC0_EOC BIT(3) /*!< the bit is mirror image of the EOC bit of ADC0 */ +#define ADC_SSTAT_ADC0_EOIC BIT(4) /*!< the bit is mirror image of the EOIC bit of ADC0 */ +#define ADC_SSTAT_ADC0_STIC BIT(5) /*!< the bit is mirror image of the STIC bit of ADC0 */ +#define ADC_SSTAT_ADC0_STRC BIT(6) /*!< the bit is mirror image of the STRC bit of ADC0 */ +#define ADC_SSTAT_ADC0_ROVF BIT(7) /*!< the bit is mirror image of the ROVF bit of ADC0 */ +#define ADC_SSTAT_ADC1_WDE0 BIT(8) /*!< the bit is mirror image of the WDE0 bit of ADC1 */ +#define ADC_SSTAT_ADC1_WDE1 BIT(9) /*!< the bit is mirror image of the WDE1 bit of ADC1 */ +#define ADC_SSTAT_ADC1_WDE2 BIT(10) /*!< the bit is mirror image of the WDE2 bit of ADC1 */ +#define ADC_SSTAT_ADC1_EOC BIT(11) /*!< the bit is mirror image of the EOC bit of ADC1 */ +#define ADC_SSTAT_ADC1_EOIC BIT(12) /*!< the bit is mirror image of the EOIC bit of ADC1 */ +#define ADC_SSTAT_ADC1_STIC BIT(13) /*!< the bit is mirror image of the STIC bit of ADC1 */ +#define ADC_SSTAT_ADC1_STRC BIT(14) /*!< the bit is mirror image of the STRC bit of ADC1 */ +#define ADC_SSTAT_ADC1_ROVF BIT(15) /*!< the bit is mirror image of the ROVF bit of ADC1 */ +#define ADC_SSTAT_ADC2_WDE0 BIT(16) /*!< the bit is mirror image of the WDE0 bit of ADC2 */ +#define ADC_SSTAT_ADC2_WDE1 BIT(17) /*!< the bit is mirror image of the WDE1 bit of ADC2 */ +#define ADC_SSTAT_ADC2_WDE2 BIT(18) /*!< the bit is mirror image of the WDE2 bit of ADC2 */ +#define ADC_SSTAT_ADC2_EOC BIT(19) /*!< the bit is mirror image of the EOC bit of ADC2 */ +#define ADC_SSTAT_ADC2_EOIC BIT(20) /*!< the bit is mirror image of the EOIC bit of ADC2 */ +#define ADC_SSTAT_ADC2_STIC BIT(21) /*!< the bit is mirror image of the STIC bit of ADC2 */ +#define ADC_SSTAT_ADC2_STRC BIT(22) /*!< the bit is mirror image of the STRC bit of ADC2 */ +#define ADC_SSTAT_ADC2_ROVF BIT(23) /*!< the bit is mirror image of the ROVF bit of ADC2 */ + +/* ADC_SYNCCTL */ +#define ADC_SYNCCTL_SYNCM BITS(0,3) /*!< ADC sync mode */ +#define ADC_SYNCCTL_SYNCDLY BITS(8,11) /*!< ADC sync delay */ +#define ADC_SYNCCTL_SYNCDDM BIT(13) /*!< ADC sync DMA disable mode */ +#define ADC_SYNCCTL_SYNCDMA BITS(14,15) /*!< ADC sync DMA mode selection */ +#define ADC_SYNCCTL_ADCSCK BITS(16,19) /*!< ADC sync clock mode */ +#define ADC_SYNCCTL_ADCCK BITS(20,23) /*!< ADC clock prescaler */ + +/* ADC_SYNCDATA0 */ +#define ADC_SYNCDATA0_SYNCDATA0 BITS(0,15) /*!< ADC0 regular data in ADC synchronization mode */ +#define ADC_SYNCDATA0_SYNCDATA1 BITS(16,31) /*!< ADC1 regular data in ADC synchronization mode */ + +/* constants definitions */ +/* ADC status flag */ +#define ADC_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion flag */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion flag */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< start flag of inserted channel group */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< start flag of regular channel group */ +#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< regular data register overflow */ +#define ADC_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event flag */ +#define ADC_FLAG_WDE2 ADC_STAT_WDE2 /*!< analog watchdog 2 event flag */ + +/* ADC interrupt */ +#define ADC_INT_WDE0 ADC_CTL0_WDE0IE /*!< interrupt enable for WDE0 */ +#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< interrupt enable for EOC */ +#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< interrupt enable for EOIC */ +#define ADC_INT_ROVF ADC_CTL0_ROVFIE /*!< interrupt enable for ROVF */ +#define ADC_INT_WDE1 ADC_CTL0_WDE1IE /*!< interrupt enable for WDE1 */ +#define ADC_INT_WDE2 ADC_CTL0_WDE2IE /*!< interrupt enable for WDE2 */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event interrupt flag */ +#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt flag */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt flag */ +#define ADC_INT_FLAG_ROVF ADC_STAT_ROVF /*!< regular data register overflow interrupt flag */ +#define ADC_INT_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event interrupt flag */ +#define ADC_INT_FLAG_WDE2 ADC_STAT_WDE2 /*!< analog watchdog 2 event interrupt flag */ + +/* number of conversions in discontinuous mode */ +#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) /*!< write value to ADC_CTL0_DISNUM bit field */ + +/* ADC special function definitions */ +#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ +#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ + +/* ADC calibration mode */ +#define ADC_CALIBRATION_OFFSET_MISMATCH ((uint32_t)0x00000000U) /*!< ADC calibration offset and mismatch mode */ +#define ADC_CALIBRATION_OFFSET ADC_CTL1_CALMOD /*!< ADC calibration mode */ + +/* ADC calibration times */ +#define CTL1_CALNUM(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) /*!< write value to ADC_CTL1_CLBNUM bit field */ +#define ADC_CALIBRATION_NUM1 CTL1_CALNUM(0) /*!< ADC calibration 1 time */ +#define ADC_CALIBRATION_NUM2 CTL1_CALNUM(1) /*!< ADC calibration 2 times */ +#define ADC_CALIBRATION_NUM4 CTL1_CALNUM(2) /*!< ADC calibration 4 times */ +#define ADC_CALIBRATION_NUM8 CTL1_CALNUM(3) /*!< ADC calibration 8 times */ +#define ADC_CALIBRATION_NUM16 CTL1_CALNUM(4) /*!< ADC calibration 16 times */ +#define ADC_CALIBRATION_NUM32 CTL1_CALNUM(5) /*!< ADC calibration 32 times */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ + +/* end of conversion mode */ +#define ADC_EOC_SET_SEQUENCE ((uint32_t)0x00000000U) /*!< only at the end of a sequence of regular conversions, the EOC bit is set */ +#define ADC_EOC_SET_CONVERSION ADC_CTL1_EOCM /*!< at the end of each regular conversion, the EOC bit is set */ + +/* ADC internal channel definitions */ +#define ADC_CHANNEL_INTERNAL_TEMPSENSOR ADC_CTL1_TSVEN1 /*!< temperature sensor channel */ +#define ADC_CHANNEL_INTERNAL_VREFINT ADC_CTL1_INREFEN /*!< vrefint channel */ +#define ADC_CHANNEL_INTERNAL_VBAT ADC_CTL1_VBATEN /*!< vbat channel */ +#define ADC_CHANNEL_INTERNAL_HP_TEMPSENSOR ADC_CTL1_TSVEN2 /*!< high-precision temperature sensor channel */ + +/* ADC data offset for inserted channel x */ +#define IOFFX_IOFF(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_IOFFX_IOFF bit field */ + +/* ADC high threshold for analog watchdog 0 */ +#define WDHT0_WDHT0(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT0_WDHT0 bit field */ + +/* ADC low threshold for analog watchdog 0 */ +#define WDLT0_WDLT0(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT0_WDLT0 bit field */ + +/* ADC high threshold for analog watchdog 1 */ +#define WDHT1_WDHT1(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT1_WDHT1 bit field */ + +/* ADC low threshold for analog watchdog 1 */ +#define WDLT1_WDLT1(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT1_WDLT1 bit field */ + +/* ADC high threshold for analog watchdog 2 */ +#define WDHT2_WDHT2(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDHT2_WDHT2 bit field */ + +/* ADC low threshold for analog watchdog 2 */ +#define WDLT2_WDLT2(regval) (BITS(0,23) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WDLT2_WDLT2 bit field */ + +/* ADC sequence sample time */ +#define SQX_SMP(regval) (BITS(5,14) & ((uint32_t)(regval) << 5U)) /*!< write value to RSQX_SMPn or ISQX_SMPn bit field */ + +/* ADC regular channel group length */ +#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_RSQ0_RL bit field */ + +/* ADC inserted channel group length */ +#define ISQ0_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_ISQ0_IL bit field */ + +/* ADC resolution */ +#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24U)) /*!< write value to ADC_CTL0_DRES bit field */ +#define ADC_RESOLUTION_14B ((uint8_t)0x00U) /*!< 14-bit ADC resolution */ +#define ADC_RESOLUTION_12B ((uint8_t)0x01U) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B ((uint8_t)0x02U) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B ((uint8_t)0x03U) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B ((uint8_t)0x04U) /*!< 6-bit ADC resolution */ + +/* oversampling shift */ +#define OVSCR_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5U)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */ +#define ADC_OVERSAMPLING_SHIFT_NONE OVSCR_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSCR_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSCR_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSCR_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSCR_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSCR_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSCR_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSCR_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSCR_OVSS(8) /*!< 8-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_9B OVSCR_OVSS(9) /*!< 9-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_10B OVSCR_OVSS(10) /*!< 10-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_11B OVSCR_OVSS(11) /*!< 11-bit oversampling shift */ + +/* oversampling ratio */ +#define OVSCR_OVSR(regval) (BITS(16,25) & ((uint32_t)(regval) << 16U)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */ + +/* triggered oversampling */ +#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */ + +/* configure the ADC clock */ +#define SYNCCTL_ADCSCK(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) /*!< write value to ADC_SYNCCTL_ADCSCK bit field */ +#define SYNCCTL_ADCCK(regval) (BITS(20,23) & ((uint32_t)(regval) << 20U)) /*!< write value to ADC_SYNCCTL_ADCCK bit field */ +#define ADC_CLK_SYNC_HCLK_DIV2 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(8)) /*!< ADC sync clock mode HCLK div2 */ +#define ADC_CLK_SYNC_HCLK_DIV4 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(9)) /*!< ADC sync clock mode HCLK div4 */ +#define ADC_CLK_SYNC_HCLK_DIV6 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(10)) /*!< ADC sync clock mode HCLK div6 */ +#define ADC_CLK_SYNC_HCLK_DIV8 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(11)) /*!< ADC sync clock mode HCLK div8 */ +#define ADC_CLK_SYNC_HCLK_DIV10 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(12)) /*!< ADC sync clock mode HCLK div10 */ +#define ADC_CLK_SYNC_HCLK_DIV12 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(13)) /*!< ADC sync clock mode HCLK div12 */ +#define ADC_CLK_SYNC_HCLK_DIV14 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(14)) /*!< ADC sync clock mode HCLK div14 */ +#define ADC_CLK_SYNC_HCLK_DIV16 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(15)) /*!< ADC sync clock mode HCLK div16 */ +#define ADC_CLK_ASYNC_DIV1 (SYNCCTL_ADCCK(0) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div1 */ +#define ADC_CLK_ASYNC_DIV2 (SYNCCTL_ADCCK(1) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div2 */ +#define ADC_CLK_ASYNC_DIV4 (SYNCCTL_ADCCK(2) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div4 */ +#define ADC_CLK_ASYNC_DIV6 (SYNCCTL_ADCCK(3) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div6 */ +#define ADC_CLK_ASYNC_DIV8 (SYNCCTL_ADCCK(4) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div8 */ +#define ADC_CLK_ASYNC_DIV10 (SYNCCTL_ADCCK(5) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div10 */ +#define ADC_CLK_ASYNC_DIV12 (SYNCCTL_ADCCK(6) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div12 */ +#define ADC_CLK_ASYNC_DIV16 (SYNCCTL_ADCCK(7) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div16 */ +#define ADC_CLK_ASYNC_DIV32 (SYNCCTL_ADCCK(8) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div32 */ +#define ADC_CLK_ASYNC_DIV64 (SYNCCTL_ADCCK(9) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div64 */ +#define ADC_CLK_ASYNC_DIV128 (SYNCCTL_ADCCK(10) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div128 */ +#define ADC_CLK_ASYNC_DIV256 (SYNCCTL_ADCCK(11) | SYNCCTL_ADCSCK(0)) /*!< ADC async clock mode div256 */ + +/* ADC sync DMA mode selection */ +#define SYNCCTL_SYNCDMA(regval) (BITS(14,15) & ((uint32_t)(regval) << 14U)) /*!< write value to ADC_SYNCCTL_SYNCDMA bit field */ +#define ADC_SYNC_DMA_DISABLE SYNCCTL_SYNCDMA(0) /*!< ADC sync DMA disabled */ +#define ADC_SYNC_DMA_MODE0 SYNCCTL_SYNCDMA(1) /*!< ADC sync DMA mode 0 */ +#define ADC_SYNC_DMA_MODE1 SYNCCTL_SYNCDMA(2) /*!< ADC sync DMA mode 1 */ + +/* ADC sync delay */ +#define SYNCCTL_SYNCDLY(regval) (BITS(8,11) & ((uint32_t)(regval) << 8U)) /*!< write value to ADC_SYNCCTL_SYNCDLY bit field */ +#define ADC_SYNC_DELAY_5CYCLE SYNCCTL_SYNCDLY(0) /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */ +#define ADC_SYNC_DELAY_6CYCLE SYNCCTL_SYNCDLY(1) /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */ +#define ADC_SYNC_DELAY_7CYCLE SYNCCTL_SYNCDLY(2) /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */ +#define ADC_SYNC_DELAY_8CYCLE SYNCCTL_SYNCDLY(3) /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */ +#define ADC_SYNC_DELAY_9CYCLE SYNCCTL_SYNCDLY(4) /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */ +#define ADC_SYNC_DELAY_10CYCLE SYNCCTL_SYNCDLY(5) /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */ +#define ADC_SYNC_DELAY_11CYCLE SYNCCTL_SYNCDLY(6) /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */ +#define ADC_SYNC_DELAY_12CYCLE SYNCCTL_SYNCDLY(7) /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */ +#define ADC_SYNC_DELAY_13CYCLE SYNCCTL_SYNCDLY(8) /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */ +#define ADC_SYNC_DELAY_14CYCLE SYNCCTL_SYNCDLY(9) /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */ +#define ADC_SYNC_DELAY_15CYCLE SYNCCTL_SYNCDLY(10) /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */ +#define ADC_SYNC_DELAY_16CYCLE SYNCCTL_SYNCDLY(11) /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */ +#define ADC_SYNC_DELAY_17CYCLE SYNCCTL_SYNCDLY(12) /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */ +#define ADC_SYNC_DELAY_18CYCLE SYNCCTL_SYNCDLY(13) /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */ +#define ADC_SYNC_DELAY_19CYCLE SYNCCTL_SYNCDLY(14) /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */ +#define ADC_SYNC_DELAY_20CYCLE SYNCCTL_SYNCDLY(15) /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */ + +/* ADC sync mode */ +#define SYNCCTL_SYNCM(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_SYNCCTL_SYNCM bit field */ +#define ADC_SYNC_MODE_INDEPENDENT SYNCCTL_SYNCM(0) /*!< ADC synchronization mode disabled.All the ADCs work independently */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(1) /*!< combined regular parallel & inserted parallel mode */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(2) /*!< combined regular parallel & trigger rotation mode */ +#define ADC_DAUL_INSERTED_PARALLEL SYNCCTL_SYNCM(5) /*!< inserted parallel mode */ +#define ADC_DAUL_REGULAL_PARALLEL SYNCCTL_SYNCM(6) /*!< regular parallel mode */ +#define ADC_DAUL_REGULAL_FOLLOW_UP SYNCCTL_SYNCM(7) /*!< follow-up mode */ +#define ADC_DAUL_INSERTED_TRIGGER_ROTATION SYNCCTL_SYNCM(9) /*!< trigger rotation mode */ + +/* external trigger mode for regular and inserted channel */ +#define EXTERNAL_TRIGGER_DISABLE ((uint32_t)0x00000000U) /*!< external trigger disable */ +#define EXTERNAL_TRIGGER_RISING ((uint32_t)0x00000001U) /*!< rising edge of external trigger */ +#define EXTERNAL_TRIGGER_FALLING ((uint32_t)0x00000002U) /*!< falling edge of external trigger */ +#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U) /*!< rising and falling edge of external trigger */ + +/* ADC channel group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< ADC regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< ADC inserted channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC inserted channel 3 */ + +/* ADC channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ +#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ +#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ +#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ +#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ +#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ +#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ +#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC channel 18 */ +#define ADC_CHANNEL_19 ((uint8_t)0x13U) /*!< ADC channel 19 */ +#define ADC_CHANNEL_20 ((uint8_t)0x14U) /*!< ADC channel 20 */ + +/* analog watchdog 1/2 channel selection for channel n(n=0..20) */ +#define ADC_AWD1_2_SELECTION_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_16 ((uint32_t)0x00010000U) /*!< ADC channel 16 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_17 ((uint32_t)0x00020000U) /*!< ADC channel 17 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_18 ((uint32_t)0x00040000U) /*!< ADC channel 18 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_19 ((uint32_t)0x00080000U) /*!< ADC channel 19 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_20 ((uint32_t)0x00100000U) /*!< ADC channel 20 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_ALL ((uint32_t)0x003FFFFFU) /*!< all ADC channels analog watchdog 1/2 selection */ + +/* Differential mode for channel n(n=0..21) */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_16 ((uint32_t)0x00010000U) /*!< ADC channel 16 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_17 ((uint32_t)0x00020000U) /*!< ADC channel 17 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_18 ((uint32_t)0x00040000U) /*!< ADC channel 18 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_19 ((uint32_t)0x00080000U) /*!< ADC channel 19 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_20 ((uint32_t)0x00100000U) /*!< ADC channel 20 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_21 ((uint32_t)0x00200000U) /*!< ADC channel 21 differential mode */ +#define ADC_DIFFERENTIAL_MODE_CHANNEL_ALL ((uint32_t)0x003FFFFFU) /*!< all ADC channels differential mode */ + +/* function declarations */ +/* initialization config */ +/* reset ADC */ +void adc_deinit(uint32_t adc_periph); +/* configure the ADC clock */ +void adc_clock_config(uint32_t adc_periph, uint32_t prescaler); +/* enable or disable ADC special function */ +void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue); +/* configure ADC data alignment */ +void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment); +/* enable ADC interface */ +void adc_enable(uint32_t adc_periph); +/* disable ADC interface */ +void adc_disable(uint32_t adc_periph); +/* configure ADC calibration mode */ +void adc_calibration_mode_config(uint32_t adc_periph, uint32_t clb_mode); +/* configure ADC calibration number */ +void adc_calibration_number(uint32_t adc_periph, uint32_t clb_num); +/* ADC calibration and reset calibration */ +void adc_calibration_enable(uint32_t adc_periph); +/* configure ADC resolution */ +void adc_resolution_config(uint32_t adc_periph, uint32_t resolution); +/* enable or disable ADC internal channels */ +void adc_internal_channel_config(uint32_t internal_channel, ControlStatus newvalue); + +/* DMA config */ +/* enable DMA request */ +void adc_dma_mode_enable(uint32_t adc_periph); +/* disable DMA request */ +void adc_dma_mode_disable(uint32_t adc_periph); +/* when DMA=1, the DMA engine issues a request at end of each regular conversion */ +void adc_dma_request_after_last_enable(uint32_t adc_periph); +/* the DMA engine is disabled after the end of transfer signal from DMA controller is detected */ +void adc_dma_request_after_last_disable(uint32_t adc_periph); +/* enable hpdf mode */ +void adc_hpdf_mode_enable(uint32_t adc_periph); +/* disable hpdf mode */ +void adc_hpdf_mode_disable(uint32_t adc_periph); + +/* regular group and inserted group config */ +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length); +/* configure the length of regular channel group or inserted channel group */ +void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length); +/* configure ADC regular channel */ +void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); +/* configure ADC inserted channel */ +void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time); +/* configure ADC inserted channel offset */ +void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint32_t offset); +/* configure differential mode for channel */ +void adc_channel_differential_mode_config(uint32_t adc_periph, uint32_t adc_channel, ControlStatus newvalue); +/* enable ADC external trigger */ +void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t trigger_mode); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group); +/* configure end of conversion mode */ +void adc_end_of_conversion_config(uint32_t adc_periph, uint32_t end_selection); + +/* get channel data */ +/* read ADC regular group data register */ +uint32_t adc_regular_data_read(uint32_t adc_periph); +/* read ADC inserted group data register */ +uint32_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel); + +/* ADC analog watchdog functions */ +/* configure ADC analog watchdog 0 single channel */ +void adc_watchdog0_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel); +/* configure ADC analog watchdog 0 group channel */ +void adc_watchdog0_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group); +/* disable ADC analog watchdog 0 */ +void adc_watchdog0_disable(uint32_t adc_periph); +/* configure ADC analog watchdog 1 channel */ +void adc_watchdog1_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue); +/* configure ADC analog watchdog 2 channel */ +void adc_watchdog2_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue); +/* disable ADC analog watchdog 1 */ +void adc_watchdog1_disable(uint32_t adc_periph); +/* disable ADC analog watchdog 2 */ +void adc_watchdog2_disable(uint32_t adc_periph); +/* configure ADC analog watchdog 0 threshold */ +void adc_watchdog0_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold); +/* configure ADC analog watchdog 1 threshold */ +void adc_watchdog1_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold); +/* configure ADC analog watchdog 2 threshold */ +void adc_watchdog2_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold); + +/* ADC oversample functions */ +/* configure ADC oversample mode */ +void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint16_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(uint32_t adc_periph); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(uint32_t adc_periph); + +/* flag and interrupt functions */ +/* get the ADC flag bits */ +FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t flag); +/* clear the ADC flag bits */ +void adc_flag_clear(uint32_t adc_periph, uint32_t flag); +/* enable ADC interrupt */ +void adc_interrupt_enable(uint32_t adc_periph, uint32_t interrupt); +/* disable ADC interrupt */ +void adc_interrupt_disable(uint32_t adc_periph, uint32_t interrupt); +/* get the ADC interrupt bits */ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t int_flag); +/* clear the ADC flag */ +void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t int_flag); + +/* ADC synchronization */ +/* configure the ADC sync mode */ +void adc_sync_mode_config(uint32_t sync_mode); +/* configure the delay between 2 sampling phases in ADC sync modes */ +void adc_sync_delay_config(uint32_t sample_delay); +/* configure ADC sync DMA mode selection */ +void adc_sync_dma_config(uint32_t dma_mode); +/* configure ADC sync DMA engine issues requests according to the SYNCDMA bits */ +void adc_sync_dma_request_after_last_enable(void); +/* configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected */ +void adc_sync_dma_request_after_last_disable(void); +/* read ADC sync master adc regular data register 0 */ +uint32_t adc_sync_master_adc_regular_data0_read(void); +/* read ADC sync slave adc regular data register 0 */ +uint32_t adc_sync_slave_adc_regular_data0_read(void); +/* read ADC sync regular data register 1 */ +uint32_t adc_sync_regular_data1_read(void); + +#endif /* GD32H7XX_ADC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_axiim.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_axiim.h new file mode 100644 index 0000000000..e750b8b19c --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_axiim.h @@ -0,0 +1,226 @@ +/*! + \file gd32h7xx_axiim.h + \brief definitions for AXIIM(AXI interconnect matrix) + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_AXIIM_H +#define GD32H7XX_AXIIM_H + +#include "gd32h7xx.h" + +/* AXI interconnect matrix definitions */ +#define AXIIM_BASE ((uint32_t)0x51000000U) /*!< AXI interconnect matrix base address */ +#define AXIIM AXIIM_BASE /*!< AXI interconnect matrix definition */ + +/* registers definitions */ +#define AXI_PERIPH_ID4 REG32(AXIIM + 0x00001FD0U) /*!< AXI peripheral ID4 register */ +#define AXI_PERIPH_ID0 REG32(AXIIM + 0x00001FE0U) /*!< AXI peripheral ID0 register */ +#define AXI_PERIPH_ID1 REG32(AXIIM + 0x00001FE4U) /*!< AXI peripheral ID1 register */ +#define AXI_PERIPH_ID2 REG32(AXIIM + 0x00001FE8U) /*!< AXI peripheral ID2 register */ +#define AXI_PERIPH_ID3 REG32(AXIIM + 0x00001FECU) /*!< AXI peripheral ID3 register */ + +#define AXI_COMP_ID0 REG32(AXIIM + 0x00001FF0U) /*!< AXI componet ID0 register */ +#define AXI_COMP_ID1 REG32(AXIIM + 0x00001FF4U) /*!< AXI componet ID1 register */ +#define AXI_COMP_ID2 REG32(AXIIM + 0x00001FF8U) /*!< AXI componet ID2 register */ +#define AXI_COMP_ID3 REG32(AXIIM + 0x00001FFCU) /*!< AXI componet ID3 register */ + +#define AXI_MPXBM_ISS_CTL(mportx) REG32(AXIIM + 0x00002008U + 0x00001000U * (mportx)) /*!< AXI master port x bus matrix issuing functionality control register */ +#define AXI_MP0BM_ISS_CTL REG32(AXIIM + 0x00002008U) /*!< AXI master port 0 bus matrix issuing functionality control register */ +#define AXI_MP1BM_ISS_CTL REG32(AXIIM + 0x00003008U) /*!< AXI master port 1 bus matrix issuing functionality control register */ +#define AXI_MP2BM_ISS_CTL REG32(AXIIM + 0x00004008U) /*!< AXI master port 2 bus matrix issuing functionality control register */ +#define AXI_MP3BM_ISS_CTL REG32(AXIIM + 0x00005008U) /*!< AXI master port 3 bus matrix issuing functionality control register */ +#define AXI_MP4BM_ISS_CTL REG32(AXIIM + 0x00006008U) /*!< AXI master port 4 bus matrix issuing functionality control register */ +#define AXI_MP5BM_ISS_CTL REG32(AXIIM + 0x00007008U) /*!< AXI master port 5 bus matrix issuing functionality control register */ +#define AXI_MP6BM_ISS_CTL REG32(AXIIM + 0x00008008U) /*!< AXI master port 6 bus matrix issuing functionality control register */ +#define AXI_MP7BM_ISS_CTL REG32(AXIIM + 0x00009008U) /*!< AXI master port 7 bus matrix issuing functionality control register */ + +#define AXI_MPXBM_CTL(mportx) REG32(AXIIM + 0x00002024U + 0x00001000U * (mportx)) /*!< AXI master port x bus matrix functionality control register */ +#define AXI_MP0BM_CTL REG32(AXIIM + 0x00002024U) /*!< AXI master port 0 bus matrix functionality control register */ +#define AXI_MP1BM_CTL REG32(AXIIM + 0x00003024U) /*!< AXI master port 1 bus matrix functionality control register */ +#define AXI_MP6BM_CTL REG32(AXIIM + 0x00008024U) /*!< AXI master port 6 bus matrix functionality control register */ +#define AXI_MP7BM_CTL REG32(AXIIM + 0x00009024U) /*!< AXI master port 7 bus matrix functionality control register */ + +#define AXI_MPX_LB_CTL(mportx) REG32(AXIIM + 0x0000202CU + 0x00001000U * (mportx)) /*!< AXI master port x long burst functionality control register */ +#define AXI_MP0_LB_CTL REG32(AXIIM + 0x0000202CU) /*!< AXI master port 0 long burst functionality control register */ +#define AXI_MP1_LB_CTL REG32(AXIIM + 0x0000302CU) /*!< AXI master port 1 long burst functionality control register */ + +#define AXI_MPX_ISS_CTL(mportx) REG32(AXIIM + 0x00002108U + 0x00001000U * (mportx)) /*!< AXI master port x issuing functionality control register */ +#define AXI_MP0_ISS_CTL REG32(AXIIM + 0x00002108U) /*!< AXI master port 0 issuing functionality control register */ +#define AXI_MP1_ISS_CTL REG32(AXIIM + 0x00003108U) /*!< AXI master port 1 issuing functionality control register */ +#define AXI_MP6_ISS_CTL REG32(AXIIM + 0x00008108U) /*!< AXI master port 6 issuing functionality control register */ +#define AXI_MP7_ISS_CTL REG32(AXIIM + 0x00009108U) /*!< AXI master port 7 issuing functionality control register */ + +#define AXI_SPX_CTL(sportx) REG32(AXIIM + 0x00042024U + 0x00001000U * (sportx)) /*!< AXI slave port x functionality control register */ +#define AXI_SP0_CTL REG32(AXIIM + 0x00042024U) /*!< AXI slave port 0 functionality control register */ +#define AXI_SP2_CTL REG32(AXIIM + 0x00044024U) /*!< AXI slave port 2 functionality control register */ + +#define AXI_SPX_AHBISS_CTL(sportx) REG32(AXIIM + 0x00042028U + 0x00001000U * (sportx)) /*!< AXI slave port x AHB issuing functionality control register */ +#define AXI_SP0_AHBISS_CTL REG32(AXIIM + 0x00042028U) /*!< AXI slave port 0 AHB issuing functionality control register */ +#define AXI_SP2_AHBISS_CTL REG32(AXIIM + 0x00044028U) /*!< AXI slave port 2 AHB issuing functionality control register */ + +/* AXI slave port x = 0 to 5 */ +#define AXI_SPX_RDQOS_CTL(sportx) REG32(AXIIM + 0x00042100U + 0x00001000U * (sportx)) /*!< AXI slave port x read QOS control register */ +#define AXI_SPX_WRQOS_CTL(sportx) REG32(AXIIM + 0x00042104U + 0x00001000U * (sportx)) /*!< AXI slave port x write QOS control register */ +#define AXI_SPX_ISS_CTL(sportx) REG32(AXIIM + 0x00042108U + 0x00001000U * (sportx)) /*!< AXI slave port x issuing functionality control register */ + +#define AXI_PERIPH_ID4_JEP106CCODE BITS(0,3) /*!< JEP106 continuation code */ +#define AXI_PERIPH_ID4_4KBCNT BITS(4,7) /*!< register file size */ + +#define AXI_PERIPH_ID0_PARTNUM BITS(0,7) /*!< part number bit[7:0] */ + +#define AXI_PERIPH_ID1_PARTNUM BITS(0,3) /*!< part number bit[11:8] */ +#define AXI_PERIPH_ID1_JEP106ID BITS(4,7) /*!< JEP106 identity[3:0] */ + +#define AXI_PERIPH_ID2_JEP106ID BITS(0,2) /*!< JEP106 identity[6:4] */ +#define AXI_PERIPH_ID2_JEP106CF BIT(3) /*!< JEP106 code flag */ +#define AXI_PERIPH_ID2_PARTREV BITS(4,7) /*!< part revision */ + +#define AXI_PERIPH_ID3_CUSTMOD BITS(0,3) /*!< customer modification[3:0] */ +#define AXI_PERIPH_ID3_CUSTREV BITS(4,7) /*!< customer version */ + +#define AXI_COMP_ID0_PREAMB BITS(0,7) /*!< preamble bits[7:0] */ + +#define AXI_COMP_ID1_PREAMB BITS(0,3) /*!< preamble bits[11:8] */ +#define AXI_COMP_ID1_CLASS BITS(4,7) /*!< component class */ + +#define AXI_COMP_ID2_PREAMB BITS(0,7) /*!< preamble bits[19:12] */ + +#define AXI_COMP_ID3_PREAMB BITS(0,7) /*!< preamble bits[27:20] */ + +#define AXI_MPXBM_ISS_CTL_RD_ISSOV BIT(0) /*!< override target read issuing function */ +#define AXI_MPXBM_ISS_CTL_WR_ISSOV BIT(1) /*!< override target write issuing function */ + +#define AXI_MPXBM_CTL_BPDIS BIT(0) /*!< beats packing function disable configure */ + +#define AXI_MPX_LB_CTL_LBEN BIT(0) /*!< control long burst function */ + +#define AXI_MPX_ISS_CTL_RD_ISSOV BIT(0) /*!< override AMIB read issuing function */ +#define AXI_MPX_ISS_CTL_WR_ISSOV BIT(1) /*!< override AMIB write issuing function */ + +#define AXI_SPX_CTL_TRANSALT BIT(0) /*!< slave port transaction alteration configure bit */ + +#define AXI_SPX_AHBISS_CTL_WR_AHB_ISSOV BIT(0) /*!< converts AHB-Lite write transaction to single beat AXI transaction */ +#define AXI_SPX_AHBISS_CTL_RD_AHB_ISSOV BIT(1) /*!< converts AHB-Lite read transaction to single beat AXI transaction */ + +#define AXI_SPX_RDQOS_CTL_RDQOS BITS(0,3) /*!< slave port read channel QoS configure bits */ + +#define AXI_SPX_WRQOS_CTL_WRQOS BITS(0,3) /*!< slave port write channel QoS configure bits */ + +#define AXI_SPX_ISS_CTL_RD_ISSOV BIT(0) /*!< slave port override ASIB read issuing control bit */ +#define AXI_SPX_ISS_CTL_WR_ISSOV BIT(1) /*!< slave port override ASIB write issuing control bit */ + +/* AXI master port select */ +typedef enum +{ + MASTER_PORT0 = 0U, /*!< AXI master port 0 */ + MASTER_PORT1, /*!< AXI master port 1 */ + MASTER_PORT2, /*!< AXI master port 2 */ + MASTER_PORT3, /*!< AXI master port 3 */ + MASTER_PORT4, /*!< AXI master port 4 */ + MASTER_PORT5, /*!< AXI master port 5 */ + MASTER_PORT6, /*!< AXI master port 6 */ + MASTER_PORT7 /*!< AXI master port 7 */ +} master_port_enum; + +/* AXI slave port select */ +typedef enum +{ + SLAVE_PORT0 = 0U, /*!< AXI slave port 0 */ + SLAVE_PORT1, /*!< AXI slave port 1 */ + SLAVE_PORT2, /*!< AXI slave port 2 */ + SLAVE_PORT3, /*!< AXI slave port 3 */ + SLAVE_PORT4, /*!< AXI slave port 4 */ + SLAVE_PORT5 /*!< AXI slave port 5 */ +} slave_port_enum; + +/* AXI master port x bus mutrix read issuing capability is set to 1, mportx: MASTER_PORTx (x=0..7) */ +#define __AXI_MPXBM_READ_ISSOV_ENABLE(mportx) {AXI_MPXBM_ISS_CTL(mportx) |= AXI_MPXBM_ISS_CTL_RD_ISSOV} +/* AXI master port x bus mutrix read issuing capability is normal, mportx: MASTER_PORTx (x=0..7) */ +#define __AXI_MPXBM_READ_ISSOV_DISABLE(mportx) {AXI_MPXBM_ISS_CTL(mportx) &= ~AXI_MPXBM_ISS_CTL_RD_ISSOV} + +/* AXI master port x bus mutrix write issuing capability is set to 1, mportx: MASTER_PORTx (x=0..7) */ +#define __AXI_MPXBM_WRITE_ISSOV_ENABLE(mportx) {AXI_MPXBM_ISS_CTL(mportx) |= AXI_MPXBM_ISS_CTL_WR_ISSOV} +/* AXI master port x bus mutrix write issuing capability is normal, mportx: MASTER_PORTx (x=0..7) */ +#define __AXI_MPXBM_WRITE_ISSOV_DISABLE(mportx) {AXI_MPXBM_ISS_CTL(mportx) &= ~AXI_MPXBM_ISS_CTL_WR_ISSOV} + +/* enable AXI master port x beats packing function, mportx: MASTER_PORTx (x=0,1,6,7) */ +#define __AXI_MPXBM_BEATS_PACKING_ENABLE(mportx) {AXI_MPXBM_CTL(mportx) &= ~AXI_MPXBM_CTL_BPDIS} +/* disable AXI master port x beats packing function, mportx: MASTER_PORTx (x=0,1,6,7) */ +#define __AXI_MPXBM_BEATS_PACKING_DISABLE(mportx) {AXI_MPXBM_CTL(mportx) |= AXI_MPXBM_CTL_BPDIS} + +/* enable AXI master port long burst function, mportx: MASTER_PORTx (x=0,1) */ +#define __AXI_MPX_LONG_BURST_ENABLE(mportx) {AXI_MPX_LB_CTL(mportx) |= AXI_MPX_LB_CTL_LBEN} +/* disable AXI master port x long burst function, mportx: MASTER_PORTx (x=0,1) */ +#define __AXI_MPX_LONG_BURST_DISABLE(mportx) {AXI_MPX_LB_CTL(mportx) &= ~AXI_MPX_LB_CTL_LBEN} + +/* force AMIB read issuing capability to 1, mportx: MASTER_PORTx (x=0,1,2,7) */ +#define __AXI_MPX_READ_ISSOV_ENABLE(mportx) {AXI_MPX_ISS_CTL(mportx) |= AXI_MPX_ISS_CTL_RD_ISSOV} +/* AMIB read issuing capability is normal, mportx: MASTER_PORTx (x=0,1,2,7) */ +#define __AXI_MPX_READ_ISSOV_DISABLE(mportx) {AXI_MPX_ISS_CTL(mportx) &= ~AXI_MPX_ISS_CTL_RD_ISSOV} + +/* force AMIB write issuing capability to 1, mportx: MASTER_PORTx (x=0,1,2,7) */ +#define __AXI_MPX_WRITE_ISSOV_ENABLE(mportx) {AXI_MPX_ISS_CTL(mportx) |= AXI_MPX_ISS_CTL_WR_ISSOV} +/* AMIB write issuing capability is normal, mportx: MASTER_PORTx (x=0,1,2,7) */ +#define __AXI_MPX_WRITE_ISSOV_DISABLE(mportx) {AXI_MPX_ISS_CTL(mportx) &= ~AXI_MPX_ISS_CTL_WR_ISSOV} + +/* enable AXI slave port transaction alteration function, mportx: SLAVE_PORTx (x=0,2) */ +#define __AXI_SPX_TRANSACTION_ALTER_ENABLE(sportx) {AXI_SPX_CTL(sportx) |= AXI_SPX_CTL_TRANSALT} +/* AXI slave port transaction alteration function in normal operation, mportx: SLAVE_PORTx (x=0,2) */ +#define __AXI_SPX_TRANSACTION_ALTER_DISABLE(sportx) {AXI_SPX_CTL(sportx) &= ~AXI_SPX_CTL_TRANSALT} + +/* enable convert AHB-Lite write transaction to single beat AXI transaction, mportx: SLAVE_PORTx (x=0,2) */ +#define __AXI_SPX_CONVERT_AHB_WR_TO_SINGLE_BEAT_TRANS_ENABLE(sportx) {AXI_SPX_AHBISS_CTL(sportx) |= AXI_SPX_AHBISS_CTL_WR_AHB_ISSOV} +/* disable convert AHB-Lite write transaction to single beat AXI transaction, mportx: SLAVE_PORTx (x=0,2) */ +#define __AXI_SPX_CONVERT_AHB_WR_TO_SINGLE_BEAT_TRANS_DISABLE(sportx) {AXI_SPX_AHBISS_CTL(sportx) &= ~AXI_SPX_AHBISS_CTL_WR_AHB_ISSOV} + +/* enable convert AHB-Lite read transaction to single beat AXI transaction, mportx: SLAVE_PORTx (x=0,2) */ +#define __AXI_SPX_CONVERT_AHB_RD_TO_SINGLE_BEAT_TRANS_ENABLE(sportx) {AXI_SPX_AHBISS_CTL(sportx) |= AXI_SPX_AHBISS_CTL_RD_AHB_ISSOV} +/* disable convert AHB-Lite read transaction to single beat AXI transaction, mportx: SLAVE_PORTx (x=0,2) */ +#define __AXI_SPX_CONVERT_AHB_RD_TO_SINGLE_BEAT_TRANS_DISABLE(sportx) {AXI_SPX_AHBISS_CTL(sportx) &= ~AXI_SPX_AHBISS_CTL_RD_AHB_ISSOV} + +/* configure slave port read channel QoS, sportx: SLAVE_PORTx (x=0..5), priority: 0x0~0xF */ +#define __AXI_SPX_READ_QOS_SET(sportx, priority) {AXI_SPX_RDQOS_CTL(sportx) |= ( (priority) & AXI_SPX_RDQOS_CTL_RDQOS)} + +/* configure slave port write channel QoS, sportx: SLAVE_PORTx (x=0..5), priority: 0x0~0xF */ +#define __AXI_SPX_WRITE_QOS_SET(sportx, priority) {AXI_SPX_WRQOS_CTL(sportx) |= ( (priority) & AXI_SPX_WRQOS_CTL_WRQOS)} + +/* force ASIB read issuing capability to 1, sportx: SLAVE_PORTx (x=0..5) */ +#define __AXI_SPX_READ_ISSOV_ENABLE(sportx) {AXI_SPX_ISS_CTL(sportx) |= AXI_SPX_ISS_CTL_RD_ISSOV} +/* ASIB read issuing capability in normal operation, mportx: SLAVE_PORTx (x=0..5) */ +#define __AXI_SPX_READ_ISSOV_DISABLE(sportx) {AXI_SPX_ISS_CTL(sportx) &= ~AXI_SPX_ISS_CTL_RD_ISSOV} + +/* force ASIB write issuing capability to 1, sportx: SLAVE_PORTx (x=0..5) */ +#define __AXI_SPX_WRITE_ISSOV_ENABLE(sportx) {AXI_SPX_ISS_CTL(sportx) |= AXI_SPX_ISS_CTL_WD_ISSOV} +/* ASIB write issuing capability in normal operation, mportx: SLAVE_PORTx (x=0..5) */ +#define __AXI_SPX_WRITE_ISSOV_DISABLE(sportx) {AXI_SPX_ISS_CTL(sportx) &= ~AXI_SPX_ISS_CTL_WD_ISSOV} + +#endif /* GD32H7XX_AXIIM_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_can.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_can.h new file mode 100644 index 0000000000..782a648472 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_can.h @@ -0,0 +1,1278 @@ +/*! + \file gd32h7xx_can.h + \brief definitions for the CAN + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_CAN_H +#define GD32H7XX_CAN_H + +#include "gd32h7xx.h" + +/* CAN definitions */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN_BASE + 0x00001000U) /*!< CAN1 base address */ +#define CAN2 (CAN_BASE + 0x00002000U) /*!< CAN2 base address */ +#define CAN_RAM(canx) ((uint32_t)((canx) + 0x00000080U)) /*!< can ram base address */ +#define CAN_PN_RAM(canx) ((uint32_t)((canx) + 0x00000B40U)) /*!< Pretended Networking ram base address */ + +/* registers definitions */ +#define CAN_CTL0(canx) REG32((canx) + 0x00000000U) /*!< CAN control register 0 */ +#define CAN_CTL1(canx) REG32((canx) + 0x00000004U) /*!< CAN control register 1 */ +#define CAN_TIMER(canx) REG32((canx) + 0x00000008U) /*!< CAN timer register */ +#define CAN_RMPUBF(canx) REG32((canx) + 0x00000010U) /*!< CAN receive mailbox public filter register */ +#define CAN_ERR0(canx) REG32((canx) + 0x0000001CU) /*!< CAN error register 0 */ +#define CAN_ERR1(canx) REG32((canx) + 0x00000020U) /*!< CAN error register 1 */ +#define CAN_INTEN(canx) REG32((canx) + 0x00000028U) /*!< CAN interrupt enable register */ +#define CAN_STAT(canx) REG32((canx) + 0x00000030U) /*!< CAN status register */ +#define CAN_CTL2(canx) REG32((canx) + 0x00000034U) /*!< CAN control register 2 */ +#define CAN_CRCC(canx) REG32((canx) + 0x00000044U) /*!< CAN crc for classical frame register */ +#define CAN_RFIFOPUBF(canx) REG32((canx) + 0x00000048U) /*!< CAN receive fifo public filter register */ +#define CAN_RFIFOIFMN(canx) REG32((canx) + 0x0000004CU) /*!< CAN receive fifo identifier filter matching number register */ +#define CAN_BT(canx) REG32((canx) + 0x00000050U) /*!< CAN bit timing register */ +#define CAN_RFIFOMPF0(canx) REG32((canx) + 0x00000880U) /*!< CAN receive fifo / mailbox private filter 0 register */ +#define CAN_RFIFOMPF1(canx) REG32((canx) + 0x00000884U) /*!< CAN receive fifo / mailbox private filter 1 register */ +#define CAN_RFIFOMPF2(canx) REG32((canx) + 0x00000888U) /*!< CAN receive fifo / mailbox private filter 2 register */ +#define CAN_RFIFOMPF3(canx) REG32((canx) + 0x0000088CU) /*!< CAN receive fifo / mailbox private filter 3 register */ +#define CAN_RFIFOMPF4(canx) REG32((canx) + 0x00000890U) /*!< CAN receive fifo / mailbox private filter 4 register */ +#define CAN_RFIFOMPF5(canx) REG32((canx) + 0x00000894U) /*!< CAN receive fifo / mailbox private filter 5 register */ +#define CAN_RFIFOMPF6(canx) REG32((canx) + 0x00000898U) /*!< CAN receive fifo / mailbox private filter 6 register */ +#define CAN_RFIFOMPF7(canx) REG32((canx) + 0x0000089CU) /*!< CAN receive fifo / mailbox private filter 7 register */ +#define CAN_RFIFOMPF8(canx) REG32((canx) + 0x000008A0U) /*!< CAN receive fifo / mailbox private filter 8 register */ +#define CAN_RFIFOMPF9(canx) REG32((canx) + 0x000008A4U) /*!< CAN receive fifo / mailbox private filter 9 register */ +#define CAN_RFIFOMPF10(canx) REG32((canx) + 0x000008A8U) /*!< CAN receive fifo / mailbox private filter 10 register */ +#define CAN_RFIFOMPF11(canx) REG32((canx) + 0x000008ACU) /*!< CAN receive fifo / mailbox private filter 11 register */ +#define CAN_RFIFOMPF12(canx) REG32((canx) + 0x000008B0U) /*!< CAN receive fifo / mailbox private filter 12 register */ +#define CAN_RFIFOMPF13(canx) REG32((canx) + 0x000008B4U) /*!< CAN receive fifo / mailbox private filter 13 register */ +#define CAN_RFIFOMPF14(canx) REG32((canx) + 0x000008B8U) /*!< CAN receive fifo / mailbox private filter 14 register */ +#define CAN_RFIFOMPF15(canx) REG32((canx) + 0x000008BCU) /*!< CAN receive fifo / mailbox private filter 15 register */ +#define CAN_RFIFOMPF16(canx) REG32((canx) + 0x000008C0U) /*!< CAN receive fifo / mailbox private filter 16 register */ +#define CAN_RFIFOMPF17(canx) REG32((canx) + 0x000008C4U) /*!< CAN receive fifo / mailbox private filter 17 register */ +#define CAN_RFIFOMPF18(canx) REG32((canx) + 0x000008C8U) /*!< CAN receive fifo / mailbox private filter 18 register */ +#define CAN_RFIFOMPF19(canx) REG32((canx) + 0x000008CCU) /*!< CAN receive fifo / mailbox private filter 19 register */ +#define CAN_RFIFOMPF20(canx) REG32((canx) + 0x000008D0U) /*!< CAN receive fifo / mailbox private filter 20 register */ +#define CAN_RFIFOMPF21(canx) REG32((canx) + 0x000008D4U) /*!< CAN receive fifo / mailbox private filter 21 register */ +#define CAN_RFIFOMPF22(canx) REG32((canx) + 0x000008D8U) /*!< CAN receive fifo / mailbox private filter 22 register */ +#define CAN_RFIFOMPF23(canx) REG32((canx) + 0x000008DCU) /*!< CAN receive fifo / mailbox private filter 23 register */ +#define CAN_RFIFOMPF24(canx) REG32((canx) + 0x000008E0U) /*!< CAN receive fifo / mailbox private filter 24 register */ +#define CAN_RFIFOMPF25(canx) REG32((canx) + 0x000008E4U) /*!< CAN receive fifo / mailbox private filter 25 register */ +#define CAN_RFIFOMPF26(canx) REG32((canx) + 0x000008E8U) /*!< CAN receive fifo / mailbox private filter 26 register */ +#define CAN_RFIFOMPF27(canx) REG32((canx) + 0x000008ECU) /*!< CAN receive fifo / mailbox private filter 27 register */ +#define CAN_RFIFOMPF28(canx) REG32((canx) + 0x000008F0U) /*!< CAN receive fifo / mailbox private filter 28 register */ +#define CAN_RFIFOMPF29(canx) REG32((canx) + 0x000008F4U) /*!< CAN receive fifo / mailbox private filter 29 register */ +#define CAN_RFIFOMPF30(canx) REG32((canx) + 0x000008F8U) /*!< CAN receive fifo / mailbox private filter 30 register */ +#define CAN_RFIFOMPF31(canx) REG32((canx) + 0x000008FCU) /*!< CAN receive fifo / mailbox private filter 31 register */ +#define CAN_PN_CTL0(canx) REG32((canx) + 0x00000B00U) /*!< Pretended Networking mode control register 0 */ +#define CAN_PN_TO(canx) REG32((canx) + 0x00000B04U) /*!< Pretended Networking mode timeout register */ +#define CAN_PN_STAT(canx) REG32((canx) + 0x00000B08U) /*!< Pretended Networking mode status register */ +#define CAN_PN_EID0(canx) REG32((canx) + 0x00000B0CU) /*!< Pretended Networking mode expected identifier 0 register */ +#define CAN_PN_EDLC(canx) REG32((canx) + 0x00000B10U) /*!< Pretended Networking mode expected dlc register */ +#define CAN_PN_EDL0(canx) REG32((canx) + 0x00000B14U) /*!< Pretended Networking mode expected data low 0 register */ +#define CAN_PN_EDL1(canx) REG32((canx) + 0x00000B18U) /*!< Pretended Networking mode expected data low 1 register */ +#define CAN_PN_IFEID1(canx) REG32((canx) + 0x00000B1CU) /*!< Pretended Networking mode identifier filter / expected identifier 1 register */ +#define CAN_PN_DF0EDH0(canx) REG32((canx) + 0x00000B20U) /*!< Pretended Networking mode data 0 filter / expected data high 0 register */ +#define CAN_PN_DF1EDH1(canx) REG32((canx) + 0x00000B24U) /*!< Pretended Networking mode data 1 filter / expected data high 1 register */ +#define CAN_PN_RWM0CS(canx) REG32((canx) + 0x00000B40U) /*!< Pretended Networking mode received wakeup mailbox 0 control status information register */ +#define CAN_PN_RWM0I(canx) REG32((canx) + 0x00000B44U) /*!< Pretended Networking mode received wakeup mailbox 0 identifier register */ +#define CAN_PN_RWM0D0(canx) REG32((canx) + 0x00000B48U) /*!< Pretended Networking mode received wakeup mailbox 0 data 0 register */ +#define CAN_PN_RWM0D1(canx) REG32((canx) + 0x00000B4CU) /*!< Pretended Networking mode received wakeup mailbox 0 data 1 register */ +#define CAN_PN_RWM1CS(canx) REG32((canx) + 0x00000B50U) /*!< Pretended Networking mode received wakeup mailbox 1 control status information register */ +#define CAN_PN_RWM1I(canx) REG32((canx) + 0x00000B54U) /*!< Pretended Networking mode received wakeup mailbox 1 identifier register */ +#define CAN_PN_RWM1D0(canx) REG32((canx) + 0x00000B58U) /*!< Pretended Networking mode received wakeup mailbox 1 data 0 register */ +#define CAN_PN_RWM1D1(canx) REG32((canx) + 0x00000B5CU) /*!< Pretended Networking mode received wakeup mailbox 1 data 1 register */ +#define CAN_PN_RWM2CS(canx) REG32((canx) + 0x00000B60U) /*!< Pretended Networking mode received wakeup mailbox 2 control status information register */ +#define CAN_PN_RWM2I(canx) REG32((canx) + 0x00000B64U) /*!< Pretended Networking mode received wakeup mailbox 2 identifier register */ +#define CAN_PN_RWM2D0(canx) REG32((canx) + 0x00000B68U) /*!< Pretended Networking mode received wakeup mailbox 2 data 0 register */ +#define CAN_PN_RWM2D1(canx) REG32((canx) + 0x00000B6CU) /*!< Pretended Networking mode received wakeup mailbox 2 data 1 register */ +#define CAN_PN_RWM3CS(canx) REG32((canx) + 0x00000B70U) /*!< Pretended Networking mode received wakeup mailbox 3 control status information register */ +#define CAN_PN_RWM3I(canx) REG32((canx) + 0x00000B74U) /*!< Pretended Networking mode received wakeup mailbox 3 identifier register */ +#define CAN_PN_RWM3D0(canx) REG32((canx) + 0x00000B78U) /*!< Pretended Networking mode received wakeup mailbox 3 data 0 register */ +#define CAN_PN_RWM3D1(canx) REG32((canx) + 0x00000B7CU) /*!< Pretended Networking mode received wakeup mailbox 3 data 1 register */ +#define CAN_FDCTL(canx) REG32((canx) + 0x00000C00U) /*!< CAN FD control register */ +#define CAN_FDBT(canx) REG32((canx) + 0x00000C04U) /*!< CAN bit timing register */ +#define CAN_CRCCFD(canx) REG32((canx) + 0x00000C08U) /*!< CAN CRC for classical and FD frame register */ + +/* bits definitions */ +/* CAN_CTL0 */ +#define CAN_CTL0_MSZ BITS(0, 4) /*!< memory size */ +#define CAN_CTL0_FS BITS(8, 9) /*!< format selection */ +#define CAN_CTL0_FDEN BIT(11) /*!< CAN FD operation enable */ +#define CAN_CTL0_MST BIT(12) /*!< mailbox stop transmission */ +#define CAN_CTL0_LAPRIOEN BIT(13) /*!< enable local arbitration priority */ +#define CAN_CTL0_PNMOD BIT(14) /*!< Pretended Networking mode selection */ +#define CAN_CTL0_DMAEN BIT(15) /*!< enable DMA */ +#define CAN_CTL0_RPFQEN BIT(16) /*!< enable rx private filters enable & rx mailbox queue */ +#define CAN_CTL0_SRDIS BIT(17) /*!< enable self reception */ +#define CAN_CTL0_PNS BIT(18) /*!< Pretended Networking state */ +#define CAN_CTL0_PNEN BIT(19) /*!< enable Pretended Networking mode */ +#define CAN_CTL0_LPS BIT(20) /*!< low power state */ +#define CAN_CTL0_WERREN BIT(21) /*!< enable error warning */ +#define CAN_CTL0_INAS BIT(24) /*!< inactive mode state */ +#define CAN_CTL0_SWRST BIT(25) /*!< software reset */ +#define CAN_CTL0_NRDY BIT(27) /*!< not ready */ +#define CAN_CTL0_HALT BIT(28) /*!< halt CAN */ +#define CAN_CTL0_RFEN BIT(29) /*!< rx fifo enable */ +#define CAN_CTL0_INAMOD BIT(30) /*!< enable inactive mode */ +#define CAN_CTL0_CANDIS BIT(31) /*!< disable CAN */ + +/* CAN_CTL1 */ +#define CAN_CTL1_MMOD BIT(3) /*!< monitor mode */ +#define CAN_CTL1_MTO BIT(4) /*!< mailbox transmission order */ +#define CAN_CTL1_TSYNC BIT(5) /*!< enable time synchronization */ +#define CAN_CTL1_ABORDIS BIT(6) /*!< not enable automatic bus off recovery */ +#define CAN_CTL1_BSPMOD BIT(7) /*!< bit sampling mode */ +#define CAN_CTL1_RWERRIE BIT(10) /*!< enable rx error warning interrupt */ +#define CAN_CTL1_TWERRIE BIT(11) /*!< enable tx error warning interrupt */ +#define CAN_CTL1_LSCMOD BIT(12) /*!< loopback and silent communication mode */ +#define CAN_CTL1_ERRSIE BIT(14) /*!< enable error summary interrupt */ +#define CAN_CTL1_BOIE BIT(15) /*!< enable bus off interrupt */ + +/* CAN_TIMER */ +#define CAN_TIMER_CNT BITS(0,15) /*!< counter value */ + +/* CAN_RMPUBF */ +#define CAN_RMPUBF_MFD0 BIT(0) /*!< mailbox filter data bit 0 */ +#define CAN_RMPUBF_MFD1 BIT(1) /*!< mailbox filter data bit 1 */ +#define CAN_RMPUBF_MFD2 BIT(2) /*!< mailbox filter data bit 2 */ +#define CAN_RMPUBF_MFD3 BIT(3) /*!< mailbox filter data bit 3 */ +#define CAN_RMPUBF_MFD4 BIT(4) /*!< mailbox filter data bit 4 */ +#define CAN_RMPUBF_MFD5 BIT(5) /*!< mailbox filter data bit 5 */ +#define CAN_RMPUBF_MFD6 BIT(6) /*!< mailbox filter data bit 6 */ +#define CAN_RMPUBF_MFD7 BIT(7) /*!< mailbox filter data bit 7 */ +#define CAN_RMPUBF_MFD8 BIT(8) /*!< mailbox filter data bit 8 */ +#define CAN_RMPUBF_MFD9 BIT(9) /*!< mailbox filter data bit 9 */ +#define CAN_RMPUBF_MFD10 BIT(10) /*!< mailbox filter data bit 10 */ +#define CAN_RMPUBF_MFD11 BIT(11) /*!< mailbox filter data bit 11 */ +#define CAN_RMPUBF_MFD12 BIT(12) /*!< mailbox filter data bit 12 */ +#define CAN_RMPUBF_MFD13 BIT(13) /*!< mailbox filter data bit 13 */ +#define CAN_RMPUBF_MFD14 BIT(14) /*!< mailbox filter data bit 14 */ +#define CAN_RMPUBF_MFD15 BIT(15) /*!< mailbox filter data bit 15 */ +#define CAN_RMPUBF_MFD16 BIT(16) /*!< mailbox filter data bit 16 */ +#define CAN_RMPUBF_MFD17 BIT(17) /*!< mailbox filter data bit 17 */ +#define CAN_RMPUBF_MFD18 BIT(18) /*!< mailbox filter data bit 18 */ +#define CAN_RMPUBF_MFD19 BIT(19) /*!< mailbox filter data bit 19 */ +#define CAN_RMPUBF_MFD20 BIT(20) /*!< mailbox filter data bit 20 */ +#define CAN_RMPUBF_MFD21 BIT(21) /*!< mailbox filter data bit 21 */ +#define CAN_RMPUBF_MFD22 BIT(22) /*!< mailbox filter data bit 22 */ +#define CAN_RMPUBF_MFD23 BIT(23) /*!< mailbox filter data bit 23 */ +#define CAN_RMPUBF_MFD24 BIT(24) /*!< mailbox filter data bit 24 */ +#define CAN_RMPUBF_MFD25 BIT(25) /*!< mailbox filter data bit 25 */ +#define CAN_RMPUBF_MFD26 BIT(26) /*!< mailbox filter data bit 26 */ +#define CAN_RMPUBF_MFD27 BIT(27) /*!< mailbox filter data bit 27 */ +#define CAN_RMPUBF_MFD28 BIT(28) /*!< mailbox filter data bit 28 */ +#define CAN_RMPUBF_MFD29 BIT(29) /*!< mailbox filter data bit 29 */ +#define CAN_RMPUBF_MFD30 BIT(30) /*!< mailbox filter data bit 30 */ +#define CAN_RMPUBF_MFD31 BIT(31) /*!< mailbox filter data bit 31 */ + +/* CAN_ERR0 */ +#define CAN_ERR0_TECNT BITS(0, 7) /*!< transmit error count defined by the CAN standard */ +#define CAN_ERR0_RECNT BITS(8, 15) /*!< receive error count defined by the CAN standard */ +#define CAN_ERR0_TEFCNT BITS(16, 23) /*!< transmit error count for the data phase of FD frames with BRS bit set */ +#define CAN_ERR0_REFCNT BITS(24, 31) /*!< receive error count for the data phase of FD frames with BRS bit set */ + +/* CAN_ERR1 */ +#define CAN_ERR1_ERRSF BIT(1) /*!< error summary flag */ +#define CAN_ERR1_BOF BIT(2) /*!< bus off flag */ +#define CAN_ERR1_RS BIT(3) /*!< receiving state */ +#define CAN_ERR1_ERRSI BITS(4, 5) /*!< error state indicator */ +#define CAN_ERR1_TS BIT(6) /*!< transmitting state */ +#define CAN_ERR1_IDLEF BIT(7) /*!< idle flag */ +#define CAN_ERR1_RWERRF BIT(8) /*!< rx error warning flag */ +#define CAN_ERR1_TWERRF BIT(9) /*!< tx error warning flag */ +#define CAN_ERR1_STFERR BIT(10) /*!< stuff error */ +#define CAN_ERR1_FMERR BIT(11) /*!< form error */ +#define CAN_ERR1_CRCERR BIT(12) /*!< CRC error */ +#define CAN_ERR1_ACKERR BIT(13) /*!< ACK error */ +#define CAN_ERR1_BDERR BIT(14) /*!< bit dominant error for all format frames */ +#define CAN_ERR1_BRERR BIT(15) /*!< bit recessive error for all format frames */ +#define CAN_ERR1_RWERRIF BIT(16) /*!< rx error warning interrupt flag */ +#define CAN_ERR1_TWERRIF BIT(17) /*!< tx error warning interrupt flag */ +#define CAN_ERR1_SYN BIT(18) /*!< synchronization flag */ +#define CAN_ERR1_BORF BIT(19) /*!< bus off recovery flag */ +#define CAN_ERR1_ERRFSF BIT(20) /*!< error summary flag for data phase of FD frames with BRS bit set */ +#define CAN_ERR1_ERROVR BIT(21) /*!< error overrun */ +#define CAN_ERR1_STFFERR BIT(26) /*!< stuff error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_FMFERR BIT(27) /*!< form error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_CRCFERR BIT(28) /*!< CRC error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_BDFERR BIT(30) /*!< bit dominant error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_BRFERR BIT(31) /*!< bit recessive error in data phase of FD frames with BRS bit set */ + +/* CAN_INTEN */ +#define CAN_INTEN_MIE0 BIT(0) /*!< enable message 0 transmission and reception interrupt */ +#define CAN_INTEN_MIE1 BIT(1) /*!< enable message 1 transmission and reception interrupt */ +#define CAN_INTEN_MIE2 BIT(2) /*!< enable message 2 transmission and reception interrupt */ +#define CAN_INTEN_MIE3 BIT(3) /*!< enable message 3 transmission and reception interrupt */ +#define CAN_INTEN_MIE4 BIT(4) /*!< enable message 4 transmission and reception interrupt */ +#define CAN_INTEN_MIE5 BIT(5) /*!< enable message 5 transmission and reception interrupt */ +#define CAN_INTEN_MIE6 BIT(6) /*!< enable message 6 transmission and reception interrupt */ +#define CAN_INTEN_MIE7 BIT(7) /*!< enable message 7 transmission and reception interrupt */ +#define CAN_INTEN_MIE8 BIT(8) /*!< enable message 8 transmission and reception interrupt */ +#define CAN_INTEN_MIE9 BIT(9) /*!< enable message 9 transmission and reception interrupt */ +#define CAN_INTEN_MIE10 BIT(10) /*!< enable message 10 transmission and reception interrupt */ +#define CAN_INTEN_MIE11 BIT(11) /*!< enable message 11 transmission and reception interrupt */ +#define CAN_INTEN_MIE12 BIT(12) /*!< enable message 12 transmission and reception interrupt */ +#define CAN_INTEN_MIE13 BIT(13) /*!< enable message 13 transmission and reception interrupt */ +#define CAN_INTEN_MIE14 BIT(14) /*!< enable message 14 transmission and reception interrupt */ +#define CAN_INTEN_MIE15 BIT(15) /*!< enable message 15 transmission and reception interrupt */ +#define CAN_INTEN_MIE16 BIT(16) /*!< enable message 16 transmission and reception interrupt */ +#define CAN_INTEN_MIE17 BIT(17) /*!< enable message 17 transmission and reception interrupt */ +#define CAN_INTEN_MIE18 BIT(18) /*!< enable message 18 transmission and reception interrupt */ +#define CAN_INTEN_MIE19 BIT(19) /*!< enable message 19 transmission and reception interrupt */ +#define CAN_INTEN_MIE20 BIT(20) /*!< enable message 20 transmission and reception interrupt */ +#define CAN_INTEN_MIE21 BIT(21) /*!< enable message 21 transmission and reception interrupt */ +#define CAN_INTEN_MIE22 BIT(22) /*!< enable message 22 transmission and reception interrupt */ +#define CAN_INTEN_MIE23 BIT(23) /*!< enable message 23 transmission and reception interrupt */ +#define CAN_INTEN_MIE24 BIT(24) /*!< enable message 24 transmission and reception interrupt */ +#define CAN_INTEN_MIE25 BIT(25) /*!< enable message 25 transmission and reception interrupt */ +#define CAN_INTEN_MIE26 BIT(26) /*!< enable message 26 transmission and reception interrupt */ +#define CAN_INTEN_MIE27 BIT(27) /*!< enable message 27 transmission and reception interrupt */ +#define CAN_INTEN_MIE28 BIT(28) /*!< enable message 28 transmission and reception interrupt */ +#define CAN_INTEN_MIE29 BIT(29) /*!< enable message 29 transmission and reception interrupt */ +#define CAN_INTEN_MIE30 BIT(30) /*!< enable message 30 transmission and reception interrupt */ +#define CAN_INTEN_MIE31 BIT(31) /*!< enable message 31 transmission and reception interrupt */ + +/* CAN_STAT */ +#define CAN_STAT_MS0_RFC BIT(0) /*!< mailbox 0 state / clear rx fifo bit */ +#define CAN_STAT_MS1_RES BIT(1) /*!< mailbox 1 state */ +#define CAN_STAT_MS2_RES BIT(2) /*!< mailbox 2 state */ +#define CAN_STAT_MS3_RES BIT(3) /*!< mailbox 3 state */ +#define CAN_STAT_MS4_RES BIT(4) /*!< mailbox 4 state */ +#define CAN_STAT_MS5_RFNE BIT(5) /*!< mailbox 5 state / rx fifo not empty */ +#define CAN_STAT_MS6_RFW BIT(6) /*!< mailbox 6 state / rx fifo warning */ +#define CAN_STAT_MS7_RFO BIT(7) /*!< mailbox 7 state / rx fifo overflow */ +#define CAN_STAT_MS8 BIT(8) /*!< mailbox 8 state */ +#define CAN_STAT_MS9 BIT(9) /*!< mailbox 9 state */ +#define CAN_STAT_MS10 BIT(10) /*!< mailbox 10 state */ +#define CAN_STAT_MS11 BIT(11) /*!< mailbox 11 state */ +#define CAN_STAT_MS12 BIT(12) /*!< mailbox 12 state */ +#define CAN_STAT_MS13 BIT(13) /*!< mailbox 13 state */ +#define CAN_STAT_MS14 BIT(14) /*!< mailbox 14 state */ +#define CAN_STAT_MS15 BIT(15) /*!< mailbox 15 state */ +#define CAN_STAT_MS16 BIT(16) /*!< mailbox 16 state */ +#define CAN_STAT_MS17 BIT(17) /*!< mailbox 17 state */ +#define CAN_STAT_MS18 BIT(18) /*!< mailbox 18 state */ +#define CAN_STAT_MS19 BIT(19) /*!< mailbox 19 state */ +#define CAN_STAT_MS20 BIT(20) /*!< mailbox 20 state */ +#define CAN_STAT_MS21 BIT(21) /*!< mailbox 21 state */ +#define CAN_STAT_MS22 BIT(22) /*!< mailbox 22 state */ +#define CAN_STAT_MS23 BIT(23) /*!< mailbox 23 state */ +#define CAN_STAT_MS24 BIT(24) /*!< mailbox 24 state */ +#define CAN_STAT_MS25 BIT(25) /*!< mailbox 25 state */ +#define CAN_STAT_MS26 BIT(26) /*!< mailbox 26 state */ +#define CAN_STAT_MS27 BIT(27) /*!< mailbox 27 state */ +#define CAN_STAT_MS28 BIT(28) /*!< mailbox 28 state */ +#define CAN_STAT_MS29 BIT(29) /*!< mailbox 29 state */ +#define CAN_STAT_MS30 BIT(30) /*!< mailbox 30 state */ +#define CAN_STAT_MS31 BIT(31) /*!< mailbox 31 state */ + +/* CAN_CTL2 */ +#define CAN_CTL2_EFDIS BIT(11) /*!< disable edge filtering */ +#define CAN_CTL2_ISO BIT(12) /*!< ISO CAN FD */ +#define CAN_CTL2_PREEN BIT(14) /*!< protocol exception detection enable by CAN standard */ +#define CAN_CTL2_ITSRC BIT(15) /*!< internal counter source */ +#define CAN_CTL2_IDERTR_RMF BIT(16) /*!< IDE and RTR field filter type for rx mailbox reception */ +#define CAN_CTL2_RRFRMS BIT(17) /*!< remote request frame is stored */ +#define CAN_CTL2_RFO BIT(18) /*!< receive filter order */ +#define CAN_CTL2_ASD BITS(19, 23) /*!< arbitration start delay */ +#define CAN_CTL2_RFFN BITS(24, 27) /*!< rx fifo filter number */ +#define CAN_CTL2_BORIE BIT(30) /*!< enable bus off recovery interrupt */ +#define CAN_CTL2_ERRFSIE BIT(31) /*!< error summary interrupt enable bit for data phase of FD frames with BRS bit set */ + +/* CAN_CRCC */ +#define CAN_CRCC_CRCTC BITS(0, 14) /*!< transmitted CRC value for classical frames */ +#define CAN_CRCC_ANTM BITS(16, 20) /*!< associated number of mailbox for transmitting the CRCTC[14:0] value */ + +/* CAN_RFIFOPUBF */ +#define CAN_RFIFOPUBF_FFD0 BIT(0) /*!< rx fifo filter data bit 0 */ +#define CAN_RFIFOPUBF_FFD1 BIT(1) /*!< rx fifo filter data bit 1 */ +#define CAN_RFIFOPUBF_FFD2 BIT(2) /*!< rx fifo filter data bit 2 */ +#define CAN_RFIFOPUBF_FFD3 BIT(3) /*!< rx fifo filter data bit 3 */ +#define CAN_RFIFOPUBF_FFD4 BIT(4) /*!< rx fifo filter data bit 4 */ +#define CAN_RFIFOPUBF_FFD5 BIT(5) /*!< rx fifo filter data bit 5 */ +#define CAN_RFIFOPUBF_FFD6 BIT(6) /*!< rx fifo filter data bit 6 */ +#define CAN_RFIFOPUBF_FFD7 BIT(7) /*!< rx fifo filter data bit 7 */ +#define CAN_RFIFOPUBF_FFD8 BIT(8) /*!< rx fifo filter data bit 8 */ +#define CAN_RFIFOPUBF_FFD9 BIT(9) /*!< rx fifo filter data bit 9 */ +#define CAN_RFIFOPUBF_FFD10 BIT(10) /*!< rx fifo filter data bit 10 */ +#define CAN_RFIFOPUBF_FFD11 BIT(11) /*!< rx fifo filter data bit 11 */ +#define CAN_RFIFOPUBF_FFD12 BIT(12) /*!< rx fifo filter data bit 12 */ +#define CAN_RFIFOPUBF_FFD13 BIT(13) /*!< rx fifo filter data bit 13 */ +#define CAN_RFIFOPUBF_FFD14 BIT(14) /*!< rx fifo filter data bit 14 */ +#define CAN_RFIFOPUBF_FFD15 BIT(15) /*!< rx fifo filter data bit 15 */ +#define CAN_RFIFOPUBF_FFD16 BIT(16) /*!< rx fifo filter data bit 16 */ +#define CAN_RFIFOPUBF_FFD17 BIT(17) /*!< rx fifo filter data bit 17 */ +#define CAN_RFIFOPUBF_FFD18 BIT(18) /*!< rx fifo filter data bit 18 */ +#define CAN_RFIFOPUBF_FFD19 BIT(19) /*!< rx fifo filter data bit 19 */ +#define CAN_RFIFOPUBF_FFD20 BIT(20) /*!< rx fifo filter data bit 20 */ +#define CAN_RFIFOPUBF_FFD21 BIT(21) /*!< rx fifo filter data bit 21 */ +#define CAN_RFIFOPUBF_FFD22 BIT(22) /*!< rx fifo filter data bit 22 */ +#define CAN_RFIFOPUBF_FFD23 BIT(23) /*!< rx fifo filter data bit 23 */ +#define CAN_RFIFOPUBF_FFD24 BIT(24) /*!< rx fifo filter data bit 24 */ +#define CAN_RFIFOPUBF_FFD25 BIT(25) /*!< rx fifo filter data bit 25 */ +#define CAN_RFIFOPUBF_FFD26 BIT(26) /*!< rx fifo filter data bit 26 */ +#define CAN_RFIFOPUBF_FFD27 BIT(27) /*!< rx fifo filter data bit 27 */ +#define CAN_RFIFOPUBF_FFD28 BIT(28) /*!< rx fifo filter data bit 28 */ +#define CAN_RFIFOPUBF_FFD29 BIT(29) /*!< rx fifo filter data bit 29 */ +#define CAN_RFIFOPUBF_FFD30 BIT(30) /*!< rx fifo filter data bit 30 */ +#define CAN_RFIFOPUBF_FFD31 BIT(31) /*!< rx fifo filter data bit 31 */ + +/* CAN_RFIFOIFMN */ +#define CAN_RFIFOIFMN_IDFMN BITS(0, 8) /*!< identifier filter matching number */ + +/* CAN_BT */ +#define CAN_BT_PBS2 BITS(0, 4) /*!< phase buffer segment 2 */ +#define CAN_BT_PBS1 BITS(5, 9) /*!< phase buffer segment 1 */ +#define CAN_BT_PTS BITS(10, 15) /*!< propagation time segment */ +#define CAN_BT_SJW BITS(16, 20) /*!< resynchronization jump width */ +#define CAN_BT_BAUDPSC BITS(21, 30) /*!< baud rate prescaler */ + +/* CAN_RFIFOMPFx, x = 0..31 */ +#define CAN_RFIFOMPF_FMFD0 BIT(0) /*!< fifo / mailbox filter data bit 0 */ +#define CAN_RFIFOMPF_FMFD1 BIT(1) /*!< fifo / mailbox filter data bit 1 */ +#define CAN_RFIFOMPF_FMFD2 BIT(2) /*!< fifo / mailbox filter data bit 2 */ +#define CAN_RFIFOMPF_FMFD3 BIT(3) /*!< fifo / mailbox filter data bit 3 */ +#define CAN_RFIFOMPF_FMFD4 BIT(4) /*!< fifo / mailbox filter data bit 4 */ +#define CAN_RFIFOMPF_FMFD5 BIT(5) /*!< fifo / mailbox filter data bit 5 */ +#define CAN_RFIFOMPF_FMFD6 BIT(6) /*!< fifo / mailbox filter data bit 6 */ +#define CAN_RFIFOMPF_FMFD7 BIT(7) /*!< fifo / mailbox filter data bit 7 */ +#define CAN_RFIFOMPF_FMFD8 BIT(8) /*!< fifo / mailbox filter data bit 8 */ +#define CAN_RFIFOMPF_FMFD9 BIT(9) /*!< fifo / mailbox filter data bit 9 */ +#define CAN_RFIFOMPF_FMFD10 BIT(10) /*!< fifo / mailbox filter data bit 10 */ +#define CAN_RFIFOMPF_FMFD11 BIT(11) /*!< fifo / mailbox filter data bit 11 */ +#define CAN_RFIFOMPF_FMFD12 BIT(12) /*!< fifo / mailbox filter data bit 12 */ +#define CAN_RFIFOMPF_FMFD13 BIT(13) /*!< fifo / mailbox filter data bit 13 */ +#define CAN_RFIFOMPF_FMFD14 BIT(14) /*!< fifo / mailbox filter data bit 14 */ +#define CAN_RFIFOMPF_FMFD15 BIT(15) /*!< fifo / mailbox filter data bit 15 */ +#define CAN_RFIFOMPF_FMFD16 BIT(16) /*!< fifo / mailbox filter data bit 16 */ +#define CAN_RFIFOMPF_FMFD17 BIT(17) /*!< fifo / mailbox filter data bit 17 */ +#define CAN_RFIFOMPF_FMFD18 BIT(18) /*!< fifo / mailbox filter data bit 18 */ +#define CAN_RFIFOMPF_FMFD19 BIT(19) /*!< fifo / mailbox filter data bit 19 */ +#define CAN_RFIFOMPF_FMFD20 BIT(20) /*!< fifo / mailbox filter data bit 20 */ +#define CAN_RFIFOMPF_FMFD21 BIT(21) /*!< fifo / mailbox filter data bit 21 */ +#define CAN_RFIFOMPF_FMFD22 BIT(22) /*!< fifo / mailbox filter data bit 22 */ +#define CAN_RFIFOMPF_FMFD23 BIT(23) /*!< fifo / mailbox filter data bit 23 */ +#define CAN_RFIFOMPF_FMFD24 BIT(24) /*!< fifo / mailbox filter data bit 24 */ +#define CAN_RFIFOMPF_FMFD25 BIT(25) /*!< fifo / mailbox filter data bit 25 */ +#define CAN_RFIFOMPF_FMFD26 BIT(26) /*!< fifo / mailbox filter data bit 26 */ +#define CAN_RFIFOMPF_FMFD27 BIT(27) /*!< fifo / mailbox filter data bit 27 */ +#define CAN_RFIFOMPF_FMFD28 BIT(28) /*!< fifo / mailbox filter data bit 28 */ +#define CAN_RFIFOMPF_FMFD29 BIT(29) /*!< fifo / mailbox filter data bit 29 */ +#define CAN_RFIFOMPF_FMFD30 BIT(30) /*!< fifo / mailbox filter data bit 30 */ +#define CAN_RFIFOMPF_FMFD31 BIT(31) /*!< fifo / mailbox filter data bit 31 */ + +/* CAN_PN_CTL0 */ +#define CAN_PN_CTL0_FFT BITS(0, 1) /*!< frame filtering type in Pretended Networking mode */ +#define CAN_PN_CTL0_IDFT BITS(2, 3) /*!< ID field filtering type in Pretended Networking mode */ +#define CAN_PN_CTL0_DATAFT BITS(4, 5) /*!< data field filtering type in Pretended Networking mode */ +#define CAN_PN_CTL0_NMM BITS(8, 15) /*!< number of messages matching times */ +#define CAN_PN_CTL0_WMIE BIT(16) /*!< enable wakeup match interrupt */ +#define CAN_PN_CTL0_WTOIE BIT(17) /*!< enable wakeup timeout interrupt */ + +/* CAN_PN_TO */ +#define CAN_PN_TO_WTO BITS(0, 15) /*!< wakeup timeout */ + +/* CAN_PN_STAT */ +#define CAN_PN_STAT_MMCNTS BIT(7) /*!< matching message counter state */ +#define CAN_PN_STAT_MMCNT BITS(8, 15) /*!< matching message counter in Pretended Networking mode */ +#define CAN_PN_STAT_WMS BIT(16) /*!< wakeup match flag status */ +#define CAN_PN_STAT_WTOS BIT(17) /*!< wakeup timeout flag status */ + +/* CAN_PN_EID0 */ +#define CAN_PN_EID0_EID_ELT BITS(0, 28) /*!< expected ID field / expected ID low threshold in Pretended Networking mode */ +#define CAN_PN_EID0_ERTR BIT(29) /*!< expected RTR in Pretended Networking mode */ +#define CAN_PN_EID0_EIDE BIT(30) /*!< expected IDE in Pretended Networking mode */ + +/* CAN_PN_EDLC */ +#define CAN_PN_EDLC_DLCEHT BITS(0, 3) /*!< DLC expected high threshold in Pretended Networking mode */ +#define CAN_PN_EDLC_DLCELT BITS(16, 19) /*!< DLC expected low threshold in Pretended Networking mode */ + +/* CAN_PN_EDL0 */ +#define CAN_PN_EDL0_DB3ELT BITS(0, 7) /*!< data byte 3 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL0_DB2ELT BITS(8, 15) /*!< data byte 2 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL0_DB1ELT BITS(16, 23) /*!< data byte 1 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL0_DB0ELT BITS(24, 31) /*!< data byte 0 expected low threshold in Pretended Networking mode */ + +/* CAN_PN_EDL1 */ +#define CAN_PN_EDL1_DB7ELT BITS(0, 7) /*!< data byte 7 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL1_DB6ELT BITS(8, 15) /*!< data byte 6 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL1_DB5ELT BITS(16, 23) /*!< data byte 5 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL1_DB4ELT BITS(24, 31) /*!< data byte 4 expected low threshold in Pretended Networking mode */ + +/* CAN_PN_IFEID1 */ +#define CAN_PN_IFEID1_IDFD_EHT BITS(0, 28) /*!< IDE filter data in Pretended Networking mode */ +#define CAN_PN_IFEID1_RTRFD BIT(29) /*!< RTR filter data in Pretended Networking mode */ +#define CAN_PN_IFEID1_IDEFD BIT(30) /*!< ID filter data / ID expected high threshold in Pretended Networking mode */ + +/* CAN_PN_DF0EDH0 */ +#define CAN_PN_DF0EDH0_DB3FD_EHT BITS(0, 7) /*!< data byte 3 filter data / data byte 3 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF0EDH0_DB2FD_EHT BITS(8, 15) /*!< data byte 2 filter data / data byte 2 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF0EDH0_DB1FD_EHT BITS(16, 23) /*!< data byte 1 filter data / data byte 1 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF0EDH0_DB0FD_EHT BITS(24, 31) /*!< data byte 0 filter data / data byte 0 expected high threshold in Pretended Networking mode */ + +/* CAN_PN_DF1EDH1 */ +#define CAN_PN_DF1EDH1_DB7FD_EHT BITS(0, 7) /*!< data byte 7 filter data / data byte 7 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF1EDH1_DB6FD_EHT BITS(8, 15) /*!< data byte 6 filter data / data byte 6 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF1EDH1_DB5FD_EHT BITS(16, 23) /*!< data byte 5 filter data / data byte 5 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF1EDH1_DB4FD_EHT BITS(24, 31) /*!< data byte 4 filter data / data byte 4 expected high threshold in Pretended Networking mode */ + +/* CAN_PN_RWMxCS, x = 0..3 */ +#define CAN_PN_RWMXCS_RDLC BITS(16, 19) /*!< received DLC bits */ +#define CAN_PN_RWMXCS_RRTR BIT(20) /*!< received RTR bit */ +#define CAN_PN_RWMXCS_RIDE BIT(21) /*!< received IDE bit */ +#define CAN_PN_RWMXCS_RSRR BIT(22) /*!< received SRR bit */ + +/* CAN_PN_RWMxI, x = 0..3 */ +#define CAN_PN_RWMXI_RID BITS(0, 28) /*!< received ID bits */ + +/* CAN_PN_RWMxD0, x = 0..3 */ +#define CAN_PN_RWMXD0_RDB3 BITS(0, 7) /*!< received data byte 3 */ +#define CAN_PN_RWMXD0_RDB2 BITS(8, 15) /*!< received data byte 2 */ +#define CAN_PN_RWMXD0_RDB1 BITS(16, 23) /*!< received data byte 1 */ +#define CAN_PN_RWMXD0_RDB0 BITS(24, 31) /*!< received data byte 0 */ + +/* CAN_PN_RWMxD1, x = 0..3 */ +#define CAN_PN_RWMXD1_RDB7 BITS(0, 7) /*!< received data byte 7 */ +#define CAN_PN_RWMXD1_RDB6 BITS(8, 15) /*!< received data byte 6 */ +#define CAN_PN_RWMXD1_RDB5 BITS(16, 23) /*!< received data byte 5 */ +#define CAN_PN_RWMXD1_RDB4 BITS(24, 31) /*!< received data byte 4 */ + +/* CAN_FDCTL */ +#define CAN_FDCTL_TDCV BITS(0, 5) /*!< transmitter delay compensation value */ +#define CAN_FDCTL_TDCO BITS(8, 12) /*!< transmitter delay compensation offset */ +#define CAN_FDCTL_TDCS BIT(14) /*!< transmitter delay compensation status */ +#define CAN_FDCTL_TDCEN BIT(15) /*!< transmitter delay compensation enable */ +#define CAN_FDCTL_MDSZ BITS(16, 17) /*!< mailbox data size */ +#define CAN_FDCTL_BRSEN BIT(31) /*!< bit rate of data switch enable */ + +/* CAN_FDBT */ +#define CAN_FDBT_DPBS2 BITS(0, 2) /*!< phase buffer segment 2 for data bit time */ +#define CAN_FDBT_DPBS1 BITS(5, 7) /*!< phase buffer segment 1 for data bit time */ +#define CAN_FDBT_DPTS BITS(10, 14) /*!< propagation time segment for data bit time */ +#define CAN_FDBT_DSJW BITS(16, 18) /*!< resynchronization jump width for data bit time */ +#define CAN_FDBT_DBAUDPSC BITS(20, 29) /*!< baud rate prescaler for data bit time */ + +/* CAN_CRCCFD */ +#define CAN_CRCCFD_CRCTCI BITS(0, 20) /*!< transmitted CRC value for classical and ISO / non-ISO frames */ +#define CAN_CRCCFD_ANTM BITS(24, 28) /*!< associated number of mailbox for transmitting the CRCTCI[20:0] value */ + +/* CAN_MDES0 */ +#define CAN_MDES0_TIMESTAMP BITS(0, 15) /*!< free-running counter timestamp */ +#define CAN_MDES0_DLC BITS(16, 19) /*!< data length code in bytes */ +#define CAN_MDES0_RTR BIT(20) /*!< remote transmission request */ +#define CAN_MDES0_IDE BIT(21) /*!< ID extended bit */ +#define CAN_MDES0_SRR BIT(22) /*!< substitute remote request */ +#define CAN_MDES0_CODE BITS(24, 27) /*!< mailbox code */ +#define CAN_MDES0_ESI BIT(29) /*!< error state indicator */ +#define CAN_MDES0_BRS BIT(30) /*!< bit rate switch */ +#define CAN_MDES0_FDF BIT(31) /*!< FD format indicator */ + +/* CAN_MDES1 */ +#define CAN_MDES1_ID_EXD BITS(0, 17) /*!< identifier for extended frame */ +#define CAN_MDES1_ID_STD BITS(18, 28) /*!< identifier for standard frame */ +#define CAN_MDES1_PRIO BITS(29, 31) /*!< local priority */ + +/* CAN_FDES0 */ +#define CAN_FDES0_TIMESTAMP BITS(0, 15) /*!< free-running counter timestamp */ +#define CAN_FDES0_DLC BITS(16, 19) /*!< data length code in bytes */ +#define CAN_FDES0_RTR BIT(20) /*!< remote transmission request */ +#define CAN_FDES0_IDE BIT(21) /*!< ID extended bit */ +#define CAN_FDES0_SRR BIT(22) /*!< substitute remote request */ +#define CAN_FDES0_IDFMN BITS(23, 31) /*!< identifier filter matching number */ + +/* CAN_FDES1 */ +#define CAN_FDES1_ID_EXT BITS(0, 17) /*!< identifier for extended frame */ +#define CAN_FDES1_ID_STD BITS(18, 28) /*!< identifier for standard frame */ + +/* CAN_FDESX_A */ +#define CAN_FDESX_ID_EXD_A BITS(0, 28) /*!< extended ID in format A */ +#define CAN_FDESX_ID_STD_A BITS(18, 28) /*!< standard ID in format A */ +#define CAN_FDESX_IDE_A BIT(30) /*!< ID extended frame for format A */ +#define CAN_FDESX_RTR_A BIT(31) /*!< remote frame for format A */ + +/* CAN_FDESX_B */ +#define CAN_FDESX_ID_EXD_B_1 BITS(0, 13) /*!< extended ID 1 in format B */ +#define CAN_FDESX_ID_STD_B_1 BITS(3, 13) /*!< standard ID 1 in format B */ +#define CAN_FDESX_IDE_B1 BIT(14) /*!< ID extended frame 1 for format B */ +#define CAN_FDESX_RTR_B1 BIT(15) /*!< remote frame 1 for format B */ +#define CAN_FDESX_ID_EXD_B_0 BITS(16, 29) /*!< extended ID 0 in format B */ +#define CAN_FDESX_ID_STD_B_0 BITS(19, 29) /*!< standard ID 0 in format B */ +#define CAN_FDESX_IDE_B0 BIT(30) /*!< ID extended frame 0 for format B */ +#define CAN_FDESX_RTR_B0 BIT(31) /*!< remote frame 0 for format B */ + +/* CAN_FDESX_C */ +#define CAN_FDESX_ID_C_3 BITS(0, 7) /*!< ID for frame 3 for format C */ +#define CAN_FDESX_ID_C_2 BITS(8, 15) /*!< ID for frame 2 for format C */ +#define CAN_FDESX_ID_C_1 BITS(16, 23) /*!< ID for frame 1 for format C */ +#define CAN_FDESX_ID_C_0 BITS(24, 31) /*!< ID for frame 0 for format C */ + +/* consts definitions */ +/* define the CAN bit position and its register index offset */ +#define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6U) | (uint32_t)(bitpos)) +#define CAN_REG_VAL(canx, offset) (REG32((uint32_t)(canx) + ((uint32_t)(offset) >> 6U))) +#define CAN_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define CAN_RFIFOMPF(canx, num) REG32((canx) + 0x00000880U + (num) * 0x00000004U) /*!< CAN receive fifo / mailbox private filter x register */ + +/* register offset */ +#define CTL0_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define CTL1_REG_OFFSET ((uint32_t)0x00000004U) /*!< CTL1 register offset */ +#define ERR1_REG_OFFSET ((uint32_t)0x00000020U) /*!< ERR1 register offset */ +#define INTEN_REG_OFFSET ((uint32_t)0x00000028U) /*!< INTEN register offset */ +#define STAT_REG_OFFSET ((uint32_t)0x00000030U) /*!< STAT register offset */ +#define CTL2_REG_OFFSET ((uint32_t)0x00000034U) /*!< CTL2 register offset */ +#define PN_CTL0_REG_OFFSET ((uint32_t)0x00000B00U) /*!< PN_CTL0 register offset */ +#define PN_STAT_REG_OFFSET ((uint32_t)0x00000B08U) /*!< PN_STAT register offset */ +#define FDCTL_REG_OFFSET ((uint32_t)0x00000C00U) /*!< FDCTL register offset */ + +/* CAN interrupt enable or disable */ +typedef enum { + /* interrupt in CLT1 register */ + CAN_INT_RX_WARNING = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 10U), /*!< receive warning interrupt */ + CAN_INT_TX_WARNING = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 11U), /*!< transmit warning interrupt */ + CAN_INT_ERR_SUMMARY = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 14U), /*!< error interrupt */ + CAN_INT_BUSOFF = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 15U), /*!< bus off interrupt */ + /* interrupt in CLT2 register */ + CAN_INT_BUSOFF_RECOVERY = CAN_REGIDX_BIT(CTL2_REG_OFFSET, 30U), /*!< bus off recovery interrupt */ + CAN_INT_ERR_SUMMARY_FD = CAN_REGIDX_BIT(CTL2_REG_OFFSET, 31U), /*!< fd error interrupt */ + /* interrupt in INTEN register */ + CAN_INT_MB0 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 0U), /*!< mailbox 0 interrupt */ + CAN_INT_MB1 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 1U), /*!< mailbox 1 interrupt */ + CAN_INT_MB2 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 2U), /*!< mailbox 2 interrupt */ + CAN_INT_MB3 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 3U), /*!< mailbox 3 interrupt */ + CAN_INT_MB4 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 4U), /*!< mailbox 4 interrupt */ + CAN_INT_MB5 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 5U), /*!< mailbox 5 interrupt */ + CAN_INT_MB6 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 6U), /*!< mailbox 6 interrupt */ + CAN_INT_MB7 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 7U), /*!< mailbox 7 interrupt */ + CAN_INT_MB8 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 8U), /*!< mailbox 8 interrupt */ + CAN_INT_MB9 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 9U), /*!< mailbox 9 interrupt */ + CAN_INT_MB10 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 10U), /*!< mailbox 10 interrupt */ + CAN_INT_MB11 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 11U), /*!< mailbox 11 interrupt */ + CAN_INT_MB12 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 12U), /*!< mailbox 12 interrupt */ + CAN_INT_MB13 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 13U), /*!< mailbox 13 interrupt */ + CAN_INT_MB14 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 14U), /*!< mailbox 14 interrupt */ + CAN_INT_MB15 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 15U), /*!< mailbox 15 interrupt */ + CAN_INT_MB16 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 16U), /*!< mailbox 16 interrupt */ + CAN_INT_MB17 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 17U), /*!< mailbox 17 interrupt */ + CAN_INT_MB18 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 18U), /*!< mailbox 18 interrupt */ + CAN_INT_MB19 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 19U), /*!< mailbox 19 interrupt */ + CAN_INT_MB20 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 20U), /*!< mailbox 20 interrupt */ + CAN_INT_MB21 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 21U), /*!< mailbox 21 interrupt */ + CAN_INT_MB22 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 22U), /*!< mailbox 22 interrupt */ + CAN_INT_MB23 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 23U), /*!< mailbox 23 interrupt */ + CAN_INT_MB24 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 24U), /*!< mailbox 24 interrupt */ + CAN_INT_MB25 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 25U), /*!< mailbox 25 interrupt */ + CAN_INT_MB26 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 26U), /*!< mailbox 26 interrupt */ + CAN_INT_MB27 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 27U), /*!< mailbox 27 interrupt */ + CAN_INT_MB28 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 28U), /*!< mailbox 28 interrupt */ + CAN_INT_MB29 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 29U), /*!< mailbox 29 interrupt */ + CAN_INT_MB30 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 30U), /*!< mailbox 30 interrupt */ + CAN_INT_MB31 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 31U), /*!< mailbox 31 interrupt */ + CAN_INT_FIFO_AVAILABLE = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 5U), /*!< fifo available interrupt */ + CAN_INT_FIFO_WARNING = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 6U), /*!< fifo warning interrupt */ + CAN_INT_FIFO_OVERFLOW = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 7U), /*!< fifo overflow interrupt */ + /* interrupt in PN_CTL0 register */ + CAN_INT_WAKEUP_MATCH = CAN_REGIDX_BIT(PN_CTL0_REG_OFFSET, 16U), /*!< Pretended Networking match interrupt */ + CAN_INT_WAKEUP_TIMEOUT = CAN_REGIDX_BIT(PN_CTL0_REG_OFFSET, 17U) /*!< Pretended Networking timeout wakeup interrupt */ +} can_interrupt_enum; + +/* CAN flags */ +typedef enum { + /* flags in CTL0 register */ + CAN_FLAG_CAN_PN = CAN_REGIDX_BIT(CTL0_REG_OFFSET, 18U), /*!< Pretended Networking state flag */ + CAN_FLAG_SOFT_RST = CAN_REGIDX_BIT(CTL0_REG_OFFSET, 25U), /*!< software reset flag */ + /* flags in ERR1 register */ + CAN_FLAG_ERR_SUMMARY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 1U), /*!< error summary flag */ + CAN_FLAG_BUSOFF = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 2U), /*!< bus off flag */ + CAN_FLAG_RECEIVING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 3U), /*!< receiving state flag */ + CAN_FLAG_TRANSMITTING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 6U), /*!< transmitting state flag */ + CAN_FLAG_IDLE = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 7U), /*!< IDLE state flag */ + CAN_FLAG_RX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 8U), /*!< receive warning flag */ + CAN_FLAG_TX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 9U), /*!< transmit warning flag */ + CAN_FLAG_STUFF_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 10U), /*!< stuff error flag */ + CAN_FLAG_FORM_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 11U), /*!< form error flag */ + CAN_FLAG_CRC_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 12U), /*!< CRC error flag */ + CAN_FLAG_ACK_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 13U), /*!< ACK error flag */ + CAN_FLAG_BIT_DOMINANT_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 14U), /*!< bit dominant error flag */ + CAN_FLAG_BIT_RECESSIVE_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 15U), /*!< bit recessive error flag */ + CAN_FLAG_SYNC_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 18U), /*!< synchronization flag */ + CAN_FLAG_BUSOFF_RECOVERY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 19U), /*!< bus off recovery flag */ + CAN_FLAG_ERR_SUMMARY_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 20U), /*!< FD error summary flag */ + CAN_FLAG_ERR_OVERRUN = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 21U), /*!< error overrun flag */ + CAN_FLAG_STUFF_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 26U), /*!< stuff error in FD data phase flag */ + CAN_FLAG_FORM_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 27U), /*!< form error in FD data phase flag */ + CAN_FLAG_CRC_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 28U), /*!< CRC error in FD data phase flag */ + CAN_FLAG_BIT_DOMINANT_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 30U), /*!< bit dominant error in FD data phase flag */ + CAN_FLAG_BIT_RECESSIVE_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 31U), /*!< bit recessive error in FD data phase flag */ + /* flags in STAT register */ + CAN_FLAG_MB0 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 0U), /*!< mailbox 0 flag */ + CAN_FLAG_MB1 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 1U), /*!< mailbox 1 flag */ + CAN_FLAG_MB2 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< mailbox 2 flag */ + CAN_FLAG_MB3 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< mailbox 3 flag */ + CAN_FLAG_MB4 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< mailbox 4 flag */ + CAN_FLAG_MB5 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< mailbox 5 flag */ + CAN_FLAG_MB6 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< mailbox 6 flag */ + CAN_FLAG_MB7 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< mailbox 7 flag */ + CAN_FLAG_MB8 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 8U), /*!< mailbox 8 flag */ + CAN_FLAG_MB9 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 9U), /*!< mailbox 9 flag */ + CAN_FLAG_MB10 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 10U), /*!< mailbox 10 flag */ + CAN_FLAG_MB11 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 11U), /*!< mailbox 11 flag */ + CAN_FLAG_MB12 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 12U), /*!< mailbox 12 flag */ + CAN_FLAG_MB13 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 13U), /*!< mailbox 13 flag */ + CAN_FLAG_MB14 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 14U), /*!< mailbox 14 flag */ + CAN_FLAG_MB15 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 15U), /*!< mailbox 15 flag */ + CAN_FLAG_MB16 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 16U), /*!< mailbox 16 flag */ + CAN_FLAG_MB17 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 17U), /*!< mailbox 17 flag */ + CAN_FLAG_MB18 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 18U), /*!< mailbox 18 flag */ + CAN_FLAG_MB19 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 19U), /*!< mailbox 19 flag */ + CAN_FLAG_MB20 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 20U), /*!< mailbox 20 flag */ + CAN_FLAG_MB21 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 21U), /*!< mailbox 21 flag */ + CAN_FLAG_MB22 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 22U), /*!< mailbox 22 flag */ + CAN_FLAG_MB23 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 23U), /*!< mailbox 23 flag */ + CAN_FLAG_MB24 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 24U), /*!< mailbox 24 flag */ + CAN_FLAG_MB25 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 25U), /*!< mailbox 25 flag */ + CAN_FLAG_MB26 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 26U), /*!< mailbox 26 flag */ + CAN_FLAG_MB27 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 27U), /*!< mailbox 27 flag */ + CAN_FLAG_MB28 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 28U), /*!< mailbox 28 flag */ + CAN_FLAG_MB29 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 29U), /*!< mailbox 29 flag */ + CAN_FLAG_MB30 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 30U), /*!< mailbox 30 flag */ + CAN_FLAG_MB31 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 31U), /*!< mailbox 31 flag */ + CAN_FLAG_FIFO_AVAILABLE = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< fifo available flag */ + CAN_FLAG_FIFO_WARNING = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< fifo warning flag */ + CAN_FLAG_FIFO_OVERFLOW = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< fifo overflow flag */ + /* flags in PN_STAT register */ + CAN_FLAG_WAKEUP_MATCH = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 16U), /*!< Pretended Networking match flag */ + CAN_FLAG_WAKEUP_TIMEOUT = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 17U), /*!< Pretended Networking timeout wakeup flag */ + /* flags in FDCTL register */ + CAN_FLAG_TDC_OUT_OF_RANGE = CAN_REGIDX_BIT(FDCTL_REG_OFFSET, 14U), /*!< transmitter delay is out of compensation range flag */ +} can_flag_enum; + +/* CAN interrupt flags */ +typedef enum { + /* interrupt flags in ERR1 register */ + CAN_INT_FLAG_ERR_SUMMARY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 1U), /*!< error summary interrupt flag */ + CAN_INT_FLAG_BUSOFF = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 2U), /*!< bus off interrupt flag */ + CAN_INT_FLAG_RX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 16U), /*!< receive warning interrupt flag */ + CAN_INT_FLAG_TX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 17U), /*!< transmit warning interrupt flag */ + CAN_INT_FLAG_BUSOFF_RECOVERY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 19U), /*!< bus off recovery interrupt flag */ + CAN_INT_FLAG_ERR_SUMMARY_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 20U), /*!< fd error summary interrupt flag */ + /* interrupt flags in STAT register */ + CAN_INT_FLAG_MB0 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 0U), /*!< mailbox 0 interrupt flag */ + CAN_INT_FLAG_MB1 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 1U), /*!< mailbox 1 interrupt flag */ + CAN_INT_FLAG_MB2 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< mailbox 2 interrupt flag */ + CAN_INT_FLAG_MB3 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< mailbox 3 interrupt flag */ + CAN_INT_FLAG_MB4 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< mailbox 4 interrupt flag */ + CAN_INT_FLAG_MB5 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< mailbox 5 interrupt flag */ + CAN_INT_FLAG_MB6 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< mailbox 6 interrupt flag */ + CAN_INT_FLAG_MB7 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< mailbox 7 interrupt flag */ + CAN_INT_FLAG_MB8 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 8U), /*!< mailbox 8 interrupt flag */ + CAN_INT_FLAG_MB9 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 9U), /*!< mailbox 9 interrupt flag */ + CAN_INT_FLAG_MB10 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 10U), /*!< mailbox 10 interrupt flag */ + CAN_INT_FLAG_MB11 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 11U), /*!< mailbox 11 interrupt flag */ + CAN_INT_FLAG_MB12 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 12U), /*!< mailbox 12 interrupt flag */ + CAN_INT_FLAG_MB13 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 13U), /*!< mailbox 13 interrupt flag */ + CAN_INT_FLAG_MB14 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 14U), /*!< mailbox 14 interrupt flag */ + CAN_INT_FLAG_MB15 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 15U), /*!< mailbox 15 interrupt flag */ + CAN_INT_FLAG_MB16 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 16U), /*!< mailbox 16 interrupt flag */ + CAN_INT_FLAG_MB17 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 17U), /*!< mailbox 17 interrupt flag */ + CAN_INT_FLAG_MB18 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 18U), /*!< mailbox 18 interrupt flag */ + CAN_INT_FLAG_MB19 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 19U), /*!< mailbox 19 interrupt flag */ + CAN_INT_FLAG_MB20 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 20U), /*!< mailbox 20 interrupt flag */ + CAN_INT_FLAG_MB21 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 21U), /*!< mailbox 21 interrupt flag */ + CAN_INT_FLAG_MB22 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 22U), /*!< mailbox 22 interrupt flag */ + CAN_INT_FLAG_MB23 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 23U), /*!< mailbox 23 interrupt flag */ + CAN_INT_FLAG_MB24 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 24U), /*!< mailbox 24 interrupt flag */ + CAN_INT_FLAG_MB25 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 25U), /*!< mailbox 25 interrupt flag */ + CAN_INT_FLAG_MB26 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 26U), /*!< mailbox 26 interrupt flag */ + CAN_INT_FLAG_MB27 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 27U), /*!< mailbox 27 interrupt flag */ + CAN_INT_FLAG_MB28 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 28U), /*!< mailbox 28 interrupt flag */ + CAN_INT_FLAG_MB29 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 29U), /*!< mailbox 29 interrupt flag */ + CAN_INT_FLAG_MB30 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 30U), /*!< mailbox 30 interrupt flag */ + CAN_INT_FLAG_MB31 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 31U), /*!< mailbox 31 interrupt flag */ + CAN_INT_FLAG_FIFO_AVAILABLE = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< fifo available interrupt flag */ + CAN_INT_FLAG_FIFO_WARNING = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< fifo warning interrupt flag */ + CAN_INT_FLAG_FIFO_OVERFLOW = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< fifo overflow interrupt flag */ + /* interrupt flags in PN_STAT register */ + CAN_INT_FLAG_WAKEUP_MATCH = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 16U), /*!< Pretended Networking match interrupt flag */ + CAN_INT_FLAG_WAKEUP_TIMEOUT = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 17U) /*!< Pretended Networking timeout wakeup interrupt flag */ +} can_interrupt_flag_enum; + +/* operation modes */ +typedef enum { + CAN_NORMAL_MODE = 0U, /*!< normal mode */ + CAN_MONITOR_MODE = 1U, /*!< monitor mode */ + CAN_LOOPBACK_SILENT_MODE = 2U, /*!< loopback mode */ + CAN_INACTIVE_MODE = 3U, /*!< inactive mode */ + CAN_DISABLE_MODE = 4U, /*!< disable mode */ + CAN_PN_MODE = 5U /*!< Pretended Networking mode */ +} can_operation_modes_enum; + +/* initialize parameter type */ +typedef enum { + CAN_INIT_STRUCT = 0U, /*!< CAN initialize parameters struct */ + CAN_FD_INIT_STRUCT = 1U, /*!< CAN FD parameters struct */ + CAN_FIFO_INIT_STRUCT = 2U, /*!< CAN fifo parameters struct */ + CAN_PN_MODE_INIT_STRUCT = 3U, /*!< Pretended Networking mode parameter strcut */ + CAN_PN_MODE_FILTER_STRUCT = 4U, /*!< Pretended Networking mode filter parameter strcut */ + CAN_MDSC_STRUCT = 5U, /*!< mailbox descriptor strcut */ + CAN_FDES_STRUCT = 6U, /*!< Rx fifo descriptor strcut */ + CAN_FIFO_ID_FILTER_STRUCT = 7U, /*!< Rx fifo id filter strcut */ + CAN_CRC_STRUCT = 8U, /*!< CRC strcut */ + CAN_ERRCNT_STRUCT = 9U, /*!< error counter strcut */ +} can_struct_type_enum; + +/* error state indicator */ +typedef enum { + CAN_ERROR_STATE_ACTIVE = 0U, /*!< CAN in error active */ + CAN_ERROR_STATE_PASSIVE = 1U, /*!< CAN in error passive */ + CAN_ERROR_STATE_BUS_OFF = 2U /*!< CAN in bus off */ +} can_error_state_enum; + +/* error counter structure */ +typedef struct { + uint8_t fd_data_phase_rx_errcnt; /*!< receive error counter for data phase of FD frames with BRS bit set */ + uint8_t fd_data_phase_tx_errcnt; /*!< transmit error count for the data phase of FD frames with BRS bit set */ + uint8_t rx_errcnt; /*!< receive error count defined by the CAN standard */ + uint8_t tx_errcnt; /*!< transmit error count defined by the CAN standard */ +} can_error_counter_struct; + +/* CAN initialize parameters structure */ +typedef struct { + uint32_t internal_counter_source; /*!< internal counter source */ + uint32_t mb_tx_order; /*!< mailbox transmit order */ + uint32_t mb_rx_ide_rtr_type; /*!< IDE and RTR field filter type */ + uint32_t mb_remote_frame; /*!< remote request frame is stored */ + uint8_t self_reception; /*!< enable or disable self reception */ + uint8_t mb_tx_abort_enable; /*!< enable or disable transmit abort */ + uint8_t local_priority_enable; /*!< enable or disable local priority */ + uint8_t rx_private_filter_queue_enable; /*!< private filter and queue enable */ + uint32_t edge_filter_enable; /*!< edge filter enable*/ + uint32_t protocol_exception_enable; /*!< protocol exception enable */ + uint32_t rx_filter_order; /*!< receive filter order */ + uint32_t memory_size; /*!< memory size */ + uint32_t mb_public_filter; /*!< mailbox public filter */ + uint32_t prescaler; /*!< baud rate prescaler */ + uint8_t resync_jump_width; /*!< resynchronization jump width */ + uint8_t prop_time_segment; /*!< propagation time segment */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ +} can_parameter_struct; + +/* mailbox descriptor struct */ +typedef struct { + uint32_t timestamp : 16; /*!< free-running counter timestamp */ + uint32_t dlc : 4; /*!< data length code in bytes */ + uint32_t rtr : 1; /*!< remote transmission request */ + uint32_t ide : 1; /*!< ID extended bit */ + uint32_t srr : 1; /*!< substitute remote request */ + uint32_t reserve1 : 1; /*!< reserve bit 1 */ + uint32_t code : 4; /*!< mailbox code */ + uint32_t reserve2 : 1; /*!< reserve bit 2 */ + uint32_t esi : 1; /*!< error state indicator */ + uint32_t brs : 1; /*!< bit rate switch */ + uint32_t fdf : 1; /*!< FD format indicator */ + uint32_t id : 29; /*!< identifier for frame */ + uint32_t prio : 3; /*!< local priority */ + uint32_t *data; /*!< data */ + uint32_t data_bytes; /*!< data bytes */ + uint8_t padding; /*!< FD mode padding data */ +} can_mailbox_descriptor_struct; + +/* fifo descriptor struct */ +typedef struct { + uint32_t timestamp : 16; /*!< free-running counter timestamp */ + uint32_t dlc : 4; /*!< data length code in bytes */ + uint32_t rtr : 1; /*!< remote transmission request */ + uint32_t ide : 1; /*!< ID extended bit */ + uint32_t srr : 1; /*!< substitute remote request */ + uint32_t idhit : 9; /*!< identifier filter matching number */ + uint32_t id; /*!< identifier for frame */ + uint32_t data[2]; /*!< fifo data */ +} can_rx_fifo_struct; + +/* FD initialize parameter struct */ +typedef struct { + uint32_t iso_can_fd_enable; /*!< ISO CAN FD protocol enable */ + uint32_t bitrate_switch_enable; /*!< data bit rate switch */ + uint32_t mailbox_data_size; /*!< mailbox data size */ + uint32_t tdc_enable; /*!< transmitter delay compensation enable */ + uint32_t tdc_offset; /*!< transmitter delay compensation offset */ + uint32_t prescaler; /*!< baud rate prescaler */ + uint8_t resync_jump_width; /*!< resynchronization jump width */ + uint8_t prop_time_segment; /*!< propagation time segment */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ +} can_fd_parameter_struct; + +/* FIFO ID filter table struct */ +typedef struct { + uint32_t remote_frame; /*!< expected remote frame*/ + uint32_t extended_frame; /*!< expected extended frame */ + uint32_t id; /*!< expected id */ +} can_rx_fifo_id_filter_struct; + +/* FIFO initialize parameter struct */ +typedef struct { + uint8_t dma_enable; /*!< DMA enable */ + uint32_t filter_format_and_number; /*!< FIFO ID filter format and number */ + uint32_t fifo_public_filter; /*!< FIFO ID public filter */ +} can_fifo_parameter_struct; + +/* Pretended Networking mode filter parameter struct */ +typedef struct { + uint32_t rtr; /*!< remote frame */ + uint32_t ide; /*!< extended frame */ + uint32_t id; /*!< id */ + uint32_t dlc_high_threshold; /*!< DLC expected high threshold */ + uint32_t dlc_low_threshold; /*!< DLC expected low threshold */ + uint32_t payload[2]; /*!< data */ +} can_pn_mode_filter_struct; + +/* Pretended Networking mode initialize parameter struct */ +typedef struct { + uint32_t timeout_int; /*!< enable or disable timeout interrupt */ + uint32_t match_int; /*!< enable or disable match interrupt */ + uint32_t num_matches; /*!< set number of message matching times */ + uint32_t match_timeout; /*!< set wakeup timeout value */ + uint32_t frame_filter; /*!< set frame filtering type */ + uint32_t id_filter; /*!< set id filtering type */ + uint32_t data_filter; /*!< set data filtering type */ +} can_pn_mode_config_struct; + +/* CRC parameter struct */ +typedef struct { + uint32_t classical_frm_mb_number; /*!< associated number of mailbox for transmitting the CRCTC[14:0] value */ + uint32_t classical_frm_transmitted_crc; /*!< transmitted CRC value for classical frames */ + uint32_t classical_fd_frm_mb_number; /*!< associated number of mailbox for transmitting the CRCTCI[20:0] value */ + uint32_t classical_fd_frm_transmitted_crc; /*!< transmitted CRC value for classical and ISO / non-ISO FD frames */ +} can_crc_struct; + +/* CAN_CTL0 register */ +#define CTL0_MSZ(regval) (CAN_CTL0_MSZ & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_CTL0_MSZ bit field */ +#define CAN_MEMSIZE_1_UNIT CTL0_MSZ(0U) /*!< 1 unit for message transmission and reception */ +#define CAN_MEMSIZE_2_UNIT CTL0_MSZ(1U) /*!< 2 units for message transmission and reception */ +#define CAN_MEMSIZE_3_UNIT CTL0_MSZ(2U) /*!< 3 units for message transmission and reception */ +#define CAN_MEMSIZE_4_UNIT CTL0_MSZ(3U) /*!< 4 units for message transmission and reception */ +#define CAN_MEMSIZE_5_UNIT CTL0_MSZ(4U) /*!< 5 units for message transmission and reception */ +#define CAN_MEMSIZE_6_UNIT CTL0_MSZ(5U) /*!< 6 units for message transmission and reception */ +#define CAN_MEMSIZE_7_UNIT CTL0_MSZ(6U) /*!< 7 units for message transmission and reception */ +#define CAN_MEMSIZE_8_UNIT CTL0_MSZ(7U) /*!< 8 units for message transmission and reception */ +#define CAN_MEMSIZE_9_UNIT CTL0_MSZ(8U) /*!< 9 units for message transmission and reception */ +#define CAN_MEMSIZE_10_UNIT CTL0_MSZ(9U) /*!< 10 units for message transmission and reception */ +#define CAN_MEMSIZE_11_UNIT CTL0_MSZ(10U) /*!< 11 units for message transmission and reception */ +#define CAN_MEMSIZE_12_UNIT CTL0_MSZ(11U) /*!< 12 units for message transmission and reception */ +#define CAN_MEMSIZE_13_UNIT CTL0_MSZ(12U) /*!< 13 units for message transmission and reception */ +#define CAN_MEMSIZE_14_UNIT CTL0_MSZ(13U) /*!< 14 units for message transmission and reception */ +#define CAN_MEMSIZE_15_UNIT CTL0_MSZ(14U) /*!< 15 units for message transmission and reception */ +#define CAN_MEMSIZE_16_UNIT CTL0_MSZ(15U) /*!< 16 units for message transmission and reception */ +#define CAN_MEMSIZE_17_UNIT CTL0_MSZ(16U) /*!< 17 units for message transmission and reception */ +#define CAN_MEMSIZE_18_UNIT CTL0_MSZ(17U) /*!< 18 units for message transmission and reception */ +#define CAN_MEMSIZE_19_UNIT CTL0_MSZ(18U) /*!< 19 units for message transmission and reception */ +#define CAN_MEMSIZE_20_UNIT CTL0_MSZ(19U) /*!< 20 units for message transmission and reception */ +#define CAN_MEMSIZE_21_UNIT CTL0_MSZ(20U) /*!< 21 units for message transmission and reception */ +#define CAN_MEMSIZE_22_UNIT CTL0_MSZ(21U) /*!< 22 units for message transmission and reception */ +#define CAN_MEMSIZE_23_UNIT CTL0_MSZ(22U) /*!< 23 units for message transmission and reception */ +#define CAN_MEMSIZE_24_UNIT CTL0_MSZ(23U) /*!< 24 units for message transmission and reception */ +#define CAN_MEMSIZE_25_UNIT CTL0_MSZ(24U) /*!< 25 units for message transmission and reception */ +#define CAN_MEMSIZE_26_UNIT CTL0_MSZ(25U) /*!< 26 units for message transmission and reception */ +#define CAN_MEMSIZE_27_UNIT CTL0_MSZ(26U) /*!< 27 units for message transmission and reception */ +#define CAN_MEMSIZE_28_UNIT CTL0_MSZ(27U) /*!< 28 units for message transmission and reception */ +#define CAN_MEMSIZE_29_UNIT CTL0_MSZ(28U) /*!< 29 units for message transmission and reception */ +#define CAN_MEMSIZE_30_UNIT CTL0_MSZ(29U) /*!< 30 units for message transmission and reception */ +#define CAN_MEMSIZE_31_UNIT CTL0_MSZ(30U) /*!< 31 units for message transmission and reception */ +#define CAN_MEMSIZE_32_UNIT CTL0_MSZ(31U) /*!< 32 units for message transmission and reception */ + +#define CTL0_FS(regval) (CAN_CTL0_FS & ((uint32_t)(regval) << 8U)) /*!< write value to CAN_CTL0_FS bit field */ +#define CAN_FIFO_FILTER_FORMAT_A CTL0_FS(0U) /*!< FIFO filter format A */ +#define CAN_FIFO_FILTER_FORMAT_B CTL0_FS(1U) /*!< FIFO filter format B */ +#define CAN_FIFO_FILTER_FORMAT_C CTL0_FS(2U) /*!< FIFO filter format C */ +#define CAN_FIFO_FILTER_FORMAT_D CTL0_FS(3U) /*!< FIFO filter format D */ + +#define GET_CTL0_FS(regval) GET_BITS((regval),8,9) /*!< get CAN_CTL0_FS bit field */ + +/* CAN_CTL1 register */ +#define CAN_TX_HIGH_PRIORITY_MB_FIRST ((uint32_t)0x00000000U) /*!< highest priority mailbox first */ +#define CAN_TX_LOW_NUM_MB_FIRST CAN_CTL1_MTO /*!< low number mailbox first */ + +#define CAN_BSP_MODE_ONE_SAMPLE ((uint32_t)0x00000000U) /*!< one sample for the received bit */ +#define CAN_BSP_MODE_THREE_SAMPLES CAN_CTL1_BSPMOD /*!< three sample for received bit */ + +/* CAN_ERR0 register */ +#define GET_ERR0_REFCNT(regval) GET_BITS((regval),24,31) /*!< get receive error counter for data phase of FD frames with BRS bit set */ +#define GET_ERR0_TEFCNT(regval) GET_BITS((regval),16,23) /*!< get transmit error counter for data phase of FD frames with BRS bit set */ +#define GET_ERR0_RECNT(regval) GET_BITS((regval),8,15) /*!< get receive error counter defined by the CAN standard */ +#define GET_ERR0_TECNT(regval) GET_BITS((regval),0,7) /*!< get transmit error counter defined by the CAN standard */ +#define ERR0_REFCNT(regval) (BITS(24,31) & ((uint32_t)(regval) << 24U)) /*!< set receive error counter for data phase of FD frames with BRS bit set */ +#define ERR0_TEFCNT(regval) (BITS(16,23) & ((uint32_t)(regval) << 16U)) /*!< set transmit error counter for data phase of FD frames with BRS bit set */ +#define ERR0_RECNT(regval) (BITS(8,15) & ((uint32_t)(regval) << 8U)) /*!< set receive error counter defined by the CAN standard */ +#define ERR0_TECNT(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< set transmit error counter defined by the CAN standard */ + +/* CAN_ERR1 register */ +#define GET_ERR1_ERRSI(regval) GET_BITS((regval),4,5) /*!< read CAN_ERR1_ERRSI bit field */ + +/* CAN_STAT register */ +#define STAT_MS(regval) BIT(regval) /*!< write value to CAN_STAT_MS bit field */ + +/* CAN_CTL2 register */ +#define CAN_TIMER_SOURCE_BIT_CLOCK ((uint32_t)0x00000000U) /*!< internal counter source is CAN bit clock */ +#define CAN_TIMER_SOURCE_EXTERNAL_TIME_TICK CAN_CTL2_ITSRC /*!< internal counter source is external time tick */ + +#define CAN_IDE_RTR_COMPARED ((uint32_t)0x00000000U) /*!< always compare IDE bit, never compare RTR bit */ +#define CAN_IDE_RTR_FILTERED CAN_CTL2_IDERTR_RMF /*!< filtering IDE and RTR fields */ + +#define CAN_GEN_REMOTE_RESPONSE_FRAME ((uint32_t)0x00000000U) /* remote response frame is generated when a mailbox with CODE RANSWER is found with the same ID */ +#define CAN_STORE_REMOTE_REQUEST_FRAME CAN_CTL2_RRFRMS /* remote request frame is stored as a data frame without automatic remote response frame transmitted */ + +#define CAN_RX_FILTER_ORDER_FIFO_FIRST ((uint32_t)0x00000000U) /*!< receive search FIFO first */ +#define CAN_RX_FILTER_ORDER_MAILBOX_FIRST CAN_CTL2_RFO /*!< receive search mailbox first */ + +#define CTL2_ASD(regval) (BITS(19,23) & ((uint32_t)(regval) << 19U)) /*!< write value to CAN_CTL2_ASD bit field */ + +#define CTL2_RFFN(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U)) /*!< write value to CAN_CTL2_RFFN bit field */ +#define GET_CTL2_RFFN(regval) GET_BITS((regval),24,27) /*!< get CAN_CTL2_RFFN bit field */ +#define CAN_RXFIFO_FILTER_A_NUM_8 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(0U)) /*!< FIFO ID filter format A and 8 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_16 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(1U)) /*!< FIFO ID filter format A and 16 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_24 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(2U)) /*!< FIFO ID filter format A and 24 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_32 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(3U)) /*!< FIFO ID filter format A and 32 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_40 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(4U)) /*!< FIFO ID filter format A and 40 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_48 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(5U)) /*!< FIFO ID filter format A and 48 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_56 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(6U)) /*!< FIFO ID filter format A and 56 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_64 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(7U)) /*!< FIFO ID filter format A and 64 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_72 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(8U)) /*!< FIFO ID filter format A and 72 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_80 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(9U)) /*!< FIFO ID filter format A and 80 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_88 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(10U)) /*!< FIFO ID filter format A and 88 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_96 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(11U)) /*!< FIFO ID filter format A and 96 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_104 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(12U)) /*!< FIFO ID filter format A and 104 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_16 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(0U)) /*!< FIFO ID filter format B and 16 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_32 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(1U)) /*!< FIFO ID filter format B and 32 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_48 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(2U)) /*!< FIFO ID filter format B and 48 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_64 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(3U)) /*!< FIFO ID filter format B and 64 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_80 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(4U)) /*!< FIFO ID filter format B and 80 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_96 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(5U)) /*!< FIFO ID filter format B and 96 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_112 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(6U)) /*!< FIFO ID filter format B and 112 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_128 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(7U)) /*!< FIFO ID filter format B and 128 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_144 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(8U)) /*!< FIFO ID filter format B and 144 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_160 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(9U)) /*!< FIFO ID filter format B and 160 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_176 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(10U)) /*!< FIFO ID filter format B and 176 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_192 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(11U)) /*!< FIFO ID filter format B and 192 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_208 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(12U)) /*!< FIFO ID filter format B and 208 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_32 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(0U)) /*!< FIFO ID filter format C and 32 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_64 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(1U)) /*!< FIFO ID filter format C and 64 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_96 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(2U)) /*!< FIFO ID filter format C and 96 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_128 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(3U)) /*!< FIFO ID filter format C and 128 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_160 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(4U)) /*!< FIFO ID filter format C and 160 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_192 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(5U)) /*!< FIFO ID filter format C and 192 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_224 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(6U)) /*!< FIFO ID filter format C and 224 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_256 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(7U)) /*!< FIFO ID filter format C and 256 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_288 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(8U)) /*!< FIFO ID filter format C and 288 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_320 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(9U)) /*!< FIFO ID filter format C and 320 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_352 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(10U)) /*!< FIFO ID filter format C and 352 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_384 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(11U)) /*!< FIFO ID filter format C and 384 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_416 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(12U)) /*!< FIFO ID filter format C and 416 filters */ +#define CAN_RXFIFO_FILTER_D CAN_FIFO_FILTER_FORMAT_D /*!< FIFO ID filter format D */ + +/* CAN_CRCC register */ +#define GET_CRCC_ANTM(regval) GET_BITS((regval),16,20) /*!< get associated number of mailbox for transmitting the CRCTC[14:0] value */ +#define GET_CRCC_CRCTC(regval) GET_BITS((regval),0,14) /*!< get transmitted CRC value for classical frames */ + +/* CAN_RFIFOIFMN register */ +#define GET_RFIFOIFMN_IDFMN(regval) GET_BITS((regval),0,8) /*!< get identifier filter matching number */ + +/* CAN_BT register */ +#define BT_PBS2(regval) (BITS(0,4) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_BT_PBS2 bit field */ +#define BT_PBS1(regval) (BITS(5,9) & ((uint32_t)(regval) << 5U)) /*!< write value to CAN_BT_PBS1 bit field */ +#define BT_PTS(regval) (BITS(10,15) & ((uint32_t)(regval) << 10U)) /*!< write value to CAN_BT_PTS bit field */ +#define BT_SJW(regval) (BITS(16,20) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_BT_SJW bit field */ +#define BT_BAUDPSC(regval) (BITS(21,30) & ((uint32_t)(regval) << 21U)) /*!< write value to CAN_BT_BAUDPSC bit field */ + +/* CAN_FDCTL register */ +#define GET_FDCTL_MDSZ(regval) GET_BITS((regval),16,17) /*!< get mailbox data size */ + +/* CAN_PN_CTL0 register */ +#define PN_CTL0_FFT(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_CTL0_FFT bit field */ +#define CAN_PN_FRAME_FILTERING_ID PN_CTL0_FFT(0U) /*!< all fields except DATA field, DLC field are filtered */ +#define CAN_PN_FRAME_FILTERING_ID_DATA PN_CTL0_FFT(1U) /*!< all fields are filtered */ +#define CAN_PN_FRAME_FILTERING_ID_NMM PN_CTL0_FFT(2U) /*!< all fields except DATA field, DLC field are filtered with NMM[7:0] matching times */ +#define CAN_PN_FRAME_FILTERING_ID_DATA_NMM PN_CTL0_FFT(3U) /*!< all fields are filtered with NMM[7:0] matching times */ + +#define PN_CTL0_IDFT(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) /*!< write value to CAN_PN_CTL0_IDFT bit field */ +#define CAN_PN_ID_FILTERING_EXACT PN_CTL0_IDFT(0U) /*!< DATA field equal to the expected data field */ +#define CAN_PN_ID_FILTERING_GREATER PN_CTL0_IDFT(1U) /*!< DATA field greater than or equal to the expected data */ +#define CAN_PN_ID_FILTERING_SMALLER PN_CTL0_IDFT(2U) /*!< DATA field greater than or equal to the expected data */ +#define CAN_PN_ID_FILTERING_RANGE PN_CTL0_IDFT(3U) /*!< DATA field is between expected data high threshold and low threshold */ + +#define PN_CTL0_DATAFT(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) /*!< write value to CAN_PN_CTL0_DATAFT bit field */ +#define CAN_PN_DATA_FILTERING_EXACT PN_CTL0_DATAFT(0U) /*!< ID field equal to the expected identifie */ +#define CAN_PN_DATA_FILTERING_GREATER PN_CTL0_DATAFT(1U) /*!< ID field greater than or equal to the expected identifier */ +#define CAN_PN_DATA_FILTERING_SMALLER PN_CTL0_DATAFT(2U) /*!< ID field smaller than or equal to the expected identifier */ +#define CAN_PN_DATA_FILTERING_RANGE PN_CTL0_DATAFT(3U) /*!< ID field is between expected idetifier high threshold and low threshold */ + +#define PN_CTL0_NMM(regval) (BITS(8,15) & ((uint32_t)(regval) << 8U)) /*!< write value to CAN_PN_CTL0_NMM bit field */ + +#define PN_CTL0_WMIE(regval) (BIT(16) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_PN_CTL0_WMIE bit */ + +#define PN_CTL0_WTOIE(regval) (BIT(17) & ((uint32_t)(regval) << 17U)) /*!< write value to CAN_PN_CTL0_WTOIE bit */ + +/* CAN_PN_TO register */ +#define PN_TO_WTO(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_TO_WTO bit field */ + +/* CAN_PN_STAT register */ +#define GET_PN_STAT_MMCNT(regval) GET_BITS((regval),8,15) /*!< get matching message counter in Pretended Networking mode */ + +/* CAN_PN_EID0 register */ +#define PN_EID0_EIDF_ELT_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to CAN_PN_EID0_EIDF_ELT bit field for standard frames */ +#define PN_EID0_EIDF_ELT_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_EID0_EIDF_ELT bit field for extended frames */ + +/* CAN_PN_EDLC register */ +#define PN_EDLC_DLCEHT(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_EDLC_DLCEHT bit field */ +#define PN_EDLC_DLCELT(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_PN_EDLC_DLCELT bit field */ + +/* CAN_PN_IFEID1 register */ +#define PN_IFEID1_IDEFD_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to CAN_PN_IFEID1_IDEFD bit field for standard frames */ +#define PN_IFEID1_IDEFD_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_IFEID1_IDEFD bit field for extended frames */ + +/* CAN_FDCTL register */ +#define GET_FDCTL_TDCV(regval) GET_BITS((regval),0,5) /*!< get transmitter delay compensation value */ + +#define FDCTL_TDCO(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to CAN_FDCTL_TDCO bit field */ + +#define FDCTL_MDSZ(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_FDCTL_MDSZ bit field */ +#define CAN_MAILBOX_DATA_SIZE_8_BYTES FDCTL_MDSZ(0U) /*!< mailbox data size is 8 bytes */ +#define CAN_MAILBOX_DATA_SIZE_16_BYTES FDCTL_MDSZ(1U) /*!< mailbox data size is 16 bytes */ +#define CAN_MAILBOX_DATA_SIZE_32_BYTES FDCTL_MDSZ(2U) /*!< mailbox data size is 32 bytes */ +#define CAN_MAILBOX_DATA_SIZE_64_BYTES FDCTL_MDSZ(3U) /*!< mailbox data size is 64 bytes */ + +/* CAN_FDBT register */ +#define FDBT_DPBS2(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_FDBT_DPBS2 bit field */ +#define FDBT_DPBS1(regval) (BITS(5,7) & ((uint32_t)(regval) << 5U)) /*!< write value to CAN_FDBT_DPBS1 bit field */ +#define FDBT_DPTS(regval) (BITS(10,14) & ((uint32_t)(regval) << 10U)) /*!< write value to CAN_FDBT_DPTS bit field */ +#define FDBT_DSJW(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_FDBT_DSJW bit field */ +#define FDBT_DBAUDPSC(regval) (BITS(20,29) & ((uint32_t)(regval) << 20U)) /*!< write value to CAN_FDBT_DBAUDPSC bit field */ + +/* CAN_CRCCFD register */ +#define GET_CRCCFD_CRCTCI(regval) GET_BITS((regval),0,20) /*!< get transmitted CRC value for classical and ISO / non-ISO FD frames */ +#define GET_CRCCFD_ANTM(regval) GET_BITS((regval),24,28) /*!< get associated number of mailbox for transmitting the CRCTCI[20:0] value */ + +/* MDES0 descriptor */ +#define MDES0_DLC(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) /*!< write value to MDES0 descriptor DLC bit field */ + +#define GET_MDES0_DLC(regval) GET_BITS((regval),16,19) /*!< get MDES0 descriptor DLC bit field */ + +#define MDES0_CODE(regval) (((uint32_t)(regval) << 24U) & CAN_MDES0_CODE) +#define CAN_MB_RX_STATUS_INACTIVE (0U) /*!< mailbox receive status inactive */ +#define CAN_MB_RX_STATUS_FULL (2U) /*!< mailbox receive status full */ +#define CAN_MB_RX_STATUS_EMPTY (4U) /*!< mailbox receive status empty */ +#define CAN_MB_RX_STATUS_OVERRUN (6U) /*!< mailbox receive status overrun */ +#define CAN_MB_RX_STATUS_RANSWER (10U) /*!< mailbox receive status answer */ +#define CAN_MB_RX_STATUS_BUSY (1U) /*!< mailbox receive status busy */ +#define CAN_MB_TX_STATUS_INACTIVE (8U) /*!< mailbox transmit status inactive */ +#define CAN_MB_TX_STATUS_ABORT (9U) /*!< mailbox transmit status abort */ +#define CAN_MB_TX_STATUS_DATA (12U) /*!< mailbox transmit status data */ + +#define GET_MDES0_CODE(regval) GET_BITS((regval),24,27) /*!< get MDES0 descriptor CODE bit field */ + +/* MDES1 descriptor */ +#define GET_MDES1_ID_EXD(regval) GET_BITS((regval),0,28) /*!< get MDES1 descriptor ID_STD and ID_EXD bit field */ +#define MDES1_ID_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to MDES1 descriptor ID_STD and ID_EXD bit field */ + +#define GET_MDES1_ID_STD(regval) GET_BITS((regval),18,28) /*!< get MDES1 descriptor ID_STD bit field */ +#define MDES1_ID_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to MDES1 descriptor ID_STD bit field */ + +#define MDES1_PRIO(regval) (BITS(29,31) & ((uint32_t)(regval) << 29U)) /*!< write value to MDES1 descriptor PRIO bit field */ + +/* FDES1 descriptor */ +#define GET_FDES1_ID_EXD(regval) GET_BITS((regval),0,28) /*!< get FDES1 descriptor ID_STD and ID_EXD bit field */ +#define FDES1_ID_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to FDES1 descriptor ID_STD and ID_EXD bit field */ + +#define GET_FDES1_ID_STD(regval) GET_BITS((regval),18,28) /*!< get FDES1 descriptor ID_STD bit field */ +#define FDES1_ID_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to FDES1 descriptor ID_STD bit field */ + +/* FDESx descriptor */ +#define CAN_DATA_FRAME_ACCEPTED ((uint32_t)0x00000000U) /*!< remote frames are rejected and data frames can be stored */ +#define CAN_REMOTE_FRAME_ACCEPTED ((uint32_t)0x00000001U) /*!< remote frames can be stored and data frames are rejected */ + +#define CAN_STANDARD_FRAME_ACCEPTED ((uint32_t)0x00000000U) /*!< extended frames are rejected and standard frames can be stored */ +#define CAN_EXTENDED_FRAME_ACCEPTED ((uint32_t)0x00000001U) /*!< extended frames can be stored and standard frames are rejected */ + +#define FIFO_FILTER_ID_EXD_A(val) (((uint32_t)(val) << 0U) & CAN_FDESX_ID_EXD_A) /*!< valid extended ID filter field in format A */ +#define FIFO_FILTER_ID_STD_A(val) (((uint32_t)(val) << 18U) & CAN_FDESX_ID_STD_A)/*!< valid standard ID filter field in format A */ +#define FIFO_FILTER_ID_EXD_B0(val) (GET_BITS((val),15,28) << 16U) /*!< valid extended ID filter field in format B */ +#define FIFO_FILTER_ID_EXD_B1(val) (GET_BITS((val),15,28) << 0U) /*!< valid extended ID filter field in format B */ +#define FIFO_FILTER_ID_STD_B0(val) (GET_BITS((val),0,10) << 19U) /*!< valid standard ID filter field in format B */ +#define FIFO_FILTER_ID_STD_B1(val) (GET_BITS((val),0,10) << 3U) /*!< valid standard ID filter field in format B */ +#define FIFO_FILTER_ID_EXD_C0(val) (GET_BITS((val),21,28) << 24U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_EXD_C1(val) (GET_BITS((val),21,28) << 16U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_EXD_C2(val) (GET_BITS((val),21,28) << 8U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_EXD_C3(val) (GET_BITS((val),21,28) << 0U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C0(val) (GET_BITS((val),3,10) << 24U) /*!< valid standard ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C1(val) (GET_BITS((val),3,10) << 16U) /*!< valid standard ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C2(val) (GET_BITS((val),3,10) << 8U) /*!< valid standard ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C3(val) (GET_BITS((val),3,10) << 0U) /*!< valid standard ID filter field in format C */ + +/* timeout definitions */ +#define CAN_DELAY ((uint32_t)0x01FFFFFFU) /*!< state timeout */ +#define CAN_MAX_MAILBOX_NUM 32U /*!< the supported maximum mailbox number */ +#define CAN_MAX_RAM_SIZE (CAN_MAX_MAILBOX_NUM * 4U) /*!< the maximum RAM size used for CAN mailbox */ +#define CAN_STANDARD BIT(31) /*!< standard frames */ +#define CAN_EXTENDED ((uint32_t)0x00000000U) /*!< extended frames*/ + +/* function declarations */ +/* CAN module initialize */ +/* deinitialize CAN */ +void can_deinit(uint32_t can_periph); +/* reset CAN internal state machines and CAN registers */ +ErrStatus can_software_reset(uint32_t can_periph); +/* CAN module initialization */ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init); +/* initialize CAN parameter structure with a default value */ +void can_struct_para_init(can_struct_type_enum type, void *p_struct); +/* configure receive fifo/mailbox private filter */ +void can_private_filter_config(uint32_t can_periph, uint32_t index, uint32_t filter_data); + +/* CAN operation modes */ +/* enter the corresponding mode */ +ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum mode); +/* get operation mode */ +can_operation_modes_enum can_operation_mode_get(uint32_t can_periph); +/* exit inactive mode */ +ErrStatus can_inactive_mode_exit(uint32_t can_periph); +/* exit Pretended Networking mode */ +ErrStatus can_pn_mode_exit(uint32_t can_periph); + +/* CAN FD mode configuration */ +/* can FD initialize */ +void can_fd_config(uint32_t can_periph, can_fd_parameter_struct *can_fd_para_init); +/* enable bit rate switching */ +void can_bitrate_switch_enable(uint32_t can_periph); +/* disable bit rate switching */ +void can_bitrate_switch_disable(uint32_t can_periph); +/* get transmitter delay compensation value */ +uint32_t can_tdc_get(uint32_t can_periph); +/* enable transmitter delay compensation */ +void can_tdc_enable(uint32_t can_periph); +/* disable transmitter delay compensation */ +void can_tdc_disable(uint32_t can_periph); + +/* CAN FIFO configuration */ +/* configure rx FIFO */ +void can_rx_fifo_config(uint32_t can_periph, can_fifo_parameter_struct *can_fifo_para_init); +/* configure rx FIFO filter table */ +void can_rx_fifo_filter_table_config(uint32_t can_periph, can_rx_fifo_id_filter_struct id_filter_table[]); +/* read rx FIFO data */ +void can_rx_fifo_read(uint32_t can_periph, can_rx_fifo_struct *rx_fifo); +/* get rx FIFO filter matching number */ +uint32_t can_rx_fifo_filter_matching_number_get(uint32_t can_periph); +/* clear rx FIFO */ +void can_rx_fifo_clear(uint32_t can_periph); + +/* CAN mailbox operation */ +/* get mailbox RAM address */ +uint32_t *can_ram_address_get(uint32_t can_periph, uint32_t index); +/* configure mailbox */ +void can_mailbox_config(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara); +/* abort mailbox transmit */ +void can_mailbox_transmit_abort(uint32_t can_periph, uint32_t index); +/* inactive transmit mailbox */ +void can_mailbox_transmit_inactive(uint32_t can_periph, uint32_t index); +/* read receive mailbox data */ +ErrStatus can_mailbox_receive_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara); +/* lock the receive mailbox */ +void can_mailbox_receive_lock(uint32_t can_periph, uint32_t index); +/* unlock the receive mailbox */ +void can_mailbox_receive_unlock(uint32_t can_periph); +/* inactive the receive mailbox */ +void can_mailbox_receive_inactive(uint32_t can_periph, uint32_t index); +/* get mailbox code value */ +uint32_t can_mailbox_code_get(uint32_t can_periph, uint32_t index); + +/* errors & CRC */ +/* configure error counter */ +void can_error_counter_config(uint32_t can_periph, can_error_counter_struct *errcnt_struct); +/* get error count */ +void can_error_counter_get(uint32_t can_periph, can_error_counter_struct *errcnt_struct); +/* get error state indicator */ +can_error_state_enum can_error_state_get(uint32_t can_periph); +/* get mailbox CRC value */ +void can_crc_get(uint32_t can_periph, can_crc_struct *crc_struct); + +/* Pretended Networking mode configuration */ +/* configure Pretended Networking mode parameter */ +void can_pn_mode_config(uint32_t can_periph, can_pn_mode_config_struct *pnmod_config); +/* configure pn mode filter */ +void can_pn_mode_filter_config(uint32_t can_periph, can_pn_mode_filter_struct *expect, can_pn_mode_filter_struct *filter); +/* get matching message counter of Pretended Networking mode */ +int32_t can_pn_mode_num_of_match_get(uint32_t can_periph); +/* get matching message */ +void can_pn_mode_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara); + +/* others */ +/* enable self reception */ +void can_self_reception_enable(uint32_t can_periph); +/* disable self reception */ +void can_self_reception_disable(uint32_t can_periph); +/* enable transmit abort */ +void can_transmit_abort_enable(uint32_t can_periph); +/* disable transmit abort */ +void can_transmit_abort_disable(uint32_t can_periph); +/* enable auto bus off recovery mode */ +void can_auto_busoff_recovery_enable(uint32_t can_periph); +/* disable auto bus off recovery mode */ +void can_auto_busoff_recovery_disable(uint32_t can_periph); +/* enable time sync mode */ +void can_time_sync_enable(uint32_t can_periph); +/* disable time sync mode */ +void can_time_sync_disable(uint32_t can_periph); +/* enable edge filter mode */ +void can_edge_filter_mode_enable(uint32_t can_periph); +/* disable edge filter mode */ +void can_edge_filter_mode_disable(uint32_t can_periph); +/* enable protocol exception detection mode */ +void can_ped_mode_enable(uint32_t can_periph); +/* disable protocol exception detection mode */ +void can_ped_mode_disable(uint32_t can_periph); +/* configure arbitration delay bits */ +void can_arbitration_delay_bits_config(uint32_t can_periph, uint32_t delay_bits); +/* configure bit sampling mode */ +void can_bsp_mode_config(uint32_t can_periph, uint32_t sampling_mode); + +/* CAN interrupt and flag */ +/* get CAN flag */ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); +/* clear CAN flag */ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* enable CAN interrupt */ +ErrStatus can_interrupt_enable(uint32_t can_periph, can_interrupt_enum interrupt); +/* disable CAN interrupt */ +ErrStatus can_interrupt_disable(uint32_t can_periph, can_interrupt_enum interrupt); +/* get CAN interrupt flag */ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum int_flag); +/* clear CAN interrupt flag */ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum int_flag); + +#endif /* GD32H7XX_CAN_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cau.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cau.h new file mode 100644 index 0000000000..a4456f9e4d --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cau.h @@ -0,0 +1,322 @@ +/*! + \file gd32h7xx_cau.h + \brief definitions for the CAU + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_CAU_H +#define GD32H7XX_CAU_H + +#include "gd32h7xx.h" + +/* CAU definitions */ +#define CAU CAU_BASE /*!< CAU base address */ + +/* registers definitions */ +#define CAU_CTL REG32(CAU + 0x00000000U) /*!< control register */ +#define CAU_STAT0 REG32(CAU + 0x00000004U) /*!< status register 0 */ +#define CAU_DI REG32(CAU + 0x00000008U) /*!< data input register */ +#define CAU_DO REG32(CAU + 0x0000000CU) /*!< data output register */ +#define CAU_DMAEN REG32(CAU + 0x00000010U) /*!< DMA enable register */ +#define CAU_INTEN REG32(CAU + 0x00000014U) /*!< interrupt enable register */ +#define CAU_STAT1 REG32(CAU + 0x00000018U) /*!< status register 1 */ +#define CAU_INTF REG32(CAU + 0x0000001CU) /*!< interrupt flag register */ +#define CAU_KEY0H REG32(CAU + 0x00000020U) /*!< key 0 high register */ +#define CAU_KEY0L REG32(CAU + 0x00000024U) /*!< key 0 low register */ +#define CAU_KEY1H REG32(CAU + 0x00000028U) /*!< key 1 high register */ +#define CAU_KEY1L REG32(CAU + 0x0000002CU) /*!< key 1 low register */ +#define CAU_KEY2H REG32(CAU + 0x00000030U) /*!< key 2 high register */ +#define CAU_KEY2L REG32(CAU + 0x00000034U) /*!< key 2 low register */ +#define CAU_KEY3H REG32(CAU + 0x00000038U) /*!< key 3 high register */ +#define CAU_KEY3L REG32(CAU + 0x0000003CU) /*!< key 3 low register */ +#define CAU_IV0H REG32(CAU + 0x00000040U) /*!< initial vector 0 high register */ +#define CAU_IV0L REG32(CAU + 0x00000044U) /*!< initial vector 0 low register */ +#define CAU_IV1H REG32(CAU + 0x00000048U) /*!< initial vector 1 high register */ +#define CAU_IV1L REG32(CAU + 0x0000004CU) /*!< initial vector 1 low register */ +#define CAU_GCMCCMCTXSx(x) REG32(CAU + 0x00000050U + (uint32_t)(4U * (x))) /*!< GCM or CCM mode context switch register, x = 0...7 */ +#define CAU_GCMCTXSx(x) REG32(CAU + 0x00000070U + (uint32_t)(4U * (x))) /*!< GCM mode context switch register, x = 0...7 */ + +/* bits definitions */ +/* CAU_CTL */ +#define CAU_CTL_KEY_SEL BIT(0) /*!< key select */ +#define CAU_CTL_CAUDIR BIT(2) /*!< algorithm direction */ +#define CAU_CTL_ALGM (BITS(3,5) | BIT(19)) /*!< cryptographic algorithm mode */ +#define CAU_CTL_DATAM BITS(6,7) /*!< data swapping selection */ +#define CAU_CTL_KEYM BITS(8,9) /*!< key length selection when aes mode */ +#define CAU_CTL_FFLUSH BIT(14) /*!< FIFO flush */ +#define CAU_CTL_CAUEN BIT(15) /*!< cryptographic module enable */ +#define CAU_CTL_GCM_CCMPH BITS(16,17) /*!< GCM CCM phase */ +#define CAU_CTL_NBPILB BITS(20,23) /*!< number of bytes padding in last block */ + +/* CAU_STAT0 */ +#define CAU_STAT0_IEM BIT(0) /*!< IN FIFO empty flag */ +#define CAU_STAT0_INF BIT(1) /*!< IN FIFO not full flag */ +#define CAU_STAT0_ONE BIT(2) /*!< OUT FIFO not empty flag */ +#define CAU_STAT0_OFU BIT(3) /*!< OUT FIFO full flag */ +#define CAU_STAT0_BUSY BIT(4) /*!< busy flag */ + +/* CAU_DI */ +#define CAU_DI_DI BITS(0,31) /*!< data input */ + +/* CAU_DO */ +#define CAU_DO_DO BITS(0,31) /*!< data output */ + +/* CAU_DMAEN */ +#define CAU_DMAEN_DMAIEN BIT(0) /*!< IN FIFO DMA enable */ +#define CAU_DMAEN_DMAOEN BIT(1) /*!< OUT FIFO DMA enable */ + +/* CAU_INTEN */ +#define CAU_INTEN_IINTEN BIT(0) /*!< IN FIFO interrupt enable */ +#define CAU_INTEN_OINTEN BIT(1) /*!< OUT FIFO interrupt enable */ + +/* CAU_STAT1 */ +#define CAU_STAT1_ISTA BIT(0) /*!< flag set when there is less than 4 words in IN FIFO */ +#define CAU_STAT1_OSTA BIT(1) /*!< flag set when there is one or more word in OUT FIFO */ + +/* CAU_INTF */ +#define CAU_INTF_IINTF BIT(0) /*!< IN FIFO interrupt flag */ +#define CAU_INTF_OINTF BIT(1) /*!< OUT FIFO interrupt flag */ + +/* CAU_KEYxH x=0..3 */ +#define CAU_KEYXH_KEYXH BITS(0,31) /*!< the key for des, tdes, aes */ + +/* CAU_KEYxL x=0..3 */ +#define CAU_KEYXL_KEYXL BITS(0,31) /*!< the key for des, tdes, aes */ + +/* CAU_IVxH x=0..1 */ +#define CAU_IVXH_IVXH BITS(0,31) /*!< the initialization vector for des, tdes, aes */ + +/* CAU_IVxL x=0..1 */ +#define CAU_IVXL_IVXL BITS(0,31) /*!< the initialization vector for des, tdes, aes */ + +/* constants definitions */ +/* structure for keys initialization of the cau */ +typedef struct { + uint32_t key_0_high; /*!< key 0 high */ + uint32_t key_0_low; /*!< key 0 low */ + uint32_t key_1_high; /*!< key 1 high */ + uint32_t key_1_low; /*!< key 1 low */ + uint32_t key_2_high; /*!< key 2 high */ + uint32_t key_2_low; /*!< key 2 low */ + uint32_t key_3_high; /*!< key 3 high */ + uint32_t key_3_low; /*!< key 3 low */ +} cau_key_parameter_struct; + +/* structure for vectors initialization of the cau */ +typedef struct { + uint32_t iv_0_high; /*!< init vector 0 high */ + uint32_t iv_0_low; /*!< init vector 0 low */ + uint32_t iv_1_high; /*!< init vector 1 high */ + uint32_t iv_1_low; /*!< init vector 1 low */ +} cau_iv_parameter_struct; + +/* structure for cau context swapping */ +typedef struct { + uint32_t ctl_config; /*!< current configuration */ + uint32_t iv_0_high; /*!< init vector 0 high */ + uint32_t iv_0_low; /*!< init vector 0 low */ + uint32_t iv_1_high; /*!< init vector 1 high */ + uint32_t iv_1_low; /*!< init vector 1 low */ + uint32_t key_0_high; /*!< key 0 high */ + uint32_t key_0_low; /*!< key 0 low */ + uint32_t key_1_high; /*!< key 1 high */ + uint32_t key_1_low; /*!< key 1 low */ + uint32_t key_2_high; /*!< key 2 high */ + uint32_t key_2_low; /*!< key 2 low */ + uint32_t key_3_high; /*!< key 3 high */ + uint32_t key_3_low; /*!< key 3 low */ + uint32_t gcmccmctxs[8]; /*!< GCM or CCM mode context switch */ + uint32_t gcmctxs[8]; /*!< GCM mode context switch */ +} cau_context_parameter_struct; + +/* structure for encrypt and decrypt parameters */ +typedef struct { + uint32_t alg_dir; /*!< algorithm directory */ + uint8_t *key; /*!< key */ + uint32_t key_size; /*!< key size in bytes */ + uint8_t *iv; /*!< initialization vector */ + uint32_t iv_size; /*!< iv size in bytes */ + uint8_t *input; /*!< input data */ + uint32_t in_length; /*!< input data length in bytes */ + uint8_t *aad; /*!< additional authentication data */ + uint32_t aad_size; /*!< aad size */ +} cau_parameter_struct; + +/* cau_ctl register value */ +#define CAU_ENCRYPT ((uint32_t)0x00000000U) /*!< encrypt */ +#define CAU_DECRYPT CAU_CTL_CAUDIR /*!< decrypt */ + +#define CTL_ALGM(regval) ((BITS(3,5) & ((uint32_t)(regval) << 3U)) | \ + (BIT(19) & ((uint32_t)(regval) << 16U))) /*!< write value to CAU_CTL_ALGM bit field */ +#define CAU_MODE_TDES_ECB CTL_ALGM(0) /*!< TDES-ECB (3DES Electronic codebook) */ +#define CAU_MODE_TDES_CBC CTL_ALGM(1) /*!< TDES-CBC (3DES Cipher block chaining) */ +#define CAU_MODE_DES_ECB CTL_ALGM(2) /*!< DES-ECB (simple DES Electronic codebook) */ +#define CAU_MODE_DES_CBC CTL_ALGM(3) /*!< DES-CBC (simple DES Cipher block chaining) */ +#define CAU_MODE_AES_ECB CTL_ALGM(4) /*!< AES-ECB (AES Electronic codebook) */ +#define CAU_MODE_AES_CBC CTL_ALGM(5) /*!< AES-CBC (AES Cipher block chaining) */ +#define CAU_MODE_AES_CTR CTL_ALGM(6) /*!< AES-CTR (AES counter mode) */ +#define CAU_MODE_AES_KEY CTL_ALGM(7) /*!< AES decryption key preparation mode */ +#define CAU_MODE_AES_GCM CTL_ALGM(8) /*!< AES-GCM (AES Galois/counter mode) */ +#define CAU_MODE_AES_CCM CTL_ALGM(9) /*!< AES-CCM (AES combined cipher machine mode) */ +#define CAU_MODE_AES_CFB CTL_ALGM(10) /*!< AES-CFB (cipher feedback mode) */ +#define CAU_MODE_AES_OFB CTL_ALGM(11) /*!< AES-OFB (output feedback mode) */ + +#define CTL_DATAM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6U)) /*!< write value to CAU_CTL_DATAM bit field */ +#define CAU_SWAPPING_32BIT CTL_DATAM(0) /*!< no swapping */ +#define CAU_SWAPPING_16BIT CTL_DATAM(1) /*!< half-word swapping */ +#define CAU_SWAPPING_8BIT CTL_DATAM(2) /*!< bytes swapping */ +#define CAU_SWAPPING_1BIT CTL_DATAM(3) /*!< bit swapping */ + +#define CAU_KEY 0x00000000U /*!< use the key from CAU register */ +#define CAU_EFUSE_KEY 0x00000001U /*!< use the key from EFUSE */ + +#define CTL_KEYM(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) /*!< write value to CAU_CTL_KEYM bit field */ +#define CAU_KEYSIZE_128BIT CTL_KEYM(0) /*!< 128 bit key length */ +#define CAU_KEYSIZE_192BIT CTL_KEYM(1) /*!< 192 bit key length */ +#define CAU_KEYSIZE_256BIT CTL_KEYM(2) /*!< 256 bit key length */ + +#define CTL_GCM_CCMPH(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) /*!< write value to CAU_CTL_GCM_CCMPH bit field */ +#define CAU_PREPARE_PHASE CTL_GCM_CCMPH(0) /*!< prepare phase */ +#define CAU_AAD_PHASE CTL_GCM_CCMPH(1) /*!< AAD phase */ +#define CAU_ENCRYPT_DECRYPT_PHASE CTL_GCM_CCMPH(2) /*!< encryption/decryption phase */ +#define CAU_TAG_PHASE CTL_GCM_CCMPH(3) /*!< tag phase */ + +#define CAU_PADDING_BYTES(regval) (BITS(20, 23) & ((uint32_t)(regval) << 20U)) + +/* cau_stat0 register value */ +#define CAU_FLAG_INFIFO_EMPTY CAU_STAT0_IEM /*!< IN FIFO empty */ +#define CAU_FLAG_INFIFO_NO_FULL CAU_STAT0_INF /*!< IN FIFO is not full */ +#define CAU_FLAG_OUTFIFO_NO_EMPTY CAU_STAT0_ONE /*!< OUT FIFO not empty */ +#define CAU_FLAG_OUTFIFO_FULL CAU_STAT0_OFU /*!< OUT FIFO is full */ +#define CAU_FLAG_BUSY CAU_STAT0_BUSY /*!< the CAU core is busy */ + +/* cau_dmaen register value */ +#define CAU_DMA_INFIFO CAU_DMAEN_DMAIEN /*!< DMA input enable */ +#define CAU_DMA_OUTFIFO CAU_DMAEN_DMAOEN /*!< DMA output enable */ + +/* cau_inten register value */ +#define CAU_INT_INFIFO CAU_INTEN_IINTEN /*!< IN FIFO Interrupt */ +#define CAU_INT_OUTFIFO CAU_INTEN_OINTEN /*!< OUT FIFO Interrupt */ + +/* cau_stat1 register value */ +#define CAU_FLAG_INFIFO CAU_STAT1_ISTA /*!< IN FIFO flag status */ +#define CAU_FLAG_OUTFIFO CAU_STAT1_OSTA /*!< OUT FIFO flag status */ + +/* cau_intf register value */ +#define CAU_INT_FLAG_INFIFO CAU_INTF_IINTF /*!< IN FIFO interrupt status */ +#define CAU_INT_FLAG_OUTFIFO CAU_INTF_OINTF /*!< OUT FIFO interrupt status */ + +/* function declarations */ +/* initialization functions */ +/* reset the CAU peripheral */ +void cau_deinit(void); +/* initialize the CAU encrypt and decrypt parameter struct with the default values */ +void cau_struct_para_init(cau_parameter_struct *cau_parameter); +/* initialize the key parameter struct with the default values */ +void cau_key_struct_para_init(cau_key_parameter_struct *key_initpara); +/* initialize the vectors parameter struct with the default values */ +void cau_iv_struct_para_init(cau_iv_parameter_struct *iv_initpara); +/* initialize the context parameter struct with the default values */ +void cau_context_struct_para_init(cau_context_parameter_struct *cau_context); + +/* configuration functions */ +/* enable the CAU peripheral */ +void cau_enable(void); +/* disable the CAU peripheral */ +void cau_disable(void); +/* enable the CAU DMA interface */ +void cau_dma_enable(uint32_t dma_req); +/* disable the CAU DMA interface */ +void cau_dma_disable(uint32_t dma_req); +/* initialize the CAU peripheral */ +void cau_init(uint32_t alg_dir, uint32_t algo_mode, uint32_t swapping); +/* configure key selection */ +void cau_aes_key_select(uint32_t key_selection); +/* configure key size if use AES algorithm */ +void cau_aes_keysize_config(uint32_t key_size); +/* initialize the key parameters */ +void cau_key_init(cau_key_parameter_struct *key_initpara); +/* initialize the vectors parameters */ +void cau_iv_init(cau_iv_parameter_struct *iv_initpara); +/* configure phase */ +void cau_phase_config(uint32_t phase); +/* flush the IN and OUT FIFOs */ +void cau_fifo_flush(void); +/* return whether CAU peripheral is enabled or disabled */ +ControlStatus cau_enable_state_get(void); + +/* read and write functions */ +/* write data to the IN FIFO */ +void cau_data_write(uint32_t data); +/* return the last data entered into the output FIFO */ +uint32_t cau_data_read(void); + +/* context switch functions */ +/* save context before context switching */ +void cau_context_save(cau_context_parameter_struct *cau_context, cau_key_parameter_struct *key_initpara); +/* restore context after context switching */ +void cau_context_restore(cau_context_parameter_struct *cau_context); + +/* encrypt and decrypt functions */ +/* encrypt and decrypt using AES in ECB mode */ +ErrStatus cau_aes_ecb(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using AES in CBC mode */ +ErrStatus cau_aes_cbc(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using AES in CTR mode */ +ErrStatus cau_aes_ctr(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using AES in CFB mode */ +ErrStatus cau_aes_cfb(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using AES in OFB mode */ +ErrStatus cau_aes_ofb(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using AES in GCM mode */ +ErrStatus cau_aes_gcm(cau_parameter_struct *cau_parameter, uint8_t *output, uint8_t *tag); +/* encrypt and decrypt using AES in CCM mode */ +ErrStatus cau_aes_ccm(cau_parameter_struct *cau_parameter, uint8_t *output, uint8_t tag[], uint32_t tag_size, uint8_t aad_buf[]); +/* encrypt and decrypt using TDES in ECB mode */ +ErrStatus cau_tdes_ecb(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using TDES in CBC mode */ +ErrStatus cau_tdes_cbc(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using DES in ECB mode */ +ErrStatus cau_des_ecb(cau_parameter_struct *cau_parameter, uint8_t *output); +/* encrypt and decrypt using DES in CBC mode */ +ErrStatus cau_des_cbc(cau_parameter_struct *cau_parameter, uint8_t *output); + +/* interrupt & flag functions */ +/* get the CAU flag status */ +FlagStatus cau_flag_get(uint32_t flag); +/* enable the CAU interrupts */ +void cau_interrupt_enable(uint32_t interrupt); +/* disable the CAU interrupts */ +void cau_interrupt_disable(uint32_t interrupt); +/* get the interrupt flag */ +FlagStatus cau_interrupt_flag_get(uint32_t int_flag); + +#endif /* GD32H7XX_CAU_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cmp.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cmp.h new file mode 100644 index 0000000000..f7f09c5297 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cmp.h @@ -0,0 +1,220 @@ +/*! + \file gd32h7xx_cmp.h + \brief definitions for the CMP + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_CMP_H +#define GD32H7XX_CMP_H + +#include "gd32h7xx.h" + +/* CMP definitions */ +#define CMP CMP_BASE /*!< CMP base address */ + +/* registers definitions */ +#define CMP_STAT REG32((CMP) + 0x00000000U) /*!< CMP status register */ +#define CMP_IFC REG32((CMP) + 0x00000004U) /*!< CMP interrupt flag clear register */ +#define CMP_SR REG32((CMP) + 0x00000008U) /*!< CMP alternate select register */ +#define CMP0_CS REG32((CMP) + 0x0000000CU) /*!< CMP0 control and status register */ +#define CMP1_CS REG32((CMP) + 0x00000010U) /*!< CMP1 control and status register */ + +/* bits definitions */ +/* CMP_STAT */ +#define CMP_STAT_CMP0O BIT(0) /*!< CMP0 output */ +#define CMP_STAT_CMP1O BIT(1) /*!< CMP1 output */ +#define CMP_STAT_CMP0IF BIT(16) /*!< CMP0 interrupt flag */ +#define CMP_STAT_CMP1IF BIT(17) /*!< CMP1 interrupt flag */ + +/* CMP_IFC */ +#define CMP_IFC_CMP0IC BIT(16) /*!< CMP0 interrupt flag clear */ +#define CMP_IFC_CMP1IC BIT(17) /*!< CMP1 interrupt flag clear */ + +/* CMP_SR */ +#define CMP_SR_AFSE_PA6 BITS(0,10) /*!< CMP selects alternate output ports PA6 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PA8 BIT(1) /*!< PA8 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PB12 BIT(2) /*!< PB12 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PE6 BIT(3) /*!< PE6 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PE15 BIT(4) /*!< PE15 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PG2 BIT(5) /*!< PG2 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PG3 BIT(6) /*!< PG3 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PG4 BIT(7) /*!< PG4 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PK0 BIT(8) /*!< PK0 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PK1 BIT(9) /*!< PK1 alternate function select for CMPx_OUT */ +#define CMP_SR_AFSE_PK2 BIT(10) /*!< PK2 alternate function select for CMPx_OUT */ + +/* CMPx_CS */ +#define CMP_CS_CMPXEN BIT(0) /*!< CMPx enable */ +#define CMP_CS_CMPXBEN BIT(1) /*!< CMPx scaler bridge enable bit */ +#define CMP_CS_CMPXSEN BIT(2) /*!< CMPx voltage scaler enable bit */ +#define CMP_CS_CMPXPL BIT(3) /*!< CMPx output polarity */ +#define CMP_CS_WNDEN BIT(4) /*!< CMP Window mode enable */ +#define CMP_CS_CMPXINTEN BIT(6) /*!< CMPx interrupt enable */ +#define CMP_CS_CMPXHST BITS(8,9) /*!< CMPx hysteresis */ +#define CMP_CS_CMPXM BITS(12,13) /*!< CMPx mode */ +#define CMP_CS_CMPXMISEL BITS(16,18) /*!< CMP_IM input selection */ +#define CMP_CS_CMPXPSEL BIT(20) /*!< CMP_IP input selection */ +#define CMP_CS_CMPXBLK BITS(24,27) /*!< CMPx output blanking source */ +#define CMP_CS_CMPXLK BIT(31) /*!< CMPx lock */ + + +/* constants definitions */ +/* CMP units */ +typedef enum{ + CMP0, /*!< comparator 0 */ + CMP1 /*!< comparator 1 */ +}cmp_enum; + +/* CMP operating mode */ +#define CS_CMPXM(regval) (BITS(12,13) & ((uint32_t)(regval) << 12U)) +#define CMP_MODE_HIGHSPEED CS_CMPXM(0) /*!< CMP mode high speed */ +#define CMP_MODE_MIDDLESPEED CS_CMPXM(1) /*!< CMP mode middle speed */ +#define CMP_MODE_VERYLOWSPEED CS_CMPXM(3) /*!< CMP mode very low speed */ + +/* CMP hysteresis */ +#define CS_CMPXHST(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define CMP_HYSTERESIS_NO CS_CMPXHST(0) /*!< CMP output no hysteresis */ +#define CMP_HYSTERESIS_LOW CS_CMPXHST(1) /*!< CMP output low hysteresis */ +#define CMP_HYSTERESIS_MIDDLE CS_CMPXHST(2) /*!< CMP output middle hysteresis */ +#define CMP_HYSTERESIS_HIGH CS_CMPXHST(3) /*!< CMP output high hysteresis */ + +/* CMP inverting input */ +#define CS_CMPXMSEL(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) +#define CMP_INVERTING_INPUT_1_4VREFINT CS_CMPXMSEL(0) /*!< CMP inverting input 1/4 Vrefint */ +#define CMP_INVERTING_INPUT_1_2VREFINT CS_CMPXMSEL(1) /*!< CMP inverting input 1/2 Vrefint */ +#define CMP_INVERTING_INPUT_3_4VREFINT CS_CMPXMSEL(2) /*!< CMP inverting input 3/4 Vrefint */ +#define CMP_INVERTING_INPUT_VREFINT CS_CMPXMSEL(3) /*!< CMP inverting input Vrefint */ +#define CMP_INVERTING_INPUT_PA4 CS_CMPXMSEL(4) /*!< CMP inverting input DAC0_OUT0 */ +#define CMP_INVERTING_INPUT_PA5 CS_CMPXMSEL(5) /*!< CMP inverting input DAC0_OUT1 */ +#define CMP_INVERTING_INPUT_PB1_PE10 CS_CMPXMSEL(6) /*!< CMP inverting input PB1 for CMP0 or PE10 for CMP1 */ +#define CMP_INVERTING_INPUT_PC4_PE7 CS_CMPXMSEL(7) /*!< CMP inverting input PC4 for CMP0 or PE7 for CMP1 */ + +/* CMP noninverting input*/ +#define CS_CMPXPSEL(regval) (BIT(20) & ((uint32_t)(regval) << 20U)) +#define CMP_NONINVERTING_INPUT_PB0_PE9 CS_CMPXPSEL(0) /*!< CMP noninverting input PB0 for CMP0 or PE9 for CMP1 */ +#define CMP_NONINVERTING_INPUT_PB2_PE11 CS_CMPXPSEL(1) /*!< CMP noninverting input PB2 for CMP0 or PE11 for CMP1 */ + +/* CMP output polarity*/ +#define CS_CMPXPL(regval) (BIT(3) & ((uint32_t)(regval) << 3U)) +#define CMP_OUTPUT_POLARITY_NONINVERTED CS_CMPXPL(0) /*!< CMP output not inverted */ +#define CMP_OUTPUT_POLARITY_INVERTED CS_CMPXPL(1) /*!< CMP output inverted */ + +/* CMP blanking suorce */ +#define CS_CMPXBLK(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U)) +#define CMP_BLANKING_NONE CS_CMPXBLK(0) /*!< CMP no blanking source */ +#define CMP_BLANKING_TIMER0_OC0 CS_CMPXBLK(1) /*!< CMP TIMER0_CH0 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER1_OC2 CS_CMPXBLK(2) /*!< CMP TIMER1_CH2 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER2_OC2 CS_CMPXBLK(3) /*!< CMP TIMER2_CH2 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER2_OC3 CS_CMPXBLK(4) /*!< CMP TIMER2_CH3 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER7_OC4 CS_CMPXBLK(5) /*!< CMP TIMER7_CH0 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER14_OC0 CS_CMPXBLK(6) /*!< CMP TIMER14_CH0 output compare signal selected as blanking source */ + +/* comparator output level */ +#define CMP_OUTPUTLEVEL_HIGH ((uint32_t)0x00000001U) /*!< comparator output high */ +#define CMP_OUTPUTLEVEL_LOW ((uint32_t)0x00000000U) /*!< comparator output low */ + +/* CMP alternate output ports */ +#define SR_AFSE(regval) (BITS(0,10) & ((uint32_t)(regval) << 0U)) +#define CMP_AFSE_GPIO_PA6 SR_AFSE(0) /*!< CMP alternate GPIO PA6 */ +#define CMP_AFSE_GPIO_PA8 SR_AFSE(1) /*!< CMP alternate GPIO PA8 */ +#define CMP_AFSE_GPIO_PB12 SR_AFSE(2) /*!< CMP alternate GPIO PB12 */ +#define CMP_AFSE_GPIO_PE6 SR_AFSE(3) /*!< CMP alternate GPIO PE6 */ +#define CMP_AFSE_GPIO_PE15 SR_AFSE(4) /*!< CMP alternate GPIO PE15 */ +#define CMP_AFSE_GPIO_PG2 SR_AFSE(5) /*!< CMP alternate GPIO PG2 */ +#define CMP_AFSE_GPIO_PG3 SR_AFSE(6) /*!< CMP alternate GPIO PG3 */ +#define CMP_AFSE_GPIO_PG4 SR_AFSE(7) /*!< CMP alternate GPIO PG4 */ +#define CMP_AFSE_GPIO_PK0 SR_AFSE(8) /*!< CMP alternate GPIO PK0 */ +#define CMP_AFSE_GPIO_PK1 SR_AFSE(9) /*!< CMP alternate GPIO PK1*/ +#define CMP_AFSE_GPIO_PK2 SR_AFSE(10) /*!< CMP alternate GPIO PK2 */ + +/* CMP flag definitions */ +#define CMP_FLAG_COMPARE CMP_STAT_CMP0IF /*!< CMP compare flag */ + +/* CMP interrupt definitions */ +#define CMP_INT_COMPARE CMP_CS_CMPXINTEN /*!< CMP compare interrupt */ + +/* CMP interrupt flag */ +#define CMP_INT_FLAG_COMPARE CMP_STAT_CMP0IF /*!< CMP interrupt flag */ + +/* function declarations */ +/* initialization functions */ +/* CMP deinit */ +void cmp_deinit(cmp_enum cmp_periph); +/* CMP mode init */ +void cmp_mode_init(cmp_enum cmp_periph, uint32_t operating_mode, uint32_t inverting_input, uint32_t output_hysteresis); +/* CMP noninverting input select */ +void cmp_noninverting_input_select(cmp_enum cmp_periph, uint32_t noninverting_input); +/* CMP output init */ +void cmp_output_init(cmp_enum cmp_periph, uint32_t output_polarity); +/* config comparator output port */ +void cmp_output_mux_config(cmp_enum cmp_periph, uint32_t cmp_output_sel); +/* CMP output blanking function init */ +void cmp_blanking_init(cmp_enum cmp_periph,uint32_t blanking_source_selection); + +/* enable functions */ +/* enable CMP */ +void cmp_enable(cmp_enum cmp_periph); +/* disable CMP */ +void cmp_disable(cmp_enum cmp_periph); +/* enable the window mode */ +void cmp_window_enable(void); +/* disable the window mode */ +void cmp_window_disable(void); +/* lock the CMP */ +void cmp_lock_enable(cmp_enum cmp_periph); +/* enable the voltage scaler */ +void cmp_voltage_scaler_enable(cmp_enum cmp_periph); +/* disable the voltage scaler */ +void cmp_voltage_scaler_disable(cmp_enum cmp_periph); +/* enable the scaler bridge */ +void cmp_scaler_bridge_enable(cmp_enum cmp_periph); +/* disable the scaler bridge */ +void cmp_scaler_bridge_disable(cmp_enum cmp_periph); + +/* get state related functions */ +/* get output level */ +uint32_t cmp_output_level_get(cmp_enum cmp_periph); + +/* flag and interrupt functions */ +/* get CMP flag */ +FlagStatus cmp_flag_get(cmp_enum cmp_periph, uint32_t flag); +/* clear CMP flag */ +void cmp_flag_clear(cmp_enum cmp_periph, uint32_t flag); +/* enable CMP interrupt */ +void cmp_interrupt_enable(cmp_enum cmp_periph, uint32_t interrupt); +/* disable CMP interrupt */ +void cmp_interrupt_disable(cmp_enum cmp_periph, uint32_t interrupt); +/* get CMP interrupt flag */ +FlagStatus cmp_interrupt_flag_get(cmp_enum cmp_periph, uint32_t flag); +/* clear CMP interrupt flag */ +void cmp_interrupt_flag_clear(cmp_enum cmp_periph, uint32_t flag); + +#endif /* GD32H7XX_CMP_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cpdm.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cpdm.h new file mode 100644 index 0000000000..d3857b3f9f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_cpdm.h @@ -0,0 +1,104 @@ +/*! + \file gd32h7xx_cpdm.h + \brief definitions for the CPDM + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_CPDM_H +#define GD32H7XX_CPDM_H + +#include "gd32h7xx.h" + +/* CPDM definitions */ +#define CPDM_SDIO0 (SDIO0 + 0x00001000U) /*!< SDIO0 CPDM base address */ +#define CPDM_SDIO1 (SDIO1 + 0x00000400U) /*!< SDIO1 CPDM base address */ + +/* registers definitions */ +#define CPDM_CTL(cpdmx) REG32((cpdmx) + 0x00000000U) /*!< CPDM control register */ +#define CPDM_CFG(cpdmx) REG32((cpdmx) + 0x00000004U) /*!< CPDM configuration register */ + +/* bits definitions */ +/* CPDM_CTL */ +#define CPDM_CTL_CPDMEN BIT(0) /*!< CPDM enable */ +#define CPDM_CTL_DLSEN BIT(1) /*!< CPDM delay line sample module enable */ + +/* CPDM_CFG */ +#define CPDM_CFG_CPSEL BITS(0,3) /*!< select the phase of the output clock */ +#define CPDM_CFG_DLSTCNT BITS(8,14) /*!< define a delay step count for a unit delay UNIT */ +#define CPDM_CFG_DLLEN BITS(16,27) /*!< delay line length */ +#define CPDM_CFG_DLLENF BIT(31) /*!< valid mark of delay line length */ + +/* constants definitions */ +/* output clock phase selection enum definition */ +typedef enum +{ + CPDM_OUTPUT_PHASE_SELECTION_0 = 0, /*!< output clock phase = input clock */ + CPDM_OUTPUT_PHASE_SELECTION_1, /*!< output clock phase = input clock + 1 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_2, /*!< output clock phase = input clock + 2 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_3, /*!< output clock phase = input clock + 3 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_4, /*!< output clock phase = input clock + 4 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_5, /*!< output clock phase = input clock + 5 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_6, /*!< output clock phase = input clock + 6 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_7, /*!< output clock phase = input clock + 7 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_8, /*!< output clock phase = input clock + 8 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_9, /*!< output clock phase = input clock + 9 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_10, /*!< output clock phase = input clock + 10 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_11, /*!< output clock phase = input clock + 11 * UNIT delay */ + CPDM_OUTPUT_PHASE_SELECTION_12, /*!< output clock phase = input clock + 12 * UNIT delay */ +}cpdm_output_phase_enum; + +#define CPDM_MAX_DELAY_STEP_COUNT ((uint32_t)0x0000007FU) /*!< max UNIT value */ +#define CPDM_MAX_PHASE ((uint32_t)0x0000000CU) /*!< max select value of the phase */ + +/* function declarations */ +/* deinitialization and initialization functions */ +/* enable CPDM */ +void cpdm_enable(uint32_t cpdm_periph); +/* disable CPDM */ +void cpdm_disable(uint32_t cpdm_periph); +/* enable CPDM delay line sample module */ +void cpdm_delayline_sample_enable(uint32_t cpdm_periph); +/* disable CPDM delay line sample module */ +void cpdm_delayline_sample_disable(uint32_t cpdm_periph); + +/* output clock configuration functions */ +/* select CPDM output clock phase */ +void cpdm_output_clock_phase_select(uint32_t cpdm_periph, cpdm_output_phase_enum output_clock_phase); +/* get delay line length valid flag */ +FlagStatus cpdm_delayline_length_valid_flag_get(uint32_t cpdm_periph); +/* get delay line length */ +uint16_t cpdm_delayline_length_get(uint32_t cpdm_periph); + +/* clock output function */ +/* configure CPDM clock output */ +void cpdm_clock_output(uint32_t cpdm_periph, cpdm_output_phase_enum output_clock_phase); + +#endif /* GD32H7XX_CPDM_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_crc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_crc.h new file mode 100644 index 0000000000..40cf163b07 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_crc.h @@ -0,0 +1,122 @@ +/*! + \file gd32h7xx_crc.h + \brief definitions for the CRC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_CRC_H +#define GD32H7XX_CRC_H + +#include "gd32h7xx.h" + +/* CRC definitions */ +#define CRC CRC_BASE /*!< CRC bsae address */ + +/* registers definitions */ +#define CRC_DATA REG32((CRC) + 0x00000000U) /*!< CRC data register */ +#define CRC_FDATA REG32((CRC) + 0x00000004U) /*!< CRC free data register */ +#define CRC_CTL REG32((CRC) + 0x00000008U) /*!< CRC control register */ +#define CRC_IDATA REG32((CRC) + 0x00000010U) /*!< CRC initialization data register */ +#define CRC_POLY REG32((CRC) + 0x00000014U) /*!< CRC polynomial register */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0,31) /*!< CRC data bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0,7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset bit */ +#define CRC_CTL_PS BITS(3,4) /*!< size of polynomial function bits */ +#define CRC_CTL_REV_I BITS(5,6) /*!< input data reverse function bits */ +#define CRC_CTL_REV_O BIT(7) /*!< output data reverse function bit */ + +/* CRC_INIT */ +#define CRC_IDATA_IDATA BITS(0,31) /*!< CRC initialization data bits */ + +/* CRC_POLY */ +#define CRC_POLY_POLY BITS(0,31) /*!< CRC polynomial value bits */ + +/* constants definitions */ +/* size of polynomial function */ +#define CTL_PS(regval) (BITS(3,4) & ((regval) << 3U)) +#define CRC_CTL_PS_32 CTL_PS(0) /*!< 32-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_16 CTL_PS(1) /*!< 16-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_8 CTL_PS(2) /*!< 8-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_7 CTL_PS(3) /*!< 7-bit polynomial for CRC calculation */ + +/* input data reverse function */ +#define CTL_REV_I(regval) (BITS(5,6) & ((regval) << 5U)) +#define CRC_INPUT_DATA_NOT CTL_REV_I(0) /*!< input data not reverse */ +#define CRC_INPUT_DATA_BYTE CTL_REV_I(1) /*!< input data reversed by byte type */ +#define CRC_INPUT_DATA_HALFWORD CTL_REV_I(2) /*!< input data reversed by half-word type */ +#define CRC_INPUT_DATA_WORD CTL_REV_I(3) /*!< input data reversed by word type */ + +/* input data format */ +#define INPUT_FORMAT_WORD 0U /*!< input data in word format */ +#define INPUT_FORMAT_HALFWORD 1U /*!< input data in half-word format */ +#define INPUT_FORMAT_BYTE 2U /*!< input data in byte format */ + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); +/* enable the reverse operation of output data */ +void crc_reverse_output_data_enable(void); +/* disable the reverse operation of output data */ +void crc_reverse_output_data_disable(void); + +/* reset data register to the value of initialization data register */ +void crc_data_register_reset(void); +/* read the data register */ +uint32_t crc_data_register_read(void); + +/* read the free data register */ +uint8_t crc_free_data_register_read(void); +/* write the free data register */ +void crc_free_data_register_write(uint8_t free_data); + +/* write the initial value register */ +void crc_init_data_register_write(uint32_t init_data); +/* configure the CRC input data function */ +void crc_input_data_reverse_config(uint32_t data_reverse); + +/* configure the CRC size of polynomial function */ +void crc_polynomial_size_set(uint32_t poly_size); +/* configure the CRC polynomial value function */ +void crc_polynomial_set(uint32_t poly); + +/* CRC calculate single data */ +uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format); +/* CRC calculate a data array */ +uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format); + +#endif /* GD32H7XX_CRC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ctc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ctc.h new file mode 100644 index 0000000000..b9e0240516 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ctc.h @@ -0,0 +1,184 @@ +/*! + \file gd32h7xx_ctc.h + \brief definitions for the CTC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_CTC_H +#define GD32H7XX_CTC_H + +#include "gd32h7xx.h" + +/* CTC definitions */ +#define CTC CTC_BASE + +/* registers definitions */ +#define CTC_CTL0 REG32((CTC) + 0x00U) /*!< CTC control register 0 */ +#define CTC_CTL1 REG32((CTC) + 0x04U) /*!< CTC control register 1 */ +#define CTC_STAT REG32((CTC) + 0x08U) /*!< CTC status register */ +#define CTC_INTC REG32((CTC) + 0x0CU) /*!< CTC interrupt clear register */ + +/* bits definitions */ +/* CTC_CTL0 */ +#define CTC_CTL0_CKOKIE BIT(0) /*!< clock trim OK(CKOKIF) interrupt enable */ +#define CTC_CTL0_CKWARNIE BIT(1) /*!< clock trim warning(CKWARNIF) interrupt enable */ +#define CTC_CTL0_ERRIE BIT(2) /*!< error(ERRIF) interrupt enable */ +#define CTC_CTL0_EREFIE BIT(3) /*!< EREFIF interrupt enable */ +#define CTC_CTL0_CNTEN BIT(5) /*!< CTC counter enable */ +#define CTC_CTL0_AUTOTRIM BIT(6) /*!< hardware automatically trim mode */ +#define CTC_CTL0_SWREFPUL BIT(7) /*!< software reference source sync pulse */ +#define CTC_CTL0_TRIMVALUE BITS(8,13) /*!< IRC48M trim value */ + +/* CTC_CTL1 */ +#define CTC_CTL1_RLVALUE BITS(0,15) /*!< CTC counter reload value */ +#define CTC_CTL1_CKLIM BITS(16,23) /*!< clock trim base limit value */ +#define CTC_CTL1_REFPSC BITS(24,26) /*!< reference signal source prescaler */ +#define CTC_CTL1_REFSEL BITS(28,29) /*!< reference signal source selection */ +#define CTC_CTL1_REFPOL BIT(31) /*!< reference signal source polarity */ + +/* CTC_STAT */ +#define CTC_STAT_CKOKIF BIT(0) /*!< clock trim OK interrupt flag */ +#define CTC_STAT_CKWARNIF BIT(1) /*!< clock trim warning interrupt flag */ +#define CTC_STAT_ERRIF BIT(2) /*!< error interrupt flag */ +#define CTC_STAT_EREFIF BIT(3) /*!< expect reference interrupt flag */ +#define CTC_STAT_CKERR BIT(8) /*!< clock trim error bit */ +#define CTC_STAT_REFMISS BIT(9) /*!< reference sync pulse miss */ +#define CTC_STAT_TRIMERR BIT(10) /*!< trim value error bit */ +#define CTC_STAT_REFDIR BIT(15) /*!< CTC trim counter direction when reference sync pulse occurred */ +#define CTC_STAT_REFCAP BITS(16,31) /*!< CTC counter capture when reference sync pulse occurred */ + +/* CTC_INTC */ +#define CTC_INTC_CKOKIC BIT(0) /*!< CKOKIF interrupt clear bit */ +#define CTC_INTC_CKWARNIC BIT(1) /*!< CKWARNIF interrupt clear bit */ +#define CTC_INTC_ERRIC BIT(2) /*!< ERRIF interrupt clear bit */ +#define CTC_INTC_EREFIC BIT(3) /*!< EREFIF interrupt clear bit */ + +/* constants definitions */ +/* hardware automatically trim mode definitions */ +#define CTC_HARDWARE_TRIM_MODE_ENABLE CTC_CTL0_AUTOTRIM /*!< hardware automatically trim mode enable*/ +#define CTC_HARDWARE_TRIM_MODE_DISABLE ((uint32_t)0x00000000U) /*!< hardware automatically trim mode disable*/ + +/* reference signal source polarity definitions */ +#define CTC_REFSOURCE_POLARITY_FALLING CTC_CTL1_REFPOL /*!< reference signal source polarity is falling edge*/ +#define CTC_REFSOURCE_POLARITY_RISING ((uint32_t)0x00000000U) /*!< reference signal source polarity is rising edge*/ + +/* reference signal source selection definitions */ +#define CTL1_REFSEL(regval) (BITS(28,29) & ((uint32_t)(regval) << 28)) +#define CTC_REFSOURCE_GPIO CTL1_REFSEL(0) /*!< GPIO is selected */ +#define CTC_REFSOURCE_LXTAL CTL1_REFSEL(1) /*!< LXTAL is selected */ + +/* reference signal source prescaler definitions */ +#define CTL1_REFPSC(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define CTC_REFSOURCE_PSC_OFF CTL1_REFPSC(0) /*!< reference signal not divided */ +#define CTC_REFSOURCE_PSC_DIV2 CTL1_REFPSC(1) /*!< reference signal divided by 2 */ +#define CTC_REFSOURCE_PSC_DIV4 CTL1_REFPSC(2) /*!< reference signal divided by 4 */ +#define CTC_REFSOURCE_PSC_DIV8 CTL1_REFPSC(3) /*!< reference signal divided by 8 */ +#define CTC_REFSOURCE_PSC_DIV16 CTL1_REFPSC(4) /*!< reference signal divided by 16 */ +#define CTC_REFSOURCE_PSC_DIV32 CTL1_REFPSC(5) /*!< reference signal divided by 32 */ +#define CTC_REFSOURCE_PSC_DIV64 CTL1_REFPSC(6) /*!< reference signal divided by 64 */ +#define CTC_REFSOURCE_PSC_DIV128 CTL1_REFPSC(7) /*!< reference signal divided by 128 */ + +/* CTC interrupt enable definitions */ +#define CTC_INT_CKOK CTC_CTL0_CKOKIE /*!< clock trim OK interrupt enable */ +#define CTC_INT_CKWARN CTC_CTL0_CKWARNIE /*!< clock trim warning interrupt enable */ +#define CTC_INT_ERR CTC_CTL0_ERRIE /*!< error interrupt enable */ +#define CTC_INT_EREF CTC_CTL0_EREFIE /*!< expect reference interrupt enable */ + +/* CTC interrupt source definitions */ +#define CTC_INT_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK interrupt flag */ +#define CTC_INT_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning interrupt flag */ +#define CTC_INT_FLAG_ERR CTC_STAT_ERRIF /*!< error interrupt flag */ +#define CTC_INT_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference interrupt flag */ +#define CTC_INT_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */ +#define CTC_INT_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */ +#define CTC_INT_FLAG_TRIMERR CTC_STAT_TRIMERR /*!< trim value error */ + +/* CTC flag definitions */ +#define CTC_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK flag */ +#define CTC_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning flag */ +#define CTC_FLAG_ERR CTC_STAT_ERRIF /*!< error flag */ +#define CTC_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference flag */ +#define CTC_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */ +#define CTC_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */ +#define CTC_FLAG_TRIMERR CTC_STAT_TRIMERR /*!< trim value error bit */ + +/* function declarations */ +/* reset ctc clock trim controller */ +void ctc_deinit(void); + +/* enable CTC trim counter */ +void ctc_counter_enable(void); +/* disable CTC trim counter */ +void ctc_counter_disable(void); + +/* configure the IRC48M trim value */ +void ctc_irc48m_trim_value_config(uint8_t trim_value); +/* generate software reference source sync pulse */ +void ctc_software_refsource_pulse_generate(void); +/* configure hardware automatically trim mode */ +void ctc_hardware_trim_mode_config(uint32_t hardmode); + +/* configure reference signal source polarity */ +void ctc_refsource_polarity_config(uint32_t polarity); +/* select reference signal source */ +void ctc_refsource_signal_select(uint32_t refs); +/* configure reference signal source prescaler */ +void ctc_refsource_prescaler_config(uint32_t prescaler); +/* configure clock trim base limit value */ +void ctc_clock_limit_value_config(uint8_t limit_value); +/* configure CTC counter reload value */ +void ctc_counter_reload_value_config(uint16_t reload_value); + +/* read CTC counter capture value when reference sync pulse occurred */ +uint16_t ctc_counter_capture_value_read(void); +/* read CTC trim counter direction when reference sync pulse occurred */ +FlagStatus ctc_counter_direction_read(void); +/* read CTC counter reload value */ +uint16_t ctc_counter_reload_value_read(void); +/* read the IRC48M trim value */ +uint8_t ctc_irc48m_trim_value_read(void); + +/* interrupt & flag functions */ +/* get CTC flag */ +FlagStatus ctc_flag_get(uint32_t flag); +/* clear CTC flag */ +void ctc_flag_clear(uint32_t flag); +/* enable the CTC interrupt */ +void ctc_interrupt_enable(uint32_t interrupt); +/* disable the CTC interrupt */ +void ctc_interrupt_disable(uint32_t interrupt); +/* get CTC interrupt flag */ +FlagStatus ctc_interrupt_flag_get(uint32_t int_flag); +/* clear CTC interrupt flag */ +void ctc_interrupt_flag_clear(uint32_t int_flag); + + +#endif /* GD32H7XX_CTC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dac.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dac.h new file mode 100644 index 0000000000..b47f2a8c60 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dac.h @@ -0,0 +1,321 @@ +/*! + \file gd32h7xx_dac.h + \brief definitions for the DAC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_DAC_H +#define GD32H7XX_DAC_H + +#include "gd32h7xx.h" + +/* DACx(x=0) definitions */ +#define DAC0 (DAC_BASE) + +/* registers definitions */ +#define DAC_CTL0(dacx) REG32((dacx) + 0x00000000U) /*!< DACx control register 0 */ +#define DAC_SWT(dacx) REG32((dacx) + 0x00000004U) /*!< DACx software trigger register */ +#define DAC_OUT0_R12DH(dacx) REG32((dacx) + 0x00000008U) /*!< DACx_OUT0 12-bit right-aligned data holding register */ +#define DAC_OUT0_L12DH(dacx) REG32((dacx) + 0x0000000CU) /*!< DACx_OUT0 12-bit left-aligned data holding register */ +#define DAC_OUT0_R8DH(dacx) REG32((dacx) + 0x00000010U) /*!< DACx_OUT0 8-bit right-aligned data holding register */ +#define DAC_OUT1_R12DH(dacx) REG32((dacx) + 0x00000014U) /*!< DACx_OUT1 12-bit right-aligned data holding register */ +#define DAC_OUT1_L12DH(dacx) REG32((dacx) + 0x00000018U) /*!< DACx_OUT1 12-bit left-aligned data holding register */ +#define DAC_OUT1_R8DH(dacx) REG32((dacx) + 0x0000001CU) /*!< DACx_OUT1 8-bit right-aligned data holding register */ +#define DACC_R12DH(dacx) REG32((dacx) + 0x00000020U) /*!< DACx concurrent mode 12-bit right-aligned data holding register */ +#define DACC_L12DH(dacx) REG32((dacx) + 0x00000024U) /*!< DACx concurrent mode 12-bit left-aligned data holding register */ +#define DACC_R8DH(dacx) REG32((dacx) + 0x00000028U) /*!< DACx concurrent mode 8-bit right-aligned data holding register */ +#define DAC_OUT0_DO(dacx) REG32((dacx) + 0x0000002CU) /*!< DACx_OUT0 data output register */ +#define DAC_OUT1_DO(dacx) REG32((dacx) + 0x00000030U) /*!< DACx_OUT1 data output register */ +#define DAC_STAT0(dacx) REG32((dacx) + 0x00000034U) /*!< DACx status register 0 */ +#define DAC_CALR(dacx) REG32((dacx) + 0x00000038U) /*!< DACx calibration register */ +#define DAC_MDCR(dacx) REG32((dacx) + 0x0000003CU) /*!< DACx mode control register */ +#define DAC_SKSTR0(dacx) REG32((dacx) + 0x00000040U) /*!< DACx sample and keep sample time register 0 */ +#define DAC_SKSTR1(dacx) REG32((dacx) + 0x00000044U) /*!< DACx sample and keep sample time register 1 */ +#define DAC_SKKTR(dacx) REG32((dacx) + 0x00000048U) /*!< DACx sample and keep keep time register */ +#define DAC_SKRTR(dacx) REG32((dacx) + 0x0000004CU) /*!< DACx sample and keep refresh time register */ + +/* bits definitions */ +/* DAC_CTL0 */ +#define DAC_CTL0_DEN0 BIT(0) /*!< DACx_OUT0 enable */ +#define DAC_CTL0_DTEN0 BIT(1) /*!< DACx_OUT0 trigger enable */ +#define DAC_CTL0_DTSEL0 BITS(2,3) /*!< DACx_OUT0 trigger selection */ +#define DAC_CTL0_DWM0 BITS(6,7) /*!< DACx_OUT0 noise wave mode */ +#define DAC_CTL0_DWBW0 BITS(8,11) /*!< DACx_OUT0 noise wave bit width */ +#define DAC_CTL0_DDMAEN0 BIT(12) /*!< DACx_OUT0 DMA enable */ +#define DAC_CTL0_DDUDRIE0 BIT(13) /*!< DACx_OUT0 DMA underrun interrupt enable */ +#define DAC_CTL0_CALEN0 BIT(14) /*!< DACx_OUT0 calibration enable */ +#define DAC_CTL0_DEN1 BIT(16) /*!< DACx_OUT1 enable bit */ +#define DAC_CTL0_DTEN1 BIT(17) /*!< DACx_OUT1 trigger enable */ +#define DAC_CTL0_DTSEL1 BITS(18,19) /*!< DACx_OUT1 trigger selection */ +#define DAC_CTL0_DWM1 BITS(22,23) /*!< DACx_OUT1 noise wave mode */ +#define DAC_CTL0_DWBW1 BITS(24,27) /*!< DACx_OUT1 noise wave bit width */ +#define DAC_CTL0_DDMAEN1 BIT(28) /*!< DACx_OUT1 DMA enable */ +#define DAC_CTL0_DDUDRIE1 BIT(29) /*!< DACx_OUT1 DMA underrun interrupt enable */ +#define DAC_CTL0_CALEN1 BIT(30) /*!< DACx_OUT1 calibration enable */ + +/* DAC_SWT */ +#define DAC_SWT_SWTR0 BIT(0) /*!< DACx_OUT0 software trigger */ +#define DAC_SWT_SWTR1 BIT(1) /*!< DACx_OUT1 software trigger */ + +/* DAC0_R12DH */ +#define DAC_OUT0_DH_R12 BITS(0,11) /*!< DACx_OUT0 12-bit right-aligned data */ + +/* DAC0_L12DH */ +#define DAC_OUT0_DH_L12 BITS(4,15) /*!< DACx_OUT0 12-bit left-aligned data */ + +/* DAC0_R8DH */ +#define DAC_OUT0_DH_R8DH BITS(0,7) /*!< DACx_OUT0 8-bit right-aligned data */ + +/* DAC1_R12DH */ +#define DAC_OUT1_DH_R12 BITS(0,11) /*!< DACx_OUT1 12-bit right-aligned data */ + +/* DAC1_L12DH */ +#define DAC_OUT1_DH_L12 BITS(4,15) /*!< DACx_OUT1 12-bit left-aligned data */ + +/* DAC1_R8DH */ +#define DAC_OUT1_DH_R8 BITS(0,7) /*!< DACx_OUT1 8-bit right-aligned data */ + +/* DACC_R12DH */ +#define DACC_OUT0_DH_R12 BITS(0,11) /*!< DAC concurrent mode DACx_OUT0 12-bit right-aligned data */ +#define DACC_OUT1_DH_R12 BITS(16,27) /*!< DAC concurrent mode DACx_OUT1 12-bit right-aligned data */ + +/* DACC_L12DH */ +#define DACC_OUT0_DH_L12 BITS(4,15) /*!< DAC concurrent mode DACx_OUT0 12-bit left-aligned data */ +#define DACC_OUT1_DH_L12 BITS(20,31) /*!< DAC concurrent mode DACx_OUT1 12-bit left-aligned data */ + +/* DACC_R8DH */ +#define DACC_OUT0_DH_R8 BITS(0,7) /*!< DAC concurrent mode DACx_OUT0 8-bit right-aligned data */ +#define DACC_OUT1_DH_R8 BITS(8,15) /*!< DAC concurrent mode DACx_OUT1 8-bit right-aligned data */ + +/* DAC0_DO */ +#define DAC_OUT0_DO_BITS BITS(0,11) /*!< DACx_OUT0 12-bit output data */ + +/* DAC1_DO */ +#define DAC_OUT1_DO_BITS BITS(0,11) /*!< DACx_OUT1 12-bit output data */ + +/* DAC_STAT0 */ +#define DAC_STAT0_DDUDR0 BIT(13) /*!< DACx_OUT0 DMA underrun flag */ +#define DAC_STAT0_CALF0 BIT(14) /*!< DACx_OUT0 calibration offset flag */ +#define DAC_STAT0_BWT0 BIT(15) /*!< DACx_OUT0 SKSTR0 writing flag */ +#define DAC_STAT0_DDUDR1 BIT(29) /*!< DACx_OUT1 DMA underrun flag */ +#define DAC_STAT0_CALF1 BIT(30) /*!< DACx_OUT1 calibration offset flag */ +#define DAC_STAT0_BWT1 BIT(31) /*!< DACx_OUT1 SKSTR1 writing flag */ + +/* DAC_CALR */ +#define DAC_CALR_OTV0 BITS(0,4) /*!< DACx_OUT0 offset calibration value */ +#define DAC_CALR_OTV1 BITS(16,20) /*!< DACx_OUT1 offset calibration value */ + +/* DAC_MDCR */ +#define DAC_MDCR_MODE0 BITS(0,2) /*!< DACx_OUT0 mode */ +#define DAC_MDCR_MODE1 BITS(16,18) /*!< DACx_OUT1 mode */ + +/* DAC_SKSTR0 */ +#define DAC_SKSTR0_TSAMP0 BITS(0,9) /*!< DACx_OUT0 sample time */ + +/* DAC_SKSTR1 */ +#define DAC_SKSTR1_TSAMP1 BITS(0,9) /*!< DACx_OUT1 sample time */ + +/* DAC_SKKTR */ +#define DAC_SKKTR_TKEEP0 BITS(0,9) /*!< DACx_OUT0 keep time */ +#define DAC_SKKTR_TKEEP1 BITS(16,25) /*!< DACx_OUT1 keep time */ + +/* DAC_SKRTR */ +#define DAC_SKRTR_TREF0 BITS(0,7) /*!< DACx_OUT0 refresh time */ +#define DAC_SKRTR_TREF1 BITS(16,23) /*!< DACx_OUT1 refresh time */ + +/* constants definitions */ +/* DAC trigger source */ +#define CTL0_DTSEL(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) +#define DAC_TRIGGER_EXTERNAL CTL0_DTSEL(0) /*!< external trigger selected from TRIGSEL */ +#define DAC_TRIGGER_SOFTWARE CTL0_DTSEL(1) /*!< software trigger */ + +/* DAC noise wave mode */ +#define CTL_DWM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) +#define DAC_WAVE_DISABLE CTL_DWM(0) /*!< wave disabled */ +#define DAC_WAVE_MODE_LFSR CTL_DWM(1) /*!< LFSR noise mode */ +#define DAC_WAVE_MODE_TRIANGLE CTL_DWM(2) /*!< triangle noise mode */ + +/* DAC noise wave bit width */ +#define DWBW(regval) (BITS(8, 11) & ((uint32_t)(regval) << 8)) +#define DAC_WAVE_BIT_WIDTH_1 DWBW(0) /*!< bit width of the wave signal is 1 */ +#define DAC_WAVE_BIT_WIDTH_2 DWBW(1) /*!< bit width of the wave signal is 2 */ +#define DAC_WAVE_BIT_WIDTH_3 DWBW(2) /*!< bit width of the wave signal is 3 */ +#define DAC_WAVE_BIT_WIDTH_4 DWBW(3) /*!< bit width of the wave signal is 4 */ +#define DAC_WAVE_BIT_WIDTH_5 DWBW(4) /*!< bit width of the wave signal is 5 */ +#define DAC_WAVE_BIT_WIDTH_6 DWBW(5) /*!< bit width of the wave signal is 6 */ +#define DAC_WAVE_BIT_WIDTH_7 DWBW(6) /*!< bit width of the wave signal is 7 */ +#define DAC_WAVE_BIT_WIDTH_8 DWBW(7) /*!< bit width of the wave signal is 8 */ +#define DAC_WAVE_BIT_WIDTH_9 DWBW(8) /*!< bit width of the wave signal is 9 */ +#define DAC_WAVE_BIT_WIDTH_10 DWBW(9) /*!< bit width of the wave signal is 10 */ +#define DAC_WAVE_BIT_WIDTH_11 DWBW(10) /*!< bit width of the wave signal is 11 */ +#define DAC_WAVE_BIT_WIDTH_12 DWBW(11) /*!< bit width of the wave signal is 12 */ + +/* unmask LFSR bits in DAC LFSR noise mode */ +#define DAC_LFSR_BIT0 DAC_WAVE_BIT_WIDTH_1 /*!< unmask the LFSR bit0 */ +#define DAC_LFSR_BITS1_0 DAC_WAVE_BIT_WIDTH_2 /*!< unmask the LFSR bits[1:0] */ +#define DAC_LFSR_BITS2_0 DAC_WAVE_BIT_WIDTH_3 /*!< unmask the LFSR bits[2:0] */ +#define DAC_LFSR_BITS3_0 DAC_WAVE_BIT_WIDTH_4 /*!< unmask the LFSR bits[3:0] */ +#define DAC_LFSR_BITS4_0 DAC_WAVE_BIT_WIDTH_5 /*!< unmask the LFSR bits[4:0] */ +#define DAC_LFSR_BITS5_0 DAC_WAVE_BIT_WIDTH_6 /*!< unmask the LFSR bits[5:0] */ +#define DAC_LFSR_BITS6_0 DAC_WAVE_BIT_WIDTH_7 /*!< unmask the LFSR bits[6:0] */ +#define DAC_LFSR_BITS7_0 DAC_WAVE_BIT_WIDTH_8 /*!< unmask the LFSR bits[7:0] */ +#define DAC_LFSR_BITS8_0 DAC_WAVE_BIT_WIDTH_9 /*!< unmask the LFSR bits[8:0] */ +#define DAC_LFSR_BITS9_0 DAC_WAVE_BIT_WIDTH_10 /*!< unmask the LFSR bits[9:0] */ +#define DAC_LFSR_BITS10_0 DAC_WAVE_BIT_WIDTH_11 /*!< unmask the LFSR bits[10:0] */ +#define DAC_LFSR_BITS11_0 DAC_WAVE_BIT_WIDTH_12 /*!< unmask the LFSR bits[11:0] */ + +/* triangle amplitude in DAC triangle noise mode */ +#define DAC_TRIANGLE_AMPLITUDE_1 DAC_WAVE_BIT_WIDTH_1 /*!< triangle amplitude is 1 */ +#define DAC_TRIANGLE_AMPLITUDE_3 DAC_WAVE_BIT_WIDTH_2 /*!< triangle amplitude is 3 */ +#define DAC_TRIANGLE_AMPLITUDE_7 DAC_WAVE_BIT_WIDTH_3 /*!< triangle amplitude is 7 */ +#define DAC_TRIANGLE_AMPLITUDE_15 DAC_WAVE_BIT_WIDTH_4 /*!< triangle amplitude is 15 */ +#define DAC_TRIANGLE_AMPLITUDE_31 DAC_WAVE_BIT_WIDTH_5 /*!< triangle amplitude is 31 */ +#define DAC_TRIANGLE_AMPLITUDE_63 DAC_WAVE_BIT_WIDTH_6 /*!< triangle amplitude is 63 */ +#define DAC_TRIANGLE_AMPLITUDE_127 DAC_WAVE_BIT_WIDTH_7 /*!< triangle amplitude is 127 */ +#define DAC_TRIANGLE_AMPLITUDE_255 DAC_WAVE_BIT_WIDTH_8 /*!< triangle amplitude is 255 */ +#define DAC_TRIANGLE_AMPLITUDE_511 DAC_WAVE_BIT_WIDTH_9 /*!< triangle amplitude is 511 */ +#define DAC_TRIANGLE_AMPLITUDE_1023 DAC_WAVE_BIT_WIDTH_10 /*!< triangle amplitude is 1023 */ +#define DAC_TRIANGLE_AMPLITUDE_2047 DAC_WAVE_BIT_WIDTH_11 /*!< triangle amplitude is 2047 */ +#define DAC_TRIANGLE_AMPLITUDE_4095 DAC_WAVE_BIT_WIDTH_12 /*!< triangle amplitude is 4095 */ + +/* DAC data alignment */ +#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< 12-bit right-aligned data */ +#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< 12-bit left-aligned data */ +#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< 8-bit right-aligned data */ + +/* DAC mode */ +#define MODE(regval) (BITS(0,2) & ((uint32_t)(regval))) +#define NORMAL_PIN_BUFFON MODE(0) /*!< DACx_OUTy work in normal mode and connect to external pin with buffer enable */ +#define NORMAL_PIN_PERIPH_BUFFON MODE(1) /*!< DACx_OUTy work in normal mode and connect to external pin and on chip peripherals with buffer enable */ +#define NORMAL_PIN_BUFFOFF MODE(2) /*!< DACx_OUTy work in normal mode and connect to external pin with buffer disable */ +#define NORMAL_PIN_PERIPH_BUFFOFF MODE(3) /*!< DACx_OUTy work in normal mode and connect to on chip peripherals with buffer disable */ +#define SAMPLEKEEP_PIN_BUFFON MODE(4) /*!< DACx_OUTy work in sample and keep mode and connect to external pin with buffer enable */ +#define SAMPLEKEEP_PIN_PERIPH_BUFFON MODE(5) /*!< DACx_OUTy work in sample and keep mode and connect to external pin and on chip peripherals with buffer enable */ +#define SAMPLEKEEP_PIN_BUFFOFF MODE(6) /*!< DACx_OUTy work in sample and keep mode and connect to external pin and on chip peripherals with buffer disable */ +#define SAMPLEKEEP_PIN_PERIPH_BUFFOFF MODE(7) /*!< DACx_OUTy work in sample and keep mode and connect to on chip peripherals with buffer disable */ + +/* DAC output channel definitions */ +#define DAC_OUT0 ((uint8_t)0x00U) /*!< DACx_OUT0 channel */ +#define DAC_OUT1 ((uint8_t)0x01U) /*!< DACx_OUT1 channel */ + +/* DAC interrupt */ +#define DAC_INT_DDUDR0 DAC_CTL0_DDUDRIE0 /*!< DACx_OUT0 DMA underrun interrupt enable */ +#define DAC_INT_DDUDR1 DAC_CTL0_DDUDRIE1 /*!< DACx_OUT1 DMA underrun interrupt enable */ + +/* DAC interrupt flag */ +#define DAC_INT_FLAG_DDUDR0 DAC_STAT0_DDUDR0 /*!< DACx_OUT0 DMA underrun interrupt flag */ +#define DAC_INT_FLAG_DDUDR1 DAC_STAT0_DDUDR1 /*!< DACx_OUT1 DMA underrun interrupt flag */ + +/* DAC flags */ +#define DAC_FLAG_DDUDR0 DAC_STAT0_DDUDR0 /*!< DACx_OUT0 DMA underrun flag */ +#define DAC_FLAG_CALF0 DAC_STAT0_CALF0 /*!< DACx_OUT0 calibration offset flag */ +#define DAC_FLAG_BWT0 DAC_STAT0_BWT0 /*!< DACx_OUT0 sample and keep wtire enable flag */ +#define DAC_FLAG_DDUDR1 DAC_STAT0_DDUDR1 /*!< DACx_OUT1 DMA underrun flag */ +#define DAC_FLAG_CALF1 DAC_STAT0_CALF1 /*!< DACx_OUT1 calibration offset flag */ +#define DAC_FLAG_BWT1 DAC_STAT0_BWT1 /*!< DACx_OUT1 sample and keep wtire enable flag */ + +/* function declarations */ +/* DAC initialization functions */ +/* deinitialize DAC */ +void dac_deinit(uint32_t dac_periph); +/* enable DAC */ +void dac_enable(uint32_t dac_periph, uint8_t dac_out); +/* disable DAC */ +void dac_disable(uint32_t dac_periph, uint8_t dac_out); +/* enable DAC DMA function */ +void dac_dma_enable(uint32_t dac_periph, uint8_t dac_out); +/* disable DAC DMA function */ +void dac_dma_disable(uint32_t dac_periph, uint8_t dac_out); + +/* DAC buffer functions */ +/* configure DAC mode */ +void dac_mode_config(uint32_t dac_periph, uint32_t dac_out, uint32_t mode); +/* get the DACx trimming value */ +uint32_t dac_trimming_value_get(uint32_t dac_periph, uint32_t dac_out); +/* set the DACx trimming value */ +void dac_trimming_value_set(uint32_t dac_periph, uint32_t dac_out, uint32_t trim_value); +/* enable the DACx trimming */ +void dac_trimming_enable(uint32_t dac_periph, uint32_t dac_out); + +/* read and write operation functions */ +/* get DAC output value */ +uint16_t dac_output_value_get(uint32_t dac_periph, uint8_t dac_out); +/* set DAC data holding register value */ +void dac_data_set(uint32_t dac_periph, uint8_t dac_out, uint32_t dac_align, uint16_t data); + +/* DAC trigger configuration */ +/* enable DAC trigger */ +void dac_trigger_enable(uint32_t dac_periph, uint8_t dac_out); +/* disable DAC trigger */ +void dac_trigger_disable(uint32_t dac_periph, uint8_t dac_out); +/* configure DAC trigger source */ +void dac_trigger_source_config(uint32_t dac_periph, uint8_t dac_out, uint32_t triggersource); +/* enable DAC software trigger */ +void dac_software_trigger_enable(uint32_t dac_periph, uint8_t dac_out); + +/* DAC wave mode configuration */ +/* configure DAC wave mode */ +void dac_wave_mode_config(uint32_t dac_periph, uint8_t dac_out, uint32_t wave_mode); +/* configure DAC LFSR noise mode */ +void dac_lfsr_noise_config(uint32_t dac_periph, uint8_t dac_out, uint32_t unmask_bits); +/* configure DAC triangle noise mode */ +void dac_triangle_noise_config(uint32_t dac_periph, uint8_t dac_out, uint32_t amplitude); + +/* DAC concurrent mode configuration */ +/* enable DAC concurrent mode */ +void dac_concurrent_enable(uint32_t dac_periph); +/* disable DAC concurrent mode */ +void dac_concurrent_disable(uint32_t dac_periph); +/* enable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_enable(uint32_t dac_periph); +/* set DAC concurrent mode data holding register value */ +void dac_concurrent_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data0, uint16_t data1); + +/* DAC sample and keep functions */ +/* DAC sample and keep mode config */ +void dac_sample_keep_mode_config(uint32_t dac_periph, uint32_t dac_out, uint32_t sample_time, uint32_t keep_time, uint32_t refresh_time); + +/* DAC interrupt and flag functions */ +/* get DAC flag */ +FlagStatus dac_flag_get(uint32_t dac_periph, uint32_t flag); +/* clear DAC flag */ +void dac_flag_clear(uint32_t dac_periph, uint32_t flag); +/* enable DAC interrupt */ +void dac_interrupt_enable(uint32_t dac_periph, uint32_t interrupt); +/* disable DAC interrupt */ +void dac_interrupt_disable(uint32_t dac_periph, uint32_t interrupt); +/* get DAC interrupt flag */ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph, uint32_t int_flag); +/* clear DAC interrupt flag */ +void dac_interrupt_flag_clear(uint32_t dac_periph, uint32_t int_flag); + +#endif /* GD32H7XX_DAC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dbg.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dbg.h new file mode 100644 index 0000000000..655b9a13ba --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dbg.h @@ -0,0 +1,187 @@ +/*! + \file gd32h7xx_dbg.h + \brief definitions for the DBG + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_DBG_H +#define GD32H7XX_DBG_H + +#include "gd32h7xx.h" + +/* DBG definitions */ +#define DBG DBG_BASE /*!< DBG base address */ + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00000000U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x00000004U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x00000034U) /*!< DBG control register 1 */ +#define DBG_CTL2 REG32(DBG + 0x0000003CU) /*!< DBG control register 2 */ +#define DBG_CTL3 REG32(DBG + 0x0000004CU) /*!< DBG control register 3 */ +#define DBG_CTL4 REG32(DBG + 0x00000054U) /*!< DBG control register 4 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL0 */ +#define DBG_CTL0_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL0_TRACE_MODE BITS(18,19) /*!< trace pin mode selection */ +#define DBG_CTL0_TRACECLKEN BIT(20) /*!< enable trace pin assignment */ + +/* DBG_CTL1 */ +#define DBG_CTL1_WWDGT_HOLD BIT(6) /*!< debug WWDGT kept when core is halted */ + +/* DBG_CTL2 */ +#define DBG_CTL2_TIMER1_HOLD BIT(0) /*!< debug TIMER1 kept when core is halted */ +#define DBG_CTL2_TIMER2_HOLD BIT(1) /*!< debug TIMER2 kept when core is halted */ +#define DBG_CTL2_TIMER3_HOLD BIT(2) /*!< debug TIMER3 kept when core is halted */ +#define DBG_CTL2_TIMER4_HOLD BIT(3) /*!< debug TIMER4 kept when core is halted */ +#define DBG_CTL2_TIMER5_HOLD BIT(4) /*!< debug TIMER5 kept when core is halted */ +#define DBG_CTL2_TIMER6_HOLD BIT(5) /*!< debug TIMER6 kept when core is halted */ +#define DBG_CTL2_TIMER22_HOLD BIT(6) /*!< debug TIMER22 kept when core is halted */ +#define DBG_CTL2_TIMER23_HOLD BIT(7) /*!< debug TIMER23 kept when core is halted */ +#define DBG_CTL2_TIMER30_HOLD BIT(8) /*!< debug TIMER30 kept when core is halted */ +#define DBG_CTL2_TIMER31_HOLD BIT(9) /*!< debug TIMER31 kept when core is halted */ +#define DBG_CTL2_TIMER50_HOLD BIT(10) /*!< debug TIMER50 kept when core is halted */ +#define DBG_CTL2_TIMER51_HOLD BIT(11) /*!< debug TIMER51 kept when core is halted */ +#define DBG_CTL2_I2C0_HOLD BIT(21) /*!< debug I2C0 kept when core is halted */ +#define DBG_CTL2_I2C1_HOLD BIT(22) /*!< debug I2C1 kept when core is halted */ +#define DBG_CTL2_I2C2_HOLD BIT(23) /*!< debug I2C2 kept when core is halted */ +#define DBG_CTL2_I2C3_HOLD BIT(24) /*!< debug I2C3 kept when core is halted */ + +/* DBG_CTL3 */ +#define DBG_CTL3_TIMER0_HOLD BIT(0) /*!< debug TIMER0 kept when core is halted */ +#define DBG_CTL3_TIMER7_HOLD BIT(1) /*!< debug TIMER7 kept when core is halted */ +#define DBG_CTL3_CAN0_HOLD BIT(2) /*!< debug CAN0 kept when core is halted */ +#define DBG_CTL3_CAN1_HOLD BIT(3) /*!< debug CAN1 kept when core is halted */ +#define DBG_CTL3_CAN2_HOLD BIT(4) /*!< debug CAN2 kept when core is halted */ +#define DBG_CTL3_TIMER14_HOLD BIT(16) /*!< debug TIMER14 kept when core is halted */ +#define DBG_CTL3_TIMER15_HOLD BIT(17) /*!< debug TIMER15 kept when core is halted */ +#define DBG_CTL3_TIMER16_HOLD BIT(18) /*!< debug TIMER16 kept when core is halted */ +#define DBG_CTL3_TIMER40_HOLD BIT(19) /*!< debug TIMER40 kept when core is halted */ +#define DBG_CTL3_TIMER41_HOLD BIT(20) /*!< debug TIMER41 kept when core is halted */ +#define DBG_CTL3_TIMER42_HOLD BIT(21) /*!< debug TIMER42 kept when core is halted */ +#define DBG_CTL3_TIMER43_HOLD BIT(22) /*!< debug TIMER43 kept when core is halted */ +#define DBG_CTL3_TIMER44_HOLD BIT(23) /*!< debug TIMER44 kept when core is halted */ + +/* DBG_CTL4 */ +#define DBG_CTL4_RTC_HOLD BIT(16) /*!< debug RTC kept when core is halted */ +#define DBG_CTL4_FWDGT_HOLD BIT(18) /*!< debug FWDGT kept when core is halted */ + +/* constants definitions */ +#define DBG_LOW_POWER_SLEEP DBG_CTL0_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL0_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL0_STB_HOLD /*!< keep debugger connection during standby mode */ + +/* define the peripheral debug hold bit position and its register index offset */ +#define DBG_REGIDX_BIT(regidx, bitpos) (((regidx) << 6) | (bitpos)) +#define DBG_REG_VAL(periph) (REG32(DBG + ((uint32_t)(periph) >> 6))) +#define DBG_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) + +/* register index */ +typedef enum +{ + DBG_IDX_CTL1 = 0x34U, /*!< DBG control register 1 offset */ + DBG_IDX_CTL2 = 0x3CU, /*!< DBG control register 2 offset */ + DBG_IDX_CTL3 = 0x4CU, /*!< DBG control register 3 offset */ + DBG_IDX_CTL4 = 0x54U /*!< DBG control register 4 offset */ +}dbg_reg_idx; + +/* peripherals hold bit */ +typedef enum +{ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 6U), /*!< debug WWDGT kept when core is halted */ + DBG_I2C3_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 24U), /*!< debug I2C3 kept when core is halted */ + DBG_I2C2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 23U), /*!< debug I2C2 kept when core is halted */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 22U), /*!< debug I2C1 kept when core is halted */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 21U), /*!< debug I2C0 kept when core is halted */ + DBG_TIMER51_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 11U), /*!< debug TIMER51 kept when core is halted */ + DBG_TIMER50_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 10U), /*!< debug TIMER50 kept when core is halted */ + DBG_TIMER31_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 9U), /*!< debug TIMER31 kept when core is halted */ + DBG_TIMER30_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 8U), /*!< debug TIMER30 kept when core is halted */ + DBG_TIMER23_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 7U), /*!< debug TIMER23 kept when core is halted */ + DBG_TIMER22_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 6U), /*!< debug TIMER22 kept when core is halted */ + DBG_TIMER6_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 5U), /*!< debug TIMER6 kept when core is halted */ + DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 4U), /*!< debug TIMER5 kept when core is halted */ + DBG_TIMER4_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 3U), /*!< debug TIMER4 kept when core is halted */ + DBG_TIMER3_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 2U), /*!< debug TIMER3 kept when core is halted */ + DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 1U), /*!< debug TIMER2 kept when core is halted */ + DBG_TIMER1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 0U), /*!< debug TIMER1 kept when core is halted */ + DBG_TIMER44_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 23U), /*!< debug TIMER44 kept when core is halted */ + DBG_TIMER43_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 22U), /*!< debug TIMER43 kept when core is halted */ + DBG_TIMER42_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 21U), /*!< debug TIMER42 kept when core is halted */ + DBG_TIMER41_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 20U), /*!< debug TIMER41 kept when core is halted */ + DBG_TIMER40_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 19U), /*!< debug TIMER40 kept when core is halted */ + DBG_TIMER16_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 18U), /*!< debug TIMER16 kept when core is halted */ + DBG_TIMER15_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 17U), /*!< debug TIMER15 kept when core is halted */ + DBG_TIMER14_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 16U), /*!< debug TIMER14 kept when core is halted */ + DBG_CAN2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 4U), /*!< debug CAN2 kept when core is halted */ + DBG_CAN1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 3U), /*!< debug CAN1 kept when core is halted */ + DBG_CAN0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 2U), /*!< debug CAN0 kept when core is halted */ + DBG_TIMER7_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 1U), /*!< debug TIMER7 kept when core is halted */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL3, 0U), /*!< debug TIMER0 kept when core is halted */ + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL4, 18U), /*!< debug FWDGT kept when core is halted */ + DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL4, 16U) /*!< debug RTC kept when core is halted */ +}dbg_periph_enum; + +#define CTL0_TRACE_MODE(regval) (BITS(18,19) & ((uint32_t)(regval) << 18U)) +#define TRACE_MODE_ASYNC CTL0_TRACE_MODE(0) /*!< trace pin used for async mode */ +#define TRACE_MODE_SYNC_DATASIZE_1 CTL0_TRACE_MODE(1) /*!< trace pin used for sync mode and data size is 1 */ +#define TRACE_MODE_SYNC_DATASIZE_2 CTL0_TRACE_MODE(2) /*!< trace pin used for sync mode and data size is 2 */ +#define TRACE_MODE_SYNC_DATASIZE_4 CTL0_TRACE_MODE(3) /*!< trace pin used for sync mode and data size is 4 */ + +/* function declarations */ +/* deinitialize the DBG */ +void dbg_deinit(void); +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/*enable low power behavior when the mcu is in debug mode*/ +void dbg_low_power_enable(uint32_t dbg_low_power); +/*disable low power behavior when the mcu is in debug mode*/ +void dbg_low_power_disable(uint32_t dbg_low_power); + +/*enable trace pin assignment*/ +void dbg_trace_pin_enable(void); +/*disable trace pin assignment*/ +void dbg_trace_pin_disable(void); +/* set trace pin mode */ +void dbg_trace_pin_mode_set(uint32_t trace_mode); + +/* enable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_enable(dbg_periph_enum dbg_periph); +/* disable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_disable(dbg_periph_enum dbg_periph); + +#endif /* GD32H7XX_DBG_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dci.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dci.h new file mode 100644 index 0000000000..8e485912e0 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dci.h @@ -0,0 +1,276 @@ +/*! + \file gd32h7xx_dci.h + \brief definitions for the DCI + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_DCI_H +#define GD32H7XX_DCI_H + +#include "gd32h7xx.h" + +/* DCI definitions */ +#define DCI DCI_BASE + +/* registers definitions */ +#define DCI_CTL REG32(DCI + 0x00000000U) /*!< DCI control register */ +#define DCI_STAT0 REG32(DCI + 0x00000004U) /*!< DCI status register 0 */ +#define DCI_STAT1 REG32(DCI + 0x00000008U) /*!< DCI status register 1 */ +#define DCI_INTEN REG32(DCI + 0x0000000CU) /*!< DCI interrupt enable register */ +#define DCI_INTF REG32(DCI + 0x00000010U) /*!< DCI interrupt flag register */ +#define DCI_INTC REG32(DCI + 0x00000014U) /*!< DCI interrupt clear register */ +#define DCI_SC REG32(DCI + 0x00000018U) /*!< DCI synchronization codes register */ +#define DCI_SCUMSK REG32(DCI + 0x0000001CU) /*!< DCI synchronization codes unmask register */ +#define DCI_CWSPOS REG32(DCI + 0x00000020U) /*!< DCI cropping window start position register */ +#define DCI_CWSZ REG32(DCI + 0x00000024U) /*!< DCI cropping window size register */ +#define DCI_DATA REG32(DCI + 0x00000028U) /*!< DCI data register */ + +/* bits definitions */ +/* DCI_CTL */ +#define DCI_CTL_CAP BIT(0) /*!< capture enable */ +#define DCI_CTL_SNAP BIT(1) /*!< snapshot mode */ +#define DCI_CTL_WDEN BIT(2) /*!< window enable */ +#define DCI_CTL_JM BIT(3) /*!< JPEG mode */ +#define DCI_CTL_ESM BIT(4) /*!< embedded synchronous mode */ +#define DCI_CTL_CKS BIT(5) /*!< clock polarity selection */ +#define DCI_CTL_HPS BIT(6) /*!< horizontal polarity selection */ +#define DCI_CTL_VPS BIT(7) /*!< vertical polarity selection */ +#define DCI_CTL_FR BITS(8,9) /*!< frame rate */ +#define DCI_CTL_DCIF BITS(10,11) /*!< digital camera interface format */ +#define DCI_CTL_CCEN BIT(12) /*!< CCIR enable */ +#define DCI_CTL_CCMOD BIT(13) /*!< CCIR mode select */ +#define DCI_CTL_DCIEN BIT(14) /*!< DCI enable */ +#define DCI_CTL_AECEN BIT(15) /*!< automatic error correction enable, 1bit correction */ +#define DCI_CTL_EVSEN BIT(16) /*!< external vsync enable */ + +/* DCI_STAT0 */ +#define DCI_STAT0_HS BIT(0) /*!< HS line status */ +#define DCI_STAT0_VS BIT(1) /*!< VS line status */ +#define DCI_STAT0_FV BIT(2) /*!< FIFO valid */ + +/* DCI_STAT1 */ +#define DCI_STAT1_EFF BIT(0) /*!< end of frame flag */ +#define DCI_STAT1_OVRF BIT(1) /*!< FIFO overrun flag */ +#define DCI_STAT1_ESEF BIT(2) /*!< embedded synchronous error flag */ +#define DCI_STAT1_VSF BIT(3) /*!< vsync flag */ +#define DCI_STAT1_ELF BIT(4) /*!< end of line flag */ +#define DCI_STAT1_F0F BIT(5) /*!< CCIR field 0 */ +#define DCI_STAT1_F1F BIT(6) /*!< CCIR field 1 */ +#define DCI_STAT1_COFF BIT(7) /*!< CCIR change of field flag */ +#define DCI_STAT1_CCEF BIT(8) /*!< CCIR error flag */ + +/* DCI_INTEN */ +#define DCI_INTEN_EFIE BIT(0) /*!< end of frame interrupt enable */ +#define DCI_INTEN_OVRIE BIT(1) /*!< FIFO overrun interrupt enable */ +#define DCI_INTEN_ESEIE BIT(2) /*!< embedded synchronous error interrupt enable */ +#define DCI_INTEN_VSIE BIT(3) /*!< vsync interrupt enable */ +#define DCI_INTEN_ELIE BIT(4) /*!< end of line interrupt enable */ +#define DCI_INTEN_F0IE BIT(5) /*!< CCIR field 0 interrupt enable */ +#define DCI_INTEN_F1IE BIT(6) /*!< CCIR field 1 interrupt enable */ +#define DCI_INTEN_COFIE BIT(7) /*!< CCIR change of field interrupt enable */ +#define DCI_INTEN_CCEIE BIT(8) /*!< CCIR error interrupt enable */ + +/* DCI_INTF */ +#define DCI_INTF_EFIF BIT(0) /*!< end of frame interrupt flag */ +#define DCI_INTF_OVRIF BIT(1) /*!< FIFO overrun interrupt flag */ +#define DCI_INTF_ESEIF BIT(2) /*!< embedded synchronous error interrupt flag */ +#define DCI_INTF_VSIF BIT(3) /*!< vsync interrupt flag */ +#define DCI_INTF_ELIF BIT(4) /*!< end of line interrupt flag */ +#define DCI_INTF_F0IF BIT(5) /*!< CCIR field 0 interrupt flag */ +#define DCI_INTF_F1IF BIT(6) /*!< CCIR field 1 interrupt flag */ +#define DCI_INTF_COFIF BIT(7) /*!< CCIR change of field interrupt flag */ +#define DCI_INTF_CCEIF BIT(8) /*!< CCIR error interrupt flag */ + +/* DCI_INTC */ +#define DCI_INTC_EFFC BIT(0) /*!< clear end of frame flag */ +#define DCI_INTC_OVRFC BIT(1) /*!< clear FIFO overrun flag */ +#define DCI_INTC_ESEFC BIT(2) /*!< clear embedded synchronous error flag */ +#define DCI_INTC_VSFC BIT(3) /*!< vsync flag clear */ +#define DCI_INTC_ELFC BIT(4) /*!< end of line flag clear */ +#define DCI_INTC_F0FC BIT(5) /*!< CCIR field 0 interrupt flag clear */ +#define DCI_INTC_F1FC BIT(6) /*!< CCIR field 1 interrupt flag clear */ +#define DCI_INTC_COFFC BIT(7) /*!< CCIR change of field flag clear */ +#define DCI_INTC_CCEFC BIT(8) /*!< CCIR error flag clear */ + +/* DCI_SC */ +#define DCI_SC_FS BITS(0,7) /*!< frame start code in embedded synchronous mode */ +#define DCI_SC_LS BITS(8,15) /*!< line start code in embedded synchronous mode */ +#define DCI_SC_LE BITS(16,23) /*!< line end code in embedded synchronous mode */ +#define DCI_SC_FE BITS(24,31) /*!< frame end code in embedded synchronous mode */ + +/* DCI_SCUNMSK */ +#define DCI_SCUMSK_FSM BITS(0,7) /*!< frame start code unmask bits in embedded synchronous mode */ +#define DCI_SCUMSK_LSM BITS(8,15) /*!< line start code unmask bits in embedded synchronous mode */ +#define DCI_SCUMSK_LEM BITS(16,23) /*!< line end code unmask bits in embedded synchronous mode */ +#define DCI_SCUMSK_FEM BITS(24,31) /*!< frame end code unmask bits in embedded synchronous mode */ + +/* DCI_CWSPOS */ +#define DCI_CWSPOS_WHSP BITS(0,13) /*!< window horizontal start position */ +#define DCI_CWSPOS_WVSP BITS(16,28) /*!< window vertical start position */ + +/* DCI_CWSZ */ +#define DCI_CWSZ_WHSZ BITS(0,13) /*!< window horizontal size */ +#define DCI_CWSZ_WVSZ BITS(16,29) /*!< window vertical size */ + +/* constants definitions */ +/* DCI parameter structure definitions */ +typedef struct { + uint32_t capture_mode; /*!< DCI capture mode: continuous or snapshot */ + uint32_t clock_polarity; /*!< clock polarity selection */ + uint32_t hsync_polarity; /*!< horizontal polarity selection */ + uint32_t vsync_polarity; /*!< vertical polarity selection */ + uint32_t frame_rate; /*!< frame capture rate */ + uint32_t interface_format; /*!< digital camera interface format */ +} dci_parameter_struct; + + +#define CCIR_PROGRESSIVE_MODE ((uint32_t)0x00000000U) /*!< CCIR progressive mode */ +#define CCIR_INTERLACE_MODE DCI_CTL_CCMOD /*!< CCIR interlace mode */ + +#define DCI_CAPTURE_MODE_CONTINUOUS ((uint32_t)0x00000000U) /*!< continuous capture mode */ +#define DCI_CAPTURE_MODE_SNAPSHOT DCI_CTL_SNAP /*!< snapshot capture mode */ + +#define DCI_CK_POLARITY_FALLING ((uint32_t)0x00000000U) /*!< capture at falling edge */ +#define DCI_CK_POLARITY_RISING DCI_CTL_CKS /*!< capture at rising edge */ + +#define DCI_HSYNC_POLARITY_LOW ((uint32_t)0x00000000U) /*!< low level during blanking period */ +#define DCI_HSYNC_POLARITY_HIGH DCI_CTL_HPS /*!< high level during blanking period */ + +#define DCI_VSYNC_POLARITY_LOW ((uint32_t)0x00000000U) /*!< low level during blanking period */ +#define DCI_VSYNC_POLARITY_HIGH DCI_CTL_VPS /*!< high level during blanking period*/ + +#define CTL_FR(regval) (BITS(8,9)&((uint32_t)(regval) << 8)) +#define DCI_FRAME_RATE_ALL CTL_FR(0) /*!< capture all frames */ +#define DCI_FRAME_RATE_1_2 CTL_FR(1) /*!< capture one in 2 frames */ +#define DCI_FRAME_RATE_1_4 CTL_FR(2) /*!< capture one in 4 frames */ + +#define CTL_DCIF(regval) (BITS(10,11)&((uint32_t)(regval) << 10)) +#define DCI_INTERFACE_FORMAT_8BITS CTL_DCIF(0) /*!< 8-bit data on every pixel clock */ +#define DCI_INTERFACE_FORMAT_10BITS CTL_DCIF(1) /*!< 10-bit data on every pixel clock */ +#define DCI_INTERFACE_FORMAT_12BITS CTL_DCIF(2) /*!< 12-bit data on every pixel clock */ +#define DCI_INTERFACE_FORMAT_14BITS CTL_DCIF(3) /*!< 14-bit data on every pixel clock */ + +/* DCI interrupt constants definitions */ +#define DCI_INT_EF BIT(0) /*!< end of frame interrupt */ +#define DCI_INT_OVR BIT(1) /*!< FIFO overrun interrupt */ +#define DCI_INT_ESE BIT(2) /*!< embedded synchronous error interrupt */ +#define DCI_INT_VSYNC BIT(3) /*!< vsync interrupt */ +#define DCI_INT_EL BIT(4) /*!< end of line interrupt */ +#define DCI_INT_F0 BIT(5) /*!< CCIR field 0 interrupt */ +#define DCI_INT_F1 BIT(6) /*!< CCIR field 1 interrupt */ +#define DCI_INT_COF BIT(7) /*!< CCIR change of field interrupt */ +#define DCI_INT_CCE BIT(8) /*!< CCIR error interrupt */ + +/* DCI interrupt flag definitions */ +#define DCI_INT_FLAG_EF BIT(0) /*!< end of frame interrupt flag */ +#define DCI_INT_FLAG_OVR BIT(1) /*!< FIFO overrun interrupt flag */ +#define DCI_INT_FLAG_ESE BIT(2) /*!< embedded synchronous error interrupt flag */ +#define DCI_INT_FLAG_VSYNC BIT(3) /*!< vsync interrupt flag */ +#define DCI_INT_FLAG_EL BIT(4) /*!< end of line interrupt flag */ +#define DCI_INT_FLAG_F0 BIT(5) /*!< CCIR field 0 interrupt flag */ +#define DCI_INT_FLAG_F1 BIT(6) /*!< CCIR field 1 interrupt flag */ +#define DCI_INT_FLAG_COF BIT(7) /*!< CCIR change of field interrupt flag */ +#define DCI_INT_FLAG_CCE BIT(8) /*!< CCIR error interrupt flag */ + +/* DCI flag definitions */ +#define DCI_FLAG_HS DCI_STAT0_HS /*!< HS line status */ +#define DCI_FLAG_VS DCI_STAT0_VS /*!< VS line status */ +#define DCI_FLAG_FV DCI_STAT0_FV /*!< FIFO valid */ +#define DCI_FLAG_EF (DCI_STAT1_EFF | BIT(31)) /*!< end of frame flag */ +#define DCI_FLAG_OVR (DCI_STAT1_OVRF | BIT(31)) /*!< FIFO overrun flag */ +#define DCI_FLAG_ESE (DCI_STAT1_ESEF | BIT(31)) /*!< embedded synchronous error flag */ +#define DCI_FLAG_VSYNC (DCI_STAT1_VSF | BIT(31)) /*!< vsync flag */ +#define DCI_FLAG_EL (DCI_STAT1_ELF | BIT(31)) /*!< end of line flag */ + +/* function declarations */ +/* initialization functions */ +/* DCI deinit */ +void dci_deinit(void); +/* initialize DCI registers */ +void dci_init(dci_parameter_struct *dci_struct); +/* enable DCI function */ +void dci_enable(void); +/* disable DCI function */ +void dci_disable(void); +/* enable DCI capture */ +void dci_capture_enable(void); +/* disable DCI capture */ +void dci_capture_disable(void); +/* enable DCI external vsync in CCIR progressive mode */ +void dci_external_vsync_enable(void); +/* disable DCI external vsync in CCIR progressive mode */ +void dci_external_vsync_disable(void); +/* enable DCI automatic error correction in CCIR interlaced mode */ +void dci_automatic_error_correction_enable(void); +/* disable DCI automatic error correction in CCIR interlaced mode */ +void dci_automatic_error_correction_disable(void); +/* enable DCI jpeg mode */ +void dci_jpeg_enable(void); +/* disable DCI jpeg mode */ +void dci_jpeg_disable(void); + +/* function configuration */ +/* enable cropping window function */ +void dci_crop_window_enable(void); +/* disable cropping window function */ +void dci_crop_window_disable(void); +/* CCIR enable */ +void dci_ccir_enable(void); +/* CCIR disable */ +void dci_ccir_disable(void); +/* CCIR mode select */ +void dci_ccir_mode_select(uint32_t ccir_mode); +/* configure DCI cropping window */ +void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height); +/* enable embedded synchronous mode */ +void dci_embedded_sync_enable(void); +/* disable embedded synchronous mode */ +void dci_embedded_sync_disable(void); +/* configure synchronous codes in embedded synchronous mode */ +void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end); +/* configure synchronous codes unmask in embedded synchronous mode */ +void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end); +/* read DCI data register */ +uint32_t dci_data_read(void); + +/* interrupt & flag functions */ +/* get specified flag */ +FlagStatus dci_flag_get(uint32_t flag); +/* enable specified DCI interrupt */ +void dci_interrupt_enable(uint32_t interrupt); +/* disable specified DCI interrupt */ +void dci_interrupt_disable(uint32_t interrupt); +/* get specified interrupt flag */ +FlagStatus dci_interrupt_flag_get(uint32_t int_flag); +/* clear specified interrupt flag */ +void dci_interrupt_flag_clear(uint32_t int_flag); + +#endif /* GD32H7XX_DCI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dma.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dma.h new file mode 100644 index 0000000000..ab7cff055f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_dma.h @@ -0,0 +1,1015 @@ +/*! + \file gd32h7xx_dma.h + \brief definitions for the DMA + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_DMA_H +#define GD32H7XX_DMA_H + +#include "gd32h7xx.h" + +/* DMA definitions */ +#define DMA0 (DMA_BASE) /*!< DMA0 base address */ +#define DMA1 (DMA_BASE + 0x00000400U) /*!< DMA1 base address */ + +/* DMAMUX definitions */ +#define DMAMUX DMAMUX_BASE /*!< DMA base address */ + +/* DMA registers definitions */ +#define DMA_INTF0(dmax) REG32((dmax) + 0x00000000U) /*!< DMA interrupt flag register 0 */ +#define DMA_INTF1(dmax) REG32((dmax) + 0x00000004U) /*!< DMA interrupt flag register 1 */ +#define DMA_INTC0(dmax) REG32((dmax) + 0x00000008U) /*!< DMA interrupt flag clear register 0 */ +#define DMA_INTC1(dmax) REG32((dmax) + 0x0000000CU) /*!< DMA interrupt flag clear register 1 */ +#define DMA_CH0CTL(dmax) REG32((dmax) + 0x00000010U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT(dmax) REG32((dmax) + 0x00000014U) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x00000018U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0M0ADDR(dmax) REG32((dmax) + 0x0000001CU) /*!< DMA channel 0 memory 0 base address register */ +#define DMA_CH0M1ADDR(dmax) REG32((dmax) + 0x00000020U) /*!< DMA channel 0 memory 1 base address register */ +#define DMA_CH0FCTL(dmax) REG32((dmax) + 0x00000024U) /*!< DMA channel 0 FIFO control register */ +#define DMA_CH1CTL(dmax) REG32((dmax) + 0x00000028U) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT(dmax) REG32((dmax) + 0x0000002CU) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x00000030U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1M0ADDR(dmax) REG32((dmax) + 0x00000034U) /*!< DMA channel 1 memory 0 base address register */ +#define DMA_CH1M1ADDR(dmax) REG32((dmax) + 0x00000038U) /*!< DMA channel 1 memory 1 base address register */ +#define DMA_CH1FCTL(dmax) REG32((dmax) + 0x0000003CU) /*!< DMA channel 1 FIFO control register */ +#define DMA_CH2CTL(dmax) REG32((dmax) + 0x00000040U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT(dmax) REG32((dmax) + 0x00000044U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x00000048U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2M0ADDR(dmax) REG32((dmax) + 0x0000004CU) /*!< DMA channel 2 memory 0 base address register */ +#define DMA_CH2M1ADDR(dmax) REG32((dmax) + 0x00000050U) /*!< DMA channel 2 memory 1 base address register */ +#define DMA_CH2FCTL(dmax) REG32((dmax) + 0x00000054U) /*!< DMA channel 2 FIFO control register */ +#define DMA_CH3CTL(dmax) REG32((dmax) + 0x00000058U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT(dmax) REG32((dmax) + 0x0000005CU) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x00000060U) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3M0ADDR(dmax) REG32((dmax) + 0x00000064U) /*!< DMA channel 3 memory 0 base address register */ +#define DMA_CH3M1ADDR(dmax) REG32((dmax) + 0x00000068U) /*!< DMA channel 3 memory 1 base address register */ +#define DMA_CH3FCTL(dmax) REG32((dmax) + 0x0000006CU) /*!< DMA channel 3 FIFO control register */ +#define DMA_CH4CTL(dmax) REG32((dmax) + 0x00000070U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT(dmax) REG32((dmax) + 0x00000074U) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x00000078U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4M0ADDR(dmax) REG32((dmax) + 0x0000007CU) /*!< DMA channel 4 memory 0 base address register */ +#define DMA_CH4M1ADDR(dmax) REG32((dmax) + 0x00000080U) /*!< DMA channel 4 memory 1 base address register */ +#define DMA_CH4FCTL(dmax) REG32((dmax) + 0x00000084U) /*!< DMA channel 4 FIFO control register */ +#define DMA_CH5CTL(dmax) REG32((dmax) + 0x00000088U) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT(dmax) REG32((dmax) + 0x0000008CU) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x00000090U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5M0ADDR(dmax) REG32((dmax) + 0x00000094U) /*!< DMA channel 5 memory 0 base address register */ +#define DMA_CH5M1ADDR(dmax) REG32((dmax) + 0x00000098U) /*!< DMA channel 5 memory 1 base address register */ +#define DMA_CH5FCTL(dmax) REG32((dmax) + 0x0000009CU) /*!< DMA channel 5 FIFO control register */ +#define DMA_CH6CTL(dmax) REG32((dmax) + 0x000000A0U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT(dmax) REG32((dmax) + 0x000000A4U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR(dmax) REG32((dmax) + 0x000000A8U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6M0ADDR(dmax) REG32((dmax) + 0x000000ACU) /*!< DMA channel 6 memory 0 base address register */ +#define DMA_CH6M1ADDR(dmax) REG32((dmax) + 0x000000B0U) /*!< DMA channel 6 memory 1 base address register */ +#define DMA_CH6FCTL(dmax) REG32((dmax) + 0x000000B4U) /*!< DMA channel 6 FIFO control register */ +#define DMA_CH7CTL(dmax) REG32((dmax) + 0x000000B8U) /*!< DMA channel 7 control register */ +#define DMA_CH7CNT(dmax) REG32((dmax) + 0x000000BCU) /*!< DMA channel 7 counter register */ +#define DMA_CH7PADDR(dmax) REG32((dmax) + 0x000000C0U) /*!< DMA channel 7 peripheral base address register */ +#define DMA_CH7M0ADDR(dmax) REG32((dmax) + 0x000000C4U) /*!< DMA channel 7 memory 0 base address register */ +#define DMA_CH7M1ADDR(dmax) REG32((dmax) + 0x000000C8U) /*!< DMA channel 7 memory 1 base address register */ +#define DMA_CH7FCTL(dmax) REG32((dmax) + 0x000000CCU) /*!< DMA channel 7 FIFO control register */ + +/* DMAMUX registers definitions */ +#define DMAMUX_RM_CH0CFG REG32(DMAMUX + 0x00000000U) /*!< DMAMUX request multiplexer channel 0 configuration register */ +#define DMAMUX_RM_CH1CFG REG32(DMAMUX + 0x00000004U) /*!< DMAMUX request multiplexer channel 1 configuration register */ +#define DMAMUX_RM_CH2CFG REG32(DMAMUX + 0x00000008U) /*!< DMAMUX request multiplexer channel 2 configuration register */ +#define DMAMUX_RM_CH3CFG REG32(DMAMUX + 0x0000000CU) /*!< DMAMUX request multiplexer channel 3 configuration register */ +#define DMAMUX_RM_CH4CFG REG32(DMAMUX + 0x00000010U) /*!< DMAMUX request multiplexer channel 4 configuration register */ +#define DMAMUX_RM_CH5CFG REG32(DMAMUX + 0x00000014U) /*!< DMAMUX request multiplexer channel 5 configuration register */ +#define DMAMUX_RM_CH6CFG REG32(DMAMUX + 0x00000018U) /*!< DMAMUX request multiplexer channel 6 configuration register */ +#define DMAMUX_RM_CH7CFG REG32(DMAMUX + 0x0000001CU) /*!< DMAMUX request multiplexer channel 7 configuration register */ +#define DMAMUX_RM_CH8CFG REG32(DMAMUX + 0x00000020U) /*!< DMAMUX request multiplexer channel 8 configuration register */ +#define DMAMUX_RM_CH9CFG REG32(DMAMUX + 0x00000024U) /*!< DMAMUX request multiplexer channel 9 configuration register */ +#define DMAMUX_RM_CH10CFG REG32(DMAMUX + 0x00000028U) /*!< DMAMUX request multiplexer channel 10 configuration register */ +#define DMAMUX_RM_CH11CFG REG32(DMAMUX + 0x0000002CU) /*!< DMAMUX request multiplexer channel 11 configuration register */ +#define DMAMUX_RM_CH12CFG REG32(DMAMUX + 0x00000030U) /*!< DMAMUX request multiplexer channel 12 configuration register */ +#define DMAMUX_RM_CH13CFG REG32(DMAMUX + 0x00000034U) /*!< DMAMUX request multiplexer channel 13 configuration register */ +#define DMAMUX_RM_CH14CFG REG32(DMAMUX + 0x00000038U) /*!< DMAMUX request multiplexer channel 14 configuration register */ +#define DMAMUX_RM_CH15CFG REG32(DMAMUX + 0x0000003CU) /*!< DMAMUX request multiplexer channel 15 configuration register */ +#define DMAMUX_RM_INTF REG32(DMAMUX + 0x00000080U) /*!< DMAMUX request multiplexer channel interrupt flag register */ +#define DMAMUX_RM_INTC REG32(DMAMUX + 0x00000084U) /*!< DMAMUX request multiplexer channel interrupt flag clear register */ +#define DMAMUX_RG_CH0CFG REG32(DMAMUX + 0x00000100U) /*!< DMAMUX generator channel 0 configuration register */ +#define DMAMUX_RG_CH1CFG REG32(DMAMUX + 0x00000104U) /*!< DMAMUX generator channel 1 configuration register */ +#define DMAMUX_RG_CH2CFG REG32(DMAMUX + 0x00000108U) /*!< DMAMUX generator channel 2 configuration register */ +#define DMAMUX_RG_CH3CFG REG32(DMAMUX + 0x0000010CU) /*!< DMAMUX generator channel 3 configuration register */ +#define DMAMUX_RG_CH4CFG REG32(DMAMUX + 0x00000110U) /*!< DMAMUX generator channel 4 configuration register */ +#define DMAMUX_RG_CH5CFG REG32(DMAMUX + 0x00000114U) /*!< DMAMUX generator channel 5 configuration register */ +#define DMAMUX_RG_CH6CFG REG32(DMAMUX + 0x00000118U) /*!< DMAMUX generator channel 6 configuration register */ +#define DMAMUX_RG_CH7CFG REG32(DMAMUX + 0x0000011CU) /*!< DMAMUX generator channel 7 configuration register */ +#define DMAMUX_RG_INTF REG32(DMAMUX + 0x00000140U) /*!< DMAMUX generator channel interrupt flag register */ +#define DMAMUX_RG_INTC REG32(DMAMUX + 0x00000144U) /*!< DMAMUX rgenerator channel interrupt flag clear register */ + +/* bits definitions */ +/* DMA_INTF */ +#define DMA_INTF_FEEIF BIT(0) /*!< FIFO error and exception flag */ +#define DMA_INTF_SDEIF BIT(2) /*!< single data mode exception flag */ +#define DMA_INTF_TAEIF BIT(3) /*!< transfer access error flag */ +#define DMA_INTF_HTFIF BIT(4) /*!< half transfer finish flag */ +#define DMA_INTF_FTFIF BIT(5) /*!< full transger finish flag */ + +/* DMA_INTC */ +#define DMA_INTC_FEEIFC BIT(0) /*!< clear FIFO error and exception flag */ +#define DMA_INTC_SDEIFC BIT(2) /*!< clear single data mode exception flag */ +#define DMA_INTC_TAEIFC BIT(3) /*!< clear single data mode exception flag */ +#define DMA_INTC_HTFIFC BIT(4) /*!< clear half transfer finish flag */ +#define DMA_INTC_FTFIFC BIT(5) /*!< clear full transger finish flag */ + +/* DMA_CHxCTL,x=0..7 */ +#define DMA_CHXCTL_CHEN BIT(0) /*!< channel x enable */ +#define DMA_CHXCTL_SDEIE BIT(1) /*!< enable bit for channel x single data mode exception interrupt */ +#define DMA_CHXCTL_TAEIE BIT(2) /*!< enable bit for channel x tranfer access error interrupt */ +#define DMA_CHXCTL_HTFIE BIT(3) /*!< enable bit for channel x half transfer finish interrupt */ +#define DMA_CHXCTL_FTFIE BIT(4) /*!< enable bit for channel x full transfer finish interrupt */ +#define DMA_CHXCTL_TM BITS(6,7) /*!< transfer mode */ +#define DMA_CHXCTL_CMEN BIT(8) /*!< circulation mode */ +#define DMA_CHXCTL_PNAGA BIT(9) /*!< next address generation algorithm of peripheral */ +#define DMA_CHXCTL_MNAGA BIT(10) /*!< next address generation algorithm of memory */ +#define DMA_CHXCTL_PWIDTH BITS(11,12) /*!< transfer width of peipheral */ +#define DMA_CHXCTL_MWIDTH BITS(13,14) /*!< transfer width of memory */ +#define DMA_CHXCTL_PAIF BIT(15) /*!< peripheral address increment fixed */ +#define DMA_CHXCTL_PRIO BITS(16,17) /*!< priority level */ +#define DMA_CHXCTL_SBMEN BIT(18) /*!< switch-buffer mode enable */ +#define DMA_CHXCTL_MBS BIT(19) /*!< memory buffer select */ +#define DMA_CHXCTL_PBURST BITS(21,22) /*!< transfer burst type of peripheral */ +#define DMA_CHXCTL_MBURST BITS(23,24) /*!< transfer burst type of memory */ + +/* DMA_CHxCNT,x=0..7 */ +#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */ + +/* DMA_CHxPADDR,x=0..7 */ +#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */ + +/* DMA_CHxM0ADDR,x=0..7 */ +#define DMA_CHXM0ADDR_M0ADDR BITS(0,31) /*!< memory 0 base address */ + +/* DMA_CHxM1ADDR,x=0..7 */ +#define DMA_CHXM1ADDR_M1ADDR BITS(0,31) /*!< memory 1 base address */ + +/* DMA_CHxFCTL,x=0..7 */ +#define DMA_CHXFCTL_FCCV BITS(0,1) /*!< FIFO counter critical value */ +#define DMA_CHXFCTL_MDMEN BIT(2) /*!< multi-data mode enable */ +#define DMA_CHXFCTL_FCNT BITS(3,5) /*!< FIFO counter */ +#define DMA_CHXFCTL_FEEIE BIT(7) /*!< FIFO exception interrupt enable */ + +/* DMAMUX_RM_CHxCFG,x=0..15 */ +#define DMAMUX_RM_CHXCFG_MUXID BITS(0,7) /*!< multiplexer input identification */ +#define DMAMUX_RM_CHXCFG_SOIE BIT(8) /*!< synchronization overrun interrupt enable */ +#define DMAMUX_RM_CHXCFG_EVGEN BIT(9) /*!< event generation enable */ +#define DMAMUX_RM_CHXCFG_SYNCEN BIT(16) /*!< synchronization enable */ +#define DMAMUX_RM_CHXCFG_SYNCP BITS(17,18) /*!< synchronization input polarity */ +#define DMAMUX_RM_CHXCFG_NBR BITS(19,23) /*!< number of DMA requests to forward */ +#define DMAMUX_RM_CHXCFG_SYNCID BITS(24,28) /*!< synchronization input identification */ + +/* DMAMUX_RM_INTF */ +#define DMAMUX_RM_INTF_SOIF0 BIT(0) /*!< synchronization overrun event flag of request multiplexer channel 0 */ +#define DMAMUX_RM_INTF_SOIF1 BIT(1) /*!< synchronization overrun event flag of request multiplexer channel 1 */ +#define DMAMUX_RM_INTF_SOIF2 BIT(2) /*!< synchronization overrun event flag of request multiplexer channel 2 */ +#define DMAMUX_RM_INTF_SOIF3 BIT(3) /*!< synchronization overrun event flag of request multiplexer channel 3 */ +#define DMAMUX_RM_INTF_SOIF4 BIT(4) /*!< synchronization overrun event flag of request multiplexer channel 4 */ +#define DMAMUX_RM_INTF_SOIF5 BIT(5) /*!< synchronization overrun event flag of request multiplexer channel 5 */ +#define DMAMUX_RM_INTF_SOIF6 BIT(6) /*!< synchronization overrun event flag of request multiplexer channel 6 */ +#define DMAMUX_RM_INTF_SOIF7 BIT(7) /*!< synchronization overrun event flag of request multiplexer channel 7 */ +#define DMAMUX_RM_INTF_SOIF8 BIT(8) /*!< synchronization overrun event flag of request multiplexer channel 8 */ +#define DMAMUX_RM_INTF_SOIF9 BIT(9) /*!< synchronization overrun event flag of request multiplexer channel 9 */ +#define DMAMUX_RM_INTF_SOIF10 BIT(10) /*!< synchronization overrun event flag of request multiplexer channel 10 */ +#define DMAMUX_RM_INTF_SOIF11 BIT(11) /*!< synchronization overrun event flag of request multiplexer channel 11 */ +#define DMAMUX_RM_INTF_SOIF12 BIT(12) /*!< synchronization overrun event flag of request multiplexer channel 12 */ +#define DMAMUX_RM_INTF_SOIF13 BIT(13) /*!< synchronization overrun event flag of request multiplexer channel 13 */ +#define DMAMUX_RM_INTF_SOIF14 BIT(14) /*!< synchronization overrun event flag of request multiplexer channel 14 */ +#define DMAMUX_RM_INTF_SOIF15 BIT(15) /*!< synchronization overrun event flag of request multiplexer channel 15 */ + +/* DMAMUX_RM_INTC */ +#define DMAMUX_RM_INTC_SOIFC0 BIT(0) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 0 */ +#define DMAMUX_RM_INTC_SOIFC1 BIT(1) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 1 */ +#define DMAMUX_RM_INTC_SOIFC2 BIT(2) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 2 */ +#define DMAMUX_RM_INTC_SOIFC3 BIT(3) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 3 */ +#define DMAMUX_RM_INTC_SOIFC4 BIT(4) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 4 */ +#define DMAMUX_RM_INTC_SOIFC5 BIT(5) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 5 */ +#define DMAMUX_RM_INTC_SOIFC6 BIT(6) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 6 */ +#define DMAMUX_RM_INTC_SOIFC7 BIT(7) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 7 */ +#define DMAMUX_RM_INTC_SOIFC8 BIT(8) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 8 */ +#define DMAMUX_RM_INTC_SOIFC9 BIT(9) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 9 */ +#define DMAMUX_RM_INTC_SOIFC10 BIT(10) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 10 */ +#define DMAMUX_RM_INTC_SOIFC11 BIT(11) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 11 */ +#define DMAMUX_RM_INTC_SOIFC12 BIT(12) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 12 */ +#define DMAMUX_RM_INTC_SOIFC13 BIT(13) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 13 */ +#define DMAMUX_RM_INTC_SOIFC14 BIT(14) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 14 */ +#define DMAMUX_RM_INTC_SOIFC15 BIT(15) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 15 */ + +/* DMAMUX_RG_CHxCFG,x=0..7 */ +#define DMAMUX_RG_CHXCFG_TID BITS(0,5) /*!< trigger input identification */ +#define DMAMUX_RG_CHXCFG_TOIE BIT(8) /*!< trigger overrun interrupt enable */ +#define DMAMUX_RG_CHXCFG_RGEN BIT(16) /*!< DMA request generator channel x enable */ +#define DMAMUX_RG_CHXCFG_RGTP BITS(17,18) /*!< DMA request generator trigger polarity */ +#define DMAMUX_RG_CHXCFG_NBRG BITS(19,23) /*!< number of DMA requests to be generated */ + +/* DMAMUX_RG_INTF */ +#define DMAMUX_RG_INTF_TOIF0 BIT(0) /*!< trigger overrun event flag of request generator channel 0 */ +#define DMAMUX_RG_INTF_TOIF1 BIT(1) /*!< trigger overrun event flag of request generator channel 1 */ +#define DMAMUX_RG_INTF_TOIF2 BIT(2) /*!< trigger overrun event flag of request generator channel 2 */ +#define DMAMUX_RG_INTF_TOIF3 BIT(3) /*!< trigger overrun event flag of request generator channel 3 */ +#define DMAMUX_RG_INTF_TOIF4 BIT(4) /*!< trigger overrun event flag of request generator channel 4 */ +#define DMAMUX_RG_INTF_TOIF5 BIT(5) /*!< trigger overrun event flag of request generator channel 5 */ +#define DMAMUX_RG_INTF_TOIF6 BIT(6) /*!< trigger overrun event flag of request generator channel 6 */ +#define DMAMUX_RG_INTF_TOIF7 BIT(7) /*!< trigger overrun event flag of request generator channel 7 */ + +/* DMAMUX_RG_INTC */ +#define DMAMUX_RG_INTC_TOIFC0 BIT(0) /*!< clear bit for trigger overrun event flag of request generator channel 0 */ +#define DMAMUX_RG_INTC_TOIFC1 BIT(1) /*!< clear bit for trigger overrun event flag of request generator channel 1 */ +#define DMAMUX_RG_INTC_TOIFC2 BIT(2) /*!< clear bit for trigger overrun event flag of request generator channel 2 */ +#define DMAMUX_RG_INTC_TOIFC3 BIT(3) /*!< clear bit for trigger overrun event flag of request generator channel 3 */ +#define DMAMUX_RG_INTC_TOIFC4 BIT(4) /*!< clear bit for trigger overrun event flag of request generator channel 4 */ +#define DMAMUX_RG_INTC_TOIFC5 BIT(5) /*!< clear bit for trigger overrun event flag of request generator channel 5 */ +#define DMAMUX_RG_INTC_TOIFC6 BIT(6) /*!< clear bit for trigger overrun event flag of request generator channel 6 */ +#define DMAMUX_RG_INTC_TOIFC7 BIT(7) /*!< clear bit for trigger overrun event flag of request generator channel 7 */ + +/* constants definitions */ +/* define the DMAMUX bit position and its register index offset */ +#define DMAMUX_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6U) | (uint32_t)(bitpos)) +#define DMAMUX_REG_VAL(offset) (REG32(DMAMUX + (((uint32_t)(offset) & 0x0000FFFFU) >> 6U))) +#define DMAMUX_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define DMAMUX_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22U) | (uint32_t)((bitpos2) << 16U) \ + | (((uint32_t)(regidx) << 6U) | (uint32_t)(bitpos))) +#define DMAMUX_REG_VAL2(offset) (REG32(DMAMUX + ((uint32_t)(offset) >> 22U))) +#define DMAMUX_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16U) +#define DMAMUX_REG_VAL3(offset) (REG32(DMAMUX + (((uint32_t)(offset) & 0x0000FFFFU) >> 6U) + 0x4U)) + +/* register offset */ +#define DMAMUX_RM_CH0CFG_REG_OFFSET ((uint32_t)0x00000000U) /*!< DMAMUX_RM_CH0CFG register offset */ +#define DMAMUX_RM_CH1CFG_REG_OFFSET ((uint32_t)0x00000004U) /*!< DMAMUX_RM_CH1CFG register offset */ +#define DMAMUX_RM_CH2CFG_REG_OFFSET ((uint32_t)0x00000008U) /*!< DMAMUX_RM_CH2CFG register offset */ +#define DMAMUX_RM_CH3CFG_REG_OFFSET ((uint32_t)0x0000000CU) /*!< DMAMUX_RM_CH3CFG register offset */ +#define DMAMUX_RM_CH4CFG_REG_OFFSET ((uint32_t)0x00000010U) /*!< DMAMUX_RM_CH4CFG register offset */ +#define DMAMUX_RM_CH5CFG_REG_OFFSET ((uint32_t)0x00000014U) /*!< DMAMUX_RM_CH5CFG register offset */ +#define DMAMUX_RM_CH6CFG_REG_OFFSET ((uint32_t)0x00000018U) /*!< DMAMUX_RM_CH6CFG register offset */ +#define DMAMUX_RM_CH7CFG_REG_OFFSET ((uint32_t)0x0000001CU) /*!< DMAMUX_RM_CH7CFG register offset */ +#define DMAMUX_RM_CH8CFG_REG_OFFSET ((uint32_t)0x00000020U) /*!< DMAMUX_RM_CH8CFG register offset */ +#define DMAMUX_RM_CH9CFG_REG_OFFSET ((uint32_t)0x00000024U) /*!< DMAMUX_RM_CH9CFG register offset */ +#define DMAMUX_RM_CH10CFG_REG_OFFSET ((uint32_t)0x00000028U) /*!< DMAMUX_RM_CH10CFG register offset */ +#define DMAMUX_RM_CH11CFG_REG_OFFSET ((uint32_t)0x0000002CU) /*!< DMAMUX_RM_CH11CFG register offset */ +#define DMAMUX_RM_CH12CFG_REG_OFFSET ((uint32_t)0x00000030U) /*!< DMAMUX_RM_CH12CFG register offset */ +#define DMAMUX_RM_CH13CFG_REG_OFFSET ((uint32_t)0x00000034U) /*!< DMAMUX_RM_CH13CFG register offset */ +#define DMAMUX_RM_CH14CFG_REG_OFFSET ((uint32_t)0x00000038U) /*!< DMAMUX_RM_CH14CFG register offset */ +#define DMAMUX_RM_CH15CFG_REG_OFFSET ((uint32_t)0x0000003CU) /*!< DMAMUX_RM_CH15CFG register offset */ +#define DMAMUX_RG_CH0CFG_REG_OFFSET ((uint32_t)0x00000100U) /*!< DMAMUX_RG_CH0CFG register offset */ +#define DMAMUX_RG_CH1CFG_REG_OFFSET ((uint32_t)0x00000104U) /*!< DMAMUX_RG_CH1CFG register offset */ +#define DMAMUX_RG_CH2CFG_REG_OFFSET ((uint32_t)0x00000108U) /*!< DMAMUX_RG_CH2CFG register offset */ +#define DMAMUX_RG_CH3CFG_REG_OFFSET ((uint32_t)0x0000010CU) /*!< DMAMUX_RG_CH3CFG register offset */ +#define DMAMUX_RG_CH4CFG_REG_OFFSET ((uint32_t)0x00000110U) /*!< DMAMUX_RG_CH0CFG register offset */ +#define DMAMUX_RG_CH5CFG_REG_OFFSET ((uint32_t)0x00000114U) /*!< DMAMUX_RG_CH1CFG register offset */ +#define DMAMUX_RG_CH6CFG_REG_OFFSET ((uint32_t)0x00000118U) /*!< DMAMUX_RG_CH2CFG register offset */ +#define DMAMUX_RG_CH7CFG_REG_OFFSET ((uint32_t)0x0000011CU) /*!< DMAMUX_RG_CH3CFG register offset */ +#define DMAMUX_RM_INTF_REG_OFFSET ((uint32_t)0x00000080U) /*!< DMAMUX_RM_INTF register offset */ +#define DMAMUX_RG_INTF_REG_OFFSET ((uint32_t)0x00000140U) /*!< DMAMUX_RG_INTF register offset */ + +/* DMA multi-data mode initialize structrue */ +typedef struct { + uint32_t request; /*!< channel input identification */ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_width; /*!< transfer data size of peripheral */ + uint32_t periph_inc; /*!< peripheral increasing mode */ + uint32_t memory0_addr; /*!< memory 0 base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t memory_inc; /*!< memory increasing mode */ + uint32_t memory_burst_width; /*!< memory burst width */ + uint32_t periph_burst_width; /*!< periph burst width */ + uint32_t critical_value; /*!< FIFO critical */ + uint32_t circular_mode; /*!< DMA circular mode */ + uint32_t direction; /*!< channel data transfer direction */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ +} dma_multi_data_parameter_struct; + +/* DMA single-data mode initialize structrue */ +typedef struct { + uint32_t request; /*!< channel input identification */ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_inc; /*!< peripheral increasing mode */ + uint32_t memory0_addr; /*!< memory 0 base address */ + uint32_t memory_inc; /*!< memory increasing mode */ + uint32_t periph_memory_width; /*!< transfer data size of peripheral */ + uint32_t circular_mode; /*!< DMA circular mode */ + uint32_t direction; /*!< channel data transfer direction */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ +} dma_single_data_parameter_struct; + +/* DMAMUX request multiplexer synchronization configuration structure */ +typedef struct { + uint32_t sync_id; /*!< synchronization input identification */ + uint32_t sync_polarity; /*!< synchronization input polarity */ + uint32_t request_number; /*!< number of DMA requests to forward */ +} dmamux_sync_parameter_struct; + +/* DMAMUX request generator trigger configuration structure */ +typedef struct { + uint32_t trigger_id; /*!< trigger input identification */ + uint32_t trigger_polarity; /*!< DMAMUX request generator trigger polarity */ + uint32_t request_number; /*!< number of DMA requests to be generated */ +} dmamux_gen_parameter_struct; + +/* DMA channel select */ +typedef enum { + DMA_CH0 = 0U, /*!< DMA Channel 0 */ + DMA_CH1, /*!< DMA Channel 1 */ + DMA_CH2, /*!< DMA Channel 2 */ + DMA_CH3, /*!< DMA Channel 3 */ + DMA_CH4, /*!< DMA Channel 4 */ + DMA_CH5, /*!< DMA Channel 5 */ + DMA_CH6, /*!< DMA Channel 6 */ + DMA_CH7 /*!< DMA Channel 7 */ +} dma_channel_enum; + +/* DMAMUX request multiplexer channel */ +typedef enum { + DMAMUX_MUXCH0 = 0U, /*!< DMAMUX request multiplexer Channel0 */ + DMAMUX_MUXCH1, /*!< DMAMUX request multiplexer Channel1 */ + DMAMUX_MUXCH2, /*!< DMAMUX request multiplexer Channel2 */ + DMAMUX_MUXCH3, /*!< DMAMUX request multiplexer Channel3 */ + DMAMUX_MUXCH4, /*!< DMAMUX request multiplexer Channel4 */ + DMAMUX_MUXCH5, /*!< DMAMUX request multiplexer Channel5 */ + DMAMUX_MUXCH6, /*!< DMAMUX request multiplexer Channel6 */ + DMAMUX_MUXCH7, /*!< DMAMUX request multiplexer Channel7 */ + DMAMUX_MUXCH8, /*!< DMAMUX request multiplexer Channel8 */ + DMAMUX_MUXCH9, /*!< DMAMUX request multiplexer Channel9 */ + DMAMUX_MUXCH10, /*!< DMAMUX request multiplexer Channel10 */ + DMAMUX_MUXCH11, /*!< DMAMUX request multiplexer Channel11 */ + DMAMUX_MUXCH12, /*!< DMAMUX request multiplexer Channel12 */ + DMAMUX_MUXCH13, /*!< DMAMUX request multiplexer Channel13 */ + DMAMUX_MUXCH14, /*!< DMAMUX request multiplexer Channel14 */ + DMAMUX_MUXCH15 /*!< DMAMUX request multiplexer Channel15 */ +} dmamux_multiplexer_channel_enum; + +/* DMAMUX request generator channel */ +typedef enum { + DMAMUX_GENCH0 = 0U, /*!< DMAMUX request generator Channel0 */ + DMAMUX_GENCH1, /*!< DMAMUX request generator Channel1 */ + DMAMUX_GENCH2, /*!< DMAMUX request generator Channel2 */ + DMAMUX_GENCH3, /*!< DMAMUX request generator Channel3 */ + DMAMUX_GENCH4, /*!< DMAMUX request generator Channel4 */ + DMAMUX_GENCH5, /*!< DMAMUX request generator Channel5 */ + DMAMUX_GENCH6, /*!< DMAMUX request generator Channel6 */ + DMAMUX_GENCH7 /*!< DMAMUX request generator Channel7 */ +} dmamux_generator_channel_enum; + +/* DMAMUX interrupt */ +typedef enum { + /* interrupts in CHxCFG register */ + DMAMUX_INT_MUXCH0_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH1_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH2_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH3_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 3 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH4_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH4CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 4 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH5_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH5CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH6_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH6CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH7_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH7CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH8_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH8CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH9_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH9CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH10_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH10CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 3 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH11_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH11CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 4 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH12_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH12CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH13_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH13CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH14_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH14CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH15_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH15CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_GENCH0_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 0 trigger overrun interrupt */ + DMAMUX_INT_GENCH1_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 1 trigger overrun interrupt */ + DMAMUX_INT_GENCH2_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 2 trigger overrun interrupt */ + DMAMUX_INT_GENCH3_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 3 trigger overrun interrupt */ + DMAMUX_INT_GENCH4_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH4CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 4 trigger overrun interrupt */ + DMAMUX_INT_GENCH5_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH5CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 5 trigger overrun interrupt */ + DMAMUX_INT_GENCH6_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH6CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 6 trigger overrun interrupt */ + DMAMUX_INT_GENCH7_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH7CFG_REG_OFFSET, 8U) /*!< DMAMUX request generator channel 7 trigger overrun interrupt */ +} dmamux_interrupt_enum; + +/* DMAMUX flags */ +typedef enum { + /* flags in INTF register */ + DMAMUX_FLAG_MUXCH0_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 0U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH1_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 1U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH2_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 2U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH3_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 3U), /*!< DMAMUX request multiplexer channel 3 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH4_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 4U), /*!< DMAMUX request multiplexer channel 4 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH5_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 5U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH6_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 6U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH7_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 7U), /*!< DMAMUX request multiplexer channel 7 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH8_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 8 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH9_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 9U), /*!< DMAMUX request multiplexer channel 9 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH10_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 10U), /*!< DMAMUX request multiplexer channel 10 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH11_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 11U), /*!< DMAMUX request multiplexer channel 11 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH12_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 12U), /*!< DMAMUX request multiplexer channel 12 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH13_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 13U), /*!< DMAMUX request multiplexer channel 13 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH14_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 14U), /*!< DMAMUX request multiplexer channel 14 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH15_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 15U), /*!< DMAMUX request multiplexer channel 15 synchronization overrun flag */ + DMAMUX_FLAG_GENCH0_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 0U), /*!< DMAMUX request generator channel 0 trigger overrun flag */ + DMAMUX_FLAG_GENCH1_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 1U), /*!< DMAMUX request generator channel 1 trigger overrun flag */ + DMAMUX_FLAG_GENCH2_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 2U), /*!< DMAMUX request generator channel 2 trigger overrun flag */ + DMAMUX_FLAG_GENCH3_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 3U), /*!< DMAMUX request generator channel 3 trigger overrun flag */ + DMAMUX_FLAG_GENCH4_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 4U), /*!< DMAMUX request generator channel 4 trigger overrun flag */ + DMAMUX_FLAG_GENCH5_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 5U), /*!< DMAMUX request generator channel 5 trigger overrun flag */ + DMAMUX_FLAG_GENCH6_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 6U), /*!< DMAMUX request generator channel 6 trigger overrun flag */ + DMAMUX_FLAG_GENCH7_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 7U) /*!< DMAMUX request generator channel 7 trigger overrun flag */ +} dmamux_flag_enum; + +/* DMAMUX interrupt flags */ +typedef enum { + /* interrupt flags in INTF register */ + DMAMUX_INT_FLAG_MUXCH0_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 0U, DMAMUX_RM_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH1_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 1U, DMAMUX_RM_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH2_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 2U, DMAMUX_RM_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH3_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 3U, DMAMUX_RM_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 3 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH4_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 4U, DMAMUX_RM_CH4CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 4 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH5_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 5U, DMAMUX_RM_CH5CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH6_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 6U, DMAMUX_RM_CH6CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH7_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 7U, DMAMUX_RM_CH7CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 7 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH8_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 8U, DMAMUX_RM_CH8CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 8 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH9_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 9U, DMAMUX_RM_CH9CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 9 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH10_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 10U, DMAMUX_RM_CH10CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 10 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH11_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 11U, DMAMUX_RM_CH11CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 11 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH12_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 12U, DMAMUX_RM_CH12CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 12 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH13_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 13U, DMAMUX_RM_CH13CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 13 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH14_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 14U, DMAMUX_RM_CH14CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 14 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH15_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 15U, DMAMUX_RM_CH15CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 15 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH0_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 0U, DMAMUX_RG_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 0 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH1_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 1U, DMAMUX_RG_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 1 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH2_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 2U, DMAMUX_RG_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 2 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH3_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 3U, DMAMUX_RG_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 3 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH4_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 4U, DMAMUX_RG_CH4CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 4 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH5_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 5U, DMAMUX_RG_CH5CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 5 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH6_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 6U, DMAMUX_RG_CH6CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 6 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH7_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 7U, DMAMUX_RG_CH7CFG_REG_OFFSET, 8U) /*!< DMAMUX request generator channel 7 trigger overrun interrupt flag */ +} dmamux_interrupt_flag_enum; + +/* DMA channel flag shift */ +#define DMA_FLAG_ADD(flag,channel) ((uint32_t)((flag)<<((((uint32_t)(channel)*6U))+((uint32_t)(((uint32_t)(channel))>>1U)&0x01U)*4U))) + +/* DMA_register address */ +#define DMA_CHCTL(dma,channel) REG32(((dma) + 0x00000010U) + 0x00000018U * (channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(dma,channel) REG32(((dma) + 0x00000014U) + 0x00000018U * (channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(dma,channel) REG32(((dma) + 0x00000018U) + 0x00000018U * (channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHM0ADDR(dma,channel) REG32(((dma) + 0x0000001CU) + 0x00000018U * (channel)) /*!< the address of DMA channel CHXM0ADDR register */ +#define DMA_CHM1ADDR(dma,channel) REG32(((dma) + 0x00000020U) + 0x00000018U * (channel)) /*!< the address of DMA channel CHXM1ADDR register */ +#define DMA_CHFCTL(dma,channel) REG32(((dma) + 0x00000024U) + 0x00000018U * (channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* DMAMUX_RM_CHxCFG base address */ +#define DMAMUX_RM_CHXCFG_BASE (DMAMUX) /*!< the base address of DMAMUX request multiplexer channel CHxCFG register */ + +/* DMAMUX request multiplexer channel shift bit */ +#define DMAMUX_RM_CHXCFG(channel) REG32(DMAMUX_RM_CHXCFG_BASE + 0x04U * (uint32_t)(channel)) /*!< the address of DMAMUX request multiplexer channel CHxCFG register */ + +/* DMAMUX_RG_CHxCFG base address */ +#define DMAMUX_RG_CHXCFG_BASE (DMAMUX + 0x00000100U) /*!< the base address of DMAMUX channel request generator CHxCFG register */ + +/* DMAMUX request generator channel shift bit */ +#define DMAMUX_RG_CHXCFG(channel) REG32(DMAMUX_RG_CHXCFG_BASE + 0x04U * (uint32_t)(channel)) /*!< the address of DMAMUX channel request generator CHxCFG register */ + +/* burst type of memory */ +#define CHCTL_MBURST(regval) (BITS(23,24) & ((uint32_t)(regval) << 23U)) +#define DMA_MEMORY_BURST_SINGLE CHCTL_MBURST(0) /*!< single burst */ +#define DMA_MEMORY_BURST_4_BEAT CHCTL_MBURST(1) /*!< 4-beat burst */ +#define DMA_MEMORY_BURST_8_BEAT CHCTL_MBURST(2) /*!< 8-beat burst */ +#define DMA_MEMORY_BURST_16_BEAT CHCTL_MBURST(3) /*!< 16-beat burst */ + +/* burst type of peripheral */ +#define CHCTL_PBURST(regval) (BITS(21,22) & ((uint32_t)(regval) << 21U)) +#define DMA_PERIPH_BURST_SINGLE CHCTL_PBURST(0) /*!< single burst */ +#define DMA_PERIPH_BURST_4_BEAT CHCTL_PBURST(1) /*!< 4-beat burst */ +#define DMA_PERIPH_BURST_8_BEAT CHCTL_PBURST(2) /*!< 8-beat burst */ +#define DMA_PERIPH_BURST_16_BEAT CHCTL_PBURST(3) /*!< 16-beat burst */ + +/* channel priority level */ +#define CHCTL_PRIO(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define DMA_PRIORITY_LOW CHCTL_PRIO(0) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3) /*!< ultra high priority */ + +/* transfer data width of memory */ +#define CHCTL_MWIDTH(regval) (BITS(13,14) & ((uint32_t)(regval) << 13U)) +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MWIDTH(0) /*!< transfer data width of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1) /*!< transfer data width of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2) /*!< transfer data width of memory is 32-bit */ + +/* transfer data width of peripheral */ +#define CHCTL_PWIDTH(regval) (BITS(11,12) & ((uint32_t)(regval) << 11U)) +#define DMA_PERIPH_WIDTH_8BIT CHCTL_PWIDTH(0) /*!< transfer data width of peripheral is 8-bit */ +#define DMA_PERIPH_WIDTH_16BIT CHCTL_PWIDTH(1) /*!< transfer data width of peripheral is 16-bit */ +#define DMA_PERIPH_WIDTH_32BIT CHCTL_PWIDTH(2) /*!< transfer data width of peripheral is 32-bit */ + +/* channel transfer mode */ +#define CHCTL_TM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6U)) +#define DMA_PERIPH_TO_MEMORY CHCTL_TM(0) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPH CHCTL_TM(1) /*!< read from memory and write to peripheral */ +#define DMA_MEMORY_TO_MEMORY CHCTL_TM(2) /*!< read from memory and write to memory */ + +/* FIFO counter critical value */ +#define CHFCTL_FCCV(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define DMA_FIFO_1_WORD CHFCTL_FCCV(0) /*!< critical value 1 word */ +#define DMA_FIFO_2_WORD CHFCTL_FCCV(1) /*!< critical value 2 word */ +#define DMA_FIFO_3_WORD CHFCTL_FCCV(2) /*!< critical value 3 word */ +#define DMA_FIFO_4_WORD CHFCTL_FCCV(3) /*!< critical value 4 word */ + +/* FIFO counter */ +#define DMA_FIFO_CNT_NO_DATA ((uint32_t)0x00000000U) /*!< no data */ +#define DMA_FIFO_CNT_1_WORD ((uint32_t)0x00000001U) /*!< 1 word */ +#define DMA_FIFO_CNT_2_WORD ((uint32_t)0x00000002U) /*!< 2 words */ +#define DMA_FIFO_CNT_3_WORD ((uint32_t)0x00000003U) /*!< 3 words */ +#define DMA_FIFO_CNT_EMPTY ((uint32_t)0x00000004U) /*!< empty */ +#define DMA_FIFO_CNT_FULL ((uint32_t)0x00000005U) /*!< full */ + +/* memory select */ +#define DMA_MEMORY_0 ((uint32_t)0x00000000U) /*!< select memory 0 */ +#define DMA_MEMORY_1 ((uint32_t)0x00000001U) /*!< select memory 1 */ + +/* DMA circular mode */ +#define DMA_CIRCULAR_MODE_ENABLE ((uint32_t)0x00000000U) /*!< circular mode enable */ +#define DMA_CIRCULAR_MODE_DISABLE ((uint32_t)0x00000001U) /*!< circular mode disable */ + +/* DMA flow controller select */ +#define DMA_FLOW_CONTROLLER_DMA ((uint32_t)0x00000000U) /*!< DMA is the flow controler */ +#define DMA_FLOW_CONTROLLER_PERI ((uint32_t)0x00000001U) /*!< peripheral is the flow controler */ + +/* peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of peripheral is increasing address mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of peripheral is fixed address mode */ +#define DMA_PERIPH_INCREASE_FIX ((uint32_t)0x00000002U) /*!< next address of peripheral is increasing fixed */ + +/* memory increasing mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint32_t)0x00000000U) /*!< next address of memory is increasing address mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint32_t)0x00000001U) /*!< next address of memory is fixed address mode */ + +/* FIFO status */ +#define DMA_FIFO_STATUS_NODATA ((uint32_t)0x00000000U) /*!< the data in the FIFO less than 1 word */ +#define DMA_FIFO_STATUS_1_WORD ((uint32_t)0x00000001U) /*!< the data in the FIFO more than 1 word, less than 2 words */ +#define DMA_FIFO_STATUS_2_WORD ((uint32_t)0x00000002U) /*!< the data in the FIFO more than 2 word, less than 3 words */ +#define DMA_FIFO_STATUS_3_WORD ((uint32_t)0x00000003U) /*!< the data in the FIFO more than 3 word, less than 4 words */ +#define DMA_FIFO_STATUS_EMPTY ((uint32_t)0x00000004U) /*!< the data in the FIFO is empty */ +#define DMA_FIFO_STATUS_FULL ((uint32_t)0x00000005U) /*!< the data in the FIFO is full */ + +/* DMA reset value */ +#define DMA_CHCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCTL register */ +#define DMA_CHCNT_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCNT register */ +#define DMA_CHPADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXPADDR register */ +#define DMA_CHMADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXMADDR register */ +#define DMA_CHINTF_RESET_VALUE ((uint32_t)0x0000003DU) /*!< clear DMA channel CHXINTFS register */ +#define DMA_CHFCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXFCTL register */ + +/* flag bits */ +#define DMA_FLAG_FEE DMA_INTF_FEEIF /*!< FIFO error and exception flag */ +#define DMA_FLAG_SDE DMA_INTF_SDEIF /*!< single data mode exception flag */ +#define DMA_FLAG_TAE DMA_INTF_TAEIF /*!< transfer access error flag */ +#define DMA_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish flag */ +#define DMA_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish flag */ + +/* DMA interrupt flag bits */ +#define DMA_INT_FLAG_FEE DMA_INTF_FEEIF /*!< FIFO error and exception flag */ +#define DMA_INT_FLAG_SDE DMA_INTF_SDEIF /*!< single data mode exception flag */ +#define DMA_INT_FLAG_TAE DMA_INTF_TAEIF /*!< transfer access error flag */ +#define DMA_INT_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish flag */ +#define DMA_INT_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish flag */ + +/* DMA interrupt */ +#define DMA_INT_SDE DMA_CHXCTL_SDEIE /*!< single data mode exception interrupt */ +#define DMA_INT_TAE DMA_CHXCTL_TAEIE /*!< tranfer access error interrupt */ +#define DMA_INT_HTF DMA_CHXCTL_HTFIE /*!< half transfer finish interrupt */ +#define DMA_INT_FTF DMA_CHXCTL_FTFIE /*!< full transfer finish interrupt */ +#define DMA_INT_FEE DMA_CHXFCTL_FEEIE /*!< FIFO exception interrupt */ + +/* DMAMUX request multiplexer channel input identification */ +#define RM_CHXCFG_MUXID(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< multiplexer input identification */ +#define DMA_REQUEST_M2M RM_CHXCFG_MUXID(0U) /*!< memory to memory transfer */ +#define DMA_REQUEST_GENERATOR0 RM_CHXCFG_MUXID(1U) /*!< DMAMUX request generator 0 */ +#define DMA_REQUEST_GENERATOR1 RM_CHXCFG_MUXID(2U) /*!< DMAMUX request generator 1 */ +#define DMA_REQUEST_GENERATOR2 RM_CHXCFG_MUXID(3U) /*!< DMAMUX request generator 2 */ +#define DMA_REQUEST_GENERATOR3 RM_CHXCFG_MUXID(4U) /*!< DMAMUX request generator 3 */ +#define DMA_REQUEST_GENERATOR4 RM_CHXCFG_MUXID(5U) /*!< DMAMUX request generator 4 */ +#define DMA_REQUEST_GENERATOR5 RM_CHXCFG_MUXID(6U) /*!< DMAMUX request generator 5 */ +#define DMA_REQUEST_GENERATOR6 RM_CHXCFG_MUXID(7U) /*!< DMAMUX request generator 6 */ +#define DMA_REQUEST_GENERATOR7 RM_CHXCFG_MUXID(8U) /*!< DMAMUX request generator 7 */ +#define DMA_REQUEST_ADC0 RM_CHXCFG_MUXID(9U) /*!< DMAMUX ADC0 request */ +#define DMA_REQUEST_ADC1 RM_CHXCFG_MUXID(10U) /*!< DMAMUX ADC1 request */ +#define DMA_REQUEST_TIMER0_CH0 RM_CHXCFG_MUXID(11U) /*!< DMAMUX TIMER0 CH0 request */ +#define DMA_REQUEST_TIMER0_CH1 RM_CHXCFG_MUXID(12U) /*!< DMAMUX TIMER0 CH1 request */ +#define DMA_REQUEST_TIMER0_CH2 RM_CHXCFG_MUXID(13U) /*!< DMAMUX TIMER0 CH2 request */ +#define DMA_REQUEST_TIMER0_CH3 RM_CHXCFG_MUXID(14U) /*!< DMAMUX TIMER0 CH3 request */ +#define DMA_REQUEST_TIMER0_MCH0 RM_CHXCFG_MUXID(15U) /*!< DMAMUX TIMER0 MCH0 request */ +#define DMA_REQUEST_TIMER0_MCH1 RM_CHXCFG_MUXID(16U) /*!< DMAMUX TIMER0 MCH1 request */ +#define DMA_REQUEST_TIMER0_MCH2 RM_CHXCFG_MUXID(17U) /*!< DMAMUX TIMER0 MCH2 request */ +#define DMA_REQUEST_TIMER0_MCH3 RM_CHXCFG_MUXID(18U) /*!< DMAMUX TIMER0 MCH3 request */ +#define DMA_REQUEST_TIMER0_UP RM_CHXCFG_MUXID(19U) /*!< DMAMUX TIMER0 UP request */ +#define DMA_REQUEST_TIMER0_TRG RM_CHXCFG_MUXID(20U) /*!< DMAMUX TIMER0 TRG request */ +#define DMA_REQUEST_TIMER0_CMT RM_CHXCFG_MUXID(21U) /*!< DMAMUX TIMER0 CMT request */ +#define DMA_REQUEST_TIMER1_CH0 RM_CHXCFG_MUXID(22U) /*!< DMAMUX TIMER1 CH0 request */ +#define DMA_REQUEST_TIMER1_CH1 RM_CHXCFG_MUXID(23U) /*!< DMAMUX TIMER1 CH1 request */ +#define DMA_REQUEST_TIMER1_CH2 RM_CHXCFG_MUXID(24U) /*!< DMAMUX TIMER1 CH2 request */ +#define DMA_REQUEST_TIMER1_CH3 RM_CHXCFG_MUXID(25U) /*!< DMAMUX TIMER1 CH3 request */ +#define DMA_REQUEST_TIMER1_UP RM_CHXCFG_MUXID(26U) /*!< DMAMUX TIMER1 UP request */ +#define DMA_REQUEST_TIMER1_TRG RM_CHXCFG_MUXID(27U) /*!< DMAMUX TIMER1 TRG request */ +#define DMA_REQUEST_TIMER2_CH0 RM_CHXCFG_MUXID(29U) /*!< DMAMUX TIMER2 CH0 request */ +#define DMA_REQUEST_TIMER2_CH1 RM_CHXCFG_MUXID(30U) /*!< DMAMUX TIMER2 CH1 request */ +#define DMA_REQUEST_TIMER2_CH2 RM_CHXCFG_MUXID(31U) /*!< DMAMUX TIMER2 CH2 request */ +#define DMA_REQUEST_TIMER2_CH3 RM_CHXCFG_MUXID(32U) /*!< DMAMUX TIMER2 CH3 request */ +#define DMA_REQUEST_TIMER2_UP RM_CHXCFG_MUXID(33U) /*!< DMAMUX TIMER2 UP request */ +#define DMA_REQUEST_TIMER2_TRG RM_CHXCFG_MUXID(35U) /*!< DMAMUX TIMER2 TRG request */ +#define DMA_REQUEST_TIMER3_CH0 RM_CHXCFG_MUXID(36U) /*!< DMAMUX TIMER3 CH0 request */ +#define DMA_REQUEST_TIMER3_CH1 RM_CHXCFG_MUXID(37U) /*!< DMAMUX TIMER3 CH1 request */ +#define DMA_REQUEST_TIMER3_CH2 RM_CHXCFG_MUXID(38U) /*!< DMAMUX TIMER3 CH2 request */ +#define DMA_REQUEST_TIMER3_CH3 RM_CHXCFG_MUXID(39U) /*!< DMAMUX TIMER3 CH3 request */ +#define DMA_REQUEST_TIMER3_TRG RM_CHXCFG_MUXID(41U) /*!< DMAMUX TIMER3 TRG request */ +#define DMA_REQUEST_TIMER3_UP RM_CHXCFG_MUXID(42U) /*!< DMAMUX TIMER3 UP request */ +#define DMA_REQUEST_I2C0_RX RM_CHXCFG_MUXID(43U) /*!< DMAMUX I2C0 RX request */ +#define DMA_REQUEST_I2C0_TX RM_CHXCFG_MUXID(44U) /*!< DMAMUX I2C0 TX request */ +#define DMA_REQUEST_I2C1_RX RM_CHXCFG_MUXID(45U) /*!< DMAMUX I2C1 RX request */ +#define DMA_REQUEST_I2C1_TX RM_CHXCFG_MUXID(46U) /*!< DMAMUX I2C1 TX request */ +#define DMA_REQUEST_SPI0_RX RM_CHXCFG_MUXID(47U) /*!< DMAMUX SPI0 RX request */ +#define DMA_REQUEST_SPI0_TX RM_CHXCFG_MUXID(48U) /*!< DMAMUX SPI0 TX request */ +#define DMA_REQUEST_SPI1_RX RM_CHXCFG_MUXID(49U) /*!< DMAMUX SPI1 RX request */ +#define DMA_REQUEST_SPI1_TX RM_CHXCFG_MUXID(50U) /*!< DMAMUX SPI1 TX request */ +#define DMA_REQUEST_USART0_RX RM_CHXCFG_MUXID(51U) /*!< DMAMUX USART0 RX request */ +#define DMA_REQUEST_USART0_TX RM_CHXCFG_MUXID(52U) /*!< DMAMUX USART0 TX request */ +#define DMA_REQUEST_USART1_RX RM_CHXCFG_MUXID(53U) /*!< DMAMUX USART1 RX request */ +#define DMA_REQUEST_USART1_TX RM_CHXCFG_MUXID(54U) /*!< DMAMUX USART1 TX request */ +#define DMA_REQUEST_USART2_RX RM_CHXCFG_MUXID(55U) /*!< DMAMUX USART2 RX request */ +#define DMA_REQUEST_USART2_TX RM_CHXCFG_MUXID(56U) /*!< DMAMUX USART2 TX request */ +#define DMA_REQUEST_TIMER7_CH0 RM_CHXCFG_MUXID(57U) /*!< DMAMUX TIMER7 CH0 request */ +#define DMA_REQUEST_TIMER7_CH1 RM_CHXCFG_MUXID(58U) /*!< DMAMUX TIMER7 CH1 request */ +#define DMA_REQUEST_TIMER7_CH2 RM_CHXCFG_MUXID(59U) /*!< DMAMUX TIMER7 CH2 request */ +#define DMA_REQUEST_TIMER7_CH3 RM_CHXCFG_MUXID(60U) /*!< DMAMUX TIMER7 CH3 request */ +#define DMA_REQUEST_TIMER7_MCH0 RM_CHXCFG_MUXID(61U) /*!< DMAMUX TIMER7 MCH0 request */ +#define DMA_REQUEST_TIMER7_MCH1 RM_CHXCFG_MUXID(62U) /*!< DMAMUX TIMER7 MCH1 request */ +#define DMA_REQUEST_TIMER7_MCH2 RM_CHXCFG_MUXID(63U) /*!< DMAMUX TIMER7 MCH2 request */ +#define DMA_REQUEST_TIMER7_MCH3 RM_CHXCFG_MUXID(64U) /*!< DMAMUX TIMER7 MCH3 request */ +#define DMA_REQUEST_TIMER7_UP RM_CHXCFG_MUXID(65U) /*!< DMAMUX TIMER7 UP request */ +#define DMA_REQUEST_TIMER7_TRG RM_CHXCFG_MUXID(66U) /*!< DMAMUX TIMER7 TRG request */ +#define DMA_REQUEST_TIMER7_CMT RM_CHXCFG_MUXID(67U) /*!< DMAMUX TIMER7 CMT request */ +#define DMA_REQUEST_TIMER4_CH0 RM_CHXCFG_MUXID(68U) /*!< DMAMUX TIMER4 CH0 request */ +#define DMA_REQUEST_TIMER4_CH1 RM_CHXCFG_MUXID(69U) /*!< DMAMUX TIMER4 CH1 request */ +#define DMA_REQUEST_TIMER4_CH2 RM_CHXCFG_MUXID(70U) /*!< DMAMUX TIMER4 CH2 request */ +#define DMA_REQUEST_TIMER4_CH3 RM_CHXCFG_MUXID(71U) /*!< DMAMUX TIMER4 CH3 request */ +#define DMA_REQUEST_TIMER4_UP RM_CHXCFG_MUXID(72U) /*!< DMAMUX TIMER4 UP request */ +#define DMA_REQUEST_TIMER4_CMT RM_CHXCFG_MUXID(73U) /*!< DMAMUX TIMER4 CMT request */ +#define DMA_REQUEST_TIMER4_TRG RM_CHXCFG_MUXID(74U) /*!< DMAMUX TIMER4 TRG request */ +#define DMA_REQUEST_SPI2_RX RM_CHXCFG_MUXID(75U) /*!< DMAMUX SPI2 RX request */ +#define DMA_REQUEST_SPI2_TX RM_CHXCFG_MUXID(76U) /*!< DMAMUX SPI2 TX request */ +#define DMA_REQUEST_UART3_RX RM_CHXCFG_MUXID(77U) /*!< DMAMUX UART3 RX request */ +#define DMA_REQUEST_UART3_TX RM_CHXCFG_MUXID(78U) /*!< DMAMUX UART3 TX request */ +#define DMA_REQUEST_UART4_RX RM_CHXCFG_MUXID(79U) /*!< DMAMUX UART4 RX request */ +#define DMA_REQUEST_UART4_TX RM_CHXCFG_MUXID(80U) /*!< DMAMUX UART4 TX request */ +#define DMA_REQUEST_DAC_CH0 RM_CHXCFG_MUXID(81U) /*!< DMAMUX DAC CH0 request */ +#define DMA_REQUEST_DAC_CH1 RM_CHXCFG_MUXID(82U) /*!< DMAMUX DAC CH1 request */ +#define DMA_REQUEST_TIMER5_UP RM_CHXCFG_MUXID(83U) /*!< DMAMUX TIMER5 UP request */ +#define DMA_REQUEST_TIMER6_UP RM_CHXCFG_MUXID(84U) /*!< DMAMUX TIMER6 UP request */ +#define DMA_REQUEST_USART5_RX RM_CHXCFG_MUXID(85U) /*!< DMAMUX USART5 RX request */ +#define DMA_REQUEST_USART5_TX RM_CHXCFG_MUXID(86U) /*!< DMAMUX USART5 TX request */ +#define DMA_REQUEST_I2C2_RX RM_CHXCFG_MUXID(87U) /*!< DMAMUX I2C2 RX request */ +#define DMA_REQUEST_I2C2_TX RM_CHXCFG_MUXID(88U) /*!< DMAMUX I2C2 TX request */ +#define DMA_REQUEST_DCI RM_CHXCFG_MUXID(89U) /*!< DMAMUX DCI request */ +#define DMA_REQUEST_CAU_IN RM_CHXCFG_MUXID(90U) /*!< DMAMUX CAU IN request */ +#define DMA_REQUEST_CAU_OUT RM_CHXCFG_MUXID(91U) /*!< DMAMUX CAU OUT request */ +#define DMA_REQUEST_HAU_IN RM_CHXCFG_MUXID(92U) /*!< DMAMUX HAU IN request */ +#define DMA_REQUEST_UART6_RX RM_CHXCFG_MUXID(93U) /*!< DMAMUX UART6 RX request */ +#define DMA_REQUEST_UART6_TX RM_CHXCFG_MUXID(94U) /*!< DMAMUX UART6 TX request */ +#define DMA_REQUEST_UART7_RX RM_CHXCFG_MUXID(95U) /*!< DMAMUX UART7 RX request */ +#define DMA_REQUEST_UART7_TX RM_CHXCFG_MUXID(96U) /*!< DMAMUX UART7 TX request */ +#define DMA_REQUEST_SPI3_RX RM_CHXCFG_MUXID(97U) /*!< DMAMUX SPI3 RX request */ +#define DMA_REQUEST_SPI3_TX RM_CHXCFG_MUXID(98U) /*!< DMAMUX SPI3 TX request */ +#define DMA_REQUEST_SPI4_RX RM_CHXCFG_MUXID(99U) /*!< DMAMUX SPI4 RX request */ +#define DMA_REQUEST_SPI4_TX RM_CHXCFG_MUXID(100U) /*!< DMAMUX SPI4 TX request */ +#define DMA_REQUEST_SAI0_B0 RM_CHXCFG_MUXID(101U) /*!< DMAMUX SAI0 B0 request */ +#define DMA_REQUEST_SAI0_B1 RM_CHXCFG_MUXID(102U) /*!< DMAMUX SAI0 B1 request */ +#define DMA_REQUEST_RSPDIF_DATA RM_CHXCFG_MUXID(103U) /*!< DMAMUX RSPDIF DATA request */ +#define DMA_REQUEST_RSPDIF_CS RM_CHXCFG_MUXID(104U) /*!< DMAMUX RSPDIF CS request */ +#define DMA_REQUEST_HPDF_FLT0 RM_CHXCFG_MUXID(105U) /*!< DMAMUX HPDF FLT0 request */ +#define DMA_REQUEST_HPDF_FLT1 RM_CHXCFG_MUXID(106U) /*!< DMAMUX HPDF FLT1 request */ +#define DMA_REQUEST_HPDF_FLT2 RM_CHXCFG_MUXID(107U) /*!< DMAMUX HPDF FLT2 request */ +#define DMA_REQUEST_HPDF_FLT3 RM_CHXCFG_MUXID(108U) /*!< DMAMUX HPDF FLT3 request */ +#define DMA_REQUEST_TIMER14_CH0 RM_CHXCFG_MUXID(109U) /*!< DMAMUX TIMER14 CH0 request */ +#define DMA_REQUEST_TIMER14_CH1 RM_CHXCFG_MUXID(110U) /*!< DMAMUX TIMER14 CH1 request */ +#define DMA_REQUEST_TIMER14_MCH0 RM_CHXCFG_MUXID(111U) /*!< DMAMUX TIMER14 MCH0 request */ +#define DMA_REQUEST_TIMER14_UP RM_CHXCFG_MUXID(112U) /*!< DMAMUX TIMER14 UP request */ +#define DMA_REQUEST_TIMER14_TRG RM_CHXCFG_MUXID(113U) /*!< DMAMUX TIMER14 TRG request */ +#define DMA_REQUEST_TIMER14_CMT RM_CHXCFG_MUXID(114U) /*!< DMAMUX TIMER14 CMT request */ +#define DMA_REQUEST_TIMER15_CH0 RM_CHXCFG_MUXID(115U) /*!< DMAMUX TIMER15 CH0 request */ +#define DMA_REQUEST_TIMER15_MCH0 RM_CHXCFG_MUXID(116U) /*!< DMAMUX TIMER15 MCH0 request */ +#define DMA_REQUEST_TIMER15_UP RM_CHXCFG_MUXID(118U) /*!< DMAMUX TIMER15 UP request */ +#define DMA_REQUEST_TIMER16_CH0 RM_CHXCFG_MUXID(119U) /*!< DMAMUX TIMER16 CH0 request */ +#define DMA_REQUEST_TIMER16_MCH0 RM_CHXCFG_MUXID(120U) /*!< DMAMUX TIMER16 MCH0 request */ +#define DMA_REQUEST_TIMER16_UP RM_CHXCFG_MUXID(122U) /*!< DMAMUX TIMER16 TRG request */ +#define DMA_REQUEST_ADC2 RM_CHXCFG_MUXID(123U) /*!< DMAMUX ADC2 request */ +#define DMA_REQUEST_FAC_READ RM_CHXCFG_MUXID(124U) /*!< DMAMUX FAC READ request */ +#define DMA_REQUEST_FAC_WRITE RM_CHXCFG_MUXID(125U) /*!< DMAMUX FAC WRITE request */ +#define DMA_REQUEST_TMU_INPUT RM_CHXCFG_MUXID(126U) /*!< DMAMUX TMU INPUT request */ +#define DMA_REQUEST_TMU_OUTPUT RM_CHXCFG_MUXID(127U) /*!< DMAMUX TMU OUTPUT request */ +#define DMA_REQUEST_TIMER22_CH0 RM_CHXCFG_MUXID(128U) /*!< DMAMUX TIMER22 CH0 request */ +#define DMA_REQUEST_TIMER22_CH1 RM_CHXCFG_MUXID(129U) /*!< DMAMUX TIMER22 CH1 request */ +#define DMA_REQUEST_TIMER22_CH2 RM_CHXCFG_MUXID(130U) /*!< DMAMUX TIMER22 CH2 request */ +#define DMA_REQUEST_TIMER22_CH3 RM_CHXCFG_MUXID(131U) /*!< DMAMUX TIMER22 CH3 request */ +#define DMA_REQUEST_TIMER22_UP RM_CHXCFG_MUXID(132U) /*!< DMAMUX TIMER22 UP request */ +#define DMA_REQUEST_TIMER22_TRG RM_CHXCFG_MUXID(134U) /*!< DMAMUX TIMER22 TRG request */ +#define DMA_REQUEST_TIMER23_CH0 RM_CHXCFG_MUXID(135U) /*!< DMAMUX TIMER23 CH0 request */ +#define DMA_REQUEST_TIMER23_CH1 RM_CHXCFG_MUXID(136U) /*!< DMAMUX TIMER23 CH1 request */ +#define DMA_REQUEST_TIMER23_CH2 RM_CHXCFG_MUXID(137U) /*!< DMAMUX TIMER23 CH2 request */ +#define DMA_REQUEST_TIMER23_CH3 RM_CHXCFG_MUXID(138U) /*!< DMAMUX TIMER23 CH3 request */ +#define DMA_REQUEST_TIMER23_UP RM_CHXCFG_MUXID(139U) /*!< DMAMUX TIMER23 UP request */ +#define DMA_REQUEST_TIMER23_TRG RM_CHXCFG_MUXID(141U) /*!< DMAMUX TIMER23 TRG request */ +#define DMA_REQUEST_TIMER30_CH0 RM_CHXCFG_MUXID(142U) /*!< DMAMUX TIMER30 CH0 request */ +#define DMA_REQUEST_TIMER30_CH1 RM_CHXCFG_MUXID(143U) /*!< DMAMUX TIMER30 CH1 request */ +#define DMA_REQUEST_TIMER30_CH2 RM_CHXCFG_MUXID(144U) /*!< DMAMUX TIMER30 CH2 request */ +#define DMA_REQUEST_TIMER30_CH3 RM_CHXCFG_MUXID(145U) /*!< DMAMUX TIMER30 CH3 request */ +#define DMA_REQUEST_TIMER30_UP RM_CHXCFG_MUXID(146U) /*!< DMAMUX TIMER30 UP request */ +#define DMA_REQUEST_TIMER30_TRG RM_CHXCFG_MUXID(148U) /*!< DMAMUX TIMER30 TRG request */ +#define DMA_REQUEST_TIMER31_CH0 RM_CHXCFG_MUXID(149U) /*!< DMAMUX TIMER31 CH0 request */ +#define DMA_REQUEST_TIMER31_CH1 RM_CHXCFG_MUXID(150U) /*!< DMAMUX TIMER31 CH1 request */ +#define DMA_REQUEST_TIMER31_CH2 RM_CHXCFG_MUXID(151U) /*!< DMAMUX TIMER31 CH2 request */ +#define DMA_REQUEST_TIMER31_CH3 RM_CHXCFG_MUXID(152U) /*!< DMAMUX TIMER31 CH3 request */ +#define DMA_REQUEST_TIMER31_UP RM_CHXCFG_MUXID(154U) /*!< DMAMUX TIMER31 UP request */ +#define DMA_REQUEST_TIMER31_TRG RM_CHXCFG_MUXID(155U) /*!< DMAMUX TIMER31 TRG request */ +#define DMA_REQUEST_TIMER40_CH0 RM_CHXCFG_MUXID(156U) /*!< DMAMUX TIMER40 CH0 request */ +#define DMA_REQUEST_TIMER40_MCH0 RM_CHXCFG_MUXID(157U) /*!< DMAMUX TIMER40 MCH0 request */ +#define DMA_REQUEST_TIMER40_CMT RM_CHXCFG_MUXID(158U) /*!< DMAMUX TIMER40 CMT request */ +#define DMA_REQUEST_TIMER40_UP RM_CHXCFG_MUXID(159U) /*!< DMAMUX TIMER40 UP request */ +#define DMA_REQUEST_TIMER41_CH0 RM_CHXCFG_MUXID(160U) /*!< DMAMUX TIMER41 CH0 request */ +#define DMA_REQUEST_TIMER41_MCH0 RM_CHXCFG_MUXID(161U) /*!< DMAMUX TIMER41 MCH0 request */ +#define DMA_REQUEST_TIMER41_CMT RM_CHXCFG_MUXID(162U) /*!< DMAMUX TIMER41 CMT request */ +#define DMA_REQUEST_TIMER41_UP RM_CHXCFG_MUXID(163U) /*!< DMAMUX TIMER41 UP request */ +#define DMA_REQUEST_TIMER42_CH0 RM_CHXCFG_MUXID(164U) /*!< DMAMUX TIMER42 CH0 request */ +#define DMA_REQUEST_TIMER42_MCH0 RM_CHXCFG_MUXID(165U) /*!< DMAMUX TIMER42 MCH0 request */ +#define DMA_REQUEST_TIMER42_CMT RM_CHXCFG_MUXID(166U) /*!< DMAMUX TIMER42 CMT request */ +#define DMA_REQUEST_TIMER42_UP RM_CHXCFG_MUXID(167U) /*!< DMAMUX TIMER42 UP request */ +#define DMA_REQUEST_TIMER43_CH0 RM_CHXCFG_MUXID(168U) /*!< DMAMUX TIMER43 CH0 request */ +#define DMA_REQUEST_TIMER43_MCH0 RM_CHXCFG_MUXID(169U) /*!< DMAMUX TIMER43 MCH0 request */ +#define DMA_REQUEST_TIMER43_CMT RM_CHXCFG_MUXID(170U) /*!< DMAMUX TIMER43 CMT request */ +#define DMA_REQUEST_TIMER43_UP RM_CHXCFG_MUXID(171U) /*!< DMAMUX TIMER43 UP request */ +#define DMA_REQUEST_TIMER44_CH0 RM_CHXCFG_MUXID(172U) /*!< DMAMUX TIMER44 CH0 request */ +#define DMA_REQUEST_TIMER44_MCH0 RM_CHXCFG_MUXID(173U) /*!< DMAMUX TIMER44 MCH0 request */ +#define DMA_REQUEST_TIMER44_CMT RM_CHXCFG_MUXID(174U) /*!< DMAMUX TIMER44 CMT request */ +#define DMA_REQUEST_TIMER44_UP RM_CHXCFG_MUXID(175U) /*!< DMAMUX TIMER44 UP request */ +#define DMA_REQUEST_TIMER50_UP RM_CHXCFG_MUXID(176U) /*!< DMAMUX TIMER50 UP request */ +#define DMA_REQUEST_TIMER51_UP RM_CHXCFG_MUXID(177U) /*!< DMAMUX TIMER51 UP request */ +#define DMA_REQUEST_SAI1_B0 RM_CHXCFG_MUXID(178U) /*!< DMAMUX SAI1 B0 request */ +#define DMA_REQUEST_SAI1_B1 RM_CHXCFG_MUXID(179U) /*!< DMAMUX SAI1 B1 request */ +#define DMA_REQUEST_SAI2_B0 RM_CHXCFG_MUXID(180U) /*!< DMAMUX SAI2 B0 request */ +#define DMA_REQUEST_SAI2_B1 RM_CHXCFG_MUXID(181U) /*!< DMAMUX SAI2 B1 request */ +#define DMA_REQUEST_SPI5_RX RM_CHXCFG_MUXID(182U) /*!< DMAMUX SPI5 RX request */ +#define DMA_REQUEST_SPI5_TX RM_CHXCFG_MUXID(183U) /*!< DMAMUX SPI5 TX request */ +#define DMA_REQUEST_I2C3_RX RM_CHXCFG_MUXID(184U) /*!< DMAMUX I2C3 RX request */ +#define DMA_REQUEST_I2C3_TX RM_CHXCFG_MUXID(185U) /*!< DMAMUX I2C3 TX request */ +#define DMA_REQUEST_CAN0 RM_CHXCFG_MUXID(186U) /*!< DMAMUX CAN0 request */ +#define DMA_REQUEST_CAN1 RM_CHXCFG_MUXID(187U) /*!< DMAMUX CAN1 request */ +#define DMA_REQUEST_CAN2 RM_CHXCFG_MUXID(188U) /*!< DMAMUX CAN2 request */ +#define DMA_REQUEST_TIMER40_CH1 RM_CHXCFG_MUXID(189U) /*!< DMAMUX TIMER40 CH1 request */ +#define DMA_REQUEST_TIMER40_TRG RM_CHXCFG_MUXID(190U) /*!< DMAMUX TIMER40 TRG request */ +#define DMA_REQUEST_TIMER41_CH1 RM_CHXCFG_MUXID(191U) /*!< DMAMUX TIMER41 CH1 request */ +#define DMA_REQUEST_TIMER41_TRG RM_CHXCFG_MUXID(192U) /*!< DMAMUX TIMER41 TRG request */ +#define DMA_REQUEST_TIMER42_CH1 RM_CHXCFG_MUXID(193U) /*!< DMAMUX TIMER42 CH1 request */ +#define DMA_REQUEST_TIMER42_TRG RM_CHXCFG_MUXID(194U) /*!< DMAMUX TIMER42 TRG request */ +#define DMA_REQUEST_TIMER43_CH1 RM_CHXCFG_MUXID(195U) /*!< DMAMUX TIMER43 CH1 request */ +#define DMA_REQUEST_TIMER43_TRG RM_CHXCFG_MUXID(196U) /*!< DMAMUX TIMER43 TRG request */ +#define DMA_REQUEST_TIMER44_CH1 RM_CHXCFG_MUXID(197U) /*!< DMAMUX TIMER44 CH1 request */ +#define DMA_REQUEST_TIMER44_TRG RM_CHXCFG_MUXID(198U) /*!< DMAMUX TIMER44 TRG request */ + +/* DMAMUX request generator trigger input identification */ +#define RG_CHXCFG_TID(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< trigger input identification */ +#define DMAMUX_TRIGGER_EVT0_OUT RG_CHXCFG_TID(0U) /*!< trigger input is Evt0_out */ +#define DMAMUX_TRIGGER_EVT1_OUT RG_CHXCFG_TID(1U) /*!< trigger input is Evt1_out */ +#define DMAMUX_TRIGGER_EVT2_OUT RG_CHXCFG_TID(2U) /*!< trigger input is Evt2_out */ +#define DMAMUX_TRIGGER_EVT3_OUT RG_CHXCFG_TID(3U) /*!< trigger input is Evt3_out */ +#define DMAMUX_TRIGGER_EVT4_OUT RG_CHXCFG_TID(4U) /*!< trigger input is Evt4_out */ +#define DMAMUX_TRIGGER_EVT5_OUT RG_CHXCFG_TID(5U) /*!< trigger input is Evt5_out */ +#define DMAMUX_TRIGGER_EVT6_OUT RG_CHXCFG_TID(6U) /*!< trigger input is Evt6_out */ +#define DMAMUX_TRIGGER_EXTI0 RG_CHXCFG_TID(7U) /*!< trigger input is EXTI0 */ +#define DMAMUX_TRIGGER_EXTI1 RG_CHXCFG_TID(8U) /*!< trigger input is EXTI1 */ +#define DMAMUX_TRIGGER_EXTI2 RG_CHXCFG_TID(9U) /*!< trigger input is EXTI2 */ +#define DMAMUX_TRIGGER_EXTI3 RG_CHXCFG_TID(10U) /*!< trigger input is EXTI3 */ +#define DMAMUX_TRIGGER_EXTI4 RG_CHXCFG_TID(11U) /*!< trigger input is EXTI4 */ +#define DMAMUX_TRIGGER_EXTI5 RG_CHXCFG_TID(12U) /*!< trigger input is EXTI5 */ +#define DMAMUX_TRIGGER_EXTI6 RG_CHXCFG_TID(13U) /*!< trigger input is EXTI6 */ +#define DMAMUX_TRIGGER_EXTI7 RG_CHXCFG_TID(14U) /*!< trigger input is EXTI7 */ +#define DMAMUX_TRIGGER_EXTI8 RG_CHXCFG_TID(15U) /*!< trigger input is EXTI8 */ +#define DMAMUX_TRIGGER_EXTI9 RG_CHXCFG_TID(16U) /*!< trigger input is EXTI9 */ +#define DMAMUX_TRIGGER_EXTI10 RG_CHXCFG_TID(17U) /*!< trigger input is EXTI10 */ +#define DMAMUX_TRIGGER_EXTI11 RG_CHXCFG_TID(18U) /*!< trigger input is EXTI11 */ +#define DMAMUX_TRIGGER_EXTI12 RG_CHXCFG_TID(19U) /*!< trigger input is EXTI12 */ +#define DMAMUX_TRIGGER_EXTI13 RG_CHXCFG_TID(20U) /*!< trigger input is EXTI13 */ +#define DMAMUX_TRIGGER_EXTI14 RG_CHXCFG_TID(21U) /*!< trigger input is EXTI14 */ +#define DMAMUX_TRIGGER_EXTI15 RG_CHXCFG_TID(22U) /*!< trigger input is EXTI15 */ +#define DMAMUX_TRIGGER_RTC_WAKEUP RG_CHXCFG_TID(23U) /*!< trigger input is wakeup*/ +#define DMAMUX_TRIGGER_CMP0_OUTPUT RG_CHXCFG_TID(24U) /*!< trigger input is CMP0 output */ +#define DMAMUX_TRIGGER_CMP1_OUTPUT RG_CHXCFG_TID(25U) /*!< trigger input is CMP1 output */ +#define DMAMUX_TRIGGER_I2C0_WAKEUP RG_CHXCFG_TID(26U) /*!< trigger input is I2C0 wakeup */ +#define DMAMUX_TRIGGER_I2C1_WAKEUP RG_CHXCFG_TID(27U) /*!< trigger input is I2C1 wakeup */ +#define DMAMUX_TRIGGER_I2C2_WAKEUP RG_CHXCFG_TID(28U) /*!< trigger input is I2C2 wakeup */ +#define DMAMUX_TRIGGER_I2C3_WAKEUP RG_CHXCFG_TID(29U) /*!< trigger input is I2C3 wakeup */ +#define DMAMUX_TRIGGER_I2C0_INT_EVENT RG_CHXCFG_TID(30U) /*!< trigger input is I2C0 interrupt event */ +#define DMAMUX_TRIGGER_I2C1_INT_EVENT RG_CHXCFG_TID(31U) /*!< trigger input is I2C1 interrupt event */ +#define DMAMUX_TRIGGER_I2C2_INT_EVENT RG_CHXCFG_TID(32U) /*!< trigger input is I2C2 interrupt event */ +#define DMAMUX_TRIGGER_I2C3_INT_EVENT RG_CHXCFG_TID(33U) /*!< trigger input is I2C3 interrupt event */ +#define DMAMUX_TRIGGER_ADC2_INT RG_CHXCFG_TID(34U) /*!< trigger input is ADC2 interrupt */ + +/* DMAMUX request generator trigger polarity */ +#define RG_CHXCFG_RGTP(regval) (BITS(17,18) & ((uint32_t)(regval) << 17U)) /*!< DMA request generator trigger polarity */ +#define DMAMUX_GEN_NO_EVENT RG_CHXCFG_RGTP(0U) /*!< no event detection */ +#define DMAMUX_GEN_RISING RG_CHXCFG_RGTP(1U) /*!< rising edge */ +#define DMAMUX_GEN_FALLING RG_CHXCFG_RGTP(2U) /*!< falling edge */ +#define DMAMUX_GEN_RISING_FALLING RG_CHXCFG_RGTP(3U) /*!< rising and falling edges */ + +/* number of DMA requests to be generated */ +#define RG_CHXCFG_NBRG(regval) (BITS(19,23) & ((uint32_t)(regval) << 19U)) /*!< number of DMA requests to be generated */ + +/* DMAMUX request multiplexer channel synchronization input identification */ +#define RM_CHXCFG_SYNCID(regval) (BITS(24,28) & ((uint32_t)(regval) << 24U)) /*!< synchronization input identification */ +#define DMAMUX_SYNC_EVT0_OUT RM_CHXCFG_SYNCID(0U) /*!< synchronization input is Evt0_out */ +#define DMAMUX_SYNC_EVT1_OUT RM_CHXCFG_SYNCID(1U) /*!< synchronization input is Evt1_out */ +#define DMAMUX_SYNC_EVT2_OUT RM_CHXCFG_SYNCID(2U) /*!< synchronization input is Evt2_out */ +#define DMAMUX_SYNC_EVT3_OUT RM_CHXCFG_SYNCID(3U) /*!< synchronization input is Evt3_out */ +#define DMAMUX_SYNC_EVT4_OUT RM_CHXCFG_SYNCID(4U) /*!< synchronization input is Evt4_out */ +#define DMAMUX_SYNC_EVT5_OUT RM_CHXCFG_SYNCID(5U) /*!< synchronization input is Evt5_out */ +#define DMAMUX_SYNC_EVT6_OUT RM_CHXCFG_SYNCID(6U) /*!< synchronization input is Evt6_out */ +#define DMAMUX_SYNC_EXTI0 RM_CHXCFG_SYNCID(7U) /*!< synchronization input is EXTI0 */ +#define DMAMUX_SYNC_EXTI1 RM_CHXCFG_SYNCID(8U) /*!< synchronization input is EXTI1 */ +#define DMAMUX_SYNC_EXTI2 RM_CHXCFG_SYNCID(9U) /*!< synchronization input is EXTI2 */ +#define DMAMUX_SYNC_EXTI3 RM_CHXCFG_SYNCID(10U) /*!< synchronization input is EXTI3 */ +#define DMAMUX_SYNC_EXTI4 RM_CHXCFG_SYNCID(11U) /*!< synchronization input is EXTI4 */ +#define DMAMUX_SYNC_EXTI5 RM_CHXCFG_SYNCID(12U) /*!< synchronization input is EXTI5 */ +#define DMAMUX_SYNC_EXTI6 RM_CHXCFG_SYNCID(13U) /*!< synchronization input is EXTI6 */ +#define DMAMUX_SYNC_EXTI7 RM_CHXCFG_SYNCID(14U) /*!< synchronization input is EXTI7 */ +#define DMAMUX_SYNC_EXTI8 RM_CHXCFG_SYNCID(15U) /*!< synchronization input is EXTI8 */ +#define DMAMUX_SYNC_EXTI9 RM_CHXCFG_SYNCID(16U) /*!< synchronization input is EXTI9 */ +#define DMAMUX_SYNC_EXTI10 RM_CHXCFG_SYNCID(17U) /*!< synchronization input is EXTI10 */ +#define DMAMUX_SYNC_EXTI11 RM_CHXCFG_SYNCID(18U) /*!< synchronization input is EXTI11 */ +#define DMAMUX_SYNC_EXTI12 RM_CHXCFG_SYNCID(19U) /*!< synchronization input is EXTI12 */ +#define DMAMUX_SYNC_EXTI13 RM_CHXCFG_SYNCID(20U) /*!< synchronization input is EXTI13 */ +#define DMAMUX_SYNC_EXTI14 RM_CHXCFG_SYNCID(21U) /*!< synchronization input is EXTI14 */ +#define DMAMUX_SYNC_EXTI15 RM_CHXCFG_SYNCID(22U) /*!< synchronization input is EXTI15 */ +#define DMAMUX_SYNC_RTC_WAKEUP RM_CHXCFG_SYNCID(23U) /*!< synchronization input is RTC wakeup */ +#define DMAMUX_SYNC_CMP0_OUTPUT RM_CHXCFG_SYNCID(24U) /*!< synchronization input is CMP0 output */ +#define DMAMUX_SYNC_I2C0_WAKEUP RM_CHXCFG_SYNCID(25U) /*!< synchronization input is I2C0 wakeup */ +#define DMAMUX_SYNC_I2C1_WAKEUP RM_CHXCFG_SYNCID(26U) /*!< synchronization input is I2C1 wakeup */ +#define DMAMUX_SYNC_I2C2_WAKEUP RM_CHXCFG_SYNCID(27U) /*!< synchronization input is I2C2 wakeup */ +#define DMAMUX_SYNC_I2C3_WAKEUP RM_CHXCFG_SYNCID(28U) /*!< synchronization input is I2C3 wakeup */ + +/* DMAMUX request multiplexer synchronization input polarity */ +#define RM_CHXCFG_SYNCP(regval) (BITS(17,18) & ((uint32_t)(regval) << 17U)) /*!< synchronization input polarity */ +#define DMAMUX_SYNC_NO_EVENT RM_CHXCFG_SYNCP(0U) /*!< no event detection */ +#define DMAMUX_SYNC_RISING RM_CHXCFG_SYNCP(1U) /*!< rising edge */ +#define DMAMUX_SYNC_FALLING RM_CHXCFG_SYNCP(2U) /*!< falling edge */ +#define DMAMUX_SYNC_RISING_FALLING RM_CHXCFG_SYNCP(3U) /*!< rising and falling edges */ + +/* number of DMA requests to forward */ +#define RM_CHXCFG_NBR(regval) (BITS(19,23) & ((uint32_t)(regval) << 19U)) /*!< number of DMA requests to forward */ + +/* function declarations */ +/* DMA deinitialization and initialization functions */ +/* deinitialize DMA registers of a channel */ +void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx); +/* initialize the DMA single data mode parameters structure with the default values */ +void dma_single_data_para_struct_init(dma_single_data_parameter_struct *init_struct); +/* initialize the DMA multi data mode parameters structure with the default values */ +void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct *init_struct); +/* initialize DMA single data mode */ +void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_single_data_parameter_struct *init_struct); +/* initialize DMA multi data mode */ +void dma_multi_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_multi_data_parameter_struct *init_struct); + +/* DMA configuration functions */ +/* configure DMA peripheral base address */ +void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address); +/* configure DMA memory base address */ +void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t memory_flag, uint32_t address); +/* configure the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number); +/* get the number of remaining data to be transferred by the DMA */ +uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority); +/* configure transfer burst beats of memory */ +void dma_memory_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mbeat); +/* configure transfer burst beats of peripheral */ +void dma_periph_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pbeat); +/* configure transfer data size of memory */ +void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t msize); +/* configure transfer data size of peripheral */ +void dma_periph_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t psize); +/* configure next address increasement algorithm of memory */ +void dma_memory_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm); +/* configure next address increasement algorithm of peripheral */ +void dma_peripheral_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm); +/* enable DMA circulation mode */ +void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t direction); +/* configure DMA switch buffer mode */ +void dma_switch_buffer_mode_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t memory1_addr, uint32_t memory_select); +/* get DMA using memory */ +uint32_t dma_using_memory_get(uint32_t dma_periph, dma_channel_enum channelx); +/* enable DMA switch buffer mode */ +void dma_switch_buffer_mode_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable DMA switch buffer mode */ +void dma_switch_buffer_mode_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* get DMA FIFO status */ +uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx); + +/* interrupt & flag functions */ +/* get DMA flag */ +FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* clear DMA flag */ +void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); +/* disable DMA interrupt */ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); +/* get DMA interrupt flag */ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag); +/* clear DMA interrupt flag */ +void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag); + +/* DMAMUX functions */ +/* DMAMUX request multiplexer functions */ +/* initialize the parameters of DMAMUX synchronization mode structure with the default values */ +void dmamux_sync_struct_para_init(dmamux_sync_parameter_struct *init_struct); +/* initialize DMAMUX request multiplexer channel synchronization mode */ +void dmamux_synchronization_init(dmamux_multiplexer_channel_enum channelx, dmamux_sync_parameter_struct *init_struct); +/* enable synchronization mode */ +void dmamux_synchronization_enable(dmamux_multiplexer_channel_enum channelx); +/* disable synchronization mode */ +void dmamux_synchronization_disable(dmamux_multiplexer_channel_enum channelx); +/* enable event generation */ +void dmamux_event_generation_enable(dmamux_multiplexer_channel_enum channelx); +/* disable event generation */ +void dmamux_event_generation_disable(dmamux_multiplexer_channel_enum channelx); + +/* DMAMUX request generator functions */ +/* initialize the parameters of DMAMUX request generator structure with the default values */ +void dmamux_gen_struct_para_init(dmamux_gen_parameter_struct *init_struct); +/* initialize DMAMUX request generator channel */ +void dmamux_request_generator_init(dmamux_generator_channel_enum channelx, dmamux_gen_parameter_struct *init_struct); +/* enable DMAMUX request generator channel */ +void dmamux_request_generator_channel_enable(dmamux_generator_channel_enum channelx); +/* disable DMAMUX request generator channel */ +void dmamux_request_generator_channel_disable(dmamux_generator_channel_enum channelx); + +/* DMAMUX configuration functions */ +/* configure synchronization input polarity */ +void dmamux_synchronization_polarity_config(dmamux_multiplexer_channel_enum channelx, uint32_t polarity); +/* configure number of DMA requests to forward */ +void dmamux_request_forward_number_config(dmamux_multiplexer_channel_enum channelx, uint32_t number); +/* configure synchronization input identification */ +void dmamux_sync_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id); +/* configure multiplexer input identification */ +void dmamux_request_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id); +/* configure trigger input polarity */ +void dmamux_trigger_polarity_config(dmamux_generator_channel_enum channelx, uint32_t polarity); +/* configure number of DMA requests to be generated */ +void dmamux_request_generate_number_config(dmamux_generator_channel_enum channelx, uint32_t number); +/* configure trigger input identification */ +void dmamux_trigger_id_config(dmamux_generator_channel_enum channelx, uint32_t id); + +/* interrupt & flag functions */ +/* get DMAMUX flag */ +FlagStatus dmamux_flag_get(dmamux_flag_enum flag); +/* clear DMAMUX flag */ +void dmamux_flag_clear(dmamux_flag_enum flag); +/* enable DMAMUX interrupt */ +void dmamux_interrupt_enable(dmamux_interrupt_enum interrupt); +/* disable DMAMUX interrupt */ +void dmamux_interrupt_disable(dmamux_interrupt_enum interrupt); +/* get DMAMUX interrupt flag */ +FlagStatus dmamux_interrupt_flag_get(dmamux_interrupt_flag_enum int_flag); +/* clear DMAMUX interrupt flag */ +void dmamux_interrupt_flag_clear(dmamux_interrupt_flag_enum int_flag); + +#endif /* GD32H7XX_DMA_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_edout.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_edout.h new file mode 100644 index 0000000000..6bef38feed --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_edout.h @@ -0,0 +1,110 @@ +/*! + \file gd32h7xx_edout.c + \brief definitions for the EDOUT + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_EDOUT_H +#define GD32H7XX_EDOUT_H + +#include "gd32h7xx.h" + +/* EDOUT definition */ +#define EDOUT EDOUT_BASE /*!< EDOUT base address */ + +/* registers definitions */ +#define EDOUT_CTL REG32((EDOUT) + 0x00000000U) /*!< EDOUT control register */ +#define EDOUT_ENABLE REG32((EDOUT) + 0x00000004U) /*!< EDOUT enable register */ +#define EDOUT_LOC REG32((EDOUT) + 0x00000008U) /*!< EDOUT location register */ +#define EDOUT_OCNT REG32((EDOUT) + 0x0000000CU) /*!< EDOUT output counter register */ +#define EDOUT_LCNT REG32((EDOUT) + 0x00000010U) /*!< EDOUT location counter register */ +#define EDOUT_ZCR REG32((EDOUT) + 0x00000014U) /*!< EDOUT Z-phase configure register */ + +/* bits definitions */ +/* EDOUT_CTL */ +#define EDOUT_CTL_POL BIT(0) /*!< active polarity of the B-phase output signal selection */ + +/* EDOUT_ENABLE */ +#define EDOUT_ENABLE_EDOUTEN BIT(0) /*!< EDOUT enable bit */ + +/* EDOUT_LOC */ +#define EDOUT_LOC_LOCMAX BITS(0,15) /*!< maximum location value for one rotation */ + +/* EDOUT_OCNT */ +#define EDOUT_OCNT_EDGC BITS(0,15) /*!< number of edges of the A-phase and the B-phase signal for the next update period */ +#define EDOUT_OCNT_PDC BITS(16,31) /*!< phase difference between the A-phase and the B-phase signal for the next update period */ + +/* EDOUT_LCNT */ +#define EDOUT_LCNT_LOCCNT BITS(0,15) /*!< current location value */ + +/* EDOUT_ZCR */ +#define EDOUT_ZCR_ZOSP BITS(0,15) /*!< Z-phase output start location */ +#define EDOUT_ZCR_ZOWH BITS(16,23) /*!< Z-phase output width */ +#define EDOUT_ZCR_ZOMD BIT(24) /*!< Z-phase output mode */ + +/* constants definitions */ +/* EDOUT_CTL */ +#define EDOUT_POL_POSITIVE ((uint32_t)0x00000000U) /*!< active polarity is positive */ +#define EDOUT_POL_NEGATIVE EDOUT_CTL_POL /*!< active polarity is negative */ + +/* EDOUT_ENABLE */ +#define EDOUT_STATE_DISABLE ((uint32_t)0x00000000U) /*!< disable EDOUT */ +#define EDOUT_STATE_ENABLE EDOUT_ENABLE_EDOUTEN /*!< enable EDOUT */ + +/* EDOUT_ZCR */ +#define EDOUT_Z_OUTPUT_MODE0 ((uint32_t)0x00000000U) /*!< Z-phase output according to the current location */ +#define EDOUT_Z_OUTPUT_MODE1 EDOUT_ZCR_ZOMD /*!< Z-phase output according to the number of edges */ + +/* function declarations */ +/* deinitialize EDOUT */ +void edout_deinit(void); +/* initialize EDOUT */ +void edout_init(uint32_t pol, uint32_t max_loc, uint32_t cur_loc); +/* enable EDOUT */ +void edout_enable(void); +/* disable EDOUT */ +void edout_disable(void); +/* set B-phase active polarity */ +void edout_polarity_config(uint32_t pol); +/* set the maximum location value for one rotation */ +void edout_max_location_value_config(uint32_t max_loc); +/* update the output counter, used to set the phase difference and the number of edges for the next update period */ +void edout_output_counter_update(int16_t num_edges, uint16_t phase_diff); +/* set the current location value */ +void edout_current_location_config(uint32_t cur_loc); +/* get the current location value */ +uint16_t edout_current_location_get(void); +/* configure Z-phase output mode */ +void edout_z_output_mode_config(uint32_t mode); +/* configure Z-phase output start location and width */ +void edout_z_output_start_loc_and_width_config(uint32_t start_loc, uint32_t width); + +#endif /* GD32H7XX_EDOUT_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_efuse.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_efuse.h new file mode 100644 index 0000000000..5792ae6c43 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_efuse.h @@ -0,0 +1,259 @@ +/*! + \file gd32h7xx_efuse.h + \brief definitions for the EFUSE + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_EFUSE_H +#define GD32H7XX_EFUSE_H + +#include "gd32h7xx.h" + +/* EFUSE definitions */ +#define EFUSE EFUSE_BASE /*!< EFUSE base address */ + +/* registers definitions */ +#define EFUSE_CTL REG32(EFUSE + 0x00000000U) /*!< EFUSE control register */ +#define EFUSE_ADDR REG32(EFUSE + 0x00000004U) /*!< EFUSE address register */ +#define EFUSE_STAT REG32(EFUSE + 0x0000000CU) /*!< EFUSE status register */ +#define EFUSE_STATC REG32(EFUSE + 0x00000010U) /*!< EFUSE status clear register */ +#define EFUSE_USER_CTL REG32(EFUSE + 0x00000014U) /*!< EFUSE user control register */ +#define EFUSE_MCU_RSV REG32(EFUSE + 0x00000018U) /*!< EFUSE MCU reserved register */ +#define EFUSE_DP0 REG32(EFUSE + 0x0000001CU) /*!< EFUSE debug password register 0 */ +#define EFUSE_DP1 REG32(EFUSE + 0x00000020U) /*!< EFUSE debug password register 1 */ +#define EFUSE_AES_KEY0 REG32(EFUSE + 0x00000024U) /*!< EFUSE firmware AES key register 0 */ +#define EFUSE_AES_KEY1 REG32(EFUSE + 0x00000028U) /*!< EFUSE firmware AES key register 1 */ +#define EFUSE_AES_KEY2 REG32(EFUSE + 0x0000002CU) /*!< EFUSE firmware AES key register 2 */ +#define EFUSE_AES_KEY3 REG32(EFUSE + 0x00000030U) /*!< EFUSE firmware AES key register3 */ +#define EFUSE_USER_DATA0 REG32(EFUSE + 0x00000034U) /*!< EFUSE user data register 0 */ +#define EFUSE_USER_DATA1 REG32(EFUSE + 0x00000038U) /*!< EFUSE user data register 1 */ +#define EFUSE_USER_DATA2 REG32(EFUSE + 0x0000003CU) /*!< EFUSE user data register 2 */ +#define EFUSE_USER_DATA3 REG32(EFUSE + 0x00000040U) /*!< EFUSE user data register 3 */ + +/* bits definitions */ +/* EFUSE_CTL */ +#define EFUSE_CTL_EFSTR BIT(0) /*!< start EFUSE operation */ +#define EFUSE_CTL_EFRW BIT(1) /*!< selection of EFUSE operation */ +#define EFUSE_CTL_MPVEN BIT(15) /*!< enable bit for program-voltage monitoring function */ +#define EFUSE_CTL_IAERRIE BIT(16) /*!< enable bit for illegal access error interrupt */ +#define EFUSE_CTL_PGIE BIT(17) /*!< enable bit for program complete interrupt */ +#define EFUSE_CTL_RDIE BIT(18) /*!< enable bit for read complete interrupt */ +#define EFUSE_CTL_PVIE BIT(19) /*!< enable bit for program voltage setting error interrupt */ +#define EFUSE_CTL_AES_KEY_CRC BITS(24,31) /*!< 8-bits CRC calculation result value of AES key bits */ + +/* EFUSE_ADDR */ +#define EFUSE_ADDR_EFADDR BITS(0,9) /*!< read or write EFUSE data start address */ +#define EFUSE_ADDR_EFSIZE BITS(10,14) /*!< read or write EFUSE data size */ + +/* EFUSE_STAT */ +#define EFUSE_STAT_IAERRIF BIT(0) /*!< illegal access error flag */ +#define EFUSE_STAT_PGIF BIT(1) /*!< program complete flag */ +#define EFUSE_STAT_RDIF BIT(2) /*!< read complete flag */ +#define EFUSE_STAT_PVIF BIT(3) /*!< program voltage setting error flag */ +#define EFUSE_STAT_LDO_RDY BIT(4) /*!< EFUSE LDO ready signal */ + +/* EFUSE_STATC */ +#define EFUSE_STATC_IAERRIC BIT(0) /*!< clear bit for illegal access error interrupt */ +#define EFUSE_STATC_PGIC BIT(1) /*!< clear bit for program complete interrupt flag */ +#define EFUSE_STATC_RDIC BIT(2) /*!< clear bit for read complete interrupt flag */ +#define EFUSE_STATC_PVIC BIT(3) /*!< clear bit for program voltage setting error interrupt flag */ + +/* EFUSE_USER_CTL */ +#define EFUSE_USER_CTL_DPLK BIT(0) /*!< EFUSE_DP register lock bit */ +#define EFUSE_USER_CTL_SCRLK BIT(1) /*!< secure-access area start/end address lock bit */ +#define EFUSE_USER_CTL_UCLK BIT(2) /*!< low 16 bits of EFUSE_USER_CTL register lock bit */ +#define EFUSE_USER_CTL_AESEN BIT(3) /*!< lock EFUSE_AES_KEY register and enable AES decrypt function */ +#define EFUSE_USER_CTL_UDLK BIT(4) /*!< EFUSE_USER_DATA register lock bit */ +#define EFUSE_USER_CTL_NDBG BITS(8,9) /*!< debug mode setting bit */ +#define EFUSE_USER_CTL_JTAGNSW BIT(10) /*!< debugger select bit */ +#define EFUSE_USER_CTL_SPC_L BIT(11) /*!< low security protection */ +#define EFUSE_USER_CTL_SPC_H BIT(12) /*!< high security protection */ +#define EFUSE_USER_CTL_SCR BIT(13) /*!< secure access mode enable bit */ +#define EFUSE_USER_CTL_ESPI_START_MODE BITS(14,15) /*!< external SPI start mode */ +#define EFUSE_USER_CTL_SCR_AREA_START BITS(16,23) /*!< secure-access area start address */ +#define EFUSE_USER_CTL_SCR_AREA_END BITS(24,31) /*!< secure-access area end address */ + +/* EFUSE_MCU_RSV */ +#define EFUSE_MCU_RSV_AESNCAU BIT(0) /*!< AES key available for CAU */ +#define EFUSE_MCU_RSV_DISLFI BIT(6) /*!< disable bit for licensed firmware install (LFI) */ +#define EFUSE_MCU_RSV_VFIMG BIT(7) /*!< enable bit for verify firmware image */ +#define EFUSE_MCU_RSV_MCURSVLK BIT(8) /*!< lock bit for low 16 bits of EFUSE_MCU_RSV register */ +#define EFUSE_MCU_RSV_DCRPLK BIT(9) /*!< lock bit for DCRP area start/end address */ +#define EFUSE_MCU_RSV_MCU_RSV BITS(10,15) /*!< MCU reserved value */ +#define EFUSE_MCU_RSV_DCRP_AREA_START BITS(16,23) /*!< DCRP area start address */ +#define EFUSE_MCU_RSV_DCRP_AREA_END BITS(24,31) /*!< DCRP area end address */ + +/* EFUSE_DP */ +#define EFUSE_DP_DP BITS(0,31) /*!< EFUSE Debug password value */ + +/* EFUSE_AES_KEY */ +#define EFUSE_AES_KEY_AESKEY BITS(0,31) /*!< EFUSE AES key value */ + +/* EFUSE_USER_DATA */ +#define EFUSE_USER_DATA_USERDATA BITS(0,31) /*!< EFUSE USER_DATA value */ + +/* constants definitions */ + +/* define the EFUSE bit position and its register index offset */ +#define EFUSE_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define EFUSE_REG_VAL(offset) (REG32(EFUSE + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define EFUSE_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define EFUSE_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define EFUSE_REG_VAL2(offset) (REG32(EFUSE + ((uint32_t)(offset) >> 22))) +#define EFUSE_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define EFUSE_CTL_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define EFUSE_STAT_REG_OFFSET ((uint32_t)0x0000000CU) /*!< STAT register offset */ +#define EFUSE_STATC_REG_OFFSET ((uint32_t)0x00000010U) /*!< STATC register offset */ + +/* EFUSE interrupt flags */ +typedef enum { + EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR = EFUSE_REGIDX_BIT2(EFUSE_CTL_REG_OFFSET, 16U, EFUSE_STAT_REG_OFFSET, 0U), /*!< illegal access error interrupt flag */ + EFUSE_INT_FLAG_PROGRAM_COMPLETE = EFUSE_REGIDX_BIT2(EFUSE_CTL_REG_OFFSET, 17U, EFUSE_STAT_REG_OFFSET, 1U), /*!< programming operation completion interrupt flag */ + EFUSE_INT_FLAG_READ_COMPLETE = EFUSE_REGIDX_BIT2(EFUSE_CTL_REG_OFFSET, 18U, EFUSE_STAT_REG_OFFSET, 2U), /*!< read operation completion interrupt flag */ + EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR = EFUSE_REGIDX_BIT2(EFUSE_CTL_REG_OFFSET, 19U, EFUSE_STAT_REG_OFFSET, 3U), /*!< program voltage setting error flag */ +} efuse_interrupt_flag_enum; + +/* EFUSE flag */ +#define EFUSE_FLAG_LDO_READY EFUSE_STAT_LDO_RDY /*!< EFUSE LDO ready signal flag */ +#define EFUSE_FLAG_ILLEGAL_ACCESS_ERR EFUSE_STAT_IAERRIF /*!< illegal access error flag */ +#define EFUSE_FLAG_PROGRAM_COMPLETE EFUSE_STAT_PGIF /*!< programming operation completion flag */ +#define EFUSE_FLAG_READ_COMPLETE EFUSE_STAT_RDIF /*!< read operation completion flag */ +#define EFUSE_FLAG_PROGRAM_VOLTAGE_ERR EFUSE_STAT_PVIF /*!< program voltage setting error flag */ + +/* EFUSE flag clear */ +#define EFUSE_FLAG_ILLEGAL_ACCESS_ERR_CLR EFUSE_STATC_IAERRIC /*!< clear illegal access error flag */ +#define EFUSE_FLAG_PROGRAM_COMPLETE_CLR EFUSE_STATC_PGIC /*!< clear programming operation completion flag */ +#define EFUSE_FLAG_READ_COMPLETE_CLR EFUSE_STATC_RDIC /*!< clear read operation completion flag */ +#define EFUSE_FLAG_PROGRAM_VOLTAGE_ERR_CLR EFUSE_STATC_PVIC /*!< clear program voltage setting error interrupt flag */ + +/* EFUSE interrupt enable */ +#define EFUSE_INT_ILLEGAL_ACCESS_ERR EFUSE_CTL_IAERRIE /*!< illegal access error interrupt enable */ +#define EFUSE_INT_PROGRAM_COMPLETE EFUSE_CTL_PGIE /*!< programming operation completion interrupt enable */ +#define EFUSE_INT_READ_COMPLETE EFUSE_CTL_RDIE /*!< read operation completion interrupt enable */ +#define EFUSE_INT_PROGRAM_VOLTAGE_ERR EFUSE_CTL_PVIE /*!< program voltage setting error interrupt enable */ + +/* EFUSE interrupt flag clear */ +#define EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR_CLR EFUSE_STATC_IAERRIC /*!< clear illegal access error interrupt flag */ +#define EFUSE_INT_FLAG_PROGRAM_COMPLETE_CLR EFUSE_STATC_PGIC /*!< clear programming operation completion interrupt flag */ +#define EFUSE_INT_FLAG_READ_COMPLETE_CLR EFUSE_STATC_RDIC /*!< clear read operation completion interrupt flag */ +#define EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR_CLR EFUSE_STATC_PVIC /*!< clear program voltage setting error interrupt flag */ + +/* EFUSE system parameter size enum, in byte unit */ +typedef enum { + USER_CTL_SIZE = 4U, /*!< user control parameter size */ + MCU_RESERVED_SIZE = 4U, /*!< MCU reserved parameter size */ + DP_SIZE = 8U, /*!< debug password parameter size */ + AES_KEY_SIZE = 16U, /*!< AES key parameter size */ + USER_DATA_SIZE = 16U, /*!< user data parameter size */ +} efuse_system_para_size_enum; + +/* EFUSE system parameter index */ +typedef enum { + USER_CTL_IDX = 0U, /*!< index of user control parameter */ + MCU_RESERVED_IDX = 1U, /*!< index of MCU reserved parameter */ + DP_IDX = 2U, /*!< index of debug password parameter */ + AES_KEY_IDX = 3U, /*!< index of AES key parameter */ + USER_DATA_IDX = 4U, /*!< index of user data parameter */ +} efuse_system_para_index_enum; + +/* EFUSE state */ +typedef enum { + EFUSE_READY = 0U, /*!< operation has been completed */ + EFUSE_BUSY, /*!< operation is in progress */ + EFUSE_IAERR, /*!< illegal access error */ + EFUSE_PVERR, /*!< program voltage setting error */ + EFUSE_TOERR, /*!< timeout error */ +} efuse_state_enum; + +/* EFADDR of EFUSE system parameters */ +#define USER_CTL_EFADDR ((uint32_t)0x00000000U) /*!< user control parameter start address */ +#define MCU_RESERVED_EFADDR ((uint32_t)0x00000020U) /*!< MCU reserved parameter start address */ +#define DP_EFADDR ((uint32_t)0x00000040U) /*!< debug password parameter start address */ +#define AES_KEY_EFADDR ((uint32_t)0x00000080U) /*!< AES key parameter start address */ +#define USER_DATA_EFADDR ((uint32_t)0x00000100U) /*!< user data parameter start address */ +#define MAX_EFADDR ((uint32_t)0x0000017FU) /*!< max efuse address */ +#define EFUSE_PARA_CNT ((uint32_t)0x00000005U) /*!< the count of system parameters in EFUSE */ + +/* EFUSE parameters' register address */ +#define EFUSE_USER_CTL_REG_ADDR (EFUSE + 0x00000014U) /*!< user control register address */ +#define EFUSE_MCU_RSV_REG_ADDR (EFUSE + 0x00000018U) /*!< MCU reserved register address */ +#define EFUSE_DP_REG_ADDR (EFUSE + 0x0000001CU) /*!< debug password register address */ +#define EFUSE_AES_KEY_REG_ADDR (EFUSE + 0x00000024U) /*!< AES key register address */ +#define EFUSE_USER_DATA_REG_ADDR (EFUSE + 0x00000034U) /*!< user data register address */ + +/* function declarations */ +/* EFUSE operation functions */ + +/* read system parameters from EFUSE macro to registers */ +ErrStatus efuse_read(uint32_t ef_addr, uint32_t size, uint32_t buf[]); +/* program register values to EFUSE macro system parameters */ +ErrStatus efuse_write(uint32_t ef_addr, uint32_t size, uint8_t *buf); +/* program all user control parameters */ +ErrStatus efuse_user_control_write(uint8_t *buf); +/* program all MCU reserved parameters */ +ErrStatus efuse_mcu_reserved_write(uint8_t *buf); +/* program all debug password parameters */ +ErrStatus efuse_dp_write(uint8_t *buf); +/* program all AES key parameters */ +ErrStatus efuse_aes_key_write(uint8_t *buf); +/* program all user data parameters */ +ErrStatus efuse_user_data_write(uint8_t *buf); + +/* FMC universal functions */ +/* get 8-bits CRC calculation result value of AES key */ +uint8_t efuse_aes_key_crc_get(void); +/* enable monitor program voltage function */ +void efuse_monitor_program_voltage_enable(void); +/* disable monitor program voltage function */ +void efuse_monitor_program_voltage_disable(void); +/* get monitor program voltage function */ +FlagStatus efuse_monitor_program_voltage_get(void); +/* get ldo ready signal */ +FlagStatus efuse_ldo_ready_get(void); + +/* flag and interrupt functions */ +/* check EFUSE flag is set or not */ +FlagStatus efuse_flag_get(uint32_t flag); +/* clear EFUSE pending flag */ +void efuse_flag_clear(uint32_t flag); +/* enable EFUSE interrupt */ +void efuse_interrupt_enable(uint32_t interrupt); +/* disable EFUSE interrupt */ +void efuse_interrupt_disable(uint32_t interrupt); +/* check EFUSE interrupt flag is set or not */ +FlagStatus efuse_interrupt_flag_get(uint32_t int_flag); +/* clear EFUSE pending interrupt flag */ +void efuse_interrupt_flag_clear(uint32_t int_flag); + +#endif /* GD32H7XX_EFUSE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_enet.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_enet.h new file mode 100644 index 0000000000..4de279ca6c --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_enet.h @@ -0,0 +1,1677 @@ +/*! + \file gd32h7xx_enet.h + \brief definitions for the ENET + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_ENET_H +#define GD32H7XX_ENET_H + +#include "gd32h7xx.h" + +/* ENET definitions */ +#define ENET0 ENET_BASE +#define ENET1 (ENET_BASE + 0x00002000U) + +/* registers definitions */ +#define ENET_MAC_CFG(enetx) REG32((enetx) + 0x00000000U) /*!< ethernet MAC configuration register */ +#define ENET_MAC_FRMF(enetx) REG32((enetx) + 0x00000004U) /*!< ethernet MAC frame filter register */ +#define ENET_MAC_HLH(enetx) REG32((enetx) + 0x00000008U) /*!< ethernet MAC hash list high register */ +#define ENET_MAC_HLL(enetx) REG32((enetx) + 0x0000000CU) /*!< ethernet MAC hash list low register */ +#define ENET_MAC_PHY_CTL(enetx) REG32((enetx) + 0x00000010U) /*!< ethernet MAC PHY control register */ +#define ENET_MAC_PHY_DATA(enetx) REG32((enetx) + 0x00000014U) /*!< ethernet MAC PHY data register */ +#define ENET_MAC_FCTL(enetx) REG32((enetx) + 0x00000018U) /*!< ethernet MAC flow control register */ +#define ENET_MAC_VLT(enetx) REG32((enetx) + 0x0000001CU) /*!< ethernet MAC VLAN tag register */ +#define ENET_MAC_RWFF(enetx) REG32((enetx) + 0x00000028U) /*!< ethernet MAC remote wakeup frame filter register */ +#define ENET_MAC_WUM(enetx) REG32((enetx) + 0x0000002CU) /*!< ethernet MAC wakeup management register */ +#define ENET_MAC_DBG(enetx) REG32((enetx) + 0x00000034U) /*!< ethernet MAC debug register */ +#define ENET_MAC_INTF(enetx) REG32((enetx) + 0x00000038U) /*!< ethernet MAC interrupt flag register */ +#define ENET_MAC_INTMSK(enetx) REG32((enetx) + 0x0000003CU) /*!< ethernet MAC interrupt mask register */ +#define ENET_MAC_ADDR0H(enetx) REG32((enetx) + 0x00000040U) /*!< ethernet MAC address 0 high register */ +#define ENET_MAC_ADDR0L(enetx) REG32((enetx) + 0x00000044U) /*!< ethernet MAC address 0 low register */ +#define ENET_MAC_ADDR1H(enetx) REG32((enetx) + 0x00000048U) /*!< ethernet MAC address 1 high register */ +#define ENET_MAC_ADDR1L(enetx) REG32((enetx) + 0x0000004CU) /*!< ethernet MAC address 1 low register */ +#define ENET_MAC_ADDT2H(enetx) REG32((enetx) + 0x00000050U) /*!< ethernet MAC address 2 high register */ +#define ENET_MAC_ADDR2L(enetx) REG32((enetx) + 0x00000054U) /*!< ethernet MAC address 2 low register */ +#define ENET_MAC_ADDR3H(enetx) REG32((enetx) + 0x00000058U) /*!< ethernet MAC address 3 high register */ +#define ENET_MAC_ADDR3L(enetx) REG32((enetx) + 0x0000005CU) /*!< ethernet MAC address 3 low register */ +#define ENET_MAC_FCTH(enetx) REG32((enetx) + 0x00001080U) /*!< ethernet MAC flow control threshold register */ +#define ENET_MSC_CTL(enetx) REG32((enetx) + 0x00000100U) /*!< ethernet MSC control register */ +#define ENET_MSC_RINTF(enetx) REG32((enetx) + 0x00000104U) /*!< ethernet MSC receive interrupt flag register */ +#define ENET_MSC_TINTF(enetx) REG32((enetx) + 0x00000108U) /*!< ethernet MSC transmit interrupt flag register */ +#define ENET_MSC_RINTMSK(enetx) REG32((enetx) + 0x0000010CU) /*!< ethernet MSC receive interrupt mask register */ +#define ENET_MSC_TINTMSK(enetx) REG32((enetx) + 0x00000110U) /*!< ethernet MSC transmit interrupt mask register */ +#define ENET_MSC_SCCNT(enetx) REG32((enetx) + 0x0000014CU) /*!< ethernet MSC transmitted good frames after a single collision counter register */ +#define ENET_MSC_MSCCNT(enetx) REG32((enetx) + 0x00000150U) /*!< ethernet MSC transmitted good frames after more than a single collision counter register */ +#define ENET_MSC_TGFCNT(enetx) REG32((enetx) + 0x00000168U) /*!< ethernet MSC transmitted good frames counter register */ +#define ENET_MSC_RFCECNT(enetx) REG32((enetx) + 0x00000194U) /*!< ethernet MSC received frames with CRC error counter register */ +#define ENET_MSC_RFAECNT(enetx) REG32((enetx) + 0x00000198U) /*!< ethernet MSC received frames with alignment error counter register */ +#define ENET_MSC_RGUFCNT(enetx) REG32((enetx) + 0x000001C4U) /*!< ethernet MSC received good unicast frames counter register */ +#define ENET_PTP_TSCTL(enetx) REG32((enetx) + 0x00000700U) /*!< ethernet PTP time stamp control register */ +#define ENET_PTP_SSINC(enetx) REG32((enetx) + 0x00000704U) /*!< ethernet PTP subsecond increment register */ +#define ENET_PTP_TSH(enetx) REG32((enetx) + 0x00000708U) /*!< ethernet PTP time stamp high register */ +#define ENET_PTP_TSL(enetx) REG32((enetx) + 0x0000070CU) /*!< ethernet PTP time stamp low register */ +#define ENET_PTP_TSUH(enetx) REG32((enetx) + 0x00000710U) /*!< ethernet PTP time stamp update high register */ +#define ENET_PTP_TSUL(enetx) REG32((enetx) + 0x00000714U) /*!< ethernet PTP time stamp update low register */ +#define ENET_PTP_TSADDEND(enetx) REG32((enetx) + 0x00000718U) /*!< ethernet PTP time stamp addend register */ +#define ENET_PTP_ETH(enetx) REG32((enetx) + 0x0000071CU) /*!< ethernet PTP expected time high register */ +#define ENET_PTP_ETL(enetx) REG32((enetx) + 0x00000720U) /*!< ethernet PTP expected time low register */ +#define ENET_PTP_TSF(enetx) REG32((enetx) + 0x00000728U) /*!< ethernet PTP time stamp flag register */ +#define ENET_PTP_PPSCTL(enetx) REG32((enetx) + 0x0000072CU) /*!< ethernet PTP PPS control register */ +#define ENET_DMA_BCTL(enetx) REG32((enetx) + 0x00001000U) /*!< ethernet DMA bus control register */ +#define ENET_DMA_TPEN(enetx) REG32((enetx) + 0x00001004U) /*!< ethernet DMA transmit poll enable register */ +#define ENET_DMA_RPEN(enetx) REG32((enetx) + 0x00001008U) /*!< ethernet DMA receive poll enable register */ +#define ENET_DMA_RDTADDR(enetx) REG32((enetx) + 0x0000100CU) /*!< ethernet DMA receive descriptor table address register */ +#define ENET_DMA_TDTADDR(enetx) REG32((enetx) + 0x00001010U) /*!< ethernet DMA transmit descriptor table address register */ +#define ENET_DMA_STAT(enetx) REG32((enetx) + 0x00001014U) /*!< ethernet DMA status register */ +#define ENET_DMA_CTL(enetx) REG32((enetx) + 0x00001018U) /*!< ethernet DMA control register */ +#define ENET_DMA_INTEN(enetx) REG32((enetx) + 0x0000101CU) /*!< ethernet DMA interrupt enable register */ +#define ENET_DMA_MFBOCNT(enetx) REG32((enetx) + 0x00001020U) /*!< ethernet DMA missed frame and buffer overflow counter register */ +#define ENET_DMA_RSWDC(enetx) REG32((enetx) + 0x00001024U) /*!< ethernet DMA receive state watchdog counter register */ +#define ENET_DMA_CTDADDR(enetx) REG32((enetx) + 0x00001048U) /*!< ethernet DMA current transmit descriptor address register */ +#define ENET_DMA_CRDADDR(enetx) REG32((enetx) + 0x0000104CU) /*!< ethernet DMA current receive descriptor address register */ +#define ENET_DMA_CTBADDR(enetx) REG32((enetx) + 0x00001050U) /*!< ethernet DMA current transmit buffer address register */ +#define ENET_DMA_CRBADDR(enetx) REG32((enetx) + 0x00001054U) /*!< ethernet DMA current receive buffer address register */ + +/* bits definitions */ +/* ENET_MAC_CFG */ +#define ENET_MAC_CFG_REN BIT(2) /*!< receiver enable */ +#define ENET_MAC_CFG_TEN BIT(3) /*!< transmitter enable */ +#define ENET_MAC_CFG_DFC BIT(4) /*!< defferal check */ +#define ENET_MAC_CFG_BOL BITS(5,6) /*!< back-off limit */ +#define ENET_MAC_CFG_APCD BIT(7) /*!< automatic pad/CRC drop */ +#define ENET_MAC_CFG_RTD BIT(9) /*!< retry disable */ +#define ENET_MAC_CFG_IPFCO BIT(10) /*!< IP frame checksum offload */ +#define ENET_MAC_CFG_DPM BIT(11) /*!< duplex mode */ +#define ENET_MAC_CFG_LBM BIT(12) /*!< loopback mode */ +#define ENET_MAC_CFG_ROD BIT(13) /*!< receive own disable */ +#define ENET_MAC_CFG_SPD BIT(14) /*!< fast eneternet speed */ +#define ENET_MAC_CFG_CSD BIT(16) /*!< carrier sense disable */ +#define ENET_MAC_CFG_IGBS BITS(17,19) /*!< inter-frame gap bit selection */ +#define ENET_MAC_CFG_JBD BIT(22) /*!< jabber disable */ +#define ENET_MAC_CFG_WDD BIT(23) /*!< watchdog disable */ +#define ENET_MAC_CFG_TFCD BIT(25) /*!< type frame CRC dropping */ + +/* ENET_MAC_FRMF */ +#define ENET_MAC_FRMF_PM BIT(0) /*!< promiscuous mode */ +#define ENET_MAC_FRMF_HUF BIT(1) /*!< hash unicast filter */ +#define ENET_MAC_FRMF_HMF BIT(2) /*!< hash multicast filter */ +#define ENET_MAC_FRMF_DAIFLT BIT(3) /*!< destination address inverse filtering enable */ +#define ENET_MAC_FRMF_MFD BIT(4) /*!< multicast filter disable */ +#define ENET_MAC_FRMF_BFRMD BIT(5) /*!< broadcast frame disable */ +#define ENET_MAC_FRMF_PCFRM BITS(6,7) /*!< pass control frames */ +#define ENET_MAC_FRMF_SAIFLT BIT(8) /*!< source address inverse filtering */ +#define ENET_MAC_FRMF_SAFLT BIT(9) /*!< source address filter */ +#define ENET_MAC_FRMF_HPFLT BIT(10) /*!< hash or perfect filter */ +#define ENET_MAC_FRMF_FAR BIT(31) /*!< frames all receive */ + +/* ENET_MAC_HLH */ +#define ENET_MAC_HLH_HLH BITS(0,31) /*!< hash list high */ + +/* ENET_MAC_HLL */ +#define ENET_MAC_HLL_HLL BITS(0,31) /*!< hash list low */ + +/* ENET_MAC_PHY_CTL */ +#define ENET_MAC_PHY_CTL_PB BIT(0) /*!< PHY busy */ +#define ENET_MAC_PHY_CTL_PW BIT(1) /*!< PHY write */ +#define ENET_MAC_PHY_CTL_CLR BITS(2,4) /*!< clock range */ +#define ENET_MAC_PHY_CTL_PR BITS(6,10) /*!< PHY register */ +#define ENET_MAC_PHY_CTL_PA BITS(11,15) /*!< PHY address */ + +/* ENET_MAC_PHY_DATA */ +#define ENET_MAC_PHY_DATA_PD BITS(0,15) /*!< PHY data */ + +/* ENET_MAC_FCTL */ +#define ENET_MAC_FCTL_FLCBBKPA BIT(0) /*!< flow control busy(in full duplex mode)/backpressure activate(in half duplex mode) */ +#define ENET_MAC_FCTL_TFCEN BIT(1) /*!< transmit flow control enable */ +#define ENET_MAC_FCTL_RFCEN BIT(2) /*!< receive flow control enable */ +#define ENET_MAC_FCTL_UPFDT BIT(3) /*!< unicast pause frame detect */ +#define ENET_MAC_FCTL_PLTS BITS(4,5) /*!< pause low threshold */ +#define ENET_MAC_FCTL_DZQP BIT(7) /*!< disable zero-quanta pause */ +#define ENET_MAC_FCTL_PTM BITS(16,31) /*!< pause time */ + +/* ENET_MAC_VLT */ +#define ENET_MAC_VLT_VLTI BITS(0,15) /*!< VLAN tag identifier(for receive frames) */ +#define ENET_MAC_VLT_VLTC BIT(16) /*!< 12-bit VLAN tag comparison */ + +/* ENET_MAC_RWFF */ +#define ENET_MAC_RWFF_DATA BITS(0,31) /*!< wakeup frame filter register data */ + +/* ENET_MAC_WUM */ +#define ENET_MAC_WUM_PWD BIT(0) /*!< power down */ +#define ENET_MAC_WUM_MPEN BIT(1) /*!< magic packet enable */ +#define ENET_MAC_WUM_WFEN BIT(2) /*!< wakeup frame enable */ +#define ENET_MAC_WUM_MPKR BIT(5) /*!< magic packet received */ +#define ENET_MAC_WUM_WUFR BIT(6) /*!< wakeup frame received */ +#define ENET_MAC_WUM_GU BIT(9) /*!< global unicast */ +#define ENET_MAC_WUM_WUFFRPR BIT(31) /*!< wakeup frame filter register pointer reset */ + +/* ENET_MAC_DBG */ +#define ENET_MAC_DBG_MRNI BIT(0) /*!< MAC receive state not idle */ +#define ENET_MAC_DBG_RXAFS BITS(1,2) /*!< Rx asynchronous FIFO status */ +#define ENET_MAC_DBG_RXFW BIT(4) /*!< RxFIFO is writing */ +#define ENET_MAC_DBG_RXFRS BITS(5,6) /*!< RxFIFO read operation status */ +#define ENET_MAC_DBG_RXFS BITS(8,9) /*!< RxFIFO state */ +#define ENET_MAC_DBG_MTNI BIT(16) /*!< MAC transmit state not idle */ +#define ENET_MAC_DBG_SOMT BITS(17,18) /*!< status of mac transmitter */ +#define ENET_MAC_DBG_PCS BIT(19) /*!< pause condition status */ +#define ENET_MAC_DBG_TXFRS BITS(20,21) /*!< TxFIFO read operation status */ +#define ENET_MAC_DBG_TXFW BIT(22) /*!< TxFIFO is writing */ +#define ENET_MAC_DBG_TXFNE BIT(24) /*!< TxFIFO not empty flag */ +#define ENET_MAC_DBG_TXFF BIT(25) /*!< TxFIFO full flag */ + +/* ENET_MAC_INTF */ +#define ENET_MAC_INTF_WUM BIT(3) /*!< WUM status */ +#define ENET_MAC_INTF_MSC BIT(4) /*!< MSC status */ +#define ENET_MAC_INTF_MSCR BIT(5) /*!< MSC receive status */ +#define ENET_MAC_INTF_MSCT BIT(6) /*!< MSC transmit status */ +#define ENET_MAC_INTF_TMST BIT(9) /*!< timestamp trigger status */ + +/* ENET_MAC_INTMSK */ +#define ENET_MAC_INTMSK_WUMIM BIT(3) /*!< WUM interrupt mask */ +#define ENET_MAC_INTMSK_TMSTIM BIT(9) /*!< timestamp trigger interrupt mask */ + +/* ENET_MAC_ADDR0H */ +#define ENET_MAC_ADDR0H_ADDR0H BITS(0,15) /*!< MAC address0 high */ +#define ENET_MAC_ADDR0H_MO BIT(31) /*!< always read 1 and must be kept */ + +/* ENET_MAC_ADDR0L */ +#define ENET_MAC_ADDR0L_ADDR0L BITS(0,31) /*!< MAC address0 low */ + +/* ENET_MAC_ADDR1H */ +#define ENET_MAC_ADDR1H_ADDR1H BITS(0,15) /*!< MAC address1 high */ +#define ENET_MAC_ADDR1H_MB BITS(24,29) /*!< mask byte */ +#define ENET_MAC_ADDR1H_SAF BIT(30) /*!< source address filter */ +#define ENET_MAC_ADDR1H_AFE BIT(31) /*!< address filter enable */ + +/* ENET_MAC_ADDR1L */ +#define ENET_MAC_ADDR1L_ADDR1L BITS(0,31) /*!< MAC address1 low */ + +/* ENET_MAC_ADDR2H */ +#define ENET_MAC_ADDR2H_ADDR2H BITS(0,15) /*!< MAC address2 high */ +#define ENET_MAC_ADDR2H_MB BITS(24,29) /*!< mask byte */ +#define ENET_MAC_ADDR2H_SAF BIT(30) /*!< source address filter */ +#define ENET_MAC_ADDR2H_AFE BIT(31) /*!< address filter enable */ + +/* ENET_MAC_ADDR2L */ +#define ENET_MAC_ADDR2L_ADDR2L BITS(0,31) /*!< MAC address2 low */ + +/* ENET_MAC_ADDR3H */ +#define ENET_MAC_ADDR3H_ADDR3H BITS(0,15) /*!< MAC address3 high */ +#define ENET_MAC_ADDR3H_MB BITS(24,29) /*!< mask byte */ +#define ENET_MAC_ADDR3H_SAF BIT(30) /*!< source address filter */ +#define ENET_MAC_ADDR3H_AFE BIT(31) /*!< address filter enable */ + +/* ENET_MAC_ADDR3L */ +#define ENET_MAC_ADDR3L_ADDR3L BITS(0,31) /*!< MAC address3 low */ + +/* ENET_MAC_FCTH */ +#define ENET_MAC_FCTH_RFA BITS(0,2) /*!< threshold of active flow control */ +#define ENET_MAC_FCTH_RFD BITS(4,6) /*!< threshold of deactive flow control */ + +/* ENET_MSC_CTL */ +#define ENET_MSC_CTL_CTR BIT(0) /*!< counter reset */ +#define ENET_MSC_CTL_CTSR BIT(1) /*!< counter stop rollover */ +#define ENET_MSC_CTL_RTOR BIT(2) /*!< reset on read */ +#define ENET_MSC_CTL_MCFZ BIT(3) /*!< MSC counter freeze */ +#define ENET_MSC_CTL_PMC BIT(4) /*!< preset MSC counter */ +#define ENET_MSC_CTL_AFHPM BIT(5) /*!< almost full or half preset mode */ + +/* ENET_MSC_RINTF */ +#define ENET_MSC_RINTF_RFCE BIT(5) /*!< received frames CRC error */ +#define ENET_MSC_RINTF_RFAE BIT(6) /*!< received frames alignment error */ +#define ENET_MSC_RINTF_RGUF BIT(17) /*!< receive good unicast frames */ + +/* ENET_MSC_TINTF */ +#define ENET_MSC_TINTF_TGFSC BIT(14) /*!< transmitted good frames single collision */ +#define ENET_MSC_TINTF_TGFMSC BIT(15) /*!< transmitted good frames more single collision */ +#define ENET_MSC_TINTF_TGF BIT(21) /*!< transmitted good frames */ + +/* ENET_MSC_RINTMSK */ +#define ENET_MSC_RINTMSK_RFCEIM BIT(5) /*!< received frame CRC error interrupt mask */ +#define ENET_MSC_RINTMSK_RFAEIM BIT(6) /*!< received frames alignment error interrupt mask */ +#define ENET_MSC_RINTMSK_RGUFIM BIT(17) /*!< received good unicast frames interrupt mask */ + +/* ENET_MSC_TINTMSK */ +#define ENET_MSC_TINTMSK_TGFSCIM BIT(14) /*!< transmitted good frames single collision interrupt mask */ +#define ENET_MSC_TINTMSK_TGFMSCIM BIT(15) /*!< transmitted good frames more single collision interrupt mask */ +#define ENET_MSC_TINTMSK_TGFIM BIT(21) /*!< transmitted good frames interrupt mask */ + +/* ENET_MSC_SCCNT */ +#define ENET_MSC_SCCNT_SCC BITS(0,31) /*!< transmitted good frames single collision counter */ + +/* ENET_MSC_MSCCNT */ +#define ENET_MSC_MSCCNT_MSCC BITS(0,31) /*!< transmitted good frames more one single collision counter */ + +/* ENET_MSC_TGFCNT */ +#define ENET_MSC_TGFCNT_TGF BITS(0,31) /*!< transmitted good frames counter */ + +/* ENET_MSC_RFCECNT */ +#define ENET_MSC_RFCECNT_RFCER BITS(0,31) /*!< received frames with CRC error counter */ + +/* ENET_MSC_RFAECNT */ +#define ENET_MSC_RFAECNT_RFAER BITS(0,31) /*!< received frames alignment error counter */ + +/* ENET_MSC_RGUFCNT */ +#define ENET_MSC_RGUFCNT_RGUF BITS(0,31) /*!< received good unicast frames counter */ + +/* ENET_PTP_TSCTL */ +#define ENET_PTP_TSCTL_TMSEN BIT(0) /*!< timestamp enable */ +#define ENET_PTP_TSCTL_TMSFCU BIT(1) /*!< timestamp fine or coarse update */ +#define ENET_PTP_TSCTL_TMSSTI BIT(2) /*!< timestamp system time initialize */ +#define ENET_PTP_TSCTL_TMSSTU BIT(3) /*!< timestamp system time update */ +#define ENET_PTP_TSCTL_TMSITEN BIT(4) /*!< timestamp interrupt trigger enable */ +#define ENET_PTP_TSCTL_TMSARU BIT(5) /*!< timestamp addend register update */ +#define ENET_PTP_TSCTL_ARFSEN BIT(8) /*!< all received frames snapshot enable */ +#define ENET_PTP_TSCTL_SCROM BIT(9) /*!< subsecond counter rollover mode */ +#define ENET_PTP_TSCTL_PFSV BIT(10) /*!< PTP frame snooping version */ +#define ENET_PTP_TSCTL_ESEN BIT(11) /*!< received Ethernet snapshot enable */ +#define ENET_PTP_TSCTL_IP6SEN BIT(12) /*!< received IPv6 snapshot enable */ +#define ENET_PTP_TSCTL_IP4SEN BIT(13) /*!< received IPv4 snapshot enable */ +#define ENET_PTP_TSCTL_ETMSEN BIT(14) /*!< received event type message snapshot enable */ +#define ENET_PTP_TSCTL_MNMSEN BIT(15) /*!< received master node message snapshot enable */ +#define ENET_PTP_TSCTL_CKNT BITS(16,17) /*!< clock node type for time stamp */ +#define ENET_PTP_TSCTL_MAFEN BIT(18) /*!< MAC address filter enable for PTP frame */ + +/* ENET_PTP_SSINC */ +#define ENET_PTP_SSINC_STMSSI BITS(0,7) /*!< system time subsecond increment */ + +/* ENET_PTP_TSH */ +#define ENET_PTP_TSH_STMS BITS(0,31) /*!< system time second */ + +/* ENET_PTP_TSL */ +#define ENET_PTP_TSL_STMSS BITS(0,30) /*!< system time subseconds */ +#define ENET_PTP_TSL_STS BIT(31) /*!< system time sign */ + +/* ENET_PTP_TSUH */ +#define ENET_PTP_TSUH_TMSUS BITS(0,31) /*!< timestamp update seconds */ + +/* ENET_PTP_TSUL */ +#define ENET_PTP_TSUL_TMSUSS BITS(0,30) /*!< timestamp update subseconds */ +#define ENET_PTP_TSUL_TMSUPNS BIT(31) /*!< timestamp update positive or negative sign */ + +/* ENET_PTP_TSADDEND */ +#define ENET_PTP_TSADDEND_TMSA BITS(0,31) /*!< timestamp addend */ + +/* ENET_PTP_ETH */ +#define ENET_PTP_ETH_ETSH BITS(0,31) /*!< expected time high */ + +/* ENET_PTP_ETL */ +#define ENET_PTP_ETL_ETSL BITS(0,31) /*!< expected time low */ + +/* ENET_PTP_TSF */ +#define ENET_PTP_TSF_TSSCO BIT(0) /*!< timestamp second counter overflow */ +#define ENET_PTP_TSF_TTM BIT(1) /*!< target time match */ + +/* ENET_PTP_PPSCTL */ +#define ENET_PTP_PPSCTL_PPSOFC BITS(0,3) /*!< PPS output frequency configure */ + +/* ENET_DMA_BCTL */ +#define ENET_DMA_BCTL_SWR BIT(0) /*!< software reset */ +#define ENET_DMA_BCTL_DAB BIT(1) /*!< DMA arbitration */ +#define ENET_DMA_BCTL_DPSL BITS(2,6) /*!< descriptor skip length */ +#define ENET_DMA_BCTL_DFM BIT(7) /*!< descriptor format mode */ +#define ENET_DMA_BCTL_PGBL BITS(8,13) /*!< programmable burst length */ +#define ENET_DMA_BCTL_RTPR BITS(14,15) /*!< RxDMA and TxDMA transfer priority ratio */ +#define ENET_DMA_BCTL_FB BIT(16) /*!< fixed Burst */ +#define ENET_DMA_BCTL_RXDP BITS(17,22) /*!< RxDMA PGBL */ +#define ENET_DMA_BCTL_UIP BIT(23) /*!< use independent PGBL */ +#define ENET_DMA_BCTL_FPBL BIT(24) /*!< four times PGBL mode */ +#define ENET_DMA_BCTL_AA BIT(25) /*!< address-aligned */ +#define ENET_DMA_BCTL_MB BIT(26) /*!< mixed burst */ + +/* ENET_DMA_TPEN */ +#define ENET_DMA_TPEN_TPE BITS(0,31) /*!< transmit poll enable */ + +/* ENET_DMA_RPEN */ +#define ENET_DMA_RPEN_RPE BITS(0,31) /*!< receive poll enable */ + +/* ENET_DMA_RDTADDR */ +#define ENET_DMA_RDTADDR_SRT BITS(0,31) /*!< start address of receive table */ + +/* ENET_DMA_TDTADDR */ +#define ENET_DMA_TDTADDR_STT BITS(0,31) /*!< start address of transmit table */ + +/* ENET_DMA_STAT */ +#define ENET_DMA_STAT_TS BIT(0) /*!< transmit status */ +#define ENET_DMA_STAT_TPS BIT(1) /*!< transmit process stopped status */ +#define ENET_DMA_STAT_TBU BIT(2) /*!< transmit buffer unavailable status */ +#define ENET_DMA_STAT_TJT BIT(3) /*!< transmit jabber timeout status */ +#define ENET_DMA_STAT_RO BIT(4) /*!< receive overflow status */ +#define ENET_DMA_STAT_TU BIT(5) /*!< transmit underflow status */ +#define ENET_DMA_STAT_RS BIT(6) /*!< receive status */ +#define ENET_DMA_STAT_RBU BIT(7) /*!< receive buffer unavailable status */ +#define ENET_DMA_STAT_RPS BIT(8) /*!< receive process stopped status */ +#define ENET_DMA_STAT_RWT BIT(9) /*!< receive watchdog timeout status */ +#define ENET_DMA_STAT_ET BIT(10) /*!< early transmit status */ +#define ENET_DMA_STAT_FBE BIT(13) /*!< fatal bus error status */ +#define ENET_DMA_STAT_ER BIT(14) /*!< early receive status */ +#define ENET_DMA_STAT_AI BIT(15) /*!< abnormal interrupt summary */ +#define ENET_DMA_STAT_NI BIT(16) /*!< normal interrupt summary */ +#define ENET_DMA_STAT_RP BITS(17,19) /*!< receive process state */ +#define ENET_DMA_STAT_TP BITS(20,22) /*!< transmit process state */ +#define ENET_DMA_STAT_EB BITS(23,25) /*!< error bits status */ +#define ENET_DMA_STAT_MSC BIT(27) /*!< MSC status */ +#define ENET_DMA_STAT_WUM BIT(28) /*!< WUM status */ +#define ENET_DMA_STAT_TST BIT(29) /*!< timestamp trigger status */ + +/* ENET_DMA_CTL */ +#define ENET_DMA_CTL_SRE BIT(1) /*!< start/stop receive enable */ +#define ENET_DMA_CTL_OSF BIT(2) /*!< operate on second frame */ +#define ENET_DMA_CTL_RTHC BITS(3,4) /*!< receive threshold control */ +#define ENET_DMA_CTL_FUF BIT(6) /*!< forward undersized good frames */ +#define ENET_DMA_CTL_FERF BIT(7) /*!< forward error frames */ +#define ENET_DMA_CTL_STE BIT(13) /*!< start/stop transmission enable */ +#define ENET_DMA_CTL_TTHC BITS(14,16) /*!< transmit threshold control */ +#define ENET_DMA_CTL_FTF BIT(20) /*!< flush transmit FIFO */ +#define ENET_DMA_CTL_TSFD BIT(21) /*!< transmit store-and-forward */ +#define ENET_DMA_CTL_DAFRF BIT(24) /*!< disable flushing of received frames */ +#define ENET_DMA_CTL_RSFD BIT(25) /*!< receive store-and-forward */ +#define ENET_DMA_CTL_DTCERFD BIT(26) /*!< dropping of TCP/IP checksum error frames disable */ + +/* ENET_DMA_INTEN */ +#define ENET_DMA_INTEN_TIE BIT(0) /*!< transmit interrupt enable */ +#define ENET_DMA_INTEN_TPSIE BIT(1) /*!< transmit process stopped interrupt enable */ +#define ENET_DMA_INTEN_TBUIE BIT(2) /*!< transmit buffer unavailable interrupt enable */ +#define ENET_DMA_INTEN_TJTIE BIT(3) /*!< transmit jabber timeout interrupt enable */ +#define ENET_DMA_INTEN_ROIE BIT(4) /*!< receive overflow interrupt enable */ +#define ENET_DMA_INTEN_TUIE BIT(5) /*!< transmit underflow interrupt enable */ +#define ENET_DMA_INTEN_RIE BIT(6) /*!< receive interrupt enable */ +#define ENET_DMA_INTEN_RBUIE BIT(7) /*!< receive buffer unavailable interrupt enable */ +#define ENET_DMA_INTEN_RPSIE BIT(8) /*!< receive process stopped interrupt enable */ +#define ENET_DMA_INTEN_RWTIE BIT(9) /*!< receive watchdog timeout interrupt enable */ +#define ENET_DMA_INTEN_ETIE BIT(10) /*!< early transmit interrupt enable */ +#define ENET_DMA_INTEN_FBEIE BIT(13) /*!< fatal bus error interrupt enable */ +#define ENET_DMA_INTEN_ERIE BIT(14) /*!< early receive interrupt enable */ +#define ENET_DMA_INTEN_AIE BIT(15) /*!< abnormal interrupt summary enable */ +#define ENET_DMA_INTEN_NIE BIT(16) /*!< normal interrupt summary enable */ + +/* ENET_DMA_MFBOCNT */ +#define ENET_DMA_MFBOCNT_MSFC BITS(0,15) /*!< missed frames by the controller */ +#define ENET_DMA_MFBOCNT_MSFA BITS(17,27) /*!< missed frames by the application */ + +/* ENET_DMA_RSWDC */ +#define ENET_DMA_RSWDC_WDCFRS BITS(0,7) /*!< watchdog counter for receive status (RS) */ + +/* ENET_DMA_CTDADDR */ +#define ENET_DMA_CTDADDR_TDAP BITS(0,31) /*!< transmit descriptor address pointer */ + +/* ENET_DMA_CRDADDR */ +#define ENET_DMA_CRDADDR_RDAP BITS(0,31) /*!< receive descriptor address pointer */ + +/* ENET_DMA_CTBADDR */ +#define ENET_DMA_CTBADDR_TBAP BITS(0,31) /*!< transmit buffer address pointer */ + +/* ENET_DMA_CRBADDR */ +#define ENET_DMA_CRBADDR_RBAP BITS(0,31) /*!< receive buffer address pointer */ + +/* ENET DMA Tx descriptor TDES0 */ +#define ENET_TDES0_DB BIT(0) /*!< deferred */ +#define ENET_TDES0_UFE BIT(1) /*!< underflow error */ +#define ENET_TDES0_EXD BIT(2) /*!< excessive deferral */ +#define ENET_TDES0_COCNT BITS(3,6) /*!< collision count */ +#define ENET_TDES0_VFRM BIT(7) /*!< VLAN frame */ +#define ENET_TDES0_ECO BIT(8) /*!< excessive collision */ +#define ENET_TDES0_LCO BIT(9) /*!< late collision */ +#define ENET_TDES0_NCA BIT(10) /*!< no carrier */ +#define ENET_TDES0_LCA BIT(11) /*!< loss of carrier */ +#define ENET_TDES0_IPPE BIT(12) /*!< IP payload error */ +#define ENET_TDES0_FRMF BIT(13) /*!< frame flushed */ +#define ENET_TDES0_JT BIT(14) /*!< jabber timeout */ +#define ENET_TDES0_ES BIT(15) /*!< error summary */ +#define ENET_TDES0_IPHE BIT(16) /*!< IP header error */ +#define ENET_TDES0_TTMSS BIT(17) /*!< transmit timestamp status */ +#define ENET_TDES0_TCHM BIT(20) /*!< the second address chained mode */ +#define ENET_TDES0_TERM BIT(21) /*!< transmit end of ring mode*/ +#define ENET_TDES0_CM BITS(22,23) /*!< checksum mode */ +#define ENET_TDES0_TTSEN BIT(25) /*!< transmit timestamp function enable */ +#define ENET_TDES0_DPAD BIT(26) /*!< disable adding pad */ +#define ENET_TDES0_DCRC BIT(27) /*!< disable CRC */ +#define ENET_TDES0_FSG BIT(28) /*!< first segment */ +#define ENET_TDES0_LSG BIT(29) /*!< last segment */ +#define ENET_TDES0_INTC BIT(30) /*!< interrupt on completion */ +#define ENET_TDES0_DAV BIT(31) /*!< DAV bit */ + +/* ENET DMA Tx descriptor TDES1 */ +#define ENET_TDES1_TB1S BITS(0,12) /*!< transmit buffer 1 size */ +#define ENET_TDES1_TB2S BITS(16,28) /*!< transmit buffer 2 size */ + +/* ENET DMA Tx descriptor TDES2 */ +#define ENET_TDES2_TB1AP BITS(0,31) /*!< transmit buffer 1 address pointer/transmit frame timestamp low 32-bit value */ + +/* ENET DMA Tx descriptor TDES3 */ +#define ENET_TDES3_TB2AP BITS(0,31) /*!< transmit buffer 2 address pointer (or next descriptor address) / transmit frame timestamp high 32-bit value */ + +//#define SELECT_DESCRIPTORS_ENHANCED_MODE + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/* ENET DMA Tx descriptor TDES6 */ +#define ENET_TDES6_TTSL BITS(0,31) /*!< transmit frame timestamp low 32-bit value */ + +/* ENET DMA Tx descriptor TDES7 */ +#define ENET_TDES7_TTSH BITS(0,31) /*!< transmit frame timestamp high 32-bit value */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* ENET DMA Rx descriptor RDES0 */ +#define ENET_RDES0_PCERR BIT(0) /*!< payload checksum error */ +#define ENET_RDES0_EXSV BIT(0) /*!< extended status valid */ +#define ENET_RDES0_CERR BIT(1) /*!< CRC error */ +#define ENET_RDES0_DBERR BIT(2) /*!< dribble bit error */ +#define ENET_RDES0_RERR BIT(3) /*!< receive error */ +#define ENET_RDES0_RWDT BIT(4) /*!< receive watchdog timeout */ +#define ENET_RDES0_FRMT BIT(5) /*!< frame type */ +#define ENET_RDES0_LCO BIT(6) /*!< late collision */ +#define ENET_RDES0_IPHERR BIT(7) /*!< IP frame header error */ +#define ENET_RDES0_TSV BIT(7) /*!< timestamp valid */ +#define ENET_RDES0_LDES BIT(8) /*!< last descriptor */ +#define ENET_RDES0_FDES BIT(9) /*!< first descriptor */ +#define ENET_RDES0_VTAG BIT(10) /*!< VLAN tag */ +#define ENET_RDES0_OERR BIT(11) /*!< overflow Error */ +#define ENET_RDES0_LERR BIT(12) /*!< length error */ +#define ENET_RDES0_SAFF BIT(13) /*!< SA filter fail */ +#define ENET_RDES0_DERR BIT(14) /*!< descriptor error */ +#define ENET_RDES0_ERRS BIT(15) /*!< error summary */ +#define ENET_RDES0_FRML BITS(16,29) /*!< frame length */ +#define ENET_RDES0_DAFF BIT(30) /*!< destination address filter fail */ +#define ENET_RDES0_DAV BIT(31) /*!< descriptor available */ + +/* ENET DMA Rx descriptor RDES1 */ +#define ENET_RDES1_RB1S BITS(0,12) /*!< receive buffer 1 size */ +#define ENET_RDES1_RCHM BIT(14) /*!< receive chained mode for second address */ +#define ENET_RDES1_RERM BIT(15) /*!< receive end of ring mode*/ +#define ENET_RDES1_RB2S BITS(16,28) /*!< receive buffer 2 size */ +#define ENET_RDES1_DINTC BIT(31) /*!< disable interrupt on completion */ + +/* ENET DMA Rx descriptor RDES2 */ +#define ENET_RDES2_RB1AP BITS(0,31) /*!< receive buffer 1 address pointer / receive frame timestamp low 32-bit */ + +/* ENET DMA Rx descriptor RDES3 */ +#define ENET_RDES3_RB2AP BITS(0,31) /*!< receive buffer 2 address pointer (next descriptor address)/receive frame timestamp high 32-bit value */ + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/* ENET DMA Rx descriptor RDES4 */ +#define ENET_RDES4_IPPLDT BITS(0,2) /*!< IP frame payload type */ +#define ENET_RDES4_IPHERR BIT(3) /*!< IP frame header error */ +#define ENET_RDES4_IPPLDERR BIT(4) /*!< IP frame payload error */ +#define ENET_RDES4_IPCKSB BIT(5) /*!< IP frame checksum bypassed */ +#define ENET_RDES4_IPF4 BIT(6) /*!< IP frame in version 4 */ +#define ENET_RDES4_IPF6 BIT(7) /*!< IP frame in version 6 */ +#define ENET_RDES4_PTPMT BITS(8,11) /*!< PTP message type */ +#define ENET_RDES4_PTPOEF BIT(12) /*!< PTP on ethernet frame */ +#define ENET_RDES4_PTPVF BIT(13) /*!< PTP version format */ + +/* ENET DMA Rx descriptor RDES6 */ +#define ENET_RDES6_RTSL BITS(0,31) /*!< receive frame timestamp low 32-bit value */ + +/* ENET DMA Rx descriptor RDES7 */ +#define ENET_RDES7_RTSH BITS(0,31) /*!< receive frame timestamp high 32-bit value */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* constants definitions */ +/* define bit position and its register index offset */ +#define ENET_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6U) | (uint32_t)(bitpos)) +#define ENET_REG_VAL(enetx, periph) (REG32((enetx) + ((uint32_t)(periph) >> 6U))) +#define ENET_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) + +/* ENET clock range judgement */ +#define ENET_RANGE(hclk, n, m) (((hclk) >= (n))&&((hclk) < (m))) + +/* define MAC address configuration and reference address */ +#define ENET_SET_MACADDRH(p) (((uint32_t)(p)[5] << 8U) | (uint32_t)(p)[4]) +#define ENET_SET_MACADDRL(p) (((uint32_t)(p)[3] << 24U) | ((uint32_t)(p)[2] << 16U) | ((uint32_t)(p)[1] << 8U) | (uint32_t)(p)[0]) +#define ENET_ADDRH_BASE(enetx) ((enetx) + 0x40U) +#define ENET_ADDRL_BASE(enetx) ((enetx) + 0x44U) +#define ENET_GET_MACADDR(enetx, offset, n) ((uint8_t)((REG32((ENET_ADDRL_BASE(enetx) + (offset)) - (((n) / 4U) * 4U)) >> (8U * ((n) % 4U))) & 0xFFU)) + +/* register offset */ +#define MAC_FCTL_REG_OFFSET 0x00000018U /*!< MAC flow control register offset */ +#define MAC_WUM_REG_OFFSET 0x0000002CU /*!< MAC wakeup management register offset */ +#define MAC_INTF_REG_OFFSET 0x00000038U /*!< MAC interrupt flag register offset */ +#define MAC_INTMSK_REG_OFFSET 0x0000003CU /*!< MAC interrupt mask register offset */ + +#define MSC_RINTF_REG_OFFSET 0x00000104U /*!< MSC receive interrupt flag register offset */ +#define MSC_TINTF_REG_OFFSET 0x00000108U /*!< MSC transmit interrupt flag register offset */ +#define MSC_RINTMSK_REG_OFFSET 0x0000010CU /*!< MSC receive interrupt mask register offset */ +#define MSC_TINTMSK_REG_OFFSET 0x00000110U /*!< MSC transmit interrupt mask register offset */ +#define MSC_SCCNT_REG_OFFSET 0x0000014CU /*!< MSC transmitted good frames after a single collision counter register offset */ +#define MSC_MSCCNT_REG_OFFSET 0x00000150U /*!< MSC transmitted good frames after more than a single collision counter register offset */ +#define MSC_TGFCNT_REG_OFFSET 0x00000168U /*!< MSC transmitted good frames counter register offset */ +#define MSC_RFCECNT_REG_OFFSET 0x00000194U /*!< MSC received frames with CRC error counter register offset */ +#define MSC_RFAECNT_REG_OFFSET 0x00000198U /*!< MSC received frames with alignment error counter register offset */ +#define MSC_RGUFCNT_REG_OFFSET 0x000001C4U /*!< MSC received good unicast frames counter register offset */ + +#define PTP_TSF_REG_OFFSET 0x00000728U /*!< PTP time stamp flag register offset */ + +#define DMA_STAT_REG_OFFSET 0x00001014U /*!< DMA status register offset */ +#define DMA_INTEN_REG_OFFSET 0x0000101CU /*!< DMA interrupt enable register offset */ +#define DMA_TDTADDR_REG_OFFSET 0x00001010U /*!< DMA transmit descriptor table address register offset */ +#define DMA_CTDADDR_REG_OFFSET 0x00001048U /*!< DMA current transmit descriptor address register */ +#define DMA_CTBADDR_REG_OFFSET 0x00001050U /*!< DMA current transmit buffer address register */ +#define DMA_RDTADDR_REG_OFFSET 0x0000100CU /*!< DMA receive descriptor table address register */ +#define DMA_CRDADDR_REG_OFFSET 0x0000104CU /*!< DMA current receive descriptor address register */ +#define DMA_CRBADDR_REG_OFFSET 0x00001054U /*!< DMA current receive buffer address register */ + +/* ENET status flag get */ +typedef enum { + /* ENET_MAC_WUM register */ + ENET_MAC_FLAG_MPKR = ENET_REGIDX_BIT(MAC_WUM_REG_OFFSET, 5U), /*!< magic packet received flag */ + ENET_MAC_FLAG_WUFR = ENET_REGIDX_BIT(MAC_WUM_REG_OFFSET, 6U), /*!< wakeup frame received flag */ + /* ENET_MAC_FCTL register */ + ENET_MAC_FLAG_FLOWCONTROL = ENET_REGIDX_BIT(MAC_FCTL_REG_OFFSET, 0U), /*!< flow control status flag */ + /* ENET_MAC_INTF register */ + ENET_MAC_FLAG_WUM = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 3U), /*!< WUM status flag */ + ENET_MAC_FLAG_MSC = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 4U), /*!< MSC status flag */ + ENET_MAC_FLAG_MSCR = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 5U), /*!< MSC receive status flag */ + ENET_MAC_FLAG_MSCT = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 6U), /*!< MSC transmit status flag */ + ENET_MAC_FLAG_TMST = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 9U), /*!< timestamp trigger status flag */ + /* ENET_PTP_TSF register */ + ENET_PTP_FLAG_TSSCO = ENET_REGIDX_BIT(PTP_TSF_REG_OFFSET, 0U), /*!< timestamp second counter overflow flag */ + ENET_PTP_FLAG_TTM = ENET_REGIDX_BIT(PTP_TSF_REG_OFFSET, 1U), /*!< target time match flag */ + /* ENET_MSC_RINTF register */ + ENET_MSC_FLAG_RFCE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 5U), /*!< received frames CRC error flag */ + ENET_MSC_FLAG_RFAE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 6U), /*!< received frames alignment error flag */ + ENET_MSC_FLAG_RGUF = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 17U), /*!< received good unicast frames flag */ + /* ENET_MSC_TINTF register */ + ENET_MSC_FLAG_TGFSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 14U), /*!< transmitted good frames single collision flag */ + ENET_MSC_FLAG_TGFMSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 15U), /*!< transmitted good frames more single collision flag */ + ENET_MSC_FLAG_TGF = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 21U), /*!< transmitted good frames flag */ + /* ENET_DMA_STAT register */ + ENET_DMA_FLAG_TS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_FLAG_TPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_FLAG_TBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_FLAG_TJT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_FLAG_RO = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_FLAG_TU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_FLAG_RS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_FLAG_RBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_FLAG_RPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_FLAG_RWT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_FLAG_ET = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_FLAG_FBE = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_FLAG_ER = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_FLAG_AI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_FLAG_NI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U), /*!< normal interrupt summary flag */ + ENET_DMA_FLAG_EB_DMA_ERROR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 23U), /*!< error during data transfer by RxDMA/TxDMA flag */ + ENET_DMA_FLAG_EB_TRANSFER_ERROR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 24U), /*!< error during write/read transfer flag */ + ENET_DMA_FLAG_EB_ACCESS_ERROR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 25U), /*!< error during data buffer/descriptor access flag */ + ENET_DMA_FLAG_MSC = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 27U), /*!< MSC status flag */ + ENET_DMA_FLAG_WUM = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 28U), /*!< WUM status flag */ + ENET_DMA_FLAG_TST = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 29U) /*!< timestamp trigger status flag */ +} enet_flag_enum; + +/* ENET stutus flag clear */ +typedef enum { + /* ENET_DMA_STAT register */ + ENET_DMA_FLAG_TS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_FLAG_TPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_FLAG_TBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_FLAG_TJT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_FLAG_RO_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_FLAG_TU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_FLAG_RS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_FLAG_RBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_FLAG_RPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_FLAG_RWT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_FLAG_ET_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_FLAG_FBE_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_FLAG_ER_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_FLAG_AI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_FLAG_NI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U) /*!< normal interrupt summary flag */ +} enet_flag_clear_enum; + +/* ENET interrupt enable/disable */ +typedef enum { + /* ENET_MAC_INTMSK register */ + ENET_MAC_INT_WUMIM = ENET_REGIDX_BIT(MAC_INTMSK_REG_OFFSET, 3U), /*!< WUM interrupt mask */ + ENET_MAC_INT_TMSTIM = ENET_REGIDX_BIT(MAC_INTMSK_REG_OFFSET, 9U), /*!< timestamp trigger interrupt mask */ + /* ENET_MSC_RINTMSK register */ + ENET_MSC_INT_RFCEIM = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 5U), /*!< received frame CRC error interrupt mask */ + ENET_MSC_INT_RFAEIM = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 6U), /*!< received frames alignment error interrupt mask */ + ENET_MSC_INT_RGUFIM = ENET_REGIDX_BIT(MSC_RINTMSK_REG_OFFSET, 17U), /*!< received good unicast frames interrupt mask */ + /* ENET_MSC_TINTMSK register */ + ENET_MSC_INT_TGFSCIM = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 14U), /*!< transmitted good frames single collision interrupt mask */ + ENET_MSC_INT_TGFMSCIM = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 15U), /*!< transmitted good frames more single collision interrupt mask */ + ENET_MSC_INT_TGFIM = ENET_REGIDX_BIT(MSC_TINTMSK_REG_OFFSET, 21U), /*!< transmitted good frames interrupt mask */ + /* ENET_DMA_INTEN register */ + ENET_DMA_INT_TIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 0U), /*!< transmit interrupt enable */ + ENET_DMA_INT_TPSIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 1U), /*!< transmit process stopped interrupt enable */ + ENET_DMA_INT_TBUIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 2U), /*!< transmit buffer unavailable interrupt enable */ + ENET_DMA_INT_TJTIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 3U), /*!< transmit jabber timeout interrupt enable */ + ENET_DMA_INT_ROIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 4U), /*!< receive overflow interrupt enable */ + ENET_DMA_INT_TUIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 5U), /*!< transmit underflow interrupt enable */ + ENET_DMA_INT_RIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 6U), /*!< receive interrupt enable */ + ENET_DMA_INT_RBUIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 7U), /*!< receive buffer unavailable interrupt enable */ + ENET_DMA_INT_RPSIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 8U), /*!< receive process stopped interrupt enable */ + ENET_DMA_INT_RWTIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 9U), /*!< receive watchdog timeout interrupt enable */ + ENET_DMA_INT_ETIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 10U), /*!< early transmit interrupt enable */ + ENET_DMA_INT_FBEIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 13U), /*!< fatal bus error interrupt enable */ + ENET_DMA_INT_ERIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 14U), /*!< early receive interrupt enable */ + ENET_DMA_INT_AIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 15U), /*!< abnormal interrupt summary enable */ + ENET_DMA_INT_NIE = ENET_REGIDX_BIT(DMA_INTEN_REG_OFFSET, 16U) /*!< normal interrupt summary enable */ +} enet_int_enum; + +/* ENET interrupt flag get */ +typedef enum { + /* ENET_MAC_INTF register */ + ENET_MAC_INT_FLAG_WUM = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 3U), /*!< WUM status flag */ + ENET_MAC_INT_FLAG_MSC = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 4U), /*!< MSC status flag */ + ENET_MAC_INT_FLAG_MSCR = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 5U), /*!< MSC receive status flag */ + ENET_MAC_INT_FLAG_MSCT = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 6U), /*!< MSC transmit status flag */ + ENET_MAC_INT_FLAG_TMST = ENET_REGIDX_BIT(MAC_INTF_REG_OFFSET, 9U), /*!< timestamp trigger status flag */ + /* ENET_MSC_RINTF register */ + ENET_MSC_INT_FLAG_RFCE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 5U), /*!< received frames CRC error flag */ + ENET_MSC_INT_FLAG_RFAE = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 6U), /*!< received frames alignment error flag */ + ENET_MSC_INT_FLAG_RGUF = ENET_REGIDX_BIT(MSC_RINTF_REG_OFFSET, 17U), /*!< received good unicast frames flag */ + /* ENET_MSC_TINTF register */ + ENET_MSC_INT_FLAG_TGFSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 14U), /*!< transmitted good frames single collision flag */ + ENET_MSC_INT_FLAG_TGFMSC = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 15U), /*!< transmitted good frames more single collision flag */ + ENET_MSC_INT_FLAG_TGF = ENET_REGIDX_BIT(MSC_TINTF_REG_OFFSET, 21U), /*!< transmitted good frames flag */ + /* ENET_DMA_STAT register */ + ENET_DMA_INT_FLAG_TS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_INT_FLAG_TPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_INT_FLAG_TBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_INT_FLAG_TJT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_INT_FLAG_RO = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_INT_FLAG_TU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_INT_FLAG_RS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_INT_FLAG_RBU = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_INT_FLAG_RPS = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_INT_FLAG_RWT = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_INT_FLAG_ET = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_INT_FLAG_FBE = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_INT_FLAG_ER = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_INT_FLAG_AI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_INT_FLAG_NI = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U), /*!< normal interrupt summary flag */ + ENET_DMA_INT_FLAG_MSC = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 27U), /*!< MSC status flag */ + ENET_DMA_INT_FLAG_WUM = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 28U), /*!< WUM status flag */ + ENET_DMA_INT_FLAG_TST = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 29U) /*!< timestamp trigger status flag */ +} enet_int_flag_enum; + +/* ENET interrupt flag clear */ +typedef enum { + /* ENET_DMA_STAT register */ + ENET_DMA_INT_FLAG_TS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 0U), /*!< transmit status flag */ + ENET_DMA_INT_FLAG_TPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 1U), /*!< transmit process stopped status flag */ + ENET_DMA_INT_FLAG_TBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 2U), /*!< transmit buffer unavailable status flag */ + ENET_DMA_INT_FLAG_TJT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 3U), /*!< transmit jabber timeout status flag */ + ENET_DMA_INT_FLAG_RO_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 4U), /*!< receive overflow status flag */ + ENET_DMA_INT_FLAG_TU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 5U), /*!< transmit underflow status flag */ + ENET_DMA_INT_FLAG_RS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 6U), /*!< receive status flag */ + ENET_DMA_INT_FLAG_RBU_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 7U), /*!< receive buffer unavailable status flag */ + ENET_DMA_INT_FLAG_RPS_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 8U), /*!< receive process stopped status flag */ + ENET_DMA_INT_FLAG_RWT_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 9U), /*!< receive watchdog timeout status flag */ + ENET_DMA_INT_FLAG_ET_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 10U), /*!< early transmit status flag */ + ENET_DMA_INT_FLAG_FBE_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 13U), /*!< fatal bus error status flag */ + ENET_DMA_INT_FLAG_ER_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 14U), /*!< early receive status flag */ + ENET_DMA_INT_FLAG_AI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 15U), /*!< abnormal interrupt summary flag */ + ENET_DMA_INT_FLAG_NI_CLR = ENET_REGIDX_BIT(DMA_STAT_REG_OFFSET, 16U) /*!< normal interrupt summary flag */ +} enet_int_flag_clear_enum; + +/* current RX/TX descriptor/buffer/descriptor table address get */ +typedef enum { + ENET_RX_DESC_TABLE = DMA_RDTADDR_REG_OFFSET, /*!< RX descriptor table */ + ENET_RX_CURRENT_DESC = DMA_CRDADDR_REG_OFFSET, /*!< current RX descriptor */ + ENET_RX_CURRENT_BUFFER = DMA_CRBADDR_REG_OFFSET, /*!< current RX buffer */ + ENET_TX_DESC_TABLE = DMA_TDTADDR_REG_OFFSET, /*!< TX descriptor table */ + ENET_TX_CURRENT_DESC = DMA_CTDADDR_REG_OFFSET, /*!< current TX descriptor */ + ENET_TX_CURRENT_BUFFER = DMA_CTBADDR_REG_OFFSET /*!< current TX buffer */ +} enet_desc_reg_enum; + +/* MAC statistics counter get */ +typedef enum { + ENET_MSC_TX_SCCNT = MSC_SCCNT_REG_OFFSET, /*!< MSC transmitted good frames after a single collision counter */ + ENET_MSC_TX_MSCCNT = MSC_MSCCNT_REG_OFFSET, /*!< MSC transmitted good frames after more than a single collision counter */ + ENET_MSC_TX_TGFCNT = MSC_TGFCNT_REG_OFFSET, /*!< MSC transmitted good frames counter */ + ENET_MSC_RX_RFCECNT = MSC_RFCECNT_REG_OFFSET, /*!< MSC received frames with CRC error counter */ + ENET_MSC_RX_RFAECNT = MSC_RFAECNT_REG_OFFSET, /*!< MSC received frames with alignment error counter */ + ENET_MSC_RX_RGUFCNT = MSC_RGUFCNT_REG_OFFSET /*!< MSC received good unicast frames counter */ +} enet_msc_counter_enum; + +/* function option, used for ENET initialization */ +typedef enum { + FORWARD_OPTION = BIT(0), /*!< configure the frame forward related parameters */ + DMABUS_OPTION = BIT(1), /*!< configure the DMA bus mode related parameters */ + DMA_MAXBURST_OPTION = BIT(2), /*!< configure the DMA max burst related parameters */ + DMA_ARBITRATION_OPTION = BIT(3), /*!< configure the DMA arbitration related parameters */ + STORE_OPTION = BIT(4), /*!< configure the store forward mode related parameters */ + DMA_OPTION = BIT(5), /*!< configure the DMA control related parameters */ + VLAN_OPTION = BIT(6), /*!< configure the VLAN tag related parameters */ + FLOWCTL_OPTION = BIT(7), /*!< configure the flow control related parameters */ + HASHH_OPTION = BIT(8), /*!< configure the hash list high 32-bit related parameters */ + HASHL_OPTION = BIT(9), /*!< configure the hash list low 32-bit related parameters */ + FILTER_OPTION = BIT(10), /*!< configure the frame filter control related parameters */ + HALFDUPLEX_OPTION = BIT(11), /*!< configure the halfduplex related parameters */ + TIMER_OPTION = BIT(12), /*!< configure the frame timer related parameters */ + INTERFRAMEGAP_OPTION = BIT(13) /*!< configure the inter frame gap related parameters */ +} enet_option_enum; + +/* phy mode and mac loopback configurations */ +typedef enum { + ENET_AUTO_NEGOTIATION = 0x01U, /*!< PHY auto negotiation */ + ENET_100M_FULLDUPLEX = (ENET_MAC_CFG_SPD | ENET_MAC_CFG_DPM), /*!< 100Mbit/s, full-duplex */ + ENET_100M_HALFDUPLEX = ENET_MAC_CFG_SPD, /*!< 100Mbit/s, half-duplex */ + ENET_10M_FULLDUPLEX = ENET_MAC_CFG_DPM, /*!< 10Mbit/s, full-duplex */ + ENET_10M_HALFDUPLEX = (uint32_t)0x00000000U, /*!< 10Mbit/s, half-duplex */ + ENET_LOOPBACKMODE = (ENET_MAC_CFG_LBM | ENET_MAC_CFG_DPM) /*!< MAC in loopback mode at the MII */ +} enet_mediamode_enum; + +/* IP frame checksum function */ +typedef enum { + ENET_NO_AUTOCHECKSUM = (uint32_t)0x00000000U, /*!< disable IP frame checksum function */ + ENET_AUTOCHECKSUM_DROP_FAILFRAMES = ENET_MAC_CFG_IPFCO, /*!< enable IP frame checksum function */ + ENET_AUTOCHECKSUM_ACCEPT_FAILFRAMES = (ENET_MAC_CFG_IPFCO | ENET_DMA_CTL_DTCERFD) /*!< enable IP frame checksum function, and the received frame + with only payload error but no other errors will not be dropped */ +} enet_chksumconf_enum; + +/* received frame filter function */ +typedef enum { + ENET_PROMISCUOUS_MODE = ENET_MAC_FRMF_PM, /*!< promiscuous mode enabled */ + ENET_RECEIVEALL = (int32_t)ENET_MAC_FRMF_FAR, /*!< all received frame are forwarded to application */ + ENET_BROADCAST_FRAMES_PASS = (uint32_t)0x00000000U, /*!< the address filters pass all received broadcast frames */ + ENET_BROADCAST_FRAMES_DROP = ENET_MAC_FRMF_BFRMD /*!< the address filters filter all incoming broadcast frames */ +} enet_frmrecept_enum; + +/* register group value get */ +typedef enum { + ALL_MAC_REG = 0U, /*!< MAC register group */ + ALL_MSC_REG = 22U, /*!< MSC register group */ + ALL_PTP_REG = 33U, /*!< PTP register group */ + ALL_DMA_REG = 44U /*!< DMA register group */ +} enet_registers_type_enum; + +/* dma direction select */ +typedef enum { + ENET_DMA_TX = ENET_DMA_STAT_TP, /*!< DMA transmit direction */ + ENET_DMA_RX = ENET_DMA_STAT_RP /*!< DMA receive direction */ +} enet_dmadirection_enum; + +/* PHY operation direction select */ +typedef enum { + ENET_PHY_READ = (uint32_t)0x00000000U, /*!< read PHY */ + ENET_PHY_WRITE = ENET_MAC_PHY_CTL_PW /*!< write PHY */ +} enet_phydirection_enum; + +/* register operation direction select */ +typedef enum { + ENET_REG_READ, /*!< read register */ + ENET_REG_WRITE /*!< write register */ +} enet_regdirection_enum; + +/* ENET MAC addresses */ +typedef enum { + ENET_MAC_ADDRESS0 = ((uint32_t)0x00000000U), /*!< MAC address0 */ + ENET_MAC_ADDRESS1 = ((uint32_t)0x00000008U), /*!< MAC address1 */ + ENET_MAC_ADDRESS2 = ((uint32_t)0x00000010U), /*!< MAC address2 */ + ENET_MAC_ADDRESS3 = ((uint32_t)0x00000018U) /*!< MAC address3 */ +} enet_macaddress_enum; + +/* descriptor information */ +typedef enum { + TXDESC_COLLISION_COUNT, /*!< the number of collisions occurred before the frame was transmitted */ + TXDESC_BUFFER_1_ADDR, /*!< transmit frame buffer 1 address */ + RXDESC_FRAME_LENGTH, /*!< the byte length of the received frame that was transferred to the buffer */ + RXDESC_BUFFER_1_SIZE, /*!< receive buffer 1 size */ + RXDESC_BUFFER_2_SIZE, /*!< receive buffer 2 size */ + RXDESC_BUFFER_1_ADDR /*!< receive frame buffer 1 address */ +} enet_descstate_enum; + +/* MSC counters preset mode */ +typedef enum { + ENET_MSC_PRESET_NONE = 0U, /*!< do not preset MSC counter */ + ENET_MSC_PRESET_HALF = ENET_MSC_CTL_PMC, /*!< preset all MSC counters to almost-half(0x7FFF FFF0) value */ + ENET_MSC_PRESET_FULL = ENET_MSC_CTL_PMC | ENET_MSC_CTL_AFHPM /*!< preset all MSC counters to almost-full(0xFFFF FFF0) value */ +} enet_msc_preset_enum; + +/* structure for initialization of the ENET */ +typedef struct { + uint32_t option_enable; /*!< select which function to configure */ + uint32_t forward_frame; /*!< frame forward related parameters */ + uint32_t dmabus_mode; /*!< DMA bus mode related parameters */ + uint32_t dma_maxburst; /*!< DMA max burst related parameters */ + uint32_t dma_arbitration; /*!< DMA Tx and Rx arbitration related parameters */ + uint32_t store_forward_mode; /*!< store forward mode related parameters */ + uint32_t dma_function; /*!< DMA control related parameters */ + uint32_t vlan_config; /*!< VLAN tag related parameters */ + uint32_t flow_control; /*!< flow control related parameters */ + uint32_t hashtable_high; /*!< hash list high 32-bit related parameters */ + uint32_t hashtable_low; /*!< hash list low 32-bit related parameters */ + uint32_t framesfilter_mode; /*!< frame filter control related parameters */ + uint32_t halfduplex_param; /*!< halfduplex related parameters */ + uint32_t timer_config; /*!< frame timer related parameters */ + uint32_t interframegap; /*!< inter frame gap related parameters */ +} enet_initpara_struct; + +/* structure for ENET DMA desciptors */ +typedef struct { + uint32_t status; /*!< status */ + uint32_t control_buffer_size; /*!< control and buffer1, buffer2 lengths */ + uint32_t buffer1_addr; /*!< buffer1 address pointer/timestamp low */ + uint32_t buffer2_next_desc_addr; /*!< buffer2 or next descriptor address pointer/timestamp high */ + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE + uint32_t extended_status; /*!< extended status */ + uint32_t reserved; /*!< reserved */ + uint32_t timestamp_low; /*!< timestamp low */ + uint32_t timestamp_high; /*!< timestamp high */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +} enet_descriptors_struct; + +/* structure of PTP system time */ +typedef struct { + uint32_t second; /*!< second of system time */ + uint32_t nanosecond; /*!< nanosecond of system time */ + uint32_t sign; /*!< sign of system time */ +} enet_ptp_systime_struct; + +/* mac_cfg register value */ +#define MAC_CFG_BOL(regval) (BITS(5,6) & ((uint32_t)(regval) << 5U)) /*!< write value to ENET_MAC_CFG_BOL bit field */ +#define ENET_BACKOFFLIMIT_10 MAC_CFG_BOL(0) /*!< min (n, 10) */ +#define ENET_BACKOFFLIMIT_8 MAC_CFG_BOL(1) /*!< min (n, 8) */ +#define ENET_BACKOFFLIMIT_4 MAC_CFG_BOL(2) /*!< min (n, 4) */ +#define ENET_BACKOFFLIMIT_1 MAC_CFG_BOL(3) /*!< min (n, 1) */ + +#define MAC_CFG_IGBS(regval) (BITS(17,19) & ((uint32_t)(regval) << 17U)) /*!< write value to ENET_MAC_CFG_IGBS bit field */ +#define ENET_INTERFRAMEGAP_96BIT MAC_CFG_IGBS(0) /*!< minimum 96 bit times */ +#define ENET_INTERFRAMEGAP_88BIT MAC_CFG_IGBS(1) /*!< minimum 88 bit times */ +#define ENET_INTERFRAMEGAP_80BIT MAC_CFG_IGBS(2) /*!< minimum 80 bit times */ +#define ENET_INTERFRAMEGAP_72BIT MAC_CFG_IGBS(3) /*!< minimum 72 bit times */ +#define ENET_INTERFRAMEGAP_64BIT MAC_CFG_IGBS(4) /*!< minimum 64 bit times */ +#define ENET_INTERFRAMEGAP_56BIT MAC_CFG_IGBS(5) /*!< minimum 56 bit times */ +#define ENET_INTERFRAMEGAP_48BIT MAC_CFG_IGBS(6) /*!< minimum 48 bit times */ +#define ENET_INTERFRAMEGAP_40BIT MAC_CFG_IGBS(7) /*!< minimum 40 bit times */ + +#define ENET_TYPEFRAME_CRC_DROP_ENABLE ENET_MAC_CFG_TFCD /*!< FCS field(last 4 bytes) of frame will be dropped before forwarding */ +#define ENET_TYPEFRAME_CRC_DROP_DISABLE ((uint32_t)0x00000000U) /*!< FCS field(last 4 bytes) of frame will not be dropped before forwarding */ +#define ENET_TYPEFRAME_CRC_DROP ENET_MAC_CFG_TFCD /*!< the function that FCS field(last 4 bytes) of frame will be dropped before forwarding */ + +#define ENET_WATCHDOG_ENABLE ((uint32_t)0x00000000U) /*!< the MAC allows no more than 2048 bytes of the frame being received */ +#define ENET_WATCHDOG_DISABLE ENET_MAC_CFG_WDD /*!< the MAC disables the watchdog timer on the receiver, and can receive frames of up to 16384 bytes */ + +#define ENET_JABBER_ENABLE ((uint32_t)0x00000000U) /*!< the maximum transmission byte is 2048 */ +#define ENET_JABBER_DISABLE ENET_MAC_CFG_JBD /*!< the maximum transmission byte can be 16384 */ + +#define ENET_CARRIERSENSE_ENABLE ((uint32_t)0x00000000U) /*!< the MAC transmitter generates carrier sense error and aborts the transmission */ +#define ENET_CARRIERSENSE_DISABLE ENET_MAC_CFG_CSD /*!< the MAC transmitter ignores the MII CRS signal during frame transmission in half-duplex mode */ + +#define ENET_SPEEDMODE_10M ((uint32_t)0x00000000U) /*!< 10 Mbit/s */ +#define ENET_SPEEDMODE_100M ENET_MAC_CFG_SPD /*!< 100 Mbit/s */ + +#define ENET_RECEIVEOWN_ENABLE ((uint32_t)0x00000000U) /*!< the MAC receives all packets that are given by the PHY while transmitting */ +#define ENET_RECEIVEOWN_DISABLE ENET_MAC_CFG_ROD /*!< the MAC disables the reception of frames in half-duplex mode */ + +#define ENET_LOOPBACKMODE_ENABLE ENET_MAC_CFG_LBM /*!< the MAC operates in loopback mode at the MII */ +#define ENET_LOOPBACKMODE_DISABLE ((uint32_t)0x00000000U) /*!< the MAC operates in normal mode */ + +#define ENET_MODE_FULLDUPLEX ENET_MAC_CFG_DPM /*!< full-duplex mode enable */ +#define ENET_MODE_HALFDUPLEX ((uint32_t)0x00000000U) /*!< half-duplex mode enable */ + +#define ENET_CHECKSUMOFFLOAD_ENABLE ENET_MAC_CFG_IPFCO /*!< IP frame checksum offload function enabled for received IP frame */ +#define ENET_CHECKSUMOFFLOAD_DISABLE ((uint32_t)0x00000000U) /*!< the checksum offload function in the receiver is disabled */ + +#define ENET_RETRYTRANSMISSION_ENABLE ((uint32_t)0x00000000U) /*!< the MAC attempts retries up to 16 times based on the settings of BOL*/ +#define ENET_RETRYTRANSMISSION_DISABLE ENET_MAC_CFG_RTD /*!< the MAC attempts only 1 transmission */ + +#define ENET_AUTO_PADCRC_DROP_ENABLE ENET_MAC_CFG_APCD /*!< the MAC strips the Pad/FCS field on received frames */ +#define ENET_AUTO_PADCRC_DROP_DISABLE ((uint32_t)0x00000000U) /*!< the MAC forwards all received frames without modify it */ +#define ENET_AUTO_PADCRC_DROP ENET_MAC_CFG_APCD /*!< the function of the MAC strips the Pad/FCS field on received frames */ + +#define ENET_DEFERRALCHECK_ENABLE ENET_MAC_CFG_DFC /*!< the deferral check function is enabled in the MAC */ +#define ENET_DEFERRALCHECK_DISABLE ((uint32_t)0x00000000U) /*!< the deferral check function is disabled */ + +/* mac_frmf register value */ +#define MAC_FRMF_PCFRM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6U)) /*!< write value to ENET_MAC_FRMF_PCFRM bit field */ +#define ENET_PCFRM_PREVENT_ALL MAC_FRMF_PCFRM(0) /*!< MAC prevents all control frames from reaching the application */ +#define ENET_PCFRM_PREVENT_PAUSEFRAME MAC_FRMF_PCFRM(1) /*!< MAC only forwards all other control frames except pause control frame */ +#define ENET_PCFRM_FORWARD_ALL MAC_FRMF_PCFRM(2) /*!< MAC forwards all control frames to application even if they fail the address filter */ +#define ENET_PCFRM_FORWARD_FILTERED MAC_FRMF_PCFRM(3) /*!< MAC forwards control frames that only pass the address filter */ + +#define ENET_RX_FILTER_DISABLE ENET_MAC_FRMF_FAR /*!< all received frame are forwarded to application */ +#define ENET_RX_FILTER_ENABLE ((uint32_t)0x00000000U) /*!< only the frame passed the filter can be forwarded to application */ + +#define ENET_SRC_FILTER_NORMAL_ENABLE ENET_MAC_FRMF_SAFLT /*!< filter source address */ +#define ENET_SRC_FILTER_INVERSE_ENABLE (ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT) /*!< inverse source address filtering result */ +#define ENET_SRC_FILTER_DISABLE ((uint32_t)0x00000000U) /*!< source address function in filter disable */ +#define ENET_SRC_FILTER ENET_MAC_FRMF_SAFLT /*!< filter source address function */ +#define ENET_SRC_FILTER_INVERSE ENET_MAC_FRMF_SAIFLT /*!< inverse source address filtering result function */ + +#define ENET_BROADCASTFRAMES_ENABLE ((uint32_t)0x00000000U) /*!< the address filters pass all received broadcast frames */ +#define ENET_BROADCASTFRAMES_DISABLE ENET_MAC_FRMF_BFRMD /*!< the address filters filter all incoming broadcast frames */ + +#define ENET_DEST_FILTER_INVERSE_ENABLE ENET_MAC_FRMF_DAIFLT /*!< inverse DA filtering result */ +#define ENET_DEST_FILTER_INVERSE_DISABLE ((uint32_t)0x00000000U) /*!< not inverse DA filtering result */ +#define ENET_DEST_FILTER_INVERSE ENET_MAC_FRMF_DAIFLT /*!< inverse DA filtering result function */ + +#define ENET_PROMISCUOUS_ENABLE ENET_MAC_FRMF_PM /*!< promiscuous mode enabled */ +#define ENET_PROMISCUOUS_DISABLE ((uint32_t)0x00000000U) /*!< promiscuous mode disabled */ + +#define ENET_MULTICAST_FILTER_HASH_OR_PERFECT (ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT) /*!< pass multicast frames that match either the perfect or the hash filtering */ +#define ENET_MULTICAST_FILTER_HASH ENET_MAC_FRMF_HMF /*!< pass multicast frames that match the hash filtering */ +#define ENET_MULTICAST_FILTER_PERFECT ((uint32_t)0x00000000U) /*!< pass multicast frames that match the perfect filtering */ +#define ENET_MULTICAST_FILTER_NONE ENET_MAC_FRMF_MFD /*!< all multicast frames are passed */ +#define ENET_MULTICAST_FILTER_PASS ENET_MAC_FRMF_MFD /*!< pass all multicast frames function */ +#define ENET_MULTICAST_FILTER_HASH_MODE ENET_MAC_FRMF_HMF /*!< HASH multicast filter function */ +#define ENET_FILTER_MODE_EITHER ENET_MAC_FRMF_HPFLT /*!< HASH or perfect filter function */ + +#define ENET_UNICAST_FILTER_EITHER (ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_HPFLT) /*!< pass unicast frames that match either the perfect or the hash filtering */ +#define ENET_UNICAST_FILTER_HASH ENET_MAC_FRMF_HUF /*!< pass unicast frames that match the hash filtering */ +#define ENET_UNICAST_FILTER_PERFECT ((uint32_t)0x00000000U) /*!< pass unicast frames that match the perfect filtering */ +#define ENET_UNICAST_FILTER_HASH_MODE ENET_MAC_FRMF_HUF /*!< HASH unicast filter function */ + +/* mac_phy_ctl register value */ +#define MAC_PHY_CTL_CLR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2U)) /*!< write value to ENET_MAC_PHY_CTL_CLR bit field */ +#define ENET_MDC_HCLK_DIV42 MAC_PHY_CTL_CLR(0) /*!< HCLK:60-100 MHz; MDC clock= HCLK/42 */ +#define ENET_MDC_HCLK_DIV62 MAC_PHY_CTL_CLR(1) /*!< HCLK:100-150 MHz; MDC clock= HCLK/62 */ +#define ENET_MDC_HCLK_DIV16 MAC_PHY_CTL_CLR(2) /*!< HCLK:20-35 MHz; MDC clock= HCLK/16 */ +#define ENET_MDC_HCLK_DIV26 MAC_PHY_CTL_CLR(3) /*!< HCLK:35-60 MHz; MDC clock= HCLK/26 */ +#define ENET_MDC_HCLK_DIV102 MAC_PHY_CTL_CLR(4) /*!< HCLK:150-180 MHz; MDC clock= HCLK/102 */ +#define ENET_MDC_HCLK_DIV124 MAC_PHY_CTL_CLR(5) /*!< HCLK:250-300 MHz; MDC clock= HCLK/124 */ +#define ENET_MDC_HCLK_DIV142 MAC_PHY_CTL_CLR(6) /*!< HCLK:300-350 MHz; MDC clock= HCLK/142 */ +#define ENET_MDC_HCLK_DIV162 MAC_PHY_CTL_CLR(7) + +#define MAC_PHY_CTL_PR(regval) (BITS(6,10) & ((uint32_t)(regval) << 6U)) /*!< write value to ENET_MAC_PHY_CTL_PR bit field */ + +#define MAC_PHY_CTL_PA(regval) (BITS(11,15) & ((uint32_t)(regval) << 11U)) /*!< write value to ENET_MAC_PHY_CTL_PA bit field */ + +/* mac_phy_data register value */ +#define MAC_PHY_DATA_PD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_MAC_PHY_DATA_PD bit field */ + +/* mac_fctl register value */ +#define MAC_FCTL_PLTS(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) /*!< write value to ENET_MAC_FCTL_PLTS bit field */ +#define ENET_PAUSETIME_MINUS4 MAC_FCTL_PLTS(0) /*!< pause time minus 4 slot times */ +#define ENET_PAUSETIME_MINUS28 MAC_FCTL_PLTS(1) /*!< pause time minus 28 slot times */ +#define ENET_PAUSETIME_MINUS144 MAC_FCTL_PLTS(2) /*!< pause time minus 144 slot times */ +#define ENET_PAUSETIME_MINUS256 MAC_FCTL_PLTS(3) /*!< pause time minus 256 slot times */ + +#define ENET_ZERO_QUANTA_PAUSE_ENABLE ((uint32_t)0x00000000U) /*!< enable the automatic zero-quanta generation function */ +#define ENET_ZERO_QUANTA_PAUSE_DISABLE ENET_MAC_FCTL_DZQP /*!< disable the automatic zero-quanta generation function */ +#define ENET_ZERO_QUANTA_PAUSE ENET_MAC_FCTL_DZQP /*!< the automatic zero-quanta generation function */ + +#define ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT ENET_MAC_FCTL_UPFDT /*!< besides the unique multicast address, MAC also use the MAC0 address to detect pause frame */ +#define ENET_UNIQUE_PAUSEDETECT ((uint32_t)0x00000000U) /*!< only the unique multicast address for pause frame which is specified in IEEE802.3 can be detected */ + +#define ENET_RX_FLOWCONTROL_ENABLE ENET_MAC_FCTL_RFCEN /*!< enable decoding function for the received pause frame and process it */ +#define ENET_RX_FLOWCONTROL_DISABLE ((uint32_t)0x00000000U) /*!< decode function for pause frame is disabled */ +#define ENET_RX_FLOWCONTROL ENET_MAC_FCTL_RFCEN /*!< decoding function for the received pause frame and process it */ + +#define ENET_TX_FLOWCONTROL_ENABLE ENET_MAC_FCTL_TFCEN /*!< enable the flow control operation in the MAC */ +#define ENET_TX_FLOWCONTROL_DISABLE ((uint32_t)0x00000000U) /*!< disable the flow control operation in the MAC */ +#define ENET_TX_FLOWCONTROL ENET_MAC_FCTL_TFCEN /*!< the flow control operation in the MAC */ + +#define ENET_BACK_PRESSURE_ENABLE ENET_MAC_FCTL_FLCBBKPA /*!< enable the back pressure operation in the MAC */ +#define ENET_BACK_PRESSURE_DISABLE ((uint32_t)0x00000000U) /*!< disable the back pressure operation in the MAC */ +#define ENET_BACK_PRESSURE ENET_MAC_FCTL_FLCBBKPA /*!< the back pressure operation in the MAC */ + +#define MAC_FCTL_PTM(regval) (BITS(16,31) & ((uint32_t)(regval) << 16U)) /*!< write value to ENET_MAC_FCTL_PTM bit field */ +/* mac_vlt register value */ +#define MAC_VLT_VLTI(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_MAC_VLT_VLTI bit field */ + +#define ENET_VLANTAGCOMPARISON_12BIT ENET_MAC_VLT_VLTC /*!< only low 12 bits of the VLAN tag are used for comparison */ +#define ENET_VLANTAGCOMPARISON_16BIT ((uint32_t)0x00000000U) /*!< all 16 bits of the VLAN tag are used for comparison */ + +/* mac_wum register value */ +#define ENET_WUM_FLAG_WUFFRPR ENET_MAC_WUM_WUFFRPR /*!< wakeup frame filter register poniter reset */ +#define ENET_WUM_FLAG_WUFR ENET_MAC_WUM_WUFR /*!< wakeup frame received */ +#define ENET_WUM_FLAG_MPKR ENET_MAC_WUM_MPKR /*!< magic packet received */ +#define ENET_WUM_POWER_DOWN ENET_MAC_WUM_PWD /*!< power down mode */ +#define ENET_WUM_MAGIC_PACKET_FRAME ENET_MAC_WUM_MPEN /*!< enable a wakeup event due to magic packet reception */ +#define ENET_WUM_WAKE_UP_FRAME ENET_MAC_WUM_WFEN /*!< enable a wakeup event due to wakeup frame reception */ +#define ENET_WUM_GLOBAL_UNICAST ENET_MAC_WUM_GU /*!< any received unicast frame passed filter is considered to be a wakeup frame */ + +/* mac_dbg register value */ +#define ENET_MAC_RECEIVER_NOT_IDLE ENET_MAC_DBG_MRNI /*!< MAC receiver is not in idle state */ +#define ENET_RX_ASYNCHRONOUS_FIFO_STATE ENET_MAC_DBG_RXAFS /*!< Rx asynchronous FIFO status */ +#define ENET_RXFIFO_WRITING ENET_MAC_DBG_RXFW /*!< RxFIFO is doing write operation */ +#define ENET_RXFIFO_READ_STATUS ENET_MAC_DBG_RXFRS /*!< RxFIFO read operation status */ +#define ENET_RXFIFO_STATE ENET_MAC_DBG_RXFS /*!< RxFIFO state */ +#define ENET_MAC_TRANSMITTER_NOT_IDLE ENET_MAC_DBG_MTNI /*!< MAC transmitter is not in idle state */ +#define ENET_MAC_TRANSMITTER_STATUS ENET_MAC_DBG_SOMT /*!< status of MAC transmitter */ +#define ENET_PAUSE_CONDITION_STATUS ENET_MAC_DBG_PCS /*!< pause condition status */ +#define ENET_TXFIFO_READ_STATUS ENET_MAC_DBG_TXFRS /*!< TxFIFO read operation status */ +#define ENET_TXFIFO_WRITING ENET_MAC_DBG_TXFW /*!< TxFIFO is doing write operation */ +#define ENET_TXFIFO_NOT_EMPTY ENET_MAC_DBG_TXFNE /*!< TxFIFO is not empty */ +#define ENET_TXFIFO_FULL ENET_MAC_DBG_TXFF /*!< TxFIFO is full */ + +#define GET_MAC_DBG_RXAFS(regval) GET_BITS((regval), 1U, 2U) /*!< get value of ENET_MAC_DBG_RXAFS bit field */ + +#define GET_MAC_DBG_RXFRS(regval) GET_BITS((regval), 5U, 6U) /*!< get value of ENET_MAC_DBG_RXFRS bit field */ + +#define GET_MAC_DBG_RXFS(regval) GET_BITS((regval), 8U, 9U) /*!< get value of ENET_MAC_DBG_RXFS bit field */ + +#define GET_MAC_DBG_SOMT(regval) GET_BITS((regval), 17U, 18U) /*!< get value of ENET_MAC_DBG_SOMT bit field */ + +#define GET_MAC_DBG_TXFRS(regval) GET_BITS((regval), 20U, 21U) /*!< get value of ENET_MAC_DBG_TXFRS bit field */ + +/* mac_addr0h register value */ +#define MAC_ADDR0H_ADDR0H(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_MAC_ADDR0H_ADDR0H bit field */ + +/* mac_addrxh register value, x = 1,2,3 */ +#define MAC_ADDR123H_ADDR123H(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_MAC_ADDRxH_ADDRxH(x=1,2,3) bit field */ + +#define ENET_ADDRESS_MASK_BYTE0 BIT(24) /*!< low register bits [7:0] */ +#define ENET_ADDRESS_MASK_BYTE1 BIT(25) /*!< low register bits [15:8] */ +#define ENET_ADDRESS_MASK_BYTE2 BIT(26) /*!< low register bits [23:16] */ +#define ENET_ADDRESS_MASK_BYTE3 BIT(27) /*!< low register bits [31:24] */ +#define ENET_ADDRESS_MASK_BYTE4 BIT(28) /*!< high register bits [7:0] */ +#define ENET_ADDRESS_MASK_BYTE5 BIT(29) /*!< high register bits [15:8] */ + +#define ENET_ADDRESS_FILTER_SA BIT(30) /*!< use MAC address[47:0] is to compare with the SA fields of the received frame */ +#define ENET_ADDRESS_FILTER_DA ((uint32_t)0x00000000U) /*!< use MAC address[47:0] is to compare with the DA fields of the received frame */ + +/* mac_fcth register value */ +#define MAC_FCTH_RFA(regval) ((BITS(0,2) & ((uint32_t)(regval) << 0U)) << 8U) /*!< write value to ENET_MAC_FCTH_RFA bit field */ +#define ENET_ACTIVE_THRESHOLD_256BYTES MAC_FCTH_RFA(0) /*!< threshold level is 256 bytes */ +#define ENET_ACTIVE_THRESHOLD_512BYTES MAC_FCTH_RFA(1) /*!< threshold level is 512 bytes */ +#define ENET_ACTIVE_THRESHOLD_768BYTES MAC_FCTH_RFA(2) /*!< threshold level is 768 bytes */ +#define ENET_ACTIVE_THRESHOLD_1024BYTES MAC_FCTH_RFA(3) /*!< threshold level is 1024 bytes */ +#define ENET_ACTIVE_THRESHOLD_1280BYTES MAC_FCTH_RFA(4) /*!< threshold level is 1280 bytes */ +#define ENET_ACTIVE_THRESHOLD_1536BYTES MAC_FCTH_RFA(5) /*!< threshold level is 1536 bytes */ +#define ENET_ACTIVE_THRESHOLD_1792BYTES MAC_FCTH_RFA(6) /*!< threshold level is 1792 bytes */ + +#define MAC_FCTH_RFD(regval) ((BITS(4,6) & ((uint32_t)(regval) << 4U)) << 8U) /*!< write value to ENET_MAC_FCTH_RFD bit field */ +#define ENET_DEACTIVE_THRESHOLD_256BYTES MAC_FCTH_RFD(0) /*!< threshold level is 256 bytes */ +#define ENET_DEACTIVE_THRESHOLD_512BYTES MAC_FCTH_RFD(1) /*!< threshold level is 512 bytes */ +#define ENET_DEACTIVE_THRESHOLD_768BYTES MAC_FCTH_RFD(2) /*!< threshold level is 768 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1024BYTES MAC_FCTH_RFD(3) /*!< threshold level is 1024 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1280BYTES MAC_FCTH_RFD(4) /*!< threshold level is 1280 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1536BYTES MAC_FCTH_RFD(5) /*!< threshold level is 1536 bytes */ +#define ENET_DEACTIVE_THRESHOLD_1792BYTES MAC_FCTH_RFD(6) /*!< threshold level is 1792 bytes */ + +/* msc_ctl register value */ +#define ENET_MSC_COUNTER_STOP_ROLLOVER ENET_MSC_CTL_CTSR /*!< counter stop rollover */ +#define ENET_MSC_RESET_ON_READ ENET_MSC_CTL_RTOR /*!< reset on read */ +#define ENET_MSC_COUNTERS_FREEZE ENET_MSC_CTL_MCFZ /*!< MSC counter freeze */ + +/* ptp_tsctl register value */ +#define PTP_TSCTL_CKNT(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) /*!< write value to ENET_PTP_TSCTL_CKNT bit field */ + +#define ENET_RXTX_TIMESTAMP ENET_PTP_TSCTL_TMSEN /*!< enable timestamp function for transmit and receive frames */ +#define ENET_PTP_TIMESTAMP_INT ENET_PTP_TSCTL_TMSITEN /*!< timestamp interrupt trigger enable */ +#define ENET_ALL_RX_TIMESTAMP ENET_PTP_TSCTL_ARFSEN /*!< all received frames are taken snapshot */ +#define ENET_NONTYPE_FRAME_SNAPSHOT ENET_PTP_TSCTL_ESEN /*!< take snapshot when received non type frame */ +#define ENET_IPV6_FRAME_SNAPSHOT ENET_PTP_TSCTL_IP6SEN /*!< take snapshot for IPv6 frame */ +#define ENET_IPV4_FRAME_SNAPSHOT ENET_PTP_TSCTL_IP4SEN /*!< take snapshot for IPv4 frame */ +#define ENET_PTP_FRAME_USE_MACADDRESS_FILTER ENET_PTP_TSCTL_MAFEN /*!< enable MAC address1-3 to filter the PTP frame */ + +/* ptp_ssinc register value */ +#define PTP_SSINC_STMSSI(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_PTP_SSINC_STMSSI bit field */ + +/* ptp_tsl register value */ +#define GET_PTP_TSL_STMSS(regval) GET_BITS((uint32_t)(regval), 0U, 30U) /*!< get value of ENET_PTP_TSL_STMSS bit field */ + +#define ENET_PTP_TIME_POSITIVE ((uint32_t)0x00000000U) /*!< time value is positive */ +#define ENET_PTP_TIME_NEGATIVE ENET_PTP_TSL_STS /*!< time value is negative */ + +#define GET_PTP_TSL_STS(regval) (((regval) & BIT(31)) >> (31U)) /*!< get value of ENET_PTP_TSL_STS bit field */ + +/* ptp_tsul register value */ +#define PTP_TSUL_TMSUSS(regval) (BITS(0,30) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_PTP_TSUL_TMSUSS bit field */ + +#define ENET_PTP_ADD_TO_TIME ((uint32_t)0x00000000U) /*!< timestamp update value is added to system time */ +#define ENET_PTP_SUBSTRACT_FROM_TIME ENET_PTP_TSUL_TMSUPNS /*!< timestamp update value is subtracted from system time */ + +/* ptp_ppsctl register value */ +#define PTP_PPSCTL_PPSOFC(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_PTP_PPSCTL_PPSOFC bit field */ +#define ENET_PPSOFC_1HZ PTP_PPSCTL_PPSOFC(0) /*!< PPS output 1Hz frequency */ +#define ENET_PPSOFC_2HZ PTP_PPSCTL_PPSOFC(1) /*!< PPS output 2Hz frequency */ +#define ENET_PPSOFC_4HZ PTP_PPSCTL_PPSOFC(2) /*!< PPS output 4Hz frequency */ +#define ENET_PPSOFC_8HZ PTP_PPSCTL_PPSOFC(3) /*!< PPS output 8Hz frequency */ +#define ENET_PPSOFC_16HZ PTP_PPSCTL_PPSOFC(4) /*!< PPS output 16Hz frequency */ +#define ENET_PPSOFC_32HZ PTP_PPSCTL_PPSOFC(5) /*!< PPS output 32Hz frequency */ +#define ENET_PPSOFC_64HZ PTP_PPSCTL_PPSOFC(6) /*!< PPS output 64Hz frequency */ +#define ENET_PPSOFC_128HZ PTP_PPSCTL_PPSOFC(7) /*!< PPS output 128Hz frequency */ +#define ENET_PPSOFC_256HZ PTP_PPSCTL_PPSOFC(8) /*!< PPS output 256Hz frequency */ +#define ENET_PPSOFC_512HZ PTP_PPSCTL_PPSOFC(9) /*!< PPS output 512Hz frequency */ +#define ENET_PPSOFC_1024HZ PTP_PPSCTL_PPSOFC(10) /*!< PPS output 1024Hz frequency */ +#define ENET_PPSOFC_2048HZ PTP_PPSCTL_PPSOFC(11) /*!< PPS output 2048Hz frequency */ +#define ENET_PPSOFC_4096HZ PTP_PPSCTL_PPSOFC(12) /*!< PPS output 4096Hz frequency */ +#define ENET_PPSOFC_8192HZ PTP_PPSCTL_PPSOFC(13) /*!< PPS output 8192Hz frequency */ +#define ENET_PPSOFC_16384HZ PTP_PPSCTL_PPSOFC(14) /*!< PPS output 16384Hz frequency */ +#define ENET_PPSOFC_32768HZ PTP_PPSCTL_PPSOFC(15) /*!< PPS output 32768Hz frequency */ + +/* dma_bctl register value */ +#define DMA_BCTL_DPSL(regval) (BITS(2,6) & ((uint32_t)(regval) << 2U)) /*!< write value to ENET_DMA_BCTL_DPSL bit field */ +#define GET_DMA_BCTL_DPSL(regval) GET_BITS((regval),2,6) /*!< get value of ENET_DMA_BCTL_DPSL bit field */ + +#define ENET_ENHANCED_DESCRIPTOR ENET_DMA_BCTL_DFM /*!< enhanced mode descriptor */ +#define ENET_NORMAL_DESCRIPTOR ((uint32_t)0x00000000U) /*!< normal mode descriptor */ + +#define DMA_BCTL_PGBL(regval) (BITS(8,13) & ((uint32_t)(regval) << 8U)) /*!< write value to ENET_DMA_BCTL_PGBL bit field */ +#define ENET_PGBL_1BEAT DMA_BCTL_PGBL(1) /*!< maximum number of beats is 1 */ +#define ENET_PGBL_2BEAT DMA_BCTL_PGBL(2) /*!< maximum number of beats is 2 */ +#define ENET_PGBL_4BEAT DMA_BCTL_PGBL(4) /*!< maximum number of beats is 4 */ +#define ENET_PGBL_8BEAT DMA_BCTL_PGBL(8) /*!< maximum number of beats is 8 */ +#define ENET_PGBL_16BEAT DMA_BCTL_PGBL(16) /*!< maximum number of beats is 16 */ +#define ENET_PGBL_32BEAT DMA_BCTL_PGBL(32) /*!< maximum number of beats is 32 */ +#define ENET_PGBL_4xPGBL_4BEAT (DMA_BCTL_PGBL(1)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 4 */ +#define ENET_PGBL_4xPGBL_8BEAT (DMA_BCTL_PGBL(2)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 8 */ +#define ENET_PGBL_4xPGBL_16BEAT (DMA_BCTL_PGBL(4)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 16 */ +#define ENET_PGBL_4xPGBL_32BEAT (DMA_BCTL_PGBL(8)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 32 */ +#define ENET_PGBL_4xPGBL_64BEAT (DMA_BCTL_PGBL(16)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 64 */ +#define ENET_PGBL_4xPGBL_128BEAT (DMA_BCTL_PGBL(32)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats is 128 */ + +#define DMA_BCTL_RTPR(regval) (BITS(14,15) & ((uint32_t)(regval) << 14U)) /*!< write value to ENET_DMA_BCTL_RTPR bit field */ +#define ENET_ARBITRATION_RXTX_1_1 DMA_BCTL_RTPR(0) /*!< receive and transmit priority ratio is 1:1*/ +#define ENET_ARBITRATION_RXTX_2_1 DMA_BCTL_RTPR(1) /*!< receive and transmit priority ratio is 2:1*/ +#define ENET_ARBITRATION_RXTX_3_1 DMA_BCTL_RTPR(2) /*!< receive and transmit priority ratio is 3:1 */ +#define ENET_ARBITRATION_RXTX_4_1 DMA_BCTL_RTPR(3) /*!< receive and transmit priority ratio is 4:1 */ +#define ENET_ARBITRATION_RXPRIORTX ENET_DMA_BCTL_DAB /*!< RxDMA has higher priority than TxDMA */ + +#define ENET_FIXED_BURST_ENABLE ENET_DMA_BCTL_FB /*!< AHB can only use SINGLE/INCR4/INCR8/INCR16 during start of normal burst transfers */ +#define ENET_FIXED_BURST_DISABLE ((uint32_t)0x00000000U) /*!< AHB can use SINGLE/INCR burst transfer operations */ + +#define DMA_BCTL_RXDP(regval) (BITS(17,22) & ((uint32_t)(regval) << 17U)) /*!< write value to ENET_DMA_BCTL_RXDP bit field */ +#define ENET_RXDP_1BEAT DMA_BCTL_RXDP(1) /*!< maximum number of beats 1 */ +#define ENET_RXDP_2BEAT DMA_BCTL_RXDP(2) /*!< maximum number of beats 2 */ +#define ENET_RXDP_4BEAT DMA_BCTL_RXDP(4) /*!< maximum number of beats 4 */ +#define ENET_RXDP_8BEAT DMA_BCTL_RXDP(8) /*!< maximum number of beats 8 */ +#define ENET_RXDP_16BEAT DMA_BCTL_RXDP(16) /*!< maximum number of beats 16 */ +#define ENET_RXDP_32BEAT DMA_BCTL_RXDP(32) /*!< maximum number of beats 32 */ +#define ENET_RXDP_4xPGBL_4BEAT (DMA_BCTL_RXDP(1)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 4 */ +#define ENET_RXDP_4xPGBL_8BEAT (DMA_BCTL_RXDP(2)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 8 */ +#define ENET_RXDP_4xPGBL_16BEAT (DMA_BCTL_RXDP(4)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 16 */ +#define ENET_RXDP_4xPGBL_32BEAT (DMA_BCTL_RXDP(8)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 32 */ +#define ENET_RXDP_4xPGBL_64BEAT (DMA_BCTL_RXDP(16)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 64 */ +#define ENET_RXDP_4xPGBL_128BEAT (DMA_BCTL_RXDP(32)|ENET_DMA_BCTL_FPBL) /*!< maximum number of beats 128 */ + +#define ENET_RXTX_DIFFERENT_PGBL ENET_DMA_BCTL_UIP /*!< RxDMA uses the RXDP[5:0], while TxDMA uses the PGBL[5:0] */ +#define ENET_RXTX_SAME_PGBL ((uint32_t)0x00000000U) /*!< RxDMA/TxDMA uses PGBL[5:0] */ + +#define ENET_ADDRESS_ALIGN_ENABLE ENET_DMA_BCTL_AA /*!< enabled address-aligned */ +#define ENET_ADDRESS_ALIGN_DISABLE ((uint32_t)0x00000000U) /*!< disable address-aligned */ + +#define ENET_MIXED_BURST_ENABLE ENET_DMA_BCTL_MB /*!< AHB master interface transfer burst length greater than 16 with INCR */ +#define ENET_MIXED_BURST_DISABLE ((uint32_t)0x00000000U) /*!< AHB master interface only transfer fixed burst length with 16 and below */ + +/* dma_stat register value */ +#define GET_DMA_STAT_RP(regval) GET_BITS((uint32_t)(regval), 17U, 19U) /*!< get value of ENET_DMA_STAT_RP bit field */ +#define ENET_RX_STATE_STOPPED ((uint32_t)0x00000000U) /*!< reset or stop rx command issued */ +#define ENET_RX_STATE_FETCHING BIT(17) /*!< fetching the Rx descriptor */ +#define ENET_RX_STATE_WAITING (BIT(17)|BIT(18)) /*!< waiting for receive packet */ +#define ENET_RX_STATE_SUSPENDED BIT(19) /*!< Rx descriptor unavailable */ +#define ENET_RX_STATE_CLOSING (BIT(17)|BIT(19)) /*!< closing receive descriptor */ +#define ENET_RX_STATE_QUEUING ENET_DMA_STAT_RP /*!< transferring the receive packet data from recevie buffer to host memory */ + +#define GET_DMA_STAT_TP(regval) GET_BITS((uint32_t)(regval), 20U, 22U) /*!< get value of ENET_DMA_STAT_TP bit field */ +#define ENET_TX_STATE_STOPPED ((uint32_t)0x00000000U) /*!< reset or stop Tx Command issued */ +#define ENET_TX_STATE_FETCHING BIT(20) /*!< fetching the Tx descriptor */ +#define ENET_TX_STATE_WAITING BIT(21) /*!< waiting for status */ +#define ENET_TX_STATE_READING (BIT(20)|BIT(21)) /*!< reading the data from host memory buffer and queuing it to transmit buffer */ +#define ENET_TX_STATE_SUSPENDED (BIT(21)|BIT(22)) /*!< Tx descriptor unavailabe or transmit buffer underflow */ +#define ENET_TX_STATE_CLOSING ENET_DMA_STAT_TP /*!< closing Tx descriptor */ + +#define GET_DMA_STAT_EB(regval) GET_BITS((uint32_t)(regval), 23U, 25U) /*!< get value of ENET_DMA_STAT_EB bit field */ +#define ENET_ERROR_TXDATA_TRANSFER BIT(23) /*!< error during data transfer by TxDMA or RxDMA */ +#define ENET_ERROR_READ_TRANSFER BIT(24) /*!< error during write transfer or read transfer */ +#define ENET_ERROR_DESC_ACCESS BIT(25) /*!< error during descriptor or buffer access */ + +/* dma_ctl register value */ +#define DMA_CTL_RTHC(regval) (BITS(3,4) & ((uint32_t)(regval) << 3U)) /*!< write value to ENET_DMA_CTL_RTHC bit field */ +#define ENET_RX_THRESHOLD_64BYTES DMA_CTL_RTHC(0) /*!< threshold level is 64 Bytes */ +#define ENET_RX_THRESHOLD_32BYTES DMA_CTL_RTHC(1) /*!< threshold level is 32 Bytes */ +#define ENET_RX_THRESHOLD_96BYTES DMA_CTL_RTHC(2) /*!< threshold level is 96 Bytes */ +#define ENET_RX_THRESHOLD_128BYTES DMA_CTL_RTHC(3) /*!< threshold level is 128 Bytes */ + +#define DMA_CTL_TTHC(regval) (BITS(14,16) & ((uint32_t)(regval) << 14U)) /*!< write value to ENET_DMA_CTL_TTHC bit field */ +#define ENET_TX_THRESHOLD_64BYTES DMA_CTL_TTHC(0) /*!< threshold level is 64 Bytes */ +#define ENET_TX_THRESHOLD_128BYTES DMA_CTL_TTHC(1) /*!< threshold level is 128 Bytes */ +#define ENET_TX_THRESHOLD_192BYTES DMA_CTL_TTHC(2) /*!< threshold level is 192 Bytes */ +#define ENET_TX_THRESHOLD_256BYTES DMA_CTL_TTHC(3) /*!< threshold level is 256 Bytes */ +#define ENET_TX_THRESHOLD_40BYTES DMA_CTL_TTHC(4) /*!< threshold level is 40 Bytes */ +#define ENET_TX_THRESHOLD_32BYTES DMA_CTL_TTHC(5) /*!< threshold level is 32 Bytes */ +#define ENET_TX_THRESHOLD_24BYTES DMA_CTL_TTHC(6) /*!< threshold level is 24 Bytes */ +#define ENET_TX_THRESHOLD_16BYTES DMA_CTL_TTHC(7) /*!< threshold level is 16 Bytes */ + +#define ENET_TCPIP_CKSUMERROR_ACCEPT ENET_DMA_CTL_DTCERFD /*!< Rx frame with only payload error but no other errors will not be dropped */ +#define ENET_TCPIP_CKSUMERROR_DROP ((uint32_t)0x00000000U) /*!< all error frames will be dropped when FERF = 0 */ + +#define ENET_RX_MODE_STOREFORWARD ENET_DMA_CTL_RSFD /*!< RxFIFO operates in store-and-forward mode */ +#define ENET_RX_MODE_CUTTHROUGH ((uint32_t)0x00000000U) /*!< RxFIFO operates in cut-through mode */ + +#define ENET_FLUSH_RXFRAME_ENABLE ((uint32_t)0x00000000U) /*!< RxDMA flushes all frames */ +#define ENET_FLUSH_RXFRAME_DISABLE ENET_DMA_CTL_DAFRF /*!< RxDMA does not flush any frames */ +#define ENET_NO_FLUSH_RXFRAME ENET_DMA_CTL_DAFRF /*!< RxDMA does not flush frames function */ + +#define ENET_TX_MODE_STOREFORWARD ENET_DMA_CTL_TSFD /*!< TxFIFO operates in store-and-forward mode */ +#define ENET_TX_MODE_CUTTHROUGH ((uint32_t)0x00000000U) /*!< TxFIFO operates in cut-through mode */ + +#define ENET_FORWARD_ERRFRAMES_ENABLE (ENET_DMA_CTL_FERF << 2U) /*!< all frame received with error except runt error are forwarded to memory */ +#define ENET_FORWARD_ERRFRAMES_DISABLE ((uint32_t)0x00000000U) /*!< RxFIFO drop error frame */ +#define ENET_FORWARD_ERRFRAMES (ENET_DMA_CTL_FERF << 2U) /*!< the function that all frame received with error except runt error are forwarded to memory */ + +#define ENET_FORWARD_UNDERSZ_GOODFRAMES_ENABLE (ENET_DMA_CTL_FUF << 2U) /*!< forward undersized good frames */ +#define ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE ((uint32_t)0x00000000U) /*!< RxFIFO drops all frames whose length is less than 64 bytes */ +#define ENET_FORWARD_UNDERSZ_GOODFRAMES (ENET_DMA_CTL_FUF << 2U) /*!< the function that forwarding undersized good frames */ + +#define ENET_SECONDFRAME_OPT_ENABLE ENET_DMA_CTL_OSF /*!< TxDMA controller operate on second frame mode enable*/ +#define ENET_SECONDFRAME_OPT_DISABLE ((uint32_t)0x00000000U) /*!< TxDMA controller operate on second frame mode disable */ +#define ENET_SECONDFRAME_OPT ENET_DMA_CTL_OSF /*!< TxDMA controller operate on second frame function */ + +/* dma_mfbocnt register value */ +#define GET_DMA_MFBOCNT_MSFC(regval) GET_BITS((regval), 0U, 15U) /*!< get value of ENET_DMA_MFBOCNT_MSFC bit fiel */ +#define GET_DMA_MFBOCNT_MSFA(regval) GET_BITS((regval), 17U, 27U) /*!< get value of ENET_DMA_MFBOCNT_MSFA bit field */ + +/* dma_rswdc register value */ +#define DMA_RSWDC_WDCFRS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET_DMA_RSWDC_WDCFRS bit field */ + +/* dma tx descriptor tdes0 register value */ +#define TDES0_CONT(regval) (BITS(3,6) & ((uint32_t)(regval) << 3U)) /*!< write value to ENET DMA TDES0 CONT bit field */ +#define GET_TDES0_COCNT(regval) GET_BITS((regval), 3U, 6U) /*!< get value of ENET DMA TDES0 CONT bit field */ + +#define TDES0_CM(regval) (BITS(22,23) & ((uint32_t)(regval) << 22U)) /*!< write value to ENET DMA TDES0 CM bit field */ +#define ENET_CHECKSUM_DISABLE TDES0_CM(0) /*!< checksum insertion disabled */ +#define ENET_CHECKSUM_IPV4HEADER TDES0_CM(1) /*!< only IP header checksum calculation and insertion are enabled */ +#define ENET_CHECKSUM_TCPUDPICMP_SEGMENT TDES0_CM(2) /*!< TCP/UDP/ICMP checksum insertion calculated but pseudo-header */ +#define ENET_CHECKSUM_TCPUDPICMP_FULL TDES0_CM(3) /*!< TCP/UDP/ICMP checksum insertion fully calculated */ + +/* dma tx descriptor tdes1 register value */ +#define TDES1_TB1S(regval) (BITS(0,12) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET DMA TDES1 TB1S bit field */ + +#define TDES1_TB2S(regval) (BITS(16,28) & ((uint32_t)(regval) << 16U)) /*!< write value to ENET DMA TDES1 TB2S bit field */ + +/* dma rx descriptor rdes0 register value */ +#define RDES0_FRML(regval) (BITS(16,29) & ((uint32_t)(regval) << 16U)) /*!< write value to ENET DMA RDES0 FRML bit field */ +#define GET_RDES0_FRML(regval) GET_BITS((regval), 16U, 29U) /*!< get value of ENET DMA RDES0 FRML bit field */ + +/* dma rx descriptor rdes1 register value */ +#define ENET_RECEIVE_COMPLETE_INT_ENABLE ((uint32_t)0x00000000U) /*!< RS bit immediately set after Rx completed */ +#define ENET_RECEIVE_COMPLETE_INT_DISABLE ENET_RDES1_DINTC /*!< RS bit not immediately set after Rx completed */ + +#define GET_RDES1_RB1S(regval) GET_BITS((regval), 0U, 12U) /*!< get value of ENET DMA RDES1 RB1S bit field */ + +#define GET_RDES1_RB2S(regval) GET_BITS((regval), 16U, 28U) /*!< get value of ENET DMA RDES1 RB2S bit field */ + +/* dma rx descriptor rdes4 register value */ +#define RDES4_IPPLDT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) /*!< write value to ENET DMA RDES4 IPPLDT bit field */ +#define GET_RDES4_IPPLDT(regval) GET_BITS((regval), 0U, 2U) /*!< get value of ENET DMA RDES4 IPPLDT bit field */ + +#define RDES4_PTPMT(regval) (BITS(8,11) & ((uint32_t)(regval) << 8U)) /*!< write value to ENET DMA RDES4 PTPMT bit field */ +#define GET_RDES4_PTPMT(regval) GET_BITS((regval), 8U, 11U) /*!< get value of ENET DMA RDES4 PTPMT bit field */ + +/* ENET register mask value */ +#define MAC_CFG_MASK ((uint32_t)0xFD30810FU) /*!< ENET_MAC_CFG register mask */ +#define MAC_FCTL_MASK ((uint32_t)0x0000FF41U) /*!< ENET_MAC_FCTL register mask */ +#define DMA_CTL_MASK ((uint32_t)0xF8DE3F23U) /*!< ENET_DMA_CTL register mask */ +#define DMA_BCTL_MASK ((uint32_t)0xF800007DU) /*!< ENET_DMA_BCTL register mask */ +#define ENET_MSC_PRESET_MASK (~(ENET_MSC_CTL_PMC | ENET_MSC_CTL_AFHPM)) /*!< ENET_MSC_CTL preset mask */ + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +#define ETH_DMATXDESC_SIZE 0x00000020U /*!< TxDMA enhanced descriptor size */ +#define ETH_DMARXDESC_SIZE 0x00000020U /*!< RxDMA enhanced descriptor size */ +#else +#define ETH_DMATXDESC_SIZE 0x00000010U /*!< TxDMA descriptor size */ +#define ETH_DMARXDESC_SIZE 0x00000010U /*!< RxDMA descriptor size */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + + +typedef enum { + ENET_CKNT_ORDINARY = PTP_TSCTL_CKNT(0), /*!< type of ordinary clock node type for timestamp */ + ENET_CKNT_BOUNDARY = PTP_TSCTL_CKNT(1), /*!< type of boundary clock node type for timestamp */ + ENET_CKNT_END_TO_END = PTP_TSCTL_CKNT(2), /*!< type of end-to-end transparent clock node type for timestamp */ + ENET_CKNT_PEER_TO_PEER = PTP_TSCTL_CKNT(3), /*!< type of peer-to-peer transparent clock node type for timestamp */ + ENET_PTP_SYSTIME_INIT = ENET_PTP_TSCTL_TMSSTI, /*!< timestamp initialize */ + ENET_PTP_SYSTIME_UPDATE = ENET_PTP_TSCTL_TMSSTU, /*!< timestamp update */ + ENET_PTP_ADDEND_UPDATE = ENET_PTP_TSCTL_TMSARU, /*!< addend register update */ + ENET_PTP_FINEMODE = (int32_t)(ENET_PTP_TSCTL_TMSFCU | BIT(31)), /*!< the system timestamp uses the fine method for updating */ + ENET_PTP_COARSEMODE = ENET_PTP_TSCTL_TMSFCU, /*!< the system timestamp uses the coarse method for updating */ + ENET_SUBSECOND_DIGITAL_ROLLOVER = (int32_t)(ENET_PTP_TSCTL_SCROM | BIT(31)), /*!< digital rollover mode */ + ENET_SUBSECOND_BINARY_ROLLOVER = ENET_PTP_TSCTL_SCROM, /*!< binary rollover mode */ + ENET_SNOOPING_PTP_VERSION_2 = (int32_t)(ENET_PTP_TSCTL_PFSV | BIT(31)), /*!< version 2 */ + ENET_SNOOPING_PTP_VERSION_1 = ENET_PTP_TSCTL_PFSV, /*!< version 1 */ + ENET_EVENT_TYPE_MESSAGES_SNAPSHOT = (int32_t)(ENET_PTP_TSCTL_ETMSEN | BIT(31)), /*!< only event type messages are taken snapshot */ + ENET_ALL_TYPE_MESSAGES_SNAPSHOT = ENET_PTP_TSCTL_ETMSEN, /*!< all type messages are taken snapshot except announce, management and signaling message */ + ENET_MASTER_NODE_MESSAGE_SNAPSHOT = (int32_t)(ENET_PTP_TSCTL_MNMSEN | BIT(31)), /*!< snapshot is only take for master node message */ + ENET_SLAVE_NODE_MESSAGE_SNAPSHOT = ENET_PTP_TSCTL_MNMSEN /*!< snapshot is only taken for slave node message */ +} enet_ptp_function_enum; + + +/* ENET remote wake-up frame register length */ +#define ETH_WAKEUP_REGISTER_LENGTH 8U /*!< remote wake-up frame register length */ + +/* ENET frame size */ +#define ENET_MAX_FRAME_SIZE 1524U /*!< header + frame_extra + payload + CRC */ + +/* ENET delay timeout */ +#define ENET_DELAY_TO ((uint32_t)0x0004FFFFU) /*!< ENET delay timeout */ +#define ENET_RESET_TO ((uint32_t)0x000004FFU) /*!< ENET reset timeout */ + +#define IF_USE_EXTERNPHY_LIB 0U +#if (1U == IF_USE_EXTERNPHY_LIB) +#include "phy.h" +#endif + +#ifndef ENET_RXBUF_NUM +#define ENET_RXBUF_NUM 5U /*!< ethernet Rx DMA descriptor number */ +#endif + +#ifndef ENET_TXBUF_NUM +#define ENET_TXBUF_NUM 5U /*!< ethernet Tx DMA descriptor number */ +#endif + +#ifndef ENET_RXBUF_SIZE +#define ENET_RXBUF_SIZE ENET_MAX_FRAME_SIZE /*!< ethernet receive buffer size */ +#endif + +#ifndef ENET_TXBUF_SIZE +#define ENET_TXBUF_SIZE ENET_MAX_FRAME_SIZE /*!< ethernet transmit buffer size */ +#endif + +/* #define SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* #define USE_DELAY */ + +#ifndef _PHY_H_ +#define DP83848 0U +#define LAN8700 1U +#define PHY_TYPE DP83848 + +#define PHY_ADDRESS ((uint16_t)1U) /*!< phy address determined by the hardware */ + +/* PHY read write timeouts */ +#define PHY_READ_TO ((uint32_t)0x0004FFFFU) /*!< PHY read timeout */ +#define PHY_WRITE_TO ((uint32_t)0x0004FFFFU) /*!< PHY write timeout */ + +/* PHY delay */ +#define PHY_RESETDELAY ((uint32_t)0x008FFFFFU) /*!< PHY reset delay */ +#define PHY_CONFIGDELAY ((uint32_t)0x00FFFFFFU) /*!< PHY configure delay */ + +/* PHY register address */ +#define PHY_REG_BCR 0U /*!< tranceiver basic control register */ +#define PHY_REG_BSR 1U /*!< tranceiver basic status register */ + +/* PHY basic control register */ +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< enable phy loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< configure speed to 100 Mbit/s and the full-duplex mode */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< configure speed to 100 Mbit/s and the half-duplex mode */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< configure speed to 10 Mbit/s and the full-duplex mode */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< configure speed to 10 Mbit/s and the half-duplex mode */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< enable the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< isolate PHY from MII */ + +/* PHY basic status register */ +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< auto-negotioation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< jabber condition detected */ + +#if(PHY_TYPE == LAN8700) +#define PHY_SR 31U /*!< tranceiver status register */ +#define PHY_SPEED_STATUS ((uint16_t)0x0004U) /*!< configured information of speed: 10Mbit/s */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010U) /*!< configured information of duplex: full-duplex */ +#elif(PHY_TYPE == DP83848) +#define PHY_SR 16U /*!< tranceiver status register */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< configured information of speed: 10Mbit/s */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< configured information of duplex: full-duplex */ +#endif /* PHY_TYPE */ + +#endif /* _PHY_H_ */ + +/* function declarations */ +/* main function */ +/* deinitialize the ENET, and reset structure parameters for ENET initialization */ +void enet_deinit(uint32_t enet_periph); +/* configure the parameters which are usually less cared for initialization */ +void enet_initpara_config(enet_option_enum option, uint32_t para); +/* initialize ENET peripheral with generally concerned parameters and the less cared parameters */ +ErrStatus enet_init(uint32_t enet_periph, enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept); +/* reset all core internal registers located in CLK_TX and CLK_RX */ +ErrStatus enet_software_reset(uint32_t enet_periph); +/* check receive frame valid and return frame size */ +uint32_t enet_rxframe_size_get(uint32_t enet_periph); +/* initialize the dma tx/rx descriptors's parameters in chain mode */ +void enet_descriptors_chain_init(uint32_t enet_periph, enet_dmadirection_enum direction); +/* initialize the dma tx/rx descriptors's parameters in ring mode */ +void enet_descriptors_ring_init(uint32_t enet_periph, enet_dmadirection_enum direction); +/* handle current received frame data to application buffer */ +ErrStatus enet_frame_receive(uint32_t enet_periph, uint8_t buffer[], uint32_t bufsize); +/* handle current received frame but without data copy to application buffer */ +#define ENET_NOCOPY_FRAME_RECEIVE(enet_periph) enet_frame_receive((enet_periph), NULL, 0U) +/* handle application buffer data to transmit it */ +ErrStatus enet_frame_transmit(uint32_t enet_periph, uint8_t buffer[], uint32_t length); +/* handle current transmit frame but without data copy from application buffer */ +#define ENET_NOCOPY_FRAME_TRANSMIT(enet_periph, len) enet_frame_transmit((enet_periph), NULL, (len)) +/* configure the transmit IP frame checksum offload calculation and insertion */ +ErrStatus enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum); +/* ENET Tx and Rx function enable (include MAC and DMA module) */ +void enet_enable(uint32_t enet_periph); +/* ENET Tx and Rx function disable (include MAC and DMA module) */ +void enet_disable(uint32_t enet_periph); +/* configure MAC address */ +void enet_mac_address_set(uint32_t enet_periph, enet_macaddress_enum mac_addr, uint8_t paddr[]); +/* get MAC address */ +ErrStatus enet_mac_address_get(uint32_t enet_periph, enet_macaddress_enum mac_addr, uint8_t paddr[], uint8_t bufsize); + +/* MAC function */ +/* ENET Tx function enable (include MAC and DMA module) */ +void enet_tx_enable(uint32_t enet_periph); +/* ENET Tx function disable (include MAC and DMA module) */ +void enet_tx_disable(uint32_t enet_periph); +/* ENET Rx function enable (include MAC and DMA module) */ +void enet_rx_enable(uint32_t enet_periph); +/* ENET Rx function disable (include MAC and DMA module) */ +void enet_rx_disable(uint32_t enet_periph); +/* put registers value into the application buffer */ +void enet_registers_get(uint32_t enet_periph, enet_registers_type_enum type, uint32_t *preg, uint32_t num); +/* get the enet debug status from the debug register */ +uint32_t enet_debug_status_get(uint32_t enet_periph, uint32_t mac_debug); +/* enable the MAC address filter */ +void enet_address_filter_enable(uint32_t enet_periph, enet_macaddress_enum mac_addr); +/* disable the MAC address filter */ +void enet_address_filter_disable(uint32_t enet_periph, enet_macaddress_enum mac_addr); +/* configure the MAC address filter */ +void enet_address_filter_config(uint32_t enet_periph, enet_macaddress_enum mac_addr, uint32_t addr_mask, uint32_t filter_type); +/* PHY interface configuration (configure SMI clock and reset PHY chip) */ +ErrStatus enet_phy_config(uint32_t enet_periph); +/* write to/read from a PHY register */ +ErrStatus enet_phy_write_read(uint32_t enet_periph, enet_phydirection_enum direction, uint16_t phy_address, uint16_t phy_reg, uint16_t *pvalue); +/* enable the loopback function of phy chip */ +ErrStatus enet_phyloopback_enable(uint32_t enet_periph); +/* disable the loopback function of phy chip */ +ErrStatus enet_phyloopback_disable(uint32_t enet_periph); +/* enable ENET forward feature */ +void enet_forward_feature_enable(uint32_t enet_periph, uint32_t feature); +/* disable ENET forward feature */ +void enet_forward_feature_disable(uint32_t enet_periph, uint32_t feature); +/* enable ENET fliter feature */ +void enet_fliter_feature_enable(uint32_t enet_periph, uint32_t feature); +/* disable ENET fliter feature */ +void enet_fliter_feature_disable(uint32_t enet_periph, uint32_t feature); + +/* flow control function */ +/* generate the pause frame, ENET will send pause frame after enable transmit flow control */ +ErrStatus enet_pauseframe_generate(uint32_t enet_periph); +/* configure the pause frame detect type */ +void enet_pauseframe_detect_config(uint32_t enet_periph, uint32_t detect); +/* configure the pause frame parameters */ +void enet_pauseframe_config(uint32_t enet_periph, uint32_t pausetime, uint32_t pause_threshold); +/* configure the threshold of the flow control(deactive and active threshold) */ +void enet_flowcontrol_threshold_config(uint32_t enet_periph, uint32_t deactive, uint32_t active); +/* enable ENET flow control feature */ +void enet_flowcontrol_feature_enable(uint32_t enet_periph, uint32_t feature); +/* disable ENET flow control feature */ +void enet_flowcontrol_feature_disable(uint32_t enet_periph, uint32_t feature); + +/* DMA function */ +/* get the dma transmit/receive process state */ +uint32_t enet_dmaprocess_state_get(uint32_t enet_periph, enet_dmadirection_enum direction); +/* poll the dma transmission/reception enable */ +void enet_dmaprocess_resume(uint32_t enet_periph, enet_dmadirection_enum direction); +/* check and recover the Rx process */ +void enet_rxprocess_check_recovery(uint32_t enet_periph); +/* flush the ENET transmit fifo, and wait until the flush operation completes */ +ErrStatus enet_txfifo_flush(uint32_t enet_periph); +/* get the transmit/receive address of current descriptor, or current buffer, or descriptor table */ +uint32_t enet_current_desc_address_get(uint32_t enet_periph, enet_desc_reg_enum addr_get); +/* get the Tx or Rx descriptor information */ +uint32_t enet_desc_information_get(uint32_t enet_periph, enet_descriptors_struct *desc, enet_descstate_enum info_get); +/* get the number of missed frames during receiving */ +void enet_missed_frame_counter_get(uint32_t enet_periph, uint32_t *rxfifo_drop, uint32_t *rxdma_drop); + +/* descriptor function */ +/* get the bit flag of ENET dma descriptor */ +FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag); +/* set the bit flag of ENET dma tx descriptor */ +void enet_desc_flag_set(enet_descriptors_struct *desc, uint32_t desc_flag); +/* clear the bit flag of ENET dma tx descriptor */ +void enet_desc_flag_clear(enet_descriptors_struct *desc, uint32_t desc_flag); +/* when receiving the completed, set RS bit in ENET_DMA_STAT register will immediately set */ +void enet_rx_desc_immediate_receive_complete_interrupt(enet_descriptors_struct *desc); +/* when receiving the completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time */ +void enet_rx_desc_delay_receive_complete_interrupt(uint32_t enet_periph, enet_descriptors_struct *desc, uint32_t delay_time); +/* drop current receive frame */ +void enet_rxframe_drop(uint32_t enet_periph); +/* enable DMA feature */ +void enet_dma_feature_enable(uint32_t enet_periph, uint32_t feature); +/* disable DMA feature */ +void enet_dma_feature_disable(uint32_t enet_periph, uint32_t feature); + + +/* special enhanced mode function */ +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/* get the bit of extended status flag in ENET DMA descriptor */ +uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_t desc_status); +/* configure descriptor to work in enhanced mode */ +void enet_desc_select_enhanced_mode(uint32_t enet_periph); +/* initialize the dma Tx/Rx descriptors's parameters in enhanced chain mode with ptp function */ +void enet_ptp_enhanced_descriptors_chain_init(uint32_t enet_periph, enet_dmadirection_enum direction); +/* initialize the dma Tx/Rx descriptors's parameters in enhanced ring mode with ptp function */ +void enet_ptp_enhanced_descriptors_ring_init(uint32_t enet_periph, enet_dmadirection_enum direction); +/* receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode */ +ErrStatus enet_ptpframe_receive_enhanced_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t bufsize, uint32_t timestamp[]); +/* handle current received frame but without data copy to application buffer in PTP enhanced mode */ +#define ENET_NOCOPY_PTPFRAME_RECEIVE_ENHANCED_MODE(enet_periph, ptr) enet_ptpframe_receive_enhanced_mode((enet_periph), NULL, 0U, (ptr)) +/* send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode */ +ErrStatus enet_ptpframe_transmit_enhanced_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t length, uint32_t timestamp[]); +/* handle current transmit frame but without data copy from application buffer in PTP enhanced mode */ +#define ENET_NOCOPY_PTPFRAME_TRANSMIT_ENHANCED_MODE(enet_periph, len, ptr) enet_ptpframe_transmit_enhanced_mode((enet_periph), NULL, (len), (ptr)) + +#else + +/* configure descriptor to work in normal mode */ +void enet_desc_select_normal_mode(uint32_t enet_periph); +/* initialize the dma Tx/Rx descriptors's parameters in normal chain mode with ptp function */ +void enet_ptp_normal_descriptors_chain_init(uint32_t enet_periph, enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab); +/* initialize the dma Tx/Rx descriptors's parameters in normal ring mode with ptp function */ +void enet_ptp_normal_descriptors_ring_init(uint32_t enet_periph, enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab); +/* receive a packet data with timestamp values to application buffer, when the DMA is in normal mode */ +ErrStatus enet_ptpframe_receive_normal_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t bufsize, uint32_t timestamp[]); +/* handle current received frame but without data copy to application buffer in PTP normal mode */ +#define ENET_NOCOPY_PTPFRAME_RECEIVE_NORMAL_MODE(enet_periph, ptr) enet_ptpframe_receive_normal_mode((enet_periph), NULL, 0U, (ptr)) +/* send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode */ +ErrStatus enet_ptpframe_transmit_normal_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t length, uint32_t timestamp[]); +/* handle current transmit frame but without data copy from application buffer in PTP normal mode */ +#define ENET_NOCOPY_PTPFRAME_TRANSMIT_NORMAL_MODE(enet_periph, len, ptr) enet_ptpframe_transmit_normal_mode((enet_periph), NULL, (len), (ptr)) + +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* WUM function */ +/* wakeup frame filter register pointer reset */ +void enet_wum_filter_register_pointer_reset(uint32_t enet_periph); +/* set the remote wakeup frame registers */ +void enet_wum_filter_config(uint32_t enet_periph, uint32_t pdata[]); +/* enable wakeup management features */ +void enet_wum_feature_enable(uint32_t enet_periph, uint32_t feature); +/* disable wakeup management features */ +void enet_wum_feature_disable(uint32_t enet_periph, uint32_t feature); + +/* MSC function */ +/* reset the MAC statistics counters */ +void enet_msc_counters_reset(uint32_t enet_periph); +/* enable the MAC statistics counter features */ +void enet_msc_feature_enable(uint32_t enet_periph, uint32_t feature); +/* disable the MAC statistics counter features */ +void enet_msc_feature_disable(uint32_t enet_periph, uint32_t feature); +/* configure MAC statistics counters preset mode */ +void enet_msc_counters_preset_config(uint32_t enet_periph, enet_msc_preset_enum mode); +/* get MAC statistics counter */ +uint32_t enet_msc_counters_get(uint32_t enet_periph, enet_msc_counter_enum counter); + +/* PTP function */ +/* change subsecond to nanosecond */ +uint32_t enet_ptp_subsecond_2_nanosecond(uint32_t subsecond); +/* change nanosecond to subsecond */ +uint32_t enet_ptp_nanosecond_2_subsecond(uint32_t nanosecond); +/* enable the PTP features */ +void enet_ptp_feature_enable(uint32_t enet_periph, uint32_t feature); +/* disable the PTP features */ +void enet_ptp_feature_disable(uint32_t enet_periph, uint32_t feature); +/* configure the PTP timestamp function */ +ErrStatus enet_ptp_timestamp_function_config(uint32_t enet_periph, enet_ptp_function_enum func); +/* configure the PTP system time subsecond increment value */ +void enet_ptp_subsecond_increment_config(uint32_t enet_periph, uint32_t subsecond); +/* adjusting the PTP clock frequency only in fine update mode */ +void enet_ptp_timestamp_addend_config(uint32_t enet_periph, uint32_t add); +/* initializing or adding/subtracting to second of the PTP system time */ +void enet_ptp_timestamp_update_config(uint32_t enet_periph, uint32_t sign, uint32_t second, uint32_t subsecond); +/* configure the PTP expected target time */ +void enet_ptp_expected_time_config(uint32_t enet_periph, uint32_t second, uint32_t nanosecond); +/* get the PTP current system time */ +void enet_ptp_system_time_get(uint32_t enet_periph, enet_ptp_systime_struct *systime_struct); +/* configure the PPS output frequency */ +void enet_ptp_pps_output_frequency_config(uint32_t enet_periph, uint32_t freq); +/* configure and start PTP timestamp counter */ +void enet_ptp_start(uint32_t enet_periph, int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg); +/* adjust frequency in fine method by configure addend register */ +void enet_ptp_finecorrection_adjfreq(uint32_t enet_periph, int32_t carry_cfg); +/* update system time in coarse method */ +void enet_ptp_coarsecorrection_systime_update(uint32_t enet_periph, enet_ptp_systime_struct *systime_struct); +/* set system time in fine method */ +void enet_ptp_finecorrection_settime(uint32_t enet_periph, enet_ptp_systime_struct *systime_struct); +/* get the ptp flag status */ +FlagStatus enet_ptp_flag_get(uint32_t enet_periph, uint32_t flag); + +/* internal function */ +/* reset the ENET initpara struct, call it before using enet_initpara_config() */ +void enet_initpara_reset(void); +#ifdef USE_DELAY +/* user can provide more timing precise _ENET_DELAY_ function */ +#define _ENET_DELAY_ delay_ms +#else +/* default _ENET_DELAY_ function with less precise timing */ +#define _ENET_DELAY_ enet_delay +#endif + +/* get the ENET MAC/MSC/PTP/DMA status flag */ +FlagStatus enet_flag_get(uint32_t enet_periph, enet_flag_enum enet_flag); +/* clear the ENET DMA status flag */ +void enet_flag_clear(uint32_t enet_periph, enet_flag_clear_enum enet_flag); +/* enable ENET MAC/MSC/DMA interrupt */ +void enet_interrupt_enable(uint32_t enet_periph, enet_int_enum enet_int); +/* disable ENET MAC/MSC/DMA interrupt */ +void enet_interrupt_disable(uint32_t enet_periph, enet_int_enum enet_int); +/* get ENET MAC/MSC/DMA interrupt flag */ +FlagStatus enet_interrupt_flag_get(uint32_t enet_periph, enet_int_flag_enum int_flag); +/* clear ENET DMA interrupt flag */ +void enet_interrupt_flag_clear(uint32_t enet_periph, enet_int_flag_clear_enum int_flag_clear); + +#endif /* GD32H7XX_ENET_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exmc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exmc.h new file mode 100644 index 0000000000..54f301e3f4 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exmc.h @@ -0,0 +1,638 @@ +/*! + \file gd32h7xx_exmc.h + \brief definitions for the EXMC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_EXMC_H +#define GD32H7XX_EXMC_H + +#include "gd32h7xx.h" + +/* EXMC definitions */ +#define EXMC EXMC_BASE /*!< EXMC register base address */ + +/* registers definitions */ +/* NOR/PSRAM */ +#define EXMC_SNCTL0 REG32(EXMC + 0x00000000U) /*!< EXMC SRAM/NOR flash control register for region0 */ +#define EXMC_SNTCFG0 REG32(EXMC + 0x00000004U) /*!< EXMC SRAM/NOR flash timing configuration register for region0 */ +#define EXMC_SNWTCFG0 REG32(EXMC + 0x00000104U) /*!< EXMC SRAM/NOR flash write timing configuration register for region0 */ +#define EXMC_SNCTL1 REG32(EXMC + 0x00000008U) /*!< EXMC SRAM/NOR flash control register for region1 */ +#define EXMC_SNTCFG1 REG32(EXMC + 0x0000000CU) /*!< EXMC SRAM/NOR flash timing configuration register for region1 */ +#define EXMC_SNWTCFG1 REG32(EXMC + 0x0000010CU) /*!< EXMC SRAM/NOR flash write timing configuration register for region1 */ +#define EXMC_SNCTL2 REG32(EXMC + 0x00000010U) /*!< EXMC SRAM/NOR flash control register for region2 */ +#define EXMC_SNTCFG2 REG32(EXMC + 0x00000014U) /*!< EXMC SRAM/NOR flash timing configuration register for region2 */ +#define EXMC_SNWTCFG2 REG32(EXMC + 0x00000114U) /*!< EXMC SRAM/NOR flash write timing configuration register for region2 */ +#define EXMC_SNCTL3 REG32(EXMC + 0x00000018U) /*!< EXMC SRAM/NOR flash control register for region3 */ +#define EXMC_SNTCFG3 REG32(EXMC + 0x0000001CU) /*!< EXMC SRAM/NOR flash timing configuration register for region3 */ +#define EXMC_SNWTCFG3 REG32(EXMC + 0x0000011CU) /*!< EXMC SRAM/NOR flash write timing configuration register for region3 */ + +/* NAND */ +#define EXMC_NCTL REG32(EXMC + 0x00000080U) /*!< EXMC NAND control register */ +#define EXMC_NINTEN REG32(EXMC + 0x00000084U) /*!< EXMC NAND interrupt enable register */ +#define EXMC_NCTCFG REG32(EXMC + 0x00000088U) /*!< EXMC NAND common space timing configuration register */ +#define EXMC_NATCFG REG32(EXMC + 0x0000008CU) /*!< EXMC NAND attribute space timing configuration register */ +#define EXMC_NECC REG32(EXMC + 0x00000094U) /*!< EXMC NAND ECC register */ + +/* SDRAM */ +#define EXMC_SDCTL0 REG32(EXMC + 0x00000140U) /*!< EXMC SDRAM control register for device0 */ +#define EXMC_SDTCFG0 REG32(EXMC + 0x00000148U) /*!< EXMC SDRAM timing configuration register register for device0 */ +#define EXMC_SDCTL1 REG32(EXMC + 0x00000144U) /*!< EXMC SDRAM control register for device1 */ +#define EXMC_SDTCFG1 REG32(EXMC + 0x0000014CU) /*!< EXMC SDRAM timing configuration register register for device1 */ +#define EXMC_SDCMD REG32(EXMC + 0x00000150U) /*!< EXMC SDRAM command register */ +#define EXMC_SDARI REG32(EXMC + 0x00000154U) /*!< EXMC SDRAM auto-refresh interval register */ +#define EXMC_SDSTAT REG32(EXMC + 0x00000158U) /*!< EXMC SDRAM status register */ +#define EXMC_SDRSCTL REG32(EXMC + 0x00000180U) /*!< EXMC SDRAM read sample control register */ + +/* bits definitions */ +/* EXMC_SNCTLx,x=0..3 */ +#define EXMC_SNCTL_NRBKEN BIT(0) /*!< NOR region enable */ +#define EXMC_SNCTL_NRMUX BIT(1) /*!< NOR region memory address/data multiplexing enable */ +#define EXMC_SNCTL_NRTP BITS(2,3) /*!< NOR region memory type */ +#define EXMC_SNCTL_NRW BITS(4,5) /*!< NOR region memory data bus width */ +#define EXMC_SNCTL_NREN BIT(6) /*!< NOR flash access enable */ +#define EXMC_SNCTL_SBRSTEN BIT(8) /*!< synchronous burst enable */ +#define EXMC_SNCTL_NRWTPOL BIT(9) /*!< NWAIT signal polarity */ +#define EXMC_SNCTL_NRWTCFG BIT(11) /*!< NWAIT signal configuration, only work in synchronous mode */ +#define EXMC_SNCTL_WEN BIT(12) /*!< write enable */ +#define EXMC_SNCTL_NRWTEN BIT(13) /*!< NWAIT signal enable */ +#define EXMC_SNCTL_EXMODEN BIT(14) /*!< extended mode enable */ +#define EXMC_SNCTL_ASYNCWTEN BIT(15) /*!< asynchronous wait enable */ +#define EXMC_SNCTL_CPS BITS(16,18) /*!< CRAM page size */ +#define EXMC_SNCTL_SYNCWR BIT(19) /*!< synchronous write configuration */ +#define EXMC_SNCTL_CCK BIT(20) /*!< consecutive clock configuration */ +#define EXMC_SNCTL_BKREMAP BITS(24,25) /*!< bank remap */ + +/* EXMC_SNTCFGx,x=0..3 */ +#define EXMC_SNTCFG_ASET BITS(0,3) /*!< asynchronous address setup time */ +#define EXMC_SNTCFG_AHLD BITS(4,7) /*!< asynchronous address hold time */ +#define EXMC_SNTCFG_DSET BITS(8,15) /*!< asynchronous data setup time */ +#define EXMC_SNTCFG_BUSLAT BITS(16,19) /*!< bus latency */ +#define EXMC_SNTCFG_CKDIV BITS(20,23) /*!< synchronous clock divide ratio */ +#define EXMC_SNTCFG_DLAT BITS(24,27) /*!< synchronous data latency for NOR flash */ +#define EXMC_SNTCFG_ASYNCMOD BITS(28,29) /*!< asynchronous access mode */ + +/* EXMC_SNWTCFGx,x=0..3 */ +#define EXMC_SNWTCFG_WASET BITS(0,3) /*!< asynchronous address setup time */ +#define EXMC_SNWTCFG_WAHLD BITS(4,7) /*!< asynchronous address hold time */ +#define EXMC_SNWTCFG_WDSET BITS(8,15) /*!< asynchronous data setup time */ +#define EXMC_SNWTCFG_WBUSLAT BITS(16,19) /*!< bus latency */ +#define EXMC_SNWTCFG_WASYNCMOD BITS(28,29) /*!< asynchronous access mode */ + +/* EXMC_NCTL */ +#define EXMC_NCTL_NDWTEN BIT(1) /*!< wait function enable */ +#define EXMC_NCTL_NDBKEN BIT(2) /*!< NAND bank enable */ +#define EXMC_NCTL_NDW BITS(4,5) /*!< NAND bank memory data bus width */ +#define EXMC_NCTL_ECCEN BIT(6) /*!< ECC enable */ +#define EXMC_NCTL_CTR BITS(9,12) /*!< CLE to RE delay */ +#define EXMC_NCTL_ATR BITS(13,16) /*!< ALE to RE delay */ +#define EXMC_NCTL_ECCSZ BITS(17,19) /*!< ECC size */ + +/* EXMC_NINTEN */ +#define EXMC_NINTEN_INTRS BIT(0) /*!< rising edge interrupt status bit */ +#define EXMC_NINTEN_INTHS BIT(1) /*!< high-level interrupt status bit */ +#define EXMC_NINTEN_INTFS BIT(2) /*!< falling edge interrupt status bit */ +#define EXMC_NINTEN_INTREN BIT(3) /*!< rising edge detection interrupt enable bit */ +#define EXMC_NINTEN_INTHEN BIT(4) /*!< high-level detection interrupt enable bit */ +#define EXMC_NINTEN_INTFEN BIT(5) /*!< falling edge detection interrupt enable bit */ +#define EXMC_NINTEN_FFEPT BIT(6) /*!< FIFO empty flag */ + +/* EXMC_NCTCFG */ +#define EXMC_NCTCFG_COMSET BITS(0,7) /*!< common memory setup time */ +#define EXMC_NCTCFG_COMWAIT BITS(8,15) /*!< common memory wait time */ +#define EXMC_NCTCFG_COMHLD BITS(16,23) /*!< common memory hold time */ +#define EXMC_NCTCFG_COMHIZ BITS(24,31) /*!< common memory data bus HiZ time */ + +/* EXMC_NATCFG */ +#define EXMC_NATCFG_ATTSET BITS(0,7) /*!< attribute memory setup time */ +#define EXMC_NATCFG_ATTWAIT BITS(8,15) /*!< attribute memory wait time */ +#define EXMC_NATCFG_ATTHLD BITS(16,23) /*!< attribute memory hold time */ +#define EXMC_NATCFG_ATTHIZ BITS(24,31) /*!< attribute memory data bus HiZ time */ + +/* EXMC_NECC */ +#define EXMC_NECC_ECC BITS(0,31) /*!< ECC result */ + +/* EXMC_SDCTLx,(x=0,1) */ +#define EXMC_SDCTL_CAW BITS(0,1) /*!< column address bit width */ +#define EXMC_SDCTL_RAW BITS(2,3) /*!< row address bit width */ +#define EXMC_SDCTL_SDW BITS(4,5) /*!< SDRAM data bus width */ +#define EXMC_SDCTL_NBK BIT(6) /*!< number of banks */ +#define EXMC_SDCTL_CL BIT(7,8) /*!< CAS Latency */ +#define EXMC_SDCTL_WPEN BIT(9) /*!< write protection enable */ +#define EXMC_SDCTL_SDCLK BITS(10,11) /*!< SDRAM clock configuration */ +#define EXMC_SDCTL_BRSTRD BIT(12) /*!< burst read enable bit */ +#define EXMC_SDCTL_PIPED BITS(13,14) /*!< pipeline delay */ +#define EXMC_SDCTL_SDCLK_2 BIT(15) /*!< bit 2 SDCLK */ + +/* EXMC_SDTCFGx,(x=0,1) */ +#define EXMC_SDTCFG_LMRD BITS(0,3) /*!< load mode register delay */ +#define EXMC_SDTCFG_XSRD BITS(4,7) /*!< exit self-refresh delay */ +#define EXMC_SDTCFG_RASD BITS(8,11) /*!< row address select delay */ +#define EXMC_SDTCFG_ARFD BITS(12,15) /*!< auto refresh delay */ +#define EXMC_SDTCFG_WRD BITS(16,19) /*!< write recovery delay */ +#define EXMC_SDTCFG_RPD BITS(20,23) /*!< row precharge delay */ +#define EXMC_SDTCFG_RCD BITS(24,27) /*!< row to column delay */ + +/* EXMC_SDCMD */ +#define EXMC_SDCMD_CMD BITS(0,2) /*!< command */ +#define EXMC_SDCMD_DS1 BIT(3) /*!< select device1 */ +#define EXMC_SDCMD_DS0 BIT(4) /*!< select device0 */ +#define EXMC_SDCMD_NARF BITS(5,8) /*!< number of successive auto-refresh */ +#define EXMC_SDCMD_MRC BITS(9,21) /*!< mode register content */ + +/* EXMC_SDARI */ +#define EXMC_SDARI_REC BIT(0) /*!< refresh error flag clear */ +#define EXMC_SDARI_ARINTV BITS(1,13) /*!< auto-refresh interval */ +#define EXMC_SDARI_REIE BIT(14) /*!< refresh error interrupt enable bit */ + +/* EXMC_SDSTAT */ +#define EXMC_SDSDAT_REIF BIT(0) /*!< refresh error interrupt flag */ +#define EXMC_SDSDAT_STA0 BITS(1,2) /*!< device0 status */ +#define EXMC_SDSDAT_STA1 BITS(3,4) /*!< device1 status */ +#define EXMC_SDSDAT_NRDY BIT(5) /*!< not ready status */ + +/* EXMC_SDRSCTL */ +#define EXMC_SDRSCTL_RSEN BIT(0) /*!< read sample enable bit */ +#define EXMC_SDRSCTL_SSCR BIT(1) /*!< select sample cycle of read data */ +#define EXMC_SDRSCTL_SDSC BITS(4,7) /*!< select the delayed sample clock of read data */ + +/* constants definitions */ +/* EXMC NOR/SRAM timing initialize structure */ +typedef struct { + uint32_t asyn_access_mode; /*!< asynchronous access mode */ + uint32_t syn_data_latency; /*!< configure the data latency */ + uint32_t syn_clk_division; /*!< configure the clock divide ratio */ + uint32_t bus_latency; /*!< configure the bus latency */ + uint32_t asyn_data_setuptime; /*!< configure the data setup time, asynchronous access mode valid */ + uint32_t asyn_address_holdtime; /*!< configure the address hold time, asynchronous access mode valid */ + uint32_t asyn_address_setuptime; /*!< configure the address setup time, asynchronous access mode valid */ +} exmc_norsram_timing_parameter_struct; + +/* EXMC NOR/SRAM initialize structure */ +typedef struct { + uint32_t norsram_region; /*!< select the region of EXMC NOR/PSRAM region */ + uint32_t address_data_mux; /*!< specify whether the data bus and address bus are multiplexed */ + uint32_t memory_type; /*!< specify the type of external memory */ + uint32_t databus_width; /*!< specify the databus width of external memory */ + uint32_t burst_mode; /*!< enable or disable the burst mode */ + uint32_t nwait_polarity; /*!< specify the polarity of NWAIT signal from memory */ + uint32_t nwait_config; /*!< NWAIT signal configuration */ + uint32_t memory_write; /*!< enable or disable the write operation */ + uint32_t nwait_signal; /*!< enable or disable the NWAIT signal while in synchronous bust mode */ + uint32_t extended_mode; /*!< enable or disable the extended mode */ + uint32_t asyn_wait; /*!< enable or disable the asynchronous wait function */ + uint32_t cram_page_size; /*!< specify CRAM page size */ + uint32_t write_mode; /*!< the write mode, synchronous mode or asynchronous mode */ + exmc_norsram_timing_parameter_struct + *read_write_timing; /*!< timing parameters for read and write if the extendedmode is not used or the timing + parameters for read if the extendedmode is used */ + exmc_norsram_timing_parameter_struct *write_timing; /*!< timing parameters for write when the extendedmode is used */ +} exmc_norsram_parameter_struct; + +/* EXMC NAND timing initialize structure */ +typedef struct { + uint32_t databus_hiztime; /*!< configure the dadtabus HiZ time for write operation */ + uint32_t holdtime; /*!< configure the address hold time(or the data hold time for write operation) */ + uint32_t waittime; /*!< configure the minimum wait time */ + uint32_t setuptime; /*!< configure the address setup time */ +} exmc_nand_timing_parameter_struct; + +/* EXMC NAND initialize structure */ +typedef struct { + uint32_t ecc_size; /*!< the page size for the ECC calculation */ + uint32_t atr_latency; /*!< configure the latency of ALE low to RB low */ + uint32_t ctr_latency; /*!< configure the latency of CLE low to RB low */ + uint32_t ecc_logic; /*!< enable or disable the ECC calculation logic */ + uint32_t databus_width; /*!< the NAND flash databus width */ + uint32_t wait_feature; /*!< enable or disable the wait feature */ + exmc_nand_timing_parameter_struct *common_space_timing; /*!< the timing parameters for NAND flash common space */ + exmc_nand_timing_parameter_struct *attribute_space_timing; /*!< the timing parameters for NAND flash attribute space */ +} exmc_nand_parameter_struct; + +/* EXMC SDRAM timing initialize structure */ +typedef struct { + uint32_t row_to_column_delay; /*!< configure the row to column delay */ + uint32_t row_precharge_delay; /*!< configure the row precharge delay */ + uint32_t write_recovery_delay; /*!< configure the write recovery delay */ + uint32_t auto_refresh_delay; /*!< configure the auto refresh delay */ + uint32_t row_address_select_delay; /*!< configure the row address select delay */ + uint32_t exit_selfrefresh_delay; /*!< configure the exit self-refresh delay */ + uint32_t load_mode_register_delay; /*!< configure the load mode register delay */ +} exmc_sdram_timing_parameter_struct; + +/* EXMC SDRAM initialize structure */ +typedef struct { + uint32_t sdram_device; /*!< device of SDRAM */ + uint32_t pipeline_read_delay; /*!< the delay for reading data after CAS latency in CK_EXMC clock cycles */ + uint32_t burst_read_switch; /*!< enable or disable the burst read */ + uint32_t sdclock_config; /*!< the SDCLK memory clock for both SDRAM devices */ + uint32_t write_protection; /*!< enable or disable SDRAM device write protection function */ + uint32_t cas_latency; /*!< configure the SDRAM CAS latency */ + uint32_t internal_bank_number; /*!< the number of internal bank */ + uint32_t data_width; /*!< the databus width of SDRAM memory */ + uint32_t row_address_width; /*!< the bit width of a row address */ + uint32_t column_address_width; /*!< the bit width of a column address */ + exmc_sdram_timing_parameter_struct *timing; /*!< the timing parameters for write and read SDRAM */ +} exmc_sdram_parameter_struct; + +/* EXMC SDRAM command initialize structure */ +typedef struct { + uint32_t mode_register_content; /*!< the SDRAM mode register content */ + uint32_t auto_refresh_number; /*!< the number of successive auto-refresh cycles will be send when CMD = 011 */ + uint32_t bank_select; /*!< the bank which command will be sent to */ + uint32_t command; /*!< the commands that will be sent to SDRAM */ +} exmc_sdram_command_parameter_struct; + +/* EXMC_register address */ +#define EXMC_SNCTL(region) REG32(EXMC + 0x08U*((uint32_t)(region))) /*!< EXMC SRAM/NOR flash control registers, region = 0,1,2,3 */ +#define EXMC_SNTCFG(region) REG32(EXMC + 0x04U + 0x08U*((uint32_t)(region))) /*!< EXMC SRAM/NOR flash timing configuration registers, region = 0,1,2,3 */ +#define EXMC_SNWTCFG(region) REG32(EXMC + 0x104U + 0x08U*((uint32_t)(region))) /*!< EXMC SRAM/NOR flash write timing configuration registers, region = 0,1,2,3 */ + +#define EXMC_SDCTL(device) REG32(EXMC + 0x140U + 0x4U*(((uint32_t)(device)) - 0x4U)) /*!< EXMC SDRAM control registers,device = 0,1 */ +#define EXMC_SDTCFG(device) REG32(EXMC + 0x148U + 0x4U*(((uint32_t)(device)) - 0x4U)) /*!< EXMC SDRAM timing configuration registers,device = 0,1 */ + +/* bank remap */ +#define SNCTL_BKREMAP(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) +#define EXMC_BANK_REMAP_DEFAULT SNCTL_BKREMAP(0) /*!< default mapping */ +#define EXMC_BANK_NORPSRAM_SDRAM_SWAP SNCTL_BKREMAP(1) /*!< swap NOR/PSRAM bank and SDRAM device 0 address mapping */ + +/* CRAM page size */ +#define SNCTL_CPS(regval) (BITS(16,18) & ((uint32_t)(regval) << 16)) +#define EXMC_CRAM_AUTO_SPLIT SNCTL_CPS(0) /*!< automatic burst split on page boundary crossing */ +#define EXMC_CRAM_PAGE_SIZE_128_BYTES SNCTL_CPS(1) /*!< page size is 128 bytes */ +#define EXMC_CRAM_PAGE_SIZE_256_BYTES SNCTL_CPS(2) /*!< page size is 256 bytes */ +#define EXMC_CRAM_PAGE_SIZE_512_BYTES SNCTL_CPS(3) /*!< page size is 512 bytes */ +#define EXMC_CRAM_PAGE_SIZE_1024_BYTES SNCTL_CPS(4) /*!< page size is 1024 bytes */ + +/* NOR region memory data bus width */ +#define SNCTL_NRW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_NOR_DATABUS_WIDTH_8B SNCTL_NRW(0) /*!< NOR data width is 8 bits */ +#define EXMC_NOR_DATABUS_WIDTH_16B SNCTL_NRW(1) /*!< NOR data width is 16 bits */ + +/* NOR region memory type */ +#define SNCTL_NRTP(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define EXMC_MEMORY_TYPE_SRAM SNCTL_NRTP(0) /*!< SRAM,ROM */ +#define EXMC_MEMORY_TYPE_PSRAM SNCTL_NRTP(1) /*!< PSRAM,CRAM */ +#define EXMC_MEMORY_TYPE_NOR SNCTL_NRTP(2) /*!< NOR flash */ + +/* asynchronous access mode */ +#define SNTCFG_ASYNCMOD(regval) (BITS(28,29) & ((uint32_t)(regval) << 28)) +#define EXMC_ACCESS_MODE_A SNTCFG_ASYNCMOD(0) /*!< mode A access */ +#define EXMC_ACCESS_MODE_B SNTCFG_ASYNCMOD(1) /*!< mode B access */ +#define EXMC_ACCESS_MODE_C SNTCFG_ASYNCMOD(2) /*!< mode C access */ +#define EXMC_ACCESS_MODE_D SNTCFG_ASYNCMOD(3) /*!< mode D access */ + +/* data latency for NOR flash */ +#define SNTCFG_DLAT(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) +#define EXMC_DATALAT_2_CLK SNTCFG_DLAT(0) /*!< data latency of first burst access is 2 EXMC_CLK */ +#define EXMC_DATALAT_3_CLK SNTCFG_DLAT(1) /*!< data latency of first burst access is 3 EXMC_CLK */ +#define EXMC_DATALAT_4_CLK SNTCFG_DLAT(2) /*!< data latency of first burst access is 4 EXMC_CLK */ +#define EXMC_DATALAT_5_CLK SNTCFG_DLAT(3) /*!< data latency of first burst access is 5 EXMC_CLK */ +#define EXMC_DATALAT_6_CLK SNTCFG_DLAT(4) /*!< data latency of first burst access is 6 EXMC_CLK */ +#define EXMC_DATALAT_7_CLK SNTCFG_DLAT(5) /*!< data latency of first burst access is 7 EXMC_CLK */ +#define EXMC_DATALAT_8_CLK SNTCFG_DLAT(6) /*!< data latency of first burst access is 8 EXMC_CLK */ +#define EXMC_DATALAT_9_CLK SNTCFG_DLAT(7) /*!< data latency of first burst access is 9 EXMC_CLK */ +#define EXMC_DATALAT_10_CLK SNTCFG_DLAT(8) /*!< data latency of first burst access is 10 EXMC_CLK */ +#define EXMC_DATALAT_11_CLK SNTCFG_DLAT(9) /*!< data latency of first burst access is 11 EXMC_CLK */ +#define EXMC_DATALAT_12_CLK SNTCFG_DLAT(10) /*!< data latency of first burst access is 12 EXMC_CLK */ +#define EXMC_DATALAT_13_CLK SNTCFG_DLAT(11) /*!< data latency of first burst access is 13 EXMC_CLK */ +#define EXMC_DATALAT_14_CLK SNTCFG_DLAT(12) /*!< data latency of first burst access is 14 EXMC_CLK */ +#define EXMC_DATALAT_15_CLK SNTCFG_DLAT(13) /*!< data latency of first burst access is 15 EXMC_CLK */ +#define EXMC_DATALAT_16_CLK SNTCFG_DLAT(14) /*!< data latency of first burst access is 16 EXMC_CLK */ +#define EXMC_DATALAT_17_CLK SNTCFG_DLAT(15) /*!< data latency of first burst access is 17 EXMC_CLK */ + +/* synchronous clock divide ratio */ +#define SNTCFG_CKDIV(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) +#define EXMC_SYN_CLOCK_RATIO_DISABLE SNTCFG_CKDIV(0) /*!< no EXMC_CLK output */ +#define EXMC_SYN_CLOCK_RATIO_2_CLK SNTCFG_CKDIV(1) /*!< EXMC_CLK period = 2*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_3_CLK SNTCFG_CKDIV(2) /*!< EXMC_CLK period = 3*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_4_CLK SNTCFG_CKDIV(3) /*!< EXMC_CLK period = 4*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_5_CLK SNTCFG_CKDIV(4) /*!< EXMC_CLK period = 5*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_6_CLK SNTCFG_CKDIV(5) /*!< EXMC_CLK period = 6*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_7_CLK SNTCFG_CKDIV(6) /*!< EXMC_CLK period = 7*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_8_CLK SNTCFG_CKDIV(7) /*!< EXMC_CLK period = 8*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_9_CLK SNTCFG_CKDIV(8) /*!< EXMC_CLK period = 9*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_10_CLK SNTCFG_CKDIV(9) /*!< EXMC_CLK period = 10*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_11_CLK SNTCFG_CKDIV(10) /*!< EXMC_CLK period = 11*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_12_CLK SNTCFG_CKDIV(11) /*!< EXMC_CLK period = 12*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_13_CLK SNTCFG_CKDIV(12) /*!< EXMC_CLK period = 13*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_14_CLK SNTCFG_CKDIV(13) /*!< EXMC_CLK period = 14*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_15_CLK SNTCFG_CKDIV(14) /*!< EXMC_CLK period = 15*CK_EXMC period */ +#define EXMC_SYN_CLOCK_RATIO_16_CLK SNTCFG_CKDIV(15) /*!< EXMC_CLK period = 16*CK_EXMC period */ + +/* ECC size */ +#define NCTL_ECCSZ(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) +#define EXMC_ECC_SIZE_256BYTES NCTL_ECCSZ(0) /* ECC size is 256 bytes */ +#define EXMC_ECC_SIZE_512BYTES NCTL_ECCSZ(1) /* ECC size is 512 bytes */ +#define EXMC_ECC_SIZE_1024BYTES NCTL_ECCSZ(2) /* ECC size is 1024 bytes */ +#define EXMC_ECC_SIZE_2048BYTES NCTL_ECCSZ(3) /* ECC size is 2048 bytes */ +#define EXMC_ECC_SIZE_4096BYTES NCTL_ECCSZ(4) /* ECC size is 4096 bytes */ +#define EXMC_ECC_SIZE_8192BYTES NCTL_ECCSZ(5) /* ECC size is 8192 bytes */ + +/* ALE to RE delay */ +#define NCTL_ATR(regval) (BITS(13,16) & ((uint32_t)(regval) << 13)) +#define EXMC_ALE_RE_DELAY_1_CK_EXMC NCTL_ATR(0) /* ALE to RE delay = 1*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_2_CK_EXMC NCTL_ATR(1) /* ALE to RE delay = 2*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_3_CK_EXMC NCTL_ATR(2) /* ALE to RE delay = 3*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_4_CK_EXMC NCTL_ATR(3) /* ALE to RE delay = 4*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_5_CK_EXMC NCTL_ATR(4) /* ALE to RE delay = 5*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_6_CK_EXMC NCTL_ATR(5) /* ALE to RE delay = 6*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_7_CK_EXMC NCTL_ATR(6) /* ALE to RE delay = 7*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_8_CK_EXMC NCTL_ATR(7) /* ALE to RE delay = 8*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_9_CK_EXMC NCTL_ATR(8) /* ALE to RE delay = 9*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_10_CK_EXMC NCTL_ATR(9) /* ALE to RE delay = 10*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_11_CK_EXMC NCTL_ATR(10) /* ALE to RE delay = 11*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_12_CK_EXMC NCTL_ATR(11) /* ALE to RE delay = 12*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_13_CK_EXMC NCTL_ATR(12) /* ALE to RE delay = 13*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_14_CK_EXMC NCTL_ATR(13) /* ALE to RE delay = 14*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_15_CK_EXMC NCTL_ATR(14) /* ALE to RE delay = 15*CK_EXMC */ +#define EXMC_ALE_RE_DELAY_16_CK_EXMC NCTL_ATR(15) /* ALE to RE delay = 16*CK_EXMC */ + +/* CLE to RE delay */ +#define NCTL_CTR(regval) (BITS(9,12) & ((uint32_t)(regval) << 9)) +#define EXMC_CLE_RE_DELAY_1_CK_EXMC NCTL_CTR(0) /* CLE to RE delay = 1*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_2_CK_EXMC NCTL_CTR(1) /* CLE to RE delay = 2*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_3_CK_EXMC NCTL_CTR(2) /* CLE to RE delay = 3*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_4_CK_EXMC NCTL_CTR(3) /* CLE to RE delay = 4*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_5_CK_EXMC NCTL_CTR(4) /* CLE to RE delay = 5*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_6_CK_EXMC NCTL_CTR(5) /* CLE to RE delay = 6*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_7_CK_EXMC NCTL_CTR(6) /* CLE to RE delay = 7*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_8_CK_EXMC NCTL_CTR(7) /* CLE to RE delay = 8*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_9_CK_EXMC NCTL_CTR(8) /* CLE to RE delay = 9*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_10_CK_EXMC NCTL_CTR(9) /* CLE to RE delay = 10*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_11_CK_EXMC NCTL_CTR(10) /* CLE to RE delay = 11*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_12_CK_EXMC NCTL_CTR(11) /* CLE to RE delay = 12*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_13_CK_EXMC NCTL_CTR(12) /* CLE to RE delay = 13*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_14_CK_EXMC NCTL_CTR(13) /* CLE to RE delay = 14*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_15_CK_EXMC NCTL_CTR(14) /* CLE to RE delay = 15*CK_EXMC */ +#define EXMC_CLE_RE_DELAY_16_CK_EXMC NCTL_CTR(15) /* CLE to RE delay = 16*CK_EXMC */ + +/* NAND bank memory data bus width */ +#define NCTL_NDW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_NAND_DATABUS_WIDTH_8B NCTL_NDW(0) /*!< NAND data width is 8 bits */ +#define EXMC_NAND_DATABUS_WIDTH_16B NCTL_NDW(1) /*!< NAND data width is 16 bits */ + +/* SDRAM pipeline delay */ +#define SDCTL_PIPED(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) +#define EXMC_PIPELINE_DELAY_0_CK_EXMC SDCTL_PIPED(0) /*!< 0 CK_EXMC clock cycle delay */ +#define EXMC_PIPELINE_DELAY_1_CK_EXMC SDCTL_PIPED(1) /*!< 1 CK_EXMC clock cycle delay */ +#define EXMC_PIPELINE_DELAY_2_CK_EXMC SDCTL_PIPED(2) /*!< 2 CK_EXMC clock cycle delay */ + +/* SDRAM clock configuration */ +#define SDCTL_SDCLK(regval) (BITS(10,11) & ((uint32_t)(regval) << 10)) +#define EXMC_SDCLK_DISABLE SDCTL_SDCLK(0) /*!< SDCLK memory clock disabled */ +#define EXMC_SDCLK_PERIODS_2_CK_EXMC SDCTL_SDCLK(2) /*!< SDCLK memory period = 2*CK_EXMC */ +#define EXMC_SDCLK_PERIODS_3_CK_EXMC SDCTL_SDCLK(3) /*!< SDCLK memory period = 3*CK_EXMC */ +#define EXMC_SDCLK_PERIODS_4_CK_EXMC (EXMC_SDCTL_SDCLK_2 | SDCTL_SDCLK(2)) /*!< SDCLK memory period = 4*CK_EXMC */ +#define EXMC_SDCLK_PERIODS_5_CK_EXMC (EXMC_SDCTL_SDCLK_2 | SDCTL_SDCLK(3)) /*!< SDCLK memory period = 5*CK_EXMC */ + +/* CAS latency */ +#define SDCTL_CL(regval) (BITS(7,8) & ((uint32_t)(regval) << 7)) +#define EXMC_CAS_LATENCY_1_SDCLK SDCTL_CL(1) /*!< CAS latency is 1 memory clock cycle */ +#define EXMC_CAS_LATENCY_2_SDCLK SDCTL_CL(2) /*!< CAS latency is 2 memory clock cycle */ +#define EXMC_CAS_LATENCY_3_SDCLK SDCTL_CL(3) /*!< CAS latency is 3 memory clock cycle */ + +/* SDRAM data bus width */ +#define SDCTL_SDW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_SDRAM_DATABUS_WIDTH_8B SDCTL_SDW(0) /*!< SDRAM data width 8 bits */ +#define EXMC_SDRAM_DATABUS_WIDTH_16B SDCTL_SDW(1) /*!< SDRAM data width 16 bits */ +#define EXMC_SDRAM_DATABUS_WIDTH_32B SDCTL_SDW(2) /*!< SDRAM data width 32 bits */ + +/* SDRAM row address bit width */ +#define SDCTL_RAW(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define EXMC_SDRAM_ROW_ADDRESS_11 SDCTL_RAW(0) /*!< row address bit width is 11 bits */ +#define EXMC_SDRAM_ROW_ADDRESS_12 SDCTL_RAW(1) /*!< row address bit width is 12 bits */ +#define EXMC_SDRAM_ROW_ADDRESS_13 SDCTL_RAW(2) /*!< row address bit width is 13 bits */ + +/* SDRAM column address bit width */ +#define SDCTL_CAW(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define EXMC_SDRAM_COW_ADDRESS_8 SDCTL_CAW(0) /*!< column address bit width is 8 bits */ +#define EXMC_SDRAM_COW_ADDRESS_9 SDCTL_CAW(1) /*!< column address bit width is 9 bits */ +#define EXMC_SDRAM_COW_ADDRESS_10 SDCTL_CAW(2) /*!< column address bit width is 10 bits */ +#define EXMC_SDRAM_COW_ADDRESS_11 SDCTL_CAW(3) /*!< column address bit width is 11 bits */ + +/* SDRAM number of successive auto-refresh */ +#define SDCMD_NARF(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#define EXMC_SDRAM_AUTO_REFLESH_1_SDCLK SDCMD_NARF(0) /*!< 1 auto-refresh cycle */ +#define EXMC_SDRAM_AUTO_REFLESH_2_SDCLK SDCMD_NARF(1) /*!< 2 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_3_SDCLK SDCMD_NARF(2) /*!< 3 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_4_SDCLK SDCMD_NARF(3) /*!< 4 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_5_SDCLK SDCMD_NARF(4) /*!< 5 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_6_SDCLK SDCMD_NARF(5) /*!< 6 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_7_SDCLK SDCMD_NARF(6) /*!< 7 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_8_SDCLK SDCMD_NARF(7) /*!< 8 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_9_SDCLK SDCMD_NARF(8) /*!< 9 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_10_SDCLK SDCMD_NARF(9) /*!< 10 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_11_SDCLK SDCMD_NARF(10) /*!< 11 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_12_SDCLK SDCMD_NARF(11) /*!< 12 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_13_SDCLK SDCMD_NARF(12) /*!< 13 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_14_SDCLK SDCMD_NARF(13) /*!< 14 auto-refresh cycles */ +#define EXMC_SDRAM_AUTO_REFLESH_15_SDCLK SDCMD_NARF(14) /*!< 15 auto-refresh cycles */ + +/* SDRAM command selection */ +#define SDCMD_CMD(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define EXMC_SDRAM_NORMAL_OPERATION SDCMD_CMD(0) /*!< normal operation command */ +#define EXMC_SDRAM_CLOCK_ENABLE SDCMD_CMD(1) /*!< clock enable command */ +#define EXMC_SDRAM_PRECHARGE_ALL SDCMD_CMD(2) /*!< precharge all command */ +#define EXMC_SDRAM_AUTO_REFRESH SDCMD_CMD(3) /*!< auto-refresh command */ +#define EXMC_SDRAM_LOAD_MODE_REGISTER SDCMD_CMD(4) /*!< load mode register command */ +#define EXMC_SDRAM_SELF_REFRESH SDCMD_CMD(5) /*!< self-refresh command */ +#define EXMC_SDRAM_POWERDOWN_ENTRY SDCMD_CMD(6) /*!< power-down entry command */ + +/* SDRAM the delayed sample clock of read data */ +#define SDRSCTL_SDSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define EXMC_SDRAM_0_DELAY_CELL SDRSCTL_SDSC(0) /*!< select the clock after 0 delay cell */ +#define EXMC_SDRAM_1_DELAY_CELL SDRSCTL_SDSC(1) /*!< select the clock after 1 delay cell */ +#define EXMC_SDRAM_2_DELAY_CELL SDRSCTL_SDSC(2) /*!< select the clock after 2 delay cell */ +#define EXMC_SDRAM_3_DELAY_CELL SDRSCTL_SDSC(3) /*!< select the clock after 3 delay cell */ +#define EXMC_SDRAM_4_DELAY_CELL SDRSCTL_SDSC(4) /*!< select the clock after 4 delay cell */ +#define EXMC_SDRAM_5_DELAY_CELL SDRSCTL_SDSC(5) /*!< select the clock after 5 delay cell */ +#define EXMC_SDRAM_6_DELAY_CELL SDRSCTL_SDSC(6) /*!< select the clock after 6 delay cell */ +#define EXMC_SDRAM_7_DELAY_CELL SDRSCTL_SDSC(7) /*!< select the clock after 7 delay cell */ +#define EXMC_SDRAM_8_DELAY_CELL SDRSCTL_SDSC(8) /*!< select the clock after 8 delay cell */ +#define EXMC_SDRAM_9_DELAY_CELL SDRSCTL_SDSC(9) /*!< select the clock after 9 delay cell */ +#define EXMC_SDRAM_10_DELAY_CELL SDRSCTL_SDSC(10) /*!< select the clock after 10 delay cell */ +#define EXMC_SDRAM_11_DELAY_CELL SDRSCTL_SDSC(11) /*!< select the clock after 11 delay cell */ +#define EXMC_SDRAM_12_DELAY_CELL SDRSCTL_SDSC(12) /*!< select the clock after 12 delay cell */ +#define EXMC_SDRAM_13_DELAY_CELL SDRSCTL_SDSC(13) /*!< select the clock after 13 delay cell */ +#define EXMC_SDRAM_14_DELAY_CELL SDRSCTL_SDSC(14) /*!< select the clock after 14 delay cell */ +#define EXMC_SDRAM_15_DELAY_CELL SDRSCTL_SDSC(15) /*!< select the clock after 15 delay cell */ + +/* EXMC NOR/SRAM bank region definition */ +#define EXMC_BANK0_NORSRAM_REGION0 ((uint32_t)0x00000000U) /*!< bank0 NOR/SRAM region0 */ +#define EXMC_BANK0_NORSRAM_REGION1 ((uint32_t)0x00000001U) /*!< bank0 NOR/SRAM region1 */ +#define EXMC_BANK0_NORSRAM_REGION2 ((uint32_t)0x00000002U) /*!< bank0 NOR/SRAM region2 */ +#define EXMC_BANK0_NORSRAM_REGION3 ((uint32_t)0x00000003U) /*!< bank0 NOR/SRAM region3 */ + +/* EXMC consecutive clock */ +#define EXMC_CLOCK_SYN_MODE ((uint32_t)0x00000000U) /*!< EXMC_CLK is generated only during synchronous access */ +#define EXMC_CLOCK_UNCONDITIONALLY EXMC_SNCTL_CCK /*!< EXMC_CLK is generated unconditionally */ + +/* EXMC NOR/SRAM write mode */ +#define EXMC_ASYN_WRITE ((uint32_t)0x00000000U) /*!< asynchronous write mode */ +#define EXMC_SYN_WRITE EXMC_SNCTL_SYNCWR /*!< synchronous write mode */ + +/* EXMC NWAIT signal configuration */ +#define EXMC_NWAIT_CONFIG_BEFORE ((uint32_t)0x00000000U) /*!< NWAIT signal is active one data cycle before wait state */ +#define EXMC_NWAIT_CONFIG_DURING EXMC_SNCTL_NRWTCFG /*!< NWAIT signal is active during wait state */ + +/* EXMC NWAIT signal polarity configuration */ +#define EXMC_NWAIT_POLARITY_LOW ((uint32_t)0x00000000U) /*!< low level is active of NWAIT */ +#define EXMC_NWAIT_POLARITY_HIGH EXMC_SNCTL_NRWTPOL /*!< high level is active of NWAIT */ + +/* EXMC NAND bank definition */ +#define EXMC_BANK2_NAND ((uint32_t)0x00000002U) /*!< NAND flash bank2 */ + +/* EXMC SDRAM bank definition */ +#define EXMC_SDRAM_DEVICE0 ((uint32_t)0x00000004U) /*!< SDRAM device0 */ +#define EXMC_SDRAM_DEVICE1 ((uint32_t)0x00000005U) /*!< SDRAM device1 */ + +/* EXMC SDRAM internal banks */ +#define EXMC_SDRAM_2_INTER_BANK ((uint32_t)0x00000000U) /*!< 2 internal banks */ +#define EXMC_SDRAM_4_INTER_BANK EXMC_SDCTL_NBK /*!< 4 internal banks */ + +/* SDRAM device0 select */ +#define EXMC_SDRAM_DEVICE0_UNSELECT ((uint32_t)0x00000000U) /*!< SDRAM device0 unselect */ +#define EXMC_SDRAM_DEVICE0_SELECT EXMC_SDCMD_DS0 /*!< SDRAM device0 select */ + +/* SDRAM device1 select */ +#define EXMC_SDRAM_DEVICE1_UNSELECT ((uint32_t)0x00000000U) /*!< SDRAM device1 unselect */ +#define EXMC_SDRAM_DEVICE1_SELECT EXMC_SDCMD_DS1 /*!< SDRAM device1 select */ + +/* SDRAM device status */ +#define EXMC_SDRAM_DEVICE_NORMAL ((uint32_t)0x00000000U) /*!< normal status */ +#define EXMC_SDRAM_DEVICE_SELF_REFRESH ((uint32_t)0x00000001U) /*!< self refresh status */ +#define EXMC_SDRAM_DEVICE_POWER_DOWN ((uint32_t)0x00000002U) /*!< power down status */ + +/* sample cycle of read data */ +#define EXMC_SDRAM_READSAMPLE_0_EXTRACK ((uint32_t)0x00000000U) /*!< add 0 extra CK_EXMC cycle to the read data sample clock besides the delay chain */ +#define EXMC_SDRAM_READSAMPLE_1_EXTRACK EXMC_SDRSCTL_SSCR /*!< add 1 extra CK_EXMC cycle to the read data sample clock besides the delay chain */ + +/* EXMC flag bits */ +#define EXMC_NAND_FLAG_RISE EXMC_NINTEN_INTRS /*!< rising edge interrupt status */ +#define EXMC_NAND_FLAG_LEVEL EXMC_NINTEN_INTHS /*!< high-level interrupt status */ +#define EXMC_NAND_FLAG_FALL EXMC_NINTEN_INTFS /*!< falling edge interrupt status */ +#define EXMC_NAND_FLAG_FIFOE EXMC_NINTEN_FFEPT /*!< FIFO empty flag */ +#define EXMC_SDRAM_FLAG_REFRESH EXMC_SDSDAT_REIF /*!< refresh error interrupt flag */ +#define EXMC_SDRAM_FLAG_NREADY EXMC_SDSDAT_NRDY /*!< not ready status */ + +/* EXMC interrupt bits */ +#define EXMC_NAND_INT_RISE EXMC_NINTEN_INTREN /*!< rising edge interrupt */ +#define EXMC_NAND_INT_LEVEL EXMC_NINTEN_INTHEN /*!< high-level interrupt */ +#define EXMC_NAND_INT_FALL EXMC_NINTEN_INTFEN /*!< falling edge interrupt */ +#define EXMC_SDRAM_INT_REFRESH EXMC_SDARI_REIE /*!< refresh error interrupt */ + +/* EXMC interrupt flag bits */ +#define EXMC_NAND_INT_FLAG_RISE EXMC_NINTEN_INTREN /*!< rising edge interrupt flag */ +#define EXMC_NAND_INT_FLAG_LEVEL EXMC_NINTEN_INTHEN /*!< high-level interrupt flag */ +#define EXMC_NAND_INT_FLAG_FALL EXMC_NINTEN_INTFEN /*!< falling edge interrupt flag */ +#define EXMC_SDRAM_INT_FLAG_REFRESH EXMC_SDARI_REIE /*!< refresh error interrupt flag */ + +/* function declarations */ +/* initialization functions */ +/* NOR/SRAM */ +/* deinitialize EXMC NOR/SRAM region */ +void exmc_norsram_deinit(uint32_t exmc_norsram_region); +/* initialize exmc_norsram_parameter_struct with the default values */ +void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct); +/* initialize EXMC NOR/SRAM region */ +void exmc_norsram_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct); +/* enable EXMC NOR/SRAM region */ +void exmc_norsram_enable(uint32_t exmc_norsram_region); +/* disable EXMC NOR/SRAM region */ +void exmc_norsram_disable(uint32_t exmc_norsram_region); +/* NAND */ +/* deinitialize EXMC NAND bank */ +void exmc_nand_deinit(void); +/* initialize exmc_nand_parameter_struct with the default values */ +void exmc_nand_struct_para_init(exmc_nand_parameter_struct *exmc_nand_init_struct); +/* initialize EXMC NAND bank */ +void exmc_nand_init(exmc_nand_parameter_struct *exmc_nand_init_struct); +/* enable EXMC NAND bank */ +void exmc_nand_enable(void); +/* disable EXMC NAND bank */ +void exmc_nand_disable(void); +/* SDRAM */ +/* deinitialize EXMC SDRAM device */ +void exmc_sdram_deinit(uint32_t exmc_sdram_device); +/* initialize exmc_sdram_parameter_struct with the default values */ +void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct); +/* initialize EXMC SDRAM device */ +void exmc_sdram_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct); + +/* configuration functions */ +/* NOR/SRAM */ +/* configure NOR/PSRAM and SDRAM remap */ +void exmc_norsram_sdram_remap_config(uint32_t bank_remap); +/* get NOR/PSRAM and SDRAM remap configuration */ +uint32_t exmc_norsram_sdram_remap_get(void); +/* configure consecutive clock mode (only supported in EXMC BANK0 REGION0) */ +void exmc_norsram_consecutive_clock_config(uint32_t clock_mode); +/* configure CRAM page size */ +void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_size); +/* NAND */ +/* enable or disable the EXMC NAND ECC function */ +void exmc_nand_ecc_config(ControlStatus newvalue); +/* get NAND ECC value */ +uint32_t exmc_ecc_get(void); +/* SDRAM */ +/* enable read sample function */ +void exmc_sdram_readsample_enable(void); +/* disable read sample function */ +void exmc_sdram_readsample_disable(void); +/* configure the delayed sample clock of read data */ +void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_clk); +/* configure the SDRAM memory command */ +void exmc_sdram_command_config(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct); +/* set auto-refresh interval */ +void exmc_sdram_refresh_count_set(uint32_t exmc_count); +/* set the number of successive auto-refresh command */ +void exmc_sdram_autorefresh_number_set(uint32_t exmc_number); +/* configure the write protection function */ +void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue); +/* get the status of SDRAM device0 or device1 */ +uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device); + +/* interrupt & flag functions */ +/* get EXMC flag status */ +FlagStatus exmc_flag_get(uint32_t exmc_bank, uint32_t flag); +/* clear EXMC flag status */ +void exmc_flag_clear(uint32_t exmc_bank, uint32_t flag); +/* enable EXMC interrupt */ +void exmc_interrupt_enable(uint32_t exmc_bank, uint32_t interrupt); +/* disable EXMC interrupt */ +void exmc_interrupt_disable(uint32_t exmc_bank, uint32_t interrupt); +/* get EXMC interrupt flag */ +FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank, uint32_t interrupt); +/* clear EXMC interrupt flag */ +void exmc_interrupt_flag_clear(uint32_t exmc_bank, uint32_t interrupt); + +#endif /* GD32H7XX_EXMC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exti.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exti.h new file mode 100644 index 0000000000..39bee0ec2c --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_exti.h @@ -0,0 +1,413 @@ +/*! + \file gd32h7xx_exti.h + \brief definitions for the EXTI + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_EXTI_H +#define GD32H7XX_EXTI_H + +#include "gd32h7xx.h" + +/* EXTI definition */ +#define EXTI EXTI_BASE /*!< EXTI base address */ + +/* registers definitions */ +#define EXTI_INTEN0 REG32(EXTI + 0x00000000U) /*!< interrupt enable register 0 */ +#define EXTI_EVEN0 REG32(EXTI + 0x00000004U) /*!< event enable register 0 */ +#define EXTI_RTEN0 REG32(EXTI + 0x00000008U) /*!< rising edge trigger enable register 0 */ +#define EXTI_FTEN0 REG32(EXTI + 0x0000000CU) /*!< falling edge trigger enable register 0 */ +#define EXTI_SWIEV0 REG32(EXTI + 0x00000010U) /*!< software interrupt event register 0 */ +#define EXTI_PD0 REG32(EXTI + 0x00000014U) /*!< pending register 0 */ +#define EXTI_INTEN1 REG32(EXTI + 0x00000018U) /*!< interrupt enable register 1 */ +#define EXTI_EVEN1 REG32(EXTI + 0x0000001CU) /*!< event enable register 1 */ +#define EXTI_RTEN1 REG32(EXTI + 0x00000020U) /*!< rising edge trigger enable register 1 */ +#define EXTI_FTEN1 REG32(EXTI + 0x00000024U) /*!< falling edge trigger enable register 1 */ +#define EXTI_SWIEV1 REG32(EXTI + 0x00000028U) /*!< software interrupt event register 1 */ +#define EXTI_PD1 REG32(EXTI + 0x0000002CU) /*!< pending register 1 */ + +/* bits definitions */ +/* EXTI_INTEN0 */ +#define EXTI_INTEN0_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN0_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN0_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN0_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN0_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN0_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN0_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN0_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN0_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN0_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN0_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN0_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN0_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN0_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN0_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN0_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN0_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN0_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN0_INTEN18 BIT(18) /*!< interrupt from line 18 */ +#define EXTI_INTEN0_INTEN19 BIT(19) /*!< interrupt from line 19 */ +#define EXTI_INTEN0_INTEN20 BIT(20) /*!< interrupt from line 20 */ +#define EXTI_INTEN0_INTEN21 BIT(21) /*!< interrupt from line 21 */ +#define EXTI_INTEN0_INTEN22 BIT(22) /*!< interrupt from line 22 */ +#define EXTI_INTEN0_INTEN23 BIT(23) /*!< interrupt from line 23 */ +#define EXTI_INTEN0_INTEN24 BIT(24) /*!< interrupt from line 24 */ +#define EXTI_INTEN0_INTEN25 BIT(25) /*!< interrupt from line 25 */ +#define EXTI_INTEN0_INTEN26 BIT(26) /*!< interrupt from line 26 */ +#define EXTI_INTEN0_INTEN27 BIT(27) /*!< interrupt from line 27 */ +#define EXTI_INTEN0_INTEN28 BIT(28) /*!< interrupt from line 28 */ +#define EXTI_INTEN0_INTEN29 BIT(29) /*!< interrupt from line 29 */ +#define EXTI_INTEN0_INTEN30 BIT(30) /*!< interrupt from line 30 */ +#define EXTI_INTEN0_INTEN31 BIT(31) /*!< interrupt from line 31 */ + +/* EXTI_EVEN0 */ +#define EXTI_EVEN0_EVEN0 BIT(0) /*!< event from line 0 */ +#define EXTI_EVEN0_EVEN1 BIT(1) /*!< event from line 1 */ +#define EXTI_EVEN0_EVEN2 BIT(2) /*!< event from line 2 */ +#define EXTI_EVEN0_EVEN3 BIT(3) /*!< event from line 3 */ +#define EXTI_EVEN0_EVEN4 BIT(4) /*!< event from line 4 */ +#define EXTI_EVEN0_EVEN5 BIT(5) /*!< event from line 5 */ +#define EXTI_EVEN0_EVEN6 BIT(6) /*!< event from line 6 */ +#define EXTI_EVEN0_EVEN7 BIT(7) /*!< event from line 7 */ +#define EXTI_EVEN0_EVEN8 BIT(8) /*!< event from line 8 */ +#define EXTI_EVEN0_EVEN9 BIT(9) /*!< event from line 9 */ +#define EXTI_EVEN0_EVEN10 BIT(10) /*!< event from line 10 */ +#define EXTI_EVEN0_EVEN11 BIT(11) /*!< event from line 11 */ +#define EXTI_EVEN0_EVEN12 BIT(12) /*!< event from line 12 */ +#define EXTI_EVEN0_EVEN13 BIT(13) /*!< event from line 13 */ +#define EXTI_EVEN0_EVEN14 BIT(14) /*!< event from line 14 */ +#define EXTI_EVEN0_EVEN15 BIT(15) /*!< event from line 15 */ +#define EXTI_EVEN0_EVEN16 BIT(16) /*!< event from line 16 */ +#define EXTI_EVEN0_EVEN17 BIT(17) /*!< event from line 17 */ +#define EXTI_EVEN0_EVEN18 BIT(18) /*!< event from line 18 */ +#define EXTI_EVEN0_EVEN19 BIT(19) /*!< event from line 19 */ +#define EXTI_EVEN0_EVEN20 BIT(20) /*!< event from line 20 */ +#define EXTI_EVEN0_EVEN21 BIT(21) /*!< event from line 21 */ +#define EXTI_EVEN0_EVEN22 BIT(22) /*!< event from line 22 */ +#define EXTI_EVEN0_EVEN23 BIT(23) /*!< event from line 23 */ +#define EXTI_EVEN0_EVEN24 BIT(24) /*!< event from line 24 */ +#define EXTI_EVEN0_EVEN25 BIT(25) /*!< event from line 25 */ +#define EXTI_EVEN0_EVEN26 BIT(26) /*!< event from line 26 */ +#define EXTI_EVEN0_EVEN27 BIT(27) /*!< event from line 27 */ +#define EXTI_EVEN0_EVEN28 BIT(28) /*!< event from line 28 */ +#define EXTI_EVEN0_EVEN29 BIT(29) /*!< event from line 29 */ +#define EXTI_EVEN0_EVEN30 BIT(30) /*!< event from line 30 */ +#define EXTI_EVEN0_EVEN31 BIT(31) /*!< event from line 31 */ + +/* EXTI_RTEN0 */ +#define EXTI_RTEN0_RTEN0 BIT(0) /*!< rising edge from line 0 */ +#define EXTI_RTEN0_RTEN1 BIT(1) /*!< rising edge from line 1 */ +#define EXTI_RTEN0_RTEN2 BIT(2) /*!< rising edge from line 2 */ +#define EXTI_RTEN0_RTEN3 BIT(3) /*!< rising edge from line 3 */ +#define EXTI_RTEN0_RTEN4 BIT(4) /*!< rising edge from line 4 */ +#define EXTI_RTEN0_RTEN5 BIT(5) /*!< rising edge from line 5 */ +#define EXTI_RTEN0_RTEN6 BIT(6) /*!< rising edge from line 6 */ +#define EXTI_RTEN0_RTEN7 BIT(7) /*!< rising edge from line 7 */ +#define EXTI_RTEN0_RTEN8 BIT(8) /*!< rising edge from line 8 */ +#define EXTI_RTEN0_RTEN9 BIT(9) /*!< rising edge from line 9 */ +#define EXTI_RTEN0_RTEN10 BIT(10) /*!< rising edge from line 10 */ +#define EXTI_RTEN0_RTEN11 BIT(11) /*!< rising edge from line 11 */ +#define EXTI_RTEN0_RTEN12 BIT(12) /*!< rising edge from line 12 */ +#define EXTI_RTEN0_RTEN13 BIT(13) /*!< rising edge from line 13 */ +#define EXTI_RTEN0_RTEN14 BIT(14) /*!< rising edge from line 14 */ +#define EXTI_RTEN0_RTEN15 BIT(15) /*!< rising edge from line 15 */ +#define EXTI_RTEN0_RTEN16 BIT(16) /*!< rising edge from line 16 */ +#define EXTI_RTEN0_RTEN17 BIT(17) /*!< rising edge from line 17 */ +#define EXTI_RTEN0_RTEN18 BIT(18) /*!< rising edge from line 18 */ +#define EXTI_RTEN0_RTEN19 BIT(19) /*!< rising edge from line 19 */ +#define EXTI_RTEN0_RTEN20 BIT(20) /*!< rising edge from line 20 */ +#define EXTI_RTEN0_RTEN21 BIT(21) /*!< rising edge from line 21 */ +#define EXTI_RTEN0_RTEN22 BIT(22) /*!< rising edge from line 22 */ +#define EXTI_RTEN0_RTEN23 BIT(23) /*!< rising edge from line 23 */ +#define EXTI_RTEN0_RTEN24 BIT(24) /*!< rising edge from line 24 */ +#define EXTI_RTEN0_RTEN25 BIT(25) /*!< rising edge from line 25 */ +#define EXTI_RTEN0_RTEN26 BIT(26) /*!< rising edge from line 26 */ +#define EXTI_RTEN0_RTEN27 BIT(27) /*!< rising edge from line 27 */ +#define EXTI_RTEN0_RTEN28 BIT(28) /*!< rising edge from line 28 */ +#define EXTI_RTEN0_RTEN29 BIT(29) /*!< rising edge from line 29 */ +#define EXTI_RTEN0_RTEN30 BIT(30) /*!< rising edge from line 30 */ +#define EXTI_RTEN0_RTEN31 BIT(31) /*!< rising edge from line 31 */ + +/* EXTI_FTEN0 */ +#define EXTI_FTEN0_FTEN0 BIT(0) /*!< falling edge from line 0 */ +#define EXTI_FTEN0_FTEN1 BIT(1) /*!< falling edge from line 1 */ +#define EXTI_FTEN0_FTEN2 BIT(2) /*!< falling edge from line 2 */ +#define EXTI_FTEN0_FTEN3 BIT(3) /*!< falling edge from line 3 */ +#define EXTI_FTEN0_FTEN4 BIT(4) /*!< falling edge from line 4 */ +#define EXTI_FTEN0_FTEN5 BIT(5) /*!< falling edge from line 5 */ +#define EXTI_FTEN0_FTEN6 BIT(6) /*!< falling edge from line 6 */ +#define EXTI_FTEN0_FTEN7 BIT(7) /*!< falling edge from line 7 */ +#define EXTI_FTEN0_FTEN8 BIT(8) /*!< falling edge from line 8 */ +#define EXTI_FTEN0_FTEN9 BIT(9) /*!< falling edge from line 9 */ +#define EXTI_FTEN0_FTEN10 BIT(10) /*!< falling edge from line 10 */ +#define EXTI_FTEN0_FTEN11 BIT(11) /*!< falling edge from line 11 */ +#define EXTI_FTEN0_FTEN12 BIT(12) /*!< falling edge from line 12 */ +#define EXTI_FTEN0_FTEN13 BIT(13) /*!< falling edge from line 13 */ +#define EXTI_FTEN0_FTEN14 BIT(14) /*!< falling edge from line 14 */ +#define EXTI_FTEN0_FTEN15 BIT(15) /*!< falling edge from line 15 */ +#define EXTI_FTEN0_FTEN16 BIT(16) /*!< falling edge from line 16 */ +#define EXTI_FTEN0_FTEN17 BIT(17) /*!< falling edge from line 17 */ +#define EXTI_FTEN0_FTEN18 BIT(18) /*!< falling edge from line 18 */ +#define EXTI_FTEN0_FTEN19 BIT(19) /*!< falling edge from line 19 */ +#define EXTI_FTEN0_FTEN20 BIT(20) /*!< falling edge from line 20 */ +#define EXTI_FTEN0_FTEN21 BIT(21) /*!< falling edge from line 21 */ +#define EXTI_FTEN0_FTEN22 BIT(22) /*!< falling edge from line 22 */ +#define EXTI_FTEN0_FTEN23 BIT(23) /*!< falling edge from line 23 */ +#define EXTI_FTEN0_FTEN24 BIT(24) /*!< falling edge from line 24 */ +#define EXTI_FTEN0_FTEN25 BIT(25) /*!< falling edge from line 25 */ +#define EXTI_FTEN0_FTEN26 BIT(26) /*!< falling edge from line 26 */ +#define EXTI_FTEN0_FTEN27 BIT(27) /*!< falling edge from line 27 */ +#define EXTI_FTEN0_FTEN28 BIT(28) /*!< falling edge from line 28 */ +#define EXTI_FTEN0_FTEN29 BIT(29) /*!< falling edge from line 29 */ +#define EXTI_FTEN0_FTEN30 BIT(30) /*!< falling edge from line 30 */ +#define EXTI_FTEN0_FTEN31 BIT(31) /*!< falling edge from line 31 */ + +/* EXTI_SWIEV0 */ +#define EXTI_SWIEV0_SWIEV0 BIT(0) /*!< software interrupt/event request from line 0 */ +#define EXTI_SWIEV0_SWIEV1 BIT(1) /*!< software interrupt/event request from line 1 */ +#define EXTI_SWIEV0_SWIEV2 BIT(2) /*!< software interrupt/event request from line 2 */ +#define EXTI_SWIEV0_SWIEV3 BIT(3) /*!< software interrupt/event request from line 3 */ +#define EXTI_SWIEV0_SWIEV4 BIT(4) /*!< software interrupt/event request from line 4 */ +#define EXTI_SWIEV0_SWIEV5 BIT(5) /*!< software interrupt/event request from line 5 */ +#define EXTI_SWIEV0_SWIEV6 BIT(6) /*!< software interrupt/event request from line 6 */ +#define EXTI_SWIEV0_SWIEV7 BIT(7) /*!< software interrupt/event request from line 7 */ +#define EXTI_SWIEV0_SWIEV8 BIT(8) /*!< software interrupt/event request from line 8 */ +#define EXTI_SWIEV0_SWIEV9 BIT(9) /*!< software interrupt/event request from line 9 */ +#define EXTI_SWIEV0_SWIEV10 BIT(10) /*!< software interrupt/event request from line 10 */ +#define EXTI_SWIEV0_SWIEV11 BIT(11) /*!< software interrupt/event request from line 11 */ +#define EXTI_SWIEV0_SWIEV12 BIT(12) /*!< software interrupt/event request from line 12 */ +#define EXTI_SWIEV0_SWIEV13 BIT(13) /*!< software interrupt/event request from line 13 */ +#define EXTI_SWIEV0_SWIEV14 BIT(14) /*!< software interrupt/event request from line 14 */ +#define EXTI_SWIEV0_SWIEV15 BIT(15) /*!< software interrupt/event request from line 15 */ +#define EXTI_SWIEV0_SWIEV16 BIT(16) /*!< software interrupt/event request from line 16 */ +#define EXTI_SWIEV0_SWIEV17 BIT(17) /*!< software interrupt/event request from line 17 */ +#define EXTI_SWIEV0_SWIEV18 BIT(18) /*!< software interrupt/event request from line 18 */ +#define EXTI_SWIEV0_SWIEV19 BIT(19) /*!< software interrupt/event request from line 19 */ +#define EXTI_SWIEV0_SWIEV20 BIT(20) /*!< software interrupt/event request from line 20 */ +#define EXTI_SWIEV0_SWIEV21 BIT(21) /*!< software interrupt/event request from line 21 */ +#define EXTI_SWIEV0_SWIEV22 BIT(22) /*!< software interrupt/event request from line 22 */ +#define EXTI_SWIEV0_SWIEV23 BIT(23) /*!< software interrupt/event request from line 23 */ +#define EXTI_SWIEV0_SWIEV24 BIT(24) /*!< software interrupt/event request from line 24 */ +#define EXTI_SWIEV0_SWIEV25 BIT(25) /*!< software interrupt/event request from line 25 */ +#define EXTI_SWIEV0_SWIEV26 BIT(26) /*!< software interrupt/event request from line 26 */ +#define EXTI_SWIEV0_SWIEV27 BIT(27) /*!< software interrupt/event request from line 27 */ +#define EXTI_SWIEV0_SWIEV28 BIT(28) /*!< software interrupt/event request from line 28 */ +#define EXTI_SWIEV0_SWIEV29 BIT(29) /*!< software interrupt/event request from line 29 */ +#define EXTI_SWIEV0_SWIEV30 BIT(30) /*!< software interrupt/event request from line 30 */ +#define EXTI_SWIEV0_SWIEV31 BIT(31) /*!< software interrupt/event request from line 31 */ + +/* EXTI_PD0 */ +#define EXTI_PD0_PD0 BIT(0) /*!< interrupt pending status from line 0 */ +#define EXTI_PD0_PD1 BIT(1) /*!< interrupt pending status from line 1 */ +#define EXTI_PD0_PD2 BIT(2) /*!< interrupt pending status from line 2 */ +#define EXTI_PD0_PD3 BIT(3) /*!< interrupt pending status from line 3 */ +#define EXTI_PD0_PD4 BIT(4) /*!< interrupt pending status from line 4 */ +#define EXTI_PD0_PD5 BIT(5) /*!< interrupt pending status from line 5 */ +#define EXTI_PD0_PD6 BIT(6) /*!< interrupt pending status from line 6 */ +#define EXTI_PD0_PD7 BIT(7) /*!< interrupt pending status from line 7 */ +#define EXTI_PD0_PD8 BIT(8) /*!< interrupt pending status from line 8 */ +#define EXTI_PD0_PD9 BIT(9) /*!< interrupt pending status from line 9 */ +#define EXTI_PD0_PD10 BIT(10) /*!< interrupt pending status from line 10 */ +#define EXTI_PD0_PD11 BIT(11) /*!< interrupt pending status from line 11 */ +#define EXTI_PD0_PD12 BIT(12) /*!< interrupt pending status from line 12 */ +#define EXTI_PD0_PD13 BIT(13) /*!< interrupt pending status from line 13 */ +#define EXTI_PD0_PD14 BIT(14) /*!< interrupt pending status from line 14 */ +#define EXTI_PD0_PD15 BIT(15) /*!< interrupt pending status from line 15 */ +#define EXTI_PD0_PD16 BIT(16) /*!< interrupt pending status from line 16 */ +#define EXTI_PD0_PD17 BIT(17) /*!< interrupt pending status from line 17 */ +#define EXTI_PD0_PD18 BIT(18) /*!< interrupt pending status from line 18 */ +#define EXTI_PD0_PD19 BIT(19) /*!< interrupt pending status from line 19 */ +#define EXTI_PD0_PD20 BIT(20) /*!< interrupt pending status from line 20 */ +#define EXTI_PD0_PD21 BIT(21) /*!< interrupt pending status from line 21 */ +#define EXTI_PD0_PD22 BIT(22) /*!< interrupt pending status from line 22 */ +#define EXTI_PD0_PD23 BIT(23) /*!< interrupt pending status from line 23 */ +#define EXTI_PD0_PD24 BIT(24) /*!< interrupt pending status from line 24 */ +#define EXTI_PD0_PD25 BIT(25) /*!< interrupt pending status from line 25 */ +#define EXTI_PD0_PD26 BIT(26) /*!< interrupt pending status from line 26 */ +#define EXTI_PD0_PD27 BIT(27) /*!< interrupt pending status from line 27 */ +#define EXTI_PD0_PD28 BIT(28) /*!< interrupt pending status from line 28 */ +#define EXTI_PD0_PD29 BIT(29) /*!< interrupt pending status from line 29 */ +#define EXTI_PD0_PD30 BIT(30) /*!< interrupt pending status from line 30 */ +#define EXTI_PD0_PD31 BIT(31) /*!< interrupt pending status from line 31 */ + +/* EXTI_INTEN1 */ +#define EXTI_INTEN1_INTEN32 BIT(0) /*!< interrupt from line 32 */ +#define EXTI_INTEN1_INTEN33 BIT(1) /*!< interrupt from line 33 */ +#define EXTI_INTEN1_INTEN34 BIT(2) /*!< interrupt from line 34 */ +#define EXTI_INTEN1_INTEN35 BIT(3) /*!< interrupt from line 35 */ +#define EXTI_INTEN1_INTEN36 BIT(4) /*!< interrupt from line 36 */ +#define EXTI_INTEN1_INTEN37 BIT(5) /*!< interrupt from line 37 */ + +/* EXTI_EVEN1 */ +#define EXTI_EVEN1_EVEN32 BIT(0) /*!< event from line 32 */ +#define EXTI_EVEN1_EVEN33 BIT(1) /*!< event from line 33 */ +#define EXTI_EVEN1_EVEN34 BIT(2) /*!< event from line 34 */ +#define EXTI_EVEN1_EVEN35 BIT(3) /*!< event from line 35 */ +#define EXTI_EVEN1_EVEN36 BIT(4) /*!< event from line 36 */ +#define EXTI_EVEN1_EVEN37 BIT(5) /*!< event from line 37 */ + +/* EXTI_RTEN1 */ +#define EXTI_RTEN1_RTEN32 BIT(0) /*!< rising edge from line 32 */ +#define EXTI_RTEN1_RTEN33 BIT(1) /*!< rising edge from line 33 */ +#define EXTI_RTEN1_RTEN34 BIT(2) /*!< rising edge from line 34 */ +#define EXTI_RTEN1_RTEN35 BIT(3) /*!< rising edge from line 35 */ +#define EXTI_RTEN1_RTEN36 BIT(4) /*!< rising edge from line 36 */ +#define EXTI_RTEN1_RTEN37 BIT(5) /*!< rising edge from line 37 */ + +/* EXTI_FTEN1 */ +#define EXTI_FTEN1_FTEN32 BIT(0) /*!< falling edge from line 32 */ +#define EXTI_FTEN1_FTEN33 BIT(1) /*!< falling edge from line 33 */ +#define EXTI_FTEN1_FTEN34 BIT(2) /*!< falling edge from line 34 */ +#define EXTI_FTEN1_FTEN35 BIT(3) /*!< falling edge from line 35 */ +#define EXTI_FTEN1_FTEN36 BIT(4) /*!< falling edge from line 36 */ +#define EXTI_FTEN1_FTEN37 BIT(5) /*!< falling edge from line 37 */ + +/* EXTI_SWIEV1 */ +#define EXTI_SWIEV1_SWIEV32 BIT(0) /*!< software interrupt/event request from line 32 */ +#define EXTI_SWIEV1_SWIEV33 BIT(1) /*!< software interrupt/event request from line 33 */ +#define EXTI_SWIEV1_SWIEV34 BIT(2) /*!< software interrupt/event request from line 34 */ +#define EXTI_SWIEV1_SWIEV35 BIT(3) /*!< software interrupt/event request from line 35 */ +#define EXTI_SWIEV1_SWIEV36 BIT(4) /*!< software interrupt/event request from line 36 */ +#define EXTI_SWIEV1_SWIEV37 BIT(5) /*!< software interrupt/event request from line 37 */ + +/* EXTI_PD1 */ +#define EXTI_PD1_PD32 BIT(0) /*!< interrupt pending status from line 32 */ +#define EXTI_PD1_PD33 BIT(1) /*!< interrupt pending status from line 33 */ +#define EXTI_PD1_PD34 BIT(2) /*!< interrupt pending status from line 34 */ +#define EXTI_PD1_PD35 BIT(3) /*!< interrupt pending status from line 35 */ +#define EXTI_PD1_PD36 BIT(4) /*!< interrupt pending status from line 36 */ +#define EXTI_PD1_PD37 BIT(5) /*!< interrupt pending status from line 37 */ + +/* constants definitions */ +/* define the EXTI bit position and its register group index offset */ +#define EXTI_GROUPIDX_BIT(groupidx, bitpos) (((uint32_t)(groupidx) << 8U) | (uint32_t)(bitpos)) +#define EXTI_REG_VAL(linex) (EXTI + ((uint32_t)(linex) >> 8U)) +#define EXTI_BIT_POS(linex) BIT((uint32_t)(linex) & 0x1FU) + +/* define the EXTI register groups*/ +#define EXTI_GROUP0_OFFSET 0x00000000U /*!< the index offset of EXTI group0 */ +#define EXTI_GROUP1_OFFSET 0x00000018U /*!< the index offset of EXTI group1 */ + +/* define the registers in the group*/ +#define EXTI_INTEN(exti_group) REG32((uint32_t)(exti_group) + 0x00000000U) /*!< the index offset of register INTEN in the registe group */ +#define EXTI_EVEN(exti_group) REG32((uint32_t)(exti_group) + 0x00000004U) /*!< the index offset of register EVEN in the registe group */ +#define EXTI_RTEN(exti_group) REG32((uint32_t)(exti_group) + 0x00000008U) /*!< the index offset of register RTEN in the registe group */ +#define EXTI_FTEN(exti_group) REG32((uint32_t)(exti_group) + 0x0000000CU) /*!< the index offset of register FTEN in the registe group */ +#define EXTI_SWIEV(exti_group) REG32((uint32_t)(exti_group) + 0x00000010U) /*!< the index offset of register SWIEV in the registe group */ +#define EXTI_PD(exti_group) REG32((uint32_t)(exti_group) + 0x00000014U) /*!< the index offset of register PD in the registe group */ + +/* EXTI line number */ +typedef enum { + EXTI_0 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 0U), /*!< EXTI line 0 */ + EXTI_1 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 1U), /*!< EXTI line 1 */ + EXTI_2 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 2U), /*!< EXTI line 2 */ + EXTI_3 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 3U), /*!< EXTI line 3 */ + EXTI_4 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 4U), /*!< EXTI line 4 */ + EXTI_5 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 5U), /*!< EXTI line 5 */ + EXTI_6 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 6U), /*!< EXTI line 6 */ + EXTI_7 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 7U), /*!< EXTI line 7 */ + EXTI_8 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 8U), /*!< EXTI line 8 */ + EXTI_9 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 9U), /*!< EXTI line 9 */ + EXTI_10 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 10U), /*!< EXTI line 10 */ + EXTI_11 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 11U), /*!< EXTI line 11 */ + EXTI_12 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 12U), /*!< EXTI line 12 */ + EXTI_13 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 13U), /*!< EXTI line 13 */ + EXTI_14 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 14U), /*!< EXTI line 14 */ + EXTI_15 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 15U), /*!< EXTI line 15 */ + EXTI_16 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 16U), /*!< EXTI line 16 */ + EXTI_17 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 17U), /*!< EXTI line 17 */ + EXTI_18 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 18U), /*!< EXTI line 18 */ + EXTI_19 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 19U), /*!< EXTI line 19 */ + EXTI_20 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 20U), /*!< EXTI line 20 */ + EXTI_21 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 21U), /*!< EXTI line 21 */ + EXTI_22 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 22U), /*!< EXTI line 22 */ + EXTI_23 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 23U), /*!< EXTI line 23 */ + EXTI_24 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 24U), /*!< EXTI line 24 */ + EXTI_25 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 25U), /*!< EXTI line 25 */ + EXTI_26 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 26U), /*!< EXTI line 26 */ + EXTI_27 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 27U), /*!< EXTI line 27 */ + EXTI_28 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 28U), /*!< EXTI line 28 */ + EXTI_29 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 29U), /*!< EXTI line 29 */ + EXTI_30 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 30U), /*!< EXTI line 30 */ + EXTI_31 = EXTI_GROUPIDX_BIT(EXTI_GROUP0_OFFSET, 31U), /*!< EXTI line 31 */ + EXTI_32 = EXTI_GROUPIDX_BIT(EXTI_GROUP1_OFFSET, 32U), /*!< EXTI line 32 */ + EXTI_33 = EXTI_GROUPIDX_BIT(EXTI_GROUP1_OFFSET, 33U), /*!< EXTI line 33 */ + EXTI_34 = EXTI_GROUPIDX_BIT(EXTI_GROUP1_OFFSET, 34U), /*!< EXTI line 34 */ + EXTI_35 = EXTI_GROUPIDX_BIT(EXTI_GROUP1_OFFSET, 35U), /*!< EXTI line 35 */ + EXTI_36 = EXTI_GROUPIDX_BIT(EXTI_GROUP1_OFFSET, 36U), /*!< EXTI line 36 */ + EXTI_37 = EXTI_GROUPIDX_BIT(EXTI_GROUP1_OFFSET, 37U) /*!< EXTI line 37 */ +} exti_line_enum; + +/* external interrupt and event */ +typedef enum { + EXTI_INTERRUPT = 0, /*!< EXTI interrupt mode */ + EXTI_EVENT /*!< EXTI event mode */ +} exti_mode_enum; + +/* interrupt and event trigger mode */ +typedef enum { + EXTI_TRIG_RISING = 0, /*!< EXTI rising edge trigger */ + EXTI_TRIG_FALLING, /*!< EXTI falling edge trigger */ + EXTI_TRIG_BOTH, /*!< EXTI rising and falling edge trigger */ + EXTI_TRIG_NONE /*!< without rising edge or falling edge trigger */ +} exti_trig_type_enum; + +/* function declarations */ +/* initialization, EXTI lines configuration functions */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* initialize the EXTI line x */ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); +/* enable the interrupts from EXTI line x */ +void exti_interrupt_enable(exti_line_enum linex); +/* disable the interrupts from EXTI line x */ +void exti_interrupt_disable(exti_line_enum linex); +/* enable the events from EXTI line x */ +void exti_event_enable(exti_line_enum linex); +/* disable the events from EXTI line x */ +void exti_event_disable(exti_line_enum linex); +/* enable the software interrupt event from EXTI line x */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* disable the software interrupt event from EXTI line x */ +void exti_software_interrupt_disable(exti_line_enum linex); + +/* interrupt & flag functions */ +/* get EXTI line x interrupt pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI line x interrupt pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI line x interrupt pending flag */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI line x interrupt pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); + +#endif /* GD32H7XX_EXTI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fac.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fac.h new file mode 100644 index 0000000000..9e0cdfd9d8 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fac.h @@ -0,0 +1,268 @@ +/*! + \file gd32h7xx_fac.c + \brief definitions for the FAC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_FAC_H +#define GD32H7XX_FAC_H + +#include "gd32h7xx.h" + +/* FAC definitions */ +#define FAC FAC_BASE /*!< FAC base address */ + +#define REG16_INT(addr) (*(volatile int16_t *)(uint32_t)(addr)) +#define REG32_FLOAT(addr) (*(volatile float *)(uint32_t)(addr)) + +/* registers definitions */ +#define FAC_X0BCFG REG32((FAC) + 0x00000000U) /*!< FAC X0 buffer configure register */ +#define FAC_X1BCFG REG32((FAC) + 0x00000004U) /*!< FAC X1 buffer configure register */ +#define FAC_YBCFG REG32((FAC) + 0x00000008U) /*!< FAC Y buffer configure register */ +#define FAC_PARACFG REG32((FAC) + 0x0000000CU) /*!< FAC Parameter configure register */ +#define FAC_CTL REG32((FAC) + 0x00000010U) /*!< FAC Control register */ +#define FAC_STAT REG32((FAC) + 0x00000014U) /*!< FAC Status register */ +#define FAC_WDATA REG32((FAC) + 0x00000018U) /*!< FAC write data register */ +#define FAC_RDATA REG32((FAC) + 0x0000001CU) /*!< FAC read data register */ + +#define FAC_WDATA_INT REG16_INT((FAC) + 0x00000018U) /*!< FAC write data register */ +#define FAC_WDATA_FLOAT REG32_FLOAT((FAC) + 0x00000018U)/*!< FAC write data register */ + +#define FAC_RDATA_INT REG16_INT((FAC) + 0x0000001CU) /*!< FAC read data register */ +#define FAC_RDATA_FLOAT REG32_FLOAT((FAC) + 0x0000001CU)/*!< FAC read data register */ + +/* bits definitions */ +/* FAC_X0BCFG */ +#define FAC_X0BCFG_X0B_ADDR BITS(0,7) /*!< X0 buffer base address */ +#define FAC_X0BCFG_X0B_SIZE BITS(8,15) /*!< X0 buffer allocated size */ +#define FAC_X0BCFG_X0_WBFF BITS(24,25) /*!< watermark for buffer full flag */ + +/* FAC_X1BCFG */ +#define FAC_X1BCFG_X1B_ADDR BITS(0,7) /*!< X1 buffer base address */ +#define FAC_X1BCFG_X1B_SIZE BITS(8,15) /*!< X1 buffer allocated size */ + +/* FAC_YBCFG */ +#define FAC_YBCFG_YB_ADDR BITS(0,7) /*!< Y buffer base address */ +#define FAC_YBCFG_YB_SIZE BITS(8,15) /*!< Y buffer allocated size */ +#define FAC_YBCFG_Y_WBEF BITS(24,25) /*!< watermark for buffer empty flag */ + +/* FAC_PARACFG */ +#define FAC_PARACFG_IPP BITS(0,7) /*!< input parameter IPP */ +#define FAC_PARACFG_IPQ BITS(8,15) /*!< input parameter IPQ */ +#define FAC_PARACFG_IPR BITS(16,23) /*!< input parameter IPR */ +#define FAC_PARACFG_FUN BITS(24,30) /*!< function */ +#define FAC_PARACFG_EXE BIT(31) /*!< execution */ + +/* FAC_CTL */ +#define FAC_CTL_RIE BIT(0) /*!< read interrupt enable */ +#define FAC_CTL_WIE BIT(1) /*!< write interrupt enable */ +#define FAC_CTL_OFEIE BIT(2) /*!< overflow error interrupt enable */ +#define FAC_CTL_UFEIE BIT(3) /*!< underflow error interrupt enable */ +#define FAC_CTL_STEIE BIT(4) /*!< saturation error interrupt enable */ +#define FAC_CTL_GSTEIE BIT(5) /*!< gain saturation error interrupt enable */ +#define FAC_CTL_DREN BIT(8) /*!< DMA read channel enable */ +#define FAC_CTL_DWEN BIT(9) /*!< DMA write channel enable */ +#define FAC_CTL_FLTEN BIT(14) /*!< floating point format enable */ +#define FAC_CTL_CPEN BIT(15) /*!< clipping enable */ +#define FAC_CTL_RST BIT(16) /*!< reset FAC unit */ + +/* FAC_STAT */ +#define FAC_STAT_YBEF BIT(0) /*!< Y buffer empty flag */ +#define FAC_STAT_X0BFF BIT(1) /*!< X0 buffer full flag */ +#define FAC_STAT_OFEF BIT(8) /*!< overflow error flag */ +#define FAC_STAT_UFEF BIT(9) /*!< underflow error flag */ +#define FAC_STAT_STEF BIT(10) /*!< saturation error flag */ +#define FAC_STAT_GSTEF BIT(11) /*!< gain saturation error flag */ + +/* FAC_WDATA */ +#define FAC_WDATA_WDATA BITS(0,15) /*!< Write data */ + +/* FAC_RDATA */ +#define FAC_RDATA_RDATA BITS(0,15) /*!< Read data */ + +/* constants definitions */ +/* structure for fac filter parameters */ +typedef struct +{ + uint8_t input_addr; /*!< base address of the input buffer (X0) */ + uint8_t input_size; /*!< size of input buffer */ + uint8_t coeff_addr; /*!< base address of the coefficient buffer (X1) */ + uint8_t coeff_size; /*!< size of coefficient buffer */ + uint8_t output_addr; /*!< base address of the output buffer (Y) */ + uint8_t output_size; /*!< size of output buffer */ + uint8_t ipp; /*!< value P (vector length, number of filter taps, etc.) */ + uint8_t ipq; /*!< value Q (vector length, etc.) */ + uint8_t ipr; /*!< value R (gain, etc.) */ + uint32_t input_threshold; /*!< threshold of input buffer full */ + uint32_t output_threshold; /*!< threshold of output buffer empty */ + uint32_t clip; /*!< enable or disable the clipping feature */ + uint32_t func; /*!< FAC functions select */ +}fac_parameter_struct; + +/* structure for fac fixed data preload parameters */ +typedef struct +{ + uint8_t coeffa_size; /*!< size of the coefficient vector A */ + int16_t *coeffa_ctx; /*!< [IIR only] content of the coefficient vector A */ + uint8_t coeffb_size; /*!< size of the coefficient vector B */ + int16_t *coeffb_ctx; /*!< content of the coefficient vector B */ + uint8_t input_size; /*!< Size of the input data */ + int16_t *input_ctx; /*!< content of the input data */ + uint8_t output_size; /*!< size of the output data */ + int16_t *output_ctx; /*!< content of the output data */ +}fac_fixed_data_preload_struct; + +/* structure for fac float data preload parameters */ +typedef struct +{ + uint8_t coeffa_size; /*!< size of the coefficient vector A */ + float *coeffa_ctx; /*!< [IIR only] content of the coefficient vector A */ + uint8_t coeffb_size; /*!< size of the coefficient vector B */ + float *coeffb_ctx; /*!< content of the coefficient vector B */ + uint8_t input_size; /*!< size of the input data */ + float *input_ctx; /*!< content of the input data */ + uint8_t output_size; /*!< size of the output data */ + float *output_ctx; /*!< content of the output data */ +}fac_float_data_preload_struct; + +/* FAC function select definitions */ +#define PARACFG_FUN(regval) (FAC_PARACFG_FUN & ((uint32_t)(regval) << 24)) +#define FUNC_LOAD_X0 PARACFG_FUN(1) /*!< load_X0_buffer */ +#define FUNC_LOAD_X1 PARACFG_FUN(2) /*!< load_X1_buffer */ +#define FUNC_LOAD_Y PARACFG_FUN(3) /*!< load_Y_buffer */ +#define FUNC_CONVO_FIR PARACFG_FUN(8) /*!< convolution (FIR filter) */ +#define FUNC_IIR_DIRECT_FORM_1 PARACFG_FUN(9) /*!< IIR filter (direct form 1) */ + +/* FAC watermark setting definitions */ +#define X0BCFG_X0_WBFF(regval) (FAC_X0BCFG_X0_WBFF & ((uint32_t)(regval) << 24)) +#define FAC_THRESHOLD_1 X0BCFG_X0_WBFF(0) /*!< full/empty flag when buffer less than 1 */ +#define FAC_THRESHOLD_2 X0BCFG_X0_WBFF(1) /*!< full/empty flag when buffer less than 2 */ +#define FAC_THRESHOLD_4 X0BCFG_X0_WBFF(2) /*!< full/empty flag when buffer less than 4 */ +#define FAC_THRESHOLD_8 X0BCFG_X0_WBFF(3) /*!< full/empty flag when buffer less than 8 */ + +/* FAC clip function definitions */ +#define FAC_CP_DISABLE ((uint8_t)0x00U) /*!< clipping disabled */ +#define FAC_CP_ENABLE ((uint8_t)0x01U) /*!< clipping enabled */ + +/* FAC function execution definitions */ +#define PARACFG_EXE(regval) (FAC_PARACFG_EXE & ((uint32_t)(regval) << 31)) +#define FAC_FUNC_START PARACFG_EXE(0) /*!< start execution function */ +#define FAC_FUNC_STOP PARACFG_EXE(1) /*!< stop execution function */ + +/* FAC DMA mdoe definitions */ +#define FAC_DMA_READ FAC_CTL_DREN /*!< enable dma read */ +#define FAC_DMA_WRITE FAC_CTL_DWEN /*!< enable dma write */ + +/* FAC interrupt flag definitions */ +#define FAC_INT_FLAG_YBEF ((uint8_t)0x00U) /*!< Y buffer empty interrupt flag */ +#define FAC_INT_FLAG_X0BFF ((uint8_t)0x01U) /*!< X0 buffer full interrupt flag */ +#define FAC_INT_FLAG_OFEF ((uint8_t)0x02U) /*!< Overflow error interrupt flag */ +#define FAC_INT_FLAG_UFEF ((uint8_t)0x03U) /*!< underflow error interrupt flag */ +#define FAC_INT_FLAG_STEF ((uint8_t)0x04U) /*!< saturation error interrupt flag */ +#define FAC_INT_FLAG_GSTEF ((uint8_t)0x05U) /*!< gain saturation error interrupt flag */ + +/* FAC flag definitions */ +#define FAC_FLAG_YBEF FAC_STAT_YBEF /*!< Y buffer empty flag */ +#define FAC_FLAG_X0BFF FAC_STAT_X0BFF /*!< X0 buffer full flag */ +#define FAC_FLAG_OFEF FAC_STAT_OFEF /*!< overflow error flag */ +#define FAC_FLAG_UFEF FAC_STAT_UFEF /*!< underflow error flag */ +#define FAC_FLAG_STEF FAC_STAT_STEF /*!< saturation error flag */ +#define FAC_FLAG_GSTEF FAC_STAT_GSTEF /*!< gain saturation error flag */ + +/* FAC function declarations */ +/* initialization functions */ +/* reset the FAC peripheral */ +void fac_deinit(void); +/* initialize the FAC filter parameter struct with the default values */ +void fac_struct_para_init(fac_parameter_struct* fac_parameter); +/* initialize the FAC fixed data preload parameter struct with the default values */ +void fac_fixed_data_preload_init(fac_fixed_data_preload_struct *init_struct); +/* initialize the FAC float data preload parameter struct with the default values */ +void fac_float_data_preload_init(fac_float_data_preload_struct *init_struct); +/* initialize the FAC peripheral */ +void fac_init(fac_parameter_struct* fac_parameter); +/* FAC preload X0 X1 Y fixed buffer */ +void fac_fixed_buffer_preload(fac_fixed_data_preload_struct* init_struct); +/* FAC preload X0 X1 Y float buffer*/ +void fac_float_buffer_preload(fac_float_data_preload_struct* init_struct); +/* FAC preload data */ +void fac_fixed_data_preload(uint8_t size, int16_t array[]); +/* FAC preload float data */ +void fac_float_data_preload(uint8_t size, float array[]); +/* configuration functions */ +/* FAC reset write and read pointers */ +void fac_reset(void); +/* config the FAC clip feature */ +void fac_clip_config(uint8_t cpmod); +/* enable FAC float point format */ +void fac_float_enable(void); +/* disable FAC float point format */ +void fac_float_disable(void); +/* enable the FAC dma */ +void fac_dma_enable(uint32_t dma_req); +/* disable the FAC dma */ +void fac_dma_disable(uint32_t dma_req); +/* FAC config input buffer */ +void fac_x0_config(uint32_t watermark, uint8_t baseaddr, uint8_t bufsize); +/* FAC config coefficient buffer */ +void fac_x1_config(uint8_t baseaddr, uint8_t bufsize); +/* FAC config output buffer */ +void fac_y_config(uint32_t watermark, uint8_t baseaddr, uint8_t bufsize); +/* FAC config function execute */ +void fac_function_config(fac_parameter_struct* fac_parameter); +/* start the FAC */ +void fac_start(void); +/* stop the FAC */ +void fac_stop(void); +/* finish the filter calculate */ +void fac_finish_calculate(void); + +/* FAC data write and read */ +/* FAC write data with fixed ponit format */ +void fac_fixed_data_write(int16_t data); +/* FAC read data with fixed point format */ +int16_t fac_fixed_data_read(void); +/* FAC write data with float ponit format */ +void fac_float_data_write(float data); +/* FAC read data with fixed point format */ +float fac_float_data_read(void); + +/* interrupt & flag functions */ +/* enable the FAC interrupt */ +void fac_interrupt_enable(uint32_t interrupt); +/* disable the FAC interrupt */ +void fac_interrupt_disable(uint32_t interrupt); +/* get the FAC interrupt flag status */ +FlagStatus fac_interrupt_flag_get(uint8_t interrupt); +/* get the FAC flag status */ +FlagStatus fac_flag_get(uint32_t flag); + +#endif /* GD32H7XX_FAC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fmc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fmc.h new file mode 100644 index 0000000000..3330e93e4c --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fmc.h @@ -0,0 +1,534 @@ +/*! + \file gd32h7xx_fmc.h + \brief definitions for the FMC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_FMC_H +#define GD32H7XX_FMC_H + +#include "gd32h7xx.h" + +/* FMC definition */ +#define FMC FMC_BASE /*!< FMC register base address */ + +/* registers definitions */ +#define FMC_KEY REG32((FMC) + 0x00000004U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x00000008U) /*!< FMC option byte unlock key register */ +#define FMC_CTL REG32((FMC) + 0x0000000CU) /*!< FMC control register */ +#define FMC_STAT REG32((FMC) + 0x00000010U) /*!< FMC status register */ +#define FMC_ADDR REG32((FMC) + 0x00000014U) /*!< FMC address register */ +#define FMC_OBCTL REG32((FMC) + 0x00000018U) /*!< FMC option byte control register */ +#define FMC_OBSTAT0_EFT REG32((FMC) + 0x0000001CU) /*!< FMC effective option byte status 0 register */ +#define FMC_OBSTAT0_MDF REG32((FMC) + 0x00000020U) /*!< FMC modified option byte status 0 register */ +#define FMC_DCRPADDR_EFT REG32((FMC) + 0x00000028U) /*!< FMC effective DCRP address register */ +#define FMC_DCRPADDR_MDF REG32((FMC) + 0x0000002CU) /*!< FMC modified DCRP address register */ +#define FMC_SCRADDR_EFT REG32((FMC) + 0x00000030U) /*!< FMC effective secure address register */ +#define FMC_SCRADDR_MDF REG32((FMC) + 0x00000034U) /*!< FMC modified secure address register */ +#define FMC_WP_EFT REG32((FMC) + 0x00000038U) /*!< FMC effective erase/program protection register */ +#define FMC_WP_MDF REG32((FMC) + 0x0000003CU) /*!< FMC modified erase/program protection register */ +#define FMC_BTADDR_EFT REG32((FMC) + 0x00000040U) /*!< FMC effective boot address register */ +#define FMC_BTADDR_MDF REG32((FMC) + 0x00000044U) /*!< FMC modified boot address register */ +#define FMC_OBSTAT1_EFT REG32((FMC) + 0x00000050U) /*!< FMC effective option byte status 1 register */ +#define FMC_OBSTAT1_MDF REG32((FMC) + 0x00000054U) /*!< FMC modified option byte status 1 register */ +#define FMC_NODEC REG32((FMC) + 0x00000060U) /*!< FMC NO-RTDEC area register */ +#define FMC_ECCADDR REG32((FMC) + 0x00000064U) /*!< FMC ECC error address register */ +#define FMC_AESIV0_EFT REG32((FMC) + 0x00000068U) /*!< FMC effective AES IV 0 register */ +#define FMC_AESIV1_EFT REG32((FMC) + 0x0000006CU) /*!< FMC effective AES IV 1 register */ +#define FMC_AESIV2_EFT REG32((FMC) + 0x00000070U) /*!< FMC effective AES IV 2 register */ +#define FMC_AESIV0_MDF REG32((FMC) + 0x00000074U) /*!< FMC modified AES IV 0 register */ +#define FMC_AESIV1_MDF REG32((FMC) + 0x00000078U) /*!< FMC modified AES IV 1 register */ +#define FMC_AESIV2_MDF REG32((FMC) + 0x0000007CU) /*!< FMC modified AES IV 2 register */ +#define FMC_PID0 REG32((FMC) + 0x00000100U) /*!< FMC product ID register 0 */ +#define FMC_PID1 REG32((FMC) + 0x00000104U) /*!< FMC product ID register 1 */ + +/* bits definitions */ +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC_CTL unlock key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option byte unlock key bits */ + +/* FMC_CTL */ +#define FMC_CTL_LK BIT(0) /*!< FMC_CTL lock bit */ +#define FMC_CTL_PG BIT(1) /*!< main flash program command bit */ +#define FMC_CTL_SER BIT(2) /*!< main flash sector erase command bit */ +#define FMC_CTL_MER BIT(3) /*!< main flash mass erase command bit */ +#define FMC_CTL_PGCHEN BIT(4) /*!< check programming area enable bit */ +#define FMC_CTL_START BIT(7) /*!< send erase command to FMC bit */ +#define FMC_CTL_ENDIE BIT(16) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_WPERRIE BIT(17) /*!< erase/program protection error interrupt enable bit */ +#define FMC_CTL_PGSERRIE BIT(18) /*!< program sequence error interrupt enable bit */ +#define FMC_CTL_RPERRIE BIT(23) /*!< read protection error interrupt enable bit */ +#define FMC_CTL_RSERRIE BIT(24) /*!< read secure error interrupt enable bit */ +#define FMC_CTL_ECCCORIE BIT(25) /*!< one bit correct error interrupt enable bit */ +#define FMC_CTL_ECCDETIE BIT(26) /*!< two bits detect error interrupt enable bit */ + +/* FMC_STAT */ +#define FMC_STAT_BUSY BIT(0) /*!< flash busy flag bit */ +#define FMC_STAT_ENDF BIT(16) /*!< end of operation flag bit */ +#define FMC_STAT_WPERR BIT(17) /*!< erase/program protection error flag bit */ +#define FMC_STAT_PGSERR BIT(18) /*!< program sequence error flag bit */ +#define FMC_STAT_RPERR BIT(23) /*!< read protection error flag bit */ +#define FMC_STAT_RSERR BIT(24) /*!< read secure error flag bit */ +#define FMC_STAT_ECCCOR BIT(25) /*!< one bit correct error flag bit */ +#define FMC_STAT_ECCDET BIT(26) /*!< two bits detect error flag bit */ +#define FMC_STAT_OBMERR BIT(30) /*!< option byte modify error flag */ +#define FMC_STAT_FECCF BIT(31) /*!< flash ECC function flag */ + +/* FMC_ADDR */ +#define FMC_ADDR_ADDR BITS(0,31) /*!< address of flash to be erased */ + +/* FMC_OBCTL */ +#define FMC_OBCTL_OBLK BIT(0) /*!< FMC_OBCTL lock bit */ +#define FMC_OBCTL_OBSTART BIT(1) /*!< send option bytes modification start command to FMC */ +#define FMC_OBCTL_OBMERRIE BIT(30) /*!< option byte modify error interrupt enable bit */ + +/* FMC_OBSTAT0_EFT */ +#define FMC_OBSTAT0_EFT_BOR_TH BITS(2,3) /*!< effective option byte brownout reset threshold value */ +#define FMC_OBSTAT0_EFT_NWDG_HW BIT(4) /*!< effective option byte watchdog value */ +#define FMC_OBSTAT0_EFT_NRST_DPSLP BIT(6) /*!< effective option byte deepsleep reset value */ +#define FMC_OBSTAT0_EFT_NRST_STDBY BIT(7) /*!< effective option byte standby reset value */ +#define FMC_OBSTAT0_EFT_SPC BITS(8,15) /*!< effective option byte security protection code */ +#define FMC_OBSTAT0_EFT_FWDGSPD_DPSLP BIT(17) /*!< effective option byte watchdog suspend status in deepsleep mode */ +#define FMC_OBSTAT0_EFT_FWDGSPD_STDBY BIT(18) /*!< effective option byte watchdog suspend status in standby mode */ +#define FMC_OBSTAT0_EFT_SCR BIT(21) /*!< effective option byte security access mode status bit */ +#define FMC_OBSTAT0_EFT_ITCMECCEN BIT(22) /*!< effective option byte ITCM ECC function enable status bit */ +#define FMC_OBSTAT0_EFT_DTCM0ECCEN BIT(23) /*!< effective option byte DTCM0 ECC function enable status bit */ +#define FMC_OBSTAT0_EFT_DTCM1ECCEN BIT(24) /*!< effective option byte DTCM1 ECC function enable status bit */ +#define FMC_OBSTAT0_EFT_IOSPDOPEN BIT(29) /*!< effective option byte I/O speed optimization, high-speed at low-voltage enable status bit */ + +/* FMC_OBSTAT0_MDF */ +#define FMC_OBSTAT0_MDF_BOR_TH BITS(2,3) /*!< modified option byte brownout reset threshold value */ +#define FMC_OBSTAT0_MDF_NWDG_HW BIT(4) /*!< modified option byte watchdog value */ +#define FMC_OBSTAT0_MDF_NRST_DPSLP BIT(6) /*!< modified option byte deepsleep reset value */ +#define FMC_OBSTAT0_MDF_NRST_STDBY BIT(7) /*!< modified option byte standby reset value */ +#define FMC_OBSTAT0_MDF_SPC BITS(8,15) /*!< modified option byte security protection code */ +#define FMC_OBSTAT0_MDF_FWDGSPD_DPSLP BIT(17) /*!< modified option byte watchdog suspend status in deepsleep mode */ +#define FMC_OBSTAT0_MDF_FWDGSPD_STDBY BIT(18) /*!< modified option byte watchdog suspend status in standby mode */ +#define FMC_OBSTAT0_MDF_SCR BIT(21) /*!< modified option byte security access mode status bit */ +#define FMC_OBSTAT0_MDF_ITCMECCEN BIT(22) /*!< modified option byte ITCM ECC function enable status bit */ +#define FMC_OBSTAT0_MDF_DTCM0ECCEN BIT(23) /*!< modified option byte DTCM0 ECC function enable status bit */ +#define FMC_OBSTAT0_MDF_DTCM1ECCEN BIT(24) /*!< modified option byte DTCM1 ECC function enable status bit */ +#define FMC_OBSTAT0_MDF_IOSPDOPEN BIT(29) /*!< modified option byte I/O speed optimization, high-speed at low-voltage enable status bit */ + +/* FMC_DCRPADDR_EFT */ +#define FMC_DCRPADDR_EFT_DCRP_AREA_START BITS(0,10) /*!< effective option byte DCRP area start status bits */ +#define FMC_DCRPADDR_EFT_DCRP_AREA_END BITS(16,26) /*!< effective option byte DCRP area end status bits */ +#define FMC_DCRPADDR_EFT_DCRP_EREN BIT(31) /*!< effective option byte DCRP area erase enable bit */ + +/* FMC_DCRPADDR_MDF */ +#define FMC_DCRPADDR_MDF_DCRP_AREA_START BITS(0,10) /*!< modified option byte DCRP area start status bits */ +#define FMC_DCRPADDR_MDF_DCRP_AREA_END BITS(16,26) /*!< modified option byte DCRP area end status bits */ +#define FMC_DCRPADDR_MDF_DCRP_EREN BIT(31) /*!< modified option byte DCRP area erase enable bit */ + +/* FMC_SCRADDR_EFT */ +#define FMC_SCRADDR_EFT_SCR_AREA_START BITS(0,10) /*!< effective option byte secure-access area start status bits */ +#define FMC_SCRADDR_EFT_SCR_AREA_END BITS(16,26) /*!< effective option byte secure-access area end status bits */ +#define FMC_SCRADDR_EFT_SCR_EREN BIT(31) /*!< effective option byte secure-access area erase enable bit */ + +/* FMC_SCRADDR_MDF */ +#define FMC_SCRADDR_MDF_SCR_AREA_START BITS(0,10) /*!< modified option byte secure-access area start status bits */ +#define FMC_SCRADDR_MDF_SCR_AREA_END BITS(16,26) /*!< modified option byte secure-access area end status bits */ +#define FMC_SCRADDR_MDF_SCR_EREN BIT(31) /*!< modified option byte secure-access area erase enable bit */ + +/* FMC_WP_EFT */ +#define FMC_WP_EFT_WP BITS(0,29) /*!< effective option byte erase/program protection status bits */ + +/* FMC_WP_MDF */ +#define FMC_WP_MDF_WP BITS(0,29) /*!< modified option byte erase/program protection status bits */ + +/* FMC_BTADDR_EFT */ +#define FMC_BTADDR_EFT_BOOT_ADDR0 BITS(0,15) /*!< effective option byte boot address 0 */ +#define FMC_BTADDR_EFT_BOOT_ADDR1 BITS(16,31) /*!< effective option byte boot address 1 */ + +/* FMC_BTADDR_MDF */ +#define FMC_BTADDR_MDF_BOOT_ADDR0 BITS(0,15) /*!< modified option byte boot address 0 */ +#define FMC_BTADDR_MDF_BOOT_ADDR1 BITS(16,31) /*!< modified option byte boot address 1 */ + +/* FMC_OBSTAT1_EFT */ +#define FMC_OBSTAT1_EFT_ITCM_SZ_SHRRAM BITS(0,3) /*!< effective option byte ITCM size of shared RAM */ +#define FMC_OBSTAT1_EFT_DTCM_SZ_SHRRAM BITS(4,7) /*!< effective option byte DTCM size of shared RAM */ +#define FMC_OBSTAT1_EFT_DATA BITS(16,31) /*!< effective option byte user data value */ + +/* FMC_OBSTAT1_MDF */ +#define FMC_OBSTAT1_MDF_ITCM_SZ_SHRRAM BITS(0,3) /*!< modified option byte ITCM size of shared RAM */ +#define FMC_OBSTAT1_MDF_DTCM_SZ_SHRRAM BITS(4,7) /*!< modified option byte DTCM size of shared RAM */ +#define FMC_OBSTAT1_MDF_DATA BITS(16,31) /*!< modified option byte user data value */ + +/* FMC_NODEC */ +#define FMC_NODEC_NODEC_AREA_START BITS(0,10) /*!< NO-RTDEC area start status bits */ +#define FMC_NODEC_NODEC_AREA_END BITS(16,26) /*!< NO-RTDEC area end status bits */ + +/* FMC_ECCADDR */ +#define FMC_ECCADDR_ECCADDR BITS(0,31) /*!< address of byte where an ECC error is detected */ + +/* FMC_AESIV0_EFT */ +#define FMC_AESIV0_EFT_AESIV BITS(0,31) /*!< AES initialization vector status value 0 */ + +/* FMC_AESIV1_EFT */ +#define FMC_AESIV1_EFT_AESIV BITS(0,31) /*!< AES initialization vector status value 1 */ + +/* FMC_AESIV2_EFT */ +#define FMC_AESIV2_EFT_AESIV BITS(0,31) /*!< AES initialization vector status value 2 */ + +/* FMC_AESIV0_MDF */ +#define FMC_AESIV0_MDF_AESIV BITS(0,31) /*!< AES initialization vector configuration value 0 */ + +/* FMC_AESIV1_MDF */ +#define FMC_AESIV1_MDF_AESIV BITS(0,31) /*!< AES initialization vector configuration value 1 */ + +/* FMC_AESIV2_MDF */ +#define FMC_AESIV2_MDF_AESIV BITS(0,31) /*!< AES initialization vector configuration value 2 */ + +/* FMC_PID0 */ +#define FMC_PID0_PID BITS(0,31) /*!< product ID 0 */ + +/* FMC_PID1 */ +#define FMC_PID1_PID BITS(0,31) /*!< product ID 1 */ + +/* constants definitions */ +/* FMC state */ +typedef enum { + FMC_READY = 0U, /*!< the operation has been completed */ + FMC_BUSY, /*!< the operation is in progress */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_PGSERR, /*!< program sequence error */ + FMC_RPERR, /*!< read protection error */ + FMC_RSERR, /*!< read secure error */ + FMC_ECCCOR, /*!< one bit correct error */ + FMC_ECCDET, /*!< two bits detect error */ + FMC_OBMERR, /*!< option byte modify error */ + FMC_TOERR /*!< timeout error */ +} fmc_state_enum; + +/* define the FMC bit position and its register index offset */ +#define FMC_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define FMC_REG_VAL(offset) (REG32(FMC + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define FMC_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define FMC_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define FMC_REG_VAL2(offset) (REG32(FMC + ((uint32_t)(offset) >> 22))) +#define FMC_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define FMC_STAT_REG_OFFSET ((uint32_t)0x00000010U) /*!< STAT register offset */ +#define FMC_CTL_REG_OFFSET ((uint32_t)0x0000000CU) /*!< CTL register offset */ +#define FMC_OBCTL_REG_OFFSET ((uint32_t)0x00000018U) /*!< OBCTL register offset */ + +/* FMC flags */ +typedef enum { + /* flags in STAT register */ + FMC_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 0U), /*!< flash busy flag */ + FMC_FLAG_END = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 16U), /*!< flash end of operation flag */ + FMC_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 17U), /*!< flash erase/program protection error flag */ + FMC_FLAG_PGSERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 18U), /*!< flash program sequence error flag */ + FMC_FLAG_RPERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 23U), /*!< flash read protection error flag */ + FMC_FLAG_RSERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 24U), /*!< flash read secure error flag */ + FMC_FLAG_ECCCOR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 25U), /*!< flash one bit correct error flag */ + FMC_FLAG_ECCDET = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 26U), /*!< flash two bits detect error flag */ + FMC_FLAG_OBMERR = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 30U), /*!< option byte modify error flag */ + FMC_FLAG_FECC = FMC_REGIDX_BIT(FMC_STAT_REG_OFFSET, 31U) /*!< flash ECC function flag */ +} fmc_flag_enum; + +/* FMC interrupt flags */ +typedef enum { + /* interrupt flags in STAT register */ + FMC_INT_FLAG_END = FMC_REGIDX_BIT2(FMC_CTL_REG_OFFSET, 16U, FMC_STAT_REG_OFFSET, 16U), /*!< flash end of operation interrupt flag */ + FMC_INT_FLAG_WPERR = FMC_REGIDX_BIT2(FMC_CTL_REG_OFFSET, 17U, FMC_STAT_REG_OFFSET, 17U), /*!< flash erase/program protection error interrupt flag */ + FMC_INT_FLAG_PGSERR = FMC_REGIDX_BIT2(FMC_CTL_REG_OFFSET, 18U, FMC_STAT_REG_OFFSET, 18U), /*!< flash program sequence error interrupt flag */ + FMC_INT_FLAG_RPERR = FMC_REGIDX_BIT2(FMC_CTL_REG_OFFSET, 23U, FMC_STAT_REG_OFFSET, 23U), /*!< flash read protection error interrupt flag */ + FMC_INT_FLAG_RSERR = FMC_REGIDX_BIT2(FMC_CTL_REG_OFFSET, 24U, FMC_STAT_REG_OFFSET, 24U), /*!< flash read secure error interrupt flag */ + FMC_INT_FLAG_ECCCOR = FMC_REGIDX_BIT2(FMC_CTL_REG_OFFSET, 25U, FMC_STAT_REG_OFFSET, 25U), /*!< flash one bit error detected and correct interrupt flag */ + FMC_INT_FLAG_ECCDET = FMC_REGIDX_BIT2(FMC_CTL_REG_OFFSET, 26U, FMC_STAT_REG_OFFSET, 26U), /*!< flash two bit errors detect interrupt flag */ + FMC_INT_FLAG_OBMERR = FMC_REGIDX_BIT2(FMC_OBCTL_REG_OFFSET, 30U, FMC_STAT_REG_OFFSET, 30U) /*!< option byte modify error flag */ +} fmc_interrupt_flag_enum; + +/* FMC interrupt */ +typedef enum { + /* interrupt in CTL register */ + FMC_INT_END = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 16U), /*!< FMC end of operation interrupt */ + FMC_INT_WPERR = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 17U), /*!< FMC erase/program protection error interrupt */ + FMC_INT_PGSERR = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 18U), /*!< FMC program sequence error interrupt */ + FMC_INT_RPERR = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 23U), /*!< FMC read protection error interrupt */ + FMC_INT_RSERR = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 24U), /*!< FMC read secure error interrupt */ + FMC_INT_ECCCOR = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 25U), /*!< FMC one bit correct error interrupt */ + FMC_INT_ECCDET = FMC_REGIDX_BIT(FMC_CTL_REG_OFFSET, 26U), /*!< FMC two bits detect error interrupt */ + /* interrupt in OBCTL register */ + FMC_INT_OBMERR = FMC_REGIDX_BIT(FMC_OBCTL_REG_OFFSET, 30U) /*!< FMC option byte modify error interrupt */ +} fmc_interrupt_enum; + +/* unlock key */ +#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ +#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ + +/* option byte unlock key */ +#define OB_UNLOCK_KEY0 ((uint32_t)0x08192A3BU) /*!< option byte unlock key 0 */ +#define OB_UNLOCK_KEY1 ((uint32_t)0x4C5D6E7FU) /*!< option byte unlock key 1 */ + +/* option byte BOR threshold value */ +#define OBSTAT0_BOR_TH(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) +#define OB_BOR_TH_OFF OBSTAT0_BOR_TH(0) /*!< no BOR function */ +#define OB_BOR_TH_VALUE1 OBSTAT0_BOR_TH(1) /*!< BOR threshold value 1 */ +#define OB_BOR_TH_VALUE2 OBSTAT0_BOR_TH(2) /*!< BOR threshold value 2 */ +#define OB_BOR_TH_VALUE3 OBSTAT0_BOR_TH(3) /*!< BOR threshold value 3 */ + +/* option byte software/hardware free watchdog timer */ +#define OBSTAT0_NWDG_HW(regval) (BIT(4) & ((uint32_t)(regval) << 4U)) +#define OB_FWDGT_HW OBSTAT0_NWDG_HW(0) /*!< hardware free watchdog */ +#define OB_FWDGT_SW OBSTAT0_NWDG_HW(1) /*!< software free watchdog */ + +/* option byte reset or not entering deep sleep mode */ +#define OBSTAT0_NRST_DPSLP(regval) (BIT(6) & ((uint32_t)(regval) << 6U)) +#define OB_DEEPSLEEP_RST OBSTAT0_NRST_DPSLP(0) /*!< generate a reset instead of entering deepsleep mode */ +#define OB_DEEPSLEEP_NRST OBSTAT0_NRST_DPSLP(1) /*!< no reset when entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OBSTAT0_NRST_STDBY(regval) (BIT(7) & ((uint32_t)(regval) << 7U)) +#define OB_STDBY_RST OBSTAT0_NRST_STDBY(0) /*!< generate a reset instead of entering standby mode */ +#define OB_STDBY_NRST OBSTAT0_NRST_STDBY(1) /*!< no reset when entering standby mode */ + +/* option byte FWDGT status in deep-sleep mode */ +#define OBSTAT0_FWDGSPD_DPSLP(regval) (BIT(17) & ((uint32_t)(regval)<< 17U)) +#define OB_DPSLP_FWDGT_SUSPEND OBSTAT0_FWDGSPD_DPSLP(0) /*!< free watchdog is suspended in deepsleep mode */ +#define OB_DPSLP_FWDGT_RUN OBSTAT0_FWDGSPD_DPSLP(1) /*!< free watchdog is running in deepsleep mode */ + +/* option byte FWDGT status in standby mode */ +#define OBSTAT0_FWDGSPD_STDBY(regval) (BIT(18) & ((uint32_t)(regval) << 18U)) +#define OB_STDBY_FWDGT_SUSPEND OBSTAT0_FWDGSPD_STDBY(0) /*!< free watchdog is suspended in standby mode */ +#define OB_STDBY_FWDGT_RUN OBSTAT0_FWDGSPD_STDBY(1) /*!< free watchdog is running in standby mode */ + +/* option byte security access mode configuration */ +#define OBSTAT0_SCR(regval) (BIT(21) & ((uint32_t)(regval) << 21U)) +#define OB_SECURE_MODE_DISABLE OBSTAT0_SCR(0) /*!< secure access mode disable */ +#define OB_SECURE_MODE_ENABLE OBSTAT0_SCR(1) /*!< secure access mode enable */ + +/* option byte ITCM ECC function enable configuration */ +#define OBSTAT0_ITCMECCEN(regval) (BIT(22) & ((uint32_t)(regval) << 22U)) +#define OB_ITCMECCEN_DISABLE OBSTAT0_ITCMECCEN(0) /*!< ITCM ECC function disable */ +#define OB_ITCMECCEN_ENABLE OBSTAT0_ITCMECCEN(1) /*!< ITCM ECC function enable */ + +/* option byte DTCM0 ECC function enable configuration */ +#define OBSTAT0_DTCM0ECCEN(regval) (BIT(23) & ((uint32_t)(regval) << 23U)) +#define OB_DTCM0ECCEN_DISABLE OBSTAT0_DTCM0ECCEN(0) /*!< DTCM0 ECC function disable */ +#define OB_DTCM0ECCEN_ENABLE OBSTAT0_DTCM0ECCEN(1) /*!< DTCM0 ECC function enable */ + +/* option byte DTCM1 ECC function enable configuration */ +#define OBSTAT0_DTCM1ECCEN(regval) (BIT(24) & ((uint32_t)(regval) << 24U)) +#define OB_DTCM1ECCEN_DISABLE OBSTAT0_DTCM1ECCEN(0) /*!< DTCM1 ECC function disable */ +#define OB_DTCM1ECCEN_ENABLE OBSTAT0_DTCM1ECCEN(1) /*!< DTCM1 ECC function enable */ + +/* option byte I/O speed optimization configuration */ +#define OBSTAT0_IOSPDOPEN(regval) (BIT(29) & ((uint32_t)(regval) << 29U)) +#define OB_IOSPDOPEN_DISABLE OBSTAT0_IOSPDOPEN(0) /*!< I/O speed optimization, high-speed at low-voltage diable */ +#define OB_IOSPDOPEN_ENABLE OBSTAT0_IOSPDOPEN(1) /*!< I/O speed optimization, high-speed at low-voltage enable */ + +/* option byte security protection configuration */ +#define FMC_NSPC ((uint8_t)0xAAU) /*!< no protection */ +#define FMC_LSPC ((uint8_t)0xBBU) /*!< protection level low */ +#define FMC_HSPC ((uint8_t)0xCCU) /*!< protection level high */ + +/* option byte DCRP erase enable configuration */ +#define OB_DCRPADDR_DCRP_EREN(regval) (BIT(31) & ((uint32_t)(regval) << 31U)) +#define OB_DCRP_AREA_ERASE_DISABLE OB_DCRPADDR_DCRP_EREN(0) /*!< DCRP area erase disable */ +#define OB_DCRP_AREA_ERASE_ENABLE OB_DCRPADDR_DCRP_EREN(1) /*!< DCRP area erase enable */ + +/* option byte secure-access erase enable configuration */ +#define OB_SCRADDR_SCR_EREN(regval) (BIT(31) & ((uint32_t)(regval) << 31U)) +#define OB_SCR_AREA_ERASE_DISABLE OB_SCRADDR_SCR_EREN(0) /*!< secure-access area erase disable */ +#define OB_SCR_AREA_ERASE_ENABLE OB_SCRADDR_SCR_EREN(1) /*!< secure-access area erase enable */ + +/* option byte erase/program protection */ +#define OB_WP_0 BIT(0) /*!< erase/program protection of sector 0~15 */ +#define OB_WP_1 BIT(1) /*!< erase/program protection of sector 16~31 */ +#define OB_WP_2 BIT(2) /*!< erase/program protection of sector 32~47 */ +#define OB_WP_3 BIT(3) /*!< erase/program protection of sector 48~63 */ +#define OB_WP_4 BIT(4) /*!< erase/program protection of sector 64~79 */ +#define OB_WP_5 BIT(5) /*!< erase/program protection of sector 80~95 */ +#define OB_WP_6 BIT(6) /*!< erase/program protection of sector 96~111 */ +#define OB_WP_7 BIT(7) /*!< erase/program protection of sector 112~127 */ +#define OB_WP_8 BIT(8) /*!< erase/program protection of sector 128~143 */ +#define OB_WP_9 BIT(9) /*!< erase/program protection of sector 144~159 */ +#define OB_WP_10 BIT(10) /*!< erase/program protection of sector 160~175 */ +#define OB_WP_11 BIT(11) /*!< erase/program protection of sector 176~191 */ +#define OB_WP_12 BIT(12) /*!< erase/program protection of sector 192~207 */ +#define OB_WP_13 BIT(13) /*!< erase/program protection of sector 208~223 */ +#define OB_WP_14 BIT(14) /*!< erase/program protection of sector 224~239 */ +#define OB_WP_15 BIT(15) /*!< erase/program protection of sector 240~255 */ +#define OB_WP_16 BIT(16) /*!< erase/program protection of sector 256~383 */ +#define OB_WP_17 BIT(17) /*!< erase/program protection of sector 384~511 */ +#define OB_WP_18 BIT(18) /*!< erase/program protection of sector 512~639 */ +#define OB_WP_19 BIT(19) /*!< erase/program protection of sector 640~767 */ +#define OB_WP_20 BIT(20) /*!< erase/program protection of sector 768~895 */ +#define OB_WP_21 BIT(21) /*!< erase/program protection of sector 896~1023 */ +#define OB_WP_ALL BITS(0,29) /*!< erase/program protection of all sectors */ + +/* option byte DTCM size of shared RAM */ +#define OBSTAT1_DTCM_SZ_SHRRAM(regval) (BITS(4,7) & ((uint32_t)(regval) << 4U)) +#define OB_DTCM_SHARED_RAM_0KB OBSTAT1_DTCM_SZ_SHRRAM(0) /*!< DTCM shared RAM size is 0KB */ +#define OB_DTCM_SHARED_RAM_64KB OBSTAT1_DTCM_SZ_SHRRAM(7) /*!< DTCM shared RAM size is 64KB */ +#define OB_DTCM_SHARED_RAM_128KB OBSTAT1_DTCM_SZ_SHRRAM(8) /*!< DTCM shared RAM size is 128KB */ +#define OB_DTCM_SHARED_RAM_256KB OBSTAT1_DTCM_SZ_SHRRAM(9) /*!< DTCM shared RAM size is 256KB */ +#define OB_DTCM_SHARED_RAM_512KB OBSTAT1_DTCM_SZ_SHRRAM(10) /*!< DTCM shared RAM size is 512KB */ + +/* option byte ITCM size of shared RAM */ +#define OBSTAT1_ITCM_SZ_SHRRAM(regval) (BITS(0,3) & ((uint32_t)(regval))) +#define OB_ITCM_SHARED_RAM_0KB OBSTAT1_ITCM_SZ_SHRRAM(0) /*!< ITCM shared RAM size is 0KB */ +#define OB_ITCM_SHARED_RAM_64KB OBSTAT1_ITCM_SZ_SHRRAM(7) /*!< ITCM shared RAM size is 64KB */ +#define OB_ITCM_SHARED_RAM_128KB OBSTAT1_ITCM_SZ_SHRRAM(8) /*!< ITCM shared RAM size is 128KB */ +#define OB_ITCM_SHARED_RAM_256KB OBSTAT1_ITCM_SZ_SHRRAM(9) /*!< ITCM shared RAM size is 256KB */ +#define OB_ITCM_SHARED_RAM_512KB OBSTAT1_ITCM_SZ_SHRRAM(10) /*!< ITCM shared RAM size is 512KB */ + +/* boot pin value definitions */ +#define BOOT_PIN_0 ((uint8_t)0x00U) /*!< boot pin value is 0 */ +#define BOOT_PIN_1 ((uint8_t)0x01U) /*!< boot pin value is 1 */ + +#define MAIN_FLASH_BASE_ADDRESS ((uint32_t)0x08000000U) /*!< main flash base address */ +#define SCR_SIZE_UNIT ((uint32_t)0x00001000U) /*!< secure-access area granularity */ +#define DCRP_SIZE_UNIT ((uint32_t)0x00001000U) /*!< DCRP area granularity */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0xFFFFFFFFU) /*!< count to judge of FMC timeout */ + +#define INVLD_AREA_ADDRESS ((uint8_t)0x00U) /*!< the area address is invalid */ +#define VLD_AREA_ADDRESS ((uint8_t)0x01U) /*!< the area address is valid */ + +/* function declarations */ +/* FMC operation functions */ +/* unlock FMC_CTL register */ +void fmc_unlock(void); +/* lock FMC_CTL register */ +void fmc_lock(void); +/* FMC erase sector */ +fmc_state_enum fmc_sector_erase(uint32_t address); +/* FMC typical mass erase */ +fmc_state_enum fmc_typical_mass_erase(void); +/* FMC protection-removed mass erase */ +fmc_state_enum fmc_protection_removed_mass_erase(void); +/* FMC program a word at the corresponding address */ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data); +/* FMC program a double-word at the corresponding address */ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data); +/* enable check programming area */ +fmc_state_enum fmc_check_programming_area_enable(void); +/* disable check programming area */ +fmc_state_enum fmc_check_programming_area_disable(void); + +/* FMC option bytes operation functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* send option bytes modification start command */ +fmc_state_enum ob_start(void); +/* modify option byte to factory value */ +fmc_state_enum ob_factory_value_config(void); +/* enable secure access mode */ +fmc_state_enum ob_secure_access_mode_enable(void); +/* disable secure access mode */ +fmc_state_enum ob_secure_access_mode_disable(void); +/* configure the option byte security protection level */ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc); +/* configure option byte BOR threshold value */ +fmc_state_enum ob_bor_threshold_config(uint32_t ob_bor_th); +/* configure low power related option byte */ +fmc_state_enum ob_low_power_config(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby, uint32_t ob_fwdg_suspend_deepsleep, + uint32_t ob_fwdg_suspend_standby); +/* configure TCM ECC option byte */ +fmc_state_enum ob_tcm_ecc_config(uint32_t ob_itcmecc, uint32_t ob_dtcm0ecc, uint32_t ob_dtcm1ecc); +/* configure I/O speed optimization option byte */ +fmc_state_enum ob_iospeed_optimize_config(uint32_t ob_iospeed_op); +/* configure option byte TCM shared RAM size */ +fmc_state_enum ob_tcm_shared_ram_config(uint32_t itcm_shared_ram_size, uint32_t dtcm_shared_ram_size); +/* modify option byte DATA */ +fmc_state_enum ob_data_program(uint16_t ob_data); +/* configure boot address */ +fmc_state_enum ob_boot_address_config(uint8_t boot_pin, uint16_t boot_address); +/* configure DCRP area */ +fmc_state_enum ob_dcrp_area_config(uint32_t dcrp_eren, uint32_t dcrp_start, uint32_t dcrp_end); +/* configure secure-access area */ +fmc_state_enum ob_secure_area_config(uint32_t scr_eren, uint32_t scr_start, uint32_t scr_end); +/* enable erase/program protection */ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp); +/* disable erase/program protection */ +fmc_state_enum ob_write_protection_disable(uint32_t ob_wp); +/* get the option byte secure access mode */ +FlagStatus ob_secure_mode_get(void); +/* get the option byte security protection level */ +FlagStatus ob_security_protection_flag_get(void); +/* get the option byte BOR threshold value */ +uint32_t ob_bor_threshold_get(void); +/* get low power related option byte */ +void ob_low_power_get(uint32_t *fwdgt, uint32_t *deepsleep, uint32_t *standby, uint32_t *fwdg_suspend_deepsleep, uint32_t *fwdg_suspend_standby); +/* get TCM ECC configuration */ +void ob_tcm_ecc_get(uint32_t *itcmecc_option, uint32_t *dtcm0ecc_option, uint32_t *dtcm1ecc_option); +/* get IO speed optimize configuration */ +FlagStatus ob_iospeed_optimize_get(void); +/* get the option byte TCM shared RAM size */ +void ob_tcm_shared_ram_size_get(uint32_t *itcm_shared_ram_kb_size, uint32_t *dtcm_shared_ram_kb_size); +/* get user data value */ +uint16_t ob_data_get(void); +/* get boot address */ +uint32_t ob_boot_address_get(uint8_t boot_pin); +/* get DCRP area configuration */ +uint8_t ob_dcrp_area_get(uint32_t *dcrp_erase_option, uint32_t *dcrp_area_start_addr, uint32_t *dcrp_area_end_addr); +/* get secure-access area configuration */ +uint8_t ob_secure_area_get(uint32_t *secure_area_option, uint32_t *scr_area_start_addr, uint32_t *scr_area_end_addr); +/* get the option byte erase/program protection state */ +uint32_t ob_write_protection_get(void); + +/* FMC universal functions */ +/* configure NO-RTDEC area */ +fmc_state_enum fmc_no_rtdec_config(uint32_t nodec_area_start, uint32_t nodec_area_end); +/* configure aes initialization vector */ +fmc_state_enum fmc_aes_iv_config(uint32_t *aes_iv); +/* get Flash ECC function enable flag */ +FlagStatus fmc_flash_ecc_get(void); +/* get NO-RTDEC area */ +void fmc_no_rtdec_get(uint32_t *nodec_area_start, uint32_t *nodec_area_end); +/* get AES initialization vector */ +void fmc_aes_iv_get(uint32_t *aes_iv); +/* get product ID */ +void fmc_pid_get(uint32_t *pid); + +/* interrupt & flag functions */ +/* get FMC flag status */ +FlagStatus fmc_flag_get(fmc_flag_enum flag); +/* clear FMC flag status */ +void fmc_flag_clear(fmc_flag_enum flag); +/* enable FMC interrupt */ +void fmc_interrupt_enable(fmc_interrupt_enum interrupt); +/* disable FMC interrupt */ +void fmc_interrupt_disable(fmc_interrupt_enum interrupt); +/* get FMC interrupt flag status */ +FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum int_flag); +/* clear FMC interrupt flag status */ +void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum int_flag); + +#endif /* GD32H7XX_FMC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fwdgt.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fwdgt.h new file mode 100644 index 0000000000..2cfd5b8d1d --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_fwdgt.h @@ -0,0 +1,117 @@ +/*! + \file gd32h7xx_fwdgt.h + \brief definitions for the FWDGT + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_FWDGT_H +#define GD32H7XX_FWDGT_H + +#include "gd32h7xx.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00000000U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x00000004U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x00000008U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0000000CU) /*!< FWDGT status register */ +#define FWDGT_WND REG32((FWDGT) + 0x00000010U) /*!< FWDGT window register */ + +/* bits definitions */ +/* FWDGT_CTL */ +#define FWDGT_CTL_CMD BITS(0,15) /*!< FWDGT command value */ + +/* FWDGT_PSC */ +#define FWDGT_PSC_PSC BITS(0,2) /*!< FWDGT prescaler divider value */ + +/* FWDGT_RLD */ +#define FWDGT_RLD_RLD BITS(0,11) /*!< FWDGT counter reload value */ + +/* FWDGT_STAT */ +#define FWDGT_STAT_PUD BIT(0) /*!< FWDGT prescaler divider value update */ +#define FWDGT_STAT_RUD BIT(1) /*!< FWDGT counter reload value update */ +#define FWDGT_STAT_WUD BIT(2) /*!< FWDGT counter window value update */ + +/* FWDGT_WND */ +#define FWDGT_WND_WND BITS(0,11) /*!< FWDGT counter window value */ + +/* constants definitions */ +/* FWDGT_PSC register value */ +#define PSC_PSC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define FWDGT_PSC_DIV4 ((uint8_t)PSC_PSC(0)) /*!< FWDGT prescaler set to 4 */ +#define FWDGT_PSC_DIV8 ((uint8_t)PSC_PSC(1)) /*!< FWDGT prescaler set to 8 */ +#define FWDGT_PSC_DIV16 ((uint8_t)PSC_PSC(2)) /*!< FWDGT prescaler set to 16 */ +#define FWDGT_PSC_DIV32 ((uint8_t)PSC_PSC(3)) /*!< FWDGT prescaler set to 32 */ +#define FWDGT_PSC_DIV64 ((uint8_t)PSC_PSC(4)) /*!< FWDGT prescaler set to 64 */ +#define FWDGT_PSC_DIV128 ((uint8_t)PSC_PSC(5)) /*!< FWDGT prescaler set to 128 */ +#define FWDGT_PSC_DIV256 ((uint8_t)PSC_PSC(6)) /*!< FWDGT prescaler set to 256 */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x5555U) /*!< FWDGT_CTL bits write access enable value */ +#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x0000U) /*!< FWDGT_CTL bits write access disable value */ +#define FWDGT_KEY_RELOAD ((uint16_t)0xAAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */ +#define FWDGT_KEY_ENABLE ((uint16_t)0xCCCCU) /*!< FWDGT_CTL bits fwdgt counter enable value */ + +/* FWDGT timeout value */ +#define FWDGT_WND_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_WND register write operation state flag timeout */ +#define FWDGT_PSC_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_PSC register write operation state flag timeout */ +#define FWDGT_RLD_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_RLD register write operation state flag timeout */ + +/* FWDGT flag definitions */ +#define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< a write operation to FWDGT_PSC register is on going */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< a write operation to FWDGT_RLD register is on going */ +#define FWDGT_FLAG_WUD FWDGT_STAT_WUD /*!< a write operation to FWDGT_WND register is on going */ + +/* function declarations */ +/* enable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_enable(void); +/* disable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_disable(void); +/* start the FWDGT counter */ +void fwdgt_enable(void); + +/* configure the FWDGT counter prescaler value */ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value); +/* configure the FWDGT counter reload value */ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value); +/* configure the FWDGT counter window value */ +ErrStatus fwdgt_window_value_config(uint16_t window_value); +/* reload the counter of FWDGT */ +void fwdgt_counter_reload(void); +/* configure counter reload value, and prescaler divider value */ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div); + +/* get flag state of FWDGT */ +FlagStatus fwdgt_flag_get(uint16_t flag); + +#endif /* GD32H7XX_FWDGT_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_gpio.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_gpio.h new file mode 100644 index 0000000000..6fdb5b7524 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_gpio.h @@ -0,0 +1,442 @@ +/*! + \file gd32h7xx_gpio.h + \brief definitions for the GPIO + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_GPIO_H +#define GD32H7XX_GPIO_H + +#include "gd32h7xx.h" + +/* GPIOx(x = A,B,C,D,E,F,G,H,J,K) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) +#define GPIOB (GPIO_BASE + 0x00000400U) +#define GPIOC (GPIO_BASE + 0x00000800U) +#define GPIOD (GPIO_BASE + 0x00000C00U) +#define GPIOE (GPIO_BASE + 0x00001000U) +#define GPIOF (GPIO_BASE + 0x00001400U) +#define GPIOG (GPIO_BASE + 0x00001800U) +#define GPIOH (GPIO_BASE + 0x00001C00U) +#define GPIOJ (GPIO_BASE + 0x00002400U) +#define GPIOK (GPIO_BASE + 0x00002800U) + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00000000U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x00000004U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x00000008U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0000000CU) /*!< GPIO port pull-up/pull-down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x00000010U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x00000014U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x00000018U) /*!< GPIO port bit operation register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x0000001CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x00000020U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x00000024U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x00000028U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x0000002CU) /*!< GPIO port bit toggle register */ +#define GPIO_IFL(gpiox) REG32((gpiox) + 0x00000030U) /*!< GPIO input filtering register */ +#define GPIO_IFTP(gpiox) REG32((gpiox) + 0x00000034U) /*!< GPIO input filtering type register */ + +/* bits definitions */ +/* GPIO_CTL */ +#define GPIO_CTL_CTL0 BITS(0,1) /*!< pin 0 configuration bits */ +#define GPIO_CTL_CTL1 BITS(2,3) /*!< pin 1 configuration bits */ +#define GPIO_CTL_CTL2 BITS(4,5) /*!< pin 2 configuration bits */ +#define GPIO_CTL_CTL3 BITS(6,7) /*!< pin 3 configuration bits */ +#define GPIO_CTL_CTL4 BITS(8,9) /*!< pin 4 configuration bits */ +#define GPIO_CTL_CTL5 BITS(10,11) /*!< pin 5 configuration bits */ +#define GPIO_CTL_CTL6 BITS(12,13) /*!< pin 6 configuration bits */ +#define GPIO_CTL_CTL7 BITS(14,15) /*!< pin 7 configuration bits */ +#define GPIO_CTL_CTL8 BITS(16,17) /*!< pin 8 configuration bits */ +#define GPIO_CTL_CTL9 BITS(18,19) /*!< pin 9 configuration bits */ +#define GPIO_CTL_CTL10 BITS(20,21) /*!< pin 10 configuration bits */ +#define GPIO_CTL_CTL11 BITS(22,23) /*!< pin 11 configuration bits */ +#define GPIO_CTL_CTL12 BITS(24,25) /*!< pin 12 configuration bits */ +#define GPIO_CTL_CTL13 BITS(26,27) /*!< pin 13 configuration bits */ +#define GPIO_CTL_CTL14 BITS(28,29) /*!< pin 14 configuration bits */ +#define GPIO_CTL_CTL15 BITS(30,31) /*!< pin 15 configuration bits */ + +/* GPIO_OMODE */ +#define GPIO_OMODE_OM0 BIT(0) /*!< pin 0 output mode bit */ +#define GPIO_OMODE_OM1 BIT(1) /*!< pin 1 output mode bit */ +#define GPIO_OMODE_OM2 BIT(2) /*!< pin 2 output mode bit */ +#define GPIO_OMODE_OM3 BIT(3) /*!< pin 3 output mode bit */ +#define GPIO_OMODE_OM4 BIT(4) /*!< pin 4 output mode bit */ +#define GPIO_OMODE_OM5 BIT(5) /*!< pin 5 output mode bit */ +#define GPIO_OMODE_OM6 BIT(6) /*!< pin 6 output mode bit */ +#define GPIO_OMODE_OM7 BIT(7) /*!< pin 7 output mode bit */ +#define GPIO_OMODE_OM8 BIT(8) /*!< pin 8 output mode bit */ +#define GPIO_OMODE_OM9 BIT(9) /*!< pin 9 output mode bit */ +#define GPIO_OMODE_OM10 BIT(10) /*!< pin 10 output mode bit */ +#define GPIO_OMODE_OM11 BIT(11) /*!< pin 11 output mode bit */ +#define GPIO_OMODE_OM12 BIT(12) /*!< pin 12 output mode bit */ +#define GPIO_OMODE_OM13 BIT(13) /*!< pin 13 output mode bit */ +#define GPIO_OMODE_OM14 BIT(14) /*!< pin 14 output mode bit */ +#define GPIO_OMODE_OM15 BIT(15) /*!< pin 15 output mode bit */ + +/* GPIO_OSPD */ +#define GPIO_OSPD_OSPD0 BITS(0,1) /*!< pin 0 output max speed bits */ +#define GPIO_OSPD_OSPD1 BITS(2,3) /*!< pin 1 output max speed bits */ +#define GPIO_OSPD_OSPD2 BITS(4,5) /*!< pin 2 output max speed bits */ +#define GPIO_OSPD_OSPD3 BITS(6,7) /*!< pin 3 output max speed bits */ +#define GPIO_OSPD_OSPD4 BITS(8,9) /*!< pin 4 output max speed bits */ +#define GPIO_OSPD_OSPD5 BITS(10,11) /*!< pin 5 output max speed bits */ +#define GPIO_OSPD_OSPD6 BITS(12,13) /*!< pin 6 output max speed bits */ +#define GPIO_OSPD_OSPD7 BITS(14,15) /*!< pin 7 output max speed bits */ +#define GPIO_OSPD_OSPD8 BITS(16,17) /*!< pin 8 output max speed bits */ +#define GPIO_OSPD_OSPD9 BITS(18,19) /*!< pin 9 output max speed bits */ +#define GPIO_OSPD_OSPD10 BITS(20,21) /*!< pin 10 output max speed bits */ +#define GPIO_OSPD_OSPD11 BITS(22,23) /*!< pin 11 output max speed bits */ +#define GPIO_OSPD_OSPD12 BITS(24,25) /*!< pin 12 output max speed bits */ +#define GPIO_OSPD_OSPD13 BITS(26,27) /*!< pin 13 output max speed bits */ +#define GPIO_OSPD_OSPD14 BITS(28,29) /*!< pin 14 output max speed bits */ +#define GPIO_OSPD_OSPD15 BITS(30,31) /*!< pin 15 output max speed bits */ + +/* GPIO_PUD */ +#define GPIO_PUD_PUD0 BITS(0,1) /*!< pin 0 pull-up or pull-down bits */ +#define GPIO_PUD_PUD1 BITS(2,3) /*!< pin 1 pull-up or pull-down bits */ +#define GPIO_PUD_PUD2 BITS(4,5) /*!< pin 2 pull-up or pull-down bits */ +#define GPIO_PUD_PUD3 BITS(6,7) /*!< pin 3 pull-up or pull-down bits */ +#define GPIO_PUD_PUD4 BITS(8,9) /*!< pin 4 pull-up or pull-down bits */ +#define GPIO_PUD_PUD5 BITS(10,11) /*!< pin 5 pull-up or pull-down bits */ +#define GPIO_PUD_PUD6 BITS(12,13) /*!< pin 6 pull-up or pull-down bits */ +#define GPIO_PUD_PUD7 BITS(14,15) /*!< pin 7 pull-up or pull-down bits */ +#define GPIO_PUD_PUD8 BITS(16,17) /*!< pin 8 pull-up or pull-down bits */ +#define GPIO_PUD_PUD9 BITS(18,19) /*!< pin 9 pull-up or pull-down bits */ +#define GPIO_PUD_PUD10 BITS(20,21) /*!< pin 10 pull-up or pull-down bits */ +#define GPIO_PUD_PUD11 BITS(22,23) /*!< pin 11 pull-up or pull-down bits */ +#define GPIO_PUD_PUD12 BITS(24,25) /*!< pin 12 pull-up or pull-down bits */ +#define GPIO_PUD_PUD13 BITS(26,27) /*!< pin 13 pull-up or pull-down bits */ +#define GPIO_PUD_PUD14 BITS(28,29) /*!< pin 14 pull-up or pull-down bits */ +#define GPIO_PUD_PUD15 BITS(30,31) /*!< pin 15 pull-up or pull-down bits */ + +/* GPIO_ISTAT */ +#define GPIO_ISTAT_ISTAT0 BIT(0) /*!< pin 0 input status */ +#define GPIO_ISTAT_ISTAT1 BIT(1) /*!< pin 1 input status */ +#define GPIO_ISTAT_ISTAT2 BIT(2) /*!< pin 2 input status */ +#define GPIO_ISTAT_ISTAT3 BIT(3) /*!< pin 3 input status */ +#define GPIO_ISTAT_ISTAT4 BIT(4) /*!< pin 4 input status */ +#define GPIO_ISTAT_ISTAT5 BIT(5) /*!< pin 5 input status */ +#define GPIO_ISTAT_ISTAT6 BIT(6) /*!< pin 6 input status */ +#define GPIO_ISTAT_ISTAT7 BIT(7) /*!< pin 7 input status */ +#define GPIO_ISTAT_ISTAT8 BIT(8) /*!< pin 8 input status */ +#define GPIO_ISTAT_ISTAT9 BIT(9) /*!< pin 9 input status */ +#define GPIO_ISTAT_ISTAT10 BIT(10) /*!< pin 10 input status */ +#define GPIO_ISTAT_ISTAT11 BIT(11) /*!< pin 11 input status */ +#define GPIO_ISTAT_ISTAT12 BIT(12) /*!< pin 12 input status */ +#define GPIO_ISTAT_ISTAT13 BIT(13) /*!< pin 13 input status */ +#define GPIO_ISTAT_ISTAT14 BIT(14) /*!< pin 14 input status */ +#define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ + +/* GPIO_OCTL */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4,7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8,11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12,15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16,19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20,23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24,27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28,31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0,3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4,7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8,11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12,15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16,19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20,23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24,27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28,31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +/* GPIO_TG */ +#define GPIO_TG_TG0 BIT(0) /*!< pin 0 toggle bit */ +#define GPIO_TG_TG1 BIT(1) /*!< pin 1 toggle bit */ +#define GPIO_TG_TG2 BIT(2) /*!< pin 2 toggle bit */ +#define GPIO_TG_TG3 BIT(3) /*!< pin 3 toggle bit */ +#define GPIO_TG_TG4 BIT(4) /*!< pin 4 toggle bit */ +#define GPIO_TG_TG5 BIT(5) /*!< pin 5 toggle bit */ +#define GPIO_TG_TG6 BIT(6) /*!< pin 6 toggle bit */ +#define GPIO_TG_TG7 BIT(7) /*!< pin 7 toggle bit */ +#define GPIO_TG_TG8 BIT(8) /*!< pin 8 toggle bit */ +#define GPIO_TG_TG9 BIT(9) /*!< pin 9 toggle bit */ +#define GPIO_TG_TG10 BIT(10) /*!< pin 10 toggle bit */ +#define GPIO_TG_TG11 BIT(11) /*!< pin 11 toggle bit */ +#define GPIO_TG_TG12 BIT(12) /*!< pin 12 toggle bit */ +#define GPIO_TG_TG13 BIT(13) /*!< pin 13 toggle bit */ +#define GPIO_TG_TG14 BIT(14) /*!< pin 14 toggle bit */ +#define GPIO_TG_TG15 BIT(15) /*!< pin 15 toggle bit */ + +/* GPIO_IFL */ +#define GPIO_IFL_FLPRD0 BITS(0,7) /*!< filter sampling period for GPIO1 to GPIO7 */ +#define GPIO_IFL_FLPRD1 BITS(8,15) /*!< filter sampling period for GPIO8 to GPIO15 */ + +/* GPIO_IFTP */ +#define GPIO_IFTP_IFTP0 BITS(0,1) /*!< pin 0 input filtering type bits */ +#define GPIO_IFTP_IFTP1 BITS(2,3) /*!< pin 1 input filtering type bits */ +#define GPIO_IFTP_IFTP2 BITS(4,5) /*!< pin 2 input filtering type bits */ +#define GPIO_IFTP_IFTP3 BITS(6,7) /*!< pin 3 input filtering type bits */ +#define GPIO_IFTP_IFTP4 BITS(8,9) /*!< pin 4 input filtering type bits */ +#define GPIO_IFTP_IFTP5 BITS(10,11) /*!< pin 5 input filtering type bits */ +#define GPIO_IFTP_IFTP6 BITS(12,13) /*!< pin 6 input filtering type bits */ +#define GPIO_IFTP_IFTP7 BITS(14,15) /*!< pin 7 input filtering type bits */ +#define GPIO_IFTP_IFTP8 BITS(16,17) /*!< pin 8 input filtering type bits */ +#define GPIO_IFTP_IFTP9 BITS(18,19) /*!< pin 9 input filtering type bits */ +#define GPIO_IFTP_IFTP10 BITS(20,21) /*!< pin 10 input filtering type bits */ +#define GPIO_IFTP_IFTP11 BITS(22,23) /*!< pin 11 input filtering type bits */ +#define GPIO_IFTP_IFTP12 BITS(24,25) /*!< pin 12 input filtering type bits */ +#define GPIO_IFTP_IFTP13 BITS(26,27) /*!< pin 13 input filtering type bits */ +#define GPIO_IFTP_IFTP14 BITS(28,29) /*!< pin 14 input filtering type bits */ +#define GPIO_IFTP_IFTP15 BITS(30,31) /*!< pin 15 input filtering type bits */ + +/* constants definitions */ +typedef FlagStatus bit_status; + +/* output mode definitions */ +#define CTL_CLTR(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_MODE_INPUT CTL_CLTR(0) /*!< input mode */ +#define GPIO_MODE_OUTPUT CTL_CLTR(1) /*!< output mode */ +#define GPIO_MODE_AF CTL_CLTR(2) /*!< alternate function mode */ +#define GPIO_MODE_ANALOG CTL_CLTR(3) /*!< analog mode */ + +/* pull-up/pull-down definitions */ +#define PUD_PUPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_PUPD_NONE PUD_PUPD(0) /*!< floating mode, no pull-up and pull-down resistors */ +#define GPIO_PUPD_PULLUP PUD_PUPD(1) /*!< with pull-up resistor */ +#define GPIO_PUPD_PULLDOWN PUD_PUPD(2) /*!< with pull-down resistor */ + +/* GPIO pin definitions */ +#define GPIO_PIN_0 BIT(0) /*!< GPIO pin 0 */ +#define GPIO_PIN_1 BIT(1) /*!< GPIO pin 1 */ +#define GPIO_PIN_2 BIT(2) /*!< GPIO pin 2 */ +#define GPIO_PIN_3 BIT(3) /*!< GPIO pin 3 */ +#define GPIO_PIN_4 BIT(4) /*!< GPIO pin 4 */ +#define GPIO_PIN_5 BIT(5) /*!< GPIO pin 5 */ +#define GPIO_PIN_6 BIT(6) /*!< GPIO pin 6 */ +#define GPIO_PIN_7 BIT(7) /*!< GPIO pin 7 */ +#define GPIO_PIN_8 BIT(8) /*!< GPIO pin 8 */ +#define GPIO_PIN_9 BIT(9) /*!< GPIO pin 9 */ +#define GPIO_PIN_10 BIT(10) /*!< GPIO pin 10 */ +#define GPIO_PIN_11 BIT(11) /*!< GPIO pin 11 */ +#define GPIO_PIN_12 BIT(12) /*!< GPIO pin 12 */ +#define GPIO_PIN_13 BIT(13) /*!< GPIO pin 13 */ +#define GPIO_PIN_14 BIT(14) /*!< GPIO pin 14 */ +#define GPIO_PIN_15 BIT(15) /*!< GPIO pin 15 */ +#define GPIO_PIN_ALL BITS(0,15) /*!< GPIO pin all */ + +/* GPIO mode configuration values */ +#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (2U * (n)))) +#define GPIO_MODE_MASK(n) (0x3U << (2U * (n))) + +/* GPIO pull-up/pull-down values */ +#define GPIO_PUPD_SET(n, pupd) ((uint32_t)((uint32_t)(pupd) << (2U * (n)))) +#define GPIO_PUPD_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output speed values */ +#define GPIO_OSPEED_SET(n, speed) ((uint32_t)((uint32_t)(speed) << (2U * (n)))) +#define GPIO_OSPEED_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output type */ +#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */ + +/* GPIO output max speed value */ +#define OSPD_OSPD0(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_12MHZ OSPD_OSPD0(0) /*!< output max speed 12MHz */ +#define GPIO_OSPEED_60MHZ OSPD_OSPD0(1) /*!< output max speed 60MHz */ +#define GPIO_OSPEED_85MHZ OSPD_OSPD0(2) /*!< output max speed 85MHz */ +#define GPIO_OSPEED_100_220MHZ OSPD_OSPD0(3) /*!< output max speed 100/220MHz */ + +/* GPIO input filter type values */ +#define GPIO_IFTYPE_SET(n, type) ((uint32_t)((uint32_t)(type) << (2U * (n)))) +#define GPIO_IFTYPE_MASK(n) (0x3U << (2U * (n))) + +/* GPIO input filter sample period */ +#define IFL_FLPRD0(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) +#define GPIO_ISPERIOD(vle) IFL_FLPRD0(vle) /*!< input filter sample period */ + +/* GPIO input filtering type */ +#define IFTYPE_IFTP0(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_IFTYPE_SYNC IFTYPE_IFTP0(0) /*!< input filter type synchronization */ +#define GPIO_IFTYPE_3_SAMPLE IFTYPE_IFTP0(1) /*!< input filter type filter 3 samples */ +#define GPIO_IFTYPE_6_SAMPLE IFTYPE_IFTP0(2) /*!< input filter type filter 6 samples */ +#define GPIO_IFTYPE_ASYNC IFTYPE_IFTP0(3) /*!< input filter type asynchronous */ + +/* GPIO alternate function values */ +#define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n)))) +#define GPIO_AFR_MASK(n) (0xFU << (4U * (n))) + +/* GPIO alternate function */ +#define AF(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define GPIO_AF_0 AF(0) /*!< alternate function 0 selected */ +#define GPIO_AF_1 AF(1) /*!< alternate function 1 selected */ +#define GPIO_AF_2 AF(2) /*!< alternate function 2 selected */ +#define GPIO_AF_3 AF(3) /*!< alternate function 3 selected */ +#define GPIO_AF_4 AF(4) /*!< alternate function 4 selected */ +#define GPIO_AF_5 AF(5) /*!< alternate function 5 selected */ +#define GPIO_AF_6 AF(6) /*!< alternate function 6 selected */ +#define GPIO_AF_7 AF(7) /*!< alternate function 7 selected */ +#define GPIO_AF_8 AF(8) /*!< alternate function 8 selected */ +#define GPIO_AF_9 AF(9) /*!< alternate function 9 selected */ +#define GPIO_AF_10 AF(10) /*!< alternate function 10 selected */ +#define GPIO_AF_11 AF(11) /*!< alternate function 11 selected */ +#define GPIO_AF_12 AF(12) /*!< alternate function 12 selected */ +#define GPIO_AF_13 AF(13) /*!< alternate function 13 selected */ +#define GPIO_AF_14 AF(14) /*!< alternate function 14 selected */ +#define GPIO_AF_15 AF(15) /*!< alternate function 15 selected */ + +/* function declarations */ +/* reset GPIO port */ +void gpio_deinit(uint32_t gpio_periph); +/* set GPIO mode */ +void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin); +/* set GPIO output type and speed */ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin); + +/* set GPIO pin bit */ +void gpio_bit_set(uint32_t gpio_periph, uint32_t pin); +/* reset GPIO pin bit */ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin); +/* write data to the specified GPIO pin */ +void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value); +/* write data to the specified GPIO port */ +void gpio_port_write(uint32_t gpio_periph, uint16_t data); + +/* set GPIO input filter */ +void gpio_input_filter_set(uint32_t gpio_periph, uint8_t speriod, uint32_t iftype, uint32_t pin); +/* get GPIO pin input status */ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin); +/* get GPIO port input status */ +uint16_t gpio_input_port_get(uint32_t gpio_periph); +/* get GPIO pin output status */ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin); +/* get GPIO port output status */ +uint16_t gpio_output_port_get(uint32_t gpio_periph); + +/* set GPIO alternate function */ +void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin); +/* lock GPIO pin bit */ +void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin); + +/* toggle GPIO pin status */ +void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin); +/* toggle GPIO port status */ +void gpio_port_toggle(uint32_t gpio_periph); + +#endif /* GD32H7XX_GPIO_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hau.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hau.h new file mode 100644 index 0000000000..1739f975f3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hau.h @@ -0,0 +1,223 @@ +/*! + \file gd32h7xx_hau.h + \brief definitions for the HAU + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_HAU_H +#define GD32H7XX_HAU_H + +#include "gd32h7xx.h" + +/* HAU definitions */ +#define HAU HAU_BASE + +/* registers definitions */ +#define HAU_CTL REG32(HAU + 0x00000000U) /*!< control register */ +#define HAU_DI REG32(HAU + 0x00000004U) /*!< data input register */ +#define HAU_CFG REG32(HAU + 0x00000008U) /*!< configuration register */ +#define HAU_DO0 REG32(HAU + 0x0000000CU) /*!< data output register 0 */ +#define HAU_DO1 REG32(HAU + 0x00000010U) /*!< data output register 1 */ +#define HAU_DO2 REG32(HAU + 0x00000014U) /*!< data output register 2 */ +#define HAU_DO3 REG32(HAU + 0x00000018U) /*!< data output register 3 */ +#define HAU_DO4 REG32(HAU + 0x0000001CU) /*!< data output register 4 */ +#define HAU_DO5 REG32(HAU + 0x00000324U) /*!< data output register 5 */ +#define HAU_DO6 REG32(HAU + 0x00000328U) /*!< data output register 6 */ +#define HAU_DO7 REG32(HAU + 0x0000032CU) /*!< data output register 7 */ +#define HAU_INTEN REG32(HAU + 0x00000020U) /*!< interrupt enable register */ +#define HAU_STAT REG32(HAU + 0x00000024U) /*!< status and interrupt flag register */ +#define HAU_CTXS(x) REG32(HAU + 0x000000F8U + 0x04U * (x)) /*!< context switch register x, x <= 53 */ + +/* bits definitions */ +/* HAU_CTL */ +#define HAU_CTL_START BIT(2) /*!< set to 1 to reset the HAU processor core, so that it is ready to start the digest calculation */ +#define HAU_CTL_DMAE BIT(3) /*!< DMA enable */ +#define HAU_CTL_DATAM BITS(4,5) /*!< data type mode */ +#define HAU_CTL_HMS BIT(6) /*!< HAU mode selection */ +#define HAU_CTL_ALGM_0 BIT(7) /*!< algorithm selection bit 0 */ +#define HAU_CTL_NWIF BITS(8,11) /*!< number of words in the input FIFO */ +#define HAU_CTL_DINE BIT(12) /*!< DI register not empty */ +#define HAU_CTL_MDS BIT(13) /*!< multiple DMA selection */ +#define HAU_CTL_KLM BIT(16) /*!< key length mode */ +#define HAU_CTL_ALGM_1 BIT(18) /*!< algorithm selection bit 1 */ + +/* HAU_DI */ +#define HAU_DI_DI BITS(0,31) /*!< message data input */ + +/* HAU_CFG */ +#define HAU_CFG_VBL BITS(0,4) /*!< valid bits length in the last word */ +#define HAU_CFG_CALEN BIT(8) /*!< digest calculation enable */ + +/* HAU_DOx x=0..7 */ +#define HAU_DOX_DOX BITS(0,31) /*!< message digest result of hash algorithm */ + +/* HAU_INTEN */ +#define HAU_INTEN_DIIE BIT(0) /*!< data input interrupt enable */ +#define HAU_INTEN_CCIE BIT(1) /*!< calculation completion interrupt enable */ + +/* HAU_STAT */ +#define HAU_STAT_DIF BIT(0) /*!< data input interrupt flag */ +#define HAU_STAT_CCF BIT(1) /*!< digest calculation completion interrupt flag */ +#define HAU_STAT_DMAS BIT(2) /*!< DMA status */ +#define HAU_STAT_BUSY BIT(3) /*!< busy bit */ + +/* constants definitions */ +/* structure for initialization of the hau */ +typedef struct +{ + uint32_t algo; /*!< algorithm selection */ + uint32_t mode; /*!< HAU mode selection */ + uint32_t datatype; /*!< data type mode */ + uint32_t keytype; /*!< key length mode */ +}hau_init_parameter_struct; + +/* structure for message digest result of the hau */ +typedef struct +{ + uint32_t out[8]; /*!< message digest result 0-7 */ +}hau_digest_parameter_struct; + +/* structure for context switch */ +typedef struct +{ + uint32_t hau_ctl_bak; /*!< backup of HAU_CTL register */ + uint32_t hau_cfg_bak; /*!< backup of HAU_CFG register */ + uint32_t hau_inten_bak; /*!< backup of HAU_INTEN register */ + uint32_t hau_ctxs_bak[54]; /*!< backup of HAU_CTXSx registers */ +}hau_context_parameter_struct; + +/* hau_ctl register value */ +#define HAU_ALGO_SHA1 ((uint32_t)0x00000000U) /*!< HAU function is SHA1 */ +#define HAU_ALGO_SHA224 HAU_CTL_ALGM_1 /*!< HAU function is SHA224 */ +#define HAU_ALGO_SHA256 (HAU_CTL_ALGM_1 | HAU_CTL_ALGM_0) /*!< HAU function is SHA256 */ +#define HAU_ALGO_MD5 HAU_CTL_ALGM_0 /*!< HAU function is MD5 */ + +#define HAU_MODE_HASH ((uint32_t)0x00000000U) /*!< HAU mode is HASH */ +#define HAU_MODE_HMAC HAU_CTL_HMS /*!< HAU mode is HMAC */ + +#define CTL_DATAM_1(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) /*!< write value to HAU_CTL_DATAM bit field */ +#define HAU_SWAPPING_32BIT CTL_DATAM_1(0) /*!< no swapping */ +#define HAU_SWAPPING_16BIT CTL_DATAM_1(1) /*!< half-word swapping */ +#define HAU_SWAPPING_8BIT CTL_DATAM_1(2) /*!< bytes swapping */ +#define HAU_SWAPPING_1BIT CTL_DATAM_1(3) /*!< bit swapping */ + +#define HAU_KEY_SHORTER_64 ((uint32_t)0x00000000U) /*!< HMAC key is <= 64 bytes */ +#define HAU_KEY_LONGGER_64 HAU_CTL_KLM /*!< HMAC key is > 64 bytes */ + +#define GET_CTL_NWIF(regval) GET_BITS((regval),8,11) /*!< get value of HAU_CTL_NWIF bit field */ + +#define SINGLE_DMA_AUTO_DIGEST ((uint32_t)0x00000000U) /*!< message padding and message digest calculation at the end of a DMA transfer */ +#define MULTIPLE_DMA_NO_DIGEST HAU_CTL_MDS /*!< multiple DMA transfers needed and CALEN bit is not automatically set at the end of a DMA transfer */ + +/* hau_cfg register value */ +#define CFG_VBL(regval) (BITS(0,4) & (((uint32_t)(regval)))) /*!< write value to HAU_CFG_VBL bit field */ + +/* hau_inten register value */ +#define HAU_INT_DATA_INPUT HAU_INTEN_DIIE /*!< a new block can be entered into the IN buffer */ +#define HAU_INT_CALCULATION_COMPLETE HAU_INTEN_CCIE /*!< calculation complete */ + +#define HAU_FLAG_DATA_INPUT HAU_STAT_DIF /*!< there is enough space (16 bytes) in the input FIFO */ +#define HAU_FLAG_CALCULATION_COMPLETE HAU_STAT_CCF /*!< digest calculation is completed */ +#define HAU_FLAG_DMA HAU_STAT_DMAS /*!< DMA is enabled (DMAE =1) or a transfer is processing */ +#define HAU_FLAG_BUSY HAU_STAT_BUSY /*!< data block is in process */ +#define HAU_FLAG_INFIFO_NO_EMPTY HAU_CTL_DINE /*!< the input FIFO is not empty */ + +#define HAU_INT_FLAG_DATA_INPUT HAU_STAT_DIF /*!< there is enough space (16 bytes) in the input FIFO */ +#define HAU_INT_FLAG_CALCULATION_COMPLETE HAU_STAT_CCF /*!< digest calculation is completed */ + +/* function declarations */ +/* initialization functions */ +/* reset the HAU peripheral */ +void hau_deinit(void); +/* initialize the HAU peripheral parameters */ +void hau_init(hau_init_parameter_struct* initpara); +/* initialize the structure hau_initpara with default value */ +void hau_init_struct_para_init(hau_init_parameter_struct* initpara); +/* reset the HAU processor core */ +void hau_reset(void); +/* configure the number of valid bits in last word of the message */ +void hau_last_word_validbits_num_config(uint32_t valid_num); +/* write data to the IN FIFO */ +void hau_data_write(uint32_t data); +/* return the number of words already written into the IN FIFO */ +uint32_t hau_infifo_words_num_get(void); +/* read the message digest result */ +void hau_digest_read(hau_digest_parameter_struct* digestpara); +/* enable digest calculation */ +void hau_digest_calculation_enable(void); +/* configure single or multiple DMA is used, and digest calculation at the end of a DMA transfer or not */ +void hau_multiple_single_dma_config(uint32_t multi_single); +/* enable the HAU DMA interface */ +void hau_dma_enable(void); +/* disable the HAU DMA interface */ +void hau_dma_disable(void); + +/* context swapping functions */ +/* initialize the struct context */ +void hau_context_struct_para_init(hau_context_parameter_struct* context); +/* save the HAU peripheral context */ +void hau_context_save(hau_context_parameter_struct* context_save); +/* restore the HAU peripheral context */ +void hau_context_restore(hau_context_parameter_struct* context_restore); + +/* calculate digest in HASH mode */ +/* calculate digest using SHA1 in HASH mode */ +ErrStatus hau_hash_sha_1(uint8_t input[], uint32_t in_length, uint8_t output[]); +/* calculate digest using SHA1 in HMAC mode */ +ErrStatus hau_hmac_sha_1(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]); +/* calculate digest using SHA224 in HASH mode */ +ErrStatus hau_hash_sha_224(uint8_t input[], uint32_t in_length, uint8_t output[]); +/* calculate digest using SHA224 in HMAC mode */ +ErrStatus hau_hmac_sha_224(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]); +/* calculate digest using SHA256 in HASH mode */ +ErrStatus hau_hash_sha_256(uint8_t input[], uint32_t in_length, uint8_t output[]); +/* calculate digest using SHA256 in HMAC mode */ +ErrStatus hau_hmac_sha_256(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]); +/* calculate digest using MD5 in HASH mode */ +ErrStatus hau_hash_md5(uint8_t input[], uint32_t in_length, uint8_t output[]); +/* calculate digest using MD5 in HMAC mode */ +ErrStatus hau_hmac_md5(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]); + +/* interrupt & flag functions */ +/* get the HAU flag status */ +FlagStatus hau_flag_get(uint32_t flag); +/* clear the HAU flag status */ +void hau_flag_clear(uint32_t flag); +/* enable the HAU interrupts */ +void hau_interrupt_enable(uint32_t interrupt); +/* disable the HAU interrupts */ +void hau_interrupt_disable(uint32_t interrupt); +/* get the HAU interrupt flag status */ +FlagStatus hau_interrupt_flag_get(uint32_t int_flag); +/* clear the HAU interrupt flag status */ +void hau_interrupt_flag_clear(uint32_t int_flag); + +#endif /* GD32H7XX_HAU_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hpdf.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hpdf.h new file mode 100644 index 0000000000..cb4e8c27dc --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hpdf.h @@ -0,0 +1,760 @@ +/*! + \file gd32h7xx_hpdf.h + \brief definitions for the HPDF + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_HPDF_H +#define GD32H7XX_HPDF_H + +#include "gd32h7xx.h" + +/* HPDF definitions */ +#define HPDF HPDF_BASE /*!< HPDF base address */ + +/* registers definitions */ +#define HPDF_CHXCTL(chx) REG32((HPDF) + 0x00000000U + ((chx) * 0x00000020U)) /*!< HPDF Channel x control register */ +#define HPDF_CHXCFG0(chx) REG32((HPDF) + 0x00000004U + ((chx) * 0x00000020U)) /*!< HPDF Channel x configuration register 0 */ +#define HPDF_CHXCFG1(chx) REG32((HPDF) + 0x00000008U + ((chx) * 0x00000020U)) /*!< HPDF Channel x configuration register 1 */ +#define HPDF_CHXTMFDT(chx) REG32((HPDF) + 0x0000000CU + ((chx) * 0x00000020U)) /*!< HPDF Channel x threshold monitor filter data register */ +#define HPDF_CHXPDI(chx) REG32((HPDF) + 0x00000010U + ((chx) * 0x00000020U)) /*!< HPDF Channel x parallel data input register */ +#define HPDF_CHXPS(chx) REG32((HPDF) + 0x00000014U + ((chx) * 0x00000020U)) /*!< HPDF Channel x pulse skip register */ +#define HPDF_FLTYCTL0(flty) REG32((HPDF) + 0x00000100U + ((flty) * 0x00000080U)) /*!< HPDF Filter y control register 0 */ +#define HPDF_FLTYCTL1(flty) REG32((HPDF) + 0x00000104U + ((flty) * 0x00000080U)) /*!< HPDF Filter y control register 1 */ +#define HPDF_FLTYSTAT(flty) REG32((HPDF) + 0x00000108U + ((flty) * 0x00000080U)) /*!< HPDF Filter y status register */ +#define HPDF_FLTYINTC(flty) REG32((HPDF) + 0x0000010CU + ((flty) * 0x00000080U)) /*!< HPDF Filter y interrupt flag clear register */ +#define HPDF_FLTYICGS(flty) REG32((HPDF) + 0x00000110U + ((flty) * 0x00000080U)) /*!< HPDF Filter y inserted channel group selection register */ +#define HPDF_FLTYSFCFG(flty) REG32((HPDF) + 0x00000114U + ((flty) * 0x00000080U)) /*!< HPDF Filter y sinc filter configuration register */ +#define HPDF_FLTYIDATA(flty) REG32((HPDF) + 0x00000118U + ((flty) * 0x00000080U)) /*!< HPDF Filter y inserted group conversion data register */ +#define HPDF_FLTYRDATA(flty) REG32((HPDF) + 0x0000011CU + ((flty) * 0x00000080U)) /*!< HPDF Filter y regular channel conversion data register */ +#define HPDF_FLTYTMHT(flty) REG32((HPDF) + 0x00000120U + ((flty) * 0x00000080U)) /*!< HPDF Filter y threshold monitor high threshold register */ +#define HPDF_FLTYTMLT(flty) REG32((HPDF) + 0x00000124U + ((flty) * 0x00000080U)) /*!< HPDF Filter y threshold monitor low threshold register */ +#define HPDF_FLTYTMSTAT(flty) REG32((HPDF) + 0x00000128U + ((flty) * 0x00000080U)) /*!< HPDF Filter y threshold monitor status register */ +#define HPDF_FLTYTMFC(flty) REG32((HPDF) + 0x0000012CU + ((flty) * 0x00000080U)) /*!< HPDF Filter y threshold monitor flag clear register */ +#define HPDF_FLTYEMMAX(flty) REG32((HPDF) + 0x00000130U + ((flty) * 0x00000080U)) /*!< HPDF Filter y extremes monitor maximum register */ +#define HPDF_FLTYEMMIN(flty) REG32((HPDF) + 0x00000134U + ((flty) * 0x00000080U)) /*!< HPDF Filter y extremes monitor minimum register */ +#define HPDF_FLTYCT(flty) REG32((HPDF) + 0x00000138U + ((flty) * 0x00000080U)) /*!< HPDF Filter y conversion timer register */ + +/* bits definitions */ +/* HPDF_CHXCTL */ +#define HPDF_CHXCTL_SITYP BITS(0,1) /*!< serial interface type */ +#define HPDF_CHXCTL_SPICKSS BITS(2,3) /*!< SPI clock source select */ +#define HPDF_CHXCTL_MMEN BIT(5) /*!< malfunction monitor detector enable */ +#define HPDF_CHXCTL_CKLEN BIT(6) /*!< clock loss detector enable */ +#define HPDF_CHXCTL_CHEN BIT(7) /*!< channel enable */ +#define HPDF_CHXCTL_CHPINSEL BIT(8) /*!< channel inputs pins selection */ +#define HPDF_CHXCTL_CMSD BITS(12,13) /*!< channel multiplexer select input data source */ +#define HPDF_CHXCTL_DPM BITS(14,15) /*!< data packing mode for HPDF_CHXPDI register */ +/* only available in HPDF_CH0CTL */ +#define HPDF_CH0CTL_CKOUTDIV BITS(16,23) /*!< serial clock output divider */ +#define HPDF_CH0CTL_CKOUTDM BIT(29) /*!< serial clock output duty mode */ +#define HPDF_CH0CTL_CKOUTSEL BIT(30) /*!< serial clock output source selection */ +#define HPDF_CH0CTL_HPDFEN BIT(31) /*!< HPDF peripheral enable */ + +/* HPDF_CHXCFG0 */ +#define HPDF_CHXCFG0_DTRS BITS(3,7) /*!< data right bit-shift */ +#define HPDF_CHXCFG0_CALOFF BITS(8,31) /*!< 24-bit calibration offset */ + +/* HPDF_CHXCFG1 */ +#define HPDF_CHXCFG1_MMCT BITS(0,7) /*!< malfunction monitor counter threshold */ +#define HPDF_CHXCFG1_MMBSD BITS(12,15) /*!< malfunction monitor break signal distribution */ +#define HPDF_CHXCFG1_TMFOR BITS(16,20) /*!< threshold monitor filter oversampling rate */ +#define HPDF_CHXCFG1_TMSFO BITS(22,23) /*!< threshold monitor Sinc filter order selection */ + +/* HPDF_CHXTMFDT */ +#define HPDF_CHXTMFDT_TMDATA BITS(0,15) /*!< threshold monitor data */ + +/* HPDF_CHXPDI */ +#define HPDF_CHXPDI_DATAIN0 BITS(0,15) /*!< data input for channel x or channel x+1 */ +#define HPDF_CHXPDI_DATAIN1 BITS(16,31) /*!< data input for channel x */ + +/* HPDF_CHXPS */ +#define HPDF_CHXPS_PLSK BITS(0,5) /*!< pulses to skip for input data skipping function */ + +/* HPDF_FLTYCTL0 */ +#define HPDF_FLTYCTL0_FLTEN BIT(0) /*!< HPDF_FLTy enable */ +#define HPDF_FLTYCTL0_SICC BIT(1) /*!< start inserted group channel conversion */ +#define HPDF_FLTYCTL0_ICSYN BIT(3) /*!< inserted conversion synchronously with the HPDF_FLT0 SICC trigger */ +#define HPDF_FLTYCTL0_SCMOD BIT(4) /*!< scan conversion mode of inserted conversions */ +#define HPDF_FLTYCTL0_ICDMAEN BIT(5) /*!< DMA channel enabled to read data for the inserted channel group */ +#define HPDF_FLTYCTL0_ICTSSEL BITS(8,12) /*!< inserted conversions trigger signal selection */ +#define HPDF_FLTYCTL0_ICTEEN BITS(13,14) /*!< inserted conversions trigger edge enable */ +#define HPDF_FLTYCTL0_SRCS BIT(17) /*!< start regular channel conversion by software */ +#define HPDF_FLTYCTL0_RCCM BIT(18) /*!< regular conversions continuous mode */ +#define HPDF_FLTYCTL0_RCSYN BIT(19) /*!< regular conversion synchronously with HPDF_FLT0 */ +#define HPDF_FLTYCTL0_RCDMAEN BIT(21) /*!< DMA channel enabled to read data for the regular conversion */ +#define HPDF_FLTYCTL0_RCS BITS(24,26) /*!< regular conversion channel selection*/ +#define HPDF_FLTYCTL0_FAST BIT(29) /*!< fast conversion mode enable for regular conversions */ +#define HPDF_FLTYCTL0_TMFM BIT(30) /*!< threshold monitor fast mode */ + +/* HPDF_FLTYCTL1 */ +#define HPDF_FLTYCTL1_ICEIE BIT(0) /*!< inserted conversion end interrupt enable */ +#define HPDF_FLTYCTL1_RCEIE BIT(1) /*!< regular conversion end interrupt enable */ +#define HPDF_FLTYCTL1_ICDOIE BIT(2) /*!< inserted conversion data overflow interrupt enable */ +#define HPDF_FLTYCTL1_RCDOIE BIT(3) /*!< regular conversion data overflow interrupt enable */ +#define HPDF_FLTYCTL1_TMIE BIT(4) /*!< threshold monitor interrupt enable */ +#define HPDF_FLTYCTL1_EMCS BITS(8,15) /*!< extremes monitor channel selection */ +#define HPDF_FLTYCTL1_TMCHEN BITS(16,23) /*!< threshold monitor channel enable */ +/* only available in HPDF_FLT0CTL1 */ +#define HPDF_FLT0CTL1_MMIE BIT(5) /*!< malfunction monitor detector interrupt enable */ +#define HPDF_FLT0CTL1_CKLIE BIT(6) /*!< clock loss interrupt enable */ + +/* HPDF_FLTYSTAT */ +#define HPDF_FLTYSTAT_ICEF BIT(0) /*!< inserted conversion end flag */ +#define HPDF_FLTYSTAT_RCEF BIT(1) /*!< regular conversion end flag */ +#define HPDF_FLTYSTAT_ICDOF BIT(2) /*!< inserted conversion data overflow flag */ +#define HPDF_FLTYSTAT_RCDOF BIT(3) /*!< regular conversion data overflow flag */ +#define HPDF_FLTYSTAT_TMEOF BIT(4) /*!< threshold monitor event occurred flag */ +#define HPDF_FLTYSTAT_ICPF BIT(13) /*!< inserted conversion in progress flag */ +#define HPDF_FLTYSTAT_RCPF BIT(14) /*!< regular conversion in progress flag */ +/* only available in HPDF_FLT0STAT */ +#define HPDF_FLT0STAT_CKLF BITS(16,23) /*!< clock loss flag */ +#define HPDF_FLT0STAT_MMF BITS(24,31) /*!< malfunction monitor detection flag */ + +/* HPDF_FLTYINTC */ +#define HPDF_FLTYINTC_ICDOFC BIT(2) /*!< clear the inserted conversion data overflow flag */ +#define HPDF_FLTYINTC_RCDOFC BIT(3) /*!< clear the regular conversion data overflow flag */ +/* only available in HPDF_FLT0INTC */ +#define HPDF_FLT0INTC_CKLFC BITS(16,23) /*!< clear the clock loss flag */ +#define HPDF_FLT0INTC_MMFC BITS(24,31) /*!< clear the malfunction monitor detection flag */ + +/* HPDF_FLTYICGS */ +#define HPDF_FLTYICGS_ICGSEL BITS(0,7) /*!< inserted channel group selection */ + +/* HPDF_FLTYSFCFG */ +#define HPDF_FLTYSFCFG_IOR BITS(0,7) /*!< integrator oversampling ratio */ +#define HPDF_FLTYSFCFG_SFOR BITS(16,25) /*!< Sinc filter oversampling rate (decimation rate) */ +#define HPDF_FLTYSFCFG_SFO BITS(29,31) /*!< Sinc filter order */ + +/* HPDF_FLTYIDATA */ +#define HPDF_FLTYIDATA_ICCH BITS(0,2) /*!< inserted channel most recently converted */ +#define HPDF_FLTYIDATA_IDTAT BITS(8,31) /*!< inserted group conversion data */ + +/* HPDF_FLTYRDATA */ +#define HPDF_FLTYRDATA_RCCH BITS(0,2) /*!< regular channel most recently converted */ +#define HPDF_FLTYRDATA_RCHPDT BIT(4) /*!< regular channel pending data*/ +#define HPDF_FLTYRDATA_RDATA BITS(8,31) /*!< regular channel conversion data */ + +/* HPDF_FLTYTMHT */ +#define HPDF_FLTYTMHT_HTBSD BITS(0,3) /*!< high threshold event break signal distribution */ +#define HPDF_FLTYTMHT_HTVAL BITS(8,31) /*!< threshold monitor high threshold value */ + +/* HPDF_FLTYTMLT */ +#define HPDF_FLTYTMLT_LTBSD BITS(0,3) /*!< low threshold event break signal distribution */ +#define HPDF_FLTYTMLT_LTVAL BITS(8,31) /*!< threshold monitor low threshold value */ + +/* HPDF_FLTYTMSTAT */ +#define HPDF_FLTYTMSTAT_LTF BITS(0,7) /*!< threshold monitor low threshold flag */ +#define HPDF_FLTYTMSTAT_HTF BITS(8,15) /*!< threshold monitor high threshold flag */ + +/* HPDF_FLTYTMFC */ +#define HPDF_FLTYTMFC_LTFC BITS(0,7) /*!< clear the threshold monitor low threshold flag */ +#define HPDF_FLTYTMFC_HTFC BITS(8,15) /*!< clear the threshold monitor high threshold flag */ + +/* HPDF_FLTYEMMAX */ +#define HPDF_FLTYEMMAX_MAXDC BIT(0,2) /*!< extremes monitor maximum data channel */ +#define HPDF_FLTYEMMAX_MAXVAL BITS(8,31) /*!< extremes monitor maximum value */ + +/* HPDF_FLTYEMMIN */ +#define HPDF_FLTYEMMIN_MINDC BIT(0,2) /*!< extremes monitor minimum data channel */ +#define HPDF_FLTYEMMIN_MINVAL BITS(8,31) /*!< extremes monitor minimum value */ + +/* HPDF_FLTYCT */ +#define HPDF_FLTYCT_CTCNT BIT(4,31) /*!< conversion time measured by HPDFCLK */ + +/* register offset */ +#define FLTYCTL1_REG_OFFSET ((uint16_t)0x0004U) /*!< the offset of FLTYCTL1 register */ +#define FLTYSTAT_REG_OFFSET ((uint16_t)0x0008U) /*!< the offset of FLTYSTAT register */ +#define FLTYRDATA_REG_OFFSET ((uint16_t)0x001CU) /*!< the offset of FLTYRDATA register */ +#define FLTYTMSTAT_REG_OFFSET ((uint16_t)0x0028U) /*!< the offset of FLTYTMSTAT register */ + +/* HPDF flags and interrupt definitions */ +/* define the HPDF bit position and its register index offset */ +#define HPDF_FLT0 (HPDF + 0x00000100U) +#define HPDF_FLT1 (HPDF + 0x00000180U) +#define HPDF_FLT2 (HPDF + 0x00000200U) +#define HPDF_FLT3 (HPDF + 0x00000280U) +#define HPDF_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define HPDF_REG_VAL(regidx, offset) (REG32((regidx) + (((uint32_t)(offset) & 0x0000FFC0U) >> 6))) +#define HPDF_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define HPDF_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define HPDF_REG_VAL2(regidx, offset) (REG32((regidx) + ((uint32_t)(offset) >> 22))) +#define HPDF_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* constants definitions */ +/* parameter struct definitions */ +/* channel configuration params */ +typedef struct { + uint32_t data_packing_mode; /*!< data packing mode for HPDF_CHXPDI register */ + uint32_t channel_multiplexer; /*!< channel multiplexer select input data source */ + uint32_t channel_pin_select; /*!< channel inputs pins selection */ + uint32_t ck_loss_detector; /*!< clock loss detector */ + uint32_t malfunction_monitor; /*!< malfunction monitor */ + uint32_t spi_ck_source; /*!< SPI clock source select */ + uint32_t serial_interface; /*!< serial interface type */ + int32_t calibration_offset; /*!< 24-bit calibration offset */ + uint32_t right_bit_shift; /*!< data right bit-shift */ + uint32_t tm_filter; /*!< threshold monitor Sinc filter order selection */ + uint32_t tm_filter_oversample; /*!< threshold monitor filter oversampling rate */ + uint32_t mm_break_signal; /*!< malfunction monitor break signal distribution */ + uint32_t mm_counter_threshold; /*!< malfunction monitor counter threshold */ + uint32_t plsk_value; /*!< the number of serial input samples that will be skipped */ +} hpdf_channel_parameter_struct; + +/* filter configuration params */ +typedef struct { + uint32_t tm_fast_mode; /*!< threshold monitor fast mode */ + uint32_t tm_channel; /*!< threshold monitor channel */ + int32_t tm_high_threshold; /*!< threshold monitor high threshold */ + int32_t tm_low_threshold; /*!< threshold monitor low threshold value */ + uint32_t extreme_monitor_channel; /*!< extremes monitor channel */ + uint32_t sinc_filter; /*!< sinc filter order */ + uint32_t sinc_oversample; /*!< sinc filter oversampling rate */ + uint32_t integrator_oversample; /*!< integrator oversampling rate */ + uint32_t ht_break_signal; /*!< high threshold event break signal distribution */ + uint32_t lt_break_signal; /*!< low threshold event break signal distribution */ +} hpdf_filter_parameter_struct; + +/* regular conversions configuration params */ +typedef struct { + uint32_t fast_mode; /*!< fast conversion mode enable for regular conversions */ + uint32_t rcs_channel; /*!< regular conversion channel */ + uint32_t rcdmaen; /*!< DMA channel enabled to read data for the regular conversion */ + uint32_t rcsyn; /*!< regular conversion synchronously */ + uint32_t continuous_mode; /*!< regular conversions continuous mode */ +} hpdf_rc_parameter_struct; + +/* inserted conversions configuration params */ +typedef struct { + uint32_t trigger_edge; /*!< inserted conversions trigger edge */ + uint32_t trigger_signal; /*!< inserted conversions trigger signal */ + uint32_t icdmaen; /*!< DMA channel enabled to read data for the inserted channel group */ + uint32_t scmod; /*!< scan conversion mode of inserted conversions */ + uint32_t icsyn; /*!< inserted conversion synchronously */ + uint32_t ic_channel_group; /*!< inserted channel group selection */ +} hpdf_ic_parameter_struct; + +/* enum definitions */ +/* HPDF channel */ +typedef enum { + CHANNEL0 = 0, /*!< HPDF channel0 */ + CHANNEL1, /*!< HPDF channel1 */ + CHANNEL2, /*!< HPDF channel2 */ + CHANNEL3, /*!< HPDF channel3 */ + CHANNEL4, /*!< HPDF channel4 */ + CHANNEL5, /*!< HPDF channel5 */ + CHANNEL6, /*!< HPDF channel6 */ + CHANNEL7 /*!< HPDF channel7 */ +} hpdf_channel_enum; + +/* HPDF filter */ +typedef enum { + FLT0 = 0, /*!< HPDF filter0 */ + FLT1, /*!< HPDF filter1 */ + FLT2, /*!< HPDF filter2 */ + FLT3 /*!< HPDF filter3 */ +} hpdf_filter_enum; + +/* HPDF flags */ +typedef enum { + /* flags in FLTYSTAT register */ + HPDF_FLAG_FLTY_ICEF = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 0U), /*!< inserted conversion end flag */ + HPDF_FLAG_FLTY_RCEF = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 1U), /*!< regular conversion end flag */ + HPDF_FLAG_FLTY_ICDOF = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 2U), /*!< inserted conversion overflow flag */ + HPDF_FLAG_FLTY_RCDOF = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 3U), /*!< regular conversion overflow flag */ + HPDF_FLAG_FLTY_TMEOF = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 4U), /*!< threshold monitor event occurred flag */ + HPDF_FLAG_FLTY_ICPF = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 13U), /*!< inserted conversion in progress flag */ + HPDF_FLAG_FLTY_RCPF = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 14U), /*!< regular conversion in progress flag */ + HPDF_FLAG_FLT0_CKLF0 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 16U), /*!< clock loss on channel 0 flag */ + HPDF_FLAG_FLT0_CKLF1 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 17U), /*!< clock loss on channel 1 flag */ + HPDF_FLAG_FLT0_CKLF2 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 18U), /*!< clock loss on channel 2 flag */ + HPDF_FLAG_FLT0_CKLF3 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 19U), /*!< clock loss on channel 3 flag */ + HPDF_FLAG_FLT0_CKLF4 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 20U), /*!< clock loss on channel 4 flag */ + HPDF_FLAG_FLT0_CKLF5 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 21U), /*!< clock loss on channel 5 flag */ + HPDF_FLAG_FLT0_CKLF6 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 22U), /*!< clock loss on channel 6 flag */ + HPDF_FLAG_FLT0_CKLF7 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 23U), /*!< clock loss on channel 7 flag */ + HPDF_FLAG_FLT0_MMF0 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 24U), /*!< malfunction event occurred on channel 0 flag */ + HPDF_FLAG_FLT0_MMF1 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 25U), /*!< malfunction event occurred on channel 1 flag */ + HPDF_FLAG_FLT0_MMF2 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 26U), /*!< malfunction event occurred on channel 2 flag */ + HPDF_FLAG_FLT0_MMF3 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 27U), /*!< malfunction event occurred on channel 3 flag */ + HPDF_FLAG_FLT0_MMF4 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 28U), /*!< malfunction event occurred on channel 4 flag */ + HPDF_FLAG_FLT0_MMF5 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 29U), /*!< malfunction event occurred on channel 5 flag */ + HPDF_FLAG_FLT0_MMF6 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 30U), /*!< malfunction event occurred on channel 6 flag */ + HPDF_FLAG_FLT0_MMF7 = HPDF_REGIDX_BIT(FLTYSTAT_REG_OFFSET, 31U), /*!< malfunction event occurred on channel 7 flag */ + /* flags in FLT0RDATA register */ + HPDF_FLAG_FLTY_RCHPDT = HPDF_REGIDX_BIT(FLTYRDATA_REG_OFFSET, 4U), /*!< regular channel pending data */ + /* flags in FLTYTMSTAT register */ + HPDF_FLAG_FLTY_LTF0 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 0U), /*!< threshold monitor low threshold on channel 0 flag */ + HPDF_FLAG_FLTY_LTF1 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 1U), /*!< threshold monitor low threshold on channel 1 flag */ + HPDF_FLAG_FLTY_LTF2 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 2U), /*!< threshold monitor low threshold on channel 2 flag */ + HPDF_FLAG_FLTY_LTF3 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 3U), /*!< threshold monitor low threshold on channel 3 flag */ + HPDF_FLAG_FLTY_LTF4 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 4U), /*!< threshold monitor low threshold on channel 4 flag */ + HPDF_FLAG_FLTY_LTF5 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 5U), /*!< threshold monitor low threshold on channel 5 flag */ + HPDF_FLAG_FLTY_LTF6 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 6U), /*!< threshold monitor low threshold on channel 6 flag */ + HPDF_FLAG_FLTY_LTF7 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 7U), /*!< threshold monitor low threshold on channel 7 flag */ + HPDF_FLAG_FLTY_HTF0 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 8U), /*!< threshold monitor high threshold on channel 0 flag */ + HPDF_FLAG_FLTY_HTF1 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 9U), /*!< threshold monitor high threshold on channel 1 flag */ + HPDF_FLAG_FLTY_HTF2 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 10U), /*!< threshold monitor high threshold on channel 2 flag */ + HPDF_FLAG_FLTY_HTF3 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 11U), /*!< threshold monitor high threshold on channel 3 flag */ + HPDF_FLAG_FLTY_HTF4 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 12U), /*!< threshold monitor high threshold on channel 4 flag */ + HPDF_FLAG_FLTY_HTF5 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 13U), /*!< threshold monitor high threshold on channel 5 flag */ + HPDF_FLAG_FLTY_HTF6 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 14U), /*!< threshold monitor high threshold on channel 6 flag */ + HPDF_FLAG_FLTY_HTF7 = HPDF_REGIDX_BIT(FLTYTMSTAT_REG_OFFSET, 15U) /*!< threshold monitor high threshold on channel 7 flag */ +} hpdf_flag_enum; + +/* HPDF interrput flags */ +typedef enum { + /* interrput flags in FLTYSTAT register */ + HPDF_INT_FLAG_FLTY_ICEF = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 0U, FLTYSTAT_REG_OFFSET, 0U), /*!< inserted conversion end interrupt flag */ + HPDF_INT_FLAG_FLTY_RCEF = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 1U, FLTYSTAT_REG_OFFSET, 1U), /*!< regular conversion end interruptflag */ + HPDF_INT_FLAG_FLTY_ICDOF = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 2U, FLTYSTAT_REG_OFFSET, 2U), /*!< inserted conversion overflow interrupt flag */ + HPDF_INT_FLAG_FLTY_RCDOF = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 3U, FLTYSTAT_REG_OFFSET, 3U), /*!< regular conversion overflow interrupt flag */ + HPDF_INT_FLAG_FLTY_TMEOF = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 4U, FLTYSTAT_REG_OFFSET, 4U), /*!< threshold monitor event occurred interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF0 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 16U), /*!< clock loss on channel 0 interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF1 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 17U), /*!< clock loss on channel 1 interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF2 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 18U), /*!< clock loss on channel 2 interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF3 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 19U), /*!< clock loss on channel 3 interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF4 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 20U), /*!< clock loss on channel 4 interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF5 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 21U), /*!< clock loss on channel 5 interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF6 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 22U), /*!< clock loss on channel 6 interrupt flag */ + HPDF_INT_FLAG_FLT0_CKLF7 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 6U, FLTYSTAT_REG_OFFSET, 23U), /*!< clock loss on channel 7 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF0 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 24U), /*!< malfunction monitor detection on channel 0 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF1 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 25U), /*!< malfunction monitor detection on channel 1 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF2 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 26U), /*!< malfunction monitor detection on channel 2 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF3 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 27U), /*!< malfunction monitor detection on channel 3 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF4 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 28U), /*!< malfunction monitor detection on channel 4 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF5 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 29U), /*!< malfunction monitor detection on channel 5 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF6 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 30U), /*!< malfunction monitor detection on channel 6 interrupt flag */ + HPDF_INT_FLAG_FLT0_MMF7 = HPDF_REGIDX_BIT2(FLTYCTL1_REG_OFFSET, 5U, FLTYSTAT_REG_OFFSET, 31U) /*!< malfunction monitor detection on channel 7 interrupt flag */ +} hpdf_interrput_flag_enum; + +/* HPDF interrput */ +typedef enum { + /* interrput in FLTYCTL1 register */ + HPDF_INT_FLTY_ICEIE = HPDF_REGIDX_BIT(FLTYCTL1_REG_OFFSET, 0U), /*!< inserted conversion end interrupt enable */ + HPDF_INT_FLTY_RCEIE = HPDF_REGIDX_BIT(FLTYCTL1_REG_OFFSET, 1U), /*!< regular conversion end interrupt enable */ + HPDF_INT_FLTY_ICDOIE = HPDF_REGIDX_BIT(FLTYCTL1_REG_OFFSET, 2U), /*!< inserted conversion data overflow interrupt enable */ + HPDF_INT_FLTY_RCDOIE = HPDF_REGIDX_BIT(FLTYCTL1_REG_OFFSET, 3U), /*!< regular conversion data overflow interrupt enable */ + HPDF_INT_FLTY_TMIE = HPDF_REGIDX_BIT(FLTYCTL1_REG_OFFSET, 4U), /*!< threshold monitor interrupt enable */ + HPDF_INT_FLT0_MMIE = HPDF_REGIDX_BIT(FLTYCTL1_REG_OFFSET, 5U), /*!< malfunction monitor interrupt enable */ + HPDF_INT_FLT0_CKLIE = HPDF_REGIDX_BIT(FLTYCTL1_REG_OFFSET, 6U) /*!< clock loss interrupt enable */ +} hpdf_interrput_enum; + +/* HPDF channel definitions */ +/* serial clock output source definitions */ +#define SERIAL_SYSTEM_CLK ((uint32_t)0x00000000U) /*!< serial clock output source is from system clock */ +#define SERIAL_AUDIO_CLK HPDF_CH0CTL_CKOUTSEL /*!< serial clock output source is from audio clock */ + +/* serial clock output duty mode definitions */ +#define CKOUTDM_DISABLE ((uint32_t)0x00000000U) /*!< serial clock output duty mode disable */ +#define CKOUTDM_ENABLE HPDF_CH0CTL_CKOUTDM /*!< serial clock output duty mode enable */ + +/* data packing mode definitions */ +#define DPM(regval) (BITS(14,15) & ((uint32_t)(regval) << 14)) /*!< select data packing mode */ +#define DPM_STANDARD_MODE DPM(0) /*!< standard mode */ +#define DPM_INTERLEAVED_MODE DPM(1) /*!< interleaved mode */ +#define DPM_DUAL_MODE DPM(2) /*!< dual mode */ + +/* input data source for channel definitions */ +#define IDATASEL(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) /*!< select channel y multiplexer input data source */ +#define SERIAL_INPUT IDATASEL(0) /*!< input data source for channel is taken from serial inputs */ +#define ADC_INPUT IDATASEL(1) /*!< input data source for channel is taken from ADC output register */ +#define INTERNAL_INPUT IDATASEL(2) /*!< input data source for channel is taken from internal HPDF_CHXPDI register */ + +/* channel inputs pins definitions */ +#define CHPINSEL_CURRENT ((uint32_t)0x00000000U) /*!< channel inputs select pins of the current channel */ +#define CHPINSEL_NEXT HPDF_CHXCTL_CHPINSEL /*!< channel inputs select pins of the next channel */ + +/* clock loss detector definitions */ +#define CLK_LOSS_DISABLE ((uint32_t)0x00000000U) /*!< clock loss detector disable */ +#define CLK_LOSS_ENABLE HPDF_CHXCTL_CKLEN /*!< clock loss detector enable */ + +/* SPI clock source definitions */ +#define SPICKSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) /*!< select SPI clock source */ +#define EXTERNAL_CKIN SPICKSS(0) /*!< external CKINy input */ +#define INTERNAL_CKOUT SPICKSS(1) /*!< internal CKOUT output */ +#define HALF_CKOUT_FALLING_EDGE SPICKSS(2) /*!< internal CKOUT output, sampling point on each second CKOUT falling edge. */ +#define HALF_CKOUT_RISING_EDGE SPICKSS(3) /*!< internal CKOUT output, sampling point on each second CKOUT rising edge */ + +/* serial interface type definitions */ +#define SITYP(regval) (BITS(0,1) & ((uint32_t)(regval))) /*!< select serial interface type */ +#define SPI_RISING_EDGE SITYP(0) /*!< SPI interface, sample data on rising edge */ +#define SPI_FALLING_EDGE SITYP(1) /*!< SPI interface, sample data on rising edge */ +#define MANCHESTER_CODE0 SITYP(2) /*!< manchester coded input: rising edge = logic 0, falling edge = logic 1 */ +#define MANCHESTER_CODE1 SITYP(3) /*!< manchester coded input: rising edge = logic 1, falling edge = logic 0 */ + +/* malfunction monitor detector definitions */ +#define MM_DISABLE ((uint32_t)0x00000000U) /*!< malfunction monitor disable */ +#define MM_ENABLE HPDF_CHXCTL_MMEN /*!< malfunction monitor enable */ + +/* malfunction monitor detector break signal definitions */ +#define MMBSD(regval) (BITS(12,15) & ((uint32_t)(regval)<< 12)) /*!< select break signal on channel */ +#define NO_MM_BREAK MMBSD(0) /*!< break signal is not distributed to malfunction monitor on channel */ +#define MM_BREAK0 MMBSD(1) /*!< break signal 0 is distributed to malfunction monitor on channel */ +#define MM_BREAK1 MMBSD(2) /*!< break signal 1 is distributed to malfunction monitor on channel */ +#define MM_BREAK2 MMBSD(4) /*!< break signal 2 is distributed to malfunction monitor on channel */ +#define MM_BREAK3 MMBSD(8) /*!< break signal 3 is distributed to malfunction monitor on channel */ + +/* threshold monitor fast mode definitions */ +#define TMFM_DISABLE ((uint32_t)0x00000000U) /*!< threshold monitor fast mode disable */ +#define TMFM_ENABLE HPDF_FLTYCTL0_TMFM /*!< threshold monitor fast mode enable */ + +/* regular conversions configuration definitions */ +/* fast conversion mode definitions */ +#define FAST_DISABLE ((uint32_t)0x00000000U) /*!< fast conversion mode disable */ +#define FAST_ENABLE HPDF_FLTYCTL0_FAST /*!< fast conversion mode enable */ + +/* regular conversion channel selection definitions */ +#define RCS(regval) (BITS(24,26) & ((uint32_t)(regval)<< 24 )) /*!< select regular conversion channel */ +#define RCS_CHANNEL0 RCS(0) /*!< channel 0 is selected as the regular conversion channel */ +#define RCS_CHANNEL1 RCS(1) /*!< channel 1 is selected as the regular conversion channel */ +#define RCS_CHANNEL2 RCS(2) /*!< channel 2 is selected as the regular conversion channel */ +#define RCS_CHANNEL3 RCS(3) /*!< channel 3 is selected as the regular conversion channel */ +#define RCS_CHANNEL4 RCS(4) /*!< channel 4 is selected as the regular conversion channel */ +#define RCS_CHANNEL5 RCS(5) /*!< channel 5 is selected as the regular conversion channel */ +#define RCS_CHANNEL6 RCS(6) /*!< channel 6 is selected as the regular conversion channel */ +#define RCS_CHANNEL7 RCS(7) /*!< channel 7 is selected as the regular conversion channel */ + +/* DMA channel of regular conversion definitions */ +#define RCDMAEN_DISABLE ((uint32_t)0x00000000U) /*!< disable the DMA channel to read regular data */ +#define RCDMAEN_ENABLE HPDF_FLTYCTL0_RCDMAEN /*!< enable the DMA channel to read regular data */ + +/* regular conversion synchronously definitions */ +#define RCSYN_DISABLE ((uint32_t)0x00000000U) /*!< do not launch a regular conversion synchronously */ +#define RCSYN_ENABLE HPDF_FLTYCTL0_RCSYN /*!< launch a regular conversion synchronously */ + +/* regular conversions continuous mode definitions */ +#define RCCM_DISABLE ((uint32_t)0x00000000U) /*!< regular conversions continuous mode */ +#define RCCM_ENABLE HPDF_FLTYCTL0_RCCM /*!< regular conversions continuous mode */ + +/* inserted conversions trigger edge definitions */ +#define ICTEEN(regval) (BITS(13,14) & ((uint32_t)(regval)<< 13)) /*!< select inserted conversions trigger edge */ +#define TRG_DISABLE ICTEEN(0) /*!< disable trigger detection */ +#define RISING_EDGE_TRG ICTEEN(1) /*!< each rising edge on the trigger signal */ +#define FALLING_EDGE_TRG ICTEEN(2) /*!< each falling edge on the trigger signal */ +#define EDGE_TRG ICTEEN(3) /*!< the edge (rising edges and falling edges) on the trigger signal */ + +/* inserted conversions trigger signal definitions */ +#define ICTSSEL(regval) (BITS(8,12) & ((uint32_t)(regval)<< 8)) /*!< select inserted conversions trigger signal */ +#define HPDF_ITRG0 ICTSSEL(0) /*!< HPDF_ITRG0 (TIMER0_TRGO0) */ +#define HPDF_ITRG1 ICTSSEL(1) /*!< HPDF_ITRG1 (TIMER0_TRGO1) */ +#define HPDF_ITRG2 ICTSSEL(2) /*!< HPDF_ITRG2 (TIMER7_TRGO0) */ +#define HPDF_ITRG3 ICTSSEL(3) /*!< HPDF_ITRG3 (TIMER7_TRGO1) */ +#define HPDF_ITRG4 ICTSSEL(4) /*!< HPDF_ITRG4 (TIMER2_TRGO0) */ +#define HPDF_ITRG5 ICTSSEL(5) /*!< HPDF_ITRG5 (TIMER3_TRGO0) */ +#define HPDF_ITRG6 ICTSSEL(6) /*!< HPDF_ITRG6 (TIMER15_CH1) */ +#define HPDF_ITRG7 ICTSSEL(7) /*!< HPDF_ITRG7 (TIMER5_TRGO0) */ +#define HPDF_ITRG8 ICTSSEL(8) /*!< HPDF_ITRG8 (TIMER6_TRGO0) */ +#define HPDF_ITRG11 ICTSSEL(11) /*!< HPDF_ITRG11 (TIMER22_TRGO0) */ +#define HPDF_ITRG12 ICTSSEL(12) /*!< HPDF_ITRG12 (TIMER23_TRGO0) */ +#define HPDF_ITRG24 ICTSSEL(24) /*!< HPDF_ITRG24 (EXTI11) */ +#define HPDF_ITRG25 ICTSSEL(25) /*!< HPDF_ITRG25 (EXTI15) */ +#define HPDF_ITRG31 ICTSSEL(31) /*!< HPDF_ITRG31 (HPDF_ITRG) */ + +/* inserted channel DMA enable definitions */ +#define ICDMAEN_DISABLE ((uint32_t)0x00000000U) /*!< disable DMA channel to read inserted conversions data */ +#define ICDMAEN_ENABLE HPDF_FLTYCTL0_ICDMAEN /*!< enable DMA channel to read inserted conversions data */ + +/* scan conversion mode */ +#define SCMOD_DISABLE ((uint32_t)0x00000000U) /*!< scan conversion mode disable */ +#define SCMOD_ENABLE HPDF_FLTYCTL0_SCMOD /*!< scan conversion mode enable */ + +/* inserted conversion synchronously definitions */ +#define ICSYN_DISABLE ((uint32_t)0x00000000U) /*!< do not launch an inserted conversion synchronously */ +#define ICSYN_ENABLE HPDF_FLTYCTL0_ICSYN /*!< launch an inserted conversion synchronously */ + +/* inserted channel group definitions */ +#define ICGSEL(regval) (BITS(0,7) & ((uint32_t)(regval)<< 0)) /*!< inserted channel group selection */ +#define ICGSEL_CHANNEL0 ICGSEL(0x01) /*!< channel 0 belongs to the inserted group */ +#define ICGSEL_CHANNEL1 ICGSEL(0x02) /*!< channel 1 belongs to the inserted group */ +#define ICGSEL_CHANNEL2 ICGSEL(0x04) /*!< channel 2 belongs to the inserted group */ +#define ICGSEL_CHANNEL3 ICGSEL(0x08) /*!< channel 3 belongs to the inserted group */ +#define ICGSEL_CHANNEL4 ICGSEL(0x10) /*!< channel 4 belongs to the inserted group */ +#define ICGSEL_CHANNEL5 ICGSEL(0x20) /*!< channel 5 belongs to the inserted group */ +#define ICGSEL_CHANNEL6 ICGSEL(0x40) /*!< channel 6 belongs to the inserted group */ +#define ICGSEL_CHANNEL7 ICGSEL(0x80) /*!< channel 7 belongs to the inserted group */ + +/* Sinc fliter definitions */ +/* Sinc fliter order and type definitions */ +#define SFO(regval) (BITS(29,31) & ((uint32_t)(regval)<< 29)) /*!< select Sinc filter order */ +#define FLT_FASTSINC SFO(0) /*!< FastSinc filter type */ +#define FLT_SINC1 SFO(1) /*!< Sinc1 filter type */ +#define FLT_SINC2 SFO(2) /*!< Sinc2 filter type */ +#define FLT_SINC3 SFO(3) /*!< Sinc3 filter type */ +#define FLT_SINC4 SFO(4) /*!< Sinc4 filter type */ +#define FLT_SINC5 SFO(5) /*!< Sinc4 filter type */ + +/* Sinc fliter and bypass definitions */ +#define FLT_SINC_BYPASS ((uint32_t)0x00000001U) /*!< the filter will be bypass. */ +#define INTEGRATOR_BYPASS ((uint32_t)0x00000001U) /*!< the integrator will be bypass. */ + +/* threshold monitor definitions */ +/* threshold monitor Sinc filter order definitions */ +#define TMSFO(regval) (BITS(22,23) & ((uint32_t)(regval)<< 22)) /*!< select threshold monitor Sinc filter order */ +#define TM_FASTSINC TMSFO(0) /*!< FastSinc filter */ +#define TM_SINC1 TMSFO(1) /*!< Sinc1 filter */ +#define TM_SINC2 TMSFO(2) /*!< Sinc2 filter */ +#define TM_SINC3 TMSFO(3) /*!< Sinc3 filter */ + +/* threshold monitor channel definitions */ +#define TMCHEN(regval) (BITS(16,23) & ((uint32_t)(regval)<< 16)) /*!< select threshold monitor channel */ +#define TMCHEN_DISABLE TMCHEN(0) /*!< threshold monitor is disabled on channel 0 and channel 1 */ +#define TMCHEN_CHANNEL0 TMCHEN(0x01) /*!< threshold monitor is enabled on channel 0 */ +#define TMCHEN_CHANNEL1 TMCHEN(0x02) /*!< threshold monitor is enabled on channel 1 */ +#define TMCHEN_CHANNEL2 TMCHEN(0x04) /*!< threshold monitor is enabled on channel 2 */ +#define TMCHEN_CHANNEL3 TMCHEN(0x08) /*!< threshold monitor is enabled on channel 3 */ +#define TMCHEN_CHANNEL4 TMCHEN(0x10) /*!< threshold monitor is enabled on channel 4 */ +#define TMCHEN_CHANNEL5 TMCHEN(0x20) /*!< threshold monitor is enabled on channel 5 */ +#define TMCHEN_CHANNEL6 TMCHEN(0x40) /*!< threshold monitor is enabled on channel 6 */ +#define TMCHEN_CHANNEL7 TMCHEN(0x80) /*!< threshold monitor is enabled on channel 7 */ + +/* threshold monitor high threshold event break signal definitions */ +#define HTBSD(regval) (BITS(0,1) & ((uint32_t)(regval)<< 1)) /*!< select high threshold event break signal */ +#define NO_TM_HT_BREAK HTBSD(0) /*!< break signal is not distributed to an threshold monitor high threshold event */ +#define TM_HT_BREAK0 HTBSD(1) /*!< break signal 0 is distributed to an threshold monitor high threshold event */ +#define TM_HT_BREAK1 HTBSD(2) /*!< break signal 1 is distributed to an threshold monitor high threshold event */ +#define TM_HT_BREAK2 HTBSD(4) /*!< break signal 2 is distributed to an threshold monitor high threshold event */ +#define TM_HT_BREAK3 HTBSD(8) /*!< break signal 3 is distributed to an threshold monitor high threshold event */ + +/* threshold monitor low threshold event break signal definitions */ +#define LTBSD(regval) (BITS(0,1) & ((uint32_t)(regval)<< 1)) /*!< select low threshold event break signal */ +#define NO_TM_LT_BREAK LTBSD(0) /*!< break signal is not distributed to an threshold monitor low threshold event */ +#define TM_LT_BREAK0 LTBSD(1) /*!< break signal 0 is distributed to an threshold monitor low threshold event */ +#define TM_LT_BREAK1 LTBSD(2) /*!< break signal 1 is distributed to an threshold monitor low threshold event */ +#define TM_LT_BREAK2 LTBSD(4) /*!< break signal 2 is distributed to an threshold monitor low threshold event */ +#define TM_LT_BREAK3 LTBSD(8) /*!< break signal 3 is distributed to an threshold monitor low threshold event */ + +/* threshold monitor bypass definitions */ +#define TM_FLT_BYPASS ((uint32_t)0x00000001U) /*!< the threshold monitor filter is bypassed. */ + +/* extremes monitor definitions */ +/* extremes monitor channel definitions */ +#define EMCS(regval) (BITS(8,15) & ((uint32_t)(regval)<< 8)) /*!< select extremes monitor channel */ +#define EM_CHANNEL_DISABLE EMCS(0) /*!< extremes monitor y does not accept data from channel 0 and channel 1 */ +#define EM_CHANNEL0 EMCS(0x01) /*!< extremes monitor y accepts data from channel 0 */ +#define EM_CHANNEL1 EMCS(0x02) /*!< extremes monitor y accepts data from channel 1 */ +#define EM_CHANNEL2 EMCS(0x04) /*!< extremes monitor y accepts data from channel 2 */ +#define EM_CHANNEL3 EMCS(0x08) /*!< extremes monitor y accepts data from channel 3 */ +#define EM_CHANNEL4 EMCS(0x10) /*!< extremes monitor y accepts data from channel 4 */ +#define EM_CHANNEL5 EMCS(0x20) /*!< extremes monitor y accepts data from channel 5 */ +#define EM_CHANNEL6 EMCS(0x40) /*!< extremes monitor y accepts data from channel 6 */ +#define EM_CHANNEL7 EMCS(0x80) /*!< extremes monitor y accepts data from channel 7 */ + +/* function declarations */ +/* initialize HPDF channel and filter registers */ +/* reset HPDF */ +void hpdf_deinit(void); +/* initialize the parameters of HPDF channel struct with the default values */ +void hpdf_channel_struct_para_init(hpdf_channel_parameter_struct *init_struct); +/* initialize the parameters of HPDF filter struct with the default values */ +void hpdf_filter_struct_para_init(hpdf_filter_parameter_struct *init_struct); +/* initialize the parameters of regular conversion struct with the default values */ +void hpdf_rc_struct_para_init(hpdf_rc_parameter_struct *init_struct); +/* initialize the parameters of inserted conversion struct with the default values */ +void hpdf_ic_struct_para_init(hpdf_ic_parameter_struct *init_struct); +/* enable the HPDF module globally */ +void hpdf_enable(void); +/* disable the HPDF module globally */ +void hpdf_disable(void); +/* initialize the HPDF channel */ +void hpdf_channel_init(hpdf_channel_enum channelx, hpdf_channel_parameter_struct *init_struct); +/* initialize the HPDF filter */ +void hpdf_filter_init(hpdf_filter_enum filtery, hpdf_filter_parameter_struct *init_struct); +/* initialize the regular conversion */ +void hpdf_rc_init(hpdf_filter_enum filtery, hpdf_rc_parameter_struct *init_struct); +/* initialize the inserted conversion */ +void hpdf_ic_init(hpdf_filter_enum filtery, hpdf_ic_parameter_struct *init_struct); + +/* configure the HPDF clock output */ +/* configure serial output clock */ +void hpdf_clock_output_config(uint32_t source, uint8_t divider, uint32_t mode); +/* configure serial clock output source */ +void hpdf_clock_output_source_config(uint32_t source); +/* disable serial clock output duty mode */ +void hpdf_clock_output_duty_mode_disable(void); +/* enable serial clock output duty mode */ +void hpdf_clock_output_duty_mode_enable(void); +/* configure serial clock output divider */ +void hpdf_clock_output_divider_config(uint8_t divider); + +/* configure HPDF channel */ +/* enable channel */ +void hpdf_channel_enable(hpdf_channel_enum channelx); +/* disable channel */ +void hpdf_channel_disable(hpdf_channel_enum channelx); +/* configure SPI clock source */ +void hpdf_spi_clock_source_config(hpdf_channel_enum channelx, uint32_t clock_source); +/* configure serial interface type */ +void hpdf_serial_interface_type_config(hpdf_channel_enum channelx, uint32_t type); +/* disable malfunction monitor */ +void hpdf_malfunction_monitor_disable(hpdf_channel_enum channelx); +/* enable malfunction monitor */ +void hpdf_malfunction_monitor_enable(hpdf_channel_enum channelx); +/* disable clock loss detector */ +void hpdf_clock_loss_disable(hpdf_channel_enum channelx); +/* enable clock loss detector */ +void hpdf_clock_loss_enable(hpdf_channel_enum channelx); +/* disable channel inputs pins redirection */ +void hpdf_channel_pin_redirection_disable(hpdf_channel_enum channelx); +/* enable channel inputs pins redirection */ +void hpdf_channel_pin_redirection_enable(hpdf_channel_enum channelx); +/* configure channel multiplexer select input data source */ +void hpdf_channel_multiplexer_config(hpdf_channel_enum channelx, uint32_t data_source); +/* configure data packing mode */ +void hpdf_data_pack_mode_config(hpdf_channel_enum channelx, uint32_t mode); +/* configure data right bit-shift */ +void hpdf_data_right_bit_shift_config(hpdf_channel_enum channelx, uint8_t right_shift); +/* configure calibration offset */ +void hpdf_calibration_offset_config(hpdf_channel_enum channelx, int32_t offset); +/* configure malfunction monitor break signal */ +void hpdf_malfunction_break_signal_config(hpdf_channel_enum channelx, uint32_t break_signal); +/* configure malfunction monitor counter threshold */ +void hpdf_malfunction_counter_config(hpdf_channel_enum channelx, uint8_t threshold); +/* write the parallel data on standard mode of data packing */ +void hpdf_write_parallel_data_standard_mode(hpdf_channel_enum channelx, int16_t data); +/* write the parallel data on interleaved mode of data packing */ +void hpdf_write_parallel_data_interleaved_mode(hpdf_channel_enum channelx, int32_t data); +/* write the parallel data on dual mode of data packing */ +void hpdf_write_parallel_data_dual_mode(hpdf_channel_enum channelx, int32_t data); +/* update the number of pulses to skip */ +void hpdf_pulse_skip_update(hpdf_channel_enum channelx, uint8_t number); +/* read the number of pulses to skip */ +uint8_t hpdf_pulse_skip_read(hpdf_channel_enum channelx); + +/* HPDF filter configuration */ +/* enable filter */ +void hpdf_filter_enable(hpdf_filter_enum filtery); +/* disable filter */ +void hpdf_filter_disable(hpdf_filter_enum filtery); +/* configure sinc filter order and oversample */ +void hpdf_filter_config(hpdf_filter_enum filtery, uint32_t order, uint16_t oversample); +/* configure integrator oversampling rate */ +void hpdf_integrator_oversample(hpdf_filter_enum filtery, uint16_t oversample); + +/* HPDF threshold monitor configuration */ +/* configure threshold monitor filter order and oversample */ +void hpdf_threshold_monitor_filter_config(hpdf_channel_enum channelx, uint32_t order, uint8_t oversample); +/* read the threshold monitor filter data */ +int16_t hpdf_threshold_monitor_filter_read_data(hpdf_channel_enum channelx); +/* disable threshold monitor fast mode */ +void hpdf_threshold_monitor_fast_mode_disable(hpdf_filter_enum filtery); +/* enable threshold monitor fast mode */ +void hpdf_threshold_monitor_fast_mode_enable(hpdf_filter_enum filtery); +/* configure threshold monitor channel */ +void hpdf_threshold_monitor_channel(hpdf_filter_enum filtery, uint32_t channel); +/* configure threshold monitor high threshold value */ +void hpdf_threshold_monitor_high_threshold(hpdf_filter_enum filtery, int32_t value); +/* configure threshold monitor low threshold value */ +void hpdf_threshold_monitor_low_threshold(hpdf_filter_enum filtery, int32_t value); +/* configure threshold monitor high threshold event break signal */ +void hpdf_high_threshold_break_signal(hpdf_filter_enum filtery, uint32_t break_signal); +/* configure threshold monitor low threshold event break signal */ +void hpdf_low_threshold_break_signal(hpdf_filter_enum filtery, uint32_t break_signal); + +/* configure HPDF extremes monitor */ +/* configure extremes monitor channel */ +void hpdf_extremes_monitor_channel(hpdf_filter_enum filtery, uint32_t channel); +/* get the extremes monitor maximum value */ +int32_t hpdf_extremes_monitor_maximum_get(hpdf_filter_enum filtery); +/* get the extremes monitor minimum value */ +int32_t hpdf_extremes_monitor_minimum_get(hpdf_filter_enum filtery); + +/* get the conversion timer value */ +uint32_t hpdf_conversion_time_get(hpdf_filter_enum filtery); + +/* configure HPDF regular conversions */ +/* disable regular conversions continuous mode */ +void hpdf_rc_continuous_disable(hpdf_filter_enum filtery); +/* enable regular conversions continuous mode */ +void hpdf_rc_continuous_enable(hpdf_filter_enum filtery); +/* start regular channel conversion by software */ +void hpdf_rc_start_by_software(hpdf_filter_enum filtery); +/* disable regular conversion synchronously */ +void hpdf_rc_syn_disable(hpdf_filter_enum filtery); +/* enable regular conversion synchronously */ +void hpdf_rc_syn_enable(hpdf_filter_enum filtery); +/* disable regular conversion DMA channel */ +void hpdf_rc_dma_disable(hpdf_filter_enum filtery); +/* enable regular conversion DMA channel */ +void hpdf_rc_dma_enable(hpdf_filter_enum filtery); +/* configure regular conversion channel */ +void hpdf_rc_channel_config(hpdf_filter_enum filtery, uint32_t channel); +/* disable regular conversion fast conversion mode */ +void hpdf_rc_fast_mode_disable(hpdf_filter_enum filtery); +/* enable regular conversion fast conversion mode */ +void hpdf_rc_fast_mode_enable(hpdf_filter_enum filtery); +/* get the regular conversion data */ +int32_t hpdf_rc_data_get(hpdf_filter_enum filtery); +/* get the channel of regular channel most recently converted */ +uint8_t hpdf_rc_channel_get(hpdf_filter_enum filtery); + +/* configure HPDF inserted conversions */ +/* start inserted channel conversion by software */ +void hpdf_ic_start_by_software(hpdf_filter_enum filtery); +/* disable inserted conversion synchronously */ +void hpdf_ic_syn_disable(hpdf_filter_enum filtery); +/* enable inserted conversion synchronously */ +void hpdf_ic_syn_enable(hpdf_filter_enum filtery); +/* disable inserted conversion DMA channel */ +void hpdf_ic_dma_disable(hpdf_filter_enum filtery); +/* enable inserted conversion DMA channel */ +void hpdf_ic_dma_enable(hpdf_filter_enum filtery); +/* disable scan conversion mode */ +void hpdf_ic_scan_mode_disable(hpdf_filter_enum filtery); +/* enable scan conversion mode */ +void hpdf_ic_scan_mode_enable(hpdf_filter_enum filtery); +/* disable inserted conversions trigger siganl */ +void hpdf_ic_trigger_signal_disable(hpdf_filter_enum filtery); +/* configure inserted conversions trigger siganl and trigger edge */ +void hpdf_ic_trigger_signal_config(hpdf_filter_enum filtery, uint32_t trigger, uint32_t trigger_edge); +/* configure inserted group conversions channel */ +void hpdf_ic_channel_config(hpdf_filter_enum filtery, uint32_t channel); +/* get the inserted conversions data */ +int32_t hpdf_ic_data_get(hpdf_filter_enum filtery); +/* get the channel of inserted group channel most recently converted */ +uint8_t hpdf_ic_channel_get(hpdf_filter_enum filtery); + +/* flag and interrupt functions */ +/* get the HPDF flags */ +FlagStatus hpdf_flag_get(hpdf_filter_enum filtery, hpdf_flag_enum flag); +/* clear the HPDF flags */ +void hpdf_flag_clear(hpdf_filter_enum filtery, hpdf_flag_enum flag); +/* enable HPDF interrupt */ +void hpdf_interrupt_enable(hpdf_filter_enum filtery, hpdf_interrput_enum interrupt); +/* disable HPDF interrupt */ +void hpdf_interrupt_disable(hpdf_filter_enum filtery, hpdf_interrput_enum interrupt); +/* get the HPDF interrupt flags */ +FlagStatus hpdf_interrupt_flag_get(hpdf_filter_enum filtery, hpdf_interrput_flag_enum int_flag); +/* clear the HPDF interrupt flags */ +void hpdf_interrupt_flag_clear(hpdf_filter_enum filtery, hpdf_interrput_flag_enum int_flag); + +#endif /* GD32H7XX_HPDF_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hwsem.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hwsem.h new file mode 100644 index 0000000000..c6fd52c2d5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_hwsem.h @@ -0,0 +1,365 @@ +/*! + \file gd32h7xx_hwsem.h + \brief definitions for the HWSEM + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_HWSEM_H +#define GD32H7XX_HWSEM_H + +#include "gd32h7xx.h" + +/* HWSEM definitions */ +#define HWSEM HWSEM_BASE /*!< HWSEM base address */ + +/* registers definitions */ +#define HWSEM_CTL0 REG32(HWSEM + 0x00000000U) /*!< HWSEM control register 0 */ +#define HWSEM_CTL1 REG32(HWSEM + 0x00000004U) /*!< HWSEM control register 1 */ +#define HWSEM_CTL2 REG32(HWSEM + 0x00000008U) /*!< HWSEM control register 2 */ +#define HWSEM_CTL3 REG32(HWSEM + 0x0000000CU) /*!< HWSEM control register 3 */ +#define HWSEM_CTL4 REG32(HWSEM + 0x00000010U) /*!< HWSEM control register 4 */ +#define HWSEM_CTL5 REG32(HWSEM + 0x00000014U) /*!< HWSEM control register 5 */ +#define HWSEM_CTL6 REG32(HWSEM + 0x00000018U) /*!< HWSEM control register 6 */ +#define HWSEM_CTL7 REG32(HWSEM + 0x0000001CU) /*!< HWSEM control register 7 */ +#define HWSEM_CTL8 REG32(HWSEM + 0x00000020U) /*!< HWSEM control register 8 */ +#define HWSEM_CTL9 REG32(HWSEM + 0x00000024U) /*!< HWSEM control register 9 */ +#define HWSEM_CTL10 REG32(HWSEM + 0x00000028U) /*!< HWSEM control register 10 */ +#define HWSEM_CTL11 REG32(HWSEM + 0x0000002CU) /*!< HWSEM control register 11 */ +#define HWSEM_CTL12 REG32(HWSEM + 0x00000030U) /*!< HWSEM control register 12 */ +#define HWSEM_CTL13 REG32(HWSEM + 0x00000034U) /*!< HWSEM control register 13 */ +#define HWSEM_CTL14 REG32(HWSEM + 0x00000038U) /*!< HWSEM control register 14 */ +#define HWSEM_CTL15 REG32(HWSEM + 0x0000003CU) /*!< HWSEM control register 15 */ +#define HWSEM_CTL16 REG32(HWSEM + 0x00000040U) /*!< HWSEM control register 16 */ +#define HWSEM_CTL17 REG32(HWSEM + 0x00000044U) /*!< HWSEM control register 17 */ +#define HWSEM_CTL18 REG32(HWSEM + 0x00000048U) /*!< HWSEM control register 18 */ +#define HWSEM_CTL19 REG32(HWSEM + 0x0000004CU) /*!< HWSEM control register 19 */ +#define HWSEM_CTL20 REG32(HWSEM + 0x00000050U) /*!< HWSEM control register 20 */ +#define HWSEM_CTL21 REG32(HWSEM + 0x00000054U) /*!< HWSEM control register 21 */ +#define HWSEM_CTL22 REG32(HWSEM + 0x00000058U) /*!< HWSEM control register 22 */ +#define HWSEM_CTL23 REG32(HWSEM + 0x0000005CU) /*!< HWSEM control register 23 */ +#define HWSEM_CTL24 REG32(HWSEM + 0x00000060U) /*!< HWSEM control register 24 */ +#define HWSEM_CTL25 REG32(HWSEM + 0x00000064U) /*!< HWSEM control register 25 */ +#define HWSEM_CTL26 REG32(HWSEM + 0x00000068U) /*!< HWSEM control register 26 */ +#define HWSEM_CTL27 REG32(HWSEM + 0x0000006CU) /*!< HWSEM control register 27 */ +#define HWSEM_CTL28 REG32(HWSEM + 0x00000070U) /*!< HWSEM control register 28 */ +#define HWSEM_CTL29 REG32(HWSEM + 0x00000074U) /*!< HWSEM control register 29 */ +#define HWSEM_CTL30 REG32(HWSEM + 0x00000078U) /*!< HWSEM control register 30 */ +#define HWSEM_CTL31 REG32(HWSEM + 0x0000007CU) /*!< HWSEM control register 31 */ +#define HWSEM_RLK0 REG32(HWSEM + 0x00000080U) /*!< HWSEM read lock register 0 */ +#define HWSEM_RLK1 REG32(HWSEM + 0x00000084U) /*!< HWSEM read lock register 1 */ +#define HWSEM_RLK2 REG32(HWSEM + 0x00000088U) /*!< HWSEM read lock register 2 */ +#define HWSEM_RLK3 REG32(HWSEM + 0x0000008CU) /*!< HWSEM read lock register 3 */ +#define HWSEM_RLK4 REG32(HWSEM + 0x00000090U) /*!< HWSEM read lock register 4 */ +#define HWSEM_RLK5 REG32(HWSEM + 0x00000094U) /*!< HWSEM read lock register 5 */ +#define HWSEM_RLK6 REG32(HWSEM + 0x00000098U) /*!< HWSEM read lock register 6 */ +#define HWSEM_RLK7 REG32(HWSEM + 0x0000009CU) /*!< HWSEM read lock register 7 */ +#define HWSEM_RLK8 REG32(HWSEM + 0x000000A0U) /*!< HWSEM read lock register 8 */ +#define HWSEM_RLK9 REG32(HWSEM + 0x000000A4U) /*!< HWSEM read lock register 9 */ +#define HWSEM_RLK10 REG32(HWSEM + 0x000000A8U) /*!< HWSEM read lock register 10 */ +#define HWSEM_RLK11 REG32(HWSEM + 0x000000ACU) /*!< HWSEM read lock register 11 */ +#define HWSEM_RLK12 REG32(HWSEM + 0x000000B0U) /*!< HWSEM read lock register 12 */ +#define HWSEM_RLK13 REG32(HWSEM + 0x000000B4U) /*!< HWSEM read lock register 13 */ +#define HWSEM_RLK14 REG32(HWSEM + 0x000000B8U) /*!< HWSEM read lock register 14 */ +#define HWSEM_RLK15 REG32(HWSEM + 0x000000BCU) /*!< HWSEM read lock register 15 */ +#define HWSEM_RLK16 REG32(HWSEM + 0x000000C0U) /*!< HWSEM read lock register 16 */ +#define HWSEM_RLK17 REG32(HWSEM + 0x000000C4U) /*!< HWSEM read lock register 17 */ +#define HWSEM_RLK18 REG32(HWSEM + 0x000000C8U) /*!< HWSEM read lock register 18 */ +#define HWSEM_RLK19 REG32(HWSEM + 0x000000CCU) /*!< HWSEM read lock register 19 */ +#define HWSEM_RLK20 REG32(HWSEM + 0x000000D0U) /*!< HWSEM read lock register 20 */ +#define HWSEM_RLK21 REG32(HWSEM + 0x000000D4U) /*!< HWSEM read lock register 21 */ +#define HWSEM_RLK22 REG32(HWSEM + 0x000000D8U) /*!< HWSEM read lock register 22 */ +#define HWSEM_RLK23 REG32(HWSEM + 0x000000DCU) /*!< HWSEM read lock register 23 */ +#define HWSEM_RLK24 REG32(HWSEM + 0x000000E0U) /*!< HWSEM read lock register 24 */ +#define HWSEM_RLK25 REG32(HWSEM + 0x000000E4U) /*!< HWSEM read lock register 25 */ +#define HWSEM_RLK26 REG32(HWSEM + 0x000000E8U) /*!< HWSEM read lock register 26 */ +#define HWSEM_RLK27 REG32(HWSEM + 0x000000ECU) /*!< HWSEM read lock register 27 */ +#define HWSEM_RLK28 REG32(HWSEM + 0x000000F0U) /*!< HWSEM read lock register 28 */ +#define HWSEM_RLK29 REG32(HWSEM + 0x000000F4U) /*!< HWSEM read lock register 29 */ +#define HWSEM_RLK30 REG32(HWSEM + 0x000000F8U) /*!< HWSEM read lock register 30 */ +#define HWSEM_RLK31 REG32(HWSEM + 0x000000FCU) /*!< HWSEM read lock register 31 */ +#define HWSEM_INTEN REG32(HWSEM + 0x00000100U) /*!< HWSEM interrupt enable register */ +#define HWSEM_INTC REG32(HWSEM + 0x00000104U) /*!< HWSEM interrupt flag clear register */ +#define HWSEM_STAT REG32(HWSEM + 0x00000108U) /*!< HWSEM status register */ +#define HWSEM_INTF REG32(HWSEM + 0x0000010CU) /*!< HWSEM interrupt flag register */ +#define HWSEM_UNLK REG32(HWSEM + 0x00000140U) /*!< HWSEM unlock register */ +#define HWSEM_KEY REG32(HWSEM + 0x00000144U) /*!< HWSEM key register */ + +/* bits definitions */ +/* HWSEM_CTLx, x=0..31 */ +#define HWSEM_CTL_PID BITS(0,7) /*!< HWSEM process ID */ +#define HWSEM_CTL_MID BITS(8,11) /*!< HWSEM master ID */ +#define HWSEM_CTL_LK BIT(31) /*!< HWSEM lock */ + +/* HWSEM_RLKx, x=0..31 */ +#define HWSEM_RLK_PID BITS(0,7) /*!< HWSEM read lock register process ID */ +#define HWSEM_RLK_MID BITS(8,11) /*!< HWSEM read lock register master ID */ +#define HWSEM_RLK_LK BIT(31) /*!< HWSEM read lock register lock */ + +/* HWSEM_INTEN */ +#define HWSEM_INTEN_SIE0 BIT(0) /*!< enable HWSEM interrupt for semaphore 0 */ +#define HWSEM_INTEN_SIE1 BIT(1) /*!< enable HWSEM interrupt for semaphore 1 */ +#define HWSEM_INTEN_SIE2 BIT(2) /*!< enable HWSEM interrupt for semaphore 2 */ +#define HWSEM_INTEN_SIE3 BIT(3) /*!< enable HWSEM interrupt for semaphore 3 */ +#define HWSEM_INTEN_SIE4 BIT(4) /*!< enable HWSEM interrupt for semaphore 4 */ +#define HWSEM_INTEN_SIE5 BIT(5) /*!< enable HWSEM interrupt for semaphore 5 */ +#define HWSEM_INTEN_SIE6 BIT(6) /*!< enable HWSEM interrupt for semaphore 6 */ +#define HWSEM_INTEN_SIE7 BIT(7) /*!< enable HWSEM interrupt for semaphore 7 */ +#define HWSEM_INTEN_SIE8 BIT(8) /*!< enable HWSEM interrupt for semaphore 8 */ +#define HWSEM_INTEN_SIE9 BIT(9) /*!< enable HWSEM interrupt for semaphore 9 */ +#define HWSEM_INTEN_SIE10 BIT(10) /*!< enable HWSEM interrupt for semaphore 10 */ +#define HWSEM_INTEN_SIE11 BIT(11) /*!< enable HWSEM interrupt for semaphore 11 */ +#define HWSEM_INTEN_SIE12 BIT(12) /*!< enable HWSEM interrupt for semaphore 12 */ +#define HWSEM_INTEN_SIE13 BIT(13) /*!< enable HWSEM interrupt for semaphore 13 */ +#define HWSEM_INTEN_SIE14 BIT(14) /*!< enable HWSEM interrupt for semaphore 14 */ +#define HWSEM_INTEN_SIE15 BIT(15) /*!< enable HWSEM interrupt for semaphore 15 */ +#define HWSEM_INTEN_SIE16 BIT(16) /*!< enable HWSEM interrupt for semaphore 16 */ +#define HWSEM_INTEN_SIE17 BIT(17) /*!< enable HWSEM interrupt for semaphore 17 */ +#define HWSEM_INTEN_SIE18 BIT(18) /*!< enable HWSEM interrupt for semaphore 18 */ +#define HWSEM_INTEN_SIE19 BIT(19) /*!< enable HWSEM interrupt for semaphore 19 */ +#define HWSEM_INTEN_SIE20 BIT(20) /*!< enable HWSEM interrupt for semaphore 20 */ +#define HWSEM_INTEN_SIE21 BIT(21) /*!< enable HWSEM interrupt for semaphore 21 */ +#define HWSEM_INTEN_SIE22 BIT(22) /*!< enable HWSEM interrupt for semaphore 22 */ +#define HWSEM_INTEN_SIE23 BIT(23) /*!< enable HWSEM interrupt for semaphore 23 */ +#define HWSEM_INTEN_SIE24 BIT(24) /*!< enable HWSEM interrupt for semaphore 24 */ +#define HWSEM_INTEN_SIE25 BIT(25) /*!< enable HWSEM interrupt for semaphore 25 */ +#define HWSEM_INTEN_SIE26 BIT(26) /*!< enable HWSEM interrupt for semaphore 26 */ +#define HWSEM_INTEN_SIE27 BIT(27) /*!< enable HWSEM interrupt for semaphore 27 */ +#define HWSEM_INTEN_SIE28 BIT(28) /*!< enable HWSEM interrupt for semaphore 28 */ +#define HWSEM_INTEN_SIE29 BIT(29) /*!< enable HWSEM interrupt for semaphore 29 */ +#define HWSEM_INTEN_SIE30 BIT(30) /*!< enable HWSEM interrupt for semaphore 30 */ +#define HWSEM_INTEN_SIE31 BIT(31) /*!< enable HWSEM interrupt for semaphore 31 */ + +/* HWSEM_INTC */ +#define HWSEM_INTC_SIFC0 BIT(0) /*!< clear semaphore 0 flag and interrupt flag */ +#define HWSEM_INTC_SIFC1 BIT(1) /*!< clear semaphore 1 flag and interrupt flag */ +#define HWSEM_INTC_SIFC2 BIT(2) /*!< clear semaphore 2 flag and interrupt flag */ +#define HWSEM_INTC_SIFC3 BIT(3) /*!< clear semaphore 3 flag and interrupt flag */ +#define HWSEM_INTC_SIFC4 BIT(4) /*!< clear semaphore 4 flag and interrupt flag */ +#define HWSEM_INTC_SIFC5 BIT(5) /*!< clear semaphore 5 flag and interrupt flag */ +#define HWSEM_INTC_SIFC6 BIT(6) /*!< clear semaphore 6 flag and interrupt flag */ +#define HWSEM_INTC_SIFC7 BIT(7) /*!< clear semaphore 7 flag and interrupt flag */ +#define HWSEM_INTC_SIFC8 BIT(8) /*!< clear semaphore 8 flag and interrupt flag */ +#define HWSEM_INTC_SIFC9 BIT(9) /*!< clear semaphore 9 flag and interrupt flag */ +#define HWSEM_INTC_SIFC10 BIT(10) /*!< clear semaphore 10 flag and interrupt flag */ +#define HWSEM_INTC_SIFC11 BIT(11) /*!< clear semaphore 11 flag and interrupt flag */ +#define HWSEM_INTC_SIFC12 BIT(12) /*!< clear semaphore 12 flag and interrupt flag */ +#define HWSEM_INTC_SIFC13 BIT(13) /*!< clear semaphore 13 flag and interrupt flag */ +#define HWSEM_INTC_SIFC14 BIT(14) /*!< clear semaphore 14 flag and interrupt flag */ +#define HWSEM_INTC_SIFC15 BIT(15) /*!< clear semaphore 15 flag and interrupt flag */ +#define HWSEM_INTC_SIFC16 BIT(16) /*!< clear semaphore 16 flag and interrupt flag */ +#define HWSEM_INTC_SIFC17 BIT(17) /*!< clear semaphore 17 flag and interrupt flag */ +#define HWSEM_INTC_SIFC18 BIT(18) /*!< clear semaphore 18 flag and interrupt flag */ +#define HWSEM_INTC_SIFC19 BIT(19) /*!< clear semaphore 19 flag and interrupt flag */ +#define HWSEM_INTC_SIFC20 BIT(20) /*!< clear semaphore 20 flag and interrupt flag */ +#define HWSEM_INTC_SIFC21 BIT(21) /*!< clear semaphore 21 flag and interrupt flag */ +#define HWSEM_INTC_SIFC22 BIT(22) /*!< clear semaphore 22 flag and interrupt flag */ +#define HWSEM_INTC_SIFC23 BIT(23) /*!< clear semaphore 23 flag and interrupt flag */ +#define HWSEM_INTC_SIFC24 BIT(24) /*!< clear semaphore 24 flag and interrupt flag */ +#define HWSEM_INTC_SIFC25 BIT(25) /*!< clear semaphore 25 flag and interrupt flag */ +#define HWSEM_INTC_SIFC26 BIT(26) /*!< clear semaphore 26 flag and interrupt flag */ +#define HWSEM_INTC_SIFC27 BIT(27) /*!< clear semaphore 27 flag and interrupt flag */ +#define HWSEM_INTC_SIFC28 BIT(28) /*!< clear semaphore 28 flag and interrupt flag */ +#define HWSEM_INTC_SIFC29 BIT(29) /*!< clear semaphore 29 flag and interrupt flag */ +#define HWSEM_INTC_SIFC30 BIT(30) /*!< clear semaphore 30 flag and interrupt flag */ +#define HWSEM_INTC_SIFC31 BIT(31) /*!< clear semaphore 31 flag and interrupt flag */ + +/* HWSEM_STAT */ +#define HWSEM_STAT_SF0 BIT(0) /*!< semaphore 0 unlock event occurs */ +#define HWSEM_STAT_SF1 BIT(1) /*!< semaphore 1 unlock event occurs */ +#define HWSEM_STAT_SF2 BIT(2) /*!< semaphore 2 unlock event occurs */ +#define HWSEM_STAT_SF3 BIT(3) /*!< semaphore 3 unlock event occurs */ +#define HWSEM_STAT_SF4 BIT(4) /*!< semaphore 4 unlock event occurs */ +#define HWSEM_STAT_SF5 BIT(5) /*!< semaphore 5 unlock event occurs */ +#define HWSEM_STAT_SF6 BIT(6) /*!< semaphore 6 unlock event occurs */ +#define HWSEM_STAT_SF7 BIT(7) /*!< semaphore 7 unlock event occurs */ +#define HWSEM_STAT_SF8 BIT(8) /*!< semaphore 8 unlock event occurs */ +#define HWSEM_STAT_SF9 BIT(9) /*!< semaphore 9 unlock event occurs */ +#define HWSEM_STAT_SF10 BIT(10) /*!< semaphore 10 unlock event occurs */ +#define HWSEM_STAT_SF11 BIT(11) /*!< semaphore 11 unlock event occurs */ +#define HWSEM_STAT_SF12 BIT(12) /*!< semaphore 12 unlock event occurs */ +#define HWSEM_STAT_SF13 BIT(13) /*!< semaphore 13 unlock event occurs */ +#define HWSEM_STAT_SF14 BIT(14) /*!< semaphore 14 unlock event occurs */ +#define HWSEM_STAT_SF15 BIT(15) /*!< semaphore 15 unlock event occurs */ +#define HWSEM_STAT_SF16 BIT(16) /*!< semaphore 16 unlock event occurs */ +#define HWSEM_STAT_SF17 BIT(17) /*!< semaphore 17 unlock event occurs */ +#define HWSEM_STAT_SF18 BIT(18) /*!< semaphore 18 unlock event occurs */ +#define HWSEM_STAT_SF19 BIT(19) /*!< semaphore 19 unlock event occurs */ +#define HWSEM_STAT_SF20 BIT(20) /*!< semaphore 20 unlock event occurs */ +#define HWSEM_STAT_SF21 BIT(21) /*!< semaphore 21 unlock event occurs */ +#define HWSEM_STAT_SF22 BIT(22) /*!< semaphore 22 unlock event occurs */ +#define HWSEM_STAT_SF23 BIT(23) /*!< semaphore 23 unlock event occurs */ +#define HWSEM_STAT_SF24 BIT(24) /*!< semaphore 24 unlock event occurs */ +#define HWSEM_STAT_SF25 BIT(25) /*!< semaphore 25 unlock event occurs */ +#define HWSEM_STAT_SF26 BIT(26) /*!< semaphore 26 unlock event occurs */ +#define HWSEM_STAT_SF27 BIT(27) /*!< semaphore 27 unlock event occurs */ +#define HWSEM_STAT_SF28 BIT(28) /*!< semaphore 28 unlock event occurs */ +#define HWSEM_STAT_SF29 BIT(29) /*!< semaphore 29 unlock event occurs */ +#define HWSEM_STAT_SF30 BIT(30) /*!< semaphore 30 unlock event occurs */ +#define HWSEM_STAT_SF31 BIT(31) /*!< semaphore 31 unlock event occurs */ + +/* HWSEM_INTF */ +#define HWSEM_INTF_SIF0 BIT(0) /*!< semaphore 00 interrupt is pending */ +#define HWSEM_INTF_SIF1 BIT(1) /*!< semaphore 01 interrupt is pending */ +#define HWSEM_INTF_SIF2 BIT(2) /*!< semaphore 02 interrupt is pending */ +#define HWSEM_INTF_SIF3 BIT(3) /*!< semaphore 03 interrupt is pending */ +#define HWSEM_INTF_SIF4 BIT(4) /*!< semaphore 04 interrupt is pending */ +#define HWSEM_INTF_SIF5 BIT(5) /*!< semaphore 05 interrupt is pending */ +#define HWSEM_INTF_SIF6 BIT(6) /*!< semaphore 06 interrupt is pending */ +#define HWSEM_INTF_SIF7 BIT(7) /*!< semaphore 07 interrupt is pending */ +#define HWSEM_INTF_SIF8 BIT(8) /*!< semaphore 08 interrupt is pending */ +#define HWSEM_INTF_SIF9 BIT(9) /*!< semaphore 09 interrupt is pending */ +#define HWSEM_INTF_SIF10 BIT(10) /*!< semaphore 10 interrupt is pending */ +#define HWSEM_INTF_SIF11 BIT(11) /*!< semaphore 11 interrupt is pending */ +#define HWSEM_INTF_SIF12 BIT(12) /*!< semaphore 12 interrupt is pending */ +#define HWSEM_INTF_SIF13 BIT(13) /*!< semaphore 13 interrupt is pending */ +#define HWSEM_INTF_SIF14 BIT(14) /*!< semaphore 14 interrupt is pending */ +#define HWSEM_INTF_SIF15 BIT(15) /*!< semaphore 15 interrupt is pending */ +#define HWSEM_INTF_SIF16 BIT(16) /*!< semaphore 16 interrupt is pending */ +#define HWSEM_INTF_SIF17 BIT(17) /*!< semaphore 17 interrupt is pending */ +#define HWSEM_INTF_SIF18 BIT(18) /*!< semaphore 18 interrupt is pending */ +#define HWSEM_INTF_SIF19 BIT(19) /*!< semaphore 19 interrupt is pending */ +#define HWSEM_INTF_SIF20 BIT(20) /*!< semaphore 20 interrupt is pending */ +#define HWSEM_INTF_SIF21 BIT(21) /*!< semaphore 21 interrupt is pending */ +#define HWSEM_INTF_SIF22 BIT(22) /*!< semaphore 22 interrupt is pending */ +#define HWSEM_INTF_SIF23 BIT(23) /*!< semaphore 23 interrupt is pending */ +#define HWSEM_INTF_SIF24 BIT(24) /*!< semaphore 24 interrupt is pending */ +#define HWSEM_INTF_SIF25 BIT(25) /*!< semaphore 25 interrupt is pending */ +#define HWSEM_INTF_SIF26 BIT(26) /*!< semaphore 26 interrupt is pending */ +#define HWSEM_INTF_SIF27 BIT(27) /*!< semaphore 27 interrupt is pending */ +#define HWSEM_INTF_SIF28 BIT(28) /*!< semaphore 28 interrupt is pending */ +#define HWSEM_INTF_SIF29 BIT(29) /*!< semaphore 29 interrupt is pending */ +#define HWSEM_INTF_SIF30 BIT(30) /*!< semaphore 30 interrupt is pending */ +#define HWSEM_INTF_SIF31 BIT(31) /*!< semaphore 31 interrupt is pending */ + +/* HWSEM_UNLK */ +#define HWSEM_UNLK_MID BITS(8,11) /*!< bus master ID to clear */ +#define HWSEM_UNLK_KEY BITS(16,31) /*!< HWSEM semaphore unlock key */ + +/* HWSEM_KEY */ +#define HWSEM_KEY_KEY BITS(16,31) /*!< key for unlocking all semaphores of a bus master */ + +/* constants definitions */ +/* HWSEM register address */ +#define HWSEM_CTL(sem) REG32(((HWSEM) + 0x0U) + 0x4U * (sem)) /*!< the address of HWSEM semaphore control register */ +#define HWSEM_RLK(sem) REG32(((HWSEM) + 0x80U) + 0x4U * (sem)) /*!< the address of HWSEM semaphore read lock register */ + +/* semaphore index */ +typedef enum { + SEM0 = 0U, /*!< semaphore 0 */ + SEM1, /*!< semaphore 1 */ + SEM2, /*!< semaphore 2 */ + SEM3, /*!< semaphore 3 */ + SEM4, /*!< semaphore 4 */ + SEM5, /*!< semaphore 5 */ + SEM6, /*!< semaphore 6 */ + SEM7, /*!< semaphore 7 */ + SEM8, /*!< semaphore 8 */ + SEM9, /*!< semaphore 9 */ + SEM10, /*!< semaphore 10 */ + SEM11, /*!< semaphore 11 */ + SEM12, /*!< semaphore 12 */ + SEM13, /*!< semaphore 13 */ + SEM14, /*!< semaphore 14 */ + SEM15, /*!< semaphore 15 */ + SEM16, /*!< semaphore 16 */ + SEM17, /*!< semaphore 17 */ + SEM18, /*!< semaphore 18 */ + SEM19, /*!< semaphore 19 */ + SEM20, /*!< semaphore 20 */ + SEM21, /*!< semaphore 21 */ + SEM22, /*!< semaphore 22 */ + SEM23, /*!< semaphore 23 */ + SEM24, /*!< semaphore 24 */ + SEM25, /*!< semaphore 25 */ + SEM26, /*!< semaphore 26 */ + SEM27, /*!< semaphore 27 */ + SEM28, /*!< semaphore 28 */ + SEM29, /*!< semaphore 29 */ + SEM30, /*!< semaphore 30 */ + SEM31 /*!< semaphore 31 */ +} hwsem_semaphore_enum; + +/* hwsem_ctlx register */ +#define CTL_PID(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) /*!< write value to HWSEM_CTL_PID bit field */ +#define GET_CTL_PID(regval) GET_BITS((regval),0,7) /*!< get value of HWSEM_CTL_PID bit field */ +#define CTL_MID(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) /*!< write value to HWSEM_CTL_MID bit field */ +#define GET_CTL_MID(regval) GET_BITS((regval),8,11) /*!< get value of HWSEM_CTL_MID bit field */ +#define HWSEM_LOCK HWSEM_CTL_LK /*!< HWSEM semaphore locked */ + +/* hwsem_unlk register */ +#define UNLK_MID(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) /*!< write value to HWSEM_CTL_PID bit field */ +#define UNLK_KEY(regval) (BITS(16,31) & ((uint32_t)(regval) << 16))/*!< write value to HWSEM_CTL_PID bit field */ + +/* hwsem_key register */ +#define KEY_KEY(regval) (BITS(16,31) & ((uint32_t)(regval) << 16))/*!< write value to HWSEM_CTL_PID bit field */ +#define GET_KEY_KEY(regval) GET_BITS((regval),16,31) /*!< get value of HWSEM_CTL_PID bit field */ + +/* AHB bus master ID */ +#define HWSEM_MASTER_ID 0x0BU /*!< core CM7 master ID */ + +/* function declarations */ +/* lock & unlock functions */ +/* try to lock the specific semaphore by writing process ID */ +ErrStatus hwsem_lock_set(hwsem_semaphore_enum semaphore, uint8_t process); +/* try to release the lock of the semaphore by writing process ID */ +ErrStatus hwsem_lock_release(hwsem_semaphore_enum semaphore, uint8_t process); +/* try to lock the semaphore by reading */ +ErrStatus hwsem_lock_by_reading(hwsem_semaphore_enum semaphore); +/* unlock all semaphores of the master ID */ +ErrStatus hwsem_unlock_all(uint16_t key); + +/* others */ +/* get process ID of the specific semaphore */ +uint32_t hwsem_process_id_get(hwsem_semaphore_enum semaphore); +/* get master ID of the specific semaphore */ +uint32_t hwsem_master_id_get(hwsem_semaphore_enum semaphore); +/* get the lock status of the semaphore */ +FlagStatus hwsem_lock_status_get(hwsem_semaphore_enum semaphore); +/* set the key */ +void hwsem_key_set(uint16_t key); +/* get the key */ +uint16_t hwsem_key_get(void); + +/* flag and interrupt functions */ +/* get the HWSEM flag status */ +FlagStatus hwsem_flag_get(hwsem_semaphore_enum semaphore); +/* clear HWSEM flag status */ +void hwsem_flag_clear(hwsem_semaphore_enum semaphore); +/* get HWSEM interrupt flag status */ +FlagStatus hwsem_interrupt_flag_get(hwsem_semaphore_enum semaphore); +/* clear HWSEM interrupt flag */ +void hwsem_interrupt_flag_clear(hwsem_semaphore_enum semaphore); +/* enable HWSEM interrupt */ +void hwsem_interrupt_enable(hwsem_semaphore_enum semaphore); +/* disable HWSEM interrupt */ +void hwsem_interrupt_disable(hwsem_semaphore_enum semaphore); + +#endif /* GD32H7XX_HWSEM_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_i2c.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_i2c.h new file mode 100644 index 0000000000..0b1d1814d3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_i2c.h @@ -0,0 +1,408 @@ +/*! + \file gd32h7xx_i2c.h + \brief definitions for the I2C + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_I2C_H +#define GD32H7XX_I2C_H + +#include "gd32h7xx.h" + +/* I2Cx(x=0,1,2,3) definitions */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE + 0x00000400U) /*!< I2C1 base address */ +#define I2C2 (I2C_BASE + 0x00006C00U) /*!< I2C2 base address */ +#define I2C3 (I2C_BASE + 0x00000800U) /*!< I2C3 base address */ + +/* registers definitions */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00000000U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x00000004U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x00000008U) /*!< I2C slave address register 0 */ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0000000CU) /*!< I2C slave address register 1 */ +#define I2C_TIMING(i2cx) REG32((i2cx) + 0x00000010U) /*!< I2C timing register */ +#define I2C_TIMEOUT(i2cx) REG32((i2cx) + 0x00000014U) /*!< I2C timeout register */ +#define I2C_STAT(i2cx) REG32((i2cx) + 0x00000018U) /*!< I2C status register */ +#define I2C_STATC(i2cx) REG32((i2cx) + 0x0000001CU) /*!< I2C status clear register */ +#define I2C_PEC(i2cx) REG32((i2cx) + 0x00000020U) /*!< I2C PEC register */ +#define I2C_RDATA(i2cx) REG32((i2cx) + 0x00000024U) /*!< I2C receive data register */ +#define I2C_TDATA(i2cx) REG32((i2cx) + 0x00000028U) /*!< I2C transmit data register */ +#define I2C_CTL2(i2cx) REG32((i2cx) + 0x00000090U) /*!< I2C control register 2 */ + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< I2C peripheral enable */ +#define I2C_CTL0_TIE BIT(1) /*!< transmit interrupt enable */ +#define I2C_CTL0_RBNEIE BIT(2) /*!< receive interrupt enable */ +#define I2C_CTL0_ADDMIE BIT(3) /*!< address match interrupt enable in slave mode */ +#define I2C_CTL0_NACKIE BIT(4) /*!< not acknowledge received interrupt enable */ +#define I2C_CTL0_STPDETIE BIT(5) /*!< stop detection interrupt enable */ +#define I2C_CTL0_TCIE BIT(6) /*!< transfer complete interrupt enable */ +#define I2C_CTL0_ERRIE BIT(7) /*!< error interrupt enable */ +#define I2C_CTL0_DNF BITS(8,11) /*!< digital noise filter */ +#define I2C_CTL0_ANOFF BIT(12) /*!< analog noise filter */ +#define I2C_CTL0_DENT BIT(14) /*!< DMA enable for transmission */ +#define I2C_CTL0_DENR BIT(15) /*!< DMA enable for reception */ +#define I2C_CTL0_SBCTL BIT(16) /*!< slave byte control */ +#define I2C_CTL0_SS BIT(17) /*!< whether to stretch SCL low when data is not ready in slave mode */ +#define I2C_CTL0_WUEN BIT(18) /*!< wakeup from deep-sleep mode enable */ +#define I2C_CTL0_GCEN BIT(19) /*!< whether or not to response to a general call (0x00) */ +#define I2C_CTL0_SMBHAEN BIT(20) /*!< SMBus host address enable */ +#define I2C_CTL0_SMBDAEN BIT(21) /*!< SMBus device default address enable */ +#define I2C_CTL0_SMBALTEN BIT(22) /*!< SMBus alert enable */ +#define I2C_CTL0_PECEN BIT(23) /*!< PEC calculation switch */ + +/* I2Cx_CTL1 */ +#define I2C_CTL1_SADDRESS BITS(0,9) /*!< slave address to be sent */ +#define I2C_CTL1_TRDIR BIT(10) /*!< transfer direction in master mode */ +#define I2C_CTL1_ADD10EN BIT(11) /*!< 10-bit addressing mode enable in master mode */ +#define I2C_CTL1_HEAD10R BIT(12) /*!< 10-bit address header executes read direction only in master receive mode */ +#define I2C_CTL1_START BIT(13) /*!< generate a START condition on I2C bus */ +#define I2C_CTL1_STOP BIT(14) /*!< generate a STOP condition on I2C bus */ +#define I2C_CTL1_NACKEN BIT(15) /*!< generate NACK in slave mode */ +#define I2C_CTL1_BYTENUM BITS(16,23) /*!< number of bytes to be transferred */ +#define I2C_CTL1_RELOAD BIT(24) /*!< reload mode enable */ +#define I2C_CTL1_AUTOEND BIT(25) /*!< automatic end mode in master mode */ +#define I2C_CTL1_PECTRANS BIT(26) /*!< PEC transfer */ + +/* I2Cx_SADDR0 */ +#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ +#define I2C_SADDR0_ADDFORMAT BIT(10) /*!< address mode for the I2C slave */ +#define I2C_SADDR0_ADDRESSEN BIT(15) /*!< I2C address enable */ + +/* I2Cx_SADDR1 */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave */ +#define I2C_SADDR1_ADDMSK2 BITS(8,10) /*!< ADDRESS2[7:1] mask */ +#define I2C_SADDR1_ADDRESS2EN BIT(15) /*!< second I2C address enable */ + +/* I2Cx_TIMING */ +#define I2C_TIMING_SCLL BITS(0,7) /*!< SCL low period */ +#define I2C_TIMING_SCLH BITS(8,15) /*!< SCL high period */ +#define I2C_TIMING_SDADELY BITS(16,19) /*!< data hold time */ +#define I2C_TIMING_SCLDELY BITS(20,23) /*!< data setup time */ +#define I2C_TIMING_PSC BITS(28,31) /*!< timing prescaler */ + +/* I2Cx_TIMEOUT */ +#define I2C_TIMEOUT_BUSTOA BITS(0,11) /*!< bus timeout A */ +#define I2C_TIMEOUT_TOIDLE BIT(12) /*!< idle clock timeout detection */ +#define I2C_TIMEOUT_TOEN BIT(15) /*!< clock timeout detection enable */ +#define I2C_TIMEOUT_BUSTOB BITS(16,27) /*!< bus timeout B */ +#define I2C_TIMEOUT_EXTOEN BIT(31) /*!< extended clock timeout detection enable */ + +/* I2Cx_STAT */ +#define I2C_STAT_TBE BIT(0) /*!< I2C_TDATA is empty during transmitting */ +#define I2C_STAT_TI BIT(1) /*!< transmit interrupt */ +#define I2C_STAT_RBNE BIT(2) /*!< I2C_RDATA is not empty during receiving */ +#define I2C_STAT_ADDSEND BIT(3) /*!< address received matches in slave mode */ +#define I2C_STAT_NACK BIT(4) /*!< not acknowledge flag */ +#define I2C_STAT_STPDET BIT(5) /*!< STOP condition detected in slave mode */ +#define I2C_STAT_TC BIT(6) /*!< transfer complete in master mode */ +#define I2C_STAT_TCR BIT(7) /*!< transfer complete reload */ +#define I2C_STAT_BERR BIT(8) /*!< bus error */ +#define I2C_STAT_LOSTARB BIT(9) /*!< arbitration lost */ +#define I2C_STAT_OUERR BIT(10) /*!< overrun/underrun error in slave mode */ +#define I2C_STAT_PECERR BIT(11) /*!< PEC error */ +#define I2C_STAT_TIMEOUT BIT(12) /*!< timeout flag */ +#define I2C_STAT_SMBALT BIT(13) /*!< SMBus alert */ +#define I2C_STAT_I2CBSY BIT(15) /*!< busy flag */ +#define I2C_STAT_TR BIT(16) /*!< whether the I2C is a transmitter or a receiver in slave mode */ +#define I2C_STAT_READDR BITS(17,23) /*!< received match address in slave mode */ + +/* I2Cx_STATC */ +#define I2C_STATC_ADDSENDC BIT(3) /*!< ADDSEND flag clear */ +#define I2C_STATC_NACKC BIT(4) /*!< not acknowledge flag clear */ +#define I2C_STATC_STPDETC BIT(5) /*!< STPDET flag clear */ +#define I2C_STATC_BERRC BIT(8) /*!< bus error flag clear */ +#define I2C_STATC_LOSTARBC BIT(9) /*!< arbitration Lost flag clear */ +#define I2C_STATC_OUERRC BIT(10) /*!< overrun/underrun flag clear */ +#define I2C_STATC_PECERRC BIT(11) /*!< PEC error flag clear */ +#define I2C_STATC_TIMEOUTC BIT(12) /*!< TIMEOUT flag clear */ +#define I2C_STATC_SMBALTC BIT(13) /*!< SMBus alert flag clear */ + +/* I2Cx_PEC */ +#define I2C_PEC_PECV BITS(0,7) /*!< Packet Error Checking Value that calculated by hardware when PEC is enabled */ + +/* I2Cx_RDATA */ +#define I2C_RDATA_RDATA BITS(0,7) /*!< receive data value */ + +/* I2Cx_TDATA */ +#define I2C_TDATA_TDATA BITS(0,7) /*!< transmit data value */ + +/* I2Cx_CTL2 */ +#define I2C_CTL2_ADDM BITS(9,15) /*!< address bits compare select */ + +/* constants definitions */ +/* define the I2C bit position and its register index offset */ +#define I2C_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22))) +#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define I2C_CTL0_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define I2C_STAT_REG_OFFSET ((uint32_t)0x00000018U) /*!< STAT register offset */ + +/* I2C interrupt flags */ +typedef enum { + I2C_INT_FLAG_TI = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 1U, I2C_STAT_REG_OFFSET, 1U), /*!< transmit interrupt flag */ + I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 2U, I2C_STAT_REG_OFFSET, 2U), /*!< I2C_RDATA is not empty during receiving interrupt flag */ + I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 3U, I2C_STAT_REG_OFFSET, 3U), /*!< address received matches in slave mode interrupt flag */ + I2C_INT_FLAG_NACK = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 4U, I2C_STAT_REG_OFFSET, 4U), /*!< not acknowledge interrupt flag */ + I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 5U, I2C_STAT_REG_OFFSET, 5U), /*!< stop condition detected in slave mode interrupt flag */ + I2C_INT_FLAG_TC = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 6U, I2C_STAT_REG_OFFSET, 6U), /*!< transfer complete in master mode interrupt flag */ + I2C_INT_FLAG_TCR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 6U, I2C_STAT_REG_OFFSET, 7U), /*!< transfer complete reload interrupt flag */ + I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 8U), /*!< bus error interrupt flag */ + I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 9U), /*!< arbitration lost interrupt flag */ + I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 10U), /*!< overrun/underrun error in slave mode interrupt flag */ + I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 11U), /*!< PEC error interrupt flag */ + I2C_INT_FLAG_TIMEOUT = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 12U), /*!< timeout interrupt flag */ + I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 13U) /*!< SMBus Alert interrupt flag */ +} i2c_interrupt_flag_enum; + +/* I2C DMA constants definitions */ +#define I2C_DMA_TRANSMIT ((uint32_t)0x00000000U) /*!< I2C transmit data use DMA */ +#define I2C_DMA_RECEIVE ((uint32_t)0x00000001U) /*!< I2C receive data use DMA */ + +/* I2C interrupt enable or disable */ +#define I2C_INT_ERR I2C_CTL0_ERRIE /*!< error interrupt enable */ +#define I2C_INT_TC I2C_CTL0_TCIE /*!< transfer complete interrupt enable */ +#define I2C_INT_STPDET I2C_CTL0_STPDETIE /*!< stop detection interrupt enable */ +#define I2C_INT_NACK I2C_CTL0_NACKIE /*!< not acknowledge received interrupt enable */ +#define I2C_INT_ADDM I2C_CTL0_ADDMIE /*!< address match interrupt enable */ +#define I2C_INT_RBNE I2C_CTL0_RBNEIE /*!< receive interrupt enable */ +#define I2C_INT_TI I2C_CTL0_TIE /*!< transmit interrupt enable */ + +/* I2C transfer direction in master mode */ +#define I2C_MASTER_TRANSMIT ((uint32_t)0x00000000U) /*!< I2C master transmit */ +#define I2C_MASTER_RECEIVE I2C_CTL1_TRDIR /*!< I2C master receive */ + +/* address mode for the I2C slave */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address format is 7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address format is 10 bits */ + +/* the length of filter spikes */ +#define FILTER_DISABLE ((uint32_t)0x00000000U) /*!< digital filter is disabled */ +#define FILTER_LENGTH_1 ((uint32_t)0x00000001U) /*!< digital filter is enabled and filter spikes with a length of up to 1 tI2CCLK */ +#define FILTER_LENGTH_2 ((uint32_t)0x00000002U) /*!< digital filter is enabled and filter spikes with a length of up to 2 tI2CCLK */ +#define FILTER_LENGTH_3 ((uint32_t)0x00000003U) /*!< digital filter is enabled and filter spikes with a length of up to 3 tI2CCLK */ +#define FILTER_LENGTH_4 ((uint32_t)0x00000004U) /*!< digital filter is enabled and filter spikes with a length of up to 4 tI2CCLK */ +#define FILTER_LENGTH_5 ((uint32_t)0x00000005U) /*!< digital filter is enabled and filter spikes with a length of up to 5 tI2CCLK */ +#define FILTER_LENGTH_6 ((uint32_t)0x00000006U) /*!< digital filter is enabled and filter spikes with a length of up to 6 tI2CCLK */ +#define FILTER_LENGTH_7 ((uint32_t)0x00000007U) /*!< digital filter is enabled and filter spikes with a length of up to 7 tI2CCLK */ +#define FILTER_LENGTH_8 ((uint32_t)0x00000008U) /*!< digital filter is enabled and filter spikes with a length of up to 8 tI2CCLK */ +#define FILTER_LENGTH_9 ((uint32_t)0x00000009U) /*!< digital filter is enabled and filter spikes with a length of up to 9 tI2CCLK */ +#define FILTER_LENGTH_10 ((uint32_t)0x0000000AU) /*!< digital filter is enabled and filter spikes with a length of up to 10 tI2CCLK */ +#define FILTER_LENGTH_11 ((uint32_t)0x0000000BU) /*!< digital filter is enabled and filter spikes with a length of up to 11 tI2CCLK */ +#define FILTER_LENGTH_12 ((uint32_t)0x0000000CU) /*!< digital filter is enabled and filter spikes with a length of up to 12 tI2CCLK */ +#define FILTER_LENGTH_13 ((uint32_t)0x0000000DU) /*!< digital filter is enabled and filter spikes with a length of up to 13 tI2CCLK */ +#define FILTER_LENGTH_14 ((uint32_t)0x0000000EU) /*!< digital filter is enabled and filter spikes with a length of up to 14 tI2CCLK */ +#define FILTER_LENGTH_15 ((uint32_t)0x0000000FU) /*!< digital filter is enabled and filter spikes with a length of up to 15 tI2CCLK */ + +/* defines which bits of register ADDRESS[7:1] are compared with an incoming address byte */ +#define ADDRESS_BIT1_COMPARE ((uint32_t)0x00000200U) /*!< address bit1 needs compare */ +#define ADDRESS_BIT2_COMPARE ((uint32_t)0x00000400U) /*!< address bit2 needs compare */ +#define ADDRESS_BIT3_COMPARE ((uint32_t)0x00000800U) /*!< address bit3 needs compare */ +#define ADDRESS_BIT4_COMPARE ((uint32_t)0x00001000U) /*!< address bit4 needs compare */ +#define ADDRESS_BIT5_COMPARE ((uint32_t)0x00002000U) /*!< address bit5 needs compare */ +#define ADDRESS_BIT6_COMPARE ((uint32_t)0x00004000U) /*!< address bit6 needs compare */ +#define ADDRESS_BIT7_COMPARE ((uint32_t)0x00008000U) /*!< address bit7 needs compare */ + +/* defines which bits of ADDRESS2[7:1] are compared with an incoming address byte, and which bits are masked (do not care) */ +#define ADDRESS2_NO_MASK ((uint32_t)0x00000000U) /*!< no mask, all the bits must be compared */ +#define ADDRESS2_MASK_BIT1 ((uint32_t)0x00000001U) /*!< ADDRESS2[1] is masked, only ADDRESS2[7:2] are compared */ +#define ADDRESS2_MASK_BIT1_2 ((uint32_t)0x00000002U) /*!< ADDRESS2[2:1] is masked, only ADDRESS2[7:3] are compared */ +#define ADDRESS2_MASK_BIT1_3 ((uint32_t)0x00000003U) /*!< ADDRESS2[3:1] is masked, only ADDRESS2[7:4] are compared */ +#define ADDRESS2_MASK_BIT1_4 ((uint32_t)0x00000004U) /*!< ADDRESS2[4:1] is masked, only ADDRESS2[7:5] are compared */ +#define ADDRESS2_MASK_BIT1_5 ((uint32_t)0x00000005U) /*!< ADDRESS2[5:1] is masked, only ADDRESS2[7:6] are compared */ +#define ADDRESS2_MASK_BIT1_6 ((uint32_t)0x00000006U) /*!< ADDRESS2[6:1] is masked, only ADDRESS2[7] are compared */ +#define ADDRESS2_MASK_ALL ((uint32_t)0x00000007U) /*!< all the ADDRESS2[7:1] bits are masked */ + +/* idle clock timeout detection */ +#define BUSTOA_DETECT_SCL_LOW ((uint32_t)0x00000000U) /*!< BUSTOA is used to detect SCL low timeout */ +#define BUSTOA_DETECT_IDLE I2C_TIMEOUT_TOIDLE /*!< BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle */ + +/* I2C flag definitions */ +#define I2C_FLAG_TBE I2C_STAT_TBE /*!< I2C_TDATA is empty during transmitting */ +#define I2C_FLAG_TI I2C_STAT_TI /*!< transmit interrupt */ +#define I2C_FLAG_RBNE I2C_STAT_RBNE /*!< I2C_RDATA is not empty during receiving */ +#define I2C_FLAG_ADDSEND I2C_STAT_ADDSEND /*!< address received matches in slave mode */ +#define I2C_FLAG_NACK I2C_STAT_NACK /*!< not acknowledge flag */ +#define I2C_FLAG_STPDET I2C_STAT_STPDET /*!< STOP condition detected in slave mode */ +#define I2C_FLAG_TC I2C_STAT_TC /*!< transfer complete in master mode */ +#define I2C_FLAG_TCR I2C_STAT_TCR /*!< transfer complete reload */ +#define I2C_FLAG_BERR I2C_STAT_BERR /*!< bus error */ +#define I2C_FLAG_LOSTARB I2C_STAT_LOSTARB /*!< arbitration lost */ +#define I2C_FLAG_OUERR I2C_STAT_OUERR /*!< overrun/underrun error in slave mode */ +#define I2C_FLAG_PECERR I2C_STAT_PECERR /*!< PEC error */ +#define I2C_FLAG_TIMEOUT I2C_STAT_TIMEOUT /*!< timeout flag */ +#define I2C_FLAG_SMBALT I2C_STAT_SMBALT /*!< SMBus Alert */ +#define I2C_FLAG_I2CBSY I2C_STAT_I2CBSY /*!< busy flag */ +#define I2C_FLAG_TR I2C_STAT_TR /*!< whether the I2C is a transmitter or a receiver in slave mode */ + +/* function declarations */ +/* initialization functions */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure the timing parameters */ +void i2c_timing_config(uint32_t i2c_periph, uint32_t psc, uint32_t scl_dely, uint32_t sda_dely); +/* configure digital noise filter */ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, uint32_t filter_length); +/* enable analog noise filter */ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph); +/* disable analog noise filter */ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph); +/* configure the SCL high and low period of clock in master mode */ +void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll); +/* configure I2C slave address and transfer direction in master mode */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction); + +/* application function declarations */ +/* 10-bit address header executes read direction only in master receive mode */ +void i2c_address10_header_enable(uint32_t i2c_periph); +/* 10-bit address header executes complete sequence in master receive mode */ +void i2c_address10_header_disable(uint32_t i2c_periph); +/* enable 10-bit addressing mode in master mode */ +void i2c_address10_enable(uint32_t i2c_periph); +/* disable 10-bit addressing mode in master mode */ +void i2c_address10_disable(uint32_t i2c_periph); +/* enable I2C automatic end mode in master mode */ +void i2c_automatic_end_enable(uint32_t i2c_periph); +/* disable I2C automatic end mode in master mode */ +void i2c_automatic_end_disable(uint32_t i2c_periph); +/* enable the response to a general call */ +void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph); +/* disable the response to a general call */ +void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph); +/* enable to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_enable(uint32_t i2c_periph); +/* disable to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_disable(uint32_t i2c_periph); +/* configure I2C slave address */ +void i2c_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_format); +/* define which bits of ADDRESS[7:1] need to compare with the incoming address byte */ +void i2c_address_bit_compare_config(uint32_t i2c_periph, uint32_t compare_bits); +/* disable I2C address in slave mode */ +void i2c_address_disable(uint32_t i2c_periph); +/* configure I2C second slave address */ +void i2c_second_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_mask); +/* disable I2C second address in slave mode */ +void i2c_second_address_disable(uint32_t i2c_periph); +/* get received match address in slave mode */ +uint32_t i2c_recevied_address_get(uint32_t i2c_periph); +/* enable slave byte control */ +void i2c_slave_byte_control_enable(uint32_t i2c_periph); +/* disable slave byte control */ +void i2c_slave_byte_control_disable(uint32_t i2c_periph); +/* generate a NACK in slave mode */ +void i2c_nack_enable(uint32_t i2c_periph); +/* generate an ACK in slave mode */ +void i2c_nack_disable(uint32_t i2c_periph); +/* enable wakeup from deep-sleep mode */ +void i2c_wakeup_from_deepsleep_enable(uint32_t i2c_periph); +/* disable wakeup from deep-sleep mode */ +void i2c_wakeup_from_deepsleep_disable(uint32_t i2c_periph); +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data */ +void i2c_data_transmit(uint32_t i2c_periph, uint32_t data); +/* I2C receive data */ +uint32_t i2c_data_receive(uint32_t i2c_periph); +/* enable I2C reload mode */ +void i2c_reload_enable(uint32_t i2c_periph); +/* disable I2C reload mode */ +void i2c_reload_disable(uint32_t i2c_periph); +/* configure number of bytes to be transferred */ +void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint32_t byte_number); +/* enable I2C DMA for transmission or reception */ +void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma); +/* disable I2C DMA for transmission or reception */ +void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma); +/* I2C transfers PEC value */ +void i2c_pec_transfer(uint32_t i2c_periph); +/* enable I2C PEC calculation */ +void i2c_pec_enable(uint32_t i2c_periph); +/* disable I2C PEC calculation */ +void i2c_pec_disable(uint32_t i2c_periph); +/* get packet error checking value */ +uint32_t i2c_pec_value_get(uint32_t i2c_periph); +/* enable SMBus alert */ +void i2c_smbus_alert_enable(uint32_t i2c_periph); +/* disable SMBus alert */ +void i2c_smbus_alert_disable(uint32_t i2c_periph); +/* enable SMBus device default address */ +void i2c_smbus_default_addr_enable(uint32_t i2c_periph); +/* disable SMBus device default address */ +void i2c_smbus_default_addr_disable(uint32_t i2c_periph); +/* enable SMBus host address */ +void i2c_smbus_host_addr_enable(uint32_t i2c_periph); +/* disable SMBus host address */ +void i2c_smbus_host_addr_disable(uint32_t i2c_periph); +/* enable extended clock timeout detection */ +void i2c_extented_clock_timeout_enable(uint32_t i2c_periph); +/* disable extended clock timeout detection */ +void i2c_extented_clock_timeout_disable(uint32_t i2c_periph); +/* enable clock timeout detection */ +void i2c_clock_timeout_enable(uint32_t i2c_periph); +/* disable clock timeout detection */ +void i2c_clock_timeout_disable(uint32_t i2c_periph); +/* configure bus timeout B */ +void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout); +/* configure bus timeout A */ +void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout); +/* configure idle clock timeout detection */ +void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout); + +/* interrupt & flag functions */ +/* get I2C flag status */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag); +/* clear I2C flag status */ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t interrupt); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t interrupt); +/* get I2C interrupt flag status */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); +/* clear I2C interrupt flag status */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); + +#endif /* GD32H7XX_I2C_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ipa.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ipa.h new file mode 100644 index 0000000000..e5254daf39 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ipa.h @@ -0,0 +1,479 @@ +/*! + \file gd32h7xx_ipa.h + \brief definitions for the IPA + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_IPA_H +#define GD32H7XX_IPA_H + +#include "gd32h7xx.h" + +/* IPA definitions */ +#define IPA IPA_BASE /*!< IPA base address */ + +/* bits definitions */ +/* registers definitions */ +#define IPA_CTL REG32(IPA + 0x00000000U) /*!< IPA control register */ +#define IPA_INTF REG32(IPA + 0x00000004U) /*!< IPA interrupt flag register */ +#define IPA_INTC REG32(IPA + 0x00000008U) /*!< IPA interrupt flag clear register */ +#define IPA_FMADDR REG32(IPA + 0x0000000CU) /*!< IPA foreground memory base address register */ +#define IPA_FLOFF REG32(IPA + 0x00000010U) /*!< IPA foreground line offset register */ +#define IPA_BMADDR REG32(IPA + 0x00000014U) /*!< IPA background memory base address register */ +#define IPA_BLOFF REG32(IPA + 0x00000018U) /*!< IPA background line offset register */ +#define IPA_FPCTL REG32(IPA + 0x0000001CU) /*!< IPA foreground pixel control register */ +#define IPA_FPV REG32(IPA + 0x00000020U) /*!< IPA foreground pixel value register */ +#define IPA_BPCTL REG32(IPA + 0x00000024U) /*!< IPA background pixel control register */ +#define IPA_BPV REG32(IPA + 0x00000028U) /*!< IPA background pixel value register */ +#define IPA_FLMADDR REG32(IPA + 0x0000002CU) /*!< IPA foreground LUT memory base address register */ +#define IPA_BLMADDR REG32(IPA + 0x00000030U) /*!< IPA background LUT memory base address register */ +#define IPA_DPCTL REG32(IPA + 0x00000034U) /*!< IPA destination pixel control register */ +#define IPA_DPV REG32(IPA + 0x00000038U) /*!< IPA destination pixel value register */ +#define IPA_DMADDR REG32(IPA + 0x0000003CU) /*!< IPA destination memory base address register */ +#define IPA_DLOFF REG32(IPA + 0x00000040U) /*!< IPA destination line offset register */ +#define IPA_IMS REG32(IPA + 0x00000044U) /*!< IPA image size register */ +#define IPA_LM REG32(IPA + 0x00000048U) /*!< IPA line mark register */ +#define IPA_ITCTL REG32(IPA + 0x0000004CU) /*!< IPA inter-timer control register */ +#define IPA_BSCTL REG32(IPA + 0x00000050U) /*!< IPA bilinear scaling control register */ +#define IPA_DIMS REG32(IPA + 0x00000054U) /*!< IPA scaling image size register */ +#define IPA_EF_UV_MADDR REG32(IPA + 0x0000005CU) /*!< IPA foreground even frame/UV memory base address register */ +#define IPA_CSCC_CFG0 REG32(IPA + 0x00000060U) /*!< IPA color space conversion coefficient 0 */ +#define IPA_CSCC_CFG1 REG32(IPA + 0x00000064U) /*!< IPA color space conversion coefficient 1 */ +#define IPA_CSCC_CFG2 REG32(IPA + 0x00000068U) /*!< IPA color space conversion coefficient 2 */ + +/* IPA_CTL */ +#define IPA_CTL_TEN BIT(0) /*!< transfer enable */ +#define IPA_CTL_THU BIT(1) /*!< transfer hang up */ +#define IPA_CTL_TST BIT(2) /*!< transfer stop */ +#define IPA_CTL_TAEIE BIT(8) /*!< enable bit for transfer access error interrupt */ +#define IPA_CTL_FTFIE BIT(9) /*!< enable bit for full transfer finish interrup */ +#define IPA_CTL_TLMIE BIT(10) /*!< enable bit for transfer line mark interrupt */ +#define IPA_CTL_LACIE BIT(11) /*!< enable bit for LUT access conflict interrupt */ +#define IPA_CTL_LLFIE BIT(12) /*!< enable bit for LUT loading finish interrupt */ +#define IPA_CTL_WCFIE BIT(13) /*!< enable bit for wrong configuration interrupt */ +#define IPA_CTL_PFCM BITS(16,17) /*!< pixel format convert mode */ + +/* IPA_INTF */ +#define IPA_INTF_TAEIF BIT(0) /*!< transfer access error interrupt flag */ +#define IPA_INTF_FTFIF BIT(1) /*!< full transfer finish interrupt flag */ +#define IPA_INTF_TLMIF BIT(2) /*!< transfer line mark interrupt flag */ +#define IPA_INTF_LACIF BIT(3) /*!< LUT access conflict interrupt flag */ +#define IPA_INTF_LLFIF BIT(4) /*!< LUT loading finish interrupt flag */ +#define IPA_INTF_WCFIF BIT(5) /*!< wrong configuration interrupt flag */ + +/* IPA_INTC */ +#define IPA_INTC_TAEIFC BIT(0) /*!< clear bit for transfer access error interrupt flag */ +#define IPA_INTC_FTFIFC BIT(1) /*!< clear bit for full transfer finish interrupt flag */ +#define IPA_INTC_TLMIFC BIT(2) /*!< clear bit for transfer line mark interrupt flag */ +#define IPA_INTC_LACIFC BIT(3) /*!< clear bit for LUT access conflict interrupt flag */ +#define IPA_INTC_LLFIFC BIT(4) /*!< clear bit for LUT loading finish interrupt flag */ +#define IPA_INTC_WCFIFC BIT(5) /*!< clear bit for wrong configuration interrupt flag */ + +/* IPA_FMADDR */ +#define IPA_FMADDR_FMADDR BITS(0,31) /*!< foreground memory base address */ + +/* IPA_FLOFF */ +#define IPA_FLOFF_FLOFF BITS(0,13) /*!< foreground line offset */ + +/* IPA_BMADDR */ +#define IPA_BMADDR_BMADDR BITS(0,31) /*!< background memory base address */ + +/* IPA_BLOFF */ +#define IPA_BLOFF_BLOFF BITS(0,13) /*!< background line offset */ + +/* IPA_FPCTL */ +#define IPA_FPCTL_FPF BITS(0,3) /*!< foreground pixel format */ +#define IPA_FPCTL_FLPF BIT(4) /*!< foreground LUT pixel format */ +#define IPA_FPCTL_FLLEN BIT(5) /*!< foreground LUT loading enable */ +#define IPA_FPCTL_FCNP BITS(8,15) /*!< foreground LUT number of pixel */ +#define IPA_FPCTL_FAVCA BITS(16,17) /*!< foreground alpha value calculation algorithm */ +#define IPA_FPCTL_FIIMEN BIT(23) /*!< foreground input interlace mode enable */ +#define IPA_FPCTL_FPDAV BITS(24,31) /*!< foreground pre-defined alpha value */ + +/* IPA_FPV */ +#define IPA_FPV_FPDBV BITS(0,7) /*!< foreground pre-defined red value */ +#define IPA_FPV_FPDGV BITS(8,15) /*!< foreground pre-defined green value */ +#define IPA_FPV_FPDRV BITS(16,23) /*!< foreground pre-defined red value */ + +/* IPA_BPCTL */ +#define IPA_BPCTL_BPF BITS(0,3) /*!< background pixel format */ +#define IPA_BPCTL_BLPF BIT(4) /*!< background LUT pixel format */ +#define IPA_BPCTL_BLLEN BIT(5) /*!< background LUT loading enable */ +#define IPA_BPCTL_BCNP BITS(8,15) /*!< background LUT number of pixel */ +#define IPA_BPCTL_BAVCA BITS(16,17) /*!< background alpha value calculation algorithm */ +#define IPA_BPCTL_BPDAV BITS(24,31) /*!< background pre-defined alpha value */ + +/* IPA_BPV */ +#define IPA_BPV_BPDBV BITS(0,7) /*!< background pre-defined blue value */ +#define IPA_BPV_BPDGV BITS(8,15) /*!< background pre-defined green value */ +#define IPA_BPV_BPDRV BITS(16,23) /*!< background pre-defined red value */ + +/* IPA_FLMADDR */ +#define IPA_FLMADDR_FLMADDR BITS(0,31) /*!< foreground LUT memory base address */ + +/* IPA_BLMADDR */ +#define IPA_BLMADDR_BLMADDR BITS(0,31) /*!< background LUT memory base address */ + +/* IPA_DPCTL */ +#define IPA_DPCTL_DPF BITS(0,2) /*!< destination pixel control register */ +#define IPA_DPCTL_ROT BITS(8,9) /*!< destination image rotation angle */ +#define IPA_DPCTL_HORDEC BITS(16,17) /*!< destination horizontal pre decimation filter control */ +#define IPA_DPCTL_VERDEC BITS(18,19) /*!< destination verticle pre decimation filter control */ + +/* IPA_DPV */ +/* destination pixel format ARGB8888 */ +#define IPA_DPV_DPDBV_0 BITS(0,7) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_0 BITS(8,15) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_0 BITS(16,23) /*!< destination pre-defined red value */ +#define IPA_DPV_DPDAV_0 BITS(24,31) /*!< destination pre-defined alpha value */ + +/* destination pixel format RGB888 */ +#define IPA_DPV_DPDBV_1 BITS(0,7) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_1 BITS(8,15) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_1 BITS(16,23) /*!< destination pre-defined red value */ + +/* destination pixel format RGB565 */ +#define IPA_DPV_DPDBV_2 BITS(0,4) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_2 BITS(5,10) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_2 BITS(11,15) /*!< destination pre-defined red value */ + +/* destination pixel format ARGB1555 */ +#define IPA_DPV_DPDBV_3 BITS(0,4) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_3 BITS(5,9) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_3 BITS(10,14) /*!< destination pre-defined red value */ +#define IPA_DPV_DPDAV_3 BIT(15) /*!< destination pre-defined alpha value */ + +/* destination pixel format ARGB4444 */ +#define IPA_DPV_DPDBV_4 BITS(0,3) /*!< destination pre-defined blue value */ +#define IPA_DPV_DPDGV_4 BITS(4,7) /*!< destination pre-defined green value */ +#define IPA_DPV_DPDRV_4 BITS(8,11) /*!< destination pre-defined red value */ +#define IPA_DPV_DPDAV_4 BITS(12,15) /*!< destination pre-defined alpha value */ + +/* IPA_DMADDR */ +#define IPA_DMADDR_DMADDR BITS(0,31) /*!< destination memory base address */ + +/* IPA_DLOFF */ +#define IPA_DLOFF_DLOFF BITS(0,13) /*!< destination line offset */ + +/* IPA_IMS */ +#define IPA_IMS_HEIGHT BITS(0,15) /*!< height of the image to be processed */ +#define IPA_IMS_WIDTH BITS(16,29) /*!< width of the image to be processed */ + +/* IPA_LM */ +#define IPA_LM_LM BITS(0,15) /*!< line mark */ + +/* IPA_ITCTL */ +#define IPA_ITCTL_ITEN BIT(0) /*!< inter-timer enable */ +#define IPA_ITCTL_NCCI BITS(8,15) /*!< number of clock cycles interval */ + +/* IPA_BSCTL */ +#define IPA_BSCTL_XSCALE BITS(0,13) /*!< foreground X scaling factor */ +#define IPA_BSCTL_YSCALE BITS(16,29) /*!< foreground Y scaling factor */ + +/* IPA_DIMS */ +#define IPA_DIMS_DHEIGHT BITS(0,15) /*!< destination height after scaling */ +#define IPA_DIMS_DWIDTH BITS(16,29) /*!< destination width after scaling */ + +/* IPA_EF_UV_MADDR */ +#define IPA_EF_UV_MADDR_EFUVMADDR BITS(0,31) /*!< foreground even frame/UV memory base address */ + +/* IPA_CSCC_CFG0 */ +#define IPA_CSCC_CFG0_YOFF BITS(0,8) /*!< offset implicit in the Y data */ +#define IPA_CSCC_CFG0_UVOFF BITS(9,17) /*!< offset implicit in the UV data */ +#define IPA_CSCC_CFG0_C0 BITS(18,28) /*!< Y multiplier coefficient */ +#define IPA_CSCC_CFG0_CONVMOD BIT(31) /*!< color space convert mode */ + +/* IPA_CSCC_CFG1 */ +#define IPA_CSCC_CFG1_C4 BITS(0,10) /*!< blue U/Cb multiplier coefficient */ +#define IPA_CSCC_CFG1_C1 BITS(16,26) /*!< red V/Cr multiplier coefficient */ + +/* IPA_CSCC_CFG2 */ +#define IPA_CSCC_CFG2_C3 BITS(0,10) /*!< green U/Cb multiplier coefficient */ +#define IPA_CSCC_CFG2_C2 BITS(16,26) /*!< green V/Cr multiplier coefficient */ + +/* constants definitions */ +/* IPA foreground parameter struct definitions */ +typedef struct { + uint32_t foreground_memaddr; /*!< foreground memory base address */ + uint32_t foreground_lineoff; /*!< foreground line offset */ + uint32_t foreground_prealpha; /*!< foreground pre-defined alpha value */ + uint32_t foreground_alpha_algorithm; /*!< foreground alpha value calculation algorithm */ + uint32_t foreground_pf; /*!< foreground pixel format */ + uint32_t foreground_prered; /*!< foreground pre-defined red value */ + uint32_t foreground_pregreen; /*!< foreground pre-defined green value */ + uint32_t foreground_preblue; /*!< foreground pre-defined blue value */ + uint32_t foreground_interlace_mode; /*!< foreground input interlace mode enable */ + uint32_t foreground_efuv_memaddr; /*!< foreground even frame / UV memory base address */ +} ipa_foreground_parameter_struct; + +/* IPA background parameter struct definitions */ +typedef struct { + uint32_t background_memaddr; /*!< background memory base address */ + uint32_t background_lineoff; /*!< background line offset */ + uint32_t background_prealpha; /*!< background pre-defined alpha value */ + uint32_t background_alpha_algorithm; /*!< background alpha value calculation algorithm */ + uint32_t background_pf; /*!< background pixel format */ + uint32_t background_prered; /*!< background pre-defined red value */ + uint32_t background_pregreen; /*!< background pre-defined green value */ + uint32_t background_preblue; /*!< background pre-defined blue value */ +} ipa_background_parameter_struct; + +/* IPA destination parameter struct definitions */ +typedef struct { + uint32_t destination_memaddr; /*!< destination memory base address */ + uint32_t destination_lineoff; /*!< destination line offset */ + uint32_t destination_prealpha; /*!< destination pre-defined alpha value */ + uint32_t destination_pf; /*!< destination pixel format */ + uint32_t destination_prered; /*!< destination pre-defined red value */ + uint32_t destination_pregreen; /*!< destination pre-defined green value */ + uint32_t destination_preblue; /*!< destination pre-defined blue value */ + uint32_t image_width; /*!< width of the image to be processed */ + uint32_t image_height; /*!< height of the image to be processed */ + uint32_t image_rotate; /*!< angle of image rotation */ + uint32_t image_hor_decimation; /*!< image horizontal pre-decimation in width */ + uint32_t image_ver_decimation; /*!< image vertical pre-decimation in height */ + uint32_t image_bilinear_xscale; /*!< bilinear scaling x factor */ + uint32_t image_bilinear_yscale; /*!< bilinear scaling y factor */ + uint32_t image_scaling_width; /*!< width of the image after scaling */ + uint32_t image_scaling_height; /*!< height of the image after scaling */ +} ipa_destination_parameter_struct; + +/* destination pixel format */ +typedef enum { + IPA_DPF_ARGB8888 = 0U, /*!< destination pixel format ARGB8888 */ + IPA_DPF_RGB888, /*!< destination pixel format RGB888 */ + IPA_DPF_RGB565, /*!< destination pixel format RGB565 */ + IPA_DPF_ARGB1555, /*!< destination pixel format ARGB1555 */ + IPA_DPF_ARGB4444 /*!< destination pixel format ARGB4444 */ +} ipa_dpf_enum; + +/* IPA color conversion parameter struct definitions */ +typedef struct { + uint32_t color_space; /*!< color space convert mode */ + uint32_t y_offset; /*!< offset implicit in the Y data */ + uint32_t uv_offset; /*!< offset implicit in the UV data */ + uint32_t coef_c0; /*!< Y multiplier coefficient */ + uint32_t coef_c1; /*!< V/Cr red multiplier coefficient */ + uint32_t coef_c2; /*!< V/Cr green multiplier coefficient */ + uint32_t coef_c3; /*!< U/Cb green multiplier coefficient */ + uint32_t coef_c4; /*!< U/Cb blue multiplier coefficient */ +} ipa_conversion_parameter_struct; + +/* destination pixel format */ +typedef enum { + IPA_COLORSPACE_YUV = 0U, /*!< IPA color conversion using YUV parameter */ + IPA_COLORSPACE_YCBCR /*!< IPA color conversion using YCbCr parameter */ +} ipa_colorspace_enum; + +/* LUT pixel format */ +#define IPA_LUT_PF_ARGB8888 ((uint8_t)0x00U) /*!< LUT pixel format ARGB8888 */ +#define IPA_LUT_PF_RGB888 ((uint8_t)0x01U) /*!< LUT pixel format RGB888 */ + +/* Inter-timer */ +#define IPA_INTER_TIMER_DISABLE ((uint8_t)0x00U) /*!< inter-timer disable */ +#define IPA_INTER_TIMER_ENABLE ((uint8_t)0x01U) /*!< inter-timer enable */ + +/* IPA pixel format convert mode */ +#define CTL_PFCM(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define IPA_FGTODE CTL_PFCM(0) /*!< foreground memory to destination memory without pixel format convert */ +#define IPA_FGTODE_PF_CONVERT CTL_PFCM(1) /*!< foreground memory to destination memory with pixel format convert */ +#define IPA_FGBGTODE CTL_PFCM(2) /*!< blending foreground and background memory to destination memory */ +#define IPA_FILL_UP_DE CTL_PFCM(3) /*!< fill up destination memory with specific color */ + +/* foreground alpha value calculation algorithm */ +#define FPCTL_FAVCA(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define IPA_FG_ALPHA_MODE_0 FPCTL_FAVCA(0) /*!< no effect */ +#define IPA_FG_ALPHA_MODE_1 FPCTL_FAVCA(1) /*!< FPDAV[7:0] is selected as the foreground alpha value */ +#define IPA_FG_ALPHA_MODE_2 FPCTL_FAVCA(2) /*!< FPDAV[7:0] multiplied by read alpha value */ + +/* background alpha value calculation algorithm */ +#define BPCTL_BAVCA(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define IPA_BG_ALPHA_MODE_0 BPCTL_BAVCA(0) /*!< no effect */ +#define IPA_BG_ALPHA_MODE_1 BPCTL_BAVCA(1) /*!< BPDAV[7:0] is selected as the background alpha value */ +#define IPA_BG_ALPHA_MODE_2 BPCTL_BAVCA(2) /*!< BPDAV[7:0] multiplied by read alpha value */ + +/* foreground pixel format */ +#define FPCTL_PPF(regval) (BITS(0,3) & ((uint32_t)(regval))) +#define FOREGROUND_PPF_ARGB8888 FPCTL_PPF(0) /*!< foreground pixel format ARGB8888 */ +#define FOREGROUND_PPF_RGB888 FPCTL_PPF(1) /*!< foreground pixel format RGB888 */ +#define FOREGROUND_PPF_RGB565 FPCTL_PPF(2) /*!< foreground pixel format RGB565 */ +#define FOREGROUND_PPF_ARGB1555 FPCTL_PPF(3) /*!< foreground pixel format ARGB1555 */ +#define FOREGROUND_PPF_ARGB4444 FPCTL_PPF(4) /*!< foreground pixel format ARGB4444 */ +#define FOREGROUND_PPF_L8 FPCTL_PPF(5) /*!< foreground pixel format L8 */ +#define FOREGROUND_PPF_AL44 FPCTL_PPF(6) /*!< foreground pixel format AL44 */ +#define FOREGROUND_PPF_AL88 FPCTL_PPF(7) /*!< foreground pixel format AL88 */ +#define FOREGROUND_PPF_L4 FPCTL_PPF(8) /*!< foreground pixel format L4 */ +#define FOREGROUND_PPF_A8 FPCTL_PPF(9) /*!< foreground pixel format A8 */ +#define FOREGROUND_PPF_A4 FPCTL_PPF(10) /*!< foreground pixel format A4 */ +#define FOREGROUND_PPF_YUV444_1P FPCTL_PPF(11) /*!< foreground pixel format YUV444 */ +#define FOREGROUND_PPF_UYVY422_1P FPCTL_PPF(12) /*!< foreground pixel format UYVY422 1 plane */ +#define FOREGROUND_PPF_VYUY422_1P FPCTL_PPF(13) /*!< foreground pixel format VYUY422 1 plane */ +#define FOREGROUND_PPF_YUV420_2P FPCTL_PPF(14) /*!< foreground pixel format YUV420 2 plane */ +#define FOREGROUND_PPF_YVU420_2P FPCTL_PPF(15) /*!< foreground pixel format YVU420 2 plane */ + +/* background pixel format */ +#define BPCTL_PPF(regval) (BITS(0,3) & ((uint32_t)(regval))) +#define BACKGROUND_PPF_ARGB8888 BPCTL_PPF(0) /*!< background pixel format ARGB8888 */ +#define BACKGROUND_PPF_RGB888 BPCTL_PPF(1) /*!< background pixel format RGB888 */ +#define BACKGROUND_PPF_RGB565 BPCTL_PPF(2) /*!< background pixel format RGB565 */ +#define BACKGROUND_PPF_ARGB1555 BPCTL_PPF(3) /*!< background pixel format ARGB1555 */ +#define BACKGROUND_PPF_ARGB4444 BPCTL_PPF(4) /*!< background pixel format ARGB4444 */ +#define BACKGROUND_PPF_L8 BPCTL_PPF(5) /*!< background pixel format L8 */ +#define BACKGROUND_PPF_AL44 BPCTL_PPF(6) /*!< background pixel format AL44 */ +#define BACKGROUND_PPF_AL88 BPCTL_PPF(7) /*!< background pixel format AL88 */ +#define BACKGROUND_PPF_L4 BPCTL_PPF(8) /*!< background pixel format L4 */ +#define BACKGROUND_PPF_A8 BPCTL_PPF(9) /*!< background pixel format A8 */ +#define BACKGROUND_PPF_A4 BPCTL_PPF(10) /*!< background pixel format A4 */ + +/* rotation angle */ +#define DPCTL_ROT(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define DESTINATION_ROTATE_0 DPCTL_ROT(0) /*!< destination rotate 0 degree */ +#define DESTINATION_ROTATE_90 DPCTL_ROT(1) /*!< destination rotate 90 degree */ +#define DESTINATION_ROTATE_180 DPCTL_ROT(2) /*!< destination rotate 180 degree */ +#define DESTINATION_ROTATE_270 DPCTL_ROT(3) /*!< destination rotate 270 degree */ + +/* vertical pre-decimation filter control */ +#define DPCTL_HORDEC(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define DESTINATION_HORDECIMATE_DISABLE DPCTL_HORDEC(0) /*!< disable horizontal decimate */ +#define DESTINATION_HORDECIMATE_2 DPCTL_HORDEC(1) /*!< horizontal decimated by 2 */ +#define DESTINATION_HORDECIMATE_4 DPCTL_HORDEC(2) /*!< horizontal decimated by 4 */ +#define DESTINATION_HORDECIMATE_8 DPCTL_HORDEC(3) /*!< horizontal decimated by 8 */ + +/* horizontal pre-decimation filter control */ +#define DPCTL_VERDEC(regval) (BITS(18,19) & ((uint32_t)(regval) << 18U)) +#define DESTINATION_VERDECIMATE_DISABLE DPCTL_VERDEC(0) /*!< disable verticle decimate */ +#define DESTINATION_VERDECIMATE_2 DPCTL_VERDEC(1) /*!< verticle decimated by 2 */ +#define DESTINATION_VERDECIMATE_4 DPCTL_VERDEC(2) /*!< verticle decimated by 4 */ +#define DESTINATION_VERDECIMATE_8 DPCTL_VERDEC(3) /*!< verticle decimated by 8 */ + +/* IPA flags */ +#define IPA_FLAG_TAE IPA_INTF_TAEIF /*!< transfer access error interrupt flag */ +#define IPA_FLAG_FTF IPA_INTF_FTFIF /*!< full transfer finish interrupt flag */ +#define IPA_FLAG_TLM IPA_INTF_TLMIF /*!< transfer line mark interrupt flag */ +#define IPA_FLAG_LAC IPA_INTF_LACIF /*!< LUT access conflict interrupt flag */ +#define IPA_FLAG_LLF IPA_INTF_LLFIF /*!< LUT loading finish interrupt flag */ +#define IPA_FLAG_WCF IPA_INTF_WCFIF /*!< wrong configuration interrupt flag */ + +/* IPA interrupt enable or disable */ +#define IPA_INT_TAE IPA_CTL_TAEIE /*!< transfer access error interrupt */ +#define IPA_INT_FTF IPA_CTL_FTFIE /*!< full transfer finish interrupt */ +#define IPA_INT_TLM IPA_CTL_TLMIE /*!< transfer line mark interrupt */ +#define IPA_INT_LAC IPA_CTL_LACIE /*!< LUT access conflict interrupt */ +#define IPA_INT_LLF IPA_CTL_LLFIE /*!< LUT loading finish interrupt */ +#define IPA_INT_WCF IPA_CTL_WCFIE /*!< wrong configuration interrupt */ + +/* IPA interrupt flags */ +#define IPA_INT_FLAG_TAE IPA_INTF_TAEIF /*!< transfer access error interrupt flag */ +#define IPA_INT_FLAG_FTF IPA_INTF_FTFIF /*!< full transfer finish interrupt flag */ +#define IPA_INT_FLAG_TLM IPA_INTF_TLMIF /*!< transfer line mark interrupt flag */ +#define IPA_INT_FLAG_LAC IPA_INTF_LACIF /*!< LUT access conflict interrupt flag */ +#define IPA_INT_FLAG_LLF IPA_INTF_LLFIF /*!< LUT loading finish interrupt flag */ +#define IPA_INT_FLAG_WCF IPA_INTF_WCFIF /*!< wrong configuration interrupt flag */ + +/* function declarations */ +/* functions enable or disable, pixel format convert mode set */ +/* deinitialize IPA registers */ +void ipa_deinit(void); +/* enable IPA transfer */ +void ipa_transfer_enable(void); +/* enable IPA transfer hang up */ +void ipa_transfer_hangup_enable(void); +/* disable IPA transfer hang up */ +void ipa_transfer_hangup_disable(void); +/* enable IPA transfer stop */ +void ipa_transfer_stop_enable(void); +/* disable IPA transfer stop */ +void ipa_transfer_stop_disable(void); +/* enable IPA foreground LUT loading */ +void ipa_foreground_lut_loading_enable(void); +/* enable IPA background LUT loading */ +void ipa_background_lut_loading_enable(void); +/* set pixel format convert mode, the function is invalid when the IPA transfer is enabled */ +void ipa_pixel_format_convert_mode_set(uint32_t pfcm); +/* enable foreground interlace mode */ +void ipa_foreground_interlace_mode_enable(void); +/* disable foreground interlace mode */ +void ipa_foreground_interlace_mode_disable(void); + +/* structure initialization, foreground, background, destination and LUT initialization */ +/* initialize the structure of IPA foreground parameter struct with the default values, it is + suggested that call this function after an ipa_foreground_parameter_struct structure is defined */ +void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct *foreground_struct); +/* initialize foreground parameters */ +void ipa_foreground_init(ipa_foreground_parameter_struct *foreground_struct); +/* initialize the structure of IPA background parameter struct with the default values, it is + suggested that call this function after an ipa_background_parameter_struct structure is defined */ +void ipa_background_struct_para_init(ipa_background_parameter_struct *background_struct); +/* initialize background parameters */ +void ipa_background_init(ipa_background_parameter_struct *background_struct); +/* initialize the structure of IPA destination parameter struct with the default values, it is + suggested that call this function after an ipa_destination_parameter_struct structure is defined */ +void ipa_destination_struct_para_init(ipa_destination_parameter_struct *destination_struct); +/* initialize destination parameters */ +void ipa_destination_init(ipa_destination_parameter_struct *destination_struct); +/* initialize IPA foreground LUT parameters */ +void ipa_foreground_lut_init(uint8_t fg_lut_num, uint8_t fg_lut_pf, uint32_t fg_lut_addr); +/* initialize IPA background LUT parameters */ +void ipa_background_lut_init(uint8_t bg_lut_num, uint8_t bg_lut_pf, uint32_t bg_lut_addr); + +/* configuration functions */ +/* configure IPA line mark */ +void ipa_line_mark_config(uint16_t line_num); +/* inter-timer enable or disable */ +void ipa_inter_timer_config(uint8_t timer_cfg); +/* configure the number of clock cycles interval */ +void ipa_interval_clock_num_config(uint8_t clk_num); +/* initialize the structure of IPA color conversion parameter struct with the YUV or YCbCr conversion parameter, +it is suggested that call this function after an ipa_conversion_parameter_struct structure is defined */ +void ipa_color_conversion_struct_para_init(ipa_conversion_parameter_struct *conversion_struct, ipa_colorspace_enum colorspace); +/* configure the color space conversion parameter */ +void ipa_color_conversion_config(ipa_conversion_parameter_struct *conversion_struct); +/* configure IPA foreground scaling, including horizontal/vertical pre-decimation factors and X/Y scaling factors */ +void ipa_foreground_scaling_config(uint32_t horizontal_decimation, uint32_t vertical_decimation, uint32_t image_scaling_width, + uint32_t image_scaling_height); +/* configure IPA destination scaling, including width/height of image to be processed */ +void ipa_destination_scaling_config(uint32_t dest_scaling_width, uint32_t dest_scaling_height); + +/* flag and interrupt functions */ +/* get IPA flag status in IPA_INTF register */ +FlagStatus ipa_flag_get(uint32_t flag); +/* clear IPA flag in IPA_INTF register */ +void ipa_flag_clear(uint32_t flag); +/* enable IPA interrupt */ +void ipa_interrupt_enable(uint32_t int_flag); +/* disable IPA interrupt */ +void ipa_interrupt_disable(uint32_t int_flag); +/* get IPA interrupt flag */ +FlagStatus ipa_interrupt_flag_get(uint32_t int_flag); +/* clear IPA interrupt flag */ +void ipa_interrupt_flag_clear(uint32_t int_flag); + +#endif /* GD32H7XX_IPA_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_lpdts.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_lpdts.h new file mode 100644 index 0000000000..ff84763c3a --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_lpdts.h @@ -0,0 +1,195 @@ +/*! + \file gd32h7xx_lpdts.h + \brief definitions for the LPDTS + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_LPDTS_H +#define GD32H7XX_LPDTS_H + +#include "gd32h7xx.h" + +/* LPDTS definitions */ +#define LPDTS LPDTS_BASE + +/* registers definitions */ +#define LPDTS_CFG REG32(LPDTS + 0x00000000U) /*!< LPDTS configuration register */ +#define LPDTS_SDATA REG32(LPDTS + 0x00000008U) /*!< LPDTS sensor T0 data register */ +#define LPDTS_RDATA REG32(LPDTS + 0x00000010U) /*!< LPDTS ramp data register */ +#define LPDTS_IT REG32(LPDTS + 0x00000014U) /*!< LPDTS interrupt threshold register */ +#define LPDTS_DATA REG32(LPDTS + 0x0000001CU) /*!< LPDTS temperature data register */ +#define LPDTS_STAT REG32(LPDTS + 0x00000020U) /*!< LPDTS temperature sensor status register */ +#define LPDTS_INTEN REG32(LPDTS + 0x00000024U) /*!< LPDTS interrupt enable register */ +#define LPDTS_INTC REG32(LPDTS + 0x00000028U) /*!< LPDTS interrupt clear flag register */ +#define LPDTS_OP REG32(LPDTS + 0x0000002CU) /*!< LPDTS option register */ + +/* bits definitions */ +/* LPDTS_CFG */ +#define LPDTS_CFG_TSEN BIT(0) /*!< temperature sensor enable */ +#define LPDTS_CFG_TRGS BIT(4) /*!< software trigger */ +#define LPDTS_CFG_ITSEL BITS(8,11) /*!< input trigger selection */ +#define LPDTS_CFG_SPT BITS(16,19) /*!< sampling time */ +#define LPDTS_CFG_REFSEL BIT(20) /*!< reference clock selection */ + +/* LPDTS_SDATA */ +#define LPDTS_SDATA_FREQ BITS(0,15) /*!< frequency value at temperature T0 */ +#define LPDTS_SDATA_VAL BITS(16,17) /*!< temperature T0 */ + +/* LPDTS_RDATA */ +#define LPDTS_RDATA_RCVAL BITS(0,15) /*!< ramp coefficient */ + +/* LPDTS_IT */ +#define LPDTS_IT_INTLT BITS(0,15) /*!< interrupt low threshold */ +#define LPDTS_IT_INTHT BITS(16,31) /*!< interrupt high threshold */ + +/* LPDTS_DATA */ +#define LPDTS_DATA_COVAL BITS(0,15) /*!< value of the counter output */ + +/* LPDTS_STAT */ +#define LPDTS_STAT_EMIF BIT(0) /*!< end of measurement interrupt flag */ +#define LPDTS_STAT_LTIF BIT(1) /*!< low threshold interrupt flag */ +#define LPDTS_STAT_HTIF BIT(2) /*!< high threshold interrupt flag */ +#define LPDTS_STAT_EMAIF BIT(4) /*!< end of measurement asynchronous interrupt flag */ +#define LPDTS_STAT_LTAIF BIT(5) /*!< low threshold asynchronous interrupt flag */ +#define LPDTS_STAT_HTAIF BIT(6) /*!< high threshold asynchronous interrupt flag */ +#define LPDTS_STAT_TSRF BIT(15) /*!< temperature sensor ready flag */ + +/* LPDTS_INTEN */ +#define LPDTS_INTEN_EMIE BIT(0) /*!< end of measurement interrupt enable */ +#define LPDTS_INTEN_LTIE BIT(1) /*!< low threshold interrupt enable */ +#define LPDTS_INTEN_HTIE BIT(2) /*!< high threshold interrupt enable */ +#define LPDTS_INTEN_EMAIE BIT(4) /*!< end of measurement asynchronous interrupt enable */ +#define LPDTS_INTEN_LTAIE BIT(5) /*!< low threshold asynchronous interrupt enable */ +#define LPDTS_INTEN_HTAIE BIT(6) /*!< high threshold asynchronous interrupt enable */ + +/* LPDTS_INTC */ +#define LPDTS_INTC_EMIC BIT(0) /*!< end of measurement interrupt clear */ +#define LPDTS_INTC_LTIC BIT(1) /*!< low threshold interrupt clear */ +#define LPDTS_INTC_HTIC BIT(2) /*!< high threshold interrupt clear */ +#define LPDTS_INTC_EMAIC BIT(4) /*!< end of measure asynchronous interrupt clear */ +#define LPDTS_INTC_LTAIC BIT(5) /*!< low threshold asynchronous interrupt clear */ +#define LPDTS_INTC_HTAIC BIT(6) /*!< high threshold asynchronous interrupt clear */ + +/* LPDTS_OP */ +#define LPDTS_OP_OP BITS(0,31) /*!< general purpose option */ + +/* constants definitions */ +/* parameter struct definitions */ +typedef struct { + uint32_t ref_clock; /*!< reference clock selection */ + uint32_t trigger_input; /*!< input trigger selection */ + uint32_t sampling_time; /*!< sampling time */ +} lpdts_parameter_struct; + +/* reference clock definitions */ +#define REF_PCLK ((uint32_t)0x00000000U) /*!< high speed reference clock (PCLK) */ +#define REF_LXTAL LPDTS_CFG_REFSEL /*!< low speed reference clock (LXTAL) */ + +/* input trigger selection definitions */ +#define TRIGGER_SEL(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) +#define NO_HARDWARE_TRIGGER TRIGGER_SEL(0) /*!< no hardware trigger signal */ +#define LPDTS_TRG TRIGGER_SEL(4) /*!< select LPDTS_TRG as trigger signal */ + +/* sampling time definitions */ +#define SMP_TIME(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) +#define SPT_CLOCK_1 SMP_TIME(1) /*!< 1 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_2 SMP_TIME(2) /*!< 2 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_3 SMP_TIME(3) /*!< 3 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_4 SMP_TIME(4) /*!< 4 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_5 SMP_TIME(5) /*!< 5 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_6 SMP_TIME(6) /*!< 6 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_7 SMP_TIME(7) /*!< 7 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_8 SMP_TIME(8) /*!< 8 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_9 SMP_TIME(9) /*!< 9 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_10 SMP_TIME(10) /*!< 10 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_11 SMP_TIME(11) /*!< 11 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_12 SMP_TIME(12) /*!< 12 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_13 SMP_TIME(13) /*!< 13 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_14 SMP_TIME(14) /*!< 14 LXTAL or FM(T) clocks */ +#define SPT_CLOCK_15 SMP_TIME(15) /*!< 15 LXTAL or FM(T) clocks */ + +/* LPDTS flags */ +#define LPDTS_FLAG_TSR LPDTS_STAT_TSRF /*!< temperature sensor ready flag */ +#define LPDTS_INT_FLAG_EM LPDTS_STAT_EMIF /*!< end of measurement interrupt flag */ +#define LPDTS_INT_FLAG_LT LPDTS_STAT_LTIF /*!< low threshold interrupt flag */ +#define LPDTS_INT_FLAG_HT LPDTS_STAT_HTIF /*!< high threshold interrupt flag */ +#define LPDTS_INT_FLAG_EMA LPDTS_STAT_EMAIF /*!< end of measurement asynchronous interrupt flag */ +#define LPDTS_INT_FLAG_LTA LPDTS_STAT_LTAIF /*!< low threshold asynchronous interrupt flag */ +#define LPDTS_INT_FLAG_HTA LPDTS_STAT_HTAIF /*!< high threshold asynchronous interrupt flag */ + +/* LPDTS interrupt enable */ +#define LPDTS_INT_EM LPDTS_INTEN_EMIE /*!< end of measurement interrupt enable */ +#define LPDTS_INT_LT LPDTS_INTEN_LTIE /*!< low threshold interrupt enable */ +#define LPDTS_INT_HT LPDTS_INTEN_HTIE /*!< high threshold interrupt enable */ +#define LPDTS_INT_EMA LPDTS_INTEN_EMAIE /*!< end of measurement asynchronous interrupt enable */ +#define LPDTS_INT_LTA LPDTS_INTEN_LTAIE /*!< low threshold asynchronous interrupt enable */ +#define LPDTS_INT_HTA LPDTS_INTEN_HTAIE /*!< high threshold asynchronous interrupt enable */ + +/* function declarations */ +/* initialization functions */ +/* reset the LPDTS registers */ +void lpdts_deinit(void); +/* initialize the parameters of LPDTS struct with the default values */ +void lpdts_struct_para_init(lpdts_parameter_struct *init_struct); +/* initialize the LPDTS */ +void lpdts_init(lpdts_parameter_struct *init_struct); + +/* configuration functions */ +/* enable LPDTS temperature sensor */ +void lpdts_enable(void); +/* disable LPDTS temperature sensor */ +void lpdts_disable(void); +/* enable LPDTS software trigger */ +void lpdts_soft_trigger_enable(void); +/* disable LPDTS software trigger */ +void lpdts_soft_trigger_disable(void); +/* configure LPDTS high threshold value */ +void lpdts_high_threshold_set(uint16_t value); +/* configure LPDTS low threshold value */ +void lpdts_low_threshold_set(uint16_t value); +/* configure LPDTS reference clock selection */ +void lpdts_ref_clock_source_config(uint32_t source); +/* get temperature from LPDTS */ +int32_t lpdts_temperature_get(void); + +/* flag and interrupt functions */ +/* get LPDTS flag */ +FlagStatus lpdts_flag_get(uint32_t flag); +/* enable LPDTS interrupt */ +void lpdts_interrupt_enable(uint32_t interrupt); +/* disable LPDTS interrupt */ +void lpdts_interrupt_disable(uint32_t interrupt); +/* get LPDTS interrupt flag */ +FlagStatus lpdts_interrupt_flag_get(uint32_t flag); +/* clear the LPDTS interrupt flag */ +void lpdts_interrupt_flag_clear(uint32_t flag); + +#endif /* GD32H7XX_LPDTS_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdio.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdio.h new file mode 100644 index 0000000000..ea3b655c9a --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdio.h @@ -0,0 +1,236 @@ +/*! + \file gd32h7xx_mdio.h + \brief definitions for the MDIO + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_MDIO_H +#define GD32H7XX_MDIO_H + +#include "gd32h7xx.h" + +/* MDIO definitions */ +#define MDIO MDIO_BASE /*!< MDIO base address */ + +/* registers definitions */ +#define MDIO_CTL REG32((MDIO) + 0x00000000U) /*!< MDIO control register */ +#define MDIO_RFRM REG32((MDIO) + 0x00000004U) /*!< MDIO received frame information register */ +#define MDIO_RDATA REG32((MDIO) + 0x00000008U) /*!< MDIO received data register */ +#define MDIO_RADDR REG32((MDIO) + 0x0000000CU) /*!< MDIO received address register */ +#define MDIO_TDATA REG32((MDIO) + 0x00000010U) /*!< MDIO transfer data register */ +#define MDIO_CFG REG32((MDIO) + 0x00000014U) /*!< MDIO configuration register */ +#define MDIO_STAT REG32((MDIO) + 0x00000018U) /*!< MDIO status register */ +#define MDIO_INTEN REG32((MDIO) + 0x0000001CU) /*!< MDIO interrupt enable register */ +#define MDIO_PIN REG32((MDIO) + 0x00000020U) /*!< MDIO pin value register */ +#define MDIO_TO REG32((MDIO) + 0x00000024U) /*!< MDIO timeout register */ + +/* bits definitions */ +/* MDIO_CTL */ +#define MDIO_CTL_SWRST BIT(0) /*!< reset MDIO block */ +#define MDIO_CTL_PHYB BIT(1) /*!< MDIO PHY bit length */ + +/* MDIO_RFRM */ +#define MDIO_RFRM_ROP BITS(0,1) /*!< received frame field OP */ +#define MDIO_RFRM_RPHY BITS(2,6) /*!< received frame field PHYADR */ +#define MDIO_RFRM_RDEV BITS(7,11) /*!< received frame field DEVADD */ +#define MDIO_RFRM_RTA BITS(12,13) /*!< received frame field TA */ + +/* MDIO_RDATA */ +#define MDIO_RDATA_RDATA BITS(0,15) /*!< received frame field DATA */ + +/* MDIO_RADDR */ +#define MDIO_RADDR_RADDR BITS(0,15) /*!< received frame field ADDRESS */ + +/* MDIO_TDATA */ +#define MDIO_TDATA_TDATA BITS(0,15) /*!< data that is transmitted */ + +/* MDIO_CFG */ +#define MDIO_CFG_PHYSW BITS(0,4) /*!< software provided PHYADR */ +#define MDIO_CFG_EPHYSEL BITS(5,9) /*!< selects expected PHYADR */ +#define MDIO_CFG_EDEVADD BITS(10,14) /*!< expected DEVADD */ + +/* MDIO_STAT */ +#define MDIO_STAT_WRFRM BIT(0) /*!< set at end bit of a write data frame if DEVADD and PHYADR both match */ +#define MDIO_STAT_ADDRFRM BIT(1) /*!< set at end bit of an address frame if DEVADD and PHYADR both match */ +#define MDIO_STAT_RDINCFRM BIT(2) /*!< set at end bit of a post read increment address frame if DEVADD and PHYADR both match */ +#define MDIO_STAT_RDFRM BIT(3) /*!< set at end bit of a read data frame if DEVADD and PHYADR both match */ +#define MDIO_STAT_DEVM BIT(4) /*!< set at end bit of DEVADD if DEVADD matches */ +#define MDIO_STAT_DEVNM BIT(5) /*!< set at end bit of DEVADD if DEVADD nonmatches */ +#define MDIO_STAT_PHYM BIT(6) /*!< set at end bit of PHYADR if PHYADR matches */ +#define MDIO_STAT_PHYNM BIT(7) /*!< set at end bit of PHYADR if PHYADR nonmatches */ +#define MDIO_STAT_TANM BIT(8) /*!< set at end bit of TA of a write frame if the received TA nonmatches expected ��10�� */ +#define MDIO_STAT_TO BIT(9) /*!< timeout flag */ +#define MDIO_STAT_UDR BIT(10) /*!< transmit underrun flag */ +#define MDIO_STAT_OVR BIT(11) /*!< receive overrun flag */ +#define MDIO_STAT_RBNE BIT(13) /*!< read data buffer not empty flag */ + +/* MDIO_INTEN */ +#define MDIO_INTEN_WRFRMIE BIT(0) /*!< interrupt requested when WRFRM bit becomes active */ +#define MDIO_INTEN_ADDRFRMIE BIT(1) /*!< interrupt requested when ADDRFRM bit becomes active */ +#define MDIO_INTEN_RDINCFRMIE BIT(2) /*!< interrupt requested when RDINCFRM bit becomes active */ +#define MDIO_INTEN_RDFRMIE BIT(3) /*!< interrupt requested when RDFRM bit becomes active */ +#define MDIO_INTEN_DEVMIE BIT(4) /*!< interrupt requested when DEVM bit becomes active */ +#define MDIO_INTEN_DEVNMIE BIT(5) /*!< interrupt requested when DEVNM bit becomes active */ +#define MDIO_INTEN_PHYMIE BIT(6) /*!< interrupt requested when PHYM bit becomes active */ +#define MDIO_INTEN_PHYNMIE BIT(7) /*!< interrupt requested when PHYNM bit becomes active */ +#define MDIO_INTEN_TANMIE BIT(8) /*!< interrupt requested when TANM bit becomes active */ +#define MDIO_INTEN_TOIE BIT(9) /*!< interrupt requested when TO bit becomes active */ +#define MDIO_INTEN_UDRIE BIT(10) /*!< interrupt requested when UDR bit becomes active */ +#define MDIO_INTEN_OVRIE BIT(11) /*!< interrupt requested when OVR bit becomes active */ +#define MDIO_INTEN_RBNEIE BIT(13) /*!< interrupt requested when RBNE bit becomes active */ + +/* MDIO_PIN */ +#define MDIO_PIN_PHYPIN BITS(0,4) /*!< pin value read from hardware PRTADR[4:0] pins */ + +/* MDIO_TO */ +#define MDIO_TO_TOEN BIT(0) /*!< timeout enable */ +#define MDIO_TO_TOCNT BITS(1,16) /*!< timeout counter */ + +/* constants definitions */ +/* MDIO PHY bit length definitions */ +#define MDIO_PHY_BITS_3 MDIO_CTL_PHYB /*!< MDIO PHY uses 3 bits */ +#define MDIO_PHY_BITS_5 ((uint32_t)0x00000000U) /*!< MDIO PHY uses 5 bits */ + +/* software provided PHYADR configuration definitions */ +#define CFG_PHYSW(regval) (BITS(0,4)&((uint32_t)(regval) << 0U)) + +/* expected PHYADR selection definitions */ +#define CFG_EPHYSEL(regval) (BITS(5,9)&((uint32_t)(regval) << 5U)) +#define MDIO_PHYADR_HARDWARE ((uint32_t)0x00000000U) /*!< sets expected PHYADR = PHYPIN[4:0] */ +#define MDIO_PHYADR_SOFTWARE ((uint32_t)0x0000001FU) /*!< sets expected PHYADR = PHYSW[4:0] */ +#define MDIO_PHYADR_HW_SW_MIX(regval) (BITS(0,4)&((uint32_t)(regval)))/*!< software PHYADR bit select */ + +/* expected DEVADD configuration definitions */ +#define CFG_EDEVADD(regval) (BITS(10,14)&((uint32_t)(regval) << 10U)) + +/* get value of register bit field */ +#define GET_RFRM_ROP(regval) GET_BITS((regval),0,1) /*!< get value of MDIO_RFRM_ROP bit field */ +#define GET_RFRM_RPHY(regval) GET_BITS((regval),2,6) /*!< get value of MDIO_RFRM_RPHY bit field */ +#define GET_RFRM_RDEV(regval) GET_BITS((regval),7,11) /*!< get value of MDIO_RFRM_RDEV bit field */ +#define GET_RFRM_RTA(regval) GET_BITS((regval),12,13) /*!< get value of MDIO_RFRM_RTA bit field */ +#define GET_RDATA_RDATA(regval) GET_BITS((regval),0,15) /*!< get value of MDIO_RDATA_RDATA bit field */ +#define GET_RADDR_RADDR(regval) GET_BITS((regval),0,15) /*!< get value of MDIO_RADDR_RADDR bit field */ +#define GET_PIN_PHYPIN(regval) GET_BITS((regval),0,4) /*!< get value of MDIO_PIN_PHYPIN bit field */ + +/* expected timeout configuration definitions */ +#define TO_TOCNT(regval) (BITS(1,16)&((uint32_t)(regval) << 1U)) + +/* MDIO flag definitions */ +#define MDIO_FLAG_WRFRM MDIO_STAT_WRFRM /*!< a write data frame flag status */ +#define MDIO_FLAG_ADDRFRM MDIO_STAT_ADDRFRM /*!< an address frame flag status */ +#define MDIO_FLAG_RDINCFRM MDIO_STAT_RDINCFRM /*!< a post read increment address frame flag status */ +#define MDIO_FLAG_RDFRM MDIO_STAT_RDFRM /*!< a read data frame flag status */ +#define MDIO_FLAG_DEVM MDIO_STAT_DEVM /*!< a DEVADD match frame flag status */ +#define MDIO_FLAG_DEVNM MDIO_STAT_DEVNM /*!< a DEVADD nonmatch frame flag status */ +#define MDIO_FLAG_PHYM MDIO_STAT_PHYM /*!< a PHYADR match frame flag status */ +#define MDIO_FLAG_PHYNM MDIO_STAT_PHYNM /*!< a PHYADR nonmatch frame flag status */ +#define MDIO_FLAG_TANM MDIO_STAT_TANM /*!< a TA nonmatch frame flag status */ +#define MDIO_FLAG_TIMEOUT MDIO_STAT_TO /*!< timeout flag */ +#define MDIO_FLAG_TX_UNDERRUN MDIO_STAT_UDR /*!< transmit underrun flag */ +#define MDIO_FLAG_RX_OVERRUN MDIO_STAT_OVR /*!< receive overrun flag */ +#define MDIO_FLAG_RBNE MDIO_STAT_RBNE /*!< read data buffer not empty flag */ + +/* MDIO interrupt definitions */ +#define MDIO_INT_WRFRM MDIO_INTEN_WRFRMIE /*!< a write data frame interrupt */ +#define MDIO_INT_ADDRFRM MDIO_INTEN_ADDRFRMIE /*!< an address frame interrupt */ +#define MDIO_INT_RDINCFRM MDIO_INTEN_RDINCFRMIE /*!< a post read increment address frame interrupt */ +#define MDIO_INT_RDFRM MDIO_INTEN_RDFRMIE /*!< a read data frame interrupt */ +#define MDIO_INT_DEVM MDIO_INTEN_DEVMIE /*!< a DEVADD match frame interrupt */ +#define MDIO_INT_DEVNM MDIO_INTEN_DEVNMIE /*!< a DEVADD nonmatch frame interrupt */ +#define MDIO_INT_PHYM MDIO_INTEN_PHYMIE /*!< a PHYADR match frame interrupt */ +#define MDIO_INT_PHYNM MDIO_INTEN_PHYNMIE /*!< a PHYADR nonmatch frame interrupt */ +#define MDIO_INT_TANM MDIO_INTEN_TANMIE /*!< a TA nonmatch frame interrupt */ +#define MDIO_INT_TIMEOUT MDIO_INTEN_TOIE /*!< a timeout interrupt */ +#define MDIO_INT_TX_UNDERRUN MDIO_INTEN_UDRIE /*!< a transmit underrun interrupt */ +#define MDIO_INT_RX_OVERRUN MDIO_INTEN_OVRIE /*!< a receive overrun interrupt */ +#define MDIO_INT_RBNE MDIO_INTEN_RBNEIE /*!< a read data buffer not empty interrupt */ + +/* device type definitions */ +#define DEVADD_PMA_PMD ((uint16_t)0x0001U) /*!< device type PMA/PMD */ +#define DEVADD_WIS ((uint16_t)0x0002U) /*!< device type WIS */ +#define DEVADD_PCS ((uint16_t)0x0003U) /*!< device type PCS */ +#define DEVADD_PHY_XS ((uint16_t)0x0004U) /*!< device type PHY XS */ +#define DEVADD_DTE_XS ((uint16_t)0x0005U) /*!< device type DTE XS */ + +/* function declarations */ +/* reset functions */ +/* reset MDIO */ +void mdio_deinit(void); +/* reset MDIO block */ +void mdio_software_reset(void); + +/* fuction configuration */ +/* initialize MDIO for communication */ +uint32_t mdio_init(uint32_t phy_size, uint32_t phy_softaddr, uint32_t phy_sel, uint16_t devadd); +/* configure MDIO phy bit length */ +void mdio_phy_length_config(uint32_t phy_bit); +/* set the software PHYADR value */ +void mdio_soft_phyadr_set(uint32_t phy_soft); +/* select the expected frame field PHYADR */ +void mdio_framefield_phyadr_config(uint32_t phy_sel); +/* configure the expected frame field DEVADD */ +void mdio_framefield_devadd_config(uint16_t type); +/* read the hardware PRTADR[4:0] value */ +uint32_t mdio_phy_pin_read(void); +/* configure the expected frame bit timeout */ +void mdio_timeout_config(uint16_t timeout); +/* enable MDIO frame bit timeout */ +void mdio_timeout_enable(void); +/* disable MDIO frame bit timeout */ +void mdio_timeout_disable(void); + +/* rx & tx functions */ +/* read the received frame field OP */ +uint16_t mdio_op_receive(void); +/* read the received frame field PHYADR */ +uint16_t mdio_phyadr_receive(void); +/* read the received frame field DEVADD */ +uint16_t mdio_devadd_receive(void); +/* read the received frame field TA */ +uint16_t mdio_ta_receive(void); +/* read the received frame field DATA */ +uint16_t mdio_data_receive(void); +/* read the received frame field ADDRESS */ +uint16_t mdio_address_receive(void); +/* transmit the frame field DATA */ +void mdio_data_transmit(uint16_t data); + +/* interrupt & flag functions */ +/* get the flag status of the frame */ +FlagStatus mdio_flag_get(uint32_t flag); +/* clear MDIO flag status */ +void mdio_flag_clear(uint32_t flag); +/* enable MDIO interrupt */ +void mdio_interrupt_enable(uint32_t interrupt); +/* disable MDIO interrupt */ +void mdio_interrupt_disable(uint32_t interrupt); + +#endif /* GD32H7XX_MDIO_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdma.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdma.h new file mode 100644 index 0000000000..6173468583 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_mdma.h @@ -0,0 +1,480 @@ +/*! + \file gd32h7xx_mdma.h + \brief definitions for the MDMA + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_MDMA_H +#define GD32H7XX_MDMA_H + +#include "gd32h7xx.h" + +/* MDMA definitions */ +#define MDMA (MDMA_BASE) /*!< MDMA base address */ + +/* registers definitions */ +#define MDMA_GINTF REG32(MDMA + 0x00000000U) /*!< MDMA global interrupt flag register */ + +#define MDMA_CHXSTAT0(mdma_chx) REG32(MDMA + 0x00000040U + (0x40U * (mdma_chx))) /*!< MDMA channel x status register 0 */ +#define MDMA_CHXSTATC(mdma_chx) REG32(MDMA + 0x00000044U + (0x40U * (mdma_chx))) /*!< MDMA channel x status clear register */ +#define MDMA_CHXSTAT1(mdma_chx) REG32(MDMA + 0x00000048U + (0x40U * (mdma_chx))) /*!< MDMA channel x status register 1*/ +#define MDMA_CHXCTL0(mdma_chx) REG32(MDMA + 0x0000004CU + (0x40U * (mdma_chx))) /*!< MDMA channel x control register 0 */ +#define MDMA_CHXCFG(mdma_chx) REG32(MDMA + 0x00000050U + (0x40U * (mdma_chx))) /*!< MDMA channel x configure register */ +#define MDMA_CHXBTCFG(mdma_chx) REG32(MDMA + 0x00000054U + (0x40U * (mdma_chx))) /*!< MDMA channel x block transfer configure register */ +#define MDMA_CHXSADDR(mdma_chx) REG32(MDMA + 0x00000058U + (0x40U * (mdma_chx))) /*!< MDMA channel x source address register */ +#define MDMA_CHXDADDR(mdma_chx) REG32(MDMA + 0x0000005CU + (0x40U * (mdma_chx))) /*!< MDMA channel x destination address register */ +#define MDMA_CHXMBADDRU(mdma_chx) REG32(MDMA + 0x00000060U + (0x40U * (mdma_chx))) /*!< MDMA channel x multi-block address update register */ +#define MDMA_CHXLADDR(mdma_chx) REG32(MDMA + 0x00000064U + (0x40U * (mdma_chx))) /*!< MDMA channel x link address register */ +#define MDMA_CHXCTL1(mdma_chx) REG32(MDMA + 0x00000068U + (0x40U * (mdma_chx))) /*!< MDMA channel x control register 1 */ +#define MDMA_CHXMADDR(mdma_chx) REG32(MDMA + 0x00000070U + (0x40U * (mdma_chx))) /*!< MDMA channel x mask address register */ +#define MDMA_CHXMDATA(mdma_chx) REG32(MDMA + 0x00000074U + (0x40U * (mdma_chx))) /*!< MDMA channel x mask data register */ + +/* bits definitions */ +/* MDMA_GINTF */ +#define MDMA_GINTF_GIF0 BIT(0) /*!< global interrupt flag of channel 0 */ +#define MDMA_GINTF_GIF1 BIT(1) /*!< global interrupt flag of channel 1 */ +#define MDMA_GINTF_GIF2 BIT(2) /*!< global interrupt flag of channel 2 */ +#define MDMA_GINTF_GIF3 BIT(3) /*!< global interrupt flag of channel 3 */ +#define MDMA_GINTF_GIF4 BIT(4) /*!< global interrupt flag of channel 4 */ +#define MDMA_GINTF_GIF5 BIT(5) /*!< global interrupt flag of channel 5 */ +#define MDMA_GINTF_GIF6 BIT(6) /*!< global interrupt flag of channel 6 */ +#define MDMA_GINTF_GIF7 BIT(7) /*!< global interrupt flag of channel 7 */ +#define MDMA_GINTF_GIF8 BIT(8) /*!< global interrupt flag of channel 8 */ +#define MDMA_GINTF_GIF9 BIT(9) /*!< global interrupt flag of channel 9 */ +#define MDMA_GINTF_GIF10 BIT(10) /*!< global interrupt flag of channel 10 */ +#define MDMA_GINTF_GIF11 BIT(11) /*!< global interrupt flag of channel 11 */ +#define MDMA_GINTF_GIF12 BIT(12) /*!< global interrupt flag of channel 12 */ +#define MDMA_GINTF_GIF13 BIT(13) /*!< global interrupt flag of channel 13 */ +#define MDMA_GINTF_GIF14 BIT(14) /*!< global interrupt flag of channel 14 */ +#define MDMA_GINTF_GIF15 BIT(15) /*!< global interrupt flag of channel 15 */ + +/* MDMA_CHxSTAT0,x=0..15 */ +#define MDMA_CHXSTAT0_ERR BIT(0) /*!< channel x transfer error flag */ +#define MDMA_CHXSTAT0_CHTCF BIT(1) /*!< channel x channel transfer complete flag */ +#define MDMA_CHXSTAT0_MBTCF BIT(2) /*!< channel x multi-block transfer complete flag */ +#define MDMA_CHXSTAT0_BTCF BIT(3) /*!< channel x block transfer complete flag */ +#define MDMA_CHXSTAT0_TCF BIT(4) /*!< channel x buffer transfer complete flag */ +#define MDMA_CHXSTAT0_REQAF BIT(16) /*!< channel x request active flag */ + +/* MDMA_CHxSTATC,x=0..15 */ +#define MDMA_CHXSTATC_ERRC BIT(0) /*!< channel x transfer error flag clear */ +#define MDMA_CHXSTATC_CHTCFC BIT(1) /*!< channel x channel transfer complete flag clear */ +#define MDMA_CHXSTATC_MBTCFC BIT(2) /*!< channel x multi-block transfer complete flag clear */ +#define MDMA_CHXSTATC_BTCFC BIT(3) /*!< channel x block transfer complete flag clear */ +#define MDMA_CHXSTATC_TCFC BIT(4) /*!< channel x buffer transfer complete flag clear */ + +/* MDMA_CHxSTAT1,x=0..15 */ +#define MDMA_CHXSTAT1_ERRADDR BITS(0,6) /*!< transfer error address */ +#define MDMA_CHXSTAT1_TERRD BIT(7) /*!< transfer error direction */ +#define MDMA_CHXSTAT1_LDTERR BIT(8) /*!< link data transfer error flag in the last transfer of the channel */ +#define MDMA_CHXSTAT1_MDTERR BIT(9) /*!< mask data error flag */ +#define MDMA_CHXSTAT1_ASERR BIT(10) /*!< address and size error flag */ +#define MDMA_CHXSTAT1_BZERR BIT(11) /*!< block size error flag */ + +/* MDMA_CHxCTL0,x=0..15 */ +#define MDMA_CHXCTL0_CHEN BIT(0) /*!< channel enable */ +#define MDMA_CHXCTL0_ERRIE BIT(1) /*!< transfer error interrupt enable */ +#define MDMA_CHXCTL0_CHTCIE BIT(2) /*!< channel transfer complete interrupt enable */ +#define MDMA_CHXCTL0_MBTCIE BIT(3) /*!< multi-block transfer complete interrupt enable */ +#define MDMA_CHXCTL0_BTCIE BIT(4) /*!< block transfer complete interrupt enable */ +#define MDMA_CHXCTL0_TCIE BIT(5) /*!< buffer transfer complete interrupt enable */ +#define MDMA_CHXCTL0_PRIO BITS(6,7) /*!< priority level */ +#define MDMA_CHXCTL0_SMODEN BIT(8) /*!< secure mode enable */ +#define MDMA_CHXCTL0_BES BIT(12) /*!< byte endianess swapping in half word */ +#define MDMA_CHXCTL0_HWES BIT(13) /*!< half word endianess swapping in word */ +#define MDMA_CHXCTL0_WES BIT(14) /*!< word endianess swapping in double word */ +#define MDMA_CHXCTL0_SWREQ BIT(16) /*!< software request */ + +/* MDMA_CHxCFG,x=0..15 */ +#define MDMA_CHXCFG_SIMOD BITS(0,1) /*!< source increment mode */ +#define MDMA_CHXCFG_DIMOD BITS(2,3) /*!< destination increment mode */ +#define MDMA_CHXCFG_SWIDTH BITS(4,5) /*!< data size of source */ +#define MDMA_CHXCFG_DWIDTH BITS(6,7) /*!< data size of destination */ +#define MDMA_CHXCFG_SIOS BITS(8,9) /*!< offset size of source increment */ +#define MDMA_CHXCFG_DIOS BITS(10,11) /*!< offset size of destination increment */ +#define MDMA_CHXCFG_SBURST BITS(12,14) /*!< transfer burst type of source */ +#define MDMA_CHXCFG_DBURST BITS(15,17) /*!< transfer burst type of destination */ +#define MDMA_CHXCFG_BTLEN BITS(18,24) /*!< buffer transfer length */ +#define MDMA_CHXCFG_PKEN BIT(25) /*!< pack enable */ +#define MDMA_CHXCFG_PAMOD BITS(26,27) /*!< padding and alignement mode */ +#define MDMA_CHXCFG_TRIGMOD BITS(28,29) /*!< trigger mode */ +#define MDMA_CHXCFG_SWREQMOD BIT(30) /*!< software request mode */ +#define MDMA_CHXCFG_BWMOD BIT(31) /*!< bufferable write mode */ + +/* MDMA_CHxBTCFG,x=0..15 */ +#define MDMA_CHXBTCFG_TBNUM BITS(0,16) /*!< transfer byte number in block */ +#define MDMA_CHXBTCFG_SADDRUM BIT(18) /*!< multi-block source address update mode */ +#define MDMA_CHXBTCFG_DADDRUM BIT(19) /*!< multi-block destination address update mode */ +#define MDMA_CHXBTCFG_BRNUM BITS(20,31) /*!< multi-block number */ + +/* MDMA_CHxSADDR,x=0..15 */ +#define MDMA_CHXSADDR_SADDR BITS(0,31) /*!< source address */ + +/* MDMA_CHxDADDR,x=0..15 */ +#define MDMA_CHXDADDR_DADDR BITS(0,31) /*!< destination address */ + +/* MDMA_CHxMBADDRU,x=0..15 */ +#define MDMA_CHXMBADDRU_SADDRUV BITS(0,15) /*!< source address update value */ +#define MDMA_CHXMBADDRU_DADDRUV BITS(16,31) /*!< destination address update value */ + +/* MDMA_CHxLADDR,x=0..15 */ +#define MDMA_CHXLADDR_LADDR BITS(0,31) /*!< link address */ + +/* MDMA_CHxCTL1,x=0..15 */ +#define MDMA_CHXCTL1_TRIGSEL BITS(0,5) /*!< trigger select */ +#define MDMA_CHXCTL1_SBSEL BIT(16) /*!< source bus select */ +#define MDMA_CHXCTL1_DBSEL BIT(17) /*!< destination bus select */ + +/* MDMA_CHxMADDR,x=0..15 */ +#define MDMA_CHXMADDR_MADDR BITS(0,31) /*!< mask address */ + +/* MDMA_CHxMDATA,x=0..15 */ +#define MDMA_CHXMDATA_MDATA BITS(0,31) /*!< mask data */ + +/* constants definitions */ +/* MDMA configuration structure definition */ +typedef struct { + uint32_t request; /*!< specifies the MDMA request */ + uint32_t trans_trig_mode; /*!< specifies the trigger transfer mode */ + uint32_t priority; /*!< specifies the software priority for the MDMA channelx */ + uint32_t endianness; /*!< specifies if the MDMA transactions preserve the little endianness */ + uint32_t source_inc; /*!< specifies the source increment mode */ + uint32_t dest_inc; /*!< specifies the destination increment mode */ + uint32_t source_data_size; /*!< specifies the source data size */ + uint32_t dest_data_dize; /*!< specifies the destination data size */ + uint32_t data_alignment; /*!< specifies the source to destination memory data packing/padding mode */ + uint32_t buff_trans_len; /*!< specifies the buffer transfer length (number of bytes) */ + uint32_t source_burst; /*!< specifies the burst transfer configuration for the source memory transfers */ + uint32_t dest_burst; /*!< specifies the burst transfer configuration for the destination memory transfers */ + uint32_t mask_addr; /*!< mask address */ + uint32_t mask_data; /*!< mask data */ + uint32_t source_addr; /*!< specifies the source address */ + uint32_t destination_addr; /*!< specifies the destination address */ + uint32_t tbytes_num_in_block; /*!< specifies the transfer bytes number in a buffer or block transfer */ + uint32_t source_bus; /*!< specifies the source bus */ + uint32_t destination_bus; /*!< specifies the destination bus */ + uint32_t bufferable_write_mode; /*!< specifies the bufferable write mode */ +} mdma_parameter_struct; + +/* MDMA address update direction */ +typedef enum { + UPDATE_DIR_INCREASE = 0, /*!< MDMA address update increase */ + UPDATE_DIR_DECREASE = 1, /*!< MDMA address update decrease */ +} mdma_add_update_dir_enum; + +/* MDMA multi block transfer configuration structure definition */ +typedef struct { + uint32_t block_num; /*!< multi-block number */ + uint16_t saddr_update_val; /*!< source address update value */ + uint16_t dstaddr_update_val; /*!< destination address update value */ + mdma_add_update_dir_enum saddr_update_dir; /*!< source address update direction */ + mdma_add_update_dir_enum dstaddr_update_dir; /*!< destination address update direction */ +} mdma_multi_block_parameter_struct; + +/* MDMA link node configuration structure definition */ +typedef struct { + __IO uint32_t chxcfg_reg; /*!< channel x configure register */ + __IO uint32_t chxbtcfg_reg; /*!< channel x block transfer configure register */ + __IO uint32_t chxsaddr_reg; /*!< channel x source address register */ + __IO uint32_t chxdaddr_reg; /*!< channel x destination address register */ + __IO uint32_t chxmbaddru_reg; /*!< channel x multi-block address update register */ + __IO uint32_t chxladdr_reg; /*!< channel x link address register */ + __IO uint32_t chxctl1_reg; /*!< channel x control register 1 */ + __IO uint32_t reserved; /*!< channel x reserved register */ + __IO uint32_t chxmaddr_reg; /*!< channel x mask address register */ + __IO uint32_t chxmdata_reg; /*!< channel x mask data register */ +} mdma_link_node_parameter_struct; + +/* MDMA channel select */ +typedef enum { + MDMA_CH0 = 0, /*!< MDMA channel 0 */ + MDMA_CH1, /*!< MDMA channel 1 */ + MDMA_CH2, /*!< MDMA channel 2 */ + MDMA_CH3, /*!< MDMA channel 3 */ + MDMA_CH4, /*!< MDMA channel 4 */ + MDMA_CH5, /*!< MDMA channel 5 */ + MDMA_CH6, /*!< MDMA channel 6 */ + MDMA_CH7, /*!< MDMA channel 7 */ + MDMA_CH8, /*!< MDMA channel 8 */ + MDMA_CH9, /*!< MDMA channel 9 */ + MDMA_CH10, /*!< MDMA channel 10 */ + MDMA_CH11, /*!< MDMA channel 11 */ + MDMA_CH12, /*!< MDMA channel 12 */ + MDMA_CH13, /*!< MDMA channel 13 */ + MDMA_CH14, /*!< MDMA channel 14 */ + MDMA_CH15 /*!< MDMA channel 15 */ +} mdma_channel_enum; + +/* MDMA request selection */ +#define CHXCTL1_TRIGSEL(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< trigger select */ +#define MDMA_REQUEST_DMA0_CH0_FTFIF CHXCTL1_TRIGSEL(0) /*!< MDMA hardware request is DMA0 channel 0 transfer complete flag */ +#define MDMA_REQUEST_DMA0_CH1_FTFIF CHXCTL1_TRIGSEL(1) /*!< MDMA hardware request is DMA0 channel 1 transfer complete flag */ +#define MDMA_REQUEST_DMA0_CH2_FTFIF CHXCTL1_TRIGSEL(2) /*!< MDMA hardware request is DMA0 channel 2 transfer complete flag */ +#define MDMA_REQUEST_DMA0_CH3_FTFIF CHXCTL1_TRIGSEL(3) /*!< MDMA hardware request is DMA0 channel 3 transfer complete flag */ +#define MDMA_REQUEST_DMA0_CH4_FTFIF CHXCTL1_TRIGSEL(4) /*!< MDMA hardware request is DMA0 channel 4 transfer complete flag */ +#define MDMA_REQUEST_DMA0_CH5_FTFIF CHXCTL1_TRIGSEL(5) /*!< MDMA hardware request is DMA0 channel 5 transfer complete flag */ +#define MDMA_REQUEST_DMA0_CH6_FTFIF CHXCTL1_TRIGSEL(6) /*!< MDMA hardware request is DMA0 channel 6 transfer complete flag */ +#define MDMA_REQUEST_DMA0_CH7_FTFIF CHXCTL1_TRIGSEL(7) /*!< MDMA hardware request is DMA0 channel 7 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH0_FTFIF CHXCTL1_TRIGSEL(8) /*!< MDMA hardware request is DMA1 channel 0 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH1_FTFIF CHXCTL1_TRIGSEL(9) /*!< MDMA hardware request is DMA1 channel 1 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH2_FTFIF CHXCTL1_TRIGSEL(10) /*!< MDMA hardware request is DMA1 channel 2 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH3_FTFIF CHXCTL1_TRIGSEL(11) /*!< MDMA hardware request is DMA1 channel 3 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH4_FTFIF CHXCTL1_TRIGSEL(12) /*!< MDMA hardware request is DMA1 channel 4 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH5_FTFIF CHXCTL1_TRIGSEL(13) /*!< MDMA hardware request is DMA1 channel 5 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH6_FTFIF CHXCTL1_TRIGSEL(14) /*!< MDMA hardware request is DMA1 channel 6 transfer complete flag */ +#define MDMA_REQUEST_DMA1_CH7_FTFIF CHXCTL1_TRIGSEL(15) /*!< MDMA hardware request is DMA1 channel 7 transfer complete flag */ +#define MDMA_REQUEST_TLI_INT CHXCTL1_TRIGSEL(16) /*!< MDMA hardware request is TLI interrupt flag */ +#define MDMA_REQUEST_OSPI0_FT CHXCTL1_TRIGSEL(22) /*!< MDMA hardware request is OSPI0_FT */ +#define MDMA_REQUEST_OSPI0_TC CHXCTL1_TRIGSEL(23) /*!< MDMA hardware request is OSPI0_TC */ +#define MDMA_REQUEST_IPA_CLUT_TRIG CHXCTL1_TRIGSEL(24) /*!< MDMA hardware request is IPA_CLUT_TRIG */ +#define MDMA_REQUEST_IPA_TC_TRIG CHXCTL1_TRIGSEL(25) /*!< MDMA hardware request is IPA_TC_TRIG */ +#define MDMA_REQUEST_IPA_TWM_TRIG CHXCTL1_TRIGSEL(26) /*!< MDMA hardware request is IPA_TWM_TRIG */ +#define MDMA_REQUEST_SDIO0_DATA_END CHXCTL1_TRIGSEL(29) /*!< MDMA hardware request is SDIO0_DATA_END signal */ +#define MDMA_REQUEST_SDIO0_BUF_END CHXCTL1_TRIGSEL(30) /*!< MDMA hardware request is SDIO0_BUF_END signal */ +#define MDMA_REQUEST_SDIO0_CMD_END CHXCTL1_TRIGSEL(31) /*!< MDMA hardware request is SDIO0_CMD_END signal */ +#define MDMA_REQUEST_OSPI1_FT CHXCTL1_TRIGSEL(32) /*!< MDMA hardware request is OSPI1_FT */ +#define MDMA_REQUEST_OSPI1_TC CHXCTL1_TRIGSEL(33) /*!< MDMA hardware request is OSPI1_TC */ +#define MDMA_REQUEST_SW ((uint32_t)0x40000000U) /*!< MDMA software request */ + +/* MDMA transfer trigger mode */ +#define CHCFG_TRIGMOD(regval) (BITS(28,29) & ((uint32_t)(regval) << 28U)) /*!< trigger mode */ +#define MDMA_BUFFER_TRANSFER CHCFG_TRIGMOD(0) /*!< software request or hardware request triggers a buffer transfer */ +#define MDMA_BLOCK_TRANSFER CHCFG_TRIGMOD(1) /*!< software request or hardware request triggers a block transfer */ +#define MDMA_MULTI_BLOCK_TRANSFER CHCFG_TRIGMOD(2) /*!< software request or hardware request triggers a multi-block transfer */ +#define MDMA_COMPLETE_TRANSFER CHCFG_TRIGMOD(3) /*!< software request or hardware request triggers a complete data transfer (for example, link mode) */ + +/* channel priority level */ +#define CHCTL0_PRIO(regval) (BITS(6,7) & ((uint32_t)(regval) << 6U)) +#define MDMA_PRIORITY_LOW CHCTL0_PRIO(0) /*!< priority level: low */ +#define MDMA_PRIORITY_MEDIUM CHCTL0_PRIO(1) /*!< priority level: medium */ +#define MDMA_PRIORITY_HIGH CHCTL0_PRIO(2) /*!< priority level: high */ +#define MDMA_PRIORITY_ULTRA_HIGH CHCTL0_PRIO(3) /*!< priority level: very high */ + +/* MDMA endianness */ +#define MDMA_LITTLE_ENDIANNESS ((uint32_t)0x00000000U) /*!< little endianness preserve */ +#define MDMA_BYTE_ENDIANNESS_EXCHANGE ((uint32_t)MDMA_CHXCTL0_BES) /*!< exchange the order of the bytes in a half-word */ +#define MDMA_HALFWORD_ENDIANNESS_EXCHANGE ((uint32_t)MDMA_CHXCTL0_HWES) /*!< exchange the order of the half-words in a word */ +#define MDMA_WORD_ENDIANNESS_EXCHANGE ((uint32_t)MDMA_CHXCTL0_WES) /*!< exchange the order of the words in a double word */ + +/* MDMA source adress increment mode */ +#define CHCFG_SIMOD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) /*!< source increment mode */ +#define CHCFG_SIOS(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) /*!< offset size of source increment */ +#define MDMA_SOURCE_INCREASE_DISABLE CHCFG_SIMOD(0) /*!< no increment */ +#define MDMA_SOURCE_INCREASE_8BIT (CHCFG_SIMOD(2) | CHCFG_SIOS(0)) /*!< source address pointer is incremented by a byte (8 bits) */ +#define MDMA_SOURCE_INCREASE_16BIT (CHCFG_SIMOD(2) | CHCFG_SIOS(1)) /*!< source address pointer is incremented by a half word (16 bits) */ +#define MDMA_SOURCE_INCREASE_32BIT (CHCFG_SIMOD(2) | CHCFG_SIOS(2)) /*!< source address pointer is incremented by a word (32 bits) */ +#define MDMA_SOURCE_INCREASE_64BIT (CHCFG_SIMOD(2) | CHCFG_SIOS(3)) /*!< source address pointer is incremented by a double word (64 bits) */ +#define MDMA_SOURCE_DECREASE_8BIT (CHCFG_SIMOD(3) | CHCFG_SIOS(0)) /*!< source address pointer is decremented by a byte (8 bits) */ +#define MDMA_SOURCE_DECREASE_16BIT (CHCFG_SIMOD(3) | CHCFG_SIOS(1)) /*!< source address pointer is decremented by a half word (16 bits) */ +#define MDMA_SOURCE_DECREASE_32BIT (CHCFG_SIMOD(3) | CHCFG_SIOS(2)) /*!< source address pointer is decremented by a word (32 bits) */ +#define MDMA_SOURCE_DECREASE_64BIT (CHCFG_SIMOD(3) | CHCFG_SIOS(3)) /*!< source address pointer is decremented by a double word (64 bits) */ + +/* MDMA destination adress increment mode*/ +#define CHCFG_DIMOD(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) /*!< destination increment mode */ +#define CHCFG_DIOS(regval) (BITS(10,11) & ((uint32_t)(regval) << 10U)) /*!< offset size of destination increment */ +#define MDMA_DESTINATION_INCREASE_DISABLE CHCFG_DIMOD(0) /*!< no increment */ +#define MDMA_DESTINATION_INCREASE_8BIT (CHCFG_DIMOD(2) | CHCFG_DIOS(0)) /*!< destination address pointer is incremented by a byte (8 bits) */ +#define MDMA_DESTINATION_INCREASE_16BIT (CHCFG_DIMOD(2) | CHCFG_DIOS(1)) /*!< destination address pointer is incremented by a half word (16 bits) */ +#define MDMA_DESTINATION_INCREASE_32BIT (CHCFG_DIMOD(2) | CHCFG_DIOS(2)) /*!< destination address pointer is incremented by a word (32 bits) */ +#define MDMA_DESTINATION_INCREASE_64BIT (CHCFG_DIMOD(2) | CHCFG_DIOS(3)) /*!< destination address pointer is incremented by a double word (64 bits) */ +#define MDMA_DESTINATION_DECREASE_8BIT (CHCFG_DIMOD(3) | CHCFG_DIOS(0)) /*!< destination address pointer is decremented by a byte (8 bits) */ +#define MDMA_DESTINATION_DECREASE_16BIT (CHCFG_DIMOD(3) | CHCFG_DIOS(1)) /*!< destination address pointer is decremented by a half word (16 bits) */ +#define MDMA_DESTINATION_DECREASE_32BIT (CHCFG_DIMOD(3) | CHCFG_DIOS(2)) /*!< destination address pointer is decremented by a word (32 bits) */ +#define MDMA_DESTINATION_DECREASE_64BIT (CHCFG_DIMOD(3) | CHCFG_DIOS(3)) /*!< destination address pointer is decremented by a double word (64 bits) */ + +/* MDMA source data size */ +#define CHCFG_SWIDTH(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) /*!< data size of source */ +#define MDMA_SOURCE_DATASIZE_8BIT CHCFG_SWIDTH(0) /*!< source data size is byte */ +#define MDMA_SOURCE_DATASIZE_16BIT CHCFG_SWIDTH(1) /*!< source data size is half word */ +#define MDMA_SOURCE_DATASIZE_32BIT CHCFG_SWIDTH(2) /*!< source data size is word */ +#define MDMA_SOURCE_DATASIZE_64BIT CHCFG_SWIDTH(3) /*!< source data size is double word */ + +/* MDMA destination data size */ +#define CHCFG_DWIDTH(regval) (BITS(6,7) & ((uint32_t)(regval) << 6U)) /*!< data size of destination */ +#define MDMA_DESTINATION_DATASIZE_8BIT CHCFG_DWIDTH(0) /*!< destination data size is byte */ +#define MDMA_DESTINATION_DATASIZE_16BIT CHCFG_DWIDTH(1) /*!< destination data size is half word */ +#define MDMA_DESTINATION_DATASIZE_32BIT CHCFG_DWIDTH(2) /*!< destination data size is word */ +#define MDMA_DESTINATION_DATASIZE_64BIT CHCFG_DWIDTH(3) /*!< destination data size is double word */ + +/* MDMA data alignment */ +#define CHCFG_PAMOD(regval) (BITS(26,27) & ((uint32_t)(regval) << 26U)) /*!< padding and alignement mode */ +#define MDMA_DATAALIGN_PKEN ((uint32_t)MDMA_CHXCFG_PKEN) /*!< pack/unpack the source data to match the destination data size */ +#define MDMA_DATAALIGN_RIGHT CHCFG_PAMOD(0) /*!< right aligned, padded with 0s (default) */ +#define MDMA_DATAALIGN_RIGHT_SIGNED CHCFG_PAMOD(1) /*!< right aligned with sign extended, note: this mode is allowed only if the source data size is smaller than destination data size */ +#define MDMA_DATAALIGN_LEFT CHCFG_PAMOD(2) /*!< left aligned, padded with 0s in low bytes position when source data size smaller than destination data size, and only high byte of source is written when source data size larger than destination data size */ + +/* MDMA source burst */ +#define CHCFG_SBURST(regval) (BITS(12,14) & ((uint32_t)(regval) << 12U)) /*!< transfer burst type of source */ +#define MDMA_SOURCE_BURST_SINGLE CHCFG_SBURST(0) /*!< single transfer */ +#define MDMA_SOURCE_BURST_2BEATS CHCFG_SBURST(1) /*!< burst 2 beats */ +#define MDMA_SOURCE_BURST_4BEATS CHCFG_SBURST(2) /*!< burst 4 beats */ +#define MDMA_SOURCE_BURST_8BEATS CHCFG_SBURST(3) /*!< burst 8 beats */ +#define MDMA_SOURCE_BURST_16BEATS CHCFG_SBURST(4) /*!< burst 16 beats */ +#define MDMA_SOURCE_BURST_32BEATS CHCFG_SBURST(5) /*!< burst 32 beats */ +#define MDMA_SOURCE_BURST_64BEATS CHCFG_SBURST(6) /*!< burst 64 beats */ +#define MDMA_SOURCE_BURST_128BEATS CHCFG_SBURST(7) /*!< burst 128 beats */ + +/* MDMA destination burst */ +#define CHCFG_DBURST(regval) (BITS(15,17) & ((uint32_t)(regval) << 15U)) /*!< transfer burst type of destination */ +#define MDMA_DESTINATION_BURST_SINGLE CHCFG_DBURST(0) /*!< single transfer */ +#define MDMA_DESTINATION_BURST_2BEATS CHCFG_DBURST(1) /*!< burst 2 beats */ +#define MDMA_DESTINATION_BURST_4BEATS CHCFG_DBURST(2) /*!< burst 4 beats */ +#define MDMA_DESTINATION_BURST_8BEATS CHCFG_DBURST(3) /*!< burst 8 beats */ +#define MDMA_DESTINATION_BURST_16BEATS CHCFG_DBURST(4) /*!< burst 16 beats */ +#define MDMA_DESTINATION_BURST_32BEATS CHCFG_DBURST(5) /*!< burst 32 beats */ +#define MDMA_DESTINATION_BURST_64BEATS CHCFG_DBURST(6) /*!< burst 64 beats */ +#define MDMA_DESTINATION_BURST_128BEATS CHCFG_DBURST(7) /*!< burst 128 beats */ + +/* source bus select */ +#define MDMA_SOURCE_AXI ((uint32_t)0x00000000U) /*!< source bus of channel x is the system bus or AXI bus */ +#define MDMA_SOURCE_AHB_TCM MDMA_CHXCTL1_SBSEL /*!< source bus of channel x is AHB bus or TCM */ + +/* destination bus select */ +#define MDMA_DESTINATION_AXI ((uint32_t)0x00000000U) /*!< destination bus of channel x is the system bus or AXI bus */ +#define MDMA_DESTINATION_AHB_TCM MDMA_CHXCTL1_DBSEL /*!< destination bus of channel x is AHB bus or TCM */ + +/* MDMA access error direction */ +#define MDMA_READ_ERROR ((uint32_t)0x00000000U) /*!< read access error */ +#define MDMA_WRITE_ERROR MDMA_CHXSTAT1_TERRD /*!< write access error */ + +/* MDMA bufferable write mode */ +#define MDMA_BUFFERABLE_WRITE_DISABLE ((uint32_t)0x00000000U) /*!< diable bufferable write mode */ +#define MDMA_BUFFERABLE_WRITE_ENABLE MDMA_CHXCFG_BWMOD /*!< enable bufferable write mode */ + +/* MDMA flags */ +#define STAT1_FLAG BIT(31) /*!< flag to indicate that flag is in STAT1 register */ +#define MDMA_FLAG_ERR MDMA_CHXSTAT0_ERR /*!< channel x transfer error flag */ +#define MDMA_FLAG_CHTCF MDMA_CHXSTAT0_CHTCF /*!< channel x channel transfer complete flag */ +#define MDMA_FLAG_MBTCF MDMA_CHXSTAT0_MBTCF /*!< channel x multi-block transfer complete flag */ +#define MDMA_FLAG_BTCF MDMA_CHXSTAT0_BTCF /*!< channel x block transfer complete flag */ +#define MDMA_FLAG_TCF MDMA_CHXSTAT0_TCF /*!< channel x buffer transfer complete flag */ +#define MDMA_FLAG_REQAF MDMA_CHXSTAT0_REQAF /*!< channel x request active flag */ +#define MDMA_FLAG_LDTERR (MDMA_CHXSTAT1_LDTERR | STAT1_FLAG) /*!< link data transfer error flag in the last transfer of the channel */ +#define MDMA_FLAG_MDTERR (MDMA_CHXSTAT1_MDTERR | STAT1_FLAG) /*!< mask data error flag */ +#define MDMA_FLAG_ASERR (MDMA_CHXSTAT1_ASERR | STAT1_FLAG) /*!< address and size error flag */ +#define MDMA_FLAG_BZERR (MDMA_CHXSTAT1_BZERR | STAT1_FLAG) /*!< block size error flag */ + +/* MDMA interrupt */ +#define MDMA_INT_ERR MDMA_CHXCTL0_ERRIE /*!< transfer error interrupt */ +#define MDMA_INT_CHTC MDMA_CHXCTL0_CHTCIE /*!< channel transfer complete interrupt */ +#define MDMA_INT_MBTC MDMA_CHXCTL0_MBTCIE /*!< multi-block transfer complete interrupt */ +#define MDMA_INT_BTC MDMA_CHXCTL0_BTCIE /*!< block transfer complete interrupt */ +#define MDMA_INT_TC MDMA_CHXCTL0_TCIE /*!< buffer transfer complete interrupt */ + +/* MDMA interrupt flags */ +#define MDMA_INT_FLAG_ERR MDMA_CHXSTAT0_ERR /*!< transfer error interrupt flag */ +#define MDMA_INT_FLAG_CHTCF MDMA_CHXSTAT0_CHTCF /*!< channel transfer complete interrupt flag */ +#define MDMA_INT_FLAG_MBTCF MDMA_CHXSTAT0_MBTCF /*!< multi-block transfer complete interrupt flag */ +#define MDMA_INT_FLAG_BTCF MDMA_CHXSTAT0_BTCF /*!< block transfer complete interrupt flag */ +#define MDMA_INT_FLAG_TCF MDMA_CHXSTAT0_TCF /*!< buffer transfer complete interrupt flag */ + +/* function declarations */ +/* MDMA deinitialization and initialization functions */ +/* deinitialize MDMA */ +void mdma_deinit(void); +/* deinitialize MDMA registers of a channel */ +void mdma_channel_deinit(mdma_channel_enum channelx); +/* initialize the MDMA parameters struct with the default values */ +void mdma_para_struct_init(mdma_parameter_struct *init_struct); +/* initialize the MDMA multi block transfer mode parameters struct with the default values */ +void mdma_multi_block_para_struct_init(mdma_multi_block_parameter_struct *block_init_struct); +/* initialize the MDMA link node configuration struct with the default values */ +void mdma_link_node_para_struct_init(mdma_link_node_parameter_struct *node); +/* initialize MDMA channel with MDMA parameter structure */ +void mdma_init(mdma_channel_enum channelx, mdma_parameter_struct *init_struct); +/* configure MDMA buffer/block transfer mode */ +void mdma_buffer_block_mode_config(mdma_channel_enum channelx, uint32_t saddr, uint32_t daddr, uint32_t tbnum); +/* configure MDMA multi block transfer mode */ +void mdma_multi_block_mode_config(mdma_channel_enum channelx, uint32_t tbnum, mdma_multi_block_parameter_struct *block_init_struct); +/* create MDMA link list node */ +void mdma_node_create(mdma_link_node_parameter_struct *node, mdma_multi_block_parameter_struct *block_init_struct, mdma_parameter_struct *init_struct); +/* MDMA add node to link list */ +void mdma_node_add(mdma_link_node_parameter_struct *pre_node, mdma_link_node_parameter_struct *new_node); +/* MDMA disconnect link list node */ +ErrStatus mdma_node_delete(mdma_link_node_parameter_struct *pre_node, mdma_link_node_parameter_struct *unused_node); + +/* MDMA configuration functions */ +/* configure MDMA destination base address */ +void mdma_destination_address_config(mdma_channel_enum channelx, uint32_t address); +/* configure MDMA source base address */ +void mdma_source_address_config(mdma_channel_enum channelx, uint32_t address); +/* configure MDMA destination bus */ +void mdma_destination_bus_config(mdma_channel_enum channelx, uint32_t bus); +/* configure MDMA source bus */ +void mdma_source_bus_config(mdma_channel_enum channelx, uint32_t bus); +/* configure priority level of MDMA channel */ +void mdma_priority_config(mdma_channel_enum channelx, uint32_t priority); +/* configure endianness of MDMA channel */ +void mdma_endianness_config(mdma_channel_enum channelx, uint32_t endianness); +/* configure data alignment of MDMA channel */ +void mdma_alignment_config(mdma_channel_enum channelx, uint32_t alignment); +/* configure transfer burst beats of source */ +void mdma_source_burst_beats_config(mdma_channel_enum channelx, uint32_t sbeat); +/* configure transfer burst beats of destination */ +void mdma_destination_burst_beats_config(mdma_channel_enum channelx, uint32_t dbeat); +/* configure data size of source */ +void mdma_source_width_config(mdma_channel_enum channelx, uint32_t swidth); +/* configure data size of destination */ +void mdma_destination_width_config(mdma_channel_enum channelx, uint32_t dwidth); +/* configure source adress increment mode */ +void mdma_source_increment_config(mdma_channel_enum channelx, uint32_t sinc); +/* configure destination adress increment mode */ +void mdma_destination_increment_config(mdma_channel_enum channelx, uint32_t dinc); +/* enable MDMA channel bufferable write mode */ +void mdma_channel_bufferable_write_enable(mdma_channel_enum channelx); +/* disable MDMA channel bufferable write mode */ +void mdma_channel_bufferable_write_disable(mdma_channel_enum channelx); +/* enable MDMA channel software request */ +void mdma_channel_software_request_enable(mdma_channel_enum channelx); +/* enable MDMA channel */ +void mdma_channel_enable(mdma_channel_enum channelx); +/* disable MDMA channel */ +void mdma_channel_disable(mdma_channel_enum channelx); +/* get MDMA transfer error direction */ +uint32_t mdma_transfer_error_direction_get(mdma_channel_enum channelx); +/* get MDMA transfer error address */ +uint32_t mdma_transfer_error_address_get(mdma_channel_enum channelx); + +/* interrupt & flag functions */ +/* get MDMA flag */ +FlagStatus mdma_flag_get(mdma_channel_enum channelx, uint32_t flag); +/* clear MDMA flag */ +void mdma_flag_clear(mdma_channel_enum channelx, uint32_t flag); +/* enable MDMA interrupt */ +void mdma_interrupt_enable(mdma_channel_enum channelx, uint32_t interrupt); +/* disable MDMA interrupt */ +void mdma_interrupt_disable(mdma_channel_enum channelx, uint32_t interrupt); +/* get MDMA interrupt flag */ +FlagStatus mdma_interrupt_flag_get(mdma_channel_enum channelx, uint32_t int_flag); +/* clear MDMA interrupt flag */ +void mdma_interrupt_flag_clear(mdma_channel_enum channelx, uint32_t int_flag); + +#endif /* GD32H7XX_MDMA_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_misc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_misc.h new file mode 100644 index 0000000000..8495614562 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_misc.h @@ -0,0 +1,200 @@ +/*! + \file gd32h7xx_misc.h + \brief definitions for the MISC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_MISC_H +#define GD32H7XX_MISC_H + +#include "gd32h7xx.h" + +#if (__MPU_PRESENT == 1) + +/* MPU region init parameter struct definitions */ +typedef struct +{ + uint32_t region_base_address; /*!< region base address */ + uint8_t region_number; /*!< region number */ + uint8_t region_size; /*!< region size */ + uint8_t subregion_disable; /*!< subregion disable */ + uint8_t tex_type; /*!< tex type */ + uint8_t access_permission; /*!< access permissions(AP) field */ + uint8_t access_shareable; /*!< shareable */ + uint8_t access_cacheable; /*!< cacheable */ + uint8_t access_bufferable; /*!< bufferable */ + uint8_t instruction_exec; /*!< execute never */ +}mpu_region_init_struct; + +#endif /* __MPU_PRESENT */ + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x24000000U) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000U) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80U) + +/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */ +#define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000U) + +/* priority group - define the pre-emption priority and the subpriority */ +#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x00000700U) /*!< 0 bits for pre-emption priority, 4 bits for subpriority */ +#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x00000600U) /*!< 1 bits for pre-emption priority, 3 bits for subpriority */ +#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x00000500U) /*!< 2 bits for pre-emption priority, 2 bits for subpriority */ +#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x00000400U) /*!< 3 bits for pre-emption priority, 1 bits for subpriority */ +#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x00000300U) /*!< 4 bits for pre-emption priority, 0 bits for subpriority */ + +/* choose the method to enter or exit the low power mode */ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02U) /*!< choose the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04U) /*!< choose the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10U) /*!< choose the interrupt source that can wake up the low power mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT /*!< low power mode by exiting from ISR */ +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP /*!< DEEPSLEEP mode or SLEEP mode */ +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND /*!< wakeup by all interrupt */ + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_CKSYS_DIV2 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from CK_SYS/2 */ +#define SYSTICK_CLKSOURCE_CKSYS ((uint32_t)0x00000004U) /*!< systick clock source is from CK_SYS */ + +#if (__MPU_PRESENT == 1) + +#define MPU_REGION_NUMBER0 ((uint8_t)0x00U) /*!< MPU region number 0 */ +#define MPU_REGION_NUMBER1 ((uint8_t)0x01U) /*!< MPU region number 1 */ +#define MPU_REGION_NUMBER2 ((uint8_t)0x02U) /*!< MPU region number 2 */ +#define MPU_REGION_NUMBER3 ((uint8_t)0x03U) /*!< MPU region number 3 */ +#define MPU_REGION_NUMBER4 ((uint8_t)0x04U) /*!< MPU region number 4 */ +#define MPU_REGION_NUMBER5 ((uint8_t)0x05U) /*!< MPU region number 5 */ +#define MPU_REGION_NUMBER6 ((uint8_t)0x06U) /*!< MPU region number 6 */ +#define MPU_REGION_NUMBER7 ((uint8_t)0x07U) /*!< MPU region number 7 */ +#define MPU_REGION_NUMBER8 ((uint8_t)0x08U) /*!< MPU region number 8 */ +#define MPU_REGION_NUMBER9 ((uint8_t)0x09U) /*!< MPU region number 9 */ +#define MPU_REGION_NUMBER10 ((uint8_t)0x0AU) /*!< MPU region number 10 */ +#define MPU_REGION_NUMBER11 ((uint8_t)0x0BU) /*!< MPU region number 11 */ +#define MPU_REGION_NUMBER12 ((uint8_t)0x0CU) /*!< MPU region number 12 */ +#define MPU_REGION_NUMBER13 ((uint8_t)0x0DU) /*!< MPU region number 13 */ +#define MPU_REGION_NUMBER14 ((uint8_t)0x0EU) /*!< MPU region number 14 */ +#define MPU_REGION_NUMBER15 ((uint8_t)0x0FU) /*!< MPU region number 15 */ + +#define MPU_REGION_SIZE_32B ARM_MPU_REGION_SIZE_32B /*!< MPU region size is 32 bytes, the smallest supported region size is 32 bytes */ +#define MPU_REGION_SIZE_64B ARM_MPU_REGION_SIZE_64B /*!< MPU region size is 64 bytes */ +#define MPU_REGION_SIZE_128B ARM_MPU_REGION_SIZE_128B /*!< MPU region size is 128 bytes */ +#define MPU_REGION_SIZE_256B ARM_MPU_REGION_SIZE_256B /*!< MPU region size is 256 bytes */ +#define MPU_REGION_SIZE_512B ARM_MPU_REGION_SIZE_512B /*!< MPU region size is 512 bytes */ +#define MPU_REGION_SIZE_1KB ARM_MPU_REGION_SIZE_1KB /*!< MPU region size is 1K bytes */ +#define MPU_REGION_SIZE_2KB ARM_MPU_REGION_SIZE_2KB /*!< MPU region size is 2K bytes */ +#define MPU_REGION_SIZE_4KB ARM_MPU_REGION_SIZE_4KB /*!< MPU region size is 4K bytes */ +#define MPU_REGION_SIZE_8KB ARM_MPU_REGION_SIZE_8KB /*!< MPU region size is 8K bytes */ +#define MPU_REGION_SIZE_16KB ARM_MPU_REGION_SIZE_16KB /*!< MPU region size is 16K bytes */ +#define MPU_REGION_SIZE_32KB ARM_MPU_REGION_SIZE_32KB /*!< MPU region size is 32K bytes */ +#define MPU_REGION_SIZE_64KB ARM_MPU_REGION_SIZE_64KB /*!< MPU region size is 64K bytes */ +#define MPU_REGION_SIZE_128KB ARM_MPU_REGION_SIZE_128KB /*!< MPU region size is 128K bytes */ +#define MPU_REGION_SIZE_256KB ARM_MPU_REGION_SIZE_256KB /*!< MPU region size is 256K bytes */ +#define MPU_REGION_SIZE_512KB ARM_MPU_REGION_SIZE_512KB /*!< MPU region size is 512K bytes */ +#define MPU_REGION_SIZE_1MB ARM_MPU_REGION_SIZE_1MB /*!< MPU region size is 1M bytes */ +#define MPU_REGION_SIZE_2MB ARM_MPU_REGION_SIZE_2MB /*!< MPU region size is 2M bytes */ +#define MPU_REGION_SIZE_4MB ARM_MPU_REGION_SIZE_4MB /*!< MPU region size is 4M bytes */ +#define MPU_REGION_SIZE_8MB ARM_MPU_REGION_SIZE_8MB /*!< MPU region size is 8M bytes */ +#define MPU_REGION_SIZE_16MB ARM_MPU_REGION_SIZE_16MB /*!< MPU region size is 16M bytes */ +#define MPU_REGION_SIZE_32MB ARM_MPU_REGION_SIZE_32MB /*!< MPU region size is 32M bytes */ +#define MPU_REGION_SIZE_64MB ARM_MPU_REGION_SIZE_64MB /*!< MPU region size is 64M bytes */ +#define MPU_REGION_SIZE_128MB ARM_MPU_REGION_SIZE_128MB /*!< MPU region size is 128M bytes */ +#define MPU_REGION_SIZE_256MB ARM_MPU_REGION_SIZE_256MB /*!< MPU region size is 256M bytes */ +#define MPU_REGION_SIZE_512MB ARM_MPU_REGION_SIZE_512MB /*!< MPU region size is 512M bytes */ +#define MPU_REGION_SIZE_1GB ARM_MPU_REGION_SIZE_1GB /*!< MPU region size is 1G bytes */ +#define MPU_REGION_SIZE_2GB ARM_MPU_REGION_SIZE_2GB /*!< MPU region size is 2G bytes */ +#define MPU_REGION_SIZE_4GB ARM_MPU_REGION_SIZE_4GB /*!< MPU region size is 4G bytes */ + +#define MPU_SUBREGION_ENABLE ((uint8_t)0x00U) /*!< Subregion enable */ +#define MPU_SUBREGION_DISABLE ((uint8_t)0x01U) /*!< Subregion disable */ + +#define MPU_TEX_TYPE0 ((uint8_t)0x00U) /*!< MPU TEX type 0 */ +#define MPU_TEX_TYPE1 ((uint8_t)0x01U) /*!< MPU TEX type 1 */ +#define MPU_TEX_TYPE2 ((uint8_t)0x02U) /*!< MPU TEX type 2 */ + +#define MPU_AP_NO_ACCESS ARM_MPU_AP_NONE /*!< MPU access permission no access */ +#define MPU_AP_PRIV_RW ARM_MPU_AP_PRIV /*!< MPU access permission privileged access only */ +#define MPU_AP_PRIV_RW_UNPRIV_RO ARM_MPU_AP_URO /*!< MPU access permission unprivileged access read-only */ +#define MPU_AP_FULL_ACCESS ARM_MPU_AP_FULL /*!< MPU access permission full access */ +#define MPU_AP_PRIV_RO ARM_MPU_AP_PRO /*!< MPU access permission privileged access read-only */ +#define MPU_AP_PRIV_UNPRIV_RO ARM_MPU_AP_RO /*!< MPU access permission privileged and unprivileged read-only access */ + +#define MPU_ACCESS_SHAREABLE ((uint8_t)0x01U) /*!< MPU access shareable */ +#define MPU_ACCESS_NON_SHAREABLE ((uint8_t)0x00U) /*!< MPU access non-shareable */ + +#define MPU_ACCESS_CACHEABLE ((uint8_t)0x01U) /*!< MPU access cacheable */ +#define MPU_ACCESS_NON_CACHEABLE ((uint8_t)0x00U) /*!< MPU access non-cacheable */ + +#define MPU_ACCESS_BUFFERABLE ((uint8_t)0x01U) /*!< MPU access bufferable */ +#define MPU_ACCESS_NON_BUFFERABLE ((uint8_t)0x00U) /*!< MPU access non-bufferable */ + +#define MPU_INSTRUCTION_EXEC_PERMIT ((uint8_t)0x00U) /*!< execution of an instruction fetched from this region permitted */ +#define MPU_INSTRUCTION_EXEC_NOT_PERMIT ((uint8_t)0x01U) /*!< execution of an instruction fetched from this region not permitted */ + +#define MPU_MODE_HFNMI_PRIVDEF_NONE ((uint32_t)0x00000000U) /*!< HFNMIENA and PRIVDEFENA are 0 */ +#define MPU_MODE_HARDFAULT_NMI MPU_CTRL_HFNMIENA_Msk /*!< use the MPU for memory accesses by HardFault and NMI handlers only */ +#define MPU_MODE_PRIV_DEFAULT MPU_CTRL_PRIVDEFENA_Msk /*!< enables the default memory map as a background region for privileged access only */ +#define MPU_MODE_HFNMI_PRIVDEF ((uint32_t)MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk) /*!< HFNMIENA and PRIVDEFENA are 1 */ + +#endif /* __MPU_PRESENT */ + +/* function declarations */ +/* set the priority group */ +void nvic_priority_group_set(uint32_t nvic_prigroup); + +/* enable NVIC interrupt request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority); +/* disable NVIC interrupt request */ +void nvic_irq_disable(uint8_t nvic_irq); + +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); + +/* set the state of the low power mode */ +void system_lowpower_set(uint8_t lowpower_mode); +/* reset the state of the low power mode */ +void system_lowpower_reset(uint8_t lowpower_mode); + +/* set the systick clock source */ +void systick_clksource_set(uint32_t systick_clksource); + +#if (__MPU_PRESENT == 1) +/* initialize mpu_region_init_struct with the default values */ +void mpu_region_struct_para_init(mpu_region_init_struct *mpu_init_struct); +/* configure the MPU region */ +void mpu_region_config(mpu_region_init_struct *mpu_init_struct); +/* enable the MPU region */ +void mpu_region_enable(void); +#endif /* __MPU_PRESENT */ + +#endif /* GD32H7XX_MISC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospi.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospi.h new file mode 100644 index 0000000000..a76d09957e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospi.h @@ -0,0 +1,802 @@ +/*! + \file gd32h7xx_ospi.h + \brief definitions for the OSPI + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_OSPI_H +#define GD32H7XX_OSPI_H + +#include "gd32h7xx.h" + +/* OSPI definitions */ +#define OSPI0 OSPI_BASE +#define OSPI1 (OSPI_BASE + 0x00005000U) + +/* registers definitions */ +#define OSPI_CTL(ospix) REG32((ospix) + 0x00000000U) /*!< OSPI control register */ +#define OSPI_DCFG0(ospix) REG32((ospix) + 0x00000008U) /*!< OSPI device configuration register */ +#define OSPI_DCFG1(ospix) REG32((ospix) + 0x0000000CU) /*!< OSPI device configuration register */ +#define OSPI_STAT(ospix) REG32((ospix) + 0x00000020U) /*!< OSPI status register */ +#define OSPI_STATC(ospix) REG32((ospix) + 0x00000024U) /*!< OSPI status clear register */ +#define OSPI_DTLEN(ospix) REG32((ospix) + 0x00000040U) /*!< OSPI data length register */ +#define OSPI_ADDR(ospix) REG32((ospix) + 0x00000048U) /*!< OSPI address register */ +#define OSPI_DATA(ospix) REG32((ospix) + 0x00000050U) /*!< OSPI data register */ +#define OSPI_STATMK(ospix) REG32((ospix) + 0x00000080U) /*!< OSPI status mask register */ +#define OSPI_STATMATCH(ospix) REG32((ospix) + 0x00000088U) /*!< OSPI status match register */ +#define OSPI_INTERVAL(ospix) REG32((ospix) + 0x00000090U) /*!< OSPI interval register */ +#define OSPI_TCFG(ospix) REG32((ospix) + 0x00000100U) /*!< OSPI transfer configuration register */ +#define OSPI_TIMCFG(ospix) REG32((ospix) + 0x00000108U) /*!< OSPI timing configuration register */ +#define OSPI_INS(ospix) REG32((ospix) + 0x00000110U) /*!< OSPI instruction register */ +#define OSPI_ALTE(ospix) REG32((ospix) + 0x00000120U) /*!< OSPI alternate bytes register */ +#define OSPI_WPTCFG(ospix) REG32((ospix) + 0x00000140U) /*!< OSPI wrap transfer configuration register */ +#define OSPI_WPTIMCFG(ospix) REG32((ospix) + 0x00000148U) /*!< OSPI wrap timing configuration register */ +#define OSPI_WPINS(ospix) REG32((ospix) + 0x00000150U) /*!< OSPI wrap instruction register */ +#define OSPI_WPALTE(ospix) REG32((ospix) + 0x00000160U) /*!< OSPI wrap alternate bytes register */ +#define OSPI_WTCFG(ospix) REG32((ospix) + 0x00000180U) /*!< OSPI write transfer configuration register */ +#define OSPI_WTIMCFG(ospix) REG32((ospix) + 0x00000188U) /*!< OSPI write timing configuration register */ +#define OSPI_WINS(ospix) REG32((ospix) + 0x00000190U) /*!< OSPI write instruction register */ +#define OSPI_WALTE(ospix) REG32((ospix) + 0x000001A0U) /*!< OSPI write alternate bytes register */ + +/* bits definitions */ +/* OSPI_CTL */ +#define OSPI_CTL_OSPIEN BIT(0) /*!< enable the quadspi */ + +#define OSPI_CTL_DMAEN BIT(2) /*!< dma enable */ +#define OSPI_CTL_FTL BITS(8,12) /*!< fifo threshold level */ +#define OSPI_CTL_TERRIE BIT(16) /*!< transfer error interrupt enable */ +#define OSPI_CTL_TCIE BIT(17) /*!< transfer complete interrupt enable */ +#define OSPI_CTL_FTIE BIT(18) /*!< fifo threshold interrupt enable */ +#define OSPI_CTL_SMIE BIT(19) /*!< status match interrupt enable */ +#define OSPI_CTL_SPS BIT(22) /*!< status polling mode stop */ +#define OSPI_CTL_SPMOD BIT(23) /*!< status polling match mode */ +#define OSPI_CTL_FMOD BITS(28,29) /*!< functional mode select */ + +/* OSPI_DCFG0 */ +#define OSPI_DCFG0_CSHC BITS(8,13) /*!< chip select high cycle */ +#define OSPI_DCFG0_MESZ BITS(16,20) /*!< memory size */ +#define OSPI_DCFG0_DTYSEL BITS(24,26) /*!< select device type */ + +/* OSPI_DCFG1 */ +#define OSPI_DCFG1_PSC BITS(0,7) /*!< prescaler set */ +#define OSPI_DCFG1_WPSZ BITS(16,18) /*!< wrap size */ + +/* OSPI_STAT */ +#define OSPI_STAT_TERR BIT(0) /*!< transfer error flag */ +#define OSPI_STAT_TC BIT(1) /*!< transfer complete flag */ +#define OSPI_STAT_FT BIT(2) /*!< fifo threshold flag */ +#define OSPI_STAT_SM BIT(3) /*!< status match flag */ +#define OSPI_STAT_BUSY BIT(5) /*!< busy flag */ +#define OSPI_STAT_FL BITS(8,13) /*!< fifo level */ + +/* OSPI_STATC */ +#define OSPI_STATC_TERRC BIT(0) /*!< clear transfer error flag */ +#define OSPI_STATC_TCC BIT(1) /*!< clear transfer complete flag */ +#define OSPI_STATC_SMC BIT(3) /*!< clear status match flag */ + +/* OSPI_DTLEN */ +#define OSPI_DTLEN_DTLEN BITS(0,31) /*!< data length */ + +/* OSPI_ADDR */ +#define OSPI_ADDR_ADDR BITS(0,31) /*!< address to be send to the external flash memory */ + +/* OSPI_DATA */ +#define OSPI_DATA_DATA BITS(0,31) /*!< data to be transferred through the flash memory */ + +/* OSPI_STATMK */ +#define OSPI_STATMK_MASK BITS(0,31) /*!< status mask */ + +/* OSPI_STATMATCH */ +#define OSPI_STATMATCH_MATCH BITS(0,31) /*!< status match */ + +/* OSPI_INTERVAL */ +#define OSPI_INTERVAL_INTERVAL BITS(0,15) /*!< interval cycle */ + +/* OSPI_TCFG */ +#define OSPI_TCFG_IMOD BITS(0,2) /*!< instruction mode */ +#define OSPI_TCFG_INSSZ BITS(4,5) /*!< instruction size */ +#define OSPI_TCFG_ADDRMOD BITS(8,10) /*!< address mode */ +#define OSPI_TCFG_ADDRDTR BIT(11) /*!< address double transfer rate */ +#define OSPI_TCFG_ADDRSZ BITS(12,13) /*!< address size */ +#define OSPI_TCFG_ALTEMOD BITS(16,18) /*!< alternate bytes mode */ +#define OSPI_TCFG_ABDTR BIT(19) /*!< alternate bytes double transfer rate */ +#define OSPI_TCFG_ALTESZ BITS(20,21) /*!< alternate bytes size */ +#define OSPI_TCFG_DATAMOD BITS(24,26) /*!< data mode */ +#define OSPI_TCFG_DADTR BIT(27) /*!< data double transfer rate */ + +/* OSPI_TIMCFG */ +#define OSPI_TIMCFG_DUMYC BITS(0,4) /*!< number of dummy cycles */ +#define OSPI_TIMCFG_DEHQC BIT(27) /*!< delay hold quarter cycle */ +#define OSPI_TIMCFG_SSAMPLE BIT(30) /*!< sample shift */ + +/* OSPI_INS */ +#define OSPI_INS_INSTRUCTION BITS(0,31) /*!< command information to be send to the flash memory */ + +/* OSPI_ALTE */ +#define OSPI_ALTE_ALTE BITS(0,31) /*!< alternate bytes to be send to the flash memory */ + +/* OSPI_WPTCFG */ +#define OSPI_WPTCFG_IMOD BITS(0,2) /*!< instruction mode */ +#define OSPI_WPTCFG_INSSZ BITS(4,5) /*!< instruction size */ +#define OSPI_WPTCFG_ADDRMOD BITS(8,10) /*!< address mode */ +#define OSPI_WPTCFG_ADDRDTR BIT(11) /*!< address double transfer rate */ +#define OSPI_WPTCFG_ADDRSZ BITS(12,13) /*!< address size */ +#define OSPI_WPTCFG_ALTEMOD BITS(16,18) /*!< alternate bytes mode */ +#define OSPI_WPTCFG_ABDTR BIT(19) /*!< alternate bytes double transfer rate */ +#define OSPI_WPTCFG_ALTESZ BITS(20,21) /*!< alternate bytes size */ +#define OSPI_WPTCFG_DATAMOD BITS(24,26) /*!< data mode */ +#define OSPI_WPTCFG_DADTR BIT(27) /*!< data double transfer rate */ + +/* OSPI_WPTIMCFG */ +#define OSPI_WPTIMCFG_DUMYC BITS(0,4) /*!< number of dummy cycles */ +#define OSPI_WPTIMCFG_DEHQC BIT(28) /*!< delay hold quarter cycle */ +#define OSPI_WPTIMCFG_SSAMPLE BIT(30) /*!< sample shift */ + +/* OSPI_WPINS */ +#define OSPI_WPINS_INSTRUCTION BITS(0,31) /*!< command information to be send to the flash memory */ + +/* OSPI_WPALTE */ +#define OSPI_WPALTE_ALTE BITS(0,31) /*!< optional data to be send to the flash memory */ + +/* OSPI_WTCFG */ +#define OSPI_WTCFG_IMOD BITS(0,2) /*!< instruction mode */ +#define OSPI_WTCFG_INSSZ BITS(4,5) /*!< instruction size */ +#define OSPI_WTCFG_ADDRMOD BITS(8,10) /*!< address mode */ +#define OSPI_WTCFG_ADDRDTR BIT(11) /*!< address double transfer rate */ +#define OSPI_WTCFG_ADDRSZ BITS(12,13) /*!< address size */ +#define OSPI_WTCFG_ALTEMOD BITS(16,18) /*!< alternate bytes mode */ +#define OSPI_WTCFG_ABDTR BIT(19) /*!< alternate bytes double transfer rate */ +#define OSPI_WTCFG_ALTESZ BITS(20,21) /*!< alternate bytes size */ +#define OSPI_WTCFG_DATAMOD BITS(24,26) /*!< data mode */ +#define OSPI_WTCFG_DADTR BIT(27) /*!< data double transfer rate */ + +/* OSPI_WTIMCFG */ +#define OSPI_WTIMCFG_DUMYC BITS(0,4) /*!< number of dummy cycles */ + +/* OSPI_WINS */ +#define OSPI_WINS_INSTRUCTION BITS(0,31) /*!< command information to be send to the flash memory */ + +/* OSPI_WALTE */ +#define OSPI_WALTE_ALTE BITS(0,31) /*!< optional data to be send to the flash memory */ + +/* OSPI_HBLCFG */ +#define OSPI_HBLCFG_LMOD BIT(0) /*!< latency mode */ +#define OSPI_HBLCFG_WZLAT BIT(1) /*!< write zero latency */ +#define OSPI_HBLCFG_ACCTM BITS(8,15) /*!< access time */ +#define OSPI_HBLCFG_RWRTM BITS(16,23) /*!< read write recovery time */ + +/* constants definitions */ +/* ospi init struct definitions */ +typedef struct { + uint32_t prescaler; /*! specifies the prescaler factor for generating clock based on the kernel clock. + this parameter can be a number between 0 and 255 */ + uint32_t fifo_threshold; /*! specifies the threshold number of bytes in the FIFO (used only in indirect mode) + this parameter can be a value between 1 and 31 */ + uint32_t sample_shift; /*! specifies the sample shift. The data is sampled 1/2 clock cycle delay later to + take in account external signal delays. (it should be OSPI_SAMPLE_SHIFTING_NONE in DTR mode) */ + uint32_t device_size; /*! specifies the device size. FlashSize+1 is effectively the number of address bits + required to address the flash memory. The flash capacity can be up to 4GB + (addressed using 32 bits) in indirect mode, but the addressable space in + memory-mapped mode is limited to 256MB + this parameter can be a number between 0 and 31 */ + uint32_t cs_hightime; /*! specifies the chip select high time. chipselecthightime+1 defines the minimum number + of clock cycles which the chip select must remain high between commands. */ + uint32_t memory_type; /*! it indicates the external device type connected to the OSPI. */ + + uint32_t wrap_size; /*! it indicates the wrap-size corresponding the external device configuration. */ + + uint32_t delay_hold_cycle; /*! it allows to hold to 1/4 cycle the data. */ +} ospi_parameter_struct; + +/* ospi regular command struct definitions */ +typedef struct { + uint32_t operation_type; /*! it indicates if the configuration applies to the common regsiters or + to the registers for the write operation (these registers are only + used for memory-mapped mode). */ + uint32_t instruction; /*! it contains the instruction to be sent to the device. + this parameter can be a value between 0 and 0xFFFFFFFF */ + uint32_t ins_mode; /*! it indicates the mode of the instruction */ + + uint32_t ins_size; /*! it indicates the size of the instruction */ + + uint32_t address; /*! it contains the address to be sent to the device. + this parameter can be a value between 0 and 0xFFFFFFFF */ + uint32_t addr_mode; /*! it indicates the mode of the address */ + + uint32_t addr_size; /*! it indicates the size of the address */ + + uint32_t addr_dtr_mode; /*! it enables or not the DTR mode for the address phase */ + + uint32_t alter_bytes; /*! it contains the alternate bytes to be sent to the device. + this parameter can be a value between 0 and 0xFFFFFFFF */ + uint32_t alter_bytes_mode; /*! it indicates the mode of the alternate bytes */ + + uint32_t alter_bytes_size; /*! it indicates the size of the alternate bytes */ + + uint32_t alter_bytes_dtr_mode; /*! it enables or not the DTR mode for the alternate bytes phase */ + + uint32_t data_mode; /*! it indicates the mode of the data */ + + uint32_t nbdata; /*! it indicates the number of data transferred with this command. + this field is only used for indirect mode. + this parameter can be a value between 1 and 0xFFFFFFFF */ + uint32_t data_dtr_mode; /*! it enables or not the DTR mode for the data phase */ + + uint32_t dummy_cycles; /*! it indicates the number of dummy cycles inserted before data phase. + this parameter can be a value between 0 and 31 */ +} ospi_regular_cmd_struct; + +/* ospi autopolling struct definitions */ +typedef struct { + uint32_t match; /*! specifies the value to be compared with the masked status register to get a match. + this parameter can be any value between 0 and 0xFFFFFFFF */ + uint32_t mask; /*! specifies the mask to be applied to the status bytes received. + this parameter can be any value between 0 and 0xFFFFFFFF */ + uint32_t interval; /*! specifies the number of clock cycles between two read during automatic polling phases. + this parameter can be any value between 0 and 0xFFFF */ + uint32_t match_mode; /*! specifies the method used for determining a match */ + + uint32_t automatic_stop; /*! specifies if automatic polling is stopped after a match */ + +} ospi_autopolling_struct; + +/* OSPI configuration */ +/* OSPI automatic stop */ +#define OSPI_AUTOMATIC_STOP_MATCH OSPI_CTL_SPS /*!< status polling mode stop in match */ + +/* OSPI match mode */ +#define OSPI_MATCH_MODE_AND 0x00000000U /*!< OSPI status polling match mode and */ +#define OSPI_MATCH_MODE_OR OSPI_CTL_SPMOD /*!< OSPI status polling match mode or */ + +/* OSPI functional mode */ +#define OSPI_FMOD(regval) (BITS(28,29) & ((uint32_t)(regval) << 28U)) +#define OSPI_INDIRECT_WRITE OSPI_FMOD(0) /*!< OSPI indirect write mode */ +#define OSPI_INDIRECT_READ OSPI_FMOD(1) /*!< OSPI indirect read mode */ +#define OSPI_STATUS_POLLING OSPI_FMOD(2) /*!< OSPI status polling mode */ +#define OSPI_MEMORY_MAPPED OSPI_FMOD(3) /*!< OSPI memory mapped mode */ + +/* OSPI FIFO threshold level set */ +#define OSPI_FTL(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) +#define OSPI_FIFO_THRESHOLD_1 OSPI_FTL(0) /*!< in indirect write mode, there are 1 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 1 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_2 OSPI_FTL(1) /*!< in indirect write mode, there are 2 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 2 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_3 OSPI_FTL(2) /*!< in indirect write mode, there are 3 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 3 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_4 OSPI_FTL(3) /*!< in indirect write mode, there are 4 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 4 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_5 OSPI_FTL(4) /*!< in indirect write mode, there are 5 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 5 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_6 OSPI_FTL(5) /*!< in indirect write mode, there are 6 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 6 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_7 OSPI_FTL(6) /*!< in indirect write mode, there are 7 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 7 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_8 OSPI_FTL(7) /*!< in indirect write mode, there are 8 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 8 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_9 OSPI_FTL(8) /*!< in indirect write mode, there are 9 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 9 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_10 OSPI_FTL(9) /*!< in indirect write mode, there are 10 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 10 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_11 OSPI_FTL(10) /*!< in indirect write mode, there are 11 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 11 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_12 OSPI_FTL(11) /*!< in indirect write mode, there are 12 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 12 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_13 OSPI_FTL(12) /*!< in indirect write mode, there are 13 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 13 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_14 OSPI_FTL(13) /*!< in indirect write mode, there are 14 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 14 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_15 OSPI_FTL(14) /*!< in indirect write mode, there are 15 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 15 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_16 OSPI_FTL(15) /*!< in indirect write mode, there are 16 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 16 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_17 OSPI_FTL(16) /*!< in indirect write mode, there are 17 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 17 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_18 OSPI_FTL(17) /*!< in indirect write mode, there are 18 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 18 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_19 OSPI_FTL(18) /*!< in indirect write mode, there are 19 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 19 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_20 OSPI_FTL(19) /*!< in indirect write mode, there are 20 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 20 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_21 OSPI_FTL(20) /*!< in indirect write mode, there are 21 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 21 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_22 OSPI_FTL(21) /*!< in indirect write mode, there are 22 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 22 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_23 OSPI_FTL(22) /*!< in indirect write mode, there are 23 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 23 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_24 OSPI_FTL(23) /*!< in indirect write mode, there are 24 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 24 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_25 OSPI_FTL(24) /*!< in indirect write mode, there are 25 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 25 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_26 OSPI_FTL(25) /*!< in indirect write mode, there are 26 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 26 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_27 OSPI_FTL(26) /*!< in indirect write mode, there are 27 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 27 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_28 OSPI_FTL(27) /*!< in indirect write mode, there are 28 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 28 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_29 OSPI_FTL(28) /*!< in indirect write mode, there are 29 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 29 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_30 OSPI_FTL(29) /*!< in indirect write mode, there are 30 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 30 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_31 OSPI_FTL(30) /*!< in indirect write mode, there are 31 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 31 or more free bytes available to be read from the FIFO */ +#define OSPI_FIFO_THRESHOLD_32 OSPI_FTL(31) /*!< in indirect write mode, there are 32 or more free bytes available to be written to the FIFO, + in indirect read mode, there are 32 or more free bytes available to be read from the FIFO */ + +/* OSPI chip select high cycle */ +#define OSPI_CSHC(regval) (BITS(8,13) & ((uint32_t)(regval) << 8U)) +#define OSPI_CS_HIGH_TIME_1_CYCLE OSPI_CSHC(0) /*!< OSPI csn stays high for at least 1 cycle */ +#define OSPI_CS_HIGH_TIME_2_CYCLE OSPI_CSHC(1) /*!< OSPI csn stays high for at least 2 cycle */ +#define OSPI_CS_HIGH_TIME_3_CYCLE OSPI_CSHC(2) /*!< OSPI csn stays high for at least 3 cycle */ +#define OSPI_CS_HIGH_TIME_4_CYCLE OSPI_CSHC(3) /*!< OSPI csn stays high for at least 4 cycle */ +#define OSPI_CS_HIGH_TIME_5_CYCLE OSPI_CSHC(4) /*!< OSPI csn stays high for at least 5 cycle */ +#define OSPI_CS_HIGH_TIME_6_CYCLE OSPI_CSHC(5) /*!< OSPI csn stays high for at least 6 cycle */ +#define OSPI_CS_HIGH_TIME_7_CYCLE OSPI_CSHC(6) /*!< OSPI csn stays high for at least 7 cycle */ +#define OSPI_CS_HIGH_TIME_8_CYCLE OSPI_CSHC(7) /*!< OSPI csn stays high for at least 8 cycle */ +#define OSPI_CS_HIGH_TIME_9_CYCLE OSPI_CSHC(8) /*!< OSPI csn stays high for at least 9 cycle */ +#define OSPI_CS_HIGH_TIME_10_CYCLE OSPI_CSHC(9) /*!< OSPI csn stays high for at least 10 cycle */ +#define OSPI_CS_HIGH_TIME_11_CYCLE OSPI_CSHC(10) /*!< OSPI csn stays high for at least 11 cycle */ +#define OSPI_CS_HIGH_TIME_12_CYCLE OSPI_CSHC(11) /*!< OSPI csn stays high for at least 12 cycle */ +#define OSPI_CS_HIGH_TIME_13_CYCLE OSPI_CSHC(12) /*!< OSPI csn stays high for at least 13 cycle */ +#define OSPI_CS_HIGH_TIME_14_CYCLE OSPI_CSHC(13) /*!< OSPI csn stays high for at least 14 cycle */ +#define OSPI_CS_HIGH_TIME_15_CYCLE OSPI_CSHC(14) /*!< OSPI csn stays high for at least 15 cycle */ +#define OSPI_CS_HIGH_TIME_16_CYCLE OSPI_CSHC(15) /*!< OSPI csn stays high for at least 16 cycle */ +#define OSPI_CS_HIGH_TIME_17_CYCLE OSPI_CSHC(16) /*!< OSPI csn stays high for at least 17 cycle */ +#define OSPI_CS_HIGH_TIME_18_CYCLE OSPI_CSHC(17) /*!< OSPI csn stays high for at least 18 cycle */ +#define OSPI_CS_HIGH_TIME_19_CYCLE OSPI_CSHC(18) /*!< OSPI csn stays high for at least 19 cycle */ +#define OSPI_CS_HIGH_TIME_20_CYCLE OSPI_CSHC(19) /*!< OSPI csn stays high for at least 20 cycle */ +#define OSPI_CS_HIGH_TIME_21_CYCLE OSPI_CSHC(20) /*!< OSPI csn stays high for at least 21 cycle */ +#define OSPI_CS_HIGH_TIME_22_CYCLE OSPI_CSHC(21) /*!< OSPI csn stays high for at least 22 cycle */ +#define OSPI_CS_HIGH_TIME_23_CYCLE OSPI_CSHC(22) /*!< OSPI csn stays high for at least 23 cycle */ +#define OSPI_CS_HIGH_TIME_24_CYCLE OSPI_CSHC(23) /*!< OSPI csn stays high for at least 24 cycle */ +#define OSPI_CS_HIGH_TIME_25_CYCLE OSPI_CSHC(24) /*!< OSPI csn stays high for at least 25 cycle */ +#define OSPI_CS_HIGH_TIME_26_CYCLE OSPI_CSHC(25) /*!< OSPI csn stays high for at least 26 cycle */ +#define OSPI_CS_HIGH_TIME_27_CYCLE OSPI_CSHC(26) /*!< OSPI csn stays high for at least 27 cycle */ +#define OSPI_CS_HIGH_TIME_28_CYCLE OSPI_CSHC(27) /*!< OSPI csn stays high for at least 28 cycle */ +#define OSPI_CS_HIGH_TIME_29_CYCLE OSPI_CSHC(28) /*!< OSPI csn stays high for at least 29 cycle */ +#define OSPI_CS_HIGH_TIME_30_CYCLE OSPI_CSHC(29) /*!< OSPI csn stays high for at least 30 cycle */ +#define OSPI_CS_HIGH_TIME_31_CYCLE OSPI_CSHC(30) /*!< OSPI csn stays high for at least 31 cycle */ +#define OSPI_CS_HIGH_TIME_32_CYCLE OSPI_CSHC(31) /*!< OSPI csn stays high for at least 32 cycle */ +#define OSPI_CS_HIGH_TIME_33_CYCLE OSPI_CSHC(32) /*!< OSPI csn stays high for at least 33 cycle */ +#define OSPI_CS_HIGH_TIME_34_CYCLE OSPI_CSHC(33) /*!< OSPI csn stays high for at least 34 cycle */ +#define OSPI_CS_HIGH_TIME_35_CYCLE OSPI_CSHC(34) /*!< OSPI csn stays high for at least 35 cycle */ +#define OSPI_CS_HIGH_TIME_36_CYCLE OSPI_CSHC(35) /*!< OSPI csn stays high for at least 36 cycle */ +#define OSPI_CS_HIGH_TIME_37_CYCLE OSPI_CSHC(36) /*!< OSPI csn stays high for at least 37 cycle */ +#define OSPI_CS_HIGH_TIME_38_CYCLE OSPI_CSHC(37) /*!< OSPI csn stays high for at least 38 cycle */ +#define OSPI_CS_HIGH_TIME_39_CYCLE OSPI_CSHC(38) /*!< OSPI csn stays high for at least 39 cycle */ +#define OSPI_CS_HIGH_TIME_40_CYCLE OSPI_CSHC(39) /*!< OSPI csn stays high for at least 40 cycle */ +#define OSPI_CS_HIGH_TIME_41_CYCLE OSPI_CSHC(40) /*!< OSPI csn stays high for at least 41 cycle */ +#define OSPI_CS_HIGH_TIME_42_CYCLE OSPI_CSHC(41) /*!< OSPI csn stays high for at least 42 cycle */ +#define OSPI_CS_HIGH_TIME_43_CYCLE OSPI_CSHC(42) /*!< OSPI csn stays high for at least 43 cycle */ +#define OSPI_CS_HIGH_TIME_44_CYCLE OSPI_CSHC(43) /*!< OSPI csn stays high for at least 44 cycle */ +#define OSPI_CS_HIGH_TIME_45_CYCLE OSPI_CSHC(44) /*!< OSPI csn stays high for at least 45 cycle */ +#define OSPI_CS_HIGH_TIME_46_CYCLE OSPI_CSHC(45) /*!< OSPI csn stays high for at least 46 cycle */ +#define OSPI_CS_HIGH_TIME_47_CYCLE OSPI_CSHC(46) /*!< OSPI csn stays high for at least 47 cycle */ +#define OSPI_CS_HIGH_TIME_48_CYCLE OSPI_CSHC(47) /*!< OSPI csn stays high for at least 48 cycle */ +#define OSPI_CS_HIGH_TIME_49_CYCLE OSPI_CSHC(48) /*!< OSPI csn stays high for at least 49 cycle */ +#define OSPI_CS_HIGH_TIME_50_CYCLE OSPI_CSHC(49) /*!< OSPI csn stays high for at least 50 cycle */ +#define OSPI_CS_HIGH_TIME_51_CYCLE OSPI_CSHC(50) /*!< OSPI csn stays high for at least 51 cycle */ +#define OSPI_CS_HIGH_TIME_52_CYCLE OSPI_CSHC(51) /*!< OSPI csn stays high for at least 52 cycle */ +#define OSPI_CS_HIGH_TIME_53_CYCLE OSPI_CSHC(52) /*!< OSPI csn stays high for at least 53 cycle */ +#define OSPI_CS_HIGH_TIME_54_CYCLE OSPI_CSHC(53) /*!< OSPI csn stays high for at least 54 cycle */ +#define OSPI_CS_HIGH_TIME_55_CYCLE OSPI_CSHC(54) /*!< OSPI csn stays high for at least 55 cycle */ +#define OSPI_CS_HIGH_TIME_56_CYCLE OSPI_CSHC(55) /*!< OSPI csn stays high for at least 56 cycle */ +#define OSPI_CS_HIGH_TIME_57_CYCLE OSPI_CSHC(56) /*!< OSPI csn stays high for at least 57 cycle */ +#define OSPI_CS_HIGH_TIME_58_CYCLE OSPI_CSHC(57) /*!< OSPI csn stays high for at least 58 cycle */ +#define OSPI_CS_HIGH_TIME_59_CYCLE OSPI_CSHC(58) /*!< OSPI csn stays high for at least 59 cycle */ +#define OSPI_CS_HIGH_TIME_60_CYCLE OSPI_CSHC(59) /*!< OSPI csn stays high for at least 60 cycle */ +#define OSPI_CS_HIGH_TIME_61_CYCLE OSPI_CSHC(60) /*!< OSPI csn stays high for at least 61 cycle */ +#define OSPI_CS_HIGH_TIME_62_CYCLE OSPI_CSHC(61) /*!< OSPI csn stays high for at least 62 cycle */ +#define OSPI_CS_HIGH_TIME_63_CYCLE OSPI_CSHC(62) /*!< OSPI csn stays high for at least 63 cycle */ +#define OSPI_CS_HIGH_TIME_64_CYCLE OSPI_CSHC(63) /*!< OSPI csn stays high for at least 64 cycle */ + +/* OSPI flash memory size */ +#define OSPI_MESZ(regval) (BITS(16,20) & ((uint32_t)(regval) << 16U)) +#define OSPI_MESZ_2_BYTES OSPI_MESZ(0) /*!< the size of external memory is 2 bytes */ +#define OSPI_MESZ_4_BYTES OSPI_MESZ(1) /*!< the size of external memory is 4 bytes */ +#define OSPI_MESZ_8_BYTES OSPI_MESZ(2) /*!< the size of external memory is 8 bytes */ +#define OSPI_MESZ_16_BYTES OSPI_MESZ(3) /*!< the size of external memory is 16 bytes */ +#define OSPI_MESZ_32_BYTES OSPI_MESZ(4) /*!< the size of external memory is 32 bytes */ +#define OSPI_MESZ_64_BYTES OSPI_MESZ(5) /*!< the size of external memory is 64 bytes */ +#define OSPI_MESZ_128_BYTES OSPI_MESZ(6) /*!< the size of external memory is 128 bytes */ +#define OSPI_MESZ_256_BYTES OSPI_MESZ(7) /*!< the size of external memory is 256 bytes */ +#define OSPI_MESZ_512_BYTES OSPI_MESZ(8) /*!< the size of external memory is 512 bytes */ +#define OSPI_MESZ_1024_BYTES OSPI_MESZ(9) /*!< the size of external memory is 1024 bytes */ +#define OSPI_MESZ_2_KBS OSPI_MESZ(10) /*!< the size of external memory is 2 KB */ +#define OSPI_MESZ_4_KBS OSPI_MESZ(11) /*!< the size of external memory is 4 KB */ +#define OSPI_MESZ_8_KBS OSPI_MESZ(12) /*!< the size of external memory is 8 KB */ +#define OSPI_MESZ_16_KBS OSPI_MESZ(13) /*!< the size of external memory is 16 KB */ +#define OSPI_MESZ_32_KBS OSPI_MESZ(14) /*!< the size of external memory is 32 KB */ +#define OSPI_MESZ_64_KBS OSPI_MESZ(15) /*!< the size of external memory is 64 KB */ +#define OSPI_MESZ_128_KBS OSPI_MESZ(16) /*!< the size of external memory is 128 KB */ +#define OSPI_MESZ_256_KBS OSPI_MESZ(17) /*!< the size of external memory is 256 KB */ +#define OSPI_MESZ_512_KBS OSPI_MESZ(18) /*!< the size of external memory is 512 KB */ +#define OSPI_MESZ_1024_KBS OSPI_MESZ(19) /*!< the size of external memory is 1024 KBS */ +#define OSPI_MESZ_2_MBS OSPI_MESZ(20) /*!< the size of external memory is 2 MB */ +#define OSPI_MESZ_4_MBS OSPI_MESZ(21) /*!< the size of external memory is 4 MB */ +#define OSPI_MESZ_8_MBS OSPI_MESZ(22) /*!< the size of external memory is 8 MB */ +#define OSPI_MESZ_16_MBS OSPI_MESZ(23) /*!< the size of external memory is 16 MB */ +#define OSPI_MESZ_32_MBS OSPI_MESZ(24) /*!< the size of external memory is 32 MB */ +#define OSPI_MESZ_64_MBS OSPI_MESZ(25) /*!< the size of external memory is 64 MB */ +#define OSPI_MESZ_128_MBS OSPI_MESZ(26) /*!< the size of external memory is 128 MB */ +#define OSPI_MESZ_256_MBS OSPI_MESZ(27) /*!< the size of external memory is 256 MB */ +#define OSPI_MESZ_512_MBS OSPI_MESZ(28) /*!< the size of external memory is 512 MB */ +#define OSPI_MESZ_1024_MBS OSPI_MESZ(29) /*!< the size of external memory is 1024 MB */ +#define OSPI_MESZ_2048_MBS OSPI_MESZ(30) /*!< the size of external memory is 2048 MB */ +#define OSPI_MESZ_4096_MBS OSPI_MESZ(31) /*!< the size of external memory is 4096 MB */ + +/* OSPI device type select */ +#define OSPI_DTYSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24U)) +#define OSPI_MICRON_MODE OSPI_DTYSEL(0) /*!< device type select micron mode */ +#define OSPI_MACRONIX_MODE OSPI_DTYSEL(1) /*!< device type select micronix mode */ +#define OSPI_STANDARD_MODE OSPI_DTYSEL(2) /*!< device type select standard mode */ +#define OSPI_MACRONIX_RAM_MODE OSPI_DTYSEL(3) /*!< device type select micronix ram mode */ +#define OSPI_RESERVE_MODE OSPI_DTYSEL(7) /*!< reserve mode, not use */ + +/* OSPI prescaler set */ +#define OSPI_PSC(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) + +/* OSPI wrap size set */ +#define OSPI_WPSZ(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) +#define OSPI_DIRECT OSPI_WPSZ(0) /*!< external memory indirect device does not support wrap read */ +#define OSPI_WRAP_16BYTES OSPI_WPSZ(2) /*!< external memory device supports wrap size of 16 bytes */ +#define OSPI_WRAP_32BYTES OSPI_WPSZ(3) /*!< external memory device supports wrap size of 32 bytes */ +#define OSPI_WRAP_64BYTES OSPI_WPSZ(4) /*!< external memory device supports wrap size of 64 bytes */ +#define OSPI_WRAP_128BYTES OSPI_WPSZ(5) /*!< external memory device supports wrap size of 128 bytes */ + +/* OSPI transmit configuration */ +/* OSPI operation type */ +#define OSPI_OPTYPE_COMMON_CFG ((uint32_t)0x00000000U) /*!< common configuration (indirect or auto-polling mode) */ +#define OSPI_OPTYPE_READ_CFG ((uint32_t)0x00000001U) /*!< read configuration (memory-mapped mode) */ +#define OSPI_OPTYPE_WRITE_CFG ((uint32_t)0x00000002U) /*!< write configuration (memory-mapped mode) */ +#define OSPI_OPTYPE_WRAP_CFG ((uint32_t)0x00000003U) /*!< wrap configuration (memory-mapped mode) */ + +/* OSPI instruction mode */ +#define OSPI_IMOD(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define OSPI_INSTRUCTION_NONE OSPI_IMOD(0) /*!< no instruction mode */ +#define OSPI_INSTRUCTION_1_LINE OSPI_IMOD(1) /*!< instruction mode on a single line */ +#define OSPI_INSTRUCTION_2_LINES OSPI_IMOD(2) /*!< instruction mode on two lines */ +#define OSPI_INSTRUCTION_4_LINES OSPI_IMOD(3) /*!< instruction mode on four lines */ +#define OSPI_INSTRUCTION_8_LINES OSPI_IMOD(4) /*!< instruction mode on eight lines */ + +/* OSPI instruction size */ +#define OSPI_INSSZ(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define OSPI_INSTRUCTION_8_BITS OSPI_INSSZ(0) /*!< instruction size on 8-bit address */ +#define OSPI_INSTRUCTION_16_BITS OSPI_INSSZ(1) /*!< instruction size on 16-bit address */ +#define OSPI_INSTRUCTION_24_BITS OSPI_INSSZ(2) /*!< instruction size on 24-bit address */ +#define OSPI_INSTRUCTION_32_BITS OSPI_INSSZ(3) /*!< instruction size on 32-bit address */ + +/* OSPI address mode */ +#define OSPI_ADDRMOD(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) +#define OSPI_ADDRESS_NONE OSPI_ADDRMOD(0) /*!< no address mode */ +#define OSPI_ADDRESS_1_LINE OSPI_ADDRMOD(1) /*!< address mode on a single line */ +#define OSPI_ADDRESS_2_LINES OSPI_ADDRMOD(2) /*!< address mode on two lines */ +#define OSPI_ADDRESS_4_LINES OSPI_ADDRMOD(3) /*!< address mode on four lines */ +#define OSPI_ADDRESS_8_LINES OSPI_ADDRMOD(4) /*!< address mode on eight lines */ + +/* OSPI address size */ +#define OSPI_ADDRSZ(regval) (BITS(12,13) & ((uint32_t)(regval) << 12U)) +#define OSPI_ADDRESS_8_BITS OSPI_ADDRSZ(0) /*!< address size on 8-bit address */ +#define OSPI_ADDRESS_16_BITS OSPI_ADDRSZ(1) /*!< address size on 16-bit address */ +#define OSPI_ADDRESS_24_BITS OSPI_ADDRSZ(2) /*!< address size on 24-bit address */ +#define OSPI_ADDRESS_32_BITS OSPI_ADDRSZ(3) /*!< address size on 32-bit address */ + +/* OSPI address double transfer rate */ +#define OSPI_ADDRDTR_MODE_DISABLE 0x00000000U /*!< address double transfer rate mode disable */ +#define OSPI_ADDRDTR_MODE_ENABLE OSPI_TCFG_ADDRDTR /*!< address double transfer rate mode disable */ + +/* OSPI alternate bytes mode */ +#define OSPI_ALTEMOD(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) +#define OSPI_ALTERNATE_BYTES_NONE OSPI_ALTEMOD(0) /*!< no alternate bytes mode */ +#define OSPI_ALTERNATE_BYTES_1_LINE OSPI_ALTEMOD(1) /*!< alternate bytes mode on a single line */ +#define OSPI_ALTERNATE_BYTES_2_LINES OSPI_ALTEMOD(2) /*!< alternate bytes mode on two lines */ +#define OSPI_ALTERNATE_BYTES_4_LINES OSPI_ALTEMOD(3) /*!< alternate bytes mode on four lines */ +#define OSPI_ALTERNATE_BYTES_8_LINES OSPI_ALTEMOD(4) /*!< alternate bytes mode on eight lines */ + +/* OSPI alternate bytes size */ +#define OSPI_ALTESZ(regval) (BITS(20,21) & ((uint32_t)(regval) << 20U)) +#define OSPI_ALTERNATE_BYTES_8_BITS OSPI_ALTESZ(0) /*!< alternate bytes size on 8-bit address */ +#define OSPI_ALTERNATE_BYTES_16_BITS OSPI_ALTESZ(1) /*!< alternate bytes size on 16-bit address */ +#define OSPI_ALTERNATE_BYTES_24_BITS OSPI_ALTESZ(2) /*!< alternate bytes size on 24-bit address */ +#define OSPI_ALTERNATE_BYTES_32_BITS OSPI_ALTESZ(3) /*!< alternate bytes size on 32-bit address */ + +/* OSPI alternate bytes double transfer rate */ +#define OSPI_ABDTR_MODE_DISABLE 0x00000000U /*!< alternate bytes double transfer rate mode disable */ +#define OSPI_ABDTR_MODE_ENABLE OSPI_TCFG_ABDTR /*!< alternate bytes double transfer rate mode enable */ + +/* OSPI data mode */ +#define OSPI_DATAMOD(regval) (BITS(24,26) & ((uint32_t)(regval) << 24U)) +#define OSPI_DATA_NONE OSPI_DATAMOD(0) /*!< no data mode */ +#define OSPI_DATA_1_LINE OSPI_DATAMOD(1) /*!< data mode on a single line */ +#define OSPI_DATA_2_LINES OSPI_DATAMOD(2) /*!< data mode on two lines */ +#define OSPI_DATA_4_LINES OSPI_DATAMOD(3) /*!< data mode on four lines */ +#define OSPI_DATA_8_LINES OSPI_DATAMOD(4) /*!< data mode on eight lines */ + +/* OSPI data double transfer rate */ +#define OSPI_DADTR_MODE_DISABLE 0x00000000U /*!< data double transfer rate mode disable */ +#define OSPI_DADTR_MODE_ENABLE OSPI_TCFG_DADTR /*!< data double transfer rate mode enable */ + +/* OSPI dummy cycles */ +#define OSPI_DUMYC(regval) (BITS(0,4) & ((uint32_t)(regval) << 0U)) +#define OSPI_DUMYC_CYCLES_0 OSPI_DUMYC(0) /*!< duration of the dummy instruction phase is 0 cycle */ +#define OSPI_DUMYC_CYCLES_1 OSPI_DUMYC(1) /*!< duration of the dummy instruction phase is 1 cycle */ +#define OSPI_DUMYC_CYCLES_2 OSPI_DUMYC(2) /*!< duration of the dummy instruction phase is 2 cycle */ +#define OSPI_DUMYC_CYCLES_3 OSPI_DUMYC(3) /*!< duration of the dummy instruction phase is 3 cycle */ +#define OSPI_DUMYC_CYCLES_4 OSPI_DUMYC(4) /*!< duration of the dummy instruction phase is 4 cycle */ +#define OSPI_DUMYC_CYCLES_5 OSPI_DUMYC(5) /*!< duration of the dummy instruction phase is 5 cycle */ +#define OSPI_DUMYC_CYCLES_6 OSPI_DUMYC(6) /*!< duration of the dummy instruction phase is 6 cycle */ +#define OSPI_DUMYC_CYCLES_7 OSPI_DUMYC(7) /*!< duration of the dummy instruction phase is 7 cycle */ +#define OSPI_DUMYC_CYCLES_8 OSPI_DUMYC(8) /*!< duration of the dummy instruction phase is 8 cycle */ +#define OSPI_DUMYC_CYCLES_9 OSPI_DUMYC(9) /*!< duration of the dummy instruction phase is 9 cycle */ +#define OSPI_DUMYC_CYCLES_10 OSPI_DUMYC(10) /*!< duration of the dummy instruction phase is 10 cycle */ +#define OSPI_DUMYC_CYCLES_11 OSPI_DUMYC(11) /*!< duration of the dummy instruction phase is 11 cycle */ +#define OSPI_DUMYC_CYCLES_12 OSPI_DUMYC(12) /*!< duration of the dummy instruction phase is 12 cycle */ +#define OSPI_DUMYC_CYCLES_13 OSPI_DUMYC(13) /*!< duration of the dummy instruction phase is 13 cycle */ +#define OSPI_DUMYC_CYCLES_14 OSPI_DUMYC(14) /*!< duration of the dummy instruction phase is 14 cycle */ +#define OSPI_DUMYC_CYCLES_15 OSPI_DUMYC(15) /*!< duration of the dummy instruction phase is 15 cycle */ +#define OSPI_DUMYC_CYCLES_16 OSPI_DUMYC(16) /*!< duration of the dummy instruction phase is 16 cycle */ +#define OSPI_DUMYC_CYCLES_17 OSPI_DUMYC(17) /*!< duration of the dummy instruction phase is 17 cycle */ +#define OSPI_DUMYC_CYCLES_18 OSPI_DUMYC(18) /*!< duration of the dummy instruction phase is 18 cycle */ +#define OSPI_DUMYC_CYCLES_19 OSPI_DUMYC(19) /*!< duration of the dummy instruction phase is 19 cycle */ +#define OSPI_DUMYC_CYCLES_20 OSPI_DUMYC(20) /*!< duration of the dummy instruction phase is 20 cycle */ +#define OSPI_DUMYC_CYCLES_21 OSPI_DUMYC(21) /*!< duration of the dummy instruction phase is 21 cycle */ +#define OSPI_DUMYC_CYCLES_22 OSPI_DUMYC(22) /*!< duration of the dummy instruction phase is 22 cycle */ +#define OSPI_DUMYC_CYCLES_23 OSPI_DUMYC(23) /*!< duration of the dummy instruction phase is 23 cycle */ +#define OSPI_DUMYC_CYCLES_24 OSPI_DUMYC(24) /*!< duration of the dummy instruction phase is 24 cycle */ +#define OSPI_DUMYC_CYCLES_25 OSPI_DUMYC(25) /*!< duration of the dummy instruction phase is 25 cycle */ +#define OSPI_DUMYC_CYCLES_26 OSPI_DUMYC(26) /*!< duration of the dummy instruction phase is 26 cycle */ +#define OSPI_DUMYC_CYCLES_27 OSPI_DUMYC(27) /*!< duration of the dummy instruction phase is 27 cycle */ +#define OSPI_DUMYC_CYCLES_28 OSPI_DUMYC(28) /*!< duration of the dummy instruction phase is 28 cycle */ +#define OSPI_DUMYC_CYCLES_29 OSPI_DUMYC(29) /*!< duration of the dummy instruction phase is 29 cycle */ +#define OSPI_DUMYC_CYCLES_30 OSPI_DUMYC(30) /*!< duration of the dummy instruction phase is 30 cycle */ +#define OSPI_DUMYC_CYCLES_31 OSPI_DUMYC(31) /*!< duration of the dummy instruction phase is 31 cycle */ + +/* OSPI delay hold quarter cycle */ +#define OSPI_DELAY_HOLD_NONE 0x00000000U /*!< OSPI no delay hold cycle */ +#define OSPI_DELAY_HOLD_QUARTER_CYCLE OSPI_TIMCFG_DEHQC /*!< OSPI delay hold 1/4 cycle */ + +/* OSPI sample shift */ +#define OSPI_SAMPLE_SHIFTING_NONE 0x00000000U /*!< OSPI no sample shift */ +#define OSPI_SAMPLE_SHIFTING_HALF_CYCLE OSPI_TIMCFG_SSAMPLE /*!< OSPI have 1/2 cycle sample shift */ + +/* OSPI interrupt constants definitions */ +#define OSPI_INT_TERR OSPI_CTL_TERRIE /*!< transfer error interrupt enable */ +#define OSPI_INT_TC OSPI_CTL_TCIE /*!< transfer complete interrupt enable */ +#define OSPI_INT_FT OSPI_CTL_FTIE /*!< fifo threshold interrupt enable */ +#define OSPI_INT_SM OSPI_CTL_SMIE /*!< status match interrupt enable */ + +/* OSPI flag definitions */ +#define OSPI_FLAG_TERR OSPI_STAT_TERR /*!< transfer error flag */ +#define OSPI_FLAG_TC OSPI_STAT_TC /*!< transfer complete flag */ +#define OSPI_FLAG_FT OSPI_STAT_FT /*!< fifo threshold flag */ +#define OSPI_FLAG_SM OSPI_STAT_SM /*!< status match flag */ +#define OSPI_FLAG_BUSY OSPI_STAT_BUSY /*!< busy flag */ + +/* define the OSPI bit position and its register index offset */ +#define OSPI_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define OSPI_REG_VAL(ospix, offset) (REG32((ospix) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define OSPI_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define OSPI_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define OSPI_REG_VAL2(ospix, offset) (REG32((ospix) + ((uint32_t)(offset) >> 22))) +#define OSPI_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define OSPI_CTL_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL register offset */ +#define OSPI_STAT_REG_OFFSET ((uint32_t)0x00000020U) /*!< STAT register offset */ + +/* OSPI interrupt flags */ +typedef enum { + OSPI_INT_FLAG_TERR = OSPI_REGIDX_BIT2(OSPI_CTL_REG_OFFSET, 16U, OSPI_STAT_REG_OFFSET, 0U), /*!< transfer error interrupt flag */ + OSPI_INT_FLAG_TC = OSPI_REGIDX_BIT2(OSPI_CTL_REG_OFFSET, 17U, OSPI_STAT_REG_OFFSET, 1U), /*!< transfer complete interrupt enable */ + OSPI_INT_FLAG_FT = OSPI_REGIDX_BIT2(OSPI_CTL_REG_OFFSET, 18U, OSPI_STAT_REG_OFFSET, 2U), /*!< fifo threshold interrupt flag */ + OSPI_INT_FLAG_SM = OSPI_REGIDX_BIT2(OSPI_CTL_REG_OFFSET, 19U, OSPI_STAT_REG_OFFSET, 3U), /*!< status match interrupt flag */ +} ospi_interrupt_flag_enum; + +/* function declarations */ +/* deinitialization initialization functions */ +/* reset OSPI */ +void ospi_deinit(uint32_t ospi_periph); +/* initialize the parameters of OSPI struct with the default values */ +void ospi_struct_init(ospi_parameter_struct *ospi_struct); +/* initialize OSPI parameter */ +void ospi_init(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct); +/* enable OSPI */ +void ospi_enable(uint32_t ospi_periph); +/* disable OSPI */ +void ospi_disable(uint32_t ospi_periph); + +/* device configuration functions */ +/* configure device memory type */ +void ospi_device_memory_type_config(uint32_t ospi_periph, uint32_t dtysel); +/* configure device memory size */ +void ospi_device_memory_size_config(uint32_t ospi_periph, uint32_t mesz); + +/* functional mode functions */ +/* select functional mode */ +void ospi_functional_mode_config(uint32_t ospi_periph, uint32_t fmod); +/* configure status polling mode */ +void ospi_status_polling_config(uint32_t ospi_periph, uint32_t stop, uint32_t mode); +/* configure status mask */ +void ospi_status_mask_config(uint32_t ospi_periph, uint32_t mask); +/* configure status match */ +void ospi_status_match_config(uint32_t ospi_periph, uint32_t match); +/* configure interval cycle */ +void ospi_interval_cycle_config(uint32_t ospi_periph, uint16_t interval); + +/* OSPI mode functions */ +/* configure OSPI fifo threshold level */ +void ospi_fifo_level_config(uint32_t ospi_periph, uint32_t ftl); +/* configure chip select high cycle */ +void ospi_chip_select_high_cycle_config(uint32_t ospi_periph, uint32_t cshc); +/* configure OSPI prescaler */ +void ospi_prescaler_config(uint32_t ospi_periph, uint32_t psc); +/* configure send instruction only once mode */ +void ospi_send_instruction_mode_config(uint32_t ospi_periph, uint32_t sioo); +/* configure dummy cycles number */ +void ospi_dummy_cycles_config(uint32_t ospi_periph, uint32_t dumyc); +/* configure delay hold 1/4 cycle */ +void ospi_delay_hold_cycle_config(uint32_t ospi_periph, uint32_t dehqc); +/* configure sample shift */ +void ospi_sample_shift_config(uint32_t ospi_periph, uint32_t ssample); + +/* OSPI tansfer configuration functions */ +/* configure data length */ +void ospi_data_length_config(uint32_t ospi_periph, uint32_t dtlen); +/* configure OSPI instruction */ +void ospi_instruction_config(uint32_t ospi_periph, uint32_t instruction); +/* configure OSPI instruction mode */ +void ospi_instruction_mode_config(uint32_t ospi_periph, uint32_t imod); +/* configure OSPI instruction size */ +void ospi_instruction_size_config(uint32_t ospi_periph, uint32_t inssz); +/* configure OSPI address */ +void ospi_address_config(uint32_t ospi_periph, uint32_t addr); +/* configure OSPI address mode */ +void ospi_address_mode_config(uint32_t ospi_periph, uint32_t addrmod); +/* configure OSPI address dtr */ +void ospi_address_dtr_config(uint32_t ospi_periph, uint32_t addrdtr); +/* configure OSPI address size */ +void ospi_address_size_config(uint32_t ospi_periph, uint32_t addrsz); +/* configure alternate byte */ +void ospi_alternate_byte_config(uint32_t ospi_periph, uint32_t alte); +/* configure OSPI alternate byte mode */ +void ospi_alternate_byte_mode_config(uint32_t ospi_periph, uint32_t atlemod); +/* configure OSPI alternate byte dtr */ +void ospi_alternate_byte_dtr_config(uint32_t ospi_periph, uint32_t abdtr); +/* configure OSPI alternate byte size */ +void ospi_alternate_byte_size_config(uint32_t ospi_periph, uint32_t altesz); +/* configure data mode */ +void ospi_data_mode_config(uint32_t ospi_periph, uint32_t datamod); +/* configure data size */ +void ospi_data_dtr_config(uint32_t ospi_periph, uint32_t dadtr); +/* OSPI transmit data */ +void ospi_data_transmit(uint32_t ospi_periph, uint32_t data); +/* OSPI receive data */ +uint32_t ospi_data_receive(uint32_t ospi_periph); + +/* OSPI DMA functions */ +/* enable OSPI DMA */ +void ospi_dma_enable(uint32_t ospi_periph); +/* disable OSPI DMA */ +void ospi_dma_disable(uint32_t ospi_periph); + +/* OSPI wrap configuration functions */ +/* configure wrap size */ +void ospi_wrap_size_config(uint32_t ospi_periph, uint32_t wpsz); +/* configure wrap instruction */ +void ospi_wrap_instruction_config(uint32_t ospi_periph, uint32_t instruction); +/* configure wrap instruction mode */ +void ospi_wrap_instruction_mode_config(uint32_t ospi_periph, uint32_t imod); +/* configure wrap instruction size */ +void ospi_wrap_instruction_size_config(uint32_t ospi_periph, uint32_t inssz); +/* configure wrap address */ +void ospi_wrap_address_config(uint32_t ospi_periph, uint32_t addr); +/* configure wrap address mode */ +void ospi_wrap_address_mode_config(uint32_t ospi_periph, uint32_t addrmod); +/* configure wrap address dtr */ +void ospi_wrap_address_dtr_config(uint32_t ospi_periph, uint32_t addrdtr); +/* configure wrap address size */ +void ospi_wrap_address_size_config(uint32_t ospi_periph, uint32_t addrsz); +/* configure wrap alternate byte */ +void ospi_wrap_alternate_byte_config(uint32_t ospi_periph, uint32_t alte); +/* configure wrap alternate bytes mode */ +void ospi_wrap_alternate_byte_mode_config(uint32_t ospi_periph, uint32_t atlemod); +/* configure wrap alternate bytes dtr */ +void ospi_wrap_alternate_byte_dtr_config(uint32_t ospi_periph, uint32_t abdtr); +/* configure wrap alternate bytes mode */ +void ospi_wrap_alternate_byte_size_config(uint32_t ospi_periph, uint32_t altesz); +/* configure wrap data mode */ +void ospi_wrap_data_mode_config(uint32_t ospi_periph, uint32_t datamod); +/* configure wrap data mode */ +void ospi_wrap_data_dtr_config(uint32_t ospi_periph, uint32_t dadtr); + +/* configure wrap dummy cycles number */ +void ospi_wrap_dummy_cycles_config(uint32_t ospi_periph, uint32_t dumyc); +/* delay hold 1/4 cycle in wrap */ +void ospi_wrap_delay_hold_cycle_config(uint32_t ospi_periph, uint32_t dehqc); +/* configure sample shift in wrap */ +void ospi_wrap_sample_shift_config(uint32_t ospi_periph, uint32_t ssample); + +/* OSPI write configure functions */ +/* configure write instruction */ +void ospi_write_instruction_config(uint32_t ospi_periph, uint32_t instruction); +/* configure write instruction mode */ +void ospi_write_instruction_mode_config(uint32_t ospi_periph, uint32_t imod); +/* configure write instruction size */ +void ospi_write_instruction_size_config(uint32_t ospi_periph, uint32_t inssz); +/* configure write address */ +void ospi_write_address_config(uint32_t ospi_periph, uint32_t addr); +/* configure write address mode */ +void ospi_write_address_mode_config(uint32_t ospi_periph, uint32_t addrmod); +/* configure write address dtr */ +void ospi_write_address_dtr_config(uint32_t ospi_periph, uint32_t addrdtr); +/* configure write address size */ +void ospi_write_address_size_config(uint32_t ospi_periph, uint32_t addrsz); +/* configure write alternate bytes mode */ +void ospi_write_alternate_byte_config(uint32_t ospi_periph, uint32_t alte); +/* configure write alternate byte mode */ +void ospi_write_alternate_byte_mode_config(uint32_t ospi_periph, uint32_t atlemod); +/* configure write alternate byte dtr */ +void ospi_write_alternate_byte_dtr_config(uint32_t ospi_periph, uint32_t abdtr); +/* configure write alternate byte size */ +void ospi_write_alternate_byte_size_config(uint32_t ospi_periph, uint32_t altesz); +/* configure write data mode */ +void ospi_write_data_mode_config(uint32_t ospi_periph, uint32_t datamod); +/* configure write data dtr */ +void ospi_write_data_dtr_config(uint32_t ospi_periph, uint32_t dadtr); +/* configure write dummy cycles number */ +void ospi_write_dummy_cycles_config(uint32_t ospi_periph, uint32_t dumyc); + +/* configure OSPI regular command parameter */ +void ospi_command_config(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct, ospi_regular_cmd_struct *cmd_struct); +/* transmit data */ +void ospi_transmit(uint32_t ospi_periph, uint8_t *pdata); +/* receive data */ +void ospi_receive(uint32_t ospi_periph, uint8_t *pdata); +/* configure the OSPI automatic polling mode */ +void ospi_autopolling_mode(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct, ospi_autopolling_struct *autopl_cfg_struct); + +/* flag & interrupt functions */ +/* enable OSPI interrupt */ +void ospi_interrupt_enable(uint32_t ospi_periph, uint32_t interrupt); +/* disable OSPI interrupt */ +void ospi_interrupt_disable(uint32_t ospi_periph, uint32_t interrupt); +/* get OSPI fifo level */ +uint32_t ospi_fifo_level_get(uint32_t ospi_periph); +/* get OSPI flag status */ +FlagStatus ospi_flag_get(uint32_t ospi_periph, uint32_t flag); +/* clear OSPI flag status */ +void ospi_flag_clear(uint32_t ospi_periph, uint32_t flag); +/* get OSPI interrupt status */ +FlagStatus ospi_interrupt_flag_get(uint32_t ospi_periph, uint32_t int_flag); +/* clear OSPI interrupt flag status */ +void ospi_interrupt_flag_clear(uint32_t ospi_periph, uint32_t int_flag); + +#endif /* GD32H7XX_OSPI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospim.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospim.h new file mode 100644 index 0000000000..bae120015d --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_ospim.h @@ -0,0 +1,125 @@ +/*! + \file gd32h7xx_ospim.h + \brief definitions for the OSPIM + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_OSPIM_H +#define GD32H7XX_OSPIM_H + +#include "gd32h7xx.h" + +/* OSPIM definitions */ +#define OSPIM OSPM_BASE + +#define OSPIM_PCFG0 REG32(OSPIM + 0x00000004U) /*!< OSPI I/O manager port configuration register 0 */ +#define OSPIM_PCFG1 REG32(OSPIM + 0x00000008U) /*!< OSPI I/O manager port configuration register 1 */ + +/* OSPIM_PCFG */ +#define OSPIM_PCFG_SCKEN BIT(0) /*!< enable for sck of port n */ +#define OSPIM_PCFG_SRCPCK BIT(1) /*!< source selection for sck of port n */ +#define OSPIM_PCFG_NCSEN BIT(8) /*!< enable for csn of port n */ +#define OSPIM_PCFG_SRCPCS BIT(9) /*!< source selection for csn of port n */ +#define OSPIM_PCFG_POLEN BIT(16) /*!< enable for IO[3:0] of port n */ +#define OSPIM_PCFG_SRCPLIO BITS(17,18) /*!< source selection for IO[3:0] of port n */ +#define OSPIM_PCFG_POHEN BIT(24) /*!< enable for IO[7:4] of port n */ +#define OSPIM_PCFG_SRCPHIO BITS(25,26) /*!< source selection for IO[7:4] of port n */ + +/* constants definitions */ +/* ospi io manager configuration struct definitions */ +/* ospim register address */ +#define OSPIM_PCFG(regval) REG32(OSPIM + 0x4U * ((regval) + 1U)) /*!< the address of OSPI manager port configuration register */ + +/* ospim register address */ +#define OSPIM_PORT0 0x00U /*!< OSPI manager port 0 */ +#define OSPIM_PORT1 0x01U /*!< OSPI manager port 1 */ + +/* SCK of port */ +#define OSPIM_PORT_SCK_DISABLE 0x00000000U /*!< disable SCK of port */ +#define OSPIM_PORT_SCK_ENABLE OSPIM_PCFG_SCKEN /*!< disable SCK of port */ + +/* source selection for SCK of port */ +#define OSPIM_SCK_SOURCE_OSPI0_SCK 0x00000000U /*!< the source of SCK is OSPI0_SCK */ +#define OSPIM_SCK_SOURCE_OSPI1_SCK OSPIM_PCFG_SRCPCK /*!< the source of SCK is OSPI1_SCK */ + +/* CSN of port */ +#define OSPIM_PORT_CSN_DISABLE 0x00000000U /*!< disable CSN of port */ +#define OSPIM_PORT_CSN_ENABLE OSPIM_PCFG_NCSEN /*!< enable CSN of port */ + +/* source selection for CSN of port */ +#define OSPIM_CSN_SOURCE_OSPI0_CSN 0x00000000U /*!< the source of CSN is OSPI0_CSN */ +#define OSPIM_CSN_SOURCE_OSPI1_CSN OSPIM_PCFG_SRCPCS /*!< the source of CSN is OSPI1_CSN */ + +/* IO[3:0] of port */ +#define OSPIM_IO_LOW_DISABLE 0x00000000U /*!< disable IO[3:0] of port */ +#define OSPIM_IO_LOW_ENABLE OSPIM_PCFG_POLEN /*!< enable IO[3:0] of port */ + +/* source selection for IO[3:0] of port n */ +#define OSPIM_SRCPLIO(regval) (BITS(17,18) & ((uint32_t)(regval) << 17U)) +#define OSPIM_SRCPLIO_OSPI0_IO_LOW OSPIM_SRCPLIO(0) /*!< select OSPI0_IO[3:0] in non-multiplexed mode, and select multiplexed IO[3:0] in multiplex mode */ +#define OSPIM_SRCPLIO_OSPI0_IO_HIGH OSPIM_SRCPLIO(1) /*!< select OSPI0_IO[7:4] in non-multiplexed mode, and select multiplexed IO[7:4] in multiplex mode */ +#define OSPIM_SRCPLIO_OSPI1_IO_LOW OSPIM_SRCPLIO(2) /*!< select OSPI1_IO[3:0], only valied in non-multiplexed mode */ +#define OSPIM_SRCPLIO_OSPI1_IO_HIGH OSPIM_SRCPLIO(3) /*!< select OSPI1_IO[7:4], only valied in non-multiplexed mode */ + +/* IO[7:4] of port */ +#define OSPIM_IO_HIGH_DISABLE 0x00000000U /*!< disable IO[7:4] of port */ +#define OSPIM_IO_HIGH_ENABLE OSPIM_PCFG_POHEN /*!< enable IO[7:4] of port */ + +/* source selection for IO[7:4] of port n */ +#define OSPIM_SRCPHIO(regval) (BITS(25,26) & ((uint32_t)(regval) << 25U)) +#define OSPIM_SRCPHIO_OSPI0_IO_LOW OSPIM_SRCPHIO(0) /*!< select OSPI0_IO[3:0] in non-multiplexed mode, and select multiplexed IO[3:0] in multiplex mode */ +#define OSPIM_SRCPHIO_OSPI0_IO_HIGH OSPIM_SRCPHIO(1) /*!< select OSPI0_IO[7:4] in non-multiplexed mode, and select multiplexed IO[7:4] in multiplex mode */ +#define OSPIM_SRCPHIO_OSPI1_IO_LOW OSPIM_SRCPHIO(2) /*!< select OSPI1_IO[3:0], only valied in non-multiplexed mode */ +#define OSPIM_SRCPHIO_OSPI1_IO_HIGH OSPIM_SRCPHIO(3) /*!< select OSPI1_IO[7:4], only valied in non-multiplexed mode */ + +/* function declarations */ +/* reset the OSPIM peripheral */ +void ospim_deinit(void); + +/* ospim port configuration functions */ +/* configurate SCK for port */ +void ospim_port_sck_config(uint8_t port, uint32_t sckconfg); +/* select source of SCK for port */ +void ospim_port_sck_source_select(uint8_t port, uint32_t sck_source); +/* configurate CSN for port */ +void ospim_port_csn_config(uint8_t port, uint32_t csnconfig); +/* select source of CSN for port */ +void ospim_port_csn_source_select(uint8_t port, uint32_t csn_source); +/* configurate IO[3:0] for port */ +void ospim_port_io3_0_config(uint8_t port, uint32_t ioconfig); +/* select source of IO[3:0] for port */ +void ospim_port_io3_0_source_select(uint8_t port, uint32_t io_source); +/* configurate IO[7:4] for port */ +void ospim_port_io7_4_config(uint8_t port, uint32_t ioconfig); +/* select source of IO[7:4] for port */ +void ospim_port_io7_4_source_select(uint8_t port, uint32_t io_source); + +#endif /* GD32H7XX_OSPIM_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_pmu.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_pmu.h new file mode 100644 index 0000000000..7da3d9dc13 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_pmu.h @@ -0,0 +1,279 @@ +/*! + \file gd32h7xx_pmu.h + \brief definitions for the PMU + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_PMU_H +#define GD32H7XX_PMU_H + +#include "gd32h7xx.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL0 REG32((PMU) + 0x00000000U) /*!< PMU control register 0 */ +#define PMU_CS REG32((PMU) + 0x00000004U) /*!< PMU control and status register */ +#define PMU_CTL1 REG32((PMU) + 0x00000008U) /*!< PMU control register 1 */ +#define PMU_CTL2 REG32((PMU) + 0x00000010U) /*!< PMU control register 2 */ +#define PMU_CTL3 REG32((PMU) + 0x00000014U) /*!< PMU control register 3 */ +#define PMU_PAR REG32((PMU) + 0x00000018U) /*!< PMU parameter register */ + +/* bits definitions */ +/* PMU_CTL0 */ +#define PMU_CTL0_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL0_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL0_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL0_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL0_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL0_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL0_SLDOVS BITS(14,15) /*!< deep sleep mode mode LDO output voltage select */ +#define PMU_CTL0_VAVDEN BIT(16) /*!< VDDA analog voltage detector enable */ +#define PMU_CTL0_VAVDVC BITS(17,18) /*!< VDDA analog voltage detector level configure bits */ +#define PMU_CTL0_VOVDEN BIT(19) /*!< peripheral voltage on V0.9V detector enable bit */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_WUPEN0 BIT(8) /*!< wakeup pin0(PA0) enable */ +#define PMU_CS_WUPEN1 BIT(9) /*!< wakeup pin1(PA2) enable */ +#define PMU_CS_WUPEN3 BIT(11) /*!< wakeup pin3(PC13) enable */ +#define PMU_CS_WUPEN5 BIT(13) /*!< wakeup pin5(PC1) enable */ +#define PMU_CS_VAVDF BIT(16) /*!< VDDA analog voltage detector voltage output on VDDA flag */ +#define PMU_CS_VOVDF BIT(20) /*!< peripheral voltage on V0.9V detector flag bit */ + +/* PMU_CTL1 */ +#define PMU_CTL1_BKPVSEN BIT(0) /*!< backup voltage stabilizer enable */ +#define PMU_CTL1_VBTMEN BIT(4) /*!< VBAT and temperature monitoring enable */ +#define PMU_CTL1_BKPVSRF BIT(16) /*!< backup regulator ready */ +#define PMU_CTL1_VBATLF BIT(20) /*!< VBAT level monitoring versus low threshold */ +#define PMU_CTL1_VBATHF BIT(21) /*!< VBAT level monitoring versus high threshold */ +#define PMU_CTL1_TEMPLF BIT(22) /*!< temperature level monitoring versus low threshold */ +#define PMU_CTL1_TEMPHF BIT(23) /*!< temperature level monitoring versus high threshold */ + +/* PMU_CTL2 */ +#define PMU_CTL2_BYPASS BIT(0) /*!< power management unit bypass control bit */ +#define PMU_CTL2_LDOEN BIT(1) /*!< Low drop-out voltage stabilizer enable bit */ +#define PMU_CTL2_DVSEN BIT(2) /*!< step-down voltage stabilizer enable bit */ +#define PMU_CTL2_DVSCFG BIT(3) /*!< SMPS step-down converter forced on and in high power MR mode */ +#define PMU_CTL2_DVSVC BITS(4,5) /*!< SMPS step-down converter voltage output level selection */ +#define PMU_CTL2_VCEN BIT(8) /*!< VBAT battery charging enable */ +#define PMU_CTL2_VCRSEL BIT(9) /*!< VBAT battery charging resistor selection */ +#define PMU_CTL2_DVSRF BIT(16) /*!< step-down voltage stabilizer ready flag bit */ +#define PMU_CTL2_VUSB33DEN BIT(24) /*!< VDD33USB voltage level detector enable bit */ +#define PMU_CTL2_USBSEN BIT(25) /*!< USB voltage stabilizer enable */ +#define PMU_CTL2_USB33RF BIT(26) /*!< USB supply ready flag */ + +/* PMU_CTL3 */ +#define PMU_CTL3_LDOVS BITS(12,14) /*!< voltage scaling selection according to performance */ +#define PMU_CTL3_VOVRF BIT(16) /*!< V0.9V voltage ready bit */ + +/* PMU_PAR */ +#define PMU_PAR_CNT BITS(0,11) /*!< exit deep-sleep mode wait time count configure bits */ +#define PMU_PAR_TSW_IRCCNT BITS(16,20) /*!< when enter deep-sleep, switch to IRC wait clock */ + +/* constants definitions */ +/* PMU low voltage detector threshold definitions */ +#define CTL0_LVDT(regval) (BITS(5,7) & ((uint32_t)(regval) << 5U)) +#define PMU_LVDT_0 CTL0_LVDT(0) /*!< voltage threshold is 2.1V */ +#define PMU_LVDT_1 CTL0_LVDT(1) /*!< voltage threshold is 2.3V */ +#define PMU_LVDT_2 CTL0_LVDT(2) /*!< voltage threshold is 2.4V */ +#define PMU_LVDT_3 CTL0_LVDT(3) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_4 CTL0_LVDT(4) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_5 CTL0_LVDT(5) /*!< voltage threshold is 2.9V */ +#define PMU_LVDT_6 CTL0_LVDT(6) /*!< voltage threshold is 3.0V */ +#define PMU_LVDT_7 CTL0_LVDT(7) /*!< input analog voltage on PB7 (compared with 0.8V) */ + +/* PMU deep-sleep mode voltage scaling selection */ +#define CTL0_SLDOVS(regval) (BITS(14,15) & ((uint32_t)(regval) << 14U)) +#define PMU_SLDOVS_0 CTL0_SLDOVS(0) /*!< SLDOVS scale 0.6V */ +#define PMU_SLDOVS_1 CTL0_SLDOVS(1) /*!< SLDOVS scale 0.7V */ +#define PMU_SLDOVS_2 CTL0_SLDOVS(2) /*!< SLDOVS scale 0.8V (default) */ +#define PMU_SLDOVS_3 CTL0_SLDOVS(3) /*!< SLDOVS scale 0.9V */ + +/* PMU analog voltage detector threshold definitions */ +#define CTL0_VAVDVC(regval) (BITS(17,18) & ((uint32_t)(regval) << 17U)) +#define PMU_VAVDVC_0 CTL0_VAVDVC(0) /*!< voltage threshold is 1.7V */ +#define PMU_VAVDVC_1 CTL0_VAVDVC(1) /*!< voltage threshold is 2.1V */ +#define PMU_VAVDVC_2 CTL0_VAVDVC(2) /*!< voltage threshold is 2.5V */ +#define PMU_VAVDVC_3 CTL0_VAVDVC(3) /*!< voltage threshold is 2.8V */ + +/* PMU step-down voltage stabilizer output level definitions */ +#define CTL2_DVSVC(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define PMU_STEPDOWNVOL_1P8 CTL2_DVSVC(1) /*!< SMPS step-down converter voltage output level 1.8V */ +#define PMU_STEPDOWNVOL_2P5 CTL2_DVSVC(2) /*!< SMPS step-down converter voltage output level 2.5V */ + +/* PMU VBAT battery charging resistor selection */ +#define CTL2_VCRSEL(regval) (BIT(9) & ((uint32_t)(regval) << 9U)) +#define PMU_VCRSEL_5K CTL2_VCRSEL(0) /*!< 5 kOhms resistor is selected for charing VBAT battery */ +#define PMU_VCRSEL_1P5K CTL2_VCRSEL(1) /*!< 1.5 kOhms resistor is selected for charing VBAT battery */ + +/* PMU LDO output voltage select definitions */ +#define CTL3_LDOVS(regval) (BITS(12,14) & ((uint32_t)(regval) << 12U)) +#define PMU_LDOVS_0 CTL3_LDOVS(0) /*!< LDO output voltage 0.8V mode */ +#define PMU_LDOVS_1 CTL3_LDOVS(1) /*!< LDO output voltage 0.85V mode */ +#define PMU_LDOVS_2 CTL3_LDOVS(2) /*!< LDO output voltage 0.9V mode */ +#define PMU_LDOVS_3 CTL3_LDOVS(3) /*!< LDO output voltage 0.95V mode */ +#define PMU_LDOVS_4 CTL3_LDOVS(4) /*!< LDO output voltage 0.975V mode */ +#define PMU_LDOVS_5 CTL3_LDOVS(5) /*!< LDO output voltage 1V mode */ + +/* PMU flag definitions */ +#define PMU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define PMU_REG_VAL(periph) (REG32(PMU + ((uint32_t)(periph) >> 6U))) +#define PMU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +#define PMU_CTL0_OFFSET (0x00000000U) /*!< PMU control register 0 offset */ +#define PMU_CS_OFFSET (0x00000004U) /*!< PMU control and status register offset */ +#define PMU_CTL1_OFFSET (0x00000008U) /*!< PMU control register 1 offset */ +#define PMU_CTL2_OFFSET (0x00000010U) /*!< PMU control register 2 offset */ +#define PMU_CTL3_OFFSET (0x00000014U) /*!< PMU control register 3 offset */ +#define PMU_PAR_OFFSET (0x00000018U) /*!< PMU parameter register offset */ + +#define PMU_FLAG_WAKEUP PMU_REGIDX_BIT(PMU_CS_OFFSET, 0) /*!< wakeup flag */ +#define PMU_FLAG_STANDBY PMU_REGIDX_BIT(PMU_CS_OFFSET, 1) /*!< standby flag */ +#define PMU_FLAG_LVDF PMU_REGIDX_BIT(PMU_CS_OFFSET, 2) /*!< low voltage detector status flag */ +#define PMU_FLAG_VAVDF PMU_REGIDX_BIT(PMU_CS_OFFSET, 16) /*!< VDDA analog voltage detector voltage output on VDDA flag */ +#define PMU_FLAG_VOVDF PMU_REGIDX_BIT(PMU_CS_OFFSET, 20) /*!< peripheral voltage on VDDA detector flag */ +#define PMU_FLAG_BKPVSRF PMU_REGIDX_BIT(PMU_CTL1_OFFSET, 16) /*!< backup voltage stabilizer ready flag */ +#define PMU_FLAG_VBATLF PMU_REGIDX_BIT(PMU_CTL1_OFFSET, 20) /*!< VBAT level monitoring versus low threshold */ +#define PMU_FLAG_VBATHF PMU_REGIDX_BIT(PMU_CTL1_OFFSET, 21) /*!< VBAT level monitoring versus high threshold */ +#define PMU_FLAG_TEMPLF PMU_REGIDX_BIT(PMU_CTL1_OFFSET, 22) /*!< temperature level monitoring versus low threshold */ +#define PMU_FLAG_TEMPHF PMU_REGIDX_BIT(PMU_CTL1_OFFSET, 23) /*!< temperature level monitoring versus high threshold */ +#define PMU_FLAG_DVSRF PMU_REGIDX_BIT(PMU_CTL2_OFFSET, 16) /*!< step-down voltage stabilizer ready flag bit */ +#define PMU_FLAG_USB33RF PMU_REGIDX_BIT(PMU_CTL2_OFFSET, 26) /*!< USB supply ready flag bit */ +#define PMU_FLAG_PWRRF PMU_REGIDX_BIT(PMU_CTL3_OFFSET, 16) /*!< Power Ready flag bit */ + +/* PMU wakeup pin definitions */ +#define PMU_WAKEUP_PIN0 PMU_CS_WUPEN0 /*!< wakeup pin 0 */ +#define PMU_WAKEUP_PIN1 PMU_CS_WUPEN1 /*!< wakeup pin 1 */ +#define PMU_WAKEUP_PIN3 PMU_CS_WUPEN3 /*!< wakeup pin 3 */ +#define PMU_WAKEUP_PIN5 PMU_CS_WUPEN5 /*!< wakeup pin 5 */ + +/* PMU SMPS LDO supply mode definitions */ +#define PMU_LDO_SUPPLY PMU_CTL2_LDOEN /*!< V0.9V domains are suppplied from the LDO */ +#define PMU_DIRECT_SMPS_SUPPLY PMU_CTL2_DVSEN /*!< V0.9V domains are suppplied from the SMPS only */ +#define PMU_SMPS_1V8_SUPPLIES_LDO (PMU_STEPDOWNVOL_1P8 | PMU_CTL2_DVSEN | PMU_CTL2_LDOEN) /*!< The SMPS 1.8V output supplies the LDO which supplies the V0.9V domains */ +#define PMU_SMPS_2V5_SUPPLIES_LDO (PMU_STEPDOWNVOL_2P5 | PMU_CTL2_DVSEN | PMU_CTL2_LDOEN) /*!< The SMPS 2.5V output supplies the LDO which supplies the V0.9V domains */ +#define PMU_SMPS_1V8_SUPPLIES_EXT_AND_LDO (PMU_STEPDOWNVOL_1P8 | PMU_CTL2_DVSCFG | PMU_CTL2_DVSEN | PMU_CTL2_LDOEN) /*!< The SMPS 1.8V output supplies an external circuits and the LDO. The V0.9V domains are suppplied from the LDO */ +#define PMU_SMPS_2V5_SUPPLIES_EXT_AND_LDO (PMU_STEPDOWNVOL_2P5 | PMU_CTL2_DVSCFG | PMU_CTL2_DVSEN | PMU_CTL2_LDOEN) /*!< The SMPS 2.5V output supplies an external circuits and the LDO. The V0.9V domains are suppplied from the LDO */ +#define PMU_SMPS_1V8_SUPPLIES_EXT (PMU_STEPDOWNVOL_1P8 | PMU_CTL2_DVSCFG | PMU_CTL2_DVSEN | PMU_CTL2_BYPASS) /*!< The SMPS 1.8V output supplies an external source which supplies the V0.9V domains */ +#define PMU_SMPS_2V5_SUPPLIES_EXT (PMU_STEPDOWNVOL_2P5 | PMU_CTL2_DVSCFG | PMU_CTL2_DVSEN | PMU_CTL2_BYPASS) /*!< The SMPS 2.5V output supplies an external source which supplies the V0.9V domains */ +#define PMU_BYPASS PMU_CTL2_BYPASS /*!< The SMPS disabled and the LDO Bypass. The V0.9V domains are supplied from an external source */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ + +/* function declarations */ +/* reset PMU registers */ +void pmu_deinit(void); + +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* enable PMU lvd */ +void pmu_lvd_enable(void); +/* disable PMU lvd */ +void pmu_lvd_disable(void); +/* select analog voltage detector threshold */ +void pmu_avd_select(uint32_t avdt_n); +/* enable PMU analog voltage detector */ +void pmu_avd_enable(void); +/* disable PMU analog voltage detector */ +void pmu_avd_disable(void); +/* enable PMU core voltage detector */ +void pmu_cvd_enable(void); +/* disable PMU V0.9V core voltage detector */ +void pmu_cvd_disable(void); +/* control the V0.9V core voltage level */ +void pmu_ldo_output_select(uint32_t ldo_n); +/* Deep-sleep mode V0.9V core voltage select */ +void pmu_sldo_output_select(uint32_t sldo_n); + +/* PMU VBAT battery charging resistor selection */ +void pmu_vbat_charging_select(uint32_t resistor); +/* enable VBAT battery charging */ +void pmu_vbat_charging_enable(void); +/* disable VBAT battery charging */ +void pmu_vbat_charging_disable(void); +/* enable VBAT and temperature monitoring */ +void pmu_vbat_temp_moniter_enable(void); +/* disable VBAT and temperature monitoring */ +void pmu_vbat_temp_moniter_disable(void); + +/* USB regulator */ +/* enable USB regulator */ +void pmu_usb_regulator_enable(void); +/* disable USB regulator */ +void pmu_usb_regulator_disable(void); +/* enable VDD33USB voltage level detector */ +void pmu_usb_voltage_detector_enable(void); +/* disable VDD33USB voltage level detector */ +void pmu_usb_voltage_detector_disable(void); + +/* power supply configurations */ +void pmu_smps_ldo_supply_config(uint32_t smpsmode); + +/* set PMU mode */ +/* enter sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* enter deepsleep mode */ +void pmu_to_deepsleepmode(uint8_t deepsleepmodecmd); +/* enter standby mode */ +void pmu_to_standbymode(void); +/* enable PMU wakeup pin */ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin); +/* disable PMU wakeup pin */ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin); + +/* backup related functions */ +/* enable backup domain write */ +void pmu_backup_write_enable(void); +/* disable backup domain write */ +void pmu_backup_write_disable(void); +/* enable backup voltage stabilizer */ +void pmu_backup_voltage_stabilizer_enable(void); +/* disable backup voltage stabilizer */ +void pmu_backup_voltage_stabilizer_disable(void); + +/* configure IRC counter before enter Deep-sleep mode */ +void pmu_enter_deepsleep_wait_time_config(uint32_t wait_time); +/* configure IRC counter before exit Deep-sleep mode */ +void pmu_exit_deepsleep_wait_time_config(uint32_t wait_time); + +/* flag functions */ +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag_reset); + +#endif /* GD32H7XX_PMU_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rameccmu.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rameccmu.h new file mode 100644 index 0000000000..ea7939db2b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rameccmu.h @@ -0,0 +1,181 @@ +/*! + \file gd32h7xx_rameccmu.h + \brief definitions for the RAMECCMU + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_RAMECCMU_H +#define GD32H7XX_RAMECCMU_H + +#include "gd32h7xx.h" + +/* RAMECCMU definitions */ +#define RAMECCMU0 (RAMECCMU_BASE + 0x09FE6000U) /*!< RAMECCMU for Region 0 */ +#define RAMECCMU1 RAMECCMU_BASE /*!< RAMECCMU for Region 1 */ + +/* registers definitions */ +#define RAMECCMU_INT(rameccmux) REG32((rameccmux) + 0x00000000U) /*!< RAMECCMU global interruput register */ + +#define RAMECCMU_M0CTL(rameccmux) REG32((rameccmux) + 0x00000020U) /*!< RAMECCMU monitor 0 control register */ +#define RAMECCMU_M0STAT(rameccmux) REG32((rameccmux) + 0x00000024U) /*!< RAMECCMU monitor 0 status register */ +#define RAMECCMU_M0FADDR(rameccmux) REG32((rameccmux) + 0x00000028U) /*!< RAMECCMU monitor 0 ECC failing address register */ +#define RAMECCMU_M0FDL(rameccmux) REG32((rameccmux) + 0x0000002CU) /*!< RAMECCMU monitor 0 ECC failing data low register */ +#define RAMECCMU_M0FDH(rameccmux) REG32((rameccmux) + 0x00000030U) /*!< RAMECCMU monitor 0 ECC failing data high register */ +#define RAMECCMU_M0FECODE(rameccmux) REG32((rameccmux) + 0x00000034U) /*!< RAMECCMU monitor 0 failing ECC error code register */ + +#define RAMECCMU_M1CTL(rameccmux) REG32((rameccmux) + 0x00000040U) /*!< RAMECCMU monitor 1 control register */ +#define RAMECCMU_M1STAT(rameccmux) REG32((rameccmux) + 0x00000044U) /*!< RAMECCMU monitor 1 status register */ +#define RAMECCMU_M1FADDR(rameccmux) REG32((rameccmux) + 0x00000048U) /*!< RAMECCMU monitor 1 ECC failing address register */ +#define RAMECCMU_M1FDL(rameccmux) REG32((rameccmux) + 0x0000004CU) /*!< RAMECCMU monitor 1 ECC failing data low register */ +#define RAMECCMU_M1FDH(rameccmux) REG32((rameccmux) + 0x00000050U) /*!< RAMECCMU monitor 1 ECC failing data high register */ +#define RAMECCMU_M1FECODE(rameccmux) REG32((rameccmux) + 0x00000054U) /*!< RAMECCMU monitor 1 failing ECC error code register */ + +#define RAMECCMU_M2CTL(rameccmux) REG32((rameccmux) + 0x00000060U) /*!< RAMECCMU monitor 2 control register */ +#define RAMECCMU_M2STAT(rameccmux) REG32((rameccmux) + 0x00000064U) /*!< RAMECCMU monitor 2 status register */ +#define RAMECCMU_M2FADDR(rameccmux) REG32((rameccmux) + 0x00000068U) /*!< RAMECCMU monitor 2 ECC failing address register */ +#define RAMECCMU_M2FDL(rameccmux) REG32((rameccmux) + 0x0000006CU) /*!< RAMECCMU monitor 2 ECC failing data low register */ +#define RAMECCMU_M2FDH(rameccmux) REG32((rameccmux) + 0x00000070U) /*!< RAMECCMU monitor 2 ECC failing data high register */ +#define RAMECCMU_M2FECODE(rameccmux) REG32((rameccmux) + 0x00000074U) /*!< RAMECCMU monitor 2 failing ECC error code register */ + +#define RAMECCMU_M3CTL(rameccmux) REG32((rameccmux) + 0x00000080U) /*!< RAMECCMU monitor 3 control register */ +#define RAMECCMU_M3STAT(rameccmux) REG32((rameccmux) + 0x00000084U) /*!< RAMECCMU monitor 3 status register */ +#define RAMECCMU_M3FADDR(rameccmux) REG32((rameccmux) + 0x00000088U) /*!< RAMECCMU monitor 3 ECC failing address register */ +#define RAMECCMU_M3FDL(rameccmux) REG32((rameccmux) + 0x0000008CU) /*!< RAMECCMU monitor 3 ECC failing data low register */ +#define RAMECCMU_M3FDH(rameccmux) REG32((rameccmux) + 0x00000090U) /*!< RAMECCMU monitor 3 ECC failing data high register */ +#define RAMECCMU_M3FECODE(rameccmux) REG32((rameccmux) + 0x00000094U) /*!< RAMECCMU monitor 3 failing ECC error code register */ + +#define RAMECCMU_M4CTL(rameccmux) REG32((rameccmux) + 0x000000A0U) /*!< RAMECCMU monitor 4 control register */ +#define RAMECCMU_M4STAT(rameccmux) REG32((rameccmux) + 0x000000A4U) /*!< RAMECCMU monitor 4 status register */ +#define RAMECCMU_M4FADDR(rameccmux) REG32((rameccmux) + 0x000000A8U) /*!< RAMECCMU monitor 4 ECC failing address register */ +#define RAMECCMU_M4FDL(rameccmux) REG32((rameccmux) + 0x000000ACU) /*!< RAMECCMU monitor 4 ECC failing data low register */ +#define RAMECCMU_M4FDH(rameccmux) REG32((rameccmux) + 0x000000B0U) /*!< RAMECCMU monitor 4 ECC failing data high register */ +#define RAMECCMU_M4FECODE(rameccmux) REG32((rameccmux) + 0x000000B4U) /*!< RAMECCMU monitor 4 failing ECC error code register */ + +/* bits definitions */ +/* RAMECCMU_INT */ +#define RAMECCMU_INT_GEIE BIT(0) /*!< global ECC interrupt enable */ +#define RAMECCMU_INT_GESERRIE BIT(1) /*!< global ECC single error interrupt enable */ +#define RAMECCMU_INT_GEDERRIE BIT(2) /*!< global ECC double error interrupt enable */ +#define RAMECCMU_INT_GEDERRBWIE BIT(3) /*!< global ECC double error on byte write interrupt enable */ + +/* RAMECCMU_MxCTL */ +#define RAMECCMU_MXCTL_ECCSERRIE BIT(2) /*!< ECC single error interrupt enable */ +#define RAMECCMU_MXCTL_ECCDERRIE BIT(3) /*!< ECC double error interrupt enable */ +#define RAMECCMU_MXCTL_ECCDERRBWIE BIT(4) /*!< ECC double error on byte write interrupt enable */ +#define RAMECCMU_MXCTL_ECCERRLATEN BIT(5) /*!< ECC error latching enable */ + +/* RAMECCMU_MxSTAT */ +#define RAMECCMU_MXSTAT_ECCSERRDCF BIT(0) /*!< ECC single error detected and corrected flag */ +#define RAMECCMU_MXSTAT_ECCDERRDF BIT(1) /*!< ECC double error detected flag */ +#define RAMECCMU_MXSTAT_ECCDERRBWDF BIT(2) /*!< ECC double error on byte write detected flag */ + +/* RAMECCMU_MxFADDR */ +#define RAMECCMU_MXFADDR_ECCFADDR BITS(0,31) /*!< ECC error failing address */ + +/* RAMECCMU_MxFDL */ +#define RAMECCMU_MXFDL_ECCFDL BITS(0,31) /*!< ECC failing data low bits */ + +/* RAMECCMU_MxFDH */ +#define RAMECCMU_MXFDH_ECCFDH BITS(0,31) /*!< ECC failing data high bits */ + +/* RAMECCMU_MxFECODE */ +#define RAMECCMU_MXFECODE_ECCFECODE BITS(0,31) /*!< ECC failing error code */ + +/* constants definitions */ +/* RAMECCMU monitor select */ +typedef enum +{ + RAMECCMU0_MONITOR0 = 0x00U, /*!< RAMECCMU0 monitor 0 */ + RAMECCMU0_MONITOR1 = 0x01U, /*!< RAMECCMU0 monitor 1 */ + RAMECCMU0_MONITOR2 = 0x02U, /*!< RAMECCMU0 monitor 2 */ + RAMECCMU0_MONITOR3 = 0x03U, /*!< RAMECCMU0 monitor 3 */ + RAMECCMU0_MONITOR4 = 0x04U, /*!< RAMECCMU0 monitor 4 */ + RAMECCMU1_MONITOR0 = 0x10U, /*!< RAMECCMU1 monitor 0 */ + RAMECCMU1_MONITOR1 = 0x11U, /*!< RAMECCMU1 monitor 1 */ + RAMECCMU1_MONITOR2 = 0x12U /*!< RAMECCMU1 monitor 2 */ +} rameccmu_monitor_enum; + +/* RAMECCMUx monitor register address */ +#define RAMECCMU_MXCTL(rameccmu_monitor) REG32(RAMECCMU0 - ((uint32_t)(rameccmu_monitor) >> 4U)*0x09FE6000U + 0x20U + ((rameccmu_monitor) & 0x0FU) * 0x20U) /*!< RAMECCMU monitor control register */ +#define RAMECCMU_MXSTAT(rameccmu_monitor) REG32(RAMECCMU0 - ((uint32_t)(rameccmu_monitor) >> 4U)*0x09FE6000U + 0x24U + ((rameccmu_monitor) & 0x0FU) * 0x20U) /*!< RAMECCMU monitor status register */ +#define RAMECCMU_MXFADDR(rameccmu_monitor) REG32(RAMECCMU0 - ((uint32_t)(rameccmu_monitor) >> 4U)*0x09FE6000U + 0x28U + ((rameccmu_monitor) & 0x0FU) * 0x20U) /*!< RAMECCMU monitor ECC failing address register */ +#define RAMECCMU_MXFDL(rameccmu_monitor) REG32(RAMECCMU0 - ((uint32_t)(rameccmu_monitor) >> 4U)*0x09FE6000U + 0x2CU + ((rameccmu_monitor) & 0x0FU) * 0x20U) /*!< RAMECCMU monitor ECC failing data low register */ +#define RAMECCMU_MXFDH(rameccmu_monitor) REG32(RAMECCMU0 - ((uint32_t)(rameccmu_monitor) >> 4U)*0x09FE6000U + 0x30U + ((rameccmu_monitor) & 0x0FU) * 0x20U) /*!< RAMECCMU monitor ECC failing data high register */ +#define RAMECCMU_MXFECODE(rameccmu_monitor) REG32(RAMECCMU0 - ((uint32_t)(rameccmu_monitor) >> 4U)*0x09FE6000U + 0x34U + ((rameccmu_monitor) & 0x0FU) * 0x20U) /*!< RAMECCMU monitor failing ECC error code register */ + +#define RAMECCMU_INT_ECC_GLOBAL_ERROR BIT(0) /*!< ECC global error interrupt */ +#define RAMECCMU_INT_ECC_SINGLE_ERROR BIT(1) /*!< ECC single error interrupt */ +#define RAMECCMU_INT_ECC_DOUBLE_ERROR BIT(2) /*!< ECC double error interrupt */ +#define RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE BIT(3) /*!< ECC double error on byte write interrupt */ +#define RAMECCMU_INT_ECC_ERROR_LATCHING BIT(4) /*!< ECC error latching */ + +#define RAMECCMU_FLAG_ECC_SINGLE_ERROR RAMECCMU_MXSTAT_ECCSERRDCF /*!< ECC single error detected and corrected flag */ +#define RAMECCMU_FLAG_ECC_DOUBLE_ERROR RAMECCMU_MXSTAT_ECCDERRDF /*!< ECC double error detected flag */ +#define RAMECCMU_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE RAMECCMU_MXSTAT_ECCDERRBWDF /*!< ECC double error on byte write detected flag */ + +#define RAMECCMU_INT_FLAG_ECC_SINGLE_ERROR RAMECCMU_MXSTAT_ECCSERRDCF /*!< ECC single error detected and corrected flag */ +#define RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR RAMECCMU_MXSTAT_ECCDERRDF /*!< ECC double error detected flag */ +#define RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE RAMECCMU_MXSTAT_ECCDERRBWDF /*!< ECC double error on byte write detected flag */ + + +/* function declarations */ +/* deinit RAMECCMU unit */ +void rameccmu_deinit(uint32_t rameccmu_periph); + +/* RAMECCMU monitor ECC functions */ +/* get RAMECCMU monitor ECC failing address */ +uint32_t rameccmu_monitor_failing_address_get(rameccmu_monitor_enum rameccmu_monitor); +/* get RAMECCMU monitor ECC failing data low 32 bits */ +uint32_t rameccmu_monitor_failing_data_low_bits_get(rameccmu_monitor_enum rameccmu_monitor); +/* get RAMECCMU monitor ECC failing data high 32 bits */ +uint32_t rameccmu_monitor_failing_data_high_bits_get(rameccmu_monitor_enum rameccmu_monitor); +/* get RAMECCMU monitor failing ECC error code */ +uint32_t rameccmu_monitor_failing_ecc_error_code_get(rameccmu_monitor_enum rameccmu_monitor); + +/* interrupt & flag functions */ +/* enable RAMECCMU global ECC interruput */ +void rameccmu_global_interrupt_enable(uint32_t rameccmu_periph, uint32_t interrupt); +/* disable RAMECCMU global ECC interruput */ +void rameccmu_global_interrupt_disable(uint32_t rameccmu_periph, uint32_t interrupt); +/* enable RAMECCMU monitor ECC error interruput */ +void rameccmu_monitor_interrupt_enable(rameccmu_monitor_enum rameccmu_monitor, uint32_t monitor_interrupt); +/* disable RAMECCMU monitor ECC error interruput */ +void rameccmu_monitor_interrupt_disable(rameccmu_monitor_enum rameccmu_monitor, uint32_t monitor_interrupt); +/* get RAMECCMU monitor ECC error flag */ +FlagStatus rameccmu_monitor_flag_get(rameccmu_monitor_enum rameccmu_monitor, uint32_t flag); +/* clear RAMECCMU monitor ECC error flag */ +void rameccmu_monitor_flag_clear(rameccmu_monitor_enum rameccmu_monitor, uint32_t flag); +/* get RAMECCMU monitor ECC interrupt error flag */ +FlagStatus rameccmu_monitor_interrupt_flag_get(rameccmu_monitor_enum rameccmu_monitor, uint32_t int_flag); +/* clear RAMECCMU monitor interrupt ECC error flag */ +void rameccmu_monitor_interrupt_flag_clear(rameccmu_monitor_enum rameccmu_monitor, uint32_t int_flag); + +#endif /* GD32H7XX_RAMECCMU_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rcu.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rcu.h new file mode 100644 index 0000000000..d32cdbb029 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rcu.h @@ -0,0 +1,2097 @@ +/*! + \file gd32h7xx_rcu.h + \brief definitions for the RCU + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_RCU_H +#define GD32H7XX_RCU_H + +#include "gd32h7xx.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL REG32(RCU + 0x00000000U) /*!< control register */ +#define RCU_PLL0 REG32(RCU + 0x00000004U) /*!< PLL0 register */ +#define RCU_CFG0 REG32(RCU + 0x00000008U) /*!< clock configuration register 0 */ +#define RCU_INT REG32(RCU + 0x0000000CU) /*!< clock interrupt register */ +#define RCU_AHB1RST REG32(RCU + 0x00000010U) /*!< AHB1 reset register */ +#define RCU_AHB2RST REG32(RCU + 0x00000014U) /*!< AHB2 reset register */ +#define RCU_AHB3RST REG32(RCU + 0x00000018U) /*!< AHB3 reset register */ +#define RCU_AHB4RST REG32(RCU + 0x0000001CU) /*!< AHB4 reset register */ +#define RCU_APB1RST REG32(RCU + 0x00000020U) /*!< APB1 reset register */ +#define RCU_APB2RST REG32(RCU + 0x00000024U) /*!< APB2 reset register */ +#define RCU_APB3RST REG32(RCU + 0x00000028U) /*!< APB3 reset register */ +#define RCU_APB4RST REG32(RCU + 0x0000002CU) /*!< APB4 reset register */ +#define RCU_AHB1EN REG32(RCU + 0x00000030U) /*!< AHB1 enable register */ +#define RCU_AHB2EN REG32(RCU + 0x00000034U) /*!< AHB2 enable register */ +#define RCU_AHB3EN REG32(RCU + 0x00000038U) /*!< AHB3 enable register */ +#define RCU_AHB4EN REG32(RCU + 0x0000003CU) /*!< AHB4 enable register */ +#define RCU_APB1EN REG32(RCU + 0x00000040U) /*!< APB1 enable register */ +#define RCU_APB2EN REG32(RCU + 0x00000044U) /*!< APB2 enable register */ +#define RCU_APB3EN REG32(RCU + 0x00000048U) /*!< APB3 enable register */ +#define RCU_APB4EN REG32(RCU + 0x0000004CU) /*!< APB4 enable register */ +#define RCU_AHB1SPEN REG32(RCU + 0x00000050U) /*!< AHB1 sleep mode enable register */ +#define RCU_AHB2SPEN REG32(RCU + 0x00000054U) /*!< AHB2 sleep mode enable register */ +#define RCU_AHB3SPEN REG32(RCU + 0x00000058U) /*!< AHB3 sleep mode enable register */ +#define RCU_AHB4SPEN REG32(RCU + 0x0000005CU) /*!< AHB4 sleep mode enable register */ +#define RCU_APB1SPEN REG32(RCU + 0x00000060U) /*!< APB1 sleep mode enable register */ +#define RCU_APB2SPEN REG32(RCU + 0x00000064U) /*!< APB2 sleep mode enable register */ +#define RCU_APB3SPEN REG32(RCU + 0x00000068U) /*!< APB3 sleep mode enable register */ +#define RCU_APB4SPEN REG32(RCU + 0x0000006CU) /*!< APB4 sleep mode enable register */ +#define RCU_BDCTL REG32(RCU + 0x00000070U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x00000074U) /*!< reset source / clock register */ +#define RCU_PLLADDCTL REG32(RCU + 0x00000080U) /*!< PLL clock additional control register */ +#define RCU_PLL1 REG32(RCU + 0x00000084U) /*!< PLL1 register */ +#define RCU_PLL2 REG32(RCU + 0x00000088U) /*!< PLL2 register */ +#define RCU_CFG1 REG32(RCU + 0x0000008CU) /*!< clock configuration register 1 */ +#define RCU_CFG2 REG32(RCU + 0x00000090U) /*!< clock configuration register 2 */ +#define RCU_CFG3 REG32(RCU + 0x00000094U) /*!< clock configuration register 3 */ +#define RCU_PLLALL REG32(RCU + 0x00000098U) /*!< PLL configuration register */ +#define RCU_PLL0FRA REG32(RCU + 0x0000009CU) /*!< PLL0 fraction configuration register */ +#define RCU_PLL1FRA REG32(RCU + 0x000000A0U) /*!< PLL1 fraction configuration register */ +#define RCU_PLL2FRA REG32(RCU + 0x000000A4U) /*!< PLL2 fraction configuration register */ +#define RCU_ADDCTL0 REG32(RCU + 0x000000C0U) /*!< additional clock control register 0 */ +#define RCU_ADDCTL1 REG32(RCU + 0x000000C4U) /*!< additional clock control register 1 */ +#define RCU_ADDINT REG32(RCU + 0x000000CCU) /*!< additional clock interrupt register */ +#define RCU_CFG4 REG32(RCU + 0x000000D0U) /*!< clock configuration register 4 */ +#define RCU_USBCLKCTL REG32(RCU + 0x000000D4U) /*!< USB clock control register */ +#define RCU_PLLUSBCFG REG32(RCU + 0x000000D8U) /*!< PLLUSB configuration register */ +#define RCU_ADDAPB2RST REG32(RCU + 0x000000E0U) /*!< APB2 additional reset register */ +#define RCU_ADDAPB2EN REG32(RCU + 0x000000E4U) /*!< APB2 additional enable register */ +#define RCU_ADDAPB2SPEN REG32(RCU + 0x000000E8U) /*!< APB2 additional sleep mode enable register */ +#define RCU_CFG5 REG32(RCU + 0x000000F0U) /*!< clock configuration register 5 */ + +/* bits definitions */ +/* RCU_CTL */ +#define RCU_CTL_IRC64MADJ BITS(0,6) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL_IRC64MCALIB BITS(7,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL_PLL0EN BIT(24) /*!< PLL0 enable */ +#define RCU_CTL_PLL0STB BIT(25) /*!< PLL0 clock stabilization flag */ +#define RCU_CTL_PLL1EN BIT(26) /*!< PLL1 enable */ +#define RCU_CTL_PLL1STB BIT(27) /*!< PLL1 clock stabilization flag */ +#define RCU_CTL_PLL2EN BIT(28) /*!< PLL2 enable */ +#define RCU_CTL_PLL2STB BIT(29) /*!< PLL2 clock stabilization flag */ +#define RCU_CTL_IRC64MEN BIT(30) /*!< IRC64M high speed oscillator enable */ +#define RCU_CTL_IRC64MSTB BIT(31) /*!< IRC64M high speed internal oscillator stabilization flag */ + +/* RCU_PLL0 */ +#define RCU_PLL0_PLL0PSC BITS(0,5) /*!< The PLL0 VCO source clock prescaler */ +#define RCU_PLL0_PLL0N BITS(6,14) /*!< The PLL0 VCO clock multi factor */ +#define RCU_PLL0_PLL0P BITS(16,22) /*!< The PLL0P output frequency division factor from PLL0 VCO clock */ +#define RCU_PLL0_PLL0R BITS(24,30) /*!< the PLL0R output frequency division factor from PLL0 VCO clock */ +#define RCU_PLL0_PLLSTBSRC BIT(31) /*!< PLLs stabilization signal sources */ + +/* RCU_CFG0 */ +#define RCU_CFG0_SCS BITS(0,1) /*!< system clock switch */ +#define RCU_CFG0_SCSS BITS(2,3) /*!< system clock switch status */ +#define RCU_CFG0_AHBPSC BITS(4,7) /*!< AHB prescaler selection */ +#define RCU_CFG0_APB1PSC BITS(10,12) /*!< APB1 prescaler selection */ +#define RCU_CFG0_APB2PSC BITS(13,15) /*!< APB2 prescaler selection */ +#define RCU_CFG0_RTCDIV BITS(16,21) /*!< RTC clock divider factor */ +#define RCU_CFG0_APB4PSC BITS(24,26) /*!< APB4 prescaler selection */ +#define RCU_CFG0_APB3PSC BITS(27,29) /*!< APB3 prescaler selection */ +#define RCU_CFG0_I2C0SEL BITS(30,31) /*!< I2C0 clock source selection */ + +/* RCU_INT */ +#define RCU_INT_IRC32KSTBIF BIT(0) /*!< IRC32K stabilization interrupt flag */ +#define RCU_INT_LXTALSTBIF BIT(1) /*!< LXTAL stabilization interrupt flag */ +#define RCU_INT_IRC64MSTBIF BIT(2) /*!< IRC64M stabilization interrupt flag */ +#define RCU_INT_HXTALSTBIF BIT(3) /*!< HXTAL stabilization interrupt flag */ +#define RCU_INT_PLL0STBIF BIT(4) /*!< PLL0 stabilization interrupt flag */ +#define RCU_INT_PLL1STBIF BIT(5) /*!< PLL1 stabilization interrupt flag */ +#define RCU_INT_PLL2STBIF BIT(6) /*!< PLL2 stabilization interrupt flag */ +#define RCU_INT_CKMIF BIT(7) /*!< HXTAL clock stuck interrupt flag */ +#define RCU_INT_IRC32KSTBIE BIT(8) /*!< IRC32K stabilization interrupt enable */ +#define RCU_INT_LXTALSTBIE BIT(9) /*!< LXTAL stabilization interrupt enable */ +#define RCU_INT_IRC64MSTBIE BIT(10) /*!< IRC64M stabilization interrupt enable */ +#define RCU_INT_HXTALSTBIE BIT(11) /*!< HXTAL stabilization interrupt enable */ +#define RCU_INT_PLL0STBIE BIT(12) /*!< PLL0 stabilization interrupt enable */ +#define RCU_INT_PLL1STBIE BIT(13) /*!< PLL1 stabilization interrupt enable */ +#define RCU_INT_PLL2STBIE BIT(14) /*!< PLL2 stabilization interrupt enable */ +#define RCU_INT_IRC32KSTBIC BIT(16) /*!< IRC32K stabilization interrupt clear */ +#define RCU_INT_LXTALSTBIC BIT(17) /*!< LXTAL stabilization interrupt clear */ +#define RCU_INT_IRC64MSTBIC BIT(18) /*!< IRC64M stabilization interrupt clear */ +#define RCU_INT_HXTALSTBIC BIT(19) /*!< HXTAL stabilization interrupt clear */ +#define RCU_INT_PLL0STBIC BIT(20) /*!< PLL0 stabilization interrupt clear */ +#define RCU_INT_PLL1STBIC BIT(21) /*!< PLL1 stabilization interrupt clear */ +#define RCU_INT_PLL2STBIC BIT(22) /*!< PLL2 stabilization interrupt clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL clock stuck interrupt clear */ +#define RCU_INT_LPIRC4MSTBIF BIT(24) /*!< LPIRC4M stabilization interrupt flag */ +#define RCU_INT_LPIRC4MSTBIE BIT(25) /*!< LPIRC4M stabilization interrupt enable */ +#define RCU_INT_LPIRC4MSTBIC BIT(26) /*!< LPIRC4M stabilization interrupt clear */ +#define RCU_INT_LCKMIF BIT(27) /*!< LXTAL clock stuck interrupt flag */ +#define RCU_INT_LCKMIC BIT(28) /*!< LXTAL clock stuck interrupt clear */ + +/* RCU_AHB1RST */ +#define RCU_AHB1RST_ENET1RST BIT(0) /*!< ENET1 reset */ +#define RCU_AHB1RST_USBHS0RST BIT(14) /*!< USBHS0 reset */ +#define RCU_AHB1RST_DMA0RST BIT(21) /*!< DMA0 reset */ +#define RCU_AHB1RST_DMA1RST BIT(22) /*!< DMA1 reset */ +#define RCU_AHB1RST_DMAMUXRST BIT(23) /*!< DMAMUX reset */ +#define RCU_AHB1RST_ENET0RST BIT(25) /*!< ENET0 reset */ +#define RCU_AHB1RST_USBHS1RST BIT(29) /*!< USBHS1 reset */ + +/* RCU_AHB2RST */ +#define RCU_AHB2RST_DCIRST BIT(0) /*!< DCI reset */ +#define RCU_AHB2RST_FACRST BIT(1) /*!< FAC reset */ +#define RCU_AHB2RST_SDIO1RST BIT(2) /*!< SDIO1 reset */ +#define RCU_AHB2RST_CAURST BIT(3) /*!< CAU reset */ +#define RCU_AHB2RST_HAURST BIT(4) /*!< HAU reset */ +#define RCU_AHB2RST_TRNGRST BIT(6) /*!< TRNG reset */ +#define RCU_AHB2RST_TMURST BIT(7) /*!< TMU reset */ + +/* RCU_AHB3RST */ +#define RCU_AHB3RST_EXMCRST BIT(0) /*!< EXMC reset */ +#define RCU_AHB3RST_IPARST BIT(1) /*!< IPA reset */ +#define RCU_AHB3RST_SDIO0RST BIT(2) /*!< SDIO0 reset */ +#define RCU_AHB3RST_MDMARST BIT(3) /*!< MDMA reset */ +#define RCU_AHB3RST_OSPIMRST BIT(4) /*!< OSPIM reset */ +#define RCU_AHB3RST_OSPI0RST BIT(5) /*!< OSPI0 reset */ +#define RCU_AHB3RST_OSPI1RST BIT(6) /*!< OSPI1 reset */ +#define RCU_AHB3RST_RTDEC0RST BIT(8) /*!< RTDEC0 reset */ +#define RCU_AHB3RST_RTDEC1RST BIT(9) /*!< RTDEC1 reset */ + +/* RCU_AHB4RST */ +#define RCU_AHB4RST_PARST BIT(0) /*!< GPIO port A reset */ +#define RCU_AHB4RST_PBRST BIT(1) /*!< GPIO port B reset */ +#define RCU_AHB4RST_PCRST BIT(2) /*!< GPIO port C reset */ +#define RCU_AHB4RST_PDRST BIT(3) /*!< GPIO port D reset */ +#define RCU_AHB4RST_PERST BIT(4) /*!< GPIO port E reset */ +#define RCU_AHB4RST_PFRST BIT(5) /*!< GPIO port F reset */ +#define RCU_AHB4RST_PGRST BIT(6) /*!< GPIO port G reset */ +#define RCU_AHB4RST_PHRST BIT(7) /*!< GPIO port H reset */ +#define RCU_AHB4RST_PJRST BIT(8) /*!< GPIO port J reset */ +#define RCU_AHB4RST_PKRST BIT(9) /*!< GPIO port K reset */ +#define RCU_AHB4RST_CRCRST BIT(14) /*!< CRC reset */ +#define RCU_AHB4RST_HWSEMRST BIT(15) /*!< HWSEM reset */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER1RST BIT(0) /*!< TIMER1 reset */ +#define RCU_APB1RST_TIMER2RST BIT(1) /*!< TIMER2 reset */ +#define RCU_APB1RST_TIMER3RST BIT(2) /*!< TIMER3 reset */ +#define RCU_APB1RST_TIMER4RST BIT(3) /*!< TIMER4 reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 reset */ +#define RCU_APB1RST_TIMER6RST BIT(5) /*!< TIMER6 reset */ +#define RCU_APB1RST_TIMER22RST BIT(6) /*!< TIMER22 reset */ +#define RCU_APB1RST_TIMER23RST BIT(7) /*!< TIMER23 reset */ +#define RCU_APB1RST_TIMER30RST BIT(8) /*!< TIMER30 reset */ +#define RCU_APB1RST_TIMER31RST BIT(9) /*!< TIMER31 reset */ +#define RCU_APB1RST_TIMER50RST BIT(10) /*!< TIMER50 reset */ +#define RCU_APB1RST_TIMER51RST BIT(11) /*!< TIMER51 reset */ +#define RCU_APB1RST_RSPDIFRST BIT(13) /*!< RSPDIF reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_SPI2RST BIT(15) /*!< SPI2 reset */ +#define RCU_APB1RST_MDIORST BIT(16) /*!< MDIO reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_USART2RST BIT(18) /*!< USART2 reset */ +#define RCU_APB1RST_UART3RST BIT(19) /*!< UART3 reset */ +#define RCU_APB1RST_UART4RST BIT(20) /*!< UART4 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#define RCU_APB1RST_I2C2RST BIT(23) /*!< I2C2 reset */ +#define RCU_APB1RST_I2C3RST BIT(24) /*!< I2C3 reset */ +#define RCU_APB1RST_CTCRST BIT(27) /*!< CTC reset */ +#define RCU_APB1RST_DACHOLDRST BIT(28) /*!< DAC hold clock reset */ +#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */ +#define RCU_APB1RST_UART6RST BIT(30) /*!< UART6 reset */ +#define RCU_APB1RST_UART7RST BIT(31) /*!< UART7 reset */ + +/* RCU_APB2RST */ +#define RCU_APB2RST_TIMER0RST BIT(0) /*!< TIMER0 reset */ +#define RCU_APB2RST_TIMER7RST BIT(1) /*!< TIMER7 reset */ +#define RCU_APB2RST_USART0RST BIT(4) /*!< USART0 reset */ +#define RCU_APB2RST_USART5RST BIT(5) /*!< USART5 reset */ +#define RCU_APB2RST_ADC0RST BIT(8) /*!< ADC0 reset */ +#define RCU_APB2RST_ADC1RST BIT(9) /*!< ADC1 reset */ +#define RCU_APB2RST_ADC2RST BIT(10) /*!< ADC2 reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_SPI3RST BIT(13) /*!< SPI3 reset */ +#define RCU_APB2RST_TIMER14RST BIT(16) /*!< TIMER14 reset */ +#define RCU_APB2RST_TIMER15RST BIT(17) /*!< TIMER15 reset */ +#define RCU_APB2RST_TIMER16RST BIT(18) /*!< TIMER15 reset */ +#define RCU_APB2RST_HPDFRST BIT(19) /*!< HPDF reset */ +#define RCU_APB2RST_SPI4RST BIT(20) /*!< SPI4 reset */ +#define RCU_APB2RST_SPI5RST BIT(21) /*!< SPI5 reset */ +#define RCU_APB2RST_SAI0RST BIT(22) /*!< SAI0 reset */ +#define RCU_APB2RST_SAI1RST BIT(23) /*!< SAI1 reset */ +#define RCU_APB2RST_SAI2RST BIT(24) /*!< SAI2 reset */ +#define RCU_APB2RST_TIMER40RST BIT(25) /*!< TIMER40 reset */ +#define RCU_APB2RST_TIMER41RST BIT(26) /*!< TIMER41 reset */ +#define RCU_APB2RST_TIMER42RST BIT(27) /*!< TIMER42 reset */ +#define RCU_APB2RST_TIMER43RST BIT(28) /*!< TIMER43 reset */ +#define RCU_APB2RST_TIMER44RST BIT(29) /*!< TIMER44 reset */ +#define RCU_APB2RST_EDOUTRST BIT(30) /*!< EDOUT reset */ +#define RCU_APB2RST_TRIGSELRST BIT(31) /*!< TRIGSEL reset */ + +/* RCU_APB3RST */ +#define RCU_APB3RST_TLIRST BIT(0) /*!< TLI reset */ +#define RCU_APB3RST_WWDGTRST BIT(1) /*!< WWDGT reset */ + +/* RCU_APB4RST */ +#define RCU_APB4RST_SYSCFGRST BIT(0) /*!< SYSCFG reset */ +#define RCU_APB4RST_CMPRST BIT(1) /*!< CMP reset */ +#define RCU_APB4RST_VREFRST BIT(2) /*!< VREF reset */ +#define RCU_APB4RST_LPDTSRST BIT(3) /*!< LPDTS reset */ +#define RCU_APB4RST_PMURST BIT(4) /*!< PMU reset */ + +/* RCU_AHB1EN */ +#define RCU_AHB1EN_ENET1EN BIT(0) /*!< ENET1 clock enable */ +#define RCU_AHB1EN_ENET1TXEN BIT(1) /*!< ENET1 TX clock enable */ +#define RCU_AHB1EN_ENET1RXEN BIT(2) /*!< ENET1 RX clock enable */ +#define RCU_AHB1EN_ENET1PTPEN BIT(3) /*!< ENET1 PTP clock enable */ +#define RCU_AHB1EN_USBHS0EN BIT(14) /*!< USBHS0 clock enable */ +#define RCU_AHB1EN_USBHS0ULPIEN BIT(15) /*!< USBHS0 ULPI clock enable */ +#define RCU_AHB1EN_DMA0EN BIT(21) /*!< DMA0 clock enable */ +#define RCU_AHB1EN_DMA1EN BIT(22) /*!< DMA1 clock enable */ +#define RCU_AHB1EN_DMAMUXEN BIT(23) /*!< DMAMUX clock enable */ +#define RCU_AHB1EN_ENET0EN BIT(25) /*!< ENET0 clock enable */ +#define RCU_AHB1EN_ENET0TXEN BIT(26) /*!< ENET0 TX clock enable */ +#define RCU_AHB1EN_ENET0RXEN BIT(27) /*!< ENET0 RX clock enable */ +#define RCU_AHB1EN_ENET0PTPEN BIT(28) /*!< ENET0 PTP clock enable */ +#define RCU_AHB1EN_USBHS1EN BIT(29) /*!< USBHS1 clock enable */ +#define RCU_AHB1EN_USBHS1ULPIEN BIT(30) /*!< USBHS1 ULPI clock enable */ + +/* RCU_AHB2EN */ +#define RCU_AHB2EN_DCIEN BIT(0) /*!< DCI clock enable */ +#define RCU_AHB2EN_FACEN BIT(1) /*!< FAC clock enable */ +#define RCU_AHB2EN_SDIO1EN BIT(2) /*!< SDIO1 clock enable */ +#define RCU_AHB2EN_CAUEN BIT(3) /*!< CAU clock enable */ +#define RCU_AHB2EN_HAUEN BIT(4) /*!< HAU clock enable */ +#define RCU_AHB2EN_TRNGEN BIT(6) /*!< TRNG clock enable */ +#define RCU_AHB2EN_TMUEN BIT(7) /*!< TMU clock enable */ +#define RCU_AHB2EN_RAMECCMU1EN BIT(8) /*!< RAMECCMU1 clock enable */ + +/* RCU_AHB3EN */ +#define RCU_AHB3EN_EXMCEN BIT(0) /*!< EXMC clock enable */ +#define RCU_AHB3EN_IPAEN BIT(1) /*!< IPA clock enable */ +#define RCU_AHB3EN_SDIO0EN BIT(2) /*!< SDIO0 clock enable */ +#define RCU_AHB3EN_MDMAEN BIT(3) /*!< MDMA clock enable */ +#define RCU_AHB3EN_OSPIMEN BIT(4) /*!< OSPIM clock enable */ +#define RCU_AHB3EN_OSPI0EN BIT(5) /*!< OSPI0 clock enable */ +#define RCU_AHB3EN_OSPI1EN BIT(6) /*!< OSPI1 clock enable */ +#define RCU_AHB3EN_RTDEC0EN BIT(8) /*!< RTDEC0 clock enable */ +#define RCU_AHB3EN_RTDEC1EN BIT(9) /*!< RTDEC1 clock enable */ +#define RCU_AHB3EN_RAMECCMU0EN BIT(10) /*!< RAMECCMU0 clock enable */ +#define RCU_AHB3EN_CPUEN BIT(15) /*!< CPU clock enable */ + +/* RCU_AHB4EN */ +#define RCU_AHB4EN_PAEN BIT(0) /*!< GPIO port A enable */ +#define RCU_AHB4EN_PBEN BIT(1) /*!< GPIO port B enable */ +#define RCU_AHB4EN_PCEN BIT(2) /*!< GPIO port C enable */ +#define RCU_AHB4EN_PDEN BIT(3) /*!< GPIO port D enable */ +#define RCU_AHB4EN_PEEN BIT(4) /*!< GPIO port E enable */ +#define RCU_AHB4EN_PFEN BIT(5) /*!< GPIO port F enable */ +#define RCU_AHB4EN_PGEN BIT(6) /*!< GPIO port G enable */ +#define RCU_AHB4EN_PHEN BIT(7) /*!< GPIO port H enable */ +#define RCU_AHB4EN_PJEN BIT(8) /*!< GPIO port J enable */ +#define RCU_AHB4EN_PKEN BIT(9) /*!< GPIO port K enable */ +#define RCU_AHB4EN_BKPSRAMEN BIT(13) /*!< Backup SRAM enable */ +#define RCU_AHB4EN_CRCEN BIT(14) /*!< CRC enable */ +#define RCU_AHB4EN_HWSEMEN BIT(15) /*!< HWSEM enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 enable */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 enable */ +#define RCU_APB1EN_TIMER3EN BIT(2) /*!< TIMER3 enable */ +#define RCU_APB1EN_TIMER4EN BIT(3) /*!< TIMER4 enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 enable */ +#define RCU_APB1EN_TIMER6EN BIT(5) /*!< TIMER6 enable */ +#define RCU_APB1EN_TIMER22EN BIT(6) /*!< TIMER22 enable */ +#define RCU_APB1EN_TIMER23EN BIT(7) /*!< TIMER23 enable */ +#define RCU_APB1EN_TIMER30EN BIT(8) /*!< TIMER30 enable */ +#define RCU_APB1EN_TIMER31EN BIT(9) /*!< TIMER31 enable */ +#define RCU_APB1EN_TIMER50EN BIT(10) /*!< TIMER50 enable */ +#define RCU_APB1EN_TIMER51EN BIT(11) /*!< TIMER51 enable */ +#define RCU_APB1EN_RSPDIFEN BIT(13) /*!< RSPDIF enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 enable */ +#define RCU_APB1EN_SPI2EN BIT(15) /*!< SPI2 enable */ +#define RCU_APB1EN_MDIOEN BIT(16) /*!< MDIO enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 enable */ +#define RCU_APB1EN_USART2EN BIT(18) /*!< USART2 enable */ +#define RCU_APB1EN_UART3EN BIT(19) /*!< UART3 enable */ +#define RCU_APB1EN_UART4EN BIT(20) /*!< UART4 enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 enable */ +#define RCU_APB1EN_I2C2EN BIT(23) /*!< I2C2 enable */ +#define RCU_APB1EN_I2C3EN BIT(24) /*!< I2C3 enable */ +#define RCU_APB1EN_CTCEN BIT(27) /*!< CTC enable */ +#define RCU_APB1EN_DACHOLDEN BIT(28) /*!< DAC hold clock enable */ +#define RCU_APB1EN_DACEN BIT(29) /*!< DAC enable */ +#define RCU_APB1EN_UART6EN BIT(30) /*!< UART6 enable */ +#define RCU_APB1EN_UART7EN BIT(31) /*!< UART7 enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_TIMER0EN BIT(0) /*!< TIMER0 enable */ +#define RCU_APB2EN_TIMER7EN BIT(1) /*!< TIMER7 enable */ +#define RCU_APB2EN_USART0EN BIT(4) /*!< USART0 enable */ +#define RCU_APB2EN_USART5EN BIT(5) /*!< USART5 enable */ +#define RCU_APB2EN_ADC0EN BIT(8) /*!< ADC0 enable */ +#define RCU_APB2EN_ADC1EN BIT(9) /*!< ADC1 enable */ +#define RCU_APB2EN_ADC2EN BIT(10) /*!< ADC2 enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 enable */ +#define RCU_APB2EN_SPI3EN BIT(13) /*!< SPI3 enable */ +#define RCU_APB2EN_TIMER14EN BIT(16) /*!< TIMER14 enable */ +#define RCU_APB2EN_TIMER15EN BIT(17) /*!< TIMER15 enable */ +#define RCU_APB2EN_TIMER16EN BIT(18) /*!< TIMER15 enable */ +#define RCU_APB2EN_HPDFEN BIT(19) /*!< HPDF enable */ +#define RCU_APB2EN_SPI4EN BIT(20) /*!< SPI4 enable */ +#define RCU_APB2EN_SPI5EN BIT(21) /*!< SPI5 enable */ +#define RCU_APB2EN_SAI0EN BIT(22) /*!< SAI0 enable */ +#define RCU_APB2EN_SAI1EN BIT(23) /*!< SAI1 enable */ +#define RCU_APB2EN_SAI2EN BIT(24) /*!< SAI2 enable */ +#define RCU_APB2EN_TIMER40EN BIT(25) /*!< TIMER40 enable */ +#define RCU_APB2EN_TIMER41EN BIT(26) /*!< TIMER41 enable */ +#define RCU_APB2EN_TIMER42EN BIT(27) /*!< TIMER42 enable */ +#define RCU_APB2EN_TIMER43EN BIT(28) /*!< TIMER43 enable */ +#define RCU_APB2EN_TIMER44EN BIT(29) /*!< TIMER44 enable */ +#define RCU_APB2EN_EDOUTEN BIT(30) /*!< EDOUT enable */ +#define RCU_APB2EN_TRGSELEN BIT(31) /*!< TRGSEL enable */ + +/* RCU_APB3EN */ +#define RCU_APB3EN_TLIEN BIT(0) /*!< TLI enable */ +#define RCU_APB3EN_WWDGTEN BIT(1) /*!< WWDGT enable */ + +/* RCU_APB4EN */ +#define RCU_APB4EN_SYSCFGEN BIT(0) /*!< SYSCFG enable */ +#define RCU_APB4EN_CMPEN BIT(1) /*!< CMP enable */ +#define RCU_APB4EN_VREFEN BIT(2) /*!< VREF enable */ +#define RCU_APB4EN_LPDTSEN BIT(3) /*!< LPDTS enable */ +#define RCU_APB4EN_PMUEN BIT(4) /*!< PMU enable */ + +/* RCU_AHB1SPEN */ +#define RCU_AHB1SPEN_ENET1SPEN BIT(0) /*!< ENET1 clock enable when sleep mode*/ +#define RCU_AHB1SPEN_ENET1TXSPEN BIT(1) /*!< ENET1 TX clock enable when sleep mode*/ +#define RCU_AHB1SPEN_ENET1RXSPEN BIT(2) /*!< ENET1 RX clock enable when sleep mode*/ +#define RCU_AHB1SPEN_ENET1PTPSPEN BIT(3) /*!< ENET1 PTP clock enable when sleep mode */ +#define RCU_AHB1SPEN_USBHS0SPEN BIT(14) /*!< USBHS0 clock enable when sleep mode */ +#define RCU_AHB1SPEN_USBHS0ULPISPEN BIT(15) /*!< USBHS0ULPI clock enable when sleep mode */ +#define RCU_AHB1SPEN_SRAM0SPEN BIT(16) /*!< SRAM0 clock enable when sleep mode */ +#define RCU_AHB1SPEN_SRAM1SPEN BIT(17) /*!< SRAM1 clock enable when sleep mode */ +#define RCU_AHB1SPEN_DMA0SPEN BIT(21) /*!< DMA0 clock enable when sleep mode*/ +#define RCU_AHB1SPEN_DMA1SPEN BIT(22) /*!< DMA1 clock enable when sleep mode*/ +#define RCU_AHB1SPEN_DMAMUXSPEN BIT(23) /*!< DMAMUX clock enable when sleep mode*/ +#define RCU_AHB1SPEN_ENET0SPEN BIT(25) /*!< ENET0 clock enable when sleep mode*/ +#define RCU_AHB1SPEN_ENET0TXSPEN BIT(26) /*!< ENET0 TX clock enable when sleep mode*/ +#define RCU_AHB1SPEN_ENET0RXSPEN BIT(27) /*!< ENET0 RX clock enable when sleep mode*/ +#define RCU_AHB1SPEN_ENET0PTPSPEN BIT(28) /*!< ENET0 PTP clock enable when sleep mode*/ +#define RCU_AHB1SPEN_USBHS1SPEN BIT(29) /*!< USBHS1 clock enable when sleep mode*/ +#define RCU_AHB1SPEN_USBHS1ULPISPEN BIT(30) /*!< USBHS1 ULPI clock enable when sleep mode*/ + +/* RCU_AHB2SPEN */ +#define RCU_AHB2SPEN_DCISPEN BIT(0) /*!< DCI clock enable when sleep mode*/ +#define RCU_AHB2SPEN_FACSPEN BIT(1) /*!< FAC clock enable when sleep mode*/ +#define RCU_AHB2SPEN_SDIO1SPEN BIT(2) /*!< SDIO1 clock enable when sleep mode*/ +#define RCU_AHB2SPEN_CAUSPEN BIT(3) /*!< CAU clock enable when sleep mode*/ +#define RCU_AHB2SPEN_HAUSPEN BIT(4) /*!< HAU clock enable when sleep mode*/ +#define RCU_AHB2SPEN_TRNGSPEN BIT(6) /*!< TRNG clock enable when sleep mode*/ +#define RCU_AHB2SPEN_TMUSPEN BIT(7) /*!< TMU clock enable when sleep mode*/ +#define RCU_AHB2SPEN_RAMECCMU1SPEN BIT(8) /*!< RAMECCMU1 clock enable when sleep mode*/ + +/* RCU_AHB3SPEN */ +#define RCU_AHB3SPEN_EXMCSPEN BIT(0) /*!< EXMC clock enable when sleep mode*/ +#define RCU_AHB3SPEN_IPASPEN BIT(1) /*!< IPA clock enable when sleep mode*/ +#define RCU_AHB3SPEN_SDIO0SPEN BIT(2) /*!< SDIO0 clock enable when sleep mode*/ +#define RCU_AHB3SPEN_MDMASPEN BIT(3) /*!< MDMA clock enable when sleep mode*/ +#define RCU_AHB3SPEN_OSPIMSPEN BIT(4) /*!< OSPIM clock enable when sleep mode*/ +#define RCU_AHB3SPEN_OSPI0SPEN BIT(5) /*!< OSPI0 clock enable when sleep mode*/ +#define RCU_AHB3SPEN_OSPI1SPEN BIT(6) /*!< OSPI1 clock enable when sleep mode*/ +#define RCU_AHB3SPEN_RTDEC0SPEN BIT(8) /*!< RTDEC0 clock enable when sleep mode*/ +#define RCU_AHB3SPEN_RTDEC1SPEN BIT(9) /*!< RTDEC1 clock enable when sleep mode*/ +#define RCU_AHB2SPEN_RAMECCMU0SPEN BIT(10) /*!< RAMECCMU0 clock enable when sleep mode*/ +#define RCU_AHB3SPEN_AXISRAMSPEN BIT(14) /*!< AXISRAM clock enable when sleep mode*/ +#define RCU_AHB3SPEN_FMCSPEN BIT(15) /*!< FMC clock enable when sleep mode*/ + +/* RCU_AHB4SPEN */ +#define RCU_AHB4SPEN_PASPEN BIT(0) /*!< GPIO port A clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PBSPEN BIT(1) /*!< GPIO port B clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PCSPEN BIT(2) /*!< GPIO port C clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PDSPEN BIT(3) /*!< GPIO port D clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PESPEN BIT(4) /*!< GPIO port E clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PFSPEN BIT(5) /*!< GPIO port F clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PGSPEN BIT(6) /*!< GPIO port G clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PHSPEN BIT(7) /*!< GPIO port H clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PJSPEN BIT(8) /*!< GPIO port J clock enable when sleep mode*/ +#define RCU_AHB4SPEN_PKSPEN BIT(9) /*!< GPIO port K clock enable when sleep mode*/ +#define RCU_AHB4SPEN_BKPSRAMSPEN BIT(13) /*!< BKPSRAMEN clock enable when sleep mode*/ +#define RCU_AHB4SPEN_CRCSPEN BIT(14) /*!< CRC clock enable when sleep mode*/ + +/* RCU_APB1SPEN */ +#define RCU_APB1SPEN_TIMER1SPEN BIT(0) /*!< TIMER1 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER2SPEN BIT(1) /*!< TIMER2 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER3SPEN BIT(2) /*!< TIMER3 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER4SPEN BIT(3) /*!< TIMER4 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER5SPEN BIT(4) /*!< TIMER5 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER6SPEN BIT(5) /*!< TIMER6 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER22SPEN BIT(6) /*!< TIMER22 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER23SPEN BIT(7) /*!< TIMER23 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER30SPEN BIT(8) /*!< TIMER30 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER31SPEN BIT(9) /*!< TIMER31 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER50SPEN BIT(10) /*!< TIMER50 clock enable when sleep mode*/ +#define RCU_APB1SPEN_TIMER51SPEN BIT(11) /*!< TIMER51 clock enable when sleep mode*/ +#define RCU_APB1SPEN_RSPDIFSPEN BIT(13) /*!< RSPDIF clock enable when sleep mode*/ +#define RCU_APB1SPEN_SPI1SPEN BIT(14) /*!< SPI1 clock enable when sleep mode*/ +#define RCU_APB1SPEN_SPI2SPEN BIT(15) /*!< SPI2 clock enable when sleep mode*/ +#define RCU_APB1SPEN_MDIOSPEN BIT(16) /*!< MDIO clock enable when sleep mode*/ +#define RCU_APB1SPEN_USART1SPEN BIT(17) /*!< USART1 clock enable when sleep mode*/ +#define RCU_APB1SPEN_USART2SPEN BIT(18) /*!< USART2 clock enable when sleep mode*/ +#define RCU_APB1SPEN_UART3SPEN BIT(19) /*!< UART3 clock enable when sleep mode*/ +#define RCU_APB1SPEN_UART4SPEN BIT(20) /*!< UART4 clock enable when sleep mode*/ +#define RCU_APB1SPEN_I2C0SPEN BIT(21) /*!< I2C0 clock enable when sleep mode*/ +#define RCU_APB1SPEN_I2C1SPEN BIT(22) /*!< I2C1 clock enable when sleep mode*/ +#define RCU_APB1SPEN_I2C2SPEN BIT(23) /*!< I2C2 clock enable when sleep mode*/ +#define RCU_APB1SPEN_I2C3SPEN BIT(24) /*!< I2C3 clock enable when sleep mode*/ +#define RCU_APB1SPEN_CTCSPEN BIT(27) /*!< CTC clock enable when sleep mode*/ +#define RCU_APB1SPEN_DACHOLDSPEN BIT(28) /*!< DAC hold clock enable when sleep mode*/ +#define RCU_APB1SPEN_DACSPEN BIT(29) /*!< DAC clock enable when sleep mode*/ +#define RCU_APB1SPEN_UART6SPEN BIT(30) /*!< UART6 clock enable when sleep mode*/ +#define RCU_APB1SPEN_UART7SPEN BIT(31) /*!< UART7 clock enable when sleep mode*/ + +/* RCU_APB2SPEN */ +#define RCU_APB2SPEN_TIMER0SPEN BIT(0) /*!< TIMER0 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER7SPEN BIT(1) /*!< TIMER7 clock enable when sleep mode*/ +#define RCU_APB2SPEN_USART0SPEN BIT(4) /*!< USART0 clock enable when sleep mode*/ +#define RCU_APB2SPEN_USART5SPEN BIT(5) /*!< USART5 clock enable when sleep mode*/ +#define RCU_APB2SPEN_ADC0SPEN BIT(8) /*!< ADC0 clock enable when sleep mode*/ +#define RCU_APB2SPEN_ADC1SPEN BIT(9) /*!< ADC1 clock enable when sleep mode*/ +#define RCU_APB2SPEN_ADC2SPEN BIT(10) /*!< ADC2 clock enable when sleep mode*/ +#define RCU_APB2SPEN_SPI0SPEN BIT(12) /*!< SPI0 clock enable when sleep mode*/ +#define RCU_APB2SPEN_SPI3SPEN BIT(13) /*!< SPI3 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER14SPEN BIT(16) /*!< TIMER14 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER15SPEN BIT(17) /*!< TIMER15 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER16SPEN BIT(18) /*!< TIMER16 clock enable when sleep mode*/ +#define RCU_APB2SPEN_HPDFSPEN BIT(19) /*!< HPDF clock enable when sleep mode*/ +#define RCU_APB2SPEN_SPI4SPEN BIT(20) /*!< SPI4 clock enable when sleep mode*/ +#define RCU_APB2SPEN_SPI5SPEN BIT(21) /*!< SPI5 clock enable when sleep mode*/ +#define RCU_APB2SPEN_SAI0SPEN BIT(22) /*!< SAI0 clock enable when sleep mode*/ +#define RCU_APB2SPEN_SAI1SPEN BIT(23) /*!< SAI1 clock enable when sleep mode*/ +#define RCU_APB2SPEN_SAI2SPEN BIT(24) /*!< SAI2 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER40SPEN BIT(25) /*!< TIMER40 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER41SPEN BIT(26) /*!< TIMER41 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER42SPEN BIT(27) /*!< TIMER42 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER43SPEN BIT(28) /*!< TIMER43 clock enable when sleep mode*/ +#define RCU_APB2SPEN_TIMER44SPEN BIT(29) /*!< TIMER44 clock enable when sleep mode*/ +#define RCU_APB2SPEN_EDOUTSPEN BIT(30) /*!< EDOUT clock enable when sleep mode*/ +#define RCU_APB2SPEN_TRIGSELSPEN BIT(31) /*!< TRIGSEL clock enable when sleep mode*/ + +/* RCU_APB3SPEN */ +#define RCU_APB3SPEN_TLISPEN BIT(0) /*!< TLI clock enable when sleep mode*/ +#define RCU_APB3SPEN_WWDGTSPEN BIT(1) /*!< WWDGT clock enable when sleep mode*/ + +/* RCU_APB4SPEN */ +#define RCU_APB4SPEN_SYSCFGSPEN BIT(0) /*!< SYSCFG clock enable when sleep mode*/ +#define RCU_APB4SPEN_CMPSPEN BIT(1) /*!< CMP clock enable when sleep mode*/ +#define RCU_APB4SPEN_VREFSPEN BIT(2) /*!< VREF clock enable when sleep mode*/ +#define RCU_APB4SPEN_LPDTSSPEN BIT(3) /*!< LPDTS clock enable when sleep mode*/ +#define RCU_APB4SPEN_PMUSPEN BIT(4) /*!< PMU clock enable when sleep mode*/ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< low speed crystal oscillator stabilization flag */ +#define RCU_BDCTL_LXTALBPS BIT(2) /*!< LXTAL bypass mode enable */ +#define RCU_BDCTL_LXTALDRI BITS(3,4) /*!< LXTAL drive capability */ +#define RCU_BDCTL_LCKMEN BIT(5) /*!< LXTAL clock monitor enable */ +#define RCU_BDCTL_LCKMD BIT(6) /*!< LXTAL clock failure detection flag */ +#define RCU_BDCTL_RTCSRC BITS(8,9) /*!< RTC clock entry selection */ +#define RCU_BDCTL_RTCEN BIT(15) /*!< RTC clock enable */ +#define RCU_BDCTL_BKPRST BIT(16) /*!< backup domain reset */ + +/* RCU_RSTSCK */ +#define RCU_RSTSCK_IRC32KEN BIT(0) /*!< IRC32K enable */ +#define RCU_RSTSCK_IRC32KSTB BIT(1) /*!< IRC32K stabilization flag */ +#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */ +#define RCU_RSTSCK_BORRSTF BIT(25) /*!< BOR reset flag */ +#define RCU_RSTSCK_EPRSTF BIT(26) /*!< external pin reset flag */ +#define RCU_RSTSCK_PORRSTF BIT(27) /*!< power reset flag */ +#define RCU_RSTSCK_SWRSTF BIT(28) /*!< software reset flag */ +#define RCU_RSTSCK_FWDGTRSTF BIT(29) /*!< free watchdog timer reset flag */ +#define RCU_RSTSCK_WWDGTRSTF BIT(30) /*!< window watchdog timer reset flag */ +#define RCU_RSTSCK_LPRSTF BIT(31) /*!< low-power reset flag */ + +/* RCU_PLLADDCTL */ +#define RCU_PLLADDCTL_PLL0Q BITS(0,6) /*!< the PLL0Q output frequency division factor from PLL0 VCO clock */ +#define RCU_PLLADDCTL_PLL1Q BITS(8,14) /*!< the PLL1Q output frequency division factor from PLL1 VCO clock */ +#define RCU_PLLADDCTL_PLL2Q BITS(16,22) /*!< the PLL2Q output frequency division factor from PLL2 VCO clock */ +#define RCU_PLLADDCTL_PLL0QEN BIT(23) /*!< PLL0Q divider output enable */ +#define RCU_PLLADDCTL_PLL0REN BIT(24) /*!< PLL0R divider output enable */ +#define RCU_PLLADDCTL_PLL0PEN BIT(25) /*!< PLL0P divider output enable */ +#define RCU_PLLADDCTL_PLL1QEN BIT(26) /*!< PLL1Q divider output enable */ +#define RCU_PLLADDCTL_PLL1REN BIT(27) /*!< PLL1R divider output enable */ +#define RCU_PLLADDCTL_PLL1PEN BIT(28) /*!< PLL1P divider output enable */ +#define RCU_PLLADDCTL_PLL2QEN BIT(29) /*!< PLL2Q divider output enable */ +#define RCU_PLLADDCTL_PLL2REN BIT(30) /*!< PLL2R divider output enable */ +#define RCU_PLLADDCTL_PLL2PEN BIT(31) /*!< PLL2P divider output enable */ + +/* RCU_PLL1 */ +#define RCU_PLL1_PLL1PSC BITS(0,5) /*!< the PLL1 VCO source clock prescaler */ +#define RCU_PLL1_PLL1N BITS(6,14) /*!< the PLL1 VCO clock multi factor */ +#define RCU_PLL1_PLL1P BITS(16,22) /*!< the PLL1P output frequency division factor from PLL1 VCO clock */ +#define RCU_PLL1_PLL1R BITS(24,30) /*!< the PLL1R output frequency division factor from PLL1 VCO clock */ + +/* RCU_PLL2 */ +#define RCU_PLL2_PLL2PSC BITS(0,5) /*!< the PLL2 VCO source clock prescaler */ +#define RCU_PLL2_PLL2N BITS(6,14) /*!< the PLL2 VCO clock multi factor */ +#define RCU_PLL2_PLL2P BITS(16,22) /*!< the PLL2P output frequency division factor from PLL2 VCO clock */ +#define RCU_PLL2_PLL2R BITS(24,30) /*!< the PLL2R output frequency division factor from PLL2 VCO clock */ + +/* RCU_CFG1 */ +#define RCU_CFG1_USART0SEL BITS(0,1) /*!< USART0 clock source selection */ +#define RCU_CFG1_RSPDIFSEL BITS(4,5) /*!< RSPDIF clock source selection */ +#define RCU_CFG1_CAN0SEL BITS(8,9) /*!< CAN0 clock source selection */ +#define RCU_CFG1_CAN1SEL BITS(10,11) /*!< CAN1 clock source selection */ +#define RCU_CFG1_CAN2SEL BITS(12,13) /*!< CAN2 clock source selection */ +#define RCU_CFG1_PERSEL BITS(14,15) /*!< CK_PER clock source selection */ +#define RCU_CFG1_PLL2RDIV BITS(16,17) /*!< the divider factor from PLL2R clock */ +#define RCU_CFG1_USART1SEL BITS(18,19) /*!< USART1 clock source selection */ +#define RCU_CFG1_USART2SEL BITS(20,21) /*!< USART2 clock source selection */ +#define RCU_CFG1_USART5SEL BITS(22,23) /*!< USART5 clock source selection */ +#define RCU_CFG1_TIMERSEL BIT(24) /*!< TIMER clock selection */ +#define RCU_CFG1_HPDFSEL BIT(31) /*!< HPDF clock source selection */ + +/* RCU_CFG2 */ +#define RCU_CFG2_CKOUT0DIV BITS(0,3) /*!< The CK_OUT0 divider which the CK_OUT0 frequency can be reduced */ +#define RCU_CFG2_CKOUT0SEL BITS(4,6) /*!< CKOUT0 clock source selection */ +#define RCU_CFG2_CKOUT1DIV BITS(8,11) /*!< The CK_OUT1 divider which the CK_OUT1 frequency can be reduced */ +#define RCU_CFG2_CKOUT1SEL BITS(12,14) /*!< CKOUT1 clock source selection */ +#define RCU_CFG2_SAI0SEL BITS(16,18) /*!< SAI0 clock source selection */ +#define RCU_CFG2_SAI1SEL BITS(20,22) /*!< SAI1 clock source selection */ +#define RCU_CFG2_SAI2B0SEL BITS(24,26) /*!< SAI2 Block 0 clock source selection */ +#define RCU_CFG2_SAI2B1SEL BITS(28,30) /*!< SAI2 Block 1 clock source selection */ + +/* RCU_CFG3 */ +#define RCU_CFG3_I2C1SEL BITS(0,1) /*!< I2C1 clock source selection */ +#define RCU_CFG3_I2C2SEL BITS(2,3) /*!< I2C2 clock source selection */ +#define RCU_CFG3_I2C3SEL BITS(4,5) /*!< I2C3 clock source selection */ +#define RCU_CFG3_SDIO1SEL BIT(12) /*!< SDIO1 function clock source selection */ +#define RCU_CFG3_DSPWUSSEL BIT(24) /*!< deep-sleep wakeup system clock source selection */ +#define RCU_CFG3_ADC01SEL BITS(26,27) /*!< ADC0 and ADC1 clock source selection */ +#define RCU_CFG3_ADC2SEL BITS(28,29) /*!< ADC2 clock source selection */ + +/* RCU_PLLALL */ +#define RCU_PLLALL_PLL0RNG BITS(0,1) /*!< PLL0 input clock range */ +#define RCU_PLLALL_PLL0VCOSEL BIT(2) /*!< PLL0 VCO selection */ +#define RCU_PLLALL_PLL1RNG BITS(4,5) /*!< PLL1 input clock range */ +#define RCU_PLLALL_PLL1VCOSEL BIT(6) /*!< PLL1 VCO selection */ +#define RCU_PLLALL_PLL2RNG BITS(8,9) /*!< PLL2 input clock range */ +#define RCU_PLLALL_PLL2VCOSEL BIT(10) /*!< PLL2 VCO selection */ +#define RCU_PLLALL_PLLSEL BITS(16,17) /*!< PLLs clock source selection */ + +/* RCU_PLL0FRA */ +#define RCU_PLL0FRA_PLL0FRAN BITS(0,12) /*!< fractional part of the multiplication factor for PLL0 VCO */ +#define RCU_PLL0FRA_PLL0FRAEN BIT(15) /*!< PLL0 fractional latch enable */ + +/* RCU_PLL1FRA */ +#define RCU_PLL1FRA_PLL1FRAN BITS(0,12) /*!< fractional part of the multiplication factor for PLL1 VCO */ +#define RCU_PLL1FRA_PLL1FRAEN BIT(15) /*!< PLL1 fractional latch enable */ + +/* RCU_PLL2FRA */ +#define RCU_PLL2FRA_PLL2FRAN BITS(0,12) /*!< fractional part of the multiplication factor for PLL2 VCO */ +#define RCU_PLL2FRA_PLL2FRAEN BIT(15) /*!< PLL2 fractional latch enable */ + +/* RCU_ADDCTL0 */ +#define RCU_ADDCTL0_CK48MSEL BIT(0) /*!< 48MHz clock selection */ +#define RCU_ADDCTL0_PLL48MSEL BIT(1) /*!< PLL48M clock selection */ +#define RCU_ADDCTL0_IRC48MEN BIT(16) /*!< internal 48MHz RC oscillator enable */ +#define RCU_ADDCTL0_IRC48MSTB BIT(17) /*!< internal 48MHz RC oscillator clock stabilization flag */ +#define RCU_ADDCTL0_IRC48MCALB BITS(24,31) /*!< internal 48MHz RC oscillator calibration value register */ + +/* RCU_ADDCTL1 */ +#define RCU_ADDCTL1_LPIRC4MEN BIT(0) /*!< LPIRC4M clock enable */ +#define RCU_ADDCTL1_LPIRC4MSTB BIT(1) /*!< LPIRC4M clock stabilization flag */ +#define RCU_ADDCTL1_LPIRC4MTRIM BITS(2,7) /*!< LPIRC4M clock trim adjust value */ +#define RCU_ADDCTL1_LPIRC4MCAL BITS(8,15) /*!< LPIRC4M clock calibration value */ +#define RCU_ADDCTL1_IRC64MDIV BITS(16,17) /*!< IRC64M clock divider */ +#define RCU_ADDCTL1_LPIRC4MDSPEN BIT(20) /*!< LPIRC4M clock enable in deepsleep mode */ +#define RCU_ADDCTL1_PLLUSBHS0EN BIT(28) /*!< PLLUSBHS0 clock enable */ +#define RCU_ADDCTL1_PLLUSBHS0STB BIT(29) /*!< PLLUSBHS0 clock stabilization flag */ +#define RCU_ADDCTL1_PLLUSBHS1EN BIT(30) /*!< PLLUSBHS1 clock enable */ +#define RCU_ADDCTL1_PLLUSBHS1STB BIT(31) /*!< PLLUSBHS1 clock stabilization flag */ + +/* RCU_ADDINT */ +#define RCU_ADDINT_PLLUSBHS0STBIF BIT(4) /*!< Internal PLL of USBHS0 stabilization interrupt flag */ +#define RCU_ADDINT_PLLUSBHS1STBIF BIT(5) /*!< Internal PLL of USBHS1 stabilization interrupt flag */ +#define RCU_ADDINT_IRC48MSTBIF BIT(6) /*!< IRC48M stabilization interrupt flag */ +#define RCU_ADDINT_PLLUSBHS0STBIE BIT(12) /*!< Internal PLL of USBHS0 stabilization interrupt enable */ +#define RCU_ADDINT_PLLUSBHS1STBIE BIT(13) /*!< Internal PLL of USBHS1 stabilization interrupt enable */ +#define RCU_ADDINT_IRC48MSTBIE BIT(14) /*!< Internal 48 MHz RC oscillator stabilization interrupt enable */ +#define RCU_ADDINT_PLLUSBHS0STBIC BIT(20) /*!< Internal PLL of USBHS0 stabilization interrupt clear */ +#define RCU_ADDINT_PLLUSBHS1STBIC BIT(21) /*!< Internal PLL of USBHS1 stabilization interrupt clear */ +#define RCU_ADDINT_IRC48MSTBIC BIT(22) /*!< Internal 48 MHz RC oscillator stabilization interrupt clear */ + +/* RCU_CFG4 */ +#define RCU_CFG4_SDIO0SEL BIT(0) /*!< SDIO0 clock source selection */ +#define RCU_CFG4_EXMCSEL BITS(8,9) /*!< EXMC clock surce selection */ + +/* RCU_USBCLKCTL*/ +#define RCU_USBCLKCTL_USBHS0SEL BIT(1) /*!< USBHS0 clock selection */ +#define RCU_USBCLKCTL_PLLUSBHS0PRESEL BIT(3) /*!< PLLUSBHS0 clock source selection */ +#define RCU_USBCLKCTL_USBHS0SWEN BIT(4) /*!< USBHS0 clock source selection enable */ +#define RCU_USBCLKCTL_USBHS048MSEL BITS(5,6) /*!< USBHS0 48M clock source selection */ +#define RCU_USBCLKCTL_USBHS1SEL BIT(9) /*!< USBHS1 clock selection */ +#define RCU_USBCLKCTL_PLLUSBHS1PRESEL BIT(11) /*!< PLLUSBHS1 clock source selection */ +#define RCU_USBCLKCTL_USBHS1SWEN BIT(12) /*!< USBHS1 clock source selection enable */ +#define RCU_USBCLKCTL_USBHS148MSEL BITS(13,14) /*!< USBHS1 48M clock source selection */ +#define RCU_USBCLKCTL_USBHS0PSC BITS(16,18) /*!< USBHS0 clock prescaler selection */ +#define RCU_USBCLKCTL_USBHS1PSC BITS(19,21) /*!< USBHS1 clock prescaler selection */ + +/* RCU_PLLUSBCFG*/ +#define RCU_PLLUSBCFG_PLLUSBHS0PREDV BITS(0,3) /*!< the PLLUSBHS0PREDV clock prescaler */ +#define RCU_PLLUSBCFG_USBHS0DV BITS(4,6) /*!< USBHS0 clock divider */ +#define RCU_PLLUSBCFG_PLLUSBHS0MF BITS(8,14) /*!< the PLLUSBHS0 clock multiplication factor */ +#define RCU_PLLUSBCFG_PLLUSBHS1PREDV BITS(16,19) /*!< the PLLUSBHS1PREDV clock prescaler */ +#define RCU_PLLUSBCFG_USBHS1DV BITS(20,22) /*!< USBHS1 clock divider */ +#define RCU_PLLUSBCFG_PLLUSBHS1MF BITS(24,30) /*!< the PLLUSBHS1 clock multiplication factor */ + +/* RCU_ADDAPB2RST */ +#define RCU_ADDAPB2RST_CAN0RST BIT(0) /*!< CAN0 reset */ +#define RCU_ADDAPB2RST_CAN1RST BIT(1) /*!< CAN1 reset */ +#define RCU_ADDAPB2RST_CAN2RST BIT(2) /*!< CAN2 reset */ + +/* RCU_ADDAPB2EN */ +#define RCU_ADDAPB2EN_CAN0EN BIT(0) /*!< CAN0 clock enable */ +#define RCU_ADDAPB2EN_CAN1EN BIT(1) /*!< CAN1 clock enable */ +#define RCU_ADDAPB2EN_CAN2EN BIT(2) /*!< CAN2 clock enable */ + +/* RCU_ADDAPB2SPEN */ +#define RCU_ADDAPB2SPEN_CAN0SPEN BIT(0) /*!< CAN0 clock enable when sleep mode*/ +#define RCU_ADDAPB2SPEN_CAN1SPEN BIT(1) /*!< CAN1 clock enable when sleep mode*/ +#define RCU_ADDAPB2SPEN_CAN2SPEN BIT(2) /*!< CAN2 clock enable when sleep mode*/ + +/* RCU_CFG5 */ +#define RCU_CFG5_SPI0SEL BITS(0,2) /*!< SPI0 and I2S0 clock source selection */ +#define RCU_CFG5_SPI1SEL BITS(4,6) /*!< SPI1 and I2S1 clock source selection */ +#define RCU_CFG5_SPI2SEL BITS(8,10) /*!< SPI2 and I2S2 clock source selection */ +#define RCU_CFG5_SPI3SEL BITS(12,14) /*!< SPI3 clock source selection */ +#define RCU_CFG5_SPI4SEL BITS(16,18) /*!< SPI4 clock source selection */ +#define RCU_CFG5_SPI5SEL BITS(20,22) /*!< SPI5 and I2S5 clock source selection */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph) >> 6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) + +/* register offset */ +/* peripherals enable */ +#define AHB1EN_REG_OFFSET ((uint32_t)0x00000030U) /*!< AHB1 enable register offset */ +#define AHB2EN_REG_OFFSET ((uint32_t)0x00000034U) /*!< AHB2 enable register offset */ +#define AHB3EN_REG_OFFSET ((uint32_t)0x00000038U) /*!< AHB3 enable register offset */ +#define AHB4EN_REG_OFFSET ((uint32_t)0x0000003CU) /*!< AHB4 enable register offset */ +#define APB1EN_REG_OFFSET ((uint32_t)0x00000040U) /*!< APB1 enable register offset */ +#define APB2EN_REG_OFFSET ((uint32_t)0x00000044U) /*!< APB2 enable register offset */ +#define APB3EN_REG_OFFSET ((uint32_t)0x00000048U) /*!< APB3 enable register offset */ +#define APB4EN_REG_OFFSET ((uint32_t)0x0000004CU) /*!< APB4 enable register offset */ +#define AHB1SPEN_REG_OFFSET ((uint32_t)0x00000050U) /*!< AHB1 sleep mode enable register offset */ +#define AHB2SPEN_REG_OFFSET ((uint32_t)0x00000054U) /*!< AHB2 sleep mode enable register offset */ +#define AHB3SPEN_REG_OFFSET ((uint32_t)0x00000058U) /*!< AHB3 sleep mode enable register offset */ +#define AHB4SPEN_REG_OFFSET ((uint32_t)0x0000005CU) /*!< AHB4 sleep mode enable register offset */ +#define APB1SPEN_REG_OFFSET ((uint32_t)0x00000060U) /*!< APB1 sleep mode enable register offset */ +#define APB2SPEN_REG_OFFSET ((uint32_t)0x00000064U) /*!< APB2 sleep mode enable register offset */ +#define APB3SPEN_REG_OFFSET ((uint32_t)0x00000068U) /*!< APB3 sleep mode enable register offset */ +#define APB4SPEN_REG_OFFSET ((uint32_t)0x0000006CU) /*!< APB4 sleep mode enable register offset */ +#define ADD_APB2EN_REG_OFFSET ((uint32_t)0x000000E4U) /*!< APB2 additional enable register offset */ +#define ADD_APB2SPEN_REG_OFFSET ((uint32_t)0x000000E8U) /*!< APB2 additional sleep mode enable register offset */ + +/* peripherals reset */ +#define AHB1RST_REG_OFFSET ((uint32_t)0x00000010U) /*!< AHB1 reset register offset */ +#define AHB2RST_REG_OFFSET ((uint32_t)0x00000014U) /*!< AHB2 reset register offset */ +#define AHB3RST_REG_OFFSET ((uint32_t)0x00000018U) /*!< AHB3 reset register offset */ +#define AHB4RST_REG_OFFSET ((uint32_t)0x0000001CU) /*!< AHB4 reset register offset */ +#define APB1RST_REG_OFFSET ((uint32_t)0x00000020U) /*!< APB1 reset register offset */ +#define APB2RST_REG_OFFSET ((uint32_t)0x00000024U) /*!< APB2 reset register offset */ +#define APB3RST_REG_OFFSET ((uint32_t)0x00000028U) /*!< APB3 reset register offset */ +#define APB4RST_REG_OFFSET ((uint32_t)0x0000002CU) /*!< APB4 reset register offset */ +#define ADD_APB2RST_REG_OFFSET ((uint32_t)0x000000E0U) /*!< APB2 additional reset register offset */ +#define RSTSCK_REG_OFFSET ((uint32_t)0x00000074U) /*!< reset source/clock register offset */ + +/* clock control */ +#define CTL_REG_OFFSET ((uint32_t)0x00000000U) /*!< control register offset */ +#define BDCTL_REG_OFFSET ((uint32_t)0x00000070U) /*!< backup domain control register offset */ +#define ADDCTL0_REG_OFFSET ((uint32_t)0x000000C0U) /*!< additional clock control register 0 offset */ +#define ADDCTL1_REG_OFFSET ((uint32_t)0x000000C4U) /*!< additional clock control register 1 offset */ + +/* clock stabilization and stuck interrupt */ +#define INT_REG_OFFSET ((uint32_t)0x0000000CU) /*!< clock interrupt register offset */ +#define ADDINT_REG_OFFSET ((uint32_t)0x000000CCU) /*!< additional clock interrupt register offset */ + +/* configuration register */ +#define PLL0_REG_OFFSET ((uint32_t)0x00000004U) /*!< PLL0 register offset */ +#define CFG0_REG_OFFSET ((uint32_t)0x00000008U) /*!< clock configuration register 0 offset */ +#define PLL1_REG_OFFSET ((uint32_t)0x00000084U) /*!< PLL1 register offset */ +#define PLL2_REG_OFFSET ((uint32_t)0x00000088U) /*!< PLL2 register offset */ +#define CFG1_REG_OFFSET ((uint32_t)0x0000008CU) /*!< clock configuration register 1 offset */ +#define CFG2_REG_OFFSET ((uint32_t)0x00000090U) /*!< clock configuration register 2 offset */ +#define CFG3_REG_OFFSET ((uint32_t)0x00000094U) /*!< clock configuration register 3 offset */ +#define PLLALL_REG_OFFSET ((uint32_t)0x00000098U) /*!< PLL configuration register */ +#define PLL0FRA_REG_OFFSET ((uint32_t)0x0000009CU) /*!< PLL0 fraction configuration register */ +#define PLL1FRA_REG_OFFSET ((uint32_t)0x000000A0U) /*!< PLL1 fraction configuration register */ +#define PLL2FRA_REG_OFFSET ((uint32_t)0x000000A4U) /*!< PLL2 fraction configuration register */ + +/* peripheral clock enable */ +typedef enum { + /* AHB1 peripherals */ + RCU_ENET1 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 0U), /*!< ENET1 clock */ + RCU_ENET1TX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 1U), /*!< ENET1 TX clock */ + RCU_ENET1RX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 2U), /*!< ENET1 RX clock */ + RCU_ENET1PTP = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 3U), /*!< ENET1 PTP clock */ + RCU_USBHS0 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 14U), /*!< USBHS0 clock */ + RCU_USBHS0ULPI = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 15U), /*!< USBHS0 ULPI clock */ + RCU_DMA0 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 21U), /*!< DMA0 clock */ + RCU_DMA1 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 22U), /*!< DMA1 clock */ + RCU_DMAMUX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 23U), /*!< IPA clock */ + RCU_ENET0 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 25U), /*!< ENET0 clock */ + RCU_ENET0TX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 26U), /*!< ENET0 TX clock */ + RCU_ENET0RX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 27U), /*!< ENET0 RX clock */ + RCU_ENET0PTP = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 28U), /*!< ENET0 PTP clock */ + RCU_USBHS1 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 29U), /*!< USBHS1 clock */ + RCU_USBHS1ULPI = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 30U), /*!< USBHS1 ULPI clock */ + /* AHB2 peripherals */ + RCU_DCI = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 0U), /*!< DCI clock */ + RCU_FAC = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 1U), /*!< FAC clock */ + RCU_SDIO1 = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 2U), /*!< SDIO1 clock */ + RCU_CAU = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 3U), /*!< CAU clock */ + RCU_HAU = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 4U), /*!< HAU clock */ + RCU_TRNG = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 6U), /*!< TRNG clock */ + RCU_TMU = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 7U), /*!< TMU clock */ + RCU_RAMECCMU1 = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 8U), /*!< RAMECCMU1 clock */ + /* AHB3 peripherals */ + RCU_EXMC = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 0U), /*!< EXMC clock */ + RCU_IPA = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 1U), /*!< IPA clock */ + RCU_SDIO0 = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 2U), /*!< SDIO0 clock */ + RCU_MDMA = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 3U), /*!< MDMMA clock */ + RCU_OSPIM = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 4U), /*!< OSPIM clock */ + RCU_OSPI0 = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 5U), /*!< OSPI0 clock */ + RCU_OSPI1 = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 6U), /*!< OSPI1 clock */ + RCU_RTDEC0 = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 8U), /*!< RTDEC0 clock */ + RCU_RTDEC1 = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 9U), /*!< RTDEC1 clock */ + RCU_RAMECCMU0 = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 10U), /*!< RAMECCMU0 clock */ + RCU_CPU = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 15U), /*!< CPU clock */ + /* AHB4 peripherals */ + RCU_GPIOA = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 0U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 1U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 2U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 3U), /*!< GPIOD clock */ + RCU_GPIOE = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 4U), /*!< GPIOE clock */ + RCU_GPIOF = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 5U), /*!< GPIOF clock */ + RCU_GPIOG = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 6U), /*!< GPIOG clock */ + RCU_GPIOH = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 7U), /*!< GPIOH clock */ + RCU_GPIOJ = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 8U), /*!< GPIOJ clock */ + RCU_GPIOK = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 9U), /*!< GPIOK clock */ + RCU_BKPSRAM = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 13U), /*!< BKPSRAM clock */ + RCU_CRC = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 14U), /*!< CRC clock */ + RCU_HWSEM = RCU_REGIDX_BIT(AHB4EN_REG_OFFSET, 15U), /*!< HWSEM clock */ + /* APB1 peripherals */ + RCU_TIMER1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 0U), /*!< TIMER1 clock */ + RCU_TIMER2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 1U), /*!< TIMER2 clock */ + RCU_TIMER3 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 2U), /*!< TIMER3 clock */ + RCU_TIMER4 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 3U), /*!< TIMER4 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 4U), /*!< TIMER5 clock */ + RCU_TIMER6 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 5U), /*!< TIMER6 clock */ + RCU_TIMER22 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 6U), /*!< TIMER22 clock */ + RCU_TIMER23 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 7U), /*!< TIMER23 clock */ + RCU_TIMER30 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 8U), /*!< TIMER30 clock */ + RCU_TIMER31 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 9U), /*!< TIMER31 clock */ + RCU_TIMER50 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 10U), /*!< TIMER50 clock */ + RCU_TIMER51 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 11U), /*!< TIMER51 clock */ + RCU_RSPDIF = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 13U), /*!< RSPDIF clock */ + RCU_SPI1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 14U), /*!< SPI1 clock */ + RCU_SPI2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 15U), /*!< SPI2 clock */ + RCU_MDIO = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 16U), /*!< MDIO clock */ + RCU_USART1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 17U), /*!< USART1 clock */ + RCU_USART2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 18U), /*!< USART2 clock */ + RCU_UART3 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 19U), /*!< UART3 clock */ + RCU_UART4 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 20U), /*!< UART4 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_I2C2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 23U), /*!< I2C2 clock */ + RCU_I2C3 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 24U), /*!< I2C3 clock */ + RCU_CTC = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 27U), /*!< CTC clock */ + RCU_DACHOLD = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 28U), /*!< DACHOLD clock */ + RCU_DAC = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 29U), /*!< DAC clock */ + RCU_UART6 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 30U), /*!< UART6 clock */ + RCU_UART7 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 31U), /*!< UART7 clock */ + /* APB2 peripherals */ + RCU_TIMER0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 0U), /*!< TIMER0 clock */ + RCU_TIMER7 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 1U), /*!< TIMER7 clock */ + RCU_USART0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 4U), /*!< USART0 clock */ + RCU_USART5 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 5U), /*!< USART5 clock */ + RCU_ADC0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 8U), /*!< ADC0 clock */ + RCU_ADC1 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 9U), /*!< ADC1 clock */ + RCU_ADC2 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 10U), /*!< ADC2 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI3 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 13U), /*!< SPI3 clock */ + RCU_TIMER14 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 16U), /*!< TIMER14 clock */ + RCU_TIMER15 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 17U), /*!< TIMER15 clock */ + RCU_TIMER16 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 18U), /*!< TIMER16 clock */ + RCU_HPDF = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 19U), /*!< HPDF clock */ + RCU_SPI4 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 20U), /*!< SPI4 clock */ + RCU_SPI5 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 21U), /*!< SPI5 clock */ + RCU_SAI0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 22U), /*!< SAI0 clock */ + RCU_SAI1 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 23U), /*!< SAI1 clock */ + RCU_SAI2 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 24U), /*!< SAI2 clock */ + RCU_TIMER40 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 25U), /*!< TIMER40 clock */ + RCU_TIMER41 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 26U), /*!< TIMER41 clock */ + RCU_TIMER42 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 27U), /*!< TIMER42 clock */ + RCU_TIMER43 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 28U), /*!< TIMER43 clock */ + RCU_TIMER44 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 29U), /*!< TIMER44 clock */ + RCU_EDOUT = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 30U), /*!< EDOUT clock */ + RCU_TRIGSEL = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 31U), /*!< TRIGSEL clock */ + /* APB3 peripherals */ + RCU_TLI = RCU_REGIDX_BIT(APB3EN_REG_OFFSET, 0U), /*!< TLI clock */ + RCU_WWDGT = RCU_REGIDX_BIT(APB3EN_REG_OFFSET, 1U), /*!< WWDGT clock */ + /* APB4 peripherals */ + RCU_SYSCFG = RCU_REGIDX_BIT(APB4EN_REG_OFFSET, 0U), /*!< SYSCFG clock */ + RCU_CMP = RCU_REGIDX_BIT(APB4EN_REG_OFFSET, 1U), /*!< CMP clock */ + RCU_VREF = RCU_REGIDX_BIT(APB4EN_REG_OFFSET, 2U), /*!< VREF clock */ + RCU_LPDTS = RCU_REGIDX_BIT(APB4EN_REG_OFFSET, 3U), /*!< LPDTS clock */ + RCU_PMU = RCU_REGIDX_BIT(APB4EN_REG_OFFSET, 4U), /*!< PMU clock */ + RCU_RTC = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 15U), /*!< RTC clock */ + /* APB2 additional peripherals */ + RCU_CAN0 = RCU_REGIDX_BIT(ADD_APB2EN_REG_OFFSET, 0U), /*!< CAN0 clock */ + RCU_CAN1 = RCU_REGIDX_BIT(ADD_APB2EN_REG_OFFSET, 1U), /*!< CAN1 clock */ + RCU_CAN2 = RCU_REGIDX_BIT(ADD_APB2EN_REG_OFFSET, 2U) /*!< CAN2 clock */ +} rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum { + /* AHB1 peripherals */ + RCU_ENET1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 0U), /*!< ENET1 clock when sleep mode */ + RCU_ENET1TX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 1U), /*!< ENET1 TX clock when sleep mode */ + RCU_ENET1RX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 2U), /*!< ENET1 RX clock when sleep mode */ + RCU_ENET1PTP_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 3U), /*!< ENET1 PTP clock when sleep mode */ + RCU_USBHS0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 14U), /*!< USBHS0 clock when sleep mode */ + RCU_USBHS0ULPI_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 15U), /*!< USBHS0ULPI clock when sleep mode */ + RCU_SRAM0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 16U), /*!< SRAM0 clock when sleep mode */ + RCU_SRAM1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 17U), /*!< SRAM1 clock when sleep mode */ + RCU_DMA0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 21U), /*!< DMA0 clock when sleep mode */ + RCU_DMA1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 22U), /*!< DMA1 clock when sleep mode */ + RCU_DMAMUX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 23U), /*!< DMAMUX clock when sleep mode */ + RCU_ENET0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 25U), /*!< ENET0 clock when sleep mode */ + RCU_ENET0TX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 26U), /*!< ENET0 TX clock when sleep mode */ + RCU_ENET0RX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 27U), /*!< ENET0 RX clock when sleep mode */ + RCU_ENET0PTP_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 28U), /*!< ENET0 PTP clock when sleep mode */ + RCU_USBHS1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 29U), /*!< USBHS1 clock when sleep mode */ + RCU_USBHS1ULPI_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 30U), /*!< USBHS1ULPI clock when sleep mode */ + /* AHB2 peripherals */ + RCU_DCI_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 0U), /*!< DCI clock when sleep mode */ + RCU_FAC_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 1U), /*!< FAC clock when sleep mode */ + RCU_SDIO1_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 2U), /*!< SDIO1 clock when sleep mode */ + RCU_CAU_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 3U), /*!< CAU clock when sleep mode */ + RCU_HAU_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 4U), /*!< HAU clock when sleep mode */ + RCU_TRNG_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 6U), /*!< TRNG clock when sleep mode */ + RCU_TMU_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 7U), /*!< TMU clock when sleep mode */ + RCU_RAMECCMU1_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 8U), /*!< RAMECCMU1 clock when sleep mode */ + /* AHB3 peripherals */ + RCU_EXMC_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 0U), /*!< EXMC clock when sleep mode */ + RCU_IPA_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 1U), /*!< IPA clock when sleep mode */ + RCU_SDIO0_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 2U), /*!< SDIO0 clock when sleep mode */ + RCU_MDMA_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 3U), /*!< MDMMA clock when sleep mode */ + RCU_OSPIM_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 4U), /*!< OSPIM clock when sleep mode */ + RCU_OSPI0_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 5U), /*!< OSPI0 clock when sleep mode */ + RCU_OSPI1_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 6U), /*!< OSPI1 clock when sleep mode */ + RCU_RTDEC0_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 8U), /*!< RTDEC0 clock when sleep mode */ + RCU_RTDEC1_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 9U), /*!< RTDEC1 clock when sleep mode */ + RCU_RAMECCMU0_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 10U), /*!< RAMECCMU0 clock when sleep mode */ + RCU_AXISRAM_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 14U), /*!< AXISRAM clock when sleep mode */ + RCU_FMC_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 15U), /*!< FMC clock when sleep mode */ + /* AHB4 peripherals */ + RCU_GPIOA_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 0U), /*!< GPIOA clock when sleep mode */ + RCU_GPIOB_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 1U), /*!< GPIOB clock when sleep mode */ + RCU_GPIOC_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 2U), /*!< GPIOC clock when sleep mode */ + RCU_GPIOD_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 3U), /*!< GPIOD clock when sleep mode */ + RCU_GPIOE_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 4U), /*!< GPIOE clock when sleep mode */ + RCU_GPIOF_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 5U), /*!< GPIOF clock when sleep mode */ + RCU_GPIOG_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 6U), /*!< GPIOG clock when sleep mode */ + RCU_GPIOH_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 7U), /*!< GPIOH clock when sleep mode */ + RCU_GPIOJ_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 8U), /*!< GPIOJ clock when sleep mode */ + RCU_GPIOK_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 9U), /*!< GPIOK clock when sleep mode */ + RCU_BKPSRAM_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 13U), /*!< BKPSRAM clock when sleep mode */ + RCU_CRC_SLP = RCU_REGIDX_BIT(AHB4SPEN_REG_OFFSET, 14U), /*!< CRC clock when sleep mode */ + /* APB1 peripherals */ + RCU_TIMER1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 0U), /*!< TIMER1 clock when sleep mode */ + RCU_TIMER2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 1U), /*!< TIMER2 clock when sleep mode */ + RCU_TIMER3_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 2U), /*!< TIMER3 clock when sleep mode */ + RCU_TIMER4_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 3U), /*!< TIMER4 clock when sleep mode */ + RCU_TIMER5_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 4U), /*!< TIMER5 clock when sleep mode */ + RCU_TIMER6_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 5U), /*!< TIMER6 clock when sleep mode */ + RCU_TIMER22_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 6U), /*!< TIMER22 clock when sleep mode */ + RCU_TIMER23_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 7U), /*!< TIMER23 clock when sleep mode */ + RCU_TIMER30_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 8U), /*!< TIMER30 clock when sleep mode */ + RCU_TIMER31_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 9U), /*!< TIMER31 clock when sleep mode */ + RCU_TIMER50_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 10U), /*!< TIMER50 clock when sleep mode */ + RCU_TIMER51_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 11U), /*!< TIMER51 clock when sleep mode */ + RCU_RSPDIF_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 13U), /*!< RSPDIF clock when sleep mode */ + RCU_SPI1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 14U), /*!< SPI1 clock when sleep mode */ + RCU_SPI2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 15U), /*!< SPI2 clock when sleep mode */ + RCU_MDIO_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 16U), /*!< MDIO clock when sleep mode */ + RCU_USART1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 17U), /*!< USART1 clock when sleep mode */ + RCU_USART2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 18U), /*!< USART2 clock when sleep mode */ + RCU_UART3_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 19U), /*!< UART3 clock when sleep mode */ + RCU_UART4_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 20U), /*!< UART4 clock when sleep mode */ + RCU_I2C0_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 21U), /*!< I2C0 clock when sleep mode */ + RCU_I2C1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 22U), /*!< I2C1 clock when sleep mode */ + RCU_I2C2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 23U), /*!< I2C2 clock when sleep mode */ + RCU_I2C3_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 24U), /*!< I2C3 clock when sleep mode */ + RCU_CTC_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 27U), /*!< CTC clock when sleep mode */ + RCU_DACHOLD_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 28U), /*!< DACHOLD clock when sleep mode */ + RCU_DAC_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 29U), /*!< DAC clock when sleep mode */ + RCU_UART6_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 30U), /*!< UART6 clock when sleep mode */ + RCU_UART7_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 31U), /*!< UART7 clock when sleep mode */ + /* APB2 peripherals */ + RCU_TIMER0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 0U), /*!< TIMER0 clock when sleep mode */ + RCU_TIMER7_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 1U), /*!< TIMER7 clock when sleep mode */ + RCU_USART0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 4U), /*!< USART0 clock when sleep mode */ + RCU_USART5_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 5U), /*!< USART5 clock when sleep mode */ + RCU_ADC0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 8U), /*!< ADC0 clock when sleep mode */ + RCU_ADC1_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 9U), /*!< ADC1 clock when sleep mode */ + RCU_ADC2_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 10U), /*!< ADC2 clock when sleep mode */ + RCU_SPI0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 12U), /*!< SPI0 clock when sleep mode */ + RCU_SPI3_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 13U), /*!< SPI3 clock when sleep mode */ + RCU_TIMER14_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 16U), /*!< TIMER14 clock when sleep mode */ + RCU_TIMER15_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 17U), /*!< TIMER15 clock when sleep mode */ + RCU_TIMER16_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 18U), /*!< TIMER16 clock when sleep mode */ + RCU_HPDF_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 19U), /*!< HPDF clock when sleep mode */ + RCU_SPI4_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 20U), /*!< SPI4 clock when sleep mode */ + RCU_SPI5_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 21U), /*!< SPI5 clock when sleep mode */ + RCU_SAI0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 22U), /*!< SAI0 clock when sleep mode */ + RCU_SAI1_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 23U), /*!< SAI1 clock when sleep mode */ + RCU_SAI2_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 24U), /*!< SAI2 clock when sleep mode */ + RCU_TIMER40_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 25U), /*!< TIMER40 clock when sleep mode */ + RCU_TIMER41_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 26U), /*!< TIMER41 clock when sleep mode */ + RCU_TIMER42_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 27U), /*!< TIMER42 clock when sleep mode */ + RCU_TIMER43_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 28U), /*!< TIMER43 clock when sleep mode */ + RCU_TIMER44_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 29U), /*!< TIMER44 clock when sleep mode */ + RCU_EDOUT_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 30U), /*!< EDOUT clock when sleep mode */ + RCU_TRIGSEL_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 31U), /*!< TRIGSEL clock when sleep mode */ + /* APB3 peripherals */ + RCU_TLI_SLP = RCU_REGIDX_BIT(APB3SPEN_REG_OFFSET, 0U), /*!< TLI clock when sleep mode */ + RCU_WWDGT_SLP = RCU_REGIDX_BIT(APB3SPEN_REG_OFFSET, 1U), /*!< WWDGT clock when sleep mode */ + /* APB4 peripherals */ + RCU_SYSCFG_SLP = RCU_REGIDX_BIT(APB4SPEN_REG_OFFSET, 0U), /*!< SYSCFG clock when sleep mode */ + RCU_CMP_SLP = RCU_REGIDX_BIT(APB4SPEN_REG_OFFSET, 1U), /*!< CMP clock when sleep mode */ + RCU_VREF_SLP = RCU_REGIDX_BIT(APB4SPEN_REG_OFFSET, 2U), /*!< VREF clock when sleep mode */ + RCU_LPDTS_SLP = RCU_REGIDX_BIT(APB4SPEN_REG_OFFSET, 3U), /*!< LPDTS clock when sleep mode */ + RCU_PMU_SLP = RCU_REGIDX_BIT(APB4SPEN_REG_OFFSET, 4U), /*!< PMU clock when sleep mode */ + /* APB2 additional peripherals */ + RCU_CAN0_SLP = RCU_REGIDX_BIT(ADD_APB2SPEN_REG_OFFSET, 0U), /*!< CAN0 clock when sleep mode */ + RCU_CAN1_SLP = RCU_REGIDX_BIT(ADD_APB2SPEN_REG_OFFSET, 1U), /*!< CAN1 clock when sleep mode */ + RCU_CAN2_SLP = RCU_REGIDX_BIT(ADD_APB2SPEN_REG_OFFSET, 2U) /*!< CAN2 clock when sleep mode */ +} rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum { + /* AHB1 peripherals */ + RCU_ENET1RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 0U), /*!< ENET1 clock reset */ + RCU_USBHS0RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 14U), /*!< USBHS0 clock reset */ + RCU_DMA0RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 21U), /*!< DMA0 clock reset */ + RCU_DMA1RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 22U), /*!< DMA1 clock reset */ + RCU_DMAMUXRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 23U), /*!< DMAMUX clock reset */ + RCU_ENET0RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 25U), /*!< ENET clock reset */ + RCU_USBHS1RST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 29U), /*!< USBHS1HS clock reset */ + /* AHB2 peripherals */ + RCU_DCIRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 0U), /*!< DCI clock reset */ + RCU_FACRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 1U), /*!< FAC clock reset */ + RCU_SDIO1RST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 2U), /*!< SDIO1 clock reset */ + RCU_CAURST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 3U), /*!< CAU clock reset */ + RCU_HAURST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 4U), /*!< HAU clock reset */ + RCU_TRNGRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 6U), /*!< TRNG clock reset */ + RCU_TMURST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 7U), /*!< TMU clock reset */ + /* AHB3 peripherals */ + RCU_EXMCRST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 0U), /*!< EXMC clock reset */ + RCU_IPARST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 1U), /*!< IPA clock reset */ + RCU_SDIO0RST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 2U), /*!< SDIO0 clock reset */ + RCU_MDMARST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 3U), /*!< MDMMA clock reset */ + RCU_OSPIMRST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 4U), /*!< OSPIM clock reset */ + RCU_OSPI0RST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 5U), /*!< OSPI0 clock reset */ + RCU_OSPI1RST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 6U), /*!< OSPI1 clock reset */ + RCU_RTDEC0RST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 8U), /*!< RTDEC0 clock reset */ + RCU_RTDEC1RST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 9U), /*!< RTDEC1 clock reset */ + /* AHB4 peripherals */ + RCU_GPIOARST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 0U), /*!< GPIOA clock reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 1U), /*!< GPIOB clock reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 2U), /*!< GPIOC clock reset */ + RCU_GPIODRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 3U), /*!< GPIOD clock reset */ + RCU_GPIOERST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 4U), /*!< GPIOE clock reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 5U), /*!< GPIOF clock reset */ + RCU_GPIOGRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 6U), /*!< GPIOG clock reset */ + RCU_GPIOHRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 7U), /*!< GPIOH clock reset */ + RCU_GPIOJRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 8U), /*!< GPIOJ clock reset */ + RCU_GPIOKRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 9U), /*!< GPIOK clock reset */ + RCU_CRCRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 14U), /*!< CRC clock reset */ + RCU_HWSEMRST = RCU_REGIDX_BIT(AHB4RST_REG_OFFSET, 15U), /*!< HWSEM clock reset */ + /* APB1 peripherals */ + RCU_TIMER1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 0U), /*!< TIMER1 clock reset */ + RCU_TIMER2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 1U), /*!< TIMER2 clock reset */ + RCU_TIMER3RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 2U), /*!< TIMER3 clock reset */ + RCU_TIMER4RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 3U), /*!< TIMER4 clock reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 4U), /*!< TIMER5 clock reset */ + RCU_TIMER6RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 5U), /*!< TIMER6 clock reset */ + RCU_TIMER22RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 6U), /*!< TIMER22 clock reset */ + RCU_TIMER23RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 7U), /*!< TIMER23 clock reset */ + RCU_TIMER30RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 8U), /*!< TIMER30 clock reset */ + RCU_TIMER31RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 9U), /*!< TIMER31 clock reset */ + RCU_TIMER50RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 10U), /*!< TIMER50 clock reset */ + RCU_TIMER51RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 11U), /*!< TIMER51 clock reset */ + RCU_RSPDIFRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 13U), /*!< RSPDIF clock reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 14U), /*!< SPI1 clock reset */ + RCU_SPI2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 15U), /*!< SPI2 clock reset */ + RCU_MDIORST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 16U), /*!< MDIO clock reset */ + RCU_USART1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 17U), /*!< USART1 clock reset */ + RCU_USART2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 18U), /*!< USART2 clock reset */ + RCU_UART3RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 19U), /*!< UART3 clock reset */ + RCU_UART4RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 20U), /*!< UART4 clock reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 21U), /*!< I2C0 clock reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 22U), /*!< I2C1 clock reset */ + RCU_I2C2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 23U), /*!< I2C2 clock reset */ + RCU_I2C3RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 24U), /*!< I2C3 clock reset */ + RCU_CTCRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 27U), /*!< CTC clock reset */ + RCU_DACHOLDRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 28U), /*!< DACHOLD clock reset */ + RCU_DACRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 29U), /*!< DAC clock reset */ + RCU_UART6RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 30U), /*!< UART6 clock reset */ + RCU_UART7RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 31U), /*!< UART7 clock reset */ + /* APB2 peripherals */ + RCU_TIMER0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 0U), /*!< TIMER0 clock reset */ + RCU_TIMER7RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 1U), /*!< TIMER7 clock reset */ + RCU_USART0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 4U), /*!< USART0 clock reset */ + RCU_USART5RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 5U), /*!< USART5 clock reset */ + RCU_ADC0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 8U), /*!< ADC0 clock reset */ + RCU_ADC1RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 9U), /*!< ADC1 clock reset */ + RCU_ADC2RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 10U), /*!< ADC2 clock reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 12U), /*!< SPI0 clock reset */ + RCU_SPI3RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 13U), /*!< SPI3 clock reset */ + RCU_TIMER14RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 16U), /*!< TIMER14 clock reset */ + RCU_TIMER15RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 17U), /*!< TIMER15 clock reset */ + RCU_TIMER16RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 18U), /*!< TIMER16 clock reset */ + RCU_HPDFRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 19U), /*!< HPDF clock reset */ + RCU_SPI4RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 20U), /*!< SPI4 clock reset */ + RCU_SPI5RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 21U), /*!< SPI5 clock reset */ + RCU_SAI0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 22U), /*!< SAI0 clock reset */ + RCU_SAI1RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 23U), /*!< SAI1 clock reset */ + RCU_SAI2RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 24U), /*!< SAI2 clock reset */ + RCU_TIMER40RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 25U), /*!< TIMER40 clock reset */ + RCU_TIMER41RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 26U), /*!< TIMER41 clock reset */ + RCU_TIMER42RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 27U), /*!< TIMER42 clock reset */ + RCU_TIMER43RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 28U), /*!< TIMER43 clock reset */ + RCU_TIMER44RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 29U), /*!< TIMER44 clock reset */ + RCU_EDOUTRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 30U), /*!< EDOUT clock reset */ + RCU_TRIGSELRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 31U), /*!< TRIGSEL clock reset */ + /* APB3 peripherals */ + RCU_TLIRST = RCU_REGIDX_BIT(APB3RST_REG_OFFSET, 0U), /*!< TLI clock reset */ + RCU_WWDGTRST = RCU_REGIDX_BIT(APB3RST_REG_OFFSET, 1U), /*!< WWDGT clock reset */ + /* APB4 peripherals */ + RCU_SYSCFGRST = RCU_REGIDX_BIT(APB4RST_REG_OFFSET, 0U), /*!< SYSCFG clock reset */ + RCU_CMPRST = RCU_REGIDX_BIT(APB4RST_REG_OFFSET, 1U), /*!< CMP clock reset */ + RCU_VREFRST = RCU_REGIDX_BIT(APB4RST_REG_OFFSET, 2U), /*!< VREF clock reset */ + RCU_LPDTSRST = RCU_REGIDX_BIT(APB4RST_REG_OFFSET, 3U), /*!< LPDTS clock reset */ + RCU_PMURST = RCU_REGIDX_BIT(APB4RST_REG_OFFSET, 4U), /*!< PMU clock reset */ + /* APB2 additional peripherals */ + RCU_CAN0RST = RCU_REGIDX_BIT(ADD_APB2RST_REG_OFFSET, 0U), /*!< CAN0 clock reset */ + RCU_CAN1RST = RCU_REGIDX_BIT(ADD_APB2RST_REG_OFFSET, 1U), /*!< CAN1 clock reset */ + RCU_CAN2RST = RCU_REGIDX_BIT(ADD_APB2RST_REG_OFFSET, 2U) /*!< CAN2 clock reset */ +} rcu_periph_reset_enum; + +/* clock stabilization and failure and peripheral reset flags */ +typedef enum { + /* clock stabilization flags */ + RCU_FLAG_IRC64MSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 31U), /*!< IRC64M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLL0STB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 25U), /*!< PLL0 stabilization flags */ + RCU_FLAG_PLL1STB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 27U), /*!< PLL1 stabilization flags */ + RCU_FLAG_PLL2STB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 29U), /*!< PLL2 stabilization flags */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 1U), /*!< LXTAL stabilization flags */ + RCU_FLAG_IRC32KSTB = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 1U), /*!< IRC32K stabilization flags */ + RCU_FLAG_IRC48MSTB = RCU_REGIDX_BIT(ADDCTL0_REG_OFFSET, 17U), /*!< IRC48M stabilization flags */ + RCU_FLAG_LPIRC4MSTB = RCU_REGIDX_BIT(ADDCTL1_REG_OFFSET, 1U), /*!< LPIRC4M stabilization flags */ + RCU_FLAG_PLLUSBHS0STB = RCU_REGIDX_BIT(ADDCTL1_REG_OFFSET, 29U), /*!< PLLUSBHS0 stabilization flags */ + RCU_FLAG_PLLUSBHS1STB = RCU_REGIDX_BIT(ADDCTL1_REG_OFFSET, 31U), /*!< PLLUSBHS1 stabilization flags */ + /* clock failure flag */ + RCU_FLAG_LCKMD = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 6U), /*!< LXTAL clock failure detection flags */ + /* reset source flags */ + RCU_FLAG_BORRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 25U), /*!< BOR reset flags */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 26U), /*!< External PIN reset flags */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 27U), /*!< power reset flags */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 28U), /*!< Software reset flags */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 29U), /*!< FWDGT reset flags */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 30U), /*!< WWDGT reset flags */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 31U) /*!< low-power reset flags */ +} rcu_flag_enum; + +/* clock stabilization and stuck interrupt flags */ +typedef enum { + RCU_INT_FLAG_IRC32KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 0U), /*!< IRC32K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 1U), /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC64MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 2U), /*!< IRC64M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLL0STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 4U), /*!< PLL0 stabilization interrupt flag */ + RCU_INT_FLAG_PLL1STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 5U), /*!< PLL1 stabilization interrupt flag */ + RCU_INT_FLAG_PLL2STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U), /*!< PLL2 stabilization interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 7U), /*!< HXTAL clock stuck interrupt flag */ + RCU_INT_FLAG_LCKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 27U), /*!< LXTAL clock stuck interrupt flag */ + RCU_INT_FLAG_LPIRC4MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 24U), /*!< LPIRC4M stabilization interrupt flag */ + RCU_INT_FLAG_IRC48MSTB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 6U), /*!< IRC48M stabilization interrupt flag */ + RCU_INT_FLAG_PLLUSBHS0STB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 4U), /*!< PLLUSBHS0 stabilization interrupt flag */ + RCU_INT_FLAG_PLLUSBHS1STB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 5U) /*!< PLLUSBHS1 stabilization interrupt flag */ +} rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum { + RCU_INT_FLAG_IRC32KSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 16U), /*!< IRC32K stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 17U), /*!< LXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC64MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U), /*!< IRC64M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 19U), /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLL0STB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 20U), /*!< PLL0 stabilization interrupt flags clear */ + RCU_INT_FLAG_PLL1STB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 21U), /*!< PLL1 stabilization interrupt flags clear */ + RCU_INT_FLAG_PLL2STB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U), /*!< PLL2 stabilization interrupt flags clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 23U), /*!< HXTAL clock stuck interrupt flags clear */ + RCU_INT_FLAG_LCKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 28U), /*!< LXTAL clock stuck interrupt flags clear */ + RCU_INT_FLAG_LPIRC4MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 26U), /*!< LPIRC4M stabilization interrupt flag clear */ + RCU_INT_FLAG_IRC48MSTB_CLR = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 22U), /*!< IRC48M stabilization interrupt flag clear */ + RCU_INT_FLAG_PLLUSBHS0STB_CLR = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 20U), /*!< PLLUSBHS0 stabilization interrupt flag clear */ + RCU_INT_FLAG_PLLUSBHS1STB_CLR = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 21U) /*!< PLLUSBHS1 stabilization interrupt flag clear */ +} rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum { + RCU_INT_IRC32KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 8U), /*!< IRC32K stabilization interrupt */ + RCU_INT_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 9U), /*!< LXTAL stabilization interrupt */ + RCU_INT_IRC64MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 10U), /*!< IRC64M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 11U), /*!< HXTAL stabilization interrupt */ + RCU_INT_PLL0STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 12U), /*!< PLL0 stabilization interrupt */ + RCU_INT_PLL1STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 13U), /*!< PLL1 stabilization interrupt */ + RCU_INT_PLL2STB = RCU_REGIDX_BIT(INT_REG_OFFSET, 14U), /*!< PLL2 stabilization interrupt */ + RCU_INT_IRC48MSTB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 14U), /*!< internal 48 MHz RC oscillator stabilization interrupt */ + RCU_INT_LPIRC4MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 25U), /*!< LPIRC4M stabilization interrupt */ + RCU_INT_PLLUSBHS0STB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 12U), /*!< PLLUSBHS0 stabilization interrupt */ + RCU_INT_PLLUSBHS1STB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 13U) /*!< PLLUSBHS1 stabilization interrupt */ +} rcu_int_enum; + +/* oscillator types */ +typedef enum { + RCU_HXTAL = RCU_REGIDX_BIT(CTL_REG_OFFSET, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 0U), /*!< LXTAL */ + RCU_IRC64M = RCU_REGIDX_BIT(CTL_REG_OFFSET, 30U), /*!< IRC64M */ + RCU_IRC48M = RCU_REGIDX_BIT(ADDCTL0_REG_OFFSET, 16U), /*!< IRC48M */ + RCU_IRC32K = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U), /*!< IRC32K */ + RCU_LPIRC4M = RCU_REGIDX_BIT(ADDCTL1_REG_OFFSET, 0U), /*!< LPIRC4M */ + RCU_PLL0_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 24U), /*!< PLL0 */ + RCU_PLL1_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 26U), /*!< PLL1 */ + RCU_PLL2_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 28U), /*!< PLL2 */ + RCU_PLLUSBHS0_CK = RCU_REGIDX_BIT(ADDCTL1_REG_OFFSET, 28U), /*!< PLLUSBHS0 */ + RCU_PLLUSBHS1_CK = RCU_REGIDX_BIT(ADDCTL1_REG_OFFSET, 30U) /*!< PLLUSBHS1 */ +} rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum { + CK_SYS = 0U, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB1, /*!< APB1 clock */ + CK_APB2, /*!< APB2 clock */ + CK_APB3, /*!< APB3 clock */ + CK_APB4, /*!< APB4 clock */ + CK_PLL0P, /*!< PLL0P clock */ + CK_PLL0Q, /*!< PLL0Q clock */ + CK_PLL0R, /*!< PLL0R clock */ + CK_PLL1P, /*!< PLL1P clock */ + CK_PLL1Q, /*!< PLL1Q clock */ + CK_PLL1R, /*!< PLL1R clock */ + CK_PLL2P, /*!< PLL2P clock */ + CK_PLL2Q, /*!< PLL2Q clock */ + CK_PLL2R, /*!< PLL2R clock */ + CK_PER, /*!< PER clock */ + CK_USART0, /*!< USART0 clock */ + CK_USART1, /*!< USART1 clock */ + CK_USART2, /*!< USART2 clock */ + CK_USART5, /*!< USART5 clock */ + CK_IRC64MDIV, /*!< IRC64MDIV clock */ + CK_HXTAL, /*!< HXTAL clock */ + CK_LPIRC4M /*!< LPIRC4M clock */ +} rcu_clock_freq_enum; + +typedef enum { + IDX_USART0 = 0U, /*!< idnex of USART0 */ + IDX_USART1, /*!< idnex of USART1 */ + IDX_USART2, /*!< idnex of USART2 */ + IDX_USART5 /*!< idnex of USART5 */ +} usart_idx_enum; + +typedef enum { + IDX_I2C0 = 0U, /*!< idnex of I2C0 */ + IDX_I2C1, /*!< idnex of I2C1 */ + IDX_I2C2, /*!< idnex of I2C2 */ + IDX_I2C3, /*!< idnex of I2C2 */ +} i2c_idx_enum; + +typedef enum { + IDX_CAN0 = 0U, /*!< idnex of CAN0 */ + IDX_CAN1, /*!< idnex of CAN1 */ + IDX_CAN2, /*!< idnex of CAN2 */ +} can_idx_enum; + +typedef enum { + IDX_SAI0 = 0U, /*!< idnex of SAI0 */ + IDX_SAI1 /*!< idnex of SAI1 */ +} sai_idx_enum; + +typedef enum { + IDX_SAI2B0 = 0U, /*!< idnex of SAI2B0 */ + IDX_SAI2B1 /*!< idnex of SAI2B1 */ +} sai2b_idx_enum; + +typedef enum { + IDX_ADC0 = 0U, /*!< idnex of ADC0 */ + IDX_ADC1, /*!< idnex of ADC1 */ + IDX_ADC2 /*!< idnex of ADC2 */ +} adc_idx_enum; + +typedef enum { + IDX_USBHS0 = 0U, /*!< idnex of USBHS0 */ + IDX_USBHS1 /*!< idnex of USBHS1 */ +} usbhs_idx_enum; + +typedef enum { + IDX_PLL0 = 0U, /*!< idnex of PLL0 */ + IDX_PLL1, /*!< idnex of PLL1 */ + IDX_PLL2 /*!< idnex of PLL2 */ +} pll_idx_enum; + +typedef enum { + IDX_SDIO0 = 0U, /*!< idnex of SDIO0 */ + IDX_SDIO1 /*!< idnex of SDIO1 */ +} sdio_idx_enum; + +typedef enum { + IDX_SPI0 = 0U, /*!< idnex of SPI0 */ + IDX_SPI1, /*!< idnex of SPI1 */ + IDX_SPI2, /*!< idnex of SPI2 */ + IDX_SPI3, /*!< idnex of SPI3 */ + IDX_SPI4, /*!< idnex of SPI4 */ + IDX_SPI5 /*!< idnex of SPI5 */ +} spi_idx_enum; + +/* RCU_PLLADDCTL register bit define */ +/* PLLs P/Q/R divider output enable */ +#define RCU_PLL0P RCU_PLLADDCTL_PLL0PEN /*!< PLL0P divider output enable */ +#define RCU_PLL0Q RCU_PLLADDCTL_PLL0QEN /*!< PLL0Q divider output enable */ +#define RCU_PLL0R RCU_PLLADDCTL_PLL0REN /*!< PLL0R divider output enable */ +#define RCU_PLL1P RCU_PLLADDCTL_PLL1PEN /*!< PLL1P divider output enable */ +#define RCU_PLL1Q RCU_PLLADDCTL_PLL1QEN /*!< PLL1Q divider output enable */ +#define RCU_PLL1R RCU_PLLADDCTL_PLL1REN /*!< PLL1R divider output enable */ +#define RCU_PLL2P RCU_PLLADDCTL_PLL2PEN /*!< PLL2P divider output enable */ +#define RCU_PLL2Q RCU_PLLADDCTL_PLL2QEN /*!< PLL2Q divider output enable */ +#define RCU_PLL2R RCU_PLLADDCTL_PLL2REN /*!< PLL2R divider output enable */ + +/* RCU_CFG0 register bit define */ +/* USARTx(x=0,1,2,5) clock source selection */ +#define CFG1_USART0SEL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define RCU_USARTSRC_APB CFG1_USART0SEL(0) /*!< CK_USART select CK_APB */ +#define RCU_USARTSRC_AHB CFG1_USART0SEL(1) /*!< CK_USART select CK_AHB */ +#define RCU_USARTSRC_LXTAL CFG1_USART0SEL(2) /*!< CK_USART select CK_LXTAL */ +#define RCU_USARTSRC_IRC64MDIV CFG1_USART0SEL(3) /*!< CK_USART select CK_IRC16MDIV */ + +/* I2Cx(x=0,1,2,3) clock source selection */ +#define CFG3_I2C1SEL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define RCU_I2CSRC_APB1 CFG3_I2C1SEL(0) /*!< CK_I2C select CK_APB1 */ +#define RCU_I2CSRC_PLL2R CFG3_I2C1SEL(1) /*!< CK_I2C select CK_PLL2R */ +#define RCU_I2CSRC_IRC64MDIV CFG3_I2C1SEL(2) /*!< CK_I2C select CK_IRC64MDIV */ +#define RCU_I2CSRC_LPIRC4M CFG3_I2C1SEL(3) /*!< CK_I2C select CK_LPIRC4M */ + +/* CANx(x=0,1,2) clock source selection */ +#define CFG1_CAN0SEL(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define RCU_CANSRC_HXTAL CFG1_CAN0SEL(0) /*!< CK_CAN select CK_HXTAL */ +#define RCU_CANSRC_APB2 CFG1_CAN0SEL(1) /*!< CK_CAN select CK_APB2 */ +#define RCU_CANSRC_APB2_DIV2 CFG1_CAN0SEL(2) /*!< CK_CAN select CK_APB2/2 */ +#define RCU_CANSRC_IRC64MDIV CFG1_CAN0SEL(3) /*!< CK_CAN select CK_IRC64MDIV */ + +/* RSPDIF clock selection */ +#define CFG1_RSPDIFSEL(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define RCU_RSPDIFSRC_PLL0Q CFG1_RSPDIFSEL(0) /*!< CK_RSPDIF select CK_PLL0Q */ +#define RCU_RSPDIFSRC_PLL1R CFG1_RSPDIFSEL(1) /*!< CK_RSPDIF select CK_PLL1R */ +#define RCU_RSPDIFSRC_PLL2R CFG1_RSPDIFSEL(2) /*!< CK_RSPDIF select CK_PLL2R */ +#define RCU_RSPDIFSRC_IRC64MDIV CFG1_RSPDIFSEL(3) /*!< CK_RSPDIF select CK_IRC64MDIV */ + +/* EXMC clock selection */ +#define CFG4_EXMCSEL(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define RCU_EXMCSRC_AHB CFG4_EXMCSEL(0) /*!< CK_EXMC select CK_AHB */ +#define RCU_EXMCSRC_PLL0Q CFG4_EXMCSEL(1) /*!< CK_EXMC select CK_PLL0Q */ +#define RCU_EXMCSRC_PLL1R CFG4_EXMCSEL(2) /*!< CK_EXMC select CK_PLL1R */ +#define RCU_EXMCSRC_PER CFG4_EXMCSEL(3) /*!< CK_EXMC select CK_PER */ + +/* SPIx(x=0,1,2) clock source selecion */ +#define CFG5_SPI0SEL(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define RCU_SPISRC_PLL0Q CFG5_SPI0SEL(0) /*!< CK_SPI select CK_PLL0Q */ +#define RCU_SPISRC_PLL1P CFG5_SPI0SEL(1) /*!< CK_SPI select CK_PLL1P */ +#define RCU_SPISRC_PLL2P CFG5_SPI0SEL(2) /*!< CK_SPI select CK_PLL2P */ +#define RCU_SPISRC_I2S_CKIN CFG5_SPI0SEL(3) /*!< CK_SPI select I2S_CKIN */ +#define RCU_SPISRC_PER CFG5_SPI0SEL(4) /*!< CK_SPI select CK_PER */ + +/* SPIx(x=3,4,5) clock source selection */ +#define CFG5_SPI3SEL(regval) (BITS(12,14) & ((uint32_t)(regval) << 12U)) +#define RCU_SPISRC_APB2 CFG5_SPI3SEL(0) /*!< CK_SPI select CK_APB2 */ +#define RCU_SPISRC_PLL1Q CFG5_SPI3SEL(1) /*!< CK_SPI select CK_PLL1Q */ +#define RCU_SPISRC_PLL2Q CFG5_SPI3SEL(2) /*!< CK_SPI select CK_PLL2Q */ +#define RCU_SPISRC_IRC64MDIV CFG5_SPI3SEL(3) /*!< CK_SPI select CK_IRC64MDIV */ +#define RCU_SPISRC_LPIRC4M CFG5_SPI3SEL(4) /*!< CK_SPI select CK_LPIRC4M */ +#define RCU_SPISRC_HXTAL CFG5_SPI3SEL(5) /*!< CK_SPI select CK_HXTAL */ +#define RCU_SPI5SRC_I2S_CKIN CFG5_SPI3SEL(6) /*!< CK_SPI select I2S_CKIN */ + +/* SDIOx(x=0,1) clock source selection */ +#define RCU_SDIO0SRC_PLL0Q (uint32_t)(0X00000000U) /*!< CK_SDIO0 select CK_PLL0Q */ +#define RCU_SDIO0SRC_PLL1R RCU_CFG4_SDIO0SEL /*!< CK_SDIO0 select CK_PLL1R */ +#define RCU_SDIO1SRC_PLL0Q (uint32_t)(0X00000000U) /*!< CK_SDIO1 select CK_PLL0Q */ +#define RCU_SDIO1SRC_PLL1R RCU_CFG3_SDIO1SEL /*!< CK_SDIO1 select CK_PLL1R */ + +/* Deep-sleep wakeup system clock source selection */ +#define RCU_DSPWUSSEL_IRC64MDIV (uint32_t)(0X00000000U) /*!< CK_IRC64MDIV is selected as wake up system clock from deep-sleep mode */ +#define RCU_DSPWUSSEL_LPIRC4M RCU_CFG3_DSPWUSSEL /*!< CK_LPIRC4M is selected as wake up system clock from deep-sleep mode */ + +/* ADCx(x=0,1,2) clock source selection */ +#define CFG3_ADC0SEL(regval) (BITS(26,27) & ((uint32_t)(regval) << 26U)) +#define RCU_ADCSRC_PLL1P CFG3_ADC0SEL(0) /*!< CK_ADC select CK_PLL1P */ +#define RCU_ADCSRC_PLL2R CFG3_ADC0SEL(1) /*!< CK_ADC select CK_PLL2R */ +#define RCU_ADCSRC_PER CFG3_ADC0SEL(2) /*!< CK_ADC select CK_PER */ + +/* SAIx(x=0,1) clock source selection */ +#define CFG2_SAI0SEL(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) +#define RCU_SAISRC_PLL0Q CFG2_SAI0SEL(0) /*!< CK_SAI0/1 select CK_PLL0Q */ +#define RCU_SAISRC_PLL1P CFG2_SAI0SEL(1) /*!< CK_SAI0/1 select CK_PLL1P */ +#define RCU_SAISRC_PLL2P CFG2_SAI0SEL(2) /*!< CK_SAI0/1 select CK_PLL2P */ +#define RCU_SAISRC_I2S_CKIN CFG2_SAI0SEL(3) /*!< CK_SAI0/1 select I2S_CKIN */ +#define RCU_SAISRC_PER CFG2_SAI0SEL(4) /*!< CK_SAI0/1 select CK_PER */ + +/* SAI2Bx(x=0,1) clock source selection */ +#define CFG2_SAI2B0SEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24U)) +#define RCU_SAI2BSRC_PLL0Q CFG2_SAI2B0SEL(0) /*!< SAI2 block0/1 select CK_PLL0Q */ +#define RCU_SAI2BSRC_PLL1P CFG2_SAI2B0SEL(1) /*!< SAI2 block0/1 select CK_PLL1P */ +#define RCU_SAI2BSRC_PLL2P CFG2_SAI2B0SEL(2) /*!< SAI2 block0/1 select CK_PLL2P */ +#define RCU_SAI2BSRC_I2S_CKIN CFG2_SAI2B0SEL(3) /*!< SAI2 block0/1 select I2S_CKIN */ +#define RCU_SAI2BSRC_PER CFG2_SAI2B0SEL(4) /*!< SAI2 block0/1 select CK_PER */ +#define RCU_SAI2BSRC_RSPDIF_SYMB CFG2_SAI2B0SEL(5) /*!< SAI2 block0/1 select CK_RSPDIF_SYMB */ + +/* HPDF clock source selection */ +#define RCU_HPDFSRC_APB2 (uint32_t)(0X00000000U) /*!< CK_HPDF select CK_APB2 */ +#define RCU_HPDFSRC_AHB RCU_CFG1_HPDFSEL /*!< CK_HPDF select CK_AHB */ + +/* PER clock selection */ +#define CFG1_PERSEL(regval) (BITS(14,15) & ((uint32_t)(regval) << 14U)) +#define RCU_PERSRC_IRC64MDIV CFG1_PERSEL(0) /*!< CK_PER select CK_IRC64MDIV */ +#define RCU_PERSRC_LPIRC4M CFG1_PERSEL(1) /*!< CK_PER select CK_LPIRC4M */ +#define RCU_PERSRC_HXTAL CFG1_PERSEL(2) /*!< CK_PER select CK_HXTAL */ + +/* system clock source select */ +#define CFG0_SCS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define RCU_CKSYSSRC_IRC64MDIV CFG0_SCS(0) /*!< system clock source select IRC64MDIV */ +#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */ +#define RCU_CKSYSSRC_LPIRC4M CFG0_SCS(2) /*!< system clock source select LPIRC4M */ +#define RCU_CKSYSSRC_PLL0P CFG0_SCS(3) /*!< system clock source select PLL0P */ + +/* system clock source select status */ +#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) +#define RCU_SCSS_IRC64MDIV CFG0_SCSS(0) /*!< system clock source select CK_IRC64MDIV */ +#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select CK_HXTAL */ +#define RCU_SCSS_LPIRC4M CFG0_SCSS(2) /*!< system clock source select CK_LPIRC4M */ +#define RCU_SCSS_PLL0P CFG0_SCSS(3) /*!< system clock source select CK_PLL0P */ + +/* IRC64M clock divider */ +#define ADDCTL1_IRC64MDIV(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define RCU_IRC64M_DIV1 ADDCTL1_IRC64MDIV(0) /*!< CK_IRC64MDIV is CK_IRC64M / 1 */ +#define RCU_IRC64M_DIV2 ADDCTL1_IRC64MDIV(1) /*!< CK_IRC64MDIV is CK_IRC64M / 2 */ +#define RCU_IRC64M_DIV4 ADDCTL1_IRC64MDIV(2) /*!< CK_IRC64MDIV is CK_IRC64M / 4 */ +#define RCU_IRC64M_DIV8 ADDCTL1_IRC64MDIV(3) /*!< CK_IRC64MDIV is CK_IRC64M / 8 */ + +/* AHB prescaler selection */ +#define CFG0_AHBPSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4U)) +#define RCU_AHB_CKSYS_DIV1 CFG0_AHBPSC(0) /*!< AHB prescaler select CK_SYS */ +#define RCU_AHB_CKSYS_DIV2 CFG0_AHBPSC(8) /*!< AHB prescaler select CK_SYS / 2 */ +#define RCU_AHB_CKSYS_DIV4 CFG0_AHBPSC(9) /*!< AHB prescaler select CK_SYS / 4 */ +#define RCU_AHB_CKSYS_DIV8 CFG0_AHBPSC(10) /*!< AHB prescaler select CK_SYS / 8 */ +#define RCU_AHB_CKSYS_DIV16 CFG0_AHBPSC(11) /*!< AHB prescaler select CK_SYS / 16 */ +#define RCU_AHB_CKSYS_DIV64 CFG0_AHBPSC(12) /*!< AHB prescaler select CK_SYS / 64 */ +#define RCU_AHB_CKSYS_DIV128 CFG0_AHBPSC(13) /*!< AHB prescaler select CK_SYS / 128 */ +#define RCU_AHB_CKSYS_DIV256 CFG0_AHBPSC(14) /*!< AHB prescaler select CK_SYS / 256 */ +#define RCU_AHB_CKSYS_DIV512 CFG0_AHBPSC(15) /*!< AHB prescaler select CK_SYS / 512 */ + +/* APB1 prescaler selection */ +#define CFG0_APB1PSC(regval) (BITS(10,12) & ((uint32_t)(regval) << 10U)) +#define RCU_APB1_CKAHB_DIV1 CFG0_APB1PSC(0) /*!< APB1 prescaler select CK_AHB */ +#define RCU_APB1_CKAHB_DIV2 CFG0_APB1PSC(4) /*!< APB1 prescaler select CK_AHB / 2 */ +#define RCU_APB1_CKAHB_DIV4 CFG0_APB1PSC(5) /*!< APB1 prescaler select CK_AHB / 4 */ +#define RCU_APB1_CKAHB_DIV8 CFG0_APB1PSC(6) /*!< APB1 prescaler select CK_AHB / 8 */ +#define RCU_APB1_CKAHB_DIV16 CFG0_APB1PSC(7) /*!< APB1 prescaler select CK_AHB / 16 */ + +/* APB2 prescaler selection */ +#define CFG0_APB2PSC(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) +#define RCU_APB2_CKAHB_DIV1 CFG0_APB2PSC(0) /*!< APB2 prescaler select CK_AHB */ +#define RCU_APB2_CKAHB_DIV2 CFG0_APB2PSC(4) /*!< APB2 prescaler select CK_AHB / 2 */ +#define RCU_APB2_CKAHB_DIV4 CFG0_APB2PSC(5) /*!< APB2 prescaler select CK_AHB / 4 */ +#define RCU_APB2_CKAHB_DIV8 CFG0_APB2PSC(6) /*!< APB2 prescaler select CK_AHB / 8 */ +#define RCU_APB2_CKAHB_DIV16 CFG0_APB2PSC(7) /*!< APB2 prescaler select CK_AHB / 16 */ + +/* APB3 prescaler selection */ +#define CFG0_APB3PSC(regval) (BITS(27,29) & ((uint32_t)(regval) << 27U)) +#define RCU_APB3_CKAHB_DIV1 CFG0_APB3PSC(0) /*!< APB3 prescaler select CK_AHB */ +#define RCU_APB3_CKAHB_DIV2 CFG0_APB3PSC(4) /*!< APB3 prescaler select CK_AHB / 2 */ +#define RCU_APB3_CKAHB_DIV4 CFG0_APB3PSC(5) /*!< APB3 prescaler select CK_AHB / 4 */ +#define RCU_APB3_CKAHB_DIV8 CFG0_APB3PSC(6) /*!< APB3 prescaler select CK_AHB / 8 */ +#define RCU_APB3_CKAHB_DIV16 CFG0_APB3PSC(7) /*!< APB3 prescaler select CK_AHB / 16 */ + +/* APB4 prescaler selection */ +#define CFG0_APB4PSC(regval) (BITS(24,26) & ((uint32_t)(regval) << 24U)) +#define RCU_APB4_CKAHB_DIV1 CFG0_APB4PSC(0) /*!< APB4 prescaler select CK_AHB */ +#define RCU_APB4_CKAHB_DIV2 CFG0_APB4PSC(4) /*!< APB4 prescaler select CK_AHB / 2 */ +#define RCU_APB4_CKAHB_DIV4 CFG0_APB4PSC(5) /*!< APB4 prescaler select CK_AHB / 4 */ +#define RCU_APB4_CKAHB_DIV8 CFG0_APB4PSC(6) /*!< APB4 prescaler select CK_AHB / 8 */ +#define RCU_APB4_CKAHB_DIV16 CFG0_APB4PSC(7) /*!< APB4 prescaler select CK_AHB / 16 */ + +/* RTC clock divider factor from HXTAL clock */ +#define CFG0_RTCDIV(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U)) +#define RCU_RTC_HXTAL_NONE CFG0_RTCDIV(0) /*!< no clock for RTC */ +#define RCU_RTC_HXTAL_DIV2 CFG0_RTCDIV(2) /*!< RTCDIV clock select CK_HXTAL / 2 */ +#define RCU_RTC_HXTAL_DIV3 CFG0_RTCDIV(3) /*!< RTCDIV clock select CK_HXTAL / 3 */ +#define RCU_RTC_HXTAL_DIV4 CFG0_RTCDIV(4) /*!< RTCDIV clock select CK_HXTAL / 4 */ +#define RCU_RTC_HXTAL_DIV5 CFG0_RTCDIV(5) /*!< RTCDIV clock select CK_HXTAL / 5 */ +#define RCU_RTC_HXTAL_DIV6 CFG0_RTCDIV(6) /*!< RTCDIV clock select CK_HXTAL / 6 */ +#define RCU_RTC_HXTAL_DIV7 CFG0_RTCDIV(7) /*!< RTCDIV clock select CK_HXTAL / 7 */ +#define RCU_RTC_HXTAL_DIV8 CFG0_RTCDIV(8) /*!< RTCDIV clock select CK_HXTAL / 8 */ +#define RCU_RTC_HXTAL_DIV9 CFG0_RTCDIV(9) /*!< RTCDIV clock select CK_HXTAL / 9 */ +#define RCU_RTC_HXTAL_DIV10 CFG0_RTCDIV(10) /*!< RTCDIV clock select CK_HXTAL / 10 */ +#define RCU_RTC_HXTAL_DIV11 CFG0_RTCDIV(11) /*!< RTCDIV clock select CK_HXTAL / 11 */ +#define RCU_RTC_HXTAL_DIV12 CFG0_RTCDIV(12) /*!< RTCDIV clock select CK_HXTAL / 12 */ +#define RCU_RTC_HXTAL_DIV13 CFG0_RTCDIV(13) /*!< RTCDIV clock select CK_HXTAL / 13 */ +#define RCU_RTC_HXTAL_DIV14 CFG0_RTCDIV(14) /*!< RTCDIV clock select CK_HXTAL / 14 */ +#define RCU_RTC_HXTAL_DIV15 CFG0_RTCDIV(15) /*!< RTCDIV clock select CK_HXTAL / 15 */ +#define RCU_RTC_HXTAL_DIV16 CFG0_RTCDIV(16) /*!< RTCDIV clock select CK_HXTAL / 16 */ +#define RCU_RTC_HXTAL_DIV17 CFG0_RTCDIV(17) /*!< RTCDIV clock select CK_HXTAL / 17 */ +#define RCU_RTC_HXTAL_DIV18 CFG0_RTCDIV(18) /*!< RTCDIV clock select CK_HXTAL / 18 */ +#define RCU_RTC_HXTAL_DIV19 CFG0_RTCDIV(19) /*!< RTCDIV clock select CK_HXTAL / 19 */ +#define RCU_RTC_HXTAL_DIV20 CFG0_RTCDIV(20) /*!< RTCDIV clock select CK_HXTAL / 20 */ +#define RCU_RTC_HXTAL_DIV21 CFG0_RTCDIV(21) /*!< RTCDIV clock select CK_HXTAL / 21 */ +#define RCU_RTC_HXTAL_DIV22 CFG0_RTCDIV(22) /*!< RTCDIV clock select CK_HXTAL / 22 */ +#define RCU_RTC_HXTAL_DIV23 CFG0_RTCDIV(23) /*!< RTCDIV clock select CK_HXTAL / 23 */ +#define RCU_RTC_HXTAL_DIV24 CFG0_RTCDIV(24) /*!< RTCDIV clock select CK_HXTAL / 24 */ +#define RCU_RTC_HXTAL_DIV25 CFG0_RTCDIV(25) /*!< RTCDIV clock select CK_HXTAL / 25 */ +#define RCU_RTC_HXTAL_DIV26 CFG0_RTCDIV(26) /*!< RTCDIV clock select CK_HXTAL / 26 */ +#define RCU_RTC_HXTAL_DIV27 CFG0_RTCDIV(27) /*!< RTCDIV clock select CK_HXTAL / 27 */ +#define RCU_RTC_HXTAL_DIV28 CFG0_RTCDIV(28) /*!< RTCDIV clock select CK_HXTAL / 28 */ +#define RCU_RTC_HXTAL_DIV29 CFG0_RTCDIV(29) /*!< RTCDIV clock select CK_HXTAL / 29 */ +#define RCU_RTC_HXTAL_DIV30 CFG0_RTCDIV(30) /*!< RTCDIV clock select CK_HXTAL / 30 */ +#define RCU_RTC_HXTAL_DIV31 CFG0_RTCDIV(31) /*!< RTCDIV clock select CK_HXTAL / 31 */ +#define RCU_RTC_HXTAL_DIV32 CFG0_RTCDIV(32) /*!< RTCDIV clock select CK_HXTAL / 32 */ +#define RCU_RTC_HXTAL_DIV33 CFG0_RTCDIV(33) /*!< RTCDIV clock select CK_HXTAL / 33 */ +#define RCU_RTC_HXTAL_DIV34 CFG0_RTCDIV(34) /*!< RTCDIV clock select CK_HXTAL / 34 */ +#define RCU_RTC_HXTAL_DIV35 CFG0_RTCDIV(35) /*!< RTCDIV clock select CK_HXTAL / 35 */ +#define RCU_RTC_HXTAL_DIV36 CFG0_RTCDIV(36) /*!< RTCDIV clock select CK_HXTAL / 36 */ +#define RCU_RTC_HXTAL_DIV37 CFG0_RTCDIV(37) /*!< RTCDIV clock select CK_HXTAL / 37 */ +#define RCU_RTC_HXTAL_DIV38 CFG0_RTCDIV(38) /*!< RTCDIV clock select CK_HXTAL / 38 */ +#define RCU_RTC_HXTAL_DIV39 CFG0_RTCDIV(39) /*!< RTCDIV clock select CK_HXTAL / 39 */ +#define RCU_RTC_HXTAL_DIV40 CFG0_RTCDIV(40) /*!< RTCDIV clock select CK_HXTAL / 40 */ +#define RCU_RTC_HXTAL_DIV41 CFG0_RTCDIV(41) /*!< RTCDIV clock select CK_HXTAL / 41 */ +#define RCU_RTC_HXTAL_DIV42 CFG0_RTCDIV(42) /*!< RTCDIV clock select CK_HXTAL / 42 */ +#define RCU_RTC_HXTAL_DIV43 CFG0_RTCDIV(43) /*!< RTCDIV clock select CK_HXTAL / 43 */ +#define RCU_RTC_HXTAL_DIV44 CFG0_RTCDIV(44) /*!< RTCDIV clock select CK_HXTAL / 44 */ +#define RCU_RTC_HXTAL_DIV45 CFG0_RTCDIV(45) /*!< RTCDIV clock select CK_HXTAL / 45 */ +#define RCU_RTC_HXTAL_DIV46 CFG0_RTCDIV(46) /*!< RTCDIV clock select CK_HXTAL / 46 */ +#define RCU_RTC_HXTAL_DIV47 CFG0_RTCDIV(47) /*!< RTCDIV clock select CK_HXTAL / 47 */ +#define RCU_RTC_HXTAL_DIV48 CFG0_RTCDIV(48) /*!< RTCDIV clock select CK_HXTAL / 48 */ +#define RCU_RTC_HXTAL_DIV49 CFG0_RTCDIV(49) /*!< RTCDIV clock select CK_HXTAL / 49 */ +#define RCU_RTC_HXTAL_DIV50 CFG0_RTCDIV(50) /*!< RTCDIV clock select CK_HXTAL / 50 */ +#define RCU_RTC_HXTAL_DIV51 CFG0_RTCDIV(51) /*!< RTCDIV clock select CK_HXTAL / 51 */ +#define RCU_RTC_HXTAL_DIV52 CFG0_RTCDIV(52) /*!< RTCDIV clock select CK_HXTAL / 52 */ +#define RCU_RTC_HXTAL_DIV53 CFG0_RTCDIV(53) /*!< RTCDIV clock select CK_HXTAL / 53 */ +#define RCU_RTC_HXTAL_DIV54 CFG0_RTCDIV(54) /*!< RTCDIV clock select CK_HXTAL / 54 */ +#define RCU_RTC_HXTAL_DIV55 CFG0_RTCDIV(55) /*!< RTCDIV clock select CK_HXTAL / 55 */ +#define RCU_RTC_HXTAL_DIV56 CFG0_RTCDIV(56) /*!< RTCDIV clock select CK_HXTAL / 56 */ +#define RCU_RTC_HXTAL_DIV57 CFG0_RTCDIV(57) /*!< RTCDIV clock select CK_HXTAL / 57 */ +#define RCU_RTC_HXTAL_DIV58 CFG0_RTCDIV(58) /*!< RTCDIV clock select CK_HXTAL / 58 */ +#define RCU_RTC_HXTAL_DIV59 CFG0_RTCDIV(59) /*!< RTCDIV clock select CK_HXTAL / 59 */ +#define RCU_RTC_HXTAL_DIV60 CFG0_RTCDIV(60) /*!< RTCDIV clock select CK_HXTAL / 60 */ +#define RCU_RTC_HXTAL_DIV61 CFG0_RTCDIV(61) /*!< RTCDIV clock select CK_HXTAL / 61 */ +#define RCU_RTC_HXTAL_DIV62 CFG0_RTCDIV(62) /*!< RTCDIV clock select CK_HXTAL / 62 */ +#define RCU_RTC_HXTAL_DIV63 CFG0_RTCDIV(63) /*!< RTCDIV clock select CK_HXTAL / 63 */ + +/* The CK_OUT0 divider */ +#define CFG2_CKOUT0DIV(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) +#define RCU_CKOUT0_DIV1 CFG2_CKOUT0DIV(1) /*!< CK_OUT0 is divided by 1 */ +#define RCU_CKOUT0_DIV2 CFG2_CKOUT0DIV(2) /*!< CK_OUT0 is divided by 2 */ +#define RCU_CKOUT0_DIV3 CFG2_CKOUT0DIV(3) /*!< CK_OUT0 is divided by 3 */ +#define RCU_CKOUT0_DIV4 CFG2_CKOUT0DIV(4) /*!< CK_OUT0 is divided by 4 */ +#define RCU_CKOUT0_DIV5 CFG2_CKOUT0DIV(5) /*!< CK_OUT0 is divided by 5 */ +#define RCU_CKOUT0_DIV6 CFG2_CKOUT0DIV(6) /*!< CK_OUT0 is divided by 6 */ +#define RCU_CKOUT0_DIV7 CFG2_CKOUT0DIV(7) /*!< CK_OUT0 is divided by 7 */ +#define RCU_CKOUT0_DIV8 CFG2_CKOUT0DIV(8) /*!< CK_OUT0 is divided by 8 */ +#define RCU_CKOUT0_DIV9 CFG2_CKOUT0DIV(9) /*!< CK_OUT0 is divided by 9 */ +#define RCU_CKOUT0_DIV10 CFG2_CKOUT0DIV(10) /*!< CK_OUT0 is divided by 10 */ +#define RCU_CKOUT0_DIV11 CFG2_CKOUT0DIV(11) /*!< CK_OUT0 is divided by 11 */ +#define RCU_CKOUT0_DIV12 CFG2_CKOUT0DIV(12) /*!< CK_OUT0 is divided by 12 */ +#define RCU_CKOUT0_DIV13 CFG2_CKOUT0DIV(13) /*!< CK_OUT0 is divided by 13 */ +#define RCU_CKOUT0_DIV14 CFG2_CKOUT0DIV(14) /*!< CK_OUT0 is divided by 14 */ +#define RCU_CKOUT0_DIV15 CFG2_CKOUT0DIV(15) /*!< CK_OUT0 is divided by 15 */ + +/* CKOUT0 Clock source selection */ +#define CFG2_CKOUT0SEL(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) +#define RCU_CKOUT0SRC_IRC64MDIV CFG2_CKOUT0SEL(0) /*!< internal 64MDIV RC oscillator clock selected */ +#define RCU_CKOUT0SRC_LXTAL CFG2_CKOUT0SEL(1) /*!< low speed crystal oscillator clock (LXTAL) selected */ +#define RCU_CKOUT0SRC_HXTAL CFG2_CKOUT0SEL(2) /*!< high speed crystal oscillator clock (HXTAL) selected */ +#define RCU_CKOUT0SRC_PLL0P CFG2_CKOUT0SEL(3) /*!< CK_PLL0P clock selected */ +#define RCU_CKOUT0SRC_IRC48M CFG2_CKOUT0SEL(4) /*!< CK_IRC48M clock selected */ +#define RCU_CKOUT0SRC_PER CFG2_CKOUT0SEL(5) /*!< CK_PER clock selected */ +#define RCU_CKOUT0SRC_USBHS060M CFG2_CKOUT0SEL(6) /*!< USBHS0 60M clock selected */ +#define RCU_CKOUT0SRC_USBHS160M CFG2_CKOUT0SEL(7) /*!< USBHS1 60M clock selected */ + +/* The CK_OUT1 divider */ +#define CFG2_CKOUT1DIV(regval) (BITS(8,11) & ((uint32_t)(regval) << 8U)) +#define RCU_CKOUT1_DIV1 CFG2_CKOUT1DIV(1) /*!< CK_OUT1 is divided by 1 */ +#define RCU_CKOUT1_DIV2 CFG2_CKOUT1DIV(2) /*!< CK_OUT1 is divided by 2 */ +#define RCU_CKOUT1_DIV3 CFG2_CKOUT1DIV(3) /*!< CK_OUT1 is divided by 3 */ +#define RCU_CKOUT1_DIV4 CFG2_CKOUT1DIV(4) /*!< CK_OUT1 is divided by 4 */ +#define RCU_CKOUT1_DIV5 CFG2_CKOUT1DIV(5) /*!< CK_OUT1 is divided by 5 */ +#define RCU_CKOUT1_DIV6 CFG2_CKOUT1DIV(6) /*!< CK_OUT1 is divided by 6 */ +#define RCU_CKOUT1_DIV7 CFG2_CKOUT1DIV(7) /*!< CK_OUT1 is divided by 7 */ +#define RCU_CKOUT1_DIV8 CFG2_CKOUT1DIV(8) /*!< CK_OUT1 is divided by 8 */ +#define RCU_CKOUT1_DIV9 CFG2_CKOUT1DIV(9) /*!< CK_OUT1 is divided by 9 */ +#define RCU_CKOUT1_DIV10 CFG2_CKOUT1DIV(10) /*!< CK_OUT1 is divided by 10 */ +#define RCU_CKOUT1_DIV11 CFG2_CKOUT1DIV(11) /*!< CK_OUT1 is divided by 11 */ +#define RCU_CKOUT1_DIV12 CFG2_CKOUT1DIV(12) /*!< CK_OUT1 is divided by 12 */ +#define RCU_CKOUT1_DIV13 CFG2_CKOUT1DIV(13) /*!< CK_OUT1 is divided by 13 */ +#define RCU_CKOUT1_DIV14 CFG2_CKOUT1DIV(14) /*!< CK_OUT1 is divided by 14 */ +#define RCU_CKOUT1_DIV15 CFG2_CKOUT1DIV(15) /*!< CK_OUT1 is divided by 15 */ + +/* CKOUT1 Clock source selection */ +#define CFG2_CKOUT1SEL(regval) (BITS(12,14) & ((uint32_t)(regval) << 12U)) +#define RCU_CKOUT1SRC_SYSTEMCLOCK CFG2_CKOUT1SEL(0) /*!< system clock selected */ +#define RCU_CKOUT1SRC_PLL1R CFG2_CKOUT1SEL(1) /*!< CK_PLL1R clock selected */ +#define RCU_CKOUT1SRC_HXTAL CFG2_CKOUT1SEL(2) /*!< high speed crystal oscillator clock (HXTAL) selected */ +#define RCU_CKOUT1SRC_PLL0P CFG2_CKOUT1SEL(3) /*!< CK_PLL0P clock selected */ +#define RCU_CKOUT1SRC_LPIRC4M CFG2_CKOUT1SEL(4) /*!< CK_LPIRC4M clock selected */ +#define RCU_CKOUT1SRC_IRC32K CFG2_CKOUT1SEL(5) /*!< CK_IRC32K clock selected */ +#define RCU_CKOUT1SRC_PLL2R CFG2_CKOUT1SEL(6) /*!< CK_PLL2R clock selected */ + +/* the divider factor from PLL2R clock */ +#define CFG1_PLL2RDIV(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define RCU_PLL2R_DIV2 CFG1_PLL2RDIV(0) /*!< CK_PLL2RDIV clock select CK_PLL2R / 2 */ +#define RCU_PLL2R_DIV4 CFG1_PLL2RDIV(1) /*!< CK_PLL2RDIV clock select CK_PLL2R / 4 */ +#define RCU_PLL2R_DIV8 CFG1_PLL2RDIV(2) /*!< CK_PLL2RDIV clock select CK_PLL2R / 8 */ +#define RCU_PLL2R_DIV16 CFG1_PLL2RDIV(3) /*!< CK_PLL2RDIV clock select CK_PLL2R / 16 */ + +/* TIMER clock selection */ +#define RCU_TIMER_PSC_MUL2 ((uint32_t)(~RCU_CFG1_TIMERSEL)) /*!< if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB) + or 0b100(CK_APBx = CK_AHB/2), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). + or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 2 x CK_APB2) */ +#define RCU_TIMER_PSC_MUL4 RCU_CFG1_TIMERSEL /*!< if APB1PSC/APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), + 0b100(CK_APBx = CK_AHB/2), or 0b101(CK_APBx = CK_AHB/4), the TIMER clock is equal to CK_AHB(CK_TIMERx = CK_AHB). + or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 4 x CK_APB2) */ + +/* RCU_PLL0 register bit define */ +/* The PLL0 VCO source clock prescaler */ +#define RCU_PLL0PSC_DIV_MIN ((uint32_t)1U) /*!< PLL0PSC_DIV min value */ +#define RCU_PLL0PSC_DIV_MAX ((uint32_t)63U) /*!< PLL0PSC_DIV max value */ + +/* The PLL0 VCO clock multiplication factor */ +#define RCU_PLL0N_MUL_MIN ((uint32_t)9U) /*!< PLL0N_MUL min value */ +#define RCU_PLL0N_MUL_MAX ((uint32_t)512U) /*!< PLL0N_MUL max value */ + +/* The PLL0P output frequency division factor from PLL0 VCO clock */ +#define RCU_PLL0P_DIV_MIN ((uint32_t)1U) /*!< PLL0P_DIV min value */ +#define RCU_PLL0P_DIV_MAX ((uint32_t)128U) /*!< PLL0P_DIV max value */ + +/* The PLL0R output frequency division factor from PLL0 VCO clock */ +#define RCU_PLL0R_DIV_MIN ((uint32_t)1U) /*!< PLL0R_DIV min value */ +#define RCU_PLL0R_DIV_MAX ((uint32_t)128U) /*!< PLL0R_DIV max value */ + +/* The PLL0Q output frequency division factor from PLL0 VCO clock */ +#define RCU_PLL0Q_DIV_MIN ((uint32_t)1U) /*!< PLL0Q_DIV min value */ +#define RCU_PLL0Q_DIV_MAX ((uint32_t)128U) /*!< PLL0Q_DIV max value */ + +/* PLL Clock Source Selection */ +#define PLLALL_PLLSEL(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define RCU_PLLSRC_IRC64MDIV PLLALL_PLLSEL(0) /*!< IRC64MDIV clock selected as source clock of PLL0, PLL1, PLL2 */ +#define RCU_PLLSRC_LPIRC4M PLLALL_PLLSEL(1) /*!< LPIRC4M clock selected as source clock of PLL0, PLL1, PLL2 */ +#define RCU_PLLSRC_HXTAL PLLALL_PLLSEL(2) /*!< HXTAL clock selected as source clock of PLL0, PLL1, PLL2 */ + +#define CHECK_PLL0_PSC_VALID(val) (((val) >= RCU_PLL0PSC_DIV_MIN) && ((val) <= RCU_PLL0PSC_DIV_MAX)) +#define CHECK_PLL0_N_VALID(val) (((val) >= RCU_PLL0N_MUL_MIN) && ((val) <= RCU_PLL0N_MUL_MAX)) +#define CHECK_PLL0_P_VALID(val) (((val) >= RCU_PLL0P_DIV_MIN) && ((val) <= RCU_PLL0P_DIV_MAX)) +#define CHECK_PLL0_Q_VALID(val) (((val) >= RCU_PLL0Q_DIV_MIN) && ((val) <= RCU_PLL0Q_DIV_MAX)) +#define CHECK_PLL0_R_VALID(val) (((val) >= RCU_PLL0R_DIV_MIN) && ((val) <= RCU_PLL0R_DIV_MAX)) + +/* RCU_BDCTL register bit define */ +/* LXTAL drive capability */ +#define BDCTL_LXTALDRI(regval) (BITS(3,4) & ((uint32_t)(regval) << 3U)) +#define RCU_LXTAL_LOWDRI BDCTL_LXTALDRI(0) /*!< lower driving capability */ +#define RCU_LXTAL_MED_LOWDRI BDCTL_LXTALDRI(1) /*!< medium low driving capability */ +#define RCU_LXTAL_MED_HIGHDRI BDCTL_LXTALDRI(2) /*!< medium high driving capability */ +#define RCU_LXTAL_HIGHDRI BDCTL_LXTALDRI(3) /*!< higher driving capability */ + +/* RTC clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define RCU_RTCSRC_NONE BDCTL_RTCSRC(0) /*!< no clock selected */ +#define RCU_RTCSRC_LXTAL BDCTL_RTCSRC(1) /*!< RTC source clock select LXTAL */ +#define RCU_RTCSRC_IRC32K BDCTL_RTCSRC(2) /*!< RTC source clock select IRC32K */ +#define RCU_RTCSRC_HXTAL_DIV_RTCDIV BDCTL_RTCSRC(3) /*!< RTC source clock select HXTAL/RTCDIV */ + +/* RCU_PLL1 register bit define */ +/* The PLL1 VCO source clock prescaler */ +#define RCU_PLL1PSC_DIV_MIN ((uint32_t)1U) /*!< PLL1PSC_DIV min value */ +#define RCU_PLL1PSC_DIV_MAX ((uint32_t)63U) /*!< PLL1PSC_DIV max value */ + +/* The PLL1 VCO clock multiplication factor */ +#define RCU_PLL1N_MUL_MIN ((uint32_t)9U) /*!< PLL1N_MUL min value */ +#define RCU_PLL1N_MUL_MAX ((uint32_t)512U) /*!< PLL1N_MUL max value */ + +/* The PLL1P output frequency division factor from PLL1 VCO clock */ +#define RCU_PLL1P_DIV_MIN ((uint32_t)1U) /*!< PLL1P_DIV min value */ +#define RCU_PLL1P_DIV_MAX ((uint32_t)128U) /*!< PLL1P_DIV max value */ + +/* The PLL1Q output frequency division factor from PLL1 VCO clock */ +#define RCU_PLL1Q_DIV_MIN ((uint32_t)1U) /*!< PLL1Q_DIV min value */ +#define RCU_PLL1Q_DIV_MAX ((uint32_t)128U) /*!< PLL1Q_DIV max value */ + +/* The PLL1R output frequency division factor from PLL1 VCO clock */ +#define RCU_PLL1R_DIV_MIN ((uint32_t)1U) /*!< PLL1R_DIV min value */ +#define RCU_PLL1R_DIV_MAX ((uint32_t)128U) /*!< PLL1R_DIV max value */ + +/* RCU_PLL2 register bit define */ +/* The PLL2 VCO source clock prescaler */ +#define RCU_PLL2PSC_DIV_MIN ((uint32_t)1U) /*!< PLL2PSC_DIV min value */ +#define RCU_PLL2PSC_DIV_MAX ((uint32_t)63U) /*!< PLL2PSC_DIV max value */ + +/* The PLL2 VCO clock multi factor */ +#define RCU_PLL2N_MUL_MIN ((uint32_t)9U) /*!< PLL2N_MUL min value */ +#define RCU_PLL2N_MUL_MAX ((uint32_t)512U) /*!< PLL2N_MUL max value */ + +/* The PLL2P output frequency division factor from PLL2 VCO clock */ +#define RCU_PLL2P_DIV_MIN ((uint32_t)1U) /*!< PLL2P_DIV min value */ +#define RCU_PLL2P_DIV_MAX ((uint32_t)128U) /*!< PLL2P_DIV max value */ + +/* The PLL2Q output frequency division factor from PLL2 VCO clock */ +#define RCU_PLL2Q_DIV_MIN ((uint32_t)1U) /*!< PLL2Q_DIV min value */ +#define RCU_PLL2Q_DIV_MAX ((uint32_t)128U) /*!< PLL2Q_DIV max value */ + +/* The PLL2R output frequency division factor from PLL2 VCO clock */ +#define RCU_PLL2R_DIV_MIN ((uint32_t)1U) /*!< PLL2R_DIV min value */ +#define RCU_PLL2R_DIV_MAX ((uint32_t)128U) /*!< PLL2R_DIV max value */ + +#define CHECK_PLL1_PSC_VALID(val) (((val) >= RCU_PLL1PSC_DIV_MIN) && ((val) <= RCU_PLL1PSC_DIV_MAX)) +#define CHECK_PLL1_N_VALID(val) (((val) >= RCU_PLL1N_MUL_MIN) && ((val) <= RCU_PLL1N_MUL_MAX)) +#define CHECK_PLL1_P_VALID(val) (((val) >= RCU_PLL1P_DIV_MIN) && ((val) <= RCU_PLL1P_DIV_MAX)) +#define CHECK_PLL1_Q_VALID(val) (((val) >= RCU_PLL1Q_DIV_MIN) && ((val) <= RCU_PLL1Q_DIV_MAX)) +#define CHECK_PLL1_R_VALID(val) (((val) >= RCU_PLL1R_DIV_MIN) && ((val) <= RCU_PLL1R_DIV_MAX)) + +#define CHECK_PLL2_PSC_VALID(val) (((val) >= RCU_PLL2PSC_DIV_MIN) && ((val) <= RCU_PLL2PSC_DIV_MAX)) +#define CHECK_PLL2_N_VALID(val) (((val) >= (RCU_PLL2N_MUL_MIN)) && ((val) <= RCU_PLL2N_MUL_MAX)) +#define CHECK_PLL2_P_VALID(val) (((val) >= RCU_PLL2P_DIV_MIN) && ((val) <= RCU_PLL2P_DIV_MAX)) +#define CHECK_PLL2_Q_VALID(val) (((val) >= RCU_PLL2Q_DIV_MIN) && ((val) <= RCU_PLL2Q_DIV_MAX)) +#define CHECK_PLL2_R_VALID(val) (((val) >= RCU_PLL2R_DIV_MIN) && ((val) <= RCU_PLL2R_DIV_MAX)) + +/* PLL0 input clock range */ +#define PLLALL_PLL0RNG(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define RCU_PLL0RNG_1M_2M PLLALL_PLL0RNG(0) /*!< PLL0 input clock frequency: 1-2MHz */ +#define RCU_PLL0RNG_2M_4M PLLALL_PLL0RNG(1) /*!< PLL0 input clock frequency: 2-4MHz */ +#define RCU_PLL0RNG_4M_8M PLLALL_PLL0RNG(2) /*!< PLL0 input clock frequency: 4-8MHz */ +#define RCU_PLL0RNG_8M_16M PLLALL_PLL0RNG(3) /*!< PLL0 input clock frequency: 8-16MHz */ + +/* PLL1 input clock range */ +#define PLLALL_PLL1RNG(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define RCU_PLL1RNG_1M_2M PLLALL_PLL1RNG(0) /*!< PLL1 input clock frequency: 1-2MHz */ +#define RCU_PLL1RNG_2M_4M PLLALL_PLL1RNG(1) /*!< PLL1 input clock frequency: 2-4MHz */ +#define RCU_PLL1RNG_4M_8M PLLALL_PLL1RNG(2) /*!< PLL1 input clock frequency: 4-8MHz */ +#define RCU_PLL1RNG_8M_16M PLLALL_PLL1RNG(3) /*!< PLL1 input clock frequency: 8-16MHz */ + +/* PLL2 input clock range */ +#define PLLALL_PLL2RNG(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define RCU_PLL2RNG_1M_2M PLLALL_PLL2RNG(0) /*!< PLL2 input clock frequency: 1-2MHz */ +#define RCU_PLL2RNG_2M_4M PLLALL_PLL2RNG(1) /*!< PLL2 input clock frequency: 2-4MHz */ +#define RCU_PLL2RNG_4M_8M PLLALL_PLL2RNG(2) /*!< PLL2 input clock frequency: 4-8MHz */ +#define RCU_PLL2RNG_8M_16M PLLALL_PLL2RNG(3) /*!< PLL2 input clock frequency: 8-16MHz */ + +/* PLL0 VCO selection */ +#define RCU_PLL0VCO_192M_836M ((uint32_t)0x00000000U) /*!< PLL0 select wide VCO, range: 192-836MHz */ +#define RCU_PLL0VCO_150M_420M RCU_PLLALL_PLL0VCOSEL /*!< PLL0 select narrow VCO, range: 150-420MHz */ + +/* PLL1 VCO selection */ +#define RCU_PLL1VCO_192M_836M ((uint32_t)0x00000000U) /*!< PLL1 select wide VCO, range: 192-836MHz */ +#define RCU_PLL1VCO_150M_420M RCU_PLLALL_PLL1VCOSEL /*!< PLL1 select narrow VCO, range: 150-420MHz */ + +/* PLL2 VCO selection */ +#define RCU_PLL2VCO_192M_836M ((uint32_t)0x00000000U) /*!< PLL2 select wide VCO, range: 192-836MHz */ +#define RCU_PLL2VCO_150M_420M RCU_PLLALL_PLL2VCOSEL /*!< PLL2 select narrow VCO, range: 150-420MHz */ + +/* RCU_ADDCTL0 register bit define */ +/* 48MHz clock selection */ +#define RCU_CK48MSRC_PLL48M ((uint32_t)0x00000000U) /*!< CK48M source clock select PLL48M */ +#define RCU_CK48MSRC_IRC48M RCU_ADDCTL0_CK48MSEL /*!< CK48M source clock select IRC48M */ + +/* PLL48M clock selection */ +#define RCU_PLL48MSRC_PLL0Q ((uint32_t)0x00000000U) /*!< PLL48M source clock select PLL0Q */ +#define RCU_PLL48MSRC_PLL2P RCU_ADDCTL0_PLL48MSEL /*!< PLL48M source clock select PLL2P */ + +/* USBHS clock selection */ +#define RCU_USBHSSEL_48M ((uint32_t)0x00000000U) /*!< 48M selected as USBHS source clock */ +#define RCU_USBHSSEL_60M RCU_USBCLKCTL_USBHS0SEL /*!< 60M selected as USBHS source clock */ + +/* PLLUSBHSPRE clock selection */ +#define RCU_PLLUSBHSPRE_HXTAL ((uint32_t)0x00000000U) /*!< CK_HATAL selected as PLLUSBHS source clock */ +#define RCU_PLLUSBHSPRE_IRC48M RCU_USBCLKCTL_PLLUSBHS0PRESEL /*!< CK_IRC48M selected as PLLUSBHS source clock */ + +/* PLLUSBHSPREDV division factor */ +#define PLLUSBCFG_PLLUSBHSPREDV(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) +#define RCU_PLLUSBHSPRE_DIV1 PLLUSBCFG_PLLUSBHSPREDV(1) /*!< PLLUSBHSPREDV input source clock divided by 1 */ +#define RCU_PLLUSBHSPRE_DIV2 PLLUSBCFG_PLLUSBHSPREDV(2) /*!< PLLUSBHSPREDV input source clock divided by 2 */ +#define RCU_PLLUSBHSPRE_DIV3 PLLUSBCFG_PLLUSBHSPREDV(3) /*!< PLLUSBHSPREDV input source clock divided by 3 */ +#define RCU_PLLUSBHSPRE_DIV4 PLLUSBCFG_PLLUSBHSPREDV(4) /*!< PLLUSBHSPREDV input source clock divided by 4 */ +#define RCU_PLLUSBHSPRE_DIV5 PLLUSBCFG_PLLUSBHSPREDV(5) /*!< PLLUSBHSPREDV input source clock divided by 5 */ +#define RCU_PLLUSBHSPRE_DIV6 PLLUSBCFG_PLLUSBHSPREDV(6) /*!< PLLUSBHSPREDV input source clock divided by 6 */ +#define RCU_PLLUSBHSPRE_DIV7 PLLUSBCFG_PLLUSBHSPREDV(7) /*!< PLLUSBHSPREDV input source clock divided by 7 */ +#define RCU_PLLUSBHSPRE_DIV8 PLLUSBCFG_PLLUSBHSPREDV(8) /*!< PLLUSBHSPREDV input source clock divided by 8 */ +#define RCU_PLLUSBHSPRE_DIV9 PLLUSBCFG_PLLUSBHSPREDV(9) /*!< PLLUSBHSPREDV input source clock divided by 9 */ +#define RCU_PLLUSBHSPRE_DIV10 PLLUSBCFG_PLLUSBHSPREDV(10) /*!< PLLUSBHSPREDV input source clock divided by 10 */ +#define RCU_PLLUSBHSPRE_DIV11 PLLUSBCFG_PLLUSBHSPREDV(11) /*!< PLLUSBHSPREDV input source clock divided by 11 */ +#define RCU_PLLUSBHSPRE_DIV12 PLLUSBCFG_PLLUSBHSPREDV(12) /*!< PLLUSBHSPREDV input source clock divided by 12 */ +#define RCU_PLLUSBHSPRE_DIV13 PLLUSBCFG_PLLUSBHSPREDV(13) /*!< PLLUSBHSPREDV input source clock divided by 13 */ +#define RCU_PLLUSBHSPRE_DIV14 PLLUSBCFG_PLLUSBHSPREDV(14) /*!< PLLUSBHSPREDV input source clock divided by 14 */ +#define RCU_PLLUSBHSPRE_DIV15 PLLUSBCFG_PLLUSBHSPREDV(15) /*!< PLLUSBHSPREDV input source clock divided by 15 */ + +/* USBHSDV division factor */ +#define PLLUSBCFG_USBHSDV(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) +#define RCU_USBHS_DIV2 PLLUSBCFG_USBHSDV(0) /*!< USBHSDV input source clock divided by 2 */ +#define RCU_USBHS_DIV4 PLLUSBCFG_USBHSDV(1) /*!< USBHSDV input source clock divided by 4 */ +#define RCU_USBHS_DIV6 PLLUSBCFG_USBHSDV(2) /*!< USBHSDV input source clock divided by 6 */ +#define RCU_USBHS_DIV8 PLLUSBCFG_USBHSDV(3) /*!< USBHSDV input source clock divided by 8 */ +#define RCU_USBHS_DIV10 PLLUSBCFG_USBHSDV(4) /*!< USBHSDV input source clock divided by 10 */ +#define RCU_USBHS_DIV12 PLLUSBCFG_USBHSDV(5) /*!< USBHSDV input source clock divided by 12 */ +#define RCU_USBHS_DIV14 PLLUSBCFG_USBHSDV(6) /*!< USBHSDV input source clock divided by 14 */ +#define RCU_USBHS_DIV16 PLLUSBCFG_USBHSDV(7) /*!< USBHSDV input source clock divided by 16 */ + +/* PLLUSB clock multiplication factor */ +#define PLLUSBCFG_PLLUSBHSMF(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) +#define RCU_PLLUSBHS_MUL16 PLLUSBCFG_PLLUSBHSMF(16) /*!< PLLUSBHS source clock multiply by 16 */ +#define RCU_PLLUSBHS_MUL17 PLLUSBCFG_PLLUSBHSMF(17) /*!< PLLUSBHS source clock multiply by 17 */ +#define RCU_PLLUSBHS_MUL18 PLLUSBCFG_PLLUSBHSMF(18) /*!< PLLUSBHS source clock multiply by 18 */ +#define RCU_PLLUSBHS_MUL19 PLLUSBCFG_PLLUSBHSMF(19) /*!< PLLUSBHS source clock multiply by 19 */ +#define RCU_PLLUSBHS_MUL20 PLLUSBCFG_PLLUSBHSMF(20) /*!< PLLUSBHS source clock multiply by 20 */ +#define RCU_PLLUSBHS_MUL21 PLLUSBCFG_PLLUSBHSMF(21) /*!< PLLUSBHS source clock multiply by 21 */ +#define RCU_PLLUSBHS_MUL22 PLLUSBCFG_PLLUSBHSMF(22) /*!< PLLUSBHS source clock multiply by 22 */ +#define RCU_PLLUSBHS_MUL23 PLLUSBCFG_PLLUSBHSMF(23) /*!< PLLUSBHS source clock multiply by 23 */ +#define RCU_PLLUSBHS_MUL24 PLLUSBCFG_PLLUSBHSMF(24) /*!< PLLUSBHS source clock multiply by 24 */ +#define RCU_PLLUSBHS_MUL25 PLLUSBCFG_PLLUSBHSMF(25) /*!< PLLUSBHS source clock multiply by 25 */ +#define RCU_PLLUSBHS_MUL26 PLLUSBCFG_PLLUSBHSMF(26) /*!< PLLUSBHS source clock multiply by 26 */ +#define RCU_PLLUSBHS_MUL27 PLLUSBCFG_PLLUSBHSMF(27) /*!< PLLUSBHS source clock multiply by 27 */ +#define RCU_PLLUSBHS_MUL28 PLLUSBCFG_PLLUSBHSMF(28) /*!< PLLUSBHS source clock multiply by 28 */ +#define RCU_PLLUSBHS_MUL29 PLLUSBCFG_PLLUSBHSMF(29) /*!< PLLUSBHS source clock multiply by 29 */ +#define RCU_PLLUSBHS_MUL30 PLLUSBCFG_PLLUSBHSMF(30) /*!< PLLUSBHS source clock multiply by 30 */ +#define RCU_PLLUSBHS_MUL31 PLLUSBCFG_PLLUSBHSMF(31) /*!< PLLUSBHS source clock multiply by 31 */ +#define RCU_PLLUSBHS_MUL32 PLLUSBCFG_PLLUSBHSMF(32) /*!< PLLUSBHS source clock multiply by 32 */ +#define RCU_PLLUSBHS_MUL33 PLLUSBCFG_PLLUSBHSMF(33) /*!< PLLUSBHS source clock multiply by 33 */ +#define RCU_PLLUSBHS_MUL34 PLLUSBCFG_PLLUSBHSMF(34) /*!< PLLUSBHS source clock multiply by 34 */ +#define RCU_PLLUSBHS_MUL35 PLLUSBCFG_PLLUSBHSMF(35) /*!< PLLUSBHS source clock multiply by 35 */ +#define RCU_PLLUSBHS_MUL36 PLLUSBCFG_PLLUSBHSMF(36) /*!< PLLUSBHS source clock multiply by 36 */ +#define RCU_PLLUSBHS_MUL37 PLLUSBCFG_PLLUSBHSMF(37) /*!< PLLUSBHS source clock multiply by 37 */ +#define RCU_PLLUSBHS_MUL38 PLLUSBCFG_PLLUSBHSMF(38) /*!< PLLUSBHS source clock multiply by 38 */ +#define RCU_PLLUSBHS_MUL39 PLLUSBCFG_PLLUSBHSMF(39) /*!< PLLUSBHS source clock multiply by 39 */ +#define RCU_PLLUSBHS_MUL40 PLLUSBCFG_PLLUSBHSMF(40) /*!< PLLUSBHS source clock multiply by 40 */ +#define RCU_PLLUSBHS_MUL41 PLLUSBCFG_PLLUSBHSMF(41) /*!< PLLUSBHS source clock multiply by 41 */ +#define RCU_PLLUSBHS_MUL42 PLLUSBCFG_PLLUSBHSMF(42) /*!< PLLUSBHS source clock multiply by 42 */ +#define RCU_PLLUSBHS_MUL43 PLLUSBCFG_PLLUSBHSMF(43) /*!< PLLUSBHS source clock multiply by 43 */ +#define RCU_PLLUSBHS_MUL44 PLLUSBCFG_PLLUSBHSMF(44) /*!< PLLUSBHS source clock multiply by 44 */ +#define RCU_PLLUSBHS_MUL45 PLLUSBCFG_PLLUSBHSMF(45) /*!< PLLUSBHS source clock multiply by 45 */ +#define RCU_PLLUSBHS_MUL46 PLLUSBCFG_PLLUSBHSMF(46) /*!< PLLUSBHS source clock multiply by 46 */ +#define RCU_PLLUSBHS_MUL47 PLLUSBCFG_PLLUSBHSMF(47) /*!< PLLUSBHS source clock multiply by 47 */ +#define RCU_PLLUSBHS_MUL48 PLLUSBCFG_PLLUSBHSMF(48) /*!< PLLUSBHS source clock multiply by 48 */ +#define RCU_PLLUSBHS_MUL49 PLLUSBCFG_PLLUSBHSMF(49) /*!< PLLUSBHS source clock multiply by 49 */ +#define RCU_PLLUSBHS_MUL50 PLLUSBCFG_PLLUSBHSMF(50) /*!< PLLUSBHS source clock multiply by 50 */ +#define RCU_PLLUSBHS_MUL51 PLLUSBCFG_PLLUSBHSMF(51) /*!< PLLUSBHS source clock multiply by 51 */ +#define RCU_PLLUSBHS_MUL52 PLLUSBCFG_PLLUSBHSMF(52) /*!< PLLUSBHS source clock multiply by 52 */ +#define RCU_PLLUSBHS_MUL53 PLLUSBCFG_PLLUSBHSMF(53) /*!< PLLUSBHS source clock multiply by 53 */ +#define RCU_PLLUSBHS_MUL54 PLLUSBCFG_PLLUSBHSMF(54) /*!< PLLUSBHS source clock multiply by 54 */ +#define RCU_PLLUSBHS_MUL55 PLLUSBCFG_PLLUSBHSMF(55) /*!< PLLUSBHS source clock multiply by 55 */ +#define RCU_PLLUSBHS_MUL56 PLLUSBCFG_PLLUSBHSMF(56) /*!< PLLUSBHS source clock multiply by 56 */ +#define RCU_PLLUSBHS_MUL57 PLLUSBCFG_PLLUSBHSMF(57) /*!< PLLUSBHS source clock multiply by 57 */ +#define RCU_PLLUSBHS_MUL58 PLLUSBCFG_PLLUSBHSMF(58) /*!< PLLUSBHS source clock multiply by 58 */ +#define RCU_PLLUSBHS_MUL59 PLLUSBCFG_PLLUSBHSMF(59) /*!< PLLUSBHS source clock multiply by 59 */ +#define RCU_PLLUSBHS_MUL60 PLLUSBCFG_PLLUSBHSMF(60) /*!< PLLUSBHS source clock multiply by 60 */ +#define RCU_PLLUSBHS_MUL61 PLLUSBCFG_PLLUSBHSMF(61) /*!< PLLUSBHS source clock multiply by 61 */ +#define RCU_PLLUSBHS_MUL62 PLLUSBCFG_PLLUSBHSMF(62) /*!< PLLUSBHS source clock multiply by 62 */ +#define RCU_PLLUSBHS_MUL63 PLLUSBCFG_PLLUSBHSMF(63) /*!< PLLUSBHS source clock multiply by 63 */ +#define RCU_PLLUSBHS_MUL64 PLLUSBCFG_PLLUSBHSMF(64) /*!< PLLUSBHS source clock multiply by 64 */ +#define RCU_PLLUSBHS_MUL65 PLLUSBCFG_PLLUSBHSMF(65) /*!< PLLUSBHS source clock multiply by 65 */ +#define RCU_PLLUSBHS_MUL66 PLLUSBCFG_PLLUSBHSMF(66) /*!< PLLUSBHS source clock multiply by 66 */ +#define RCU_PLLUSBHS_MUL67 PLLUSBCFG_PLLUSBHSMF(67) /*!< PLLUSBHS source clock multiply by 67 */ +#define RCU_PLLUSBHS_MUL68 PLLUSBCFG_PLLUSBHSMF(68) /*!< PLLUSBHS source clock multiply by 68 */ +#define RCU_PLLUSBHS_MUL69 PLLUSBCFG_PLLUSBHSMF(69) /*!< PLLUSBHS source clock multiply by 69 */ +#define RCU_PLLUSBHS_MUL70 PLLUSBCFG_PLLUSBHSMF(70) /*!< PLLUSBHS source clock multiply by 70 */ +#define RCU_PLLUSBHS_MUL71 PLLUSBCFG_PLLUSBHSMF(71) /*!< PLLUSBHS source clock multiply by 71 */ +#define RCU_PLLUSBHS_MUL72 PLLUSBCFG_PLLUSBHSMF(72) /*!< PLLUSBHS source clock multiply by 72 */ +#define RCU_PLLUSBHS_MUL73 PLLUSBCFG_PLLUSBHSMF(73) /*!< PLLUSBHS source clock multiply by 73 */ +#define RCU_PLLUSBHS_MUL74 PLLUSBCFG_PLLUSBHSMF(74) /*!< PLLUSBHS source clock multiply by 74 */ +#define RCU_PLLUSBHS_MUL75 PLLUSBCFG_PLLUSBHSMF(75) /*!< PLLUSBHS source clock multiply by 75 */ +#define RCU_PLLUSBHS_MUL76 PLLUSBCFG_PLLUSBHSMF(76) /*!< PLLUSBHS source clock multiply by 76 */ +#define RCU_PLLUSBHS_MUL77 PLLUSBCFG_PLLUSBHSMF(77) /*!< PLLUSBHS source clock multiply by 77 */ +#define RCU_PLLUSBHS_MUL78 PLLUSBCFG_PLLUSBHSMF(78) /*!< PLLUSBHS source clock multiply by 78 */ +#define RCU_PLLUSBHS_MUL79 PLLUSBCFG_PLLUSBHSMF(79) /*!< PLLUSBHS source clock multiply by 79 */ +#define RCU_PLLUSBHS_MUL80 PLLUSBCFG_PLLUSBHSMF(80) /*!< PLLUSBHS source clock multiply by 80 */ +#define RCU_PLLUSBHS_MUL81 PLLUSBCFG_PLLUSBHSMF(81) /*!< PLLUSBHS source clock multiply by 81 */ +#define RCU_PLLUSBHS_MUL82 PLLUSBCFG_PLLUSBHSMF(82) /*!< PLLUSBHS source clock multiply by 82 */ +#define RCU_PLLUSBHS_MUL83 PLLUSBCFG_PLLUSBHSMF(83) /*!< PLLUSBHS source clock multiply by 83 */ +#define RCU_PLLUSBHS_MUL84 PLLUSBCFG_PLLUSBHSMF(84) /*!< PLLUSBHS source clock multiply by 84 */ +#define RCU_PLLUSBHS_MUL85 PLLUSBCFG_PLLUSBHSMF(85) /*!< PLLUSBHS source clock multiply by 85 */ +#define RCU_PLLUSBHS_MUL86 PLLUSBCFG_PLLUSBHSMF(86) /*!< PLLUSBHS source clock multiply by 86 */ +#define RCU_PLLUSBHS_MUL87 PLLUSBCFG_PLLUSBHSMF(87) /*!< PLLUSBHS source clock multiply by 87 */ +#define RCU_PLLUSBHS_MUL88 PLLUSBCFG_PLLUSBHSMF(88) /*!< PLLUSBHS source clock multiply by 88 */ +#define RCU_PLLUSBHS_MUL89 PLLUSBCFG_PLLUSBHSMF(89) /*!< PLLUSBHS source clock multiply by 89 */ +#define RCU_PLLUSBHS_MUL90 PLLUSBCFG_PLLUSBHSMF(90) /*!< PLLUSBHS source clock multiply by 90 */ +#define RCU_PLLUSBHS_MUL91 PLLUSBCFG_PLLUSBHSMF(91) /*!< PLLUSBHS source clock multiply by 91 */ +#define RCU_PLLUSBHS_MUL92 PLLUSBCFG_PLLUSBHSMF(92) /*!< PLLUSBHS source clock multiply by 92 */ +#define RCU_PLLUSBHS_MUL93 PLLUSBCFG_PLLUSBHSMF(93) /*!< PLLUSBHS source clock multiply by 93 */ +#define RCU_PLLUSBHS_MUL94 PLLUSBCFG_PLLUSBHSMF(94) /*!< PLLUSBHS source clock multiply by 94 */ +#define RCU_PLLUSBHS_MUL95 PLLUSBCFG_PLLUSBHSMF(95) /*!< PLLUSBHS source clock multiply by 95 */ +#define RCU_PLLUSBHS_MUL96 PLLUSBCFG_PLLUSBHSMF(96) /*!< PLLUSBHS source clock multiply by 96 */ +#define RCU_PLLUSBHS_MUL97 PLLUSBCFG_PLLUSBHSMF(97) /*!< PLLUSBHS source clock multiply by 97 */ +#define RCU_PLLUSBHS_MUL98 PLLUSBCFG_PLLUSBHSMF(98) /*!< PLLUSBHS source clock multiply by 98 */ +#define RCU_PLLUSBHS_MUL99 PLLUSBCFG_PLLUSBHSMF(99) /*!< PLLUSBHS source clock multiply by 99 */ +#define RCU_PLLUSBHS_MUL100 PLLUSBCFG_PLLUSBHSMF(100) /*!< PLLUSBHS source clock multiply by 100 */ +#define RCU_PLLUSBHS_MUL101 PLLUSBCFG_PLLUSBHSMF(101) /*!< PLLUSBHS source clock multiply by 101 */ +#define RCU_PLLUSBHS_MUL102 PLLUSBCFG_PLLUSBHSMF(102) /*!< PLLUSBHS source clock multiply by 102 */ +#define RCU_PLLUSBHS_MUL103 PLLUSBCFG_PLLUSBHSMF(103) /*!< PLLUSBHS source clock multiply by 103 */ +#define RCU_PLLUSBHS_MUL104 PLLUSBCFG_PLLUSBHSMF(104) /*!< PLLUSBHS source clock multiply by 104 */ +#define RCU_PLLUSBHS_MUL105 PLLUSBCFG_PLLUSBHSMF(105) /*!< PLLUSBHS source clock multiply by 105 */ +#define RCU_PLLUSBHS_MUL106 PLLUSBCFG_PLLUSBHSMF(106) /*!< PLLUSBHS source clock multiply by 106 */ +#define RCU_PLLUSBHS_MUL107 PLLUSBCFG_PLLUSBHSMF(107) /*!< PLLUSBHS source clock multiply by 107 */ +#define RCU_PLLUSBHS_MUL108 PLLUSBCFG_PLLUSBHSMF(108) /*!< PLLUSBHS source clock multiply by 108 */ +#define RCU_PLLUSBHS_MUL109 PLLUSBCFG_PLLUSBHSMF(109) /*!< PLLUSBHS source clock multiply by 109 */ +#define RCU_PLLUSBHS_MUL110 PLLUSBCFG_PLLUSBHSMF(110) /*!< PLLUSBHS source clock multiply by 110 */ +#define RCU_PLLUSBHS_MUL111 PLLUSBCFG_PLLUSBHSMF(111) /*!< PLLUSBHS source clock multiply by 111 */ +#define RCU_PLLUSBHS_MUL112 PLLUSBCFG_PLLUSBHSMF(112) /*!< PLLUSBHS source clock multiply by 112 */ +#define RCU_PLLUSBHS_MUL113 PLLUSBCFG_PLLUSBHSMF(113) /*!< PLLUSBHS source clock multiply by 113 */ +#define RCU_PLLUSBHS_MUL114 PLLUSBCFG_PLLUSBHSMF(114) /*!< PLLUSBHS source clock multiply by 114 */ +#define RCU_PLLUSBHS_MUL115 PLLUSBCFG_PLLUSBHSMF(115) /*!< PLLUSBHS source clock multiply by 115 */ +#define RCU_PLLUSBHS_MUL116 PLLUSBCFG_PLLUSBHSMF(116) /*!< PLLUSBHS source clock multiply by 116 */ +#define RCU_PLLUSBHS_MUL117 PLLUSBCFG_PLLUSBHSMF(117) /*!< PLLUSBHS source clock multiply by 117 */ +#define RCU_PLLUSBHS_MUL118 PLLUSBCFG_PLLUSBHSMF(118) /*!< PLLUSBHS source clock multiply by 118 */ +#define RCU_PLLUSBHS_MUL119 PLLUSBCFG_PLLUSBHSMF(119) /*!< PLLUSBHS source clock multiply by 119 */ +#define RCU_PLLUSBHS_MUL120 PLLUSBCFG_PLLUSBHSMF(120) /*!< PLLUSBHS source clock multiply by 120 */ +#define RCU_PLLUSBHS_MUL121 PLLUSBCFG_PLLUSBHSMF(121) /*!< PLLUSBHS source clock multiply by 121 */ +#define RCU_PLLUSBHS_MUL122 PLLUSBCFG_PLLUSBHSMF(122) /*!< PLLUSBHS source clock multiply by 122 */ +#define RCU_PLLUSBHS_MUL123 PLLUSBCFG_PLLUSBHSMF(123) /*!< PLLUSBHS source clock multiply by 123 */ +#define RCU_PLLUSBHS_MUL124 PLLUSBCFG_PLLUSBHSMF(124) /*!< PLLUSBHS source clock multiply by 124 */ +#define RCU_PLLUSBHS_MUL125 PLLUSBCFG_PLLUSBHSMF(125) /*!< PLLUSBHS source clock multiply by 125 */ +#define RCU_PLLUSBHS_MUL126 PLLUSBCFG_PLLUSBHSMF(126) /*!< PLLUSBHS source clock multiply by 126 */ +#define RCU_PLLUSBHS_MUL127 PLLUSBCFG_PLLUSBHSMF(127) /*!< PLLUSBHS source clock multiply by 127 */ + +/* USBHS prescaler factor */ +#define USBCLKCTL_USBHSPSC(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) +#define RCU_USBHSPSC_DIV1 USBCLKCTL_USBHSPSC(0) /*!< USBHS prescaler select CK_PLL1Q / 1 */ +#define RCU_USBHSPSC_DIV2 USBCLKCTL_USBHSPSC(1) /*!< USBHS prescaler select CK_PLL1Q / 2 */ +#define RCU_USBHSPSC_DIV3 USBCLKCTL_USBHSPSC(2) /*!< USBHS prescaler select CK_PLL1Q / 3 */ +#define RCU_USBHSPSC_DIV4 USBCLKCTL_USBHSPSC(3) /*!< USBHS prescaler select CK_PLL1Q / 4 */ +#define RCU_USBHSPSC_DIV5 USBCLKCTL_USBHSPSC(4) /*!< USBHS prescaler select CK_PLL1Q / 5 */ +#define RCU_USBHSPSC_DIV6 USBCLKCTL_USBHSPSC(5) /*!< USBHS prescaler select CK_PLL1Q / 6 */ +#define RCU_USBHSPSC_DIV7 USBCLKCTL_USBHSPSC(6) /*!< USBHS prescaler select CK_PLL1Q / 7 */ +#define RCU_USBHSPSC_DIV8 USBCLKCTL_USBHSPSC(7) /*!< USBHS prescaler select CK_PLL1Q / 8 */ + +/* USBHS 48MHz clock selection */ +#define USBCLKCTL_USB48MSEL(regval) (BITS(5,6) & ((uint32_t)(regval) << 5U)) +#define RCU_USB48MSRC_PLL0R USBCLKCTL_USB48MSEL(0) /*!< select PLL0R as USABHS 48MHz clock source */ +#define RCU_USB48MSRC_PLLUSBHS USBCLKCTL_USB48MSEL(1) /*!< select PLLUSBHS / USBHSDV as USABHS 48MHz clock source */ +#define RCU_USB48MSRC_PLL1Q USBCLKCTL_USB48MSEL(2) /*!< select PLL1Q / USBHSPSC as USABHS 48MHz clock source */ +#define RCU_USB48MSRC_IRC48M USBCLKCTL_USB48MSEL(3) /*!< select IRC48M as USABHS 48MHz clock source */ + +/* function declarations */ +/* peripherals clock configure functions */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* enable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the peripherals */ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset); +/* disable reset the peripheral */ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset); +/* reset the BKP */ +void rcu_bkp_reset_enable(void); +/* disable the BKP reset */ +void rcu_bkp_reset_disable(void); + +/* system and peripherals clock source, system reset configure functions */ +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB1 prescaler selection */ +void rcu_apb1_clock_config(uint32_t ck_apb1); +/* configure the APB2 prescaler selection */ +void rcu_apb2_clock_config(uint32_t ck_apb2); +/* configure the APB3 prescaler selection */ +void rcu_apb3_clock_config(uint32_t ck_apb3); +/* configure the APB4 prescaler selection */ +void rcu_apb4_clock_config(uint32_t ck_apb4); +/* configure the CK_OUT0 clock source and divider */ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div); +/* configure the CK_OUT1 clock source and divider */ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div); + +/* configure the PLL input and output clock range */ +void rcu_pll_input_output_clock_range_config(pll_idx_enum pll_idx, uint32_t ck_input, uint32_t ck_output); +/* configure fractional part of the multiplication factor for PLL VCO */ +void rcu_pll_fractional_config(pll_idx_enum pll_idx, uint32_t pll_fracn); +/* enable PLL fractional latch */ +void rcu_pll_fractional_latch_enable(pll_idx_enum pll_idx); +/* disable PLL fractional latch */ +void rcu_pll_fractional_latch_disable(pll_idx_enum pll_idx); +/* configure the PLLs clock source selection */ +void rcu_pll_source_config(uint32_t pll_src); +/* configure the PLL0 */ +ErrStatus rcu_pll0_config(uint32_t pll0_psc, uint32_t pll0_n, uint32_t pll0_p, uint32_t pll0_q, uint32_t pll0_r); +/* configure the PLL1 clock */ +ErrStatus rcu_pll1_config(uint32_t pll1_psc, uint32_t pll1_n, uint32_t pll1_p, uint32_t pll1_q, uint32_t pll1_r); +/* configure the PLL2 clock */ +ErrStatus rcu_pll2_config(uint32_t pll2_psc, uint32_t pll2_n, uint32_t pll2_p, uint32_t pll2_q, uint32_t pll2_r); +/* enable the pllp pllq pllr divider output */ +void rcu_pll_clock_output_enable(uint32_t pllxy); +/* disable the pllp pllq pllr divider output */ +void rcu_pll_clock_output_disable(uint32_t pllxy); +/* configure the PLLUSBHS0 clock */ +void rcu_pllusb0_config(uint32_t pllusb_presel, uint32_t pllusb_predv, uint32_t pllusb_mf, uint32_t usbhsdv); +/* configure the PLLUSBHS1 clock */ +void rcu_pllusb1_config(uint32_t pllusb_presel, uint32_t pllusb_predv, uint32_t pllusb_mf, uint32_t usbhsdv); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +/* configure the frequency division of RTC clock when HXTAL was selected as its clock source */ +void rcu_rtc_div_config(uint32_t rtc_div); +/* configure the CK48M clock selection */ +void rcu_ck48m_clock_config(uint32_t ck48m_clock_source); +/* configure the PLL48M clock selection */ +void rcu_pll48m_clock_config(uint32_t pll48m_clock_source); +/* configure the IRC64M clock divider selection */ +void rcu_irc64mdiv_clock_config(uint32_t ck_irc64mdiv); +/* get the irc64mdiv clock */ +uint32_t rcu_irc64mdiv_freq_get(void); +/* configure the TIMER clock prescaler selection */ +void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler); +/* configure the SPI clock source selection */ +void rcu_spi_clock_config(spi_idx_enum spi_idx, uint32_t ck_spi); +/* configure the SDIO clock source selection */ +void rcu_sdio_clock_config(sdio_idx_enum sdio_idx, uint32_t ck_sdio); +/* configure the Deep-sleep wakeup system clock source selection */ +void rcu_deepsleep_wakeup_sys_clock_config(uint32_t ck_dspwussel); +/* configure the TLI clock division selection */ +void rcu_tli_clock_div_config(uint32_t pll2_r_div); +/* configure the USARTx(x=0,1,2,5) clock source selection */ +void rcu_usart_clock_config(usart_idx_enum usart_idx, uint32_t ck_usart); +/* configure the I2Cx(x=0,1,2,3) clock source selection */ +void rcu_i2c_clock_config(i2c_idx_enum i2c_idx, uint32_t ck_i2c); +/* configure the CANx(x=0,1,2) clock source selection */ +void rcu_can_clock_config(can_idx_enum can_idx, uint32_t ck_can); +/* configure the ADCx(x=0,1,2) clock source selection */ +void rcu_adc_clock_config(adc_idx_enum adc_idx, uint32_t ck_adc); +/* configure the SAIx(x=0,1) clock source selection */ +void rcu_sai_clock_config(sai_idx_enum sai_idx, uint32_t ck_sai); +/* configure the SAI2Bx(x=0,1) clock source selection */ +void rcu_sai2_block_clock_config(sai2b_idx_enum sai2b_idx, uint32_t ck_sai2b); +/* configure the RSPDIF clock source selection */ +void rcu_rspdif_clock_config(uint32_t ck_rspdif); +/* configure the EXMC clock source selection */ +void rcu_exmc_clock_config(uint32_t ck_exmc); +/* configure the HPDF clock source selection */ +void rcu_hpdf_clock_config(uint32_t ck_hpdf); +/* configure the peripheral clock source selection */ +void rcu_per_clock_config(uint32_t ck_per); +/* configure the PLL1Q prescaler */ +void rcu_usbhs_pll1qpsc_config(usbhs_idx_enum usbhs_idx, uint32_t ck_usbhspsc); +/* configure the USBHS48M clock source selection */ +void rcu_usb48m_clock_config(usbhs_idx_enum usbhs_idx, uint32_t ck_usb48m); +/* configure the USBHS clock source selection */ +void rcu_usbhs_clock_config(usbhs_idx_enum usbhs_idx, uint32_t ck_usbhs); +/* enable the USBHS clock source selection */ +void rcu_usbhs_clock_selection_enable(usbhs_idx_enum usbhs_idx); +/* disable configure the USBHS clock source selection */ +void rcu_usbhs_clock_selection_disable(usbhs_idx_enum usbhs_idx); + +/* LXTAL, IRC64M, LPIRC4M, PLLs and other oscillator configure functions */ +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); +/* wait for oscillator stabilization flags is SET or oscillator startup is timeout */ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci); +/* turn on the oscillator */ +void rcu_osci_on(rcu_osci_type_enum osci); +/* turn off the oscillator */ +void rcu_osci_off(rcu_osci_type_enum osci); +/* enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* set the IRC64M adjust value */ +void rcu_irc64m_adjust_value_set(uint32_t irc64m_adjval); +/* set the LPIRC4M adjust value */ +void rcu_lpirc4m_adjust_value_set(uint32_t lpirc4m_adjval); + +/* clock monitor configure functions */ +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); +/* enable the LXTAL clock monitor */ +void rcu_lxtal_clock_monitor_enable(void); +/* disable the LXTAL clock monitor */ +void rcu_lxtal_clock_monitor_disable(void); + +/* clock frequency get functions */ +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +/* flag & interrupt functions */ +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum interrupt); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum interrupt); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag); + +#endif /* GD32H7XX_RCU_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rspdif.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rspdif.h new file mode 100644 index 0000000000..7ae3a0244f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rspdif.h @@ -0,0 +1,326 @@ +/*! + \file gd32h7xx_rspdif.h + \brief definitions for the RSPDIF + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_RSPDIF_H +#define GD32H7XX_RSPDIF_H + +#include "gd32h7xx.h" + +/* RSPDIF definitions */ +#define RSPDIF RSPDIF_BASE /*!< RSPDIF base address */ + +/* registers definitions */ +#define RSPDIF_CTL REG32(RSPDIF + 0x00000000U) /*!< RSPDIF control register */ +#define RSPDIF_INTEN REG32(RSPDIF + 0x00000004U) /*!< RSPDIF interrupt enable register */ +#define RSPDIF_STAT REG32(RSPDIF + 0x00000008U) /*!< RSPDIF status register */ +#define RSPDIF_STATC REG32(RSPDIF + 0x0000000CU) /*!< RSPDIF status flag clear register */ +#define RSPDIF_DATA REG32(RSPDIF + 0x00000010U) /*!< RSPDIF RX data register */ +#define RSPDIF_CHSTAT REG32(RSPDIF + 0x00000014U) /*!< RSPDIF RX channel status register */ +#define RSPDIF_DTH REG32(RSPDIF + 0x00000018U) /*!< RSPDIF RX data threshold register */ + +#define RSPDIF_DATA_F0 REG32(RSPDIF + 0x00000010U) /*!< RSPDIF RX data register fomat 0 */ +#define RSPDIF_DATA_F1 REG32(RSPDIF + 0x00000010U) /*!< RSPDIF RX data register fomat 1 */ +#define RSPDIF_DATA_F2 REG32(RSPDIF + 0x00000010U) /*!< RSPDIF RX data register fomat 2 */ + +/* bits definitions */ +/* RSPDIF_CTL */ +#define RSPDIF_CTL_RXCFG BITS(0,1) /*!< RSPDIF configuration */ +#define RSPDIF_CTL_DMAREN BIT(2) /*!< RSPDIF receiver DMA enable for data flow */ +#define RSPDIF_CTL_RXSTEOMEN BIT(3) /*!< RSPDIF RX stereo mode enable */ +#define RSPDIF_CTL_RXDF BITS(4,5) /*!< RSPDIF RX data format selection */ +#define RSPDIF_CTL_PNCPEN BIT(6) /*!< RSPDIF parity error bit no copy enable bit */ +#define RSPDIF_CTL_VNCPEN BIT(7) /*!< RSPDIF validity bit no copy enable bit */ +#define RSPDIF_CTL_CUNCPEN BIT(8) /*!< RSPDIF channel status and user bits no copy enable bit */ +#define RSPDIF_CTL_PTNCPEN BIT(9) /*!< RSPDIF preamble type bits no copy enable bit */ +#define RSPDIF_CTL_DMACBEN BIT(10) /*!< RSPDIF control buffer DMA enable for control flow */ +#define RSPDIF_CTL_CFCHSEL BIT(11) /*!< RSPDIF the control flow acquires channel state source selection */ +#define RSPDIF_CTL_MAXRT BITS(12,13) /*!< RSPDIF maximum number of retries allowed during the RSPDIF synchronization phase */ +#define RSPDIF_CTL_WFRXA BIT(14) /*!< RSPDIF wait for the four valid transition signal of the selected RSPDIF channel */ +#define RSPDIF_CTL_RXCHSEL BITS(16,18) /*!< RSPDIF input channel selection */ +#define RSPDIF_CTL_SCKEN BIT(20) /*!< RSPDIF symbol clock enable */ +#define RSPDIF_CTL_BKSCKEN BIT(21) /*!< RSPDIF backup symbol clock enable */ + +/* RSPDIF_INTEN */ +#define RSPDIF_INTEN_RBNEIE BIT(0) /*!< RSPDIF_DATA register no empty interrupt enable */ +#define RSPDIF_INTEN_CBNEIE BIT(1) /*!< RSPDIF_CHSTAT register no empty interrupt enable */ +#define RSPDIF_INTEN_PERRIE BIT(2) /*!< RSPDIF parity error interrupt enable */ +#define RSPDIF_INTEN_RXORERRIE BIT(3) /*!< RSPDIF RX overrun error interrupt enable */ +#define RSPDIF_INTEN_SYNDBIE BIT(4) /*!< RSPDIF synchronization block detected interrupt enable */ +#define RSPDIF_INTEN_SYNDOIE BIT(5) /*!< RSPDIF synchronization done interrupt enable */ +#define RSPDIF_INTEN_RXDCERRIE BIT(6) /*!< RSPDIF data decoding error interrupt enable */ + +/* RSPDIF_STAT */ +#define RSPDIF_STAT_RBNE BIT(0) /*!< RSPDIF_DATA register is not empty */ +#define RSPDIF_STAT_CBNE BIT(1) /*!< RSPDIF_CHSTAT control buffer is not empty */ +#define RSPDIF_STAT_PERR BIT(2) /*!< RSPDIF parity error */ +#define RSPDIF_STAT_RXORERR BIT(3) /*!< RSPDIF RX overrun error */ +#define RSPDIF_STAT_SYNDB BIT(4) /*!< RSPDIF synchronization block detected */ +#define RSPDIF_STAT_SYNDO BIT(5) /*!< RSPDIF synchronization done */ +#define RSPDIF_STAT_FRERR BIT(6) /*!< RSPDIF frame error */ +#define RSPDIF_STAT_SYNERR BIT(7) /*!< RSPDIF synchronization error */ +#define RSPDIF_STAT_TMOUTERR BIT(8) /*!< RSPDIF timeout error */ +#define RSPDIF_STAT_CKCNT5 BITS(16,30) /*!< the number of consecutive time clock cycles */ + +/* RSPDIF_STATC */ +#define RSPDIF_STATC_PERRC BIT(2) /*!< RSPDIF clears the parity error flag */ +#define RSPDIF_STATC_RXORERRC BIT(3) /*!< RSPDIF clears the RX overrun error flag */ +#define RSPDIF_STATC_SYNDBC BIT(4) /*!< RSPDIF clears the synchronization block detected flag */ +#define RSPDIF_STATC_SYNDOC BIT(5) /*!< RSPDIF clears the synchronization done flag */ + +/* RSPDIF_DATA */ +/* RSPDIF_DATA_F0 */ +#define RSPDIF_DATA_F0_DATA0 BITS(0,23) /*!< data value */ +#define RSPDIF_DATA_F0_P BIT(24) /*!< parity error bit */ +#define RSPDIF_DATA_F0_V BIT(25) /*!< validity bit */ +#define RSPDIF_DATA_F0_U BIT(26) /*!< user bit */ +#define RSPDIF_DATA_F0_C BIT(27) /*!< channel status bit */ +#define RSPDIF_DATA_F0_PREF BITS(28,29) /*!< preamble type */ + +/* RSPDIF_DATA_F1 */ +#define RSPDIF_DATA_F1_P BIT(0) /*!< parity error bit */ +#define RSPDIF_DATA_F1_V BIT(1) /*!< validity bit */ +#define RSPDIF_DATA_F1_U BIT(2) /*!< user bit */ +#define RSPDIF_DATA_F1_C BIT(3) /*!< channel status bit */ +#define RSPDIF_DATA_F1_PREF BITS(4,5) /*!< preamble type */ +#define RSPDIF_DATA_F1_DATA0 BITS(8,31) /*!< data value */ + +/* RSPDIF_DATA_F2 */ +#define RSPDIF_DATA_F2_DATA1 BITS(0,15) /*!< steo mode: this field contains the channel B data\ + mono mode: this field contains the more recent value */ +#define RSPDIF_DATA_F2_DATA2 BITS(16,31) /*!< steo mode: this field contains the channel A data\ + mono mode: this field contains the oldest value */ + +/* RSPDIF_CHSTAT */ +#define RSPDIF_CHSTAT_USER BITS(0,15) /*!< user data information */ +#define RSPDIF_CHSTAT_CHS BITS(16,23) /*!< channel A status information */ +#define RSPDIF_CHSTAT_SOB BIT(24) /*!< start of block */ + +/* RSPDIF_DTH */ +#define RSPDIF_DTH_THHI BITS(0,12) /*!< high threshold */ +#define RSPDIF_DTH_THLO BITS(16,28) /*!< low threshold */ + +/* constants definitions */ +/* RSPDIF initialization parameter structure definitions */ +typedef struct { + uint32_t input_sel; /*!< the RSPDIF input selection */ + uint32_t max_retrie; /*!< the RSPDIF maximum allowed re-tries during synchronization phase */ + uint32_t wait_activity; /*!< the RSPDIF wait for activity on the selected input */ + uint32_t channel_sel; /*!< whether swapping the channel status from channel A or B */ + uint32_t sample_format; /*!< the RSPDIF data samples format (LSB, MSB, ...) */ + uint32_t sound_mode; /*!< the RSPDIF is in stereo or mono mode */ + uint32_t pre_type; /*!< whether opy the preamble type value into the RSPDIF_DATA */ + uint32_t channel_status_bit; /*!< whether the channel status and user bits are copied or not into the received frame */ + uint32_t validity_bit; /*!< whether the validity bit is copied or not into the received frame */ + uint32_t parity_error_bit; /*!< whether the parity error bit is copied or not into the received frame */ + uint32_t symbol_clk; /*!< the RSPDIF symbol clock generation */ + uint32_t bak_symbol_clk; /*!< the RSPDIF backup symbol clock generation */ +} rspdif_parameter_struct; + +/* RSPDIF data parameter structure definitions */ +typedef struct { + uint32_t format; /*!< the data dormat */ + uint32_t preamble; /*!< the preamble type */ + uint32_t channel_status; /*!< channel status bit */ + uint32_t user_bit; /*!< user bit */ + uint32_t validity; /*!< validity bit */ + uint32_t parity_err; /*!< parity error bit */ + uint32_t data0; /*!< data value 0 */ + uint32_t data1; /*!< data value 1 */ +} rspdif_data_struct; + +/* RSPDIF configuration */ +#define CTL_RXCFG(regval) (BITS(0,1) & ((uint32_t)(regval))) +#define RSPDIF_STATE_IDLE CTL_RXCFG(0) /*!< disable RSPDIF */ +#define RSPDIF_STATE_SYNC CTL_RXCFG(1) /*!< enable RSPDIF synchronization only */ +#define RSPDIF_STATE_RCV CTL_RXCFG(3) /*!< enable RSPDIF */ + +/* RX stereo mode enable */ +#define RSPDIF_STEREOMODE_DISABLE ((uint32_t)0x00000000U) /*!< MONO mode */ +#define RSPDIF_STEREOMODE_ENABLE ((uint32_t)RSPDIF_CTL_RXSTEOMEN) /*!< STEREO mode */ + +/* RX data format selection */ +#define CTL_RXDF(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define RSPDIF_DATAFORMAT_LSB CTL_RXDF(0) /*!< the data format is described in the RSPDIF_DATA_F0 register, audio data is right aligned (LSB) */ +#define RSPDIF_DATAFORMAT_MSB CTL_RXDF(1) /*!< the data format is described in the RSPDIF_DATA_F1 register, audio data is left aligned (MSB) */ +#define RSPDIF_DATAFORMAT_32BITS CTL_RXDF(2) /*!< the data format is described in the RSPDIF_DATA_F2 register, which packs two 16-bit audio data into one 32-bit data */ + +/* whether copy preamble type bit into RSPDIF_DATA */ +#define RSPDIF_PREAMBLE_TYPE_MASK_OFF ((uint32_t)0x00000000U) /*!< copy the preamble type bit into the RSPDIF_DATA */ +#define RSPDIF_PREAMBLE_TYPE_MASK_ON ((uint32_t)RSPDIF_CTL_PTNCPEN) /*!< do not copy the preamble type bit into the RSPDIF_DATA, but write 0 instead */ + +/* whether copy channel status and user bits into RSPDIF_DATA */ +#define RSPDIF_CHANNEL_STATUS_MASK_OFF ((uint32_t)0x00000000U) /*!< copy the channel status and user bit into the RSPDIF_DATA */ +#define RSPDIF_CHANNEL_STATUS_MASK_ON ((uint32_t)RSPDIF_CTL_CUNCPEN) /*!< do not copy the channel status and user bit into the RSPDIF_DATA, but write 0 instead */ + +/* whether copy validity bit into RSPDIF_DATA */ +#define RSPDIF_VALIDITY_MASK_OFF ((uint32_t)0x00000000U) /*!< copy the validity bit into the RSPDIF_DATA */ +#define RSPDIF_VALIDITY_MASK_ON ((uint32_t)RSPDIF_CTL_VNCPEN) /*!< do not copy the validity bit into the RSPDIF_DATA, but write 0 instead */ + +/* whether copy parity error bit into RSPDIF_DATA */ +#define RSPDIF_PERROR_MASK_OFF ((uint32_t)0x00000000U) /*!< copy the parity error bit into the RSPDIF_DATA */ +#define RSPDIF_PERROR_MASK_ON ((uint32_t)RSPDIF_CTL_PNCPEN) /*!< do not copy the parity error bit into the RSPDIF_DATA, but write 0 instead */ + +/* maximum number of retries allowed during the RSPDIF synchronization */ +#define CTL_MAXRT(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define RSPDIF_MAXRETRIES_NONE CTL_MAXRT(0) /*!< no retry */ +#define RSPDIF_MAXRETRIES_3 CTL_MAXRT(1) /*!< allow up to 3 retries */ +#define RSPDIF_MAXRETRIES_15 CTL_MAXRT(2) /*!< allow up to 15 retries */ +#define RSPDIF_MAXRETRIES_63 CTL_MAXRT(3) /*!< allow up to 63 retries */ + +/* wait for the four valid transition signal of the selected RSPDIF channel */ +#define RSPDIF_WAIT_FOR_ACTIVITY_OFF ((uint32_t)0x00000000U) /*!< RSPDIF does not wait for the valid conversion signal from the selected RSPDIF channel */ +#define RSPDIF_WAIT_FOR_ACTIVITY_ON ((uint32_t)RSPDIF_CTL_WFRXA) /*!< RSPDIF wait for the valid conversion signal from the selected RSPDIF channel */ + +/* input channel selection */ +#define CTL_RXCHSEL(regval) (BITS(16,18) & ((uint32_t)(regval) << 16)) +#define RSPDIF_INPUT_IN0 CTL_RXCHSEL(0) /*!< RSPDIF_CH0 selected */ +#define RSPDIF_INPUT_IN1 CTL_RXCHSEL(1) /*!< RSPDIF_CH1 selected */ +#define RSPDIF_INPUT_IN2 CTL_RXCHSEL(2) /*!< RSPDIF_CH2 selected */ +#define RSPDIF_INPUT_IN3 CTL_RXCHSEL(3) /*!< RSPDIF_CH3 selected */ + +/* symbol clock enable */ +#define RSPDIF_SYMBOL_CLK_OFF ((uint32_t)0x00000000U) /*!< the RSPDIF does not generate a symbol clock */ +#define RSPDIF_SYMBOL_CLK_ON RSPDIF_CTL_SCKEN /*!< the RSPDIF generates a symbol clock */ + +/* backup symbol clock enable */ +#define RSPDIF_BACKUP_SYMBOL_CLK_OFF ((uint32_t)0x00000000U) /*!< the RSPDIF does not generate a backup symbol clock */ +#define RSPDIF_BACKUP_SYMBOL_CLK_ON RSPDIF_CTL_BKSCKEN /*!< the RSPDIF generates a backup symbol clock if SCKEN = 1 */ + +/* the control flow acquires channel state source selection */ +#define RSPDIF_CHANNEL_A ((uint32_t)0x00000000U) /*!< gets channel status from channel A */ +#define RSPDIF_CHANNEL_B ((uint32_t)RSPDIF_CTL_CFCHSEL) /*!< gets channel status from channel B */ + +/* RSPDIF preamble type */ +#define RSPDIF_PREAMBLE_NONE ((uint32_t)0x00000000U) /*!< RSPDIF preamble received not used */ +#define RSPDIF_PREAMBLE_B ((uint32_t)0x00000001U) /*!< RSPDIF Preamble B received */ +#define RSPDIF_PREAMBLE_M ((uint32_t)0x00000002U) /*!< RSPDIF Preamble M received */ +#define RSPDIF_PREAMBLE_W ((uint32_t)0x00000003U) /*!< RSPDIF Preamble W received */ + +/* RSPDIF interrupt enable or disable constants definitions */ +#define RSPDIF_INT_RBNE RSPDIF_INTEN_RBNEIE /*!< RSPDIF RX buffer no empty interrupt enable */ +#define RSPDIF_INT_CBNE RSPDIF_INTEN_CBNEIE /*!< RSPDIF RX control buffer no empty interrupt enable */ +#define RSPDIF_INT_PERR RSPDIF_INTEN_PERRIE /*!< RSPDIF parity error interrupt enable */ +#define RSPDIF_INT_RXORERR RSPDIF_INTEN_RXORERRIE /*!< RSPDIF RX overrun error interrupt enable */ +#define RSPDIF_INT_SYNDB RSPDIF_INTEN_SYNDBIE /*!< RSPDIF synchronization block detected interrupt enable */ +#define RSPDIF_INT_SYNDO RSPDIF_INTEN_SYNDOIE /*!< RSPDIF synchronization done interrupt enable */ +#define RSPDIF_INT_RXDCERR RSPDIF_INTEN_RXDCERRIE /*!< RSPDIF data decoding error interrupt enable */ + +/* RSPDIF flags */ +#define RSPDIF_FLAG_RBNE RSPDIF_STAT_RBNE /*!< RSPDIF RX buffer is not empty */ +#define RSPDIF_FLAG_CBNE RSPDIF_STAT_CBNE /*!< RSPDIF RX control buffer is not empty */ +#define RSPDIF_FLAG_PERR RSPDIF_STAT_PERR /*!< RSPDIF parity error */ +#define RSPDIF_FLAG_RXORERR RSPDIF_STAT_RXORERR /*!< RSPDIF RX overrun error */ +#define RSPDIF_FLAG_SYNDB RSPDIF_STAT_SYNDB /*!< RSPDIF synchronization block detected */ +#define RSPDIF_FLAG_SYNDO RSPDIF_STAT_SYNDO /*!< RSPDIF synchronization done */ +#define RSPDIF_FLAG_FRERR RSPDIF_STAT_FRERR /*!< RSPDIF frame error */ +#define RSPDIF_FLAG_SYNERR RSPDIF_STAT_SYNERR /*!< RSPDIF synchronization error */ +#define RSPDIF_FLAG_TMOUTERR RSPDIF_STAT_TMOUTERR /*!< RSPDIF time out error */ + +/* RSPDIF interrupt flags */ +#define RSPDIF_INT_FLAG_RBNE RSPDIF_STAT_RBNE /*!< RSPDIF RX buffer no empty interrupt flag */ +#define RSPDIF_INT_FLAG_CBNE RSPDIF_STAT_CBNE /*!< RSPDIF RX control buffer no empty interrupt flag */ +#define RSPDIF_INT_FLAG_PERR RSPDIF_STAT_PERR /*!< RSPDIF parity error interrupt flag */ +#define RSPDIF_INT_FLAG_RXORERR RSPDIF_STAT_RXORERR /*!< RSPDIF RX overrun error interrupt flag */ +#define RSPDIF_INT_FLAG_SYNDB RSPDIF_STAT_SYNDB /*!< RSPDIF synchronization block detected interrupt flag */ +#define RSPDIF_INT_FLAG_SYNDO RSPDIF_STAT_SYNDO /*!< RSPDIF synchronization done interrupt flag */ +#define RSPDIF_INT_FLAG_FRERR RSPDIF_STAT_FRERR /*!< RSPDIF frame error interrupt flag */ +#define RSPDIF_INT_FLAG_SYNERR RSPDIF_STAT_SYNERR /*!< RSPDIF synchronization error interrupt flag */ +#define RSPDIF_INT_FLAG_TMOUTERR RSPDIF_STAT_TMOUTERR /*!< RSPDIF time out error interrupt flag */ + +/* function declarations */ +/* RSPDIF deinitialization and initialization functions */ +/* reset the RSPDIF */ +void rspdif_deinit(void); +/* initialize the parameters of RSPDIF structure with the default values */ +void rspdif_struct_para_init(rspdif_parameter_struct *rspdif_struct); +/* initialize the RSPDIF parameters */ +void rspdif_init(rspdif_parameter_struct *rspdif_struct); +/* specifies the RSPDIF peripheral state */ +void rspdif_enable(uint32_t mode); +/* disable RSPDIF */ +void rspdif_disable(void); + +/* symbol clock functions */ +/* enable RSPDIF symbol clock */ +void rspdif_symbol_clock_enable(void); +/* disable RSPDIF symbol clock */ +void rspdif_symbol_clock_disable(void); +/* enable RSPDIF backup symbol clock */ +void rspdif_backup_symbol_clock_enable(void); +/* disable RSPDIF backup symbol clock */ +void rspdif_backup_symbol_clock_disable(void); + +/* DMA functions */ +/* enable the RSPDIF receiver DMA */ +void rspdif_dma_enable(void); +/* disable the RSPDIF receiver DMA */ +void rspdif_dma_disable(void); +/* enable the RSPDIF control buffer DMA */ +void rspdif_control_buffer_dma_enable(void); +/* disable the RSPDIF control buffer DMA */ +void rspdif_control_buffer_dma_disable(void); + +/* transfer function */ +/* RSPDIF read data */ +void rspdif_data_read(rspdif_data_struct *data_struct); + +/* information acquisition functions */ +/* get duration of 5 symbols counted using rspdif_ck */ +uint32_t rspdif_duration_of_symbols_get(void); +/* get user data information */ +uint32_t rspdif_user_data_get(void); +/* get channel status information */ +uint32_t rspdif_channel_status_get(void); +/* get start of block */ +FlagStatus rspdif_start_block_status_get(void); +/* get threshold low estimation */ +uint32_t rspdif_low_threshold_get(void); +/* get threshold high estimation */ +uint32_t rspdif_high_threshold_get(void); + +/* flag and interrupt functions */ +/* get RSPDIF flag status */ +FlagStatus rspdif_flag_get(uint16_t flag); +/* clear RSPDIF flag */ +void rspdif_flag_clear(uint16_t flag); +/* enable RSPDIF interrupt */ +void rspdif_interrupt_enable(uint8_t interrupt); +/* disable RSPDIF interrupt */ +void rspdif_interrupt_disable(uint8_t interrupt); +/* get RSPDIF interrupt flag status */ +FlagStatus rspdif_interrupt_flag_get(uint16_t int_flag); +/* clear RSPDIF interrupt flag status */ +void rspdif_interrupt_flag_clear(uint16_t int_flag); + +#endif /* GD32H7XX_RSPDIF_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtc.h new file mode 100644 index 0000000000..c9f76006a1 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtc.h @@ -0,0 +1,729 @@ +/*! + \file gd32h7xx_rtc.h + \brief definitions for the RTC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_RTC_H +#define GD32H7XX_RTC_H + +#include "gd32h7xx.h" + +/* RTC definitions */ +#define RTC RTC_BASE /* RTC base address */ + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00000000U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x00000004U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x00000008U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0000000CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x00000010U) /*!< RTC time prescaler register */ +#define RTC_WUT REG32((RTC) + 0x00000014U) /*!< RTC wakeup timer regiser */ +#define RTC_ALRM0TD REG32((RTC) + 0x0000001CU) /*!< RTC alarm 0 time and date register */ +#define RTC_ALRM1TD REG32((RTC) + 0x00000020U) /*!< RTC alarm 1 time and date register */ +#define RTC_WPK REG32((RTC) + 0x00000024U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x00000028U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x0000002CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x00000030U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x00000034U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x00000038U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x0000003CU) /*!< RTC high resolution frequency compensation register */ +#define RTC_TAMP REG32((RTC) + 0x00000040U) /*!< RTC tamper register */ +#define RTC_ALRM0SS REG32((RTC) + 0x00000044U) /*!< RTC alarm 0 sub second register */ +#define RTC_ALRM1SS REG32((RTC) + 0x00000048U) /*!< RTC alarm 1 sub second register */ +#define RTC_CFG REG32((RTC) + 0x0000004CU) /*!< RTC configure register */ +#define RTC_BKP0 REG32((RTC) + 0x00000050U) /*!< RTC backup 0 register */ +#define RTC_BKP1 REG32((RTC) + 0x00000054U) /*!< RTC backup 1 register */ +#define RTC_BKP2 REG32((RTC) + 0x00000058U) /*!< RTC backup 2 register */ +#define RTC_BKP3 REG32((RTC) + 0x0000005CU) /*!< RTC backup 3 register */ +#define RTC_BKP4 REG32((RTC) + 0x00000060U) /*!< RTC backup 4 register */ +#define RTC_BKP5 REG32((RTC) + 0x00000064U) /*!< RTC backup 5 register */ +#define RTC_BKP6 REG32((RTC) + 0x00000068U) /*!< RTC backup 6 register */ +#define RTC_BKP7 REG32((RTC) + 0x0000006CU) /*!< RTC backup 7 register */ +#define RTC_BKP8 REG32((RTC) + 0x00000070U) /*!< RTC backup 8 register */ +#define RTC_BKP9 REG32((RTC) + 0x00000074U) /*!< RTC backup 9 register */ +#define RTC_BKP10 REG32((RTC) + 0x00000078U) /*!< RTC backup 10 register */ +#define RTC_BKP11 REG32((RTC) + 0x0000007CU) /*!< RTC backup 11 register */ +#define RTC_BKP12 REG32((RTC) + 0x00000080U) /*!< RTC backup 12 register */ +#define RTC_BKP13 REG32((RTC) + 0x00000084U) /*!< RTC backup 13 register */ +#define RTC_BKP14 REG32((RTC) + 0x00000088U) /*!< RTC backup 14 register */ +#define RTC_BKP15 REG32((RTC) + 0x0000008CU) /*!< RTC backup 15 register */ +#define RTC_BKP16 REG32((RTC) + 0x00000090U) /*!< RTC backup 16 register */ +#define RTC_BKP17 REG32((RTC) + 0x00000094U) /*!< RTC backup 17 register */ +#define RTC_BKP18 REG32((RTC) + 0x00000098U) /*!< RTC backup 18 register */ +#define RTC_BKP19 REG32((RTC) + 0x0000009CU) /*!< RTC backup 19 register */ +#define RTC_BKP20 REG32((RTC) + 0x000000A0U) /*!< RTC backup 20 register */ +#define RTC_BKP21 REG32((RTC) + 0x000000A4U) /*!< RTC backup 21 register */ +#define RTC_BKP22 REG32((RTC) + 0x000000A8U) /*!< RTC backup 22 register */ +#define RTC_BKP23 REG32((RTC) + 0x000000ACU) /*!< RTC backup 23 register */ +#define RTC_BKP24 REG32((RTC) + 0x000000B0U) /*!< RTC backup 24 register */ +#define RTC_BKP25 REG32((RTC) + 0x000000B4U) /*!< RTC backup 25 register */ +#define RTC_BKP26 REG32((RTC) + 0x000000B8U) /*!< RTC backup 26 register */ +#define RTC_BKP27 REG32((RTC) + 0x000000BCU) /*!< RTC backup 27 register */ +#define RTC_BKP28 REG32((RTC) + 0x000000C0U) /*!< RTC backup 28 register */ +#define RTC_BKP29 REG32((RTC) + 0x000000C4U) /*!< RTC backup 29 register */ +#define RTC_BKP30 REG32((RTC) + 0x000000C8U) /*!< RTC backup 30 register */ +#define RTC_BKP31 REG32((RTC) + 0x000000CCU) /*!< RTC backup 31 register */ + +/* bits definitions */ +/* RTC_TIME */ +#define RTC_TIME_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TIME_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TIME_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TIME_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TIME_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TIME_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TIME_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DATE */ +#define RTC_DATE_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DATE_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DATE_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DATE_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DATE_DOW BITS(13,15) /*!< day of week units */ +#define RTC_DATE_YRU BITS(16,19) /*!< year units in BCD code */ +#define RTC_DATE_YRT BITS(20,23) /*!< year tens in BCD code */ + +/* RTC_CTL */ +#define RTC_CTL_WTCS BITS(0,2) /*!< auto wakeup timer clock selection */ +#define RTC_CTL_TSEG BIT(3) /*!< valid event edge of time-stamp */ +#define RTC_CTL_REFEN BIT(4) /*!< reference clock detection function enable */ +#define RTC_CTL_BPSHAD BIT(5) /*!< shadow registers bypass control */ +#define RTC_CTL_CS BIT(6) /*!< display format of clock system */ +#define RTC_CTL_ALRM0EN BIT(8) /*!< alarm0 function enable */ +#define RTC_CTL_ALRM1EN BIT(9) /*!< alarm1 function enable */ +#define RTC_CTL_WTEN BIT(10) /*!< auto wakeup timer function enable */ +#define RTC_CTL_TSEN BIT(11) /*!< time-stamp function enable */ +#define RTC_CTL_ALRM0IE BIT(12) /*!< RTC alarm0 interrupt enable */ +#define RTC_CTL_ALRM1IE BIT(13) /*!< RTC alarm1 interrupt enable */ +#define RTC_CTL_WTIE BIT(14) /*!< auto wakeup timer interrupt enable */ +#define RTC_CTL_TSIE BIT(15) /*!< time-stamp interrupt enable */ +#define RTC_CTL_A1H BIT(16) /*!< add 1 hour(summer time change) */ +#define RTC_CTL_S1H BIT(17) /*!< subtract 1 hour(winter time change) */ +#define RTC_CTL_DSM BIT(18) /*!< daylight saving mark */ +#define RTC_CTL_COS BIT(19) /*!< calibration output selection */ +#define RTC_CTL_OPOL BIT(20) /*!< output polarity */ +#define RTC_CTL_OS BITS(21,22) /*!< output selection */ +#define RTC_CTL_COEN BIT(23) /*!< calibration output enable */ +#define RTC_CTL_ITSEN BIT(24) /*!< internal timestamp event enable */ + +/* RTC_STAT */ +#define RTC_STAT_ALRM0WF BIT(0) /*!< alarm0 configuration can be write flag */ +#define RTC_STAT_ALRM1WF BIT(1) /*!< alarm1 configuration can be write flag */ +#define RTC_STAT_WTWF BIT(2) /*!< wakeup timer can be write flag */ +#define RTC_STAT_SOPF BIT(3) /*!< shift function operation pending flag */ +#define RTC_STAT_YCM BIT(4) /*!< year configuration mark status flag */ +#define RTC_STAT_RSYNF BIT(5) /*!< register synchronization flag */ +#define RTC_STAT_INITF BIT(6) /*!< initialization state flag */ +#define RTC_STAT_INITM BIT(7) /*!< enter initialization mode */ +#define RTC_STAT_ALRM0F BIT(8) /*!< alarm0 occurs flag */ +#define RTC_STAT_ALRM1F BIT(9) /*!< alarm1 occurs flag */ +#define RTC_STAT_WTF BIT(10) /*!< wakeup timer flag */ +#define RTC_STAT_TSF BIT(11) /*!< time-stamp flag */ +#define RTC_STAT_TSOVRF BIT(12) /*!< time-stamp overflow flag */ +#define RTC_STAT_TP0F BIT(13) /*!< RTC tamp 0 detected flag */ +#define RTC_STAT_TP1F BIT(15) /*!< RTC tamp 1 detected flag */ +#define RTC_STAT_SCPF BIT(16) /*!< Smooth calibration pending flag */ +#define RTC_STAT_ITSF BIT(17) /*!< Internal timestamp flag */ + +/* RTC_PSC */ +#define RTC_PSC_FACTOR_S BITS(0,14) /*!< synchronous prescaler factor */ +#define RTC_PSC_FACTOR_A BITS(16,22) /*!< asynchronous prescaler factor */ + +/* RTC_WUT */ +#define RTC_WUT_WTRV BITS(0,15) /*!< auto wakeup timer reloads value */ + +/* RTC_ALRMxTD */ +#define RTC_ALRMXTD_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_ALRMXTD_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_ALRMXTD_MSKS BIT(7) /*!< alarm second mask bit */ +#define RTC_ALRMXTD_MNU BITS(8,11) /*!< minutes units in BCD code */ +#define RTC_ALRMXTD_MNT BITS(12,14) /*!< minutes tens in BCD code */ +#define RTC_ALRMXTD_MSKM BIT(15) /*!< alarm minutes mask bit */ +#define RTC_ALRMXTD_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_ALRMXTD_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_ALRMXTD_PM BIT(22) /*!< AM/PM flag */ +#define RTC_ALRMXTD_MSKH BIT(23) /*!< alarm hour mask bit */ +#define RTC_ALRMXTD_DAYU BITS(24,27) /*!< date units or week day in BCD code */ +#define RTC_ALRMXTD_DAYT BITS(28,29) /*!< date tens in BCD code */ +#define RTC_ALRMXTD_DOWS BIT(30) /*!< day of week selection */ +#define RTC_ALRMXTD_MSKD BIT(31) /*!< alarm date mask bit */ + +/* RTC_WPK */ +#define RTC_WPK_WPK BITS(0,7) /*!< key for write protection */ + +/* RTC_SS */ +#define RTC_SS_SSC BITS(0,15) /*!< sub second value */ + +/* RTC_SHIFTCTL */ +#define RTC_SHIFTCTL_SFS BITS(0,14) /*!< subtract a fraction of a second */ +#define RTC_SHIFTCTL_A1S BIT(31) /*!< one second add */ + +/* RTC_TTS */ +#define RTC_TTS_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TTS_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TTS_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TTS_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TTS_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TTS_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TTS_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DTS */ +#define RTC_DTS_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DTS_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DTS_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DTS_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DTS_DOW BITS(13,15) /*!< day of week units */ + +/* RTC_SSTS */ +#define RTC_SSTS_SSC BITS(0,15) /*!< timestamp sub second units */ + +/* RTC_HRFC */ +#define RTC_HRFC_CMSK BITS(0,8) /*!< calibration mask number */ +#define RTC_HRFC_CWND16 BIT(13) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_CWND8 BIT(14) /*!< calibration window select 8 seconds */ +#define RTC_HRFC_FREQI BIT(15) /*!< increase RTC frequency by 488.5ppm */ + +/* RTC_TAMP */ +#define RTC_TAMP_TP0EN BIT(0) /*!< tamper 0 detection enable */ +#define RTC_TAMP_TP0EG BIT(1) /*!< tamper 0 event trigger edge for RTC tamp 0 input */ +#define RTC_TAMP_TPIE BIT(2) /*!< enable tamper interrupt */ +#define RTC_TAMP_TP2EN BIT(5) /*!< tamper 2 detection enable */ +#define RTC_TAMP_TP2EG BIT(6) /*!< tamper 2 event trigger edge for RTC tamp 2 input */ +#define RTC_TAMP_TPTS BIT(7) /*!< make tamper function used for timestamp function */ +#define RTC_TAMP_FREQ BITS(8,10) /*!< sample frequency of tamper event detection */ +#define RTC_TAMP_FLT BITS(11,12) /*!< RTC tamp x filter count setting */ +#define RTC_TAMP_PRCH BITS(13,14) /*!< precharge duration time of RTC tamp x */ +#define RTC_TAMP_DISPU BIT(15) /*!< RTC tamp x pull up disable bit */ + +/* RTC_ALRM0SS */ +#define RTC_ALRM0SS_SSC BITS(0,14) /*!< alarm0 sub second value */ +#define RTC_ALRM0SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* RTC_ALRM1SS */ +#define RTC_ALRM1SS_SSC BITS(0,14) /*!< alarm1 sub second value */ +#define RTC_ALRM1SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* RTC_CFG */ +#define RTC_CFG_OUT2EN BIT(1) /*!< RTC_OUT is output on PB2 or PC13 */ +#define RTC_CFG_ALRMOUTTYPE BIT(0) /*!< RTC_ALARM output is Push-pull output type */ + +/* RTC_BKP0 */ +#define RTC_BKP0_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP1 */ +#define RTC_BKP1_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP2 */ +#define RTC_BKP2_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP3 */ +#define RTC_BKP3_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP4 */ +#define RTC_BKP4_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP5 */ +#define RTC_BKP5_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP6 */ +#define RTC_BKP6_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP7 */ +#define RTC_BKP7_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP8 */ +#define RTC_BKP8_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP9 */ +#define RTC_BKP9_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP10 */ +#define RTC_BKP10_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP11 */ +#define RTC_BKP11_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP12 */ +#define RTC_BKP12_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP13 */ +#define RTC_BKP13_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP14 */ +#define RTC_BKP14_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP15 */ +#define RTC_BKP15_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP16 */ +#define RTC_BKP16_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP17 */ +#define RTC_BKP17_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP18 */ +#define RTC_BKP18_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP19 */ +#define RTC_BKP19_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP20 */ +#define RTC_BKP20_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP21 */ +#define RTC_BKP21_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP22 */ +#define RTC_BKP22_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP23 */ +#define RTC_BKP23_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP24 */ +#define RTC_BKP24_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP25 */ +#define RTC_BKP25_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP26 */ +#define RTC_BKP26_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP27 */ +#define RTC_BKP27_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP28 */ +#define RTC_BKP28_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP29 */ +#define RTC_BKP29_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP30 */ +#define RTC_BKP30_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP31 */ +#define RTC_BKP31_DATA BITS(0,31) /*!< backup domain registers */ + +/* constants definitions */ +/* structure for initialization of the RTC */ +typedef struct { + uint8_t year; /*!< RTC year value: 0x0 - 0x99(BCD format) */ + uint8_t month; /*!< RTC month value */ + uint8_t date; /*!< RTC date value: 0x1 - 0x31(BCD format) */ + uint8_t day_of_week; /*!< RTC weekday value */ + uint8_t hour; /*!< RTC hour value */ + uint8_t minute; /*!< RTC minute value: 0x0 - 0x59(BCD format) */ + uint8_t second; /*!< RTC second value: 0x0 - 0x59(BCD format) */ + uint16_t factor_asyn; /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */ + uint16_t factor_syn; /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */ + uint32_t am_pm; /*!< RTC AM/PM value */ + uint32_t display_format; /*!< RTC time notation */ +} rtc_parameter_struct; + +/* structure for RTC alarm configuration */ +typedef struct { + uint32_t alarm_mask; /*!< RTC alarm mask */ + uint32_t weekday_or_date; /*!< specify RTC alarm is on date or weekday */ + uint8_t alarm_day; /*!< RTC alarm date or weekday value*/ + uint8_t alarm_hour; /*!< RTC alarm hour value */ + uint8_t alarm_minute; /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */ + uint8_t alarm_second; /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */ + uint32_t am_pm; /*!< RTC alarm AM/PM value */ +} rtc_alarm_struct; + +/* structure for RTC time-stamp configuration */ +typedef struct { + uint8_t timestamp_month; /*!< RTC time-stamp month value */ + uint8_t timestamp_date; /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */ + uint8_t timestamp_day; /*!< RTC time-stamp weekday value */ + uint8_t timestamp_hour; /*!< RTC time-stamp hour value */ + uint8_t timestamp_minute; /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */ + uint8_t timestamp_second; /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */ + uint32_t am_pm; /*!< RTC time-stamp AM/PM value */ +} rtc_timestamp_struct; + +/* structure for RTC tamper configuration */ +typedef struct { + uint32_t tamper_source; /*!< RTC tamper source */ + uint32_t tamper_trigger; /*!< RTC tamper trigger */ + uint32_t tamper_filter; /*!< RTC tamper consecutive samples needed during a voltage level detection */ + uint32_t tamper_sample_frequency; /*!< RTC tamper sampling frequency during a voltage level detection */ + ControlStatus tamper_precharge_enable; /*!< RTC tamper precharge feature during a voltage level detection */ + uint32_t tamper_precharge_time; /*!< RTC tamper precharge duration if precharge feature is enabled */ + ControlStatus tamper_with_timestamp; /*!< RTC tamper time-stamp feature */ +} rtc_tamper_struct; + +/* time register value */ +#define TIME_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_TIME_SC bit field */ +#define GET_TIME_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TIME_SC bit field */ + +#define TIME_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_TIME_MN bit field */ +#define GET_TIME_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TIME_MN bit field */ + +#define TIME_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_TIME_HR bit field */ +#define GET_TIME_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TIME_HR bit field */ + +#define RTC_AM ((uint32_t)0x00000000U) /*!< AM format */ +#define RTC_PM RTC_TIME_PM /*!< PM format */ + +/* date register value */ +#define DATE_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_DATE_DAY bit field */ +#define GET_DATE_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DATE_DAY bit field */ + +#define DATE_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_DATE_MON bit field */ +#define GET_DATE_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DATE_MON bit field */ +#define RTC_JAN ((uint8_t)0x01U) /*!< Janurary */ +#define RTC_FEB ((uint8_t)0x02U) /*!< February */ +#define RTC_MAR ((uint8_t)0x03U) /*!< March */ +#define RTC_APR ((uint8_t)0x04U) /*!< April */ +#define RTC_MAY ((uint8_t)0x05U) /*!< May */ +#define RTC_JUN ((uint8_t)0x06U) /*!< June */ +#define RTC_JUL ((uint8_t)0x07U) /*!< July */ +#define RTC_AUG ((uint8_t)0x08U) /*!< August */ +#define RTC_SEP ((uint8_t)0x09U) /*!< September */ +#define RTC_OCT ((uint8_t)0x10U) /*!< October */ +#define RTC_NOV ((uint8_t)0x11U) /*!< November */ +#define RTC_DEC ((uint8_t)0x12U) /*!< December */ + +#define DATE_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_DATE_DOW bit field */ +#define GET_DATE_DOW(regval) GET_BITS((uint32_t)(regval),13,15) /*!< get value of RTC_DATE_DOW bit field */ +#define RTC_MONDAY ((uint8_t)0x01) /*!< monday */ +#define RTC_TUESDAY ((uint8_t)0x02) /*!< tuesday */ +#define RTC_WEDNESDAY ((uint8_t)0x03) /*!< wednesday */ +#define RTC_THURSDAY ((uint8_t)0x04) /*!< thursday */ +#define RTC_FRIDAY ((uint8_t)0x05) /*!< friday */ +#define RTC_SATURDAY ((uint8_t)0x06) /*!< saturday */ +#define RTC_SUNDAY ((uint8_t)0x07) /*!< sunday */ + +#define DATE_YR(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_DATE_YR bit field */ +#define GET_DATE_YR(regval) GET_BITS((regval),16,23) /*!< get value of RTC_DATE_YR bit field */ + +#define RTC_OUT_PC13 ((uint32_t)0x00000000U) /*!< RTC_OUT is connected to PC13 */ +#define RTC_OUT_PB2 RTC_CTL_OUT2EN /*!< RTC_OUT is connected to PB2 */ + +#define CTL_OS(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) /*!< write value to RTC_CTL_OS bit field */ +#define RTC_OS_DISABLE CTL_OS(0) /*!< disable output RTC_ALARM */ +#define RTC_OS_ALARM0 CTL_OS(1) /*!< enable alarm0 flag output */ +#define RTC_OS_ALARM1 CTL_OS(2) /*!< enable alarm1 flag output */ +#define RTC_OS_WAKEUP CTL_OS(3) /*!< enable wakeup flag output */ + +#define RTC_ITSEN_DISABLE ((uint32_t)0x00000000U) /*!< disable output RTC_ALARM */ +#define RTC_ITSEN_ENABLE RTC_CTL_ITSEN /*!< enable alarm0 flag output */ + +#define RTC_CALIBRATION_512HZ RTC_CTL_COEN /*!< calibration output of 512Hz is enable */ +#define RTC_CALIBRATION_1HZ (RTC_CTL_COEN | RTC_CTL_COS) /*!< calibration output of 1Hz is enable */ +#define RTC_ALARM0_HIGH RTC_OS_ALARM0 /*!< enable alarm0 flag output with high level */ +#define RTC_ALARM0_LOW (RTC_OS_ALARM0 | RTC_CTL_OPOL) /*!< enable alarm0 flag output with low level*/ +#define RTC_ALARM1_HIGH RTC_OS_ALARM1 /*!< enable alarm1 flag output with high level */ +#define RTC_ALARM1_LOW (RTC_OS_ALARM1 | RTC_CTL_OPOL) /*!< enable alarm1 flag output with low level*/ +#define RTC_WAKEUP_HIGH RTC_OS_WAKEUP /*!< enable wakeup flag output with high level */ +#define RTC_WAKEUP_LOW (RTC_OS_WAKEUP | RTC_CTL_OPOL) /*!< enable wakeup flag output with low level*/ + +#define RTC_24HOUR ((uint32_t)0x00000000U) /*!< 24-hour format */ +#define RTC_12HOUR RTC_CTL_CS /*!< 12-hour format */ + +#define RTC_TIMESTAMP_RISING_EDGE ((uint32_t)0x00000000U) /*!< rising edge is valid event edge for time-stamp event */ +#define RTC_TIMESTAMP_FALLING_EDGE RTC_CTL_TSEG /*!< falling edge is valid event edge for time-stamp event */ + +#define CTL_WTCS(regval) (BITS(0,2) & ((regval)<< 0)) +#define WAKEUP_RTCCK_DIV16 CTL_WTCS(0) /*!< wakeup timer clock is RTC clock divided by 16 */ +#define WAKEUP_RTCCK_DIV8 CTL_WTCS(1) /*!< wakeup timer clock is RTC clock divided by 8 */ +#define WAKEUP_RTCCK_DIV4 CTL_WTCS(2) /*!< wakeup timer clock is RTC clock divided by 4 */ +#define WAKEUP_RTCCK_DIV2 CTL_WTCS(3) /*!< wakeup timer clock is RTC clock divided by 2 */ +#define WAKEUP_CKSPRE CTL_WTCS(4) /*!< wakeup timer clock is ckapre */ +#define WAKEUP_CKSPRE_2EXP16 CTL_WTCS(6) /*!< wakeup timer clock is ckapre and wakeup timer add 2exp16 */ + +/* psc register value */ +#define PSC_FACTOR_S(regval) (BITS(0,14) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_PSC_FACTOR_S bit field */ +#define GET_PSC_FACTOR_S(regval) GET_BITS((regval),0,14) /*!< get value of RTC_PSC_FACTOR_S bit field */ + +#define PSC_FACTOR_A(regval) (BITS(16,22) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_PSC_FACTOR_A bit field */ +#define GET_PSC_FACTOR_A(regval) GET_BITS((regval),16,22) /*!< get value of RTC_PSC_FACTOR_A bit field */ + +/* alrmtd register value */ +#define ALRMTD_SC(regval) (BITS(0,6) & ((uint32_t)(regval)<< 0)) /*!< write value to RTC_ALRMTD_SC bit field */ +#define GET_ALRMTD_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_ALRMTD_SC bit field */ + +#define ALRMTD_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_ALRMTD_MN bit field */ +#define GET_ALRMTD_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_ALRMTD_MN bit field */ + +#define ALRMTD_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_ALRMTD_HR bit field */ +#define GET_ALRMTD_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_ALRMTD_HR bit field */ + +#define ALRMTD_DAY(regval) (BITS(24,29) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMTD_DAY bit field */ +#define GET_ALRMTD_DAY(regval) GET_BITS((regval),24,29) /*!< get value of RTC_ALRMTD_DAY bit field */ + +#define RTC_ALARM_NONE_MASK ((uint32_t)0x00000000U) /*!< alarm none mask */ +#define RTC_ALARM_DATE_MASK RTC_ALRMXTD_MSKD /*!< alarm date mask */ +#define RTC_ALARM_HOUR_MASK RTC_ALRMXTD_MSKH /*!< alarm hour mask */ +#define RTC_ALARM_MINUTE_MASK RTC_ALRMXTD_MSKM /*!< alarm minute mask */ +#define RTC_ALARM_SECOND_MASK RTC_ALRMXTD_MSKS /*!< alarm second mask */ +#define RTC_ALARM_ALL_MASK (RTC_ALRMXTD_MSKD|RTC_ALRMXTD_MSKH|RTC_ALRMXTD_MSKM|RTC_ALRMXTD_MSKS) /*!< alarm all mask */ + +#define RTC_ALARM_DATE_SELECTED ((uint32_t)0x00000000U) /*!< alarm date format selected */ +#define RTC_ALARM_WEEKDAY_SELECTED RTC_ALRMXTD_DOWS /*!< alarm weekday format selected */ + +/* wpk register value */ +#define WPK_WPK(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_WPK_WPK bit field */ + +/* ss register value */ +#define SS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_SS_SSC bit field */ + +/* shiftctl register value */ +#define SHIFTCTL_SFS(regval) (BITS(0,14) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_SHIFTCTL_SFS bit field */ + +#define RTC_SHIFT_ADD1S_RESET ((uint32_t)0x00000000U) /*!< not add 1 second */ +#define RTC_SHIFT_ADD1S_SET RTC_SHIFTCTL_A1S /*!< add one second to the clock */ + +/* tts register value */ +#define TTS_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_TTS_SC bit field */ +#define GET_TTS_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TTS_SC bit field */ + +#define TTS_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_TTS_MN bit field */ +#define GET_TTS_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TTS_MN bit field */ + +#define TTS_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_TTS_HR bit field */ +#define GET_TTS_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TTS_HR bit field */ + +/* dts register value */ +#define DTS_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_DTS_DAY bit field */ +#define GET_DTS_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DTS_DAY bit field */ + +#define DTS_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_DTS_MON bit field */ +#define GET_DTS_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DTS_MON bit field */ + +#define DTS_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_DTS_DOW bit field */ +#define GET_DTS_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DTS_DOW bit field */ + +/* ssts register value */ +#define SSTS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_SSTS_SSC bit field */ + +/* hrfc register value */ +#define HRFC_CMSK(regval) (BITS(0,8) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_HRFC_CMSK bit field */ + +#define RTC_CALIBRATION_WINDOW_32S ((uint32_t)0x00000000U) /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_16S RTC_HRFC_CWND16 /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_8S RTC_HRFC_CWND8 /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */ + +#define RTC_CALIBRATION_PLUS_SET RTC_HRFC_FREQI /*!< increase RTC frequency by 488.5ppm */ +#define RTC_CALIBRATION_PLUS_RESET ((uint32_t)0x00000000U) /*!< no effect */ + +#define TAMP_PRCH(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_TAMP_PRCH bit field */ +#define RTC_PRCH_1C TAMP_PRCH(0) /*!< 1 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_2C TAMP_PRCH(1) /*!< 2 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_4C TAMP_PRCH(2) /*!< 4 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_8C TAMP_PRCH(3) /*!< 8 RTC clock prechagre time before each sampling */ + +#define TAMP_FLT(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) /*!< write value to RTC_TAMP_FLT bit field */ +#define RTC_FLT_EDGE TAMP_FLT(0) /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */ +#define RTC_FLT_2S TAMP_FLT(1) /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event */ +#define RTC_FLT_4S TAMP_FLT(2) /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */ +#define RTC_FLT_8S TAMP_FLT(3) /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event */ + +#define TAMP_FREQ(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_TAMP_FREQ bit field */ +#define RTC_FREQ_DIV32768 TAMP_FREQ(0) /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV16384 TAMP_FREQ(1) /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV8192 TAMP_FREQ(2) /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV4096 TAMP_FREQ(3) /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV2048 TAMP_FREQ(4) /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV1024 TAMP_FREQ(5) /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV512 TAMP_FREQ(6) /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV256 TAMP_FREQ(7) /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */ + +#define RTC_TAMPER0 RTC_TAMP_TP0EN /*!< tamper 0 detection enable */ +#define RTC_TAMPER2 RTC_TAMP_TP2EN /*!< tamper 2 detection enable */ + +#define RTC_TAMPER_TRIGGER_EDGE_RISING ((uint32_t)0x00000000U) /*!< tamper detection is in rising edge mode */ +#define RTC_TAMPER_TRIGGER_EDGE_FALLING RTC_TAMP_TP0EG /*!< tamper detection is in falling edge mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_LOW ((uint32_t)0x00000000U) /*!< tamper detection is in low level mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_HIGH RTC_TAMP_TP0EG /*!< tamper detection is in high level mode */ + +#define RTC_TAMPER_TRIGGER_POS ((uint32_t)0x00000001U) /* shift position of trigger relative to source */ + +#define RTC_ALARM_OUTPUT_OD ((uint32_t)0x00000000U) /*!< RTC alarm output open-drain mode */ +#define RTC_ALARM_OUTPUT_PP RTC_CTL_ALRMOUTTYPE /*!< RTC alarm output push-pull mode */ + +/* alrm0ss register value */ +#define ALRMXSS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0)) /*!< write value to RTC_ALRMXSS_SSC bit field */ + +#define ALRMXSS_MSKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMXSS_MSKSSC bit field */ +#define RTC_MSKSSC_0_14 ALRMXSS_MSKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MSKSSC_1_14 ALRMXSS_MSKSSC(1) /*!< mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared */ +#define RTC_MSKSSC_2_14 ALRMXSS_MSKSSC(2) /*!< mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared */ +#define RTC_MSKSSC_3_14 ALRMXSS_MSKSSC(3) /*!< mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared */ +#define RTC_MSKSSC_4_14 ALRMXSS_MSKSSC(4) /*!< mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared */ +#define RTC_MSKSSC_5_14 ALRMXSS_MSKSSC(5) /*!< mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared */ +#define RTC_MSKSSC_6_14 ALRMXSS_MSKSSC(6) /*!< mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared */ +#define RTC_MSKSSC_7_14 ALRMXSS_MSKSSC(7) /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */ +#define RTC_MSKSSC_8_14 ALRMXSS_MSKSSC(8) /*!< mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared */ +#define RTC_MSKSSC_9_14 ALRMXSS_MSKSSC(9) /*!< mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared */ +#define RTC_MSKSSC_10_14 ALRMXSS_MSKSSC(10) /*!< mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared */ +#define RTC_MSKSSC_11_14 ALRMXSS_MSKSSC(11) /*!< mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared */ +#define RTC_MSKSSC_12_14 ALRMXSS_MSKSSC(12) /*!< mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared */ +#define RTC_MSKSSC_13_14 ALRMXSS_MSKSSC(13) /*!< mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared */ +#define RTC_MSKSSC_14 ALRMXSS_MSKSSC(14) /*!< mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared */ +#define RTC_MSKSSC_NONE ALRMXSS_MSKSSC(15) /*!< mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared */ + +/* RTC interrupt source */ +#define RTC_INT_TIMESTAMP RTC_CTL_TSIE /*!< time-stamp interrupt enable */ +#define RTC_INT_ALARM0 RTC_CTL_ALRM0IE /*!< RTC alarm0 interrupt enable */ +#define RTC_INT_ALARM1 RTC_CTL_ALRM1IE /*!< RTC alarm1 interrupt enable */ +#define RTC_INT_TAMP_ALL RTC_TAMP_TPIE /*!< tamper detection interrupt enable */ +#define RTC_INT_WAKEUP RTC_CTL_WTIE /*!< RTC wakeup timer interrupt enable */ + +/* write protect key */ +#define RTC_UNLOCK_KEY1 ((uint8_t)0xCAU) /*!< RTC unlock key1 */ +#define RTC_UNLOCK_KEY2 ((uint8_t)0x53U) /*!< RTC unlock key2 */ +#define RTC_LOCK_KEY ((uint8_t)0xFFU) /*!< RTC lock key */ + +/* registers reset value */ +#define RTC_REGISTER_RESET ((uint32_t)0x00000000U) /*!< RTC common register reset value */ +#define RTC_DATE_RESET ((uint32_t)0x00002101U) /*!< RTC_DATE register reset value */ +#define RTC_STAT_RESET ((uint32_t)0x00000007U) /*!< RTC_STAT register reset value */ +#define RTC_PSC_RESET ((uint32_t)0x007F00FFU) /*!< RTC_PSC register reset value */ +#define RTC_WUT_RESET ((uint32_t)0x0000FFFFU) /*!< RTC_WUT register reset value */ + +/* RTC alarm */ +#define RTC_ALARM0 ((uint8_t)0x01U) /*!< RTC alarm 0 */ +#define RTC_ALARM1 ((uint8_t)0x02U) /*!< RTC alarm 1 */ + +/* RTC flag */ +#define RTC_FLAG_ALARM0W RTC_STAT_ALRM0WF /*!< alarm0 configuration can be write flag */ +#define RTC_FLAG_ALARM1W RTC_STAT_ALRM1WF /*!< alarm1 configuration can be write flag */ +#define RTC_FLAG_WTW RTC_STAT_WTWF /*!< wakeup timer can be write flag */ +#define RTC_FLAG_SOP RTC_STAT_SOPF /*!< shift function operation pending flag */ +#define RTC_FLAG_YCM RTC_STAT_YCM /*!< year parameter configured event flag */ +#define RTC_FLAG_RSYN RTC_STAT_RSYNF /*!< registers synchronized flag */ +#define RTC_FLAG_INIT RTC_STAT_INITF /*!< init mode event flag */ +#define RTC_FLAG_SCP RTC_STAT_SOPF /*!< smooth calibration pending flag */ +#define RTC_FLAG_ALARM0 RTC_STAT_ALRM0F /*!< alarm event flag */ +#define RTC_FLAG_ALARM1 RTC_STAT_ALRM1F /*!< alarm1 occurs flag */ +#define RTC_FLAG_WT RTC_STAT_WTF /*!< wakeup timer occurs flag */ +#define RTC_FLAG_TS RTC_STAT_TSF /*!< time-stamp flag */ +#define RTC_FLAG_TSOVR RTC_STAT_TSOVRF /*!< time-stamp overflow flag */ +#define RTC_FLAG_TP0 RTC_STAT_TP0F /*!< RTC tamper 0 detected flag */ +#define RTC_FLAG_TP2 RTC_STAT_TP2F /*!< RTC tamper 2 detected flag */ + +/* function declarations */ +/* initialization and configuration functions */ +/* reset most of the RTC registers */ +ErrStatus rtc_deinit(void); +/* initialize RTC registers */ +ErrStatus rtc_init(rtc_parameter_struct *rtc_initpara_struct); +/* enter RTC init mode */ +ErrStatus rtc_init_mode_enter(void); +/* exit RTC init mode */ +void rtc_init_mode_exit(void); +/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */ +ErrStatus rtc_register_sync_wait(void); + +/* get current time and date */ +void rtc_current_time_get(rtc_parameter_struct *rtc_initpara_struct); +/* get current subsecond value */ +uint32_t rtc_subsecond_get(void); + +/* alarm configuration functions */ +/* configure RTC alarm */ +void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct *rtc_alarm_time); +/* configure subsecond of RTC alarm */ +void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint32_t subsecond); +/* get RTC alarm */ +void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct *rtc_alarm_time); +/* get RTC alarm subsecond */ +uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm); +/* enable RTC alarm */ +void rtc_alarm_enable(uint8_t rtc_alarm); +/* disable RTC alarm */ +ErrStatus rtc_alarm_disable(uint8_t rtc_alarm); + +/* timestamp and tamper configuration functions */ +/* enable RTC time-stamp */ +void rtc_timestamp_enable(uint32_t edge); +/* disable RTC time-stamp */ +void rtc_timestamp_disable(void); +/* get RTC timestamp time and date */ +void rtc_timestamp_get(rtc_timestamp_struct *rtc_timestamp); +/* configure RTC time-stamp internal event */ +void rtc_timestamp_internalevent_config(uint32_t mode); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); + +/* enable RTC tamper */ +void rtc_tamper_enable(rtc_tamper_struct *rtc_tamper); +/* disable RTC tamper */ +void rtc_tamper_disable(uint32_t source); + +/* select the RTC output pin */ +void rtc_output_pin_select(uint32_t outputpin); +/* configure RTC alarm output source */ +void rtc_alarm_output_config(uint32_t source, uint32_t mode); +/* configure RTC calibration output source */ +void rtc_calibration_output_config(uint32_t source); + +/* adjust the daylight saving time by adding or substracting one hour from the current time */ +void rtc_hour_adjust(uint32_t operation); +/* adjust RTC second or subsecond value of current time */ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus); + +/* enable RTC bypass shadow registers function */ +void rtc_bypass_shadow_enable(void); +/* disable RTC bypass shadow registers function */ +void rtc_bypass_shadow_disable(void); + +/* enable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_enable(void); +/* disable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_disable(void); + +/* enable RTC wakeup timer */ +void rtc_wakeup_enable(void); +/* disable RTC wakeup timer */ +ErrStatus rtc_wakeup_disable(void); +/* set auto wakeup timer clock */ +ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock); +/* set auto wakeup timer value */ +ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer); +/* get auto wakeup timer value */ +uint16_t rtc_wakeup_timer_get(void); + +/* configure RTC smooth calibration */ +ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disable specified RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); +/* check specified flag */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear specified flag */ +void rtc_flag_clear(uint32_t flag); + +#endif /* GD32H7XX_RTC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtdec.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtdec.h new file mode 100644 index 0000000000..6c6efc58ae --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_rtdec.h @@ -0,0 +1,166 @@ +/*! + \file gd32h7xx_rtdec.h + \brief definitions for the RTDEC + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_RTDEC_H +#define GD32H7XX_RTDEC_H + +#include "gd32h7xx.h" + +/* RTDEC definitions */ +#define RTDEC0 RTDEC_BASE /*!< RTDEC0 bsae address */ +#define RTDEC1 (RTDEC_BASE + 0x00000400U) /*!< RTDEC1 bsae address */ +#define RTDEC_AREA0 ((uint8_t)0x00U) /*!< RTDEC area0 */ +#define RTDEC_AREA1 ((uint8_t)0x01U) /*!< RTDEC area1 */ +#define RTDEC_AREA2 ((uint8_t)0x02U) /*!< RTDEC area2 */ +#define RTDEC_AREA3 ((uint8_t)0x03U) /*!< RTDEC area3 */ +#define RTDEC_ARE(rtdecx, rtdec_areax) ((rtdecx) + 0x00000030U * (rtdec_areax)) + +/* registers definitions */ +#define RTDEC_ARE_CFG(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x00000020U) /*!< area configuration register */ +#define RTDEC_ARE_SADDR(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x00000024U) /*!< area start address register */ +#define RTDEC_ARE_EADDR(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x00000028U) /*!< area end address register */ +#define RTDEC_ARE_NONCE0(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x0000002CU) /*!< area random number register 0 */ +#define RTDEC_ARE_NONCE1(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x00000030U) /*!< area random number register 1 */ +#define RTDEC_ARE_KEY0(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x00000034U) /*!< area key register 0 */ +#define RTDEC_ARE_KEY1(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x00000038U) /*!< area key register 1 */ +#define RTDEC_ARE_KEY2(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x0000003CU) /*!< area key register 2 */ +#define RTDEC_ARE_KEY3(rtdecx, rtdec_areax) REG32(RTDEC_ARE((rtdecx), (rtdec_areax)) + 0x00000040U) /*!< area key register 3 */ +#define RTDEC_INTF(rtdecx) REG32((rtdecx) + 0x00000300U) /*!< interrupt flag register */ +#define RTDEC_INTC(rtdecx) REG32((rtdecx) + 0x00000304U) /*!< interrupt flag clear register */ +#define RTDEC_INTEN(rtdecx) REG32((rtdecx) + 0x00000308U) /*!< interrupt enable register */ + +/* bits definitions */ +/* RTDEC_AREx_CFG */ +#define RTDEC_ARE_EN BIT(0) /*!< area real-time decryption enable bit */ +#define RTDEC_ARE_CFG_LK BIT(1) /*!< area configure lock bit */ +#define RTDEC_ARE_K_LK BIT(2) /*!< area key lock bit */ +#define RTDEC_MODE BITS(4, 5) /*!< RTDEC mode bits */ +#define RTDEC_ARE_K_CRC BITS(8, 15) /*!< 8-bit CRC of area key bits */ +#define RTDEC_ARE_FMVER BITS(16, 31) /*!< area firmware version bits */ + +/* RTDEC_AREx_SADDR */ +#define RTDEC_ARE_SADDR_SADDR BITS(0, 31) /*!< area start address bits */ + +/* RTDEC_AREx_EADDR */ +#define RTDEC_ARE_EADDR_EADDR BITS(0, 31) /*!< area end address bits */ + +/* RTDEC_AREx_NONCE */ +#define RTDEC_ARE_NONCE_NONCE BITS(0, 31) /*!< area random number address bits */ + +/* RTDEC_AREx_KEY */ +#define RTDEC_ARE_KEY_KEY BITS(0, 31) /*!< area key bits */ + +/* RTDEC_INTF */ +#define RTDEC_SECEF BIT(0) /*!< security error interrupt flag */ +#define RTDEC_ECONEF BIT(1) /*!< execute-only or execute-never error interrupt flag */ +#define RTDEC_KEF BIT(2) /*!< key error interrupt flag */ + +/* RTDEC_INTEN */ +#define RTDEC_SECEIE BIT(0) /*!< enable bit for security error interrupt */ +#define RTDEC_ECONEIE BIT(1) /*!< enable bit for execute-only or execute-never error interrupt */ +#define RTDEC_KEIE BIT(2) /*!< enable bit for key error interrupt */ + +/* constants definitions */ +/* RTDEC modes definitions */ +#define RTDEC_MODE_SEL(regval) (RTDEC_MODE & ((uint32_t)(regval) << 4U)) +#define RTDEC_MODE_CODE_ACCESS RTDEC_MODE_SEL(0) /*!< only code accesses are decrypted */ +#define RTDEC_MODE_DATA_ACCESS RTDEC_MODE_SEL(1) /*!< only data accesses are decrypted */ +#define RTDEC_MODE_BOTH_ACCESS RTDEC_MODE_SEL(2) /*!< all read accesses are decrypted (code or data) */ + +/* RTDEC interrupt flag definitions */ +#define RTDEC_INT_FLAG_SEC_ERROR RTDEC_SECEF /*!< bit constant of security error interrupt flag */ +#define RTDEC_INT_FLAG_MODE_ERROR RTDEC_ECONEF /*!< bit constant of execute-only or execute-never error interrupt flag */ +#define RTDEC_INT_FLAG_KEY_ERROR RTDEC_KEF /*!< bit constant of key error interrupt flag */ + +/* RTDEC interrupt enable definitions */ +#define RTDEC_INT_SEC RTDEC_SECEIE /*!< enable bit for security error interrupt */ +#define RTDEC_INT_MODE RTDEC_ECONEIE /*!< enable bit for execute-only or execute-never error interrupt */ +#define RTDEC_INT_KEY RTDEC_KEIE /*!< enable bit for key error interrupt */ + +/* RTDEC flag definitions */ +#define RTDEC_FLAG_SEC_ERROR RTDEC_SECEF /*!< bit constant of security error flag */ +#define RTDEC_FLAG_MODE_ERROR RTDEC_ECONEF /*!< bit constant of execute-only or execute-never error flag */ +#define RTDEC_FLAG_KEY_ERROR RTDEC_KEF /*!< bit constant of key error flag */ + +/* structure for rtdec initialization parameter */ +typedef struct { + uint8_t access_mode; /*!< area access mode */ + uint8_t key_crc; /*!< key CRC value */ + uint16_t fw_version; /*!< area firmware version */ + uint32_t *key; /*!< area key bits */ + uint32_t *nonce; /*!< area nonce bits */ + uint32_t start_addr; /*!< area start address */ + uint32_t end_addr; /*!< area end address */ +} rtdec_parameter_struct; + +/* function declarations */ +/* initialization functions */ +/* reset RTDEC */ +void rtdec_deinit(uint32_t rtdec_periph); +/* initialize the parameters of RTDEC struct with default values */ +void rtdec_struct_para_init(rtdec_parameter_struct* rtdec_struct); +/* initialize RTDEC */ +ErrStatus rtdec_init(uint32_t rtdec_periph, uint32_t rtdec_area, rtdec_parameter_struct *rtdec_struct); +/* configure RTDEC area data attribute */ +void rtdec_config(uint32_t rtdec_periph, uint32_t rtdec_area, uint8_t access_mode, uint16_t firmware_version); +/* configure RTDEC key or register lock */ +void rtdec_lock(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t lock_type); +/* initialize RTDEC area address */ +void rtdec_addr_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t saddr, uint32_t eaddr); +/* initialize RTDEC nonce, nonce follows little endian format */ +void rtdec_nonce_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t *nonce); +/* initialize RTDEC key, key follows little endian format */ +void rtdec_key_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t *key); +/* get CRC value of RTDEC key data */ +uint8_t rtdec_key_crc_get(uint32_t rtdec_periph, uint32_t rtdec_area); +/* enable RTDEC area */ +void rtdec_enable(uint32_t rtdec_periph, uint32_t rtdec_area); +/* disable RTDEC area */ +void rtdec_disable(uint32_t rtdec_periph, uint32_t rtdec_area); + +/* flag & interrupt functions */ +/* get RTDEC error flag */ +FlagStatus rtdec_flag_get(uint32_t rtdec_periph, uint32_t flag); +/* clear RTDEC error flag */ +void rtdec_flag_clear(uint32_t rtdec_periph, uint32_t flag); +/* enable RTDEC interrupt */ +void rtdec_interrupt_enable(uint32_t rtdec_periph, uint32_t interrupt); +/* disable RTDEC interrupt */ +void rtdec_interrupt_disable(uint32_t rtdec_periph, uint32_t interrupt); +/* get RTDEC interrupt flag */ +FlagStatus rtdec_interrupt_flag_get(uint32_t rtdec_periph, uint32_t int_flag); +/* clear RTDEC interrupt flag */ +void rtdec_interrupt_flag_clear(uint32_t rtdec_periph, uint32_t int_flag); + +#endif /* GD32H7XX_RTDEC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sai.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sai.h new file mode 100644 index 0000000000..c9d1772af8 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sai.h @@ -0,0 +1,541 @@ +/*! + \file gd32h7xx_sai.h + \brief definitions for the SAI + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_SAI_H +#define GD32H7XX_SAI_H + +#include "gd32h7xx.h" + +/* SAI definitions */ +#define SAI0 (SAI_BASE + 0x00000000U) /*!< SAI0 base address */ +#define SAI1 (SAI_BASE + 0x00000400U) /*!< SAI1 base address */ +#define SAI2 (SAI_BASE + 0x00000800U) /*!< SAI2 base address */ + +/* registers definitions */ +#define SAI_SYNCFG(saix) REG32((saix) + 0x00000000U) /*!< SAI synchronize configuration register */ +#define SAI_B0CFG0(saix) REG32((saix) + 0x00000004U) /*!< SAI block 0 configuration register0 */ +#define SAI_B0CFG1(saix) REG32((saix) + 0x00000008U) /*!< SAI block 0 configuration register1 */ +#define SAI_B0FCFG(saix) REG32((saix) + 0x0000000CU) /*!< SAI block 0 frame configuration register */ +#define SAI_B0SCFG(saix) REG32((saix) + 0x00000010U) /*!< SAI block 0 slot configuration register */ +#define SAI_B0INTEN(saix) REG32((saix) + 0x00000014U) /*!< SAI block 0 interrupt enable register */ +#define SAI_B0STAT(saix) REG32((saix) + 0x00000018U) /*!< SAI block 0 status register */ +#define SAI_B0INTC(saix) REG32((saix) + 0x0000001CU) /*!< SAI block 0 interrupt flag clear register */ +#define SAI_B0DATA(saix) REG32((saix) + 0x00000020U) /*!< SAI block 0 data register */ +#define SAI_B1CFG0(saix) REG32((saix) + 0x00000024U) /*!< SAI block 1 configuration register0 */ +#define SAI_B1CFG1(saix) REG32((saix) + 0x00000028U) /*!< SAI block 1 configuration register1 */ +#define SAI_B1FCFG(saix) REG32((saix) + 0x0000002CU) /*!< SAI block 1 frame configuration register */ +#define SAI_B1SCFG(saix) REG32((saix) + 0x00000030U) /*!< SAI block 1 slot configuration register */ +#define SAI_B1INTEN(saix) REG32((saix) + 0x00000034U) /*!< SAI block 1 interrupt enable register */ +#define SAI_B1STAT(saix) REG32((saix) + 0x00000038U) /*!< SAI block 1 status register */ +#define SAI_B1INTC(saix) REG32((saix) + 0x0000003CU) /*!< SAI block 1 interrupt flag clear register */ +#define SAI_B1DATA(saix) REG32((saix) + 0x00000040U) /*!< SAI block 1 data register */ +#define SAI_PDMCTL(saix) REG32((saix) + 0x00000044U) /*!< SAI PDM control register */ +#define SAI_PDMCFG(saix) REG32((saix) + 0x00000048U) /*!< SAI PDM configuration register */ + +#define SAI_CFG0(saix, blocky) REG32(((saix) + 0x00000004U) + 0x20U * (blocky)) /*!< SAI block configuration register0 */ +#define SAI_CFG1(saix, blocky) REG32(((saix) + 0x00000008U) + 0x20U * (blocky)) /*!< SAI block configuration register1 */ +#define SAI_FCFG(saix, blocky) REG32(((saix) + 0x0000000CU) + 0x20U * (blocky)) /*!< SAI block frame configuration register */ +#define SAI_SCFG(saix, blocky) REG32(((saix) + 0x00000010U) + 0x20U * (blocky)) /*!< SAI block slot configuration register */ +#define SAI_INTEN(saix, blocky) REG32(((saix) + 0x00000014U) + 0x20U * (blocky)) /*!< SAI block interrupt enable register */ +#define SAI_STAT(saix, blocky) REG32(((saix) + 0x00000018U) + 0x20U * (blocky)) /*!< SAI block status register */ +#define SAI_INTC(saix, blocky) REG32(((saix) + 0x0000001CU) + 0x20U * (blocky)) /*!< SAI block interrupt flag clear register */ +#define SAI_DATA(saix, blocky) REG32(((saix) + 0x00000020U) + 0x20U * (blocky)) /*!< SAI block data register */ + +/* bits definitions */ +/* SAI_SYNCFG */ +#define SAI_SYNCFG_SYNI BITS(0,1) /*!< synchronization inputs */ +#define SAI_SYNCFG_SYNO BITS(4,5) /*!< synchronization outputs */ + +/* SAI_CFG0 */ +#define SAI_CFG0_OPTMOD BITS(0,1) /*!< operating mode */ +#define SAI_CFG0_PROT BITS(2,3) /*!< protocol selection */ +#define SAI_CFG0_DATAWD BITS(5,7) /*!< data width */ +#define SAI_CFG0_SHIFTDIR BIT(8) /*!< shift direction */ +#define SAI_CFG0_SAMPEDGE BIT(9) /*!< sampling clock edge */ +#define SAI_CFG0_SYNCMOD BITS(10,11) /*!< synchronization mode */ +#define SAI_CFG0_MONO BIT(12) /*!< stereo and mono mode selection */ +#define SAI_CFG0_ODRIV BIT(13) /*!< output drive */ +#define SAI_CFG0_SAIEN BIT(16) /*!< sai sub-block enable */ +#define SAI_CFG0_DMAEN BIT(17) /*!< DMA enable */ +#define SAI_CFG0_BYPASS BIT(19) /*!< clock divider logic bypass */ +#define SAI_CFG0_MDIV BITS(20,25) /*!< master clock divider ratio */ +#define SAI_CFG0_MOSPR BIT(26) /*!< the master clock oversampling rate */ +#define SAI_CFG0_MCLKEN BIT(27) /*!< the master clock enable */ + +/* SAI_CFG1 */ +#define SAI_CFG1_FFTH BITS(0,2) /*!< FIFO threshold */ +#define SAI_CFG1_FLUSH BIT(3) /*!< FIFO flush */ +#define SAI_CFG1_SDOM BIT(4) /*!< serial data output management */ +#define SAI_CFG1_MT BIT(5) /*!< mute mode on */ +#define SAI_CFG1_MTVAL BIT(6) /*!< mute value */ +#define SAI_CFG1_MTFCNT BITS(7,12) /*!< mute frame count */ +#define SAI_CFG1_CPLMOD BIT(13) /*!< complement mode */ +#define SAI_CFG1_CPAMOD BITS(14,15) /*!< compander mode */ + +/* SAI_FCFG */ +#define SAI_FCFG_FWD BITS(0,7) /*!< frame width */ +#define SAI_FCFG_FSAWD BITS(8,14) /*!< frame synchronization active width */ +#define SAI_FCFG_FSFUNC BIT(16) /*!< frame synchronization function */ +#define SAI_FCFG_FSPL BIT(17) /*!< Frame synchronization active polarity */ +#define SAI_FCFG_FSOST BIT(18) /*!< frame synchronization offset */ + +/* SAI_SCFG */ +#define SAI_SCFG_DATAOST BITS(0,4) /*!< data offset */ +#define SAI_SCFG_SLOTWD BITS(6,7) /*!< slot width */ +#define SAI_SCFG_SLOTNUM BITS(8,11) /*!< slot number within frame */ +#define SAI_SCFG_SLOTAV BITS(16,31) /*!< slot activation vector */ + +/* SAI_INTEN */ +#define SAI_INTEN_OUERRIE BIT(0) /*!< FIFO overrun or underrun interrupt enable */ +#define SAI_INTEN_MTDETIE BIT(1) /*!< mute detection interrupt enable */ +#define SAI_INTEN_ERRCKIE BIT(2) /*!< error clock interrupt enable */ +#define SAI_INTEN_FFREQIE BIT(3) /*!< FIFO request interrupt enable */ +#define SAI_INTEN_ACNRDYIE BIT(4) /*!< audio codec not ready interrupt enable */ +#define SAI_INTEN_FSADETIE BIT(5) /*!< frame synchronization advanced detection interrupt enable */ +#define SAI_INTEN_FSPDETIE BIT(6) /*!< frame synchronization postpone detection interrupt enable */ + +/* SAI_STAT */ +#define SAI_STAT_OUERR BIT(0) /*!< FIFO overrun or underrun */ +#define SAI_STAT_MTDET BIT(1) /*!< mute detection */ +#define SAI_STAT_ERRCK BIT(2) /*!< error clock */ +#define SAI_STAT_FFREQ BIT(3) /*!< FIFO request */ +#define SAI_STAT_ACNRDY BIT(4) /*!< audio codec not ready */ +#define SAI_STAT_FSADET BIT(5) /*!< frame synchronization advanced detection */ +#define SAI_STAT_FSPDET BIT(6) /*!< frame synchronization postpone detection */ +#define SAI_STAT_FFSTAT BITS(16,18) /*!< FIFO status */ + +/* SAI_INTC */ +#define SAI_INTC_OUERRC BIT(0) /*!< FIFO overrun or underrun interrupt clear */ +#define SAI_INTC_MTDETC BIT(1) /*!< mute detection interrupt clear */ +#define SAI_INTC_ERRCKC BIT(2) /*!< error clock interrupt clear */ +#define SAI_INTC_ACNRDYC BIT(4) /*!< audio codec not ready interrupt clear */ +#define SAI_INTC_FSADETC BIT(5) /*!< frame synchronization advanced detection interrupt clear */ +#define SAI_INTC_FSPDETC BIT(6) /*!< frame synchronization postpone detection interrupt clear */ + +/* SAI_DATA */ +#define SAI_DATA_DATA BITS(0,31) /*!< transfer data or receive data */ + +/* SAI_PDMCTL */ +#define SAI_PDMCTL_PDMEN BIT(0) /*!< PDM enable */ +#define SAI_PDMCTL_MICNUMSEL BITS(4,5) /*!< microphones number selected */ +#define SAI_PDMCTL_CLKL0EN BIT(8) /*!< PDM clock line 0 enable */ +#define SAI_PDMCTL_CLKL1EN BIT(9) /*!< PDM clock line 1 enable */ + +/* SAI_PDMCFG */ +#define SAI_PDMCFG_DPL0 BITS(0,2) /*!< the 0 group of left channel microphone data flow delay period */ +#define SAI_PDMCTL_DPR0 BITS(4,6) /*!< the 0 group of right channel microphone data flow delay period */ +#define SAI_PDMCFG_DPL1 BITS(8,10) /*!< the 1st group of left channel microphone data flow delay period */ +#define SAI_PDMCTL_DPR1 BITS(12,14) /*!< the 1st group of right channel microphone data flow delay period */ +#define SAI_PDMCFG_DPL2 BITS(16,18) /*!< the 2nd group of left channel microphone data flow delay period */ +#define SAI_PDMCTL_DPR2 BITS(20,22) /*!< the 2nd group of right channel microphone data flow delay period */ +#define SAI_PDMCFG_DPL3 BITS(24,26) /*!< the 3rd group of left channel microphone data flow delay period */ +#define SAI_PDMCTL_DPR3 BITS(28,30) /*!< the 3rd group of right channel microphone data flow delay period */ + +/* constants definitions */ +/* SAI initialize parameter struct definitions */ +typedef struct { + uint32_t operating_mode; /*!< operating mode */ + uint32_t protocol; /*!< protocol selection */ + uint32_t data_width; /*!< data width */ + uint32_t shift_dir; /*!< shift direction */ + uint32_t sample_edge; /*!< sampling clock edge */ + uint32_t sync_mode; /*!< synchronization mode */ + uint32_t output_drive; /*!< output drive */ + uint32_t clk_div_bypass; /*!< clock divider logic bypass */ + uint32_t mclk_div; /*!< master clock divider ratio */ + uint32_t mclk_oversampling; /*!< the master clock oversampling rate */ + uint32_t mclk_enable; /*!< the master clock enable */ + uint32_t fifo_threshold; /*!< FIFO threshold */ +} sai_parameter_struct; + +/* SAI frame initialize parameter struct definitions */ +typedef struct { + uint32_t frame_width; /*!< frame width */ + uint32_t frame_sync_width; /*!< frame synchronization active width */ + uint32_t frame_sync_function; /*!< frame synchronization function */ + uint32_t frame_sync_polarity; /*!< frame synchronization active polarity */ + uint32_t frame_sync_offset; /*!< frame synchronization offset */ +} sai_frame_parameter_struct; + +/* SAI slot initialize parameter struct definitions */ +typedef struct { + uint32_t slot_number; /*!< slot number */ + uint32_t slot_width; /*!< slot width */ + uint32_t data_offset; /*!< data offset */ + uint32_t slot_active; /*!< slot activation vector */ +} sai_slot_parameter_struct; + +/* SAI FIFO status */ +typedef enum { + FIFO_EMPTY = 0U, /*!< empty */ + FIFO_EMPTY_TO_1_4_FULL, /*!< empty < fifo_level <= 1/4_full. */ + FIFO_1_4_FULL_TO_1_2_FULL, /*!< 1/4_full < fifo_level <= 1/2_full. */ + FIFO_1_2_FULL_TO_3_4_FULL, /*!< 1/2_full < fifo_level <= 3/4_full. */ + FIFO_3_4_FULL_TO_FULL, /*!< 3/4_full < fifo_level < full */ + FIFO_FULL /*!< full */ +} sai_fifo_state_enum; + +/* SAI synchronization output definitions */ +#define SYNCFG_SYNO(regval) (BITS(4,5)&((uint32_t)(regval) << 4U)) +#define SAI_SYNCOUTPUT_OFF SYNCFG_SYNO(0) /*!< no synchronization output signals */ +#define SAI_SYNCOUTPUT_BLOCK0 SYNCFG_SYNO(1) /*!< block 0 used for further synchronization for others SAI */ +#define SAI_SYNCOUTPUT_BLOCK1 SYNCFG_SYNO(2) /*!< block 1 used for further synchronization for others SAI */ + +/* SAI synchronization input definitions */ +#define SYNCFG_SYNI(regval) (BITS(0,1)&((uint32_t)(regval) << 0U)) +#define SAI_SYNCINPUT_SAI0 SYNCFG_SYNI(0) /*!< SAI 1 / 2 selects the synchronization coming from SAI 0 */ +#define SAI_SYNCINPUT_SAI1 SYNCFG_SYNI(1) /*!< SAI 0 / 2 selects the synchronization coming from SAI 1 */ +#define SAI_SYNCINPUT_SAI2 SYNCFG_SYNI(2) /*!< SAI 0 / 1 selects the synchronization coming from SAI 2 */ + +/* SAI master clock enable */ +#define SAI_MCLK_DISABLE ((uint32_t)0x00000000U) /*!< the master clock is enable when SAI enable */ +#define SAI_MCLK_ENABLE SAI_CFG0_MCLKEN /*!< the master clock is enable now */ + +/* SAI master clock oversampling rate */ +#define SAI_MCLK_OVERSAMP_256 ((uint32_t)0x00000000U) /*!< MCLK = 256 * Ffs */ +#define SAI_MCLK_OVERSAMP_512 SAI_CFG0_MOSPR /*!< MCLK = 512 * Ffs */ + +/* SAI master clock divider ratio definitions */ +#define CFG0_MDIV(regval) (BITS(20,25)&((uint32_t)(regval) << 20U)) +#define SAI_MCLKDIV_1 CFG0_MDIV(0) /*!< primary frequency divider logic bypass */ +#define SAI_MCLKDIV_2 CFG0_MDIV(2) /*!< SAI clock is divided by 2 */ +#define SAI_MCLKDIV_3 CFG0_MDIV(3) /*!< SAI clock is divided by 3 */ +#define SAI_MCLKDIV_4 CFG0_MDIV(4) /*!< SAI clock is divided by 4 */ +#define SAI_MCLKDIV_5 CFG0_MDIV(5) /*!< SAI clock is divided by 5 */ +#define SAI_MCLKDIV_6 CFG0_MDIV(6) /*!< SAI clock is divided by 6 */ +#define SAI_MCLKDIV_7 CFG0_MDIV(7) /*!< SAI clock is divided by 7 */ +#define SAI_MCLKDIV_8 CFG0_MDIV(8) /*!< SAI clock is divided by 8 */ +#define SAI_MCLKDIV_9 CFG0_MDIV(9) /*!< SAI clock is divided by 9 */ +#define SAI_MCLKDIV_10 CFG0_MDIV(10) /*!< SAI clock is divided by 10 */ +#define SAI_MCLKDIV_11 CFG0_MDIV(11) /*!< SAI clock is divided by 11 */ +#define SAI_MCLKDIV_12 CFG0_MDIV(12) /*!< SAI clock is divided by 12 */ +#define SAI_MCLKDIV_13 CFG0_MDIV(13) /*!< SAI clock is divided by 13 */ +#define SAI_MCLKDIV_14 CFG0_MDIV(14) /*!< SAI clock is divided by 14 */ +#define SAI_MCLKDIV_15 CFG0_MDIV(15) /*!< SAI clock is divided by 15 */ +#define SAI_MCLKDIV_16 CFG0_MDIV(16) /*!< SAI clock is divided by 16 */ +#define SAI_MCLKDIV_17 CFG0_MDIV(17) /*!< SAI clock is divided by 17 */ +#define SAI_MCLKDIV_18 CFG0_MDIV(18) /*!< SAI clock is divided by 18 */ +#define SAI_MCLKDIV_19 CFG0_MDIV(19) /*!< SAI clock is divided by 19 */ +#define SAI_MCLKDIV_20 CFG0_MDIV(20) /*!< SAI clock is divided by 20 */ +#define SAI_MCLKDIV_21 CFG0_MDIV(21) /*!< SAI clock is divided by 21 */ +#define SAI_MCLKDIV_22 CFG0_MDIV(22) /*!< SAI clock is divided by 22 */ +#define SAI_MCLKDIV_23 CFG0_MDIV(23) /*!< SAI clock is divided by 23 */ +#define SAI_MCLKDIV_24 CFG0_MDIV(24) /*!< SAI clock is divided by 24 */ +#define SAI_MCLKDIV_25 CFG0_MDIV(25) /*!< SAI clock is divided by 25 */ +#define SAI_MCLKDIV_26 CFG0_MDIV(26) /*!< SAI clock is divided by 26 */ +#define SAI_MCLKDIV_27 CFG0_MDIV(27) /*!< SAI clock is divided by 27 */ +#define SAI_MCLKDIV_28 CFG0_MDIV(28) /*!< SAI clock is divided by 28 */ +#define SAI_MCLKDIV_29 CFG0_MDIV(29) /*!< SAI clock is divided by 29 */ +#define SAI_MCLKDIV_30 CFG0_MDIV(30) /*!< SAI clock is divided by 30 */ +#define SAI_MCLKDIV_31 CFG0_MDIV(31) /*!< SAI clock is divided by 31 */ +#define SAI_MCLKDIV_32 CFG0_MDIV(32) /*!< SAI clock is divided by 32 */ +#define SAI_MCLKDIV_33 CFG0_MDIV(33) /*!< SAI clock is divided by 33 */ +#define SAI_MCLKDIV_34 CFG0_MDIV(34) /*!< SAI clock is divided by 34 */ +#define SAI_MCLKDIV_35 CFG0_MDIV(35) /*!< SAI clock is divided by 35 */ +#define SAI_MCLKDIV_36 CFG0_MDIV(36) /*!< SAI clock is divided by 36 */ +#define SAI_MCLKDIV_37 CFG0_MDIV(37) /*!< SAI clock is divided by 37 */ +#define SAI_MCLKDIV_38 CFG0_MDIV(38) /*!< SAI clock is divided by 38 */ +#define SAI_MCLKDIV_39 CFG0_MDIV(39) /*!< SAI clock is divided by 39 */ +#define SAI_MCLKDIV_40 CFG0_MDIV(40) /*!< SAI clock is divided by 40 */ +#define SAI_MCLKDIV_41 CFG0_MDIV(41) /*!< SAI clock is divided by 41 */ +#define SAI_MCLKDIV_42 CFG0_MDIV(42) /*!< SAI clock is divided by 42 */ +#define SAI_MCLKDIV_43 CFG0_MDIV(43) /*!< SAI clock is divided by 43 */ +#define SAI_MCLKDIV_44 CFG0_MDIV(44) /*!< SAI clock is divided by 44 */ +#define SAI_MCLKDIV_45 CFG0_MDIV(45) /*!< SAI clock is divided by 45 */ +#define SAI_MCLKDIV_46 CFG0_MDIV(46) /*!< SAI clock is divided by 46 */ +#define SAI_MCLKDIV_47 CFG0_MDIV(47) /*!< SAI clock is divided by 47 */ +#define SAI_MCLKDIV_48 CFG0_MDIV(48) /*!< SAI clock is divided by 48 */ +#define SAI_MCLKDIV_49 CFG0_MDIV(49) /*!< SAI clock is divided by 49 */ +#define SAI_MCLKDIV_50 CFG0_MDIV(50) /*!< SAI clock is divided by 50 */ +#define SAI_MCLKDIV_51 CFG0_MDIV(51) /*!< SAI clock is divided by 51 */ +#define SAI_MCLKDIV_52 CFG0_MDIV(52) /*!< SAI clock is divided by 52 */ +#define SAI_MCLKDIV_53 CFG0_MDIV(53) /*!< SAI clock is divided by 53 */ +#define SAI_MCLKDIV_54 CFG0_MDIV(54) /*!< SAI clock is divided by 54 */ +#define SAI_MCLKDIV_55 CFG0_MDIV(55) /*!< SAI clock is divided by 55 */ +#define SAI_MCLKDIV_56 CFG0_MDIV(56) /*!< SAI clock is divided by 56 */ +#define SAI_MCLKDIV_57 CFG0_MDIV(57) /*!< SAI clock is divided by 57 */ +#define SAI_MCLKDIV_58 CFG0_MDIV(58) /*!< SAI clock is divided by 58 */ +#define SAI_MCLKDIV_59 CFG0_MDIV(59) /*!< SAI clock is divided by 59 */ +#define SAI_MCLKDIV_60 CFG0_MDIV(60) /*!< SAI clock is divided by 60 */ +#define SAI_MCLKDIV_61 CFG0_MDIV(61) /*!< SAI clock is divided by 61 */ +#define SAI_MCLKDIV_62 CFG0_MDIV(62) /*!< SAI clock is divided by 62 */ +#define SAI_MCLKDIV_63 CFG0_MDIV(63) /*!< SAI clock is divided by 63 */ + +/* SAI clock divider logic bypass */ +#define SAI_CLKDIV_BYPASS_OFF ((uint32_t)0x00000000U) /*!< clock divider ratio is applied to both primary and secondary divider logic */ +#define SAI_CLKDIV_BYPASS_ON SAI_CFG0_BYPASS /*!< clock divider logic is bypassed */ + +/* SAI output drive */ +#define SAI_OUTPUT_WITH_SAIEN ((uint32_t)0x00000000U) /*!< SAI sub-block output driven only when SAIEN is set */ +#define SAI_OUTPUT_NOW SAI_CFG0_ODRIV /*!< SAI sub-block output driven according to ODRIV setting */ + +/* SAI stereo and mono mode selection */ +#define SAI_STEREO_MODE ((uint32_t)0x00000000U) /*!< stereo mode */ +#define SAI_MONO_MODE SAI_CFG0_MONO /*!< mono mode */ + +/* SAI synchronization mode definitions */ +#define CFG0_SYNCMOD(regval) (BITS(10,11)&((uint32_t)(regval) << 10U)) +#define SAI_SYNCMODE_ASYNC CFG0_SYNCMOD(0) /*!< asynchronous with the other sub-block */ +#define SAI_SYNCMODE_OTHERBLOCK CFG0_SYNCMOD(1) /*!< synchronous with the other sub-block */ +#define SAI_SYNCMODE_EXTERNALSAI CFG0_SYNCMOD(2) /*!< synchronous with an external SAI audio sub-block */ + +/* SAI sampling clock edge */ +#define SAI_SAMPEDGE_FALLING ((uint32_t)0x00000000U) /*!< data sampled on SCK falling edge */ +#define SAI_SAMPEDGE_RISING SAI_CFG0_SAMPEDGE /*!< data sampled on SCK rising edge */ + +/* SAI Shift direction */ +#define SAI_SHIFT_MSB ((uint32_t)0x00000000U) /*!< data is shifted with MSB first */ +#define SAI_SHIFT_LSB SAI_CFG0_SHIFTDIR /*!< data is shifted with LSB first */ + +/* SAI data width definitions */ +#define CFG0_DW(regval) (BITS(5,7)&((uint32_t)(regval) << 5U)) +#define SAI_DATAWIDTH_8BIT CFG0_DW(2) /*!< SAI data width 8 bit */ +#define SAI_DATAWIDTH_10BIT CFG0_DW(3) /*!< SAI data width 10 bit */ +#define SAI_DATAWIDTH_16BIT CFG0_DW(4) /*!< SAI data width 16 bit */ +#define SAI_DATAWIDTH_20BIT CFG0_DW(5) /*!< SAI data width 20 bit */ +#define SAI_DATAWIDTH_24BIT CFG0_DW(6) /*!< SAI data width 24 bit */ +#define SAI_DATAWIDTH_32BIT CFG0_DW(7) /*!< SAI data width 32 bit */ + +/* SAI protocol selection */ +#define CFG0_PROTOCOL(regval) (BITS(2,3)&((uint32_t)(regval) << 2U)) +#define SAI_PROTOCOL_POLYMORPHIC CFG0_PROTOCOL(0) /*!< polymorphic */ +#define SAI_PROTOCOL_SPDIF CFG0_PROTOCOL(1) /*!< SPDIF */ +#define SAI_PROTOCOL_AC97 CFG0_PROTOCOL(2) /*!< AC97 */ + +/* SAI operating mode */ +#define CFG0_OPERATING(regval) (BITS(0,1)&((uint32_t)(regval) << 0U)) +#define SAI_MASTER_TRANSMITTER CFG0_OPERATING(0) /*!< master transmitter */ +#define SAI_MASTER_RECEIVER CFG0_OPERATING(1) /*!< master receiver */ +#define SAI_SLAVE_TRANSMITTER CFG0_OPERATING(2) /*!< slave transmitter */ +#define SAI_SLAVE_RECEIVER CFG0_OPERATING(3) /*!< slave receiver */ + +/* SAI compander mode */ +#define CFG1_COMPANDER(regval) (BITS(14,15)&((uint32_t)(regval) << 14U)) +#define SAI_COMPANDER_OFF CFG1_COMPANDER(0) /*!< no compansion applies */ +#define SAI_COMPANDER_ULAW CFG1_COMPANDER(2) /*!< u-law algorithm */ +#define SAI_COMPANDER_ALAW CFG1_COMPANDER(3) /*!< A-law algorithm */ + +/* SAI complement mode */ +#define SAI_COMPLEMENT_1S ((uint32_t)0x00000000U) /*!< data represented in 1's complement form */ +#define SAI_COMPLEMENT_2S SAI_CFG1_CPLMOD /*!< data represented in 2's complement form */ + +/* SAI mute value */ +#define SAI_MUTESENT_0 ((uint32_t)0x00000000U) /*!< 0 is sent via the serial data line when mute is on */ +#define SAI_MUTESENT_LASTFREAM SAI_CFG1_MTVAL /*!< if SLOTNB is less or equals to two, last frame is sent via the serial data line */ + +/* SAI mute on */ +#define SAI_MUTE_OFF ((uint32_t)0x00000000U) /*!< mute mode off */ +#define SAI_MUTE_ON SAI_CFG1_MT /*!< mute mode on */ + +/* SAI serial data line output management */ +#define SAI_SDLINE_DRIVE ((uint32_t)0x00000000U) /*!< SD line output is driven entirely during the audio frame */ +#define SAI_SDLINE_RELEASE SAI_CFG1_SDOM /*!< SD line output is released near inactive slots */ + +/* SAI FIFO threshold */ +#define CFG1_FFTH(regval) (BITS(0,2)&((uint32_t)(regval) << 0U)) +#define SAI_FIFOTH_EMPTY CFG1_FFTH(0) /*!< FIFO threshold empty */ +#define SAI_FIFOTH_QUARTER CFG1_FFTH(1) /*!< FIFO threshold quarter full */ +#define SAI_FIFOTH_HALF CFG1_FFTH(2) /*!< FIFO threshold half full */ +#define SAI_FIFOTH_THREE_QUARTER CFG1_FFTH(3) /*!< FIFO threshold three quarter full */ +#define SAI_FIFOTH_FULL CFG1_FFTH(4) /*!< FIFO threshold full */ + +/* SAI frame synchronization offset */ +#define SAI_FS_OFFSET_BEGINNING ((uint32_t)0x00000000U) /*!< FS active edge asserted at the beginning of the first bit of the first slot */ +#define SAI_FS_OFFSET_ONEBITBEFORE SAI_FCFG_FSOST /*!< FS active edge asserted one bit cycle before normal FS when FSOST is 0 */ + +/* SAI frame synchronization active polarity */ +#define SAI_FS_POLARITY_LOW ((uint32_t)0x00000000U) /*!< FS low active polarity */ +#define SAI_FS_POLARITY_HIGH SAI_FCFG_FSPL /*!< FS high active polarity */ + +/* SAI frame synchronization function */ +#define SAI_FS_FUNC_START ((uint32_t)0x00000000U) /*!< FS only defines frame start */ +#define SAI_FS_FUNC_START_CHANNEL SAI_FCFG_FSFUNC /*!< FS define both frame start and channel number */ + +/* SAI slot active */ +#define SAI_SLOT_ACTIVE_NONE ((uint32_t)0x00000000U) /*!< all slot inactive */ +#define SAI_SLOT_ACTIVE_0 BIT(16) /*!< slot 0 active */ +#define SAI_SLOT_ACTIVE_1 BIT(17) /*!< slot 1 active */ +#define SAI_SLOT_ACTIVE_2 BIT(18) /*!< slot 2 active */ +#define SAI_SLOT_ACTIVE_3 BIT(19) /*!< slot 3 active */ +#define SAI_SLOT_ACTIVE_4 BIT(20) /*!< slot 4 active */ +#define SAI_SLOT_ACTIVE_5 BIT(21) /*!< slot 5 active */ +#define SAI_SLOT_ACTIVE_6 BIT(22) /*!< slot 6 active */ +#define SAI_SLOT_ACTIVE_7 BIT(23) /*!< slot 7 active */ +#define SAI_SLOT_ACTIVE_8 BIT(24) /*!< slot 8 active */ +#define SAI_SLOT_ACTIVE_9 BIT(25) /*!< slot 9 active */ +#define SAI_SLOT_ACTIVE_10 BIT(26) /*!< slot 10 active */ +#define SAI_SLOT_ACTIVE_11 BIT(27) /*!< slot 11 active */ +#define SAI_SLOT_ACTIVE_12 BIT(28) /*!< slot 12 active */ +#define SAI_SLOT_ACTIVE_13 BIT(29) /*!< slot 13 active */ +#define SAI_SLOT_ACTIVE_14 BIT(30) /*!< slot 14 active */ +#define SAI_SLOT_ACTIVE_15 BIT(31) /*!< slot 15 active */ +#define SAI_SLOT_ACTIVE_ALL BITS(16,31) /*!< slot all active */ + +/* SAI slot width definitions */ +#define SCFG_SW(regval) (BITS(6,7)&((uint32_t)(regval) << 6U)) +#define SAI_SLOT_WIDTH_DATA SCFG_SW(0) /*!< slot width equals data width */ +#define SAI_SLOT_WIDTH_16BIT SCFG_SW(1) /*!< slot width of 16-bits */ +#define SAI_SLOT_WIDTH_32BIT SCFG_SW(2) /*!< slot width of 32-bits */ + +/* SAI interrupt enable or disable */ +#define SAI_INT_OUERR SAI_INTEN_OUERRIE /*!< FIFO overrun or underrun interrupt enable */ +#define SAI_INT_MTDET SAI_INTEN_MTDETIE /*!< mute detection interrupt enable */ +#define SAI_INT_ERRCK SAI_INTEN_ERRCKIE /*!< error clock interrupt enable */ +#define SAI_INT_FFREQ SAI_INTEN_FFREQIE /*!< FIFO request interrupt enable */ +#define SAI_INT_ACNRDY SAI_INTEN_ACNRDYIE /*!< audio codec not ready interrupt enable */ +#define SAI_INT_FSADET SAI_INTEN_FSADETIE /*!< frame synchronization advanced detection interrupt enable */ +#define SAI_INT_FSPDET SAI_INTEN_FSPDETIE /*!< frame synchronization postpone detection interrupt enable */ + +/* SAI flags */ +#define SAI_FLAG_OUERR SAI_STAT_OUERR /*!< FIFO overrun or underrun flag */ +#define SAI_FLAG_MTDET SAI_STAT_MTDET /*!< mute detection flag */ +#define SAI_FLAG_ERRCK SAI_STAT_ERRCK /*!< error clock flag */ +#define SAI_FLAG_FFREQ SAI_STAT_FFREQ /*!< FIFO request flag */ +#define SAI_FLAG_ACNRDY SAI_STAT_ACNRDY /*!< audio codec not ready flag */ +#define SAI_FLAG_FSADET SAI_STAT_FSADET /*!< frame synchronization advanced detection flag */ +#define SAI_FLAG_FSPDET SAI_STAT_FSPDET /*!< frame synchronization postpone detection flag */ + +/* SAI FIFO status */ +#define STAT_FFSTAT(regval) (BITS(16,18)&((uint32_t)(regval) << 16U)) +#define SAI_FIFO_STAT_EMPTY STAT_FFSTAT(0) /*!< FIFO status empty */ +#define SAI_FIFO_STAT_QUARTER STAT_FFSTAT(1) /*!< receiver: empty < FIFO <= 1/4, transmitter: empty < FIFO < 1/4 */ +#define SAI_FIFO_STAT_HALF STAT_FFSTAT(2) /*!< receiver: 1/4 < FIFO <= 1/2, transmitter: 1/4 <= FIFO < 1/2 */ +#define SAI_FIFO_STAT_THREE_QUARTER STAT_FFSTAT(3) /*!< receiver: 1/2 < FIFO <= 3/4, transmitter: 1/2 <= FIFO < 3/4 */ +#define SAI_FIFO_STAT_NEARFULL STAT_FFSTAT(4) /*!< receiver: 3/4 < FIFO < full, transmitter: 3/4 <= FIFO < full */ +#define SAI_FIFO_STAT_FULL STAT_FFSTAT(5) /*!< FIFO status full */ + +/* SAI PDM microphone */ +#define SAI_PDM_MICROPHONE0_L ((uint32_t)0x00000000U) /*!< the group 0 left channel microphone */ +#define SAI_PDM_MICROPHONE0_R ((uint32_t)0x00000001U) /*!< the group 0 right channel microphone */ +#define SAI_PDM_MICROPHONE1_L ((uint32_t)0x00000002U) /*!< the group 1 left channel microphone */ +#define SAI_PDM_MICROPHONE1_R ((uint32_t)0x00000003U) /*!< the group 1 right channel microphone */ +#define SAI_PDM_MICROPHONE2_L ((uint32_t)0x00000004U) /*!< the group 2 left channel microphone */ +#define SAI_PDM_MICROPHONE2_R ((uint32_t)0x00000005U) /*!< the group 2 right channel microphone */ +#define SAI_PDM_MICROPHONE3_L ((uint32_t)0x00000006U) /*!< the group 3 left channel microphone */ +#define SAI_PDM_MICROPHONE3_R ((uint32_t)0x00000007U) /*!< the group 3 right channel microphone */ + +#define SAI_BLOCK0 ((uint32_t)0x00000000U) /*!< Block 0 */ +#define SAI_BLOCK1 ((uint32_t)0x00000001U) /*!< Block 1 */ + +/* function declarations */ +/* SAI deinitialization and initialization functions */ +/* reset SAI */ +void sai_deinit(uint32_t sai_periph); +/* initialize SAI parameter struct with the default values */ +void sai_struct_para_init(sai_parameter_struct *sai_init_stuct); +/* initialize SAI frame parameter struct with the default values */ +void sai_frame_struct_para_init(sai_frame_parameter_struct *sai_frame_init_struct); +/* initialize SAI slot parameter struct with the default values */ +void sai_slot_struct_para_init(sai_slot_parameter_struct *sai_slot_init_struct); +/* initialize SAI */ +void sai_init(uint32_t sai_periph, uint32_t block, sai_parameter_struct *sai_struct); +/* initialize SAI frame */ +void sai_frame_init(uint32_t sai_periph, uint32_t block, sai_frame_parameter_struct *sai_frame_struct); +/* initialize SAI slot */ +void sai_slot_init(uint32_t sai_periph, uint32_t block, sai_slot_parameter_struct *sai_slot_struct); +/* sai enable */ +void sai_enable(uint32_t sai_periph, uint32_t block); +/* sai disable */ +void sai_disable(uint32_t sai_periph, uint32_t block); + +/* SAI configuration functions */ +/* SAI serial data near inactive slot output management */ +void sai_sdoutput_config(uint32_t sai_periph, uint32_t block, uint32_t sdout); +/* configure SAI mono mode */ +void sai_monomode_config(uint32_t sai_periph, uint32_t block, uint32_t mono); +/* configure SAI companding mode */ +void sai_companding_config(uint32_t sai_periph, uint32_t block, uint32_t compander, + uint32_t complement); +/* enable SAI mute detected or mute send */ +void sai_mute_enable(uint32_t sai_periph, uint32_t block); +/* disable SAI mute detected or mute send */ +void sai_mute_disable(uint32_t sai_periph, uint32_t block); +/* configure SAI mute value */ +void sai_mute_value_config(uint32_t sai_periph, uint32_t block, uint32_t value); +/* configure SAI mute frame count */ +void sai_mute_count_config(uint32_t sai_periph, uint32_t block, uint32_t count); +/* SAI transmit data */ +void sai_data_transmit(uint32_t sai_periph, uint32_t block, uint32_t data); +/* SAI receive data */ +uint32_t sai_data_receive(uint32_t sai_periph, uint32_t block); +/* get SAI fifo status */ +sai_fifo_state_enum sai_fifo_status_get(uint32_t sai_periph, uint32_t block); +/* SAI fifo flush */ +void sai_fifo_flush(uint32_t sai_periph, uint32_t block); + +/* SAI DMA functions */ +/* enable SAI dma */ +void sai_dma_enable(uint32_t sai_periph, uint32_t block); +/* disable SAI dma */ +void sai_dma_disable(uint32_t sai_periph, uint32_t block); + +/* SAI synchronization function */ +/* configure synchronization input select */ +void sai_sync_input_config(uint32_t sai_periph, uint32_t input); +/* configure synchronization output select */ +void sai_sync_output_config(uint32_t sai_periph, uint32_t output); + +/* SAI pdm mode functions */ +/* enable SAI pdm mode */ +void sai_pdm_enable(uint32_t sai_periph); +/* disable SAI pdm mode */ +void sai_pdm_disable(uint32_t sai_periph); +/* configure SAI pdm mode microphone number */ +void sai_pdm_microphone_number_config(uint32_t sai_periph, uint32_t microphonenum); +/* configure SAI pdm mode microphone delay */ +void sai_pdm_delay_config(uint32_t sai_periph, uint32_t microphone, uint32_t delay); +/* enable SAI pdm mode clock line 0 */ +void sai_pdm_clk0_enable(uint32_t sai_periph); +/* disable SAI pdm mode clock line 0 */ +void sai_pdm_clk0_disable(uint32_t sai_periph); +/* enable SAI pdm mode clock line 1 */ +void sai_pdm_clk1_enable(uint32_t sai_periph); +/* disable SAI pdm mode clock line 1 */ +void sai_pdm_clk1_disable(uint32_t sai_periph); + +/* flag and interrupt functions */ +/* enable the SAI interrupt */ +void sai_interrupt_enable(uint32_t sai_periph, uint32_t block, uint32_t interrupt); +/* disable the SAI interrupt */ +void sai_interrupt_disable(uint32_t sai_periph, uint32_t block, uint32_t interrupt); +/* get SAI interrupt flag status */ +FlagStatus sai_interrupt_flag_get(uint32_t sai_periph, uint32_t block, uint32_t interrupt); +/* clear SAI interrupt flag status */ +void sai_interrupt_flag_clear(uint32_t sai_periph, uint32_t block, uint32_t interrupt); +/* get SAI flag status */ +FlagStatus sai_flag_get(uint32_t sai_periph, uint32_t block, uint32_t flag); +/* clear SAI flag status */ +void sai_flag_clear(uint32_t sai_periph, uint32_t block, uint32_t flag); + +#endif /* GD32H7XX_SAI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sdio.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sdio.h new file mode 100644 index 0000000000..4540dac1fb --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_sdio.h @@ -0,0 +1,534 @@ +/*! + \file gd32h7xx_sdio.h + \brief definitions for the SDIO + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_SDIO_H +#define GD32H7XX_SDIO_H + +#include "gd32h7xx.h" + +/* SDIO definitions */ +#define SDIO0 (SDIO_BASE + 0x09FE4C00U) +#define SDIO1 (SDIO_BASE) + +/* registers definitions */ +#define SDIO_PWRCTL(sdiox) REG32((sdiox) + 0x00000000U) /*!< SDIO power control register */ +#define SDIO_CLKCTL(sdiox) REG32((sdiox) + 0x00000004U) /*!< SDIO clock control register */ +#define SDIO_CMDAGMT(sdiox) REG32((sdiox) + 0x00000008U) /*!< SDIO command argument register */ +#define SDIO_CMDCTL(sdiox) REG32((sdiox) + 0x0000000CU) /*!< SDIO command control register */ +#define SDIO_RSPCMDIDX(sdiox) REG32((sdiox) + 0x00000010U) /*!< SDIO command index response register */ +#define SDIO_RESP0(sdiox) REG32((sdiox) + 0x00000014U) /*!< SDIO response register 0 */ +#define SDIO_RESP1(sdiox) REG32((sdiox) + 0x00000018U) /*!< SDIO response register 1 */ +#define SDIO_RESP2(sdiox) REG32((sdiox) + 0x0000001CU) /*!< SDIO response register 2 */ +#define SDIO_RESP3(sdiox) REG32((sdiox) + 0x00000020U) /*!< SDIO response register 3 */ +#define SDIO_DATATO(sdiox) REG32((sdiox) + 0x00000024U) /*!< SDIO data timeout register */ +#define SDIO_DATALEN(sdiox) REG32((sdiox) + 0x00000028U) /*!< SDIO data length register */ +#define SDIO_DATACTL(sdiox) REG32((sdiox) + 0x0000002CU) /*!< SDIO data control register */ +#define SDIO_DATACNT(sdiox) REG32((sdiox) + 0x00000030U) /*!< SDIO data counter register */ +#define SDIO_STAT(sdiox) REG32((sdiox) + 0x00000034U) /*!< SDIO status register */ +#define SDIO_INTC(sdiox) REG32((sdiox) + 0x00000038U) /*!< SDIO interrupt clear register */ +#define SDIO_INTEN(sdiox) REG32((sdiox) + 0x0000003CU) /*!< SDIO interrupt enable register */ +#define SDIO_ACKTO(sdiox) REG32((sdiox) + 0x00000040U) /*!< SDIO FIFO ACK timeout register */ +#define SDIO_FIFO(sdiox) REG32((sdiox) + 0x00000080U) /*!< SDIO FIFO data register */ +#define SDIO_IDMACTL(sdiox) REG32((sdiox) + 0x00000050U) /*!< SDIO FIFO internal DMA control register */ +#define SDIO_IDMASIZE(sdiox) REG32((sdiox) + 0x00000054U) /*!< SDIO FIFO internal DMA buffer size register */ +#define SDIO_IDMAADDR0(sdiox) REG32((sdiox) + 0x00000058U) /*!< SDIO FIFO internal DMA buffer 0 base address register */ +#define SDIO_IDMAADDR1(sdiox) REG32((sdiox) + 0x0000005CU) /*!< SDIO FIFO internal DMA buffer 1 base address register */ + +/* bits definitions */ +/* SDIO_PWRCTL */ +#define SDIO_PWRCTL_PWRCTL BITS(0,1) /*!< SDIO power control bits */ +#define SDIO_PWRCTL_VSSTART BIT(2) /*!< voltage switch start bit */ +#define SDIO_PWRCTL_VSEN BIT(3) /*!< voltage switch enable bit */ +#define SDIO_PWRCTL_DIRPS BIT(4) /*!< data and command direction polarity selection bit */ + +/* SDIO_CLKCTL */ +#define SDIO_CLKCTL_DIV BITS(0,9) /*!< clock division */ +#define SDIO_CLKCTL_CLKPWRSAV BIT(12) /*!< SDIO_CLK clock dynamic switch on/off for power saving */ +#define SDIO_CLKCTL_BUSMODE BITS(14,15) /*!< SDIO card bus mode control bit */ +#define SDIO_CLKCTL_CLKEDGE BIT(16) /*!< command and data SDIO_CLK dephasing selection bit */ +#define SDIO_CLKCTL_HWEN BIT(17) /*!< hardware flow control enable bit */ +#define SDIO_CLKCTL_DRSEL BIT(18) /*!< data rate selection bit */ +#define SDIO_CLKCTL_BUSSP BIT(19) /*!< bus speed mode selection bit */ +#define SDIO_CLKCTL_RCLK BITS(20,21) /*!< receive clock selection bits */ + +/* SDIO_CMDAGMT */ +#define SDIO_CMDAGMT_CMDAGMT BITS(0,31) /*!< SDIO card command argument */ + +/* SDIO_CMDCTL */ +#define SDIO_CMDCTL_CMDIDX BITS(0,5) /*!< command index */ +#define SDIO_CMDCTL_TREN BIT(6) /*!< data transfer mode enable bit */ +#define SDIO_CMDCTL_TRSTOP BIT(7) /*!< data transfer stop bit */ +#define SDIO_CMDCTL_CMDRESP BITS(8,9) /*!< waits command response type bits */ +#define SDIO_CMDCTL_INTWAIT BIT(10) /*!< interrupt wait instead of timeout */ +#define SDIO_CMDCTL_WAITDEND BIT(11) /*!< waits for ends of data transfer */ +#define SDIO_CMDCTL_CSMEN BIT(12) /*!< command state machine (CSM) enable bit */ +#define SDIO_CMDCTL_HOLD BIT(13) /*!< hold DSM transmission and reception of new data block */ +#define SDIO_CMDCTL_BOOTMOD BIT(14) /*!< boot mode selection bit */ +#define SDIO_CMDCTL_BOOTMODEN BIT(15) /*!< boot mode procedure enable bit */ +#define SDIO_CMDCTL_CMDSR BIT(16) /*!< suspend or resume command and signals interrupt period start/end bit */ + +/* SDIO_DATATO */ +#define SDIO_DATATO_DATATO BITS(0,31) /*!< data timeout period */ + +/* SDIO_DATALEN */ +#define SDIO_DATALEN_DATALEN BITS(0,24) /*!< data transfer length */ + +/* SDIO_DATACTL */ +#define SDIO_DATACTL_DATAEN BIT(0) /*!< data transfer enabled bit */ +#define SDIO_DATACTL_DATADIR BIT(1) /*!< data transfer direction */ +#define SDIO_DATACTL_TRANSMOD BITS(2,3) /*!< data transfer mode */ +#define SDIO_DATACTL_BLKSZ BITS(4,7) /*!< data block size */ +#define SDIO_DATACTL_ACKEN BIT(12) /*!< boot acknowledgment enable bit */ +#define SDIO_DATACTL_FIFOREST BIT(13) /*!< FIFO buffer reset, flush all data */ + +/* SDIO_STAT */ +#define SDIO_STAT_CCRCERR BIT(0) /*!< command response received (CRC check failed) */ +#define SDIO_STAT_DTCRCERR BIT(1) /*!< data block sent/received (CRC check failed) */ +#define SDIO_STAT_CMDTMOUT BIT(2) /*!< command response timeout */ +#define SDIO_STAT_DTTMOUT BIT(3) /*!< data timeout */ +#define SDIO_STAT_TXURE BIT(4) /*!< transmit FIFO underrun error occurs */ +#define SDIO_STAT_RXORE BIT(5) /*!< received FIFO overrun error occurs */ +#define SDIO_STAT_CMDRECV BIT(6) /*!< command response received (CRC check passed) */ +#define SDIO_STAT_CMDSEND BIT(7) /*!< command sent (no response required) */ +#define SDIO_STAT_DTEND BIT(8) /*!< data end (data counter, SDIO_DATACNT is zero) */ +#define SDIO_STAT_DATHOLD BIT(9) /*!< data transfer hold */ +#define SDIO_STAT_DTBLKEND BIT(10) /*!< data block sent/received (CRC check passed) */ +#define SDIO_STAT_DATABOR BIT(11) /*!< data transfer aborted by CMD12 */ +#define SDIO_STAT_CMDSTA BIT(12) /*!< command path active state */ +#define SDIO_STAT_DATSTA BIT(13) /*!< data path active state */ +#define SDIO_STAT_TFH BIT(14) /*!< transmit FIFO is half empty */ +#define SDIO_STAT_RFH BIT(15) /*!< receive FIFO is half full */ +#define SDIO_STAT_TFF BIT(16) /*!< transmit FIFO is full */ +#define SDIO_STAT_RFF BIT(17) /*!< receive FIFO is full */ +#define SDIO_STAT_TFE BIT(18) /*!< transmit FIFO is empty */ +#define SDIO_STAT_RFE BIT(19) /*!< receive FIFO is empty */ +#define SDIO_STAT_DAT0BSY BIT(20) /*!< DAT0 line signal keep busy */ +#define SDIO_STAT_DAT0BSYEND BIT(21) /*!< DAT0 line signal changed from busy to ready */ +#define SDIO_STAT_SDIOINT BIT(22) /*!< SD I/O interrupt received */ +#define SDIO_STAT_ACKFAIL BIT(23) /*!< boot acknowledgment received and check fail */ +#define SDIO_STAT_ACKTO BIT(24) /*!< boot acknowledgment timeout */ +#define SDIO_STAT_VSEND BIT(25) /*!< voltage switch critical timing section end */ +#define SDIO_STAT_CLKSTOP BIT(26) /*!< SDIO_CLK stopped in voltage switch procedure */ +#define SDIO_STAT_IDMERR BIT(27) /*!< IDMA transfer error */ +#define SDIO_STAT_IDMAEND BIT(28) /*!< IDMA transfer end */ + +/* SDIO_INTC */ +#define SDIO_INTC_CCRCERRC BIT(0) /*!< CCRCERR flag clear bit */ +#define SDIO_INTC_DTCRCERRC BIT(1) /*!< DTCRCERR flag clear bit */ +#define SDIO_INTC_CMDTMOUTC BIT(2) /*!< CMDTMOUT flag clear bit */ +#define SDIO_INTC_DTTMOUTC BIT(3) /*!< DTTMOUT flag clear bit */ +#define SDIO_INTC_TXUREC BIT(4) /*!< TXURE flag clear bit */ +#define SDIO_INTC_RXOREC BIT(5) /*!< RXORE flag clear bit */ +#define SDIO_INTC_CMDRECVC BIT(6) /*!< CMDRECV flag clear bit */ +#define SDIO_INTC_CMDSENDC BIT(7) /*!< CMDSEND flag clear bit */ +#define SDIO_INTC_DTENDC BIT(8) /*!< DTEND flag clear bit */ +#define SDIO_INTC_DATHOLDC BIT(9) /*!< DATHOLD flag clear bit */ +#define SDIO_INTC_DTBLKENDC BIT(10) /*!< DTBLKEND flag clear bit */ +#define SDIO_INTC_DATABORC BIT(11) /*!< DATABOR flag clear bit */ +#define SDIO_INTC_DAT0BSYENDC BIT(21) /*!< DAT0BSYEND flag clear bit */ +#define SDIO_INTC_SDIOINTC BIT(22) /*!< SDIOINT flag clear bit */ +#define SDIO_INTC_ACKFAILC BIT(23) /*!< ACKFAIL flag clear bit */ +#define SDIO_INTC_ACKTOC BIT(24) /*!< ACKTO flag clear bit */ +#define SDIO_INTC_VSENDC BIT(25) /*!< VSEND flag clear bit */ +#define SDIO_INTC_CLKSTOPC BIT(26) /*!< CLKSTOP flag clear bit */ +#define SDIO_INTC_IDMERRC BIT(27) /*!< IDMERR flag clear bit */ +#define SDIO_INTC_IDMAENDC BIT(28) /*!< IDMAEND flag clear bit */ + +/* SDIO_INTEN */ +#define SDIO_INTEN_CCRCERRIE BIT(0) /*!< command response CRC fail interrupt enable */ +#define SDIO_INTEN_DTCRCERRIE BIT(1) /*!< data CRC fail interrupt enable */ +#define SDIO_INTEN_CMDTMOUTIE BIT(2) /*!< command response timeout interrupt enable */ +#define SDIO_INTEN_DTTMOUTIE BIT(3) /*!< data timeout interrupt enable */ +#define SDIO_INTEN_TXUREIE BIT(4) /*!< transmit FIFO underrun error interrupt enable */ +#define SDIO_INTEN_RXOREIE BIT(5) /*!< received FIFO overrun error interrupt enable */ +#define SDIO_INTEN_CMDRECVIE BIT(6) /*!< command response received interrupt enable */ +#define SDIO_INTEN_CMDSENDIE BIT(7) /*!< command sent interrupt enable */ +#define SDIO_INTEN_DTENDIE BIT(8) /*!< data end interrupt enable */ +#define SDIO_INTEN_DATHOLDIE BIT(9) /*!< data transfer hold interrupt enable */ +#define SDIO_INTEN_DTBLKENDIE BIT(10) /*!< data block end interrupt enable */ +#define SDIO_INTEN_DATABORIE BIT(11) /*!< data transfer abort interrupt enable */ +#define SDIO_INTEN_TFHIE BIT(14) /*!< transmit FIFO half empty interrupt enable */ +#define SDIO_INTEN_RFHIE BIT(15) /*!< receive FIFO half full interrupt enable */ +#define SDIO_INTEN_RFFIE BIT(17) /*!< receive FIFO full interrupt enable */ +#define SDIO_INTEN_TFEIE BIT(18) /*!< transmit FIFO empty interrupt enable */ +#define SDIO_INTEN_DAT0BSYENDIE BIT(21) /*!< DAT0 line signal changed from busy to ready interrupt enable */ +#define SDIO_INTEN_SDIOINTIE BIT(22) /*!< SD I/O interrupt received interrupt enable */ +#define SDIO_INTEN_ACKFAILIE BIT(23) /*!< boot acknowledgment received and check fail interrupt enable */ +#define SDIO_INTEN_ACKTOIE BIT(24) /*!< boot acknowledgment timeout enable */ +#define SDIO_INTEN_VSENDIE BIT(25) /*!< voltage switch critical timing section end interrupt enable */ +#define SDIO_INTEN_CLKSTOPIE BIT(26) /*!< voltage Switch clock stopped interrupt enable */ +#define SDIO_INTEN_IDMAERRIE BIT(27) /*!< IDMA transfer error interrupt enable */ +#define SDIO_INTEN_IDMAENDIE BIT(28) /*!< IDMA transfer end interrupt enable */ + +/* SDIO_ACKTO */ +#define SDIO_ACKTO_ACKTO BITS(0, 24) /*!< boot ACK timeout period */ + +/* SDIO_FIFO */ +#define SDIO_FIFO_FIFODT BITS(0, 31) /*!< receive FIFO data or transmit FIFO data */ + +/* SDIO_IDMACTL */ +#define SDIO_IDMACTL_IDMAEN BIT(0) /*!< FIFO IDMA enable bit */ +#define SDIO_IDMACTL_BUFMOD BIT(1) /*!< double buffer mode enable bit */ +#define SDIO_IDMACTL_BUFSEL BIT(2) /*!< IDMA double buffer selection bit */ + +/* SDIO_IDMASIZE */ +#define SDIO_IDMASIZE_IDMASIZE BITS(5, 12) /*!< number of bytes per buffer, buffer size = number*32 */ + +/* SDIO_IDMAADDR0 */ +#define SDIO_IDMAADDR0_IDMAADDR0 BITS(0, 31) /*!< IDMA buffer 0 base address, is a multiple of 8 */ + +/* SDIO_IDMAADDR1 */ +#define SDIO_IDMAADDR1_IDMAADDR1 BITS(0, 31) /*!< IDMA buffer 1 base address, is a multiple of 8 */ + +/* constants definitions */ +/* SDIO power control */ +#define PWRCTL_PWRCTL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define SDIO_POWER_OFF PWRCTL_PWRCTL(0) /*!< SDIO power off */ +#define SDIO_POWER_CYCLE PWRCTL_PWRCTL(2) /*!< SDIO power cycle */ +#define SDIO_POWER_ON PWRCTL_PWRCTL(3) /*!< SDIO power on */ + +/* SDIO receive clock selection */ +#define CLKCTL_RECEICECLOCK(regval) (BITS(20, 21) & ((uint32_t)(regval) << 20)) +#define SDIO_RECEIVECLOCK_INCLK CLKCTL_RECEICECLOCK(0) /*!< select SDIO_IN_CLK clock */ +#define SDIO_RECEIVECLOCK_CLKIN CLKCTL_RECEICECLOCK(1) /*!< select SDIO_CLKIN clock */ +#define SDIO_RECEIVECLOCK_FBCLK CLKCTL_RECEICECLOCK(2) /*!< select SDIO_FB_CLK clock */ + +/* SDIO card bus speed control */ +#define SDIO_BUSSPEED_LOW (uint32_t)0x00000000U /*!< DS, HS, SDR12, SDR25 bus speed */ +#define SDIO_BUSSPEED_HIGH SDIO_CLKCTL_BUSSP /*!< SDR50, SDR104, DDR50 bus speed */ + +/* SDIO data rate selection */ +#define SDIO_DATA_RATE_SDR (uint32_t)0x00000000U /*!< SDR selected */ +#define SDIO_DATA_RATE_DDR SDIO_CLKCTL_DRSEL /*!< DDR selected */ + +/* SDIO_CLK clock edge selection */ +#define SDIO_SDIOCLKEDGE_RISING (uint32_t)0x00000000U /*!< select the rising edge of the SDIOCLK to generate SDIO_CLK */ +#define SDIO_SDIOCLKEDGE_FALLING SDIO_CLKCTL_CLKEDGE /*!< select the falling edge of the SDIOCLK to generate SDIO_CLK */ + +/* SDIO_CLK clock dynamic switch on/off for power saving */ +#define SDIO_CLOCKPWRSAVE_DISABLE (uint32_t)0x00000000U /*!< SDIO_CLK clock is always on */ +#define SDIO_CLOCKPWRSAVE_ENABLE SDIO_CLKCTL_CLKPWRSAV /*!< SDIO_CLK closed when bus is idle */ + +/* SDIO card bus mode control */ +#define CLKCTL_BUSMODE(regval) (BITS(14, 15) & ((uint32_t)(regval) << 14)) +#define SDIO_BUSMODE_1BIT CLKCTL_BUSMODE(0) /*!< 1-bit SDIO card bus mode */ +#define SDIO_BUSMODE_4BIT CLKCTL_BUSMODE(1) /*!< 4-bit SDIO card bus mode */ +#define SDIO_BUSMODE_8BIT CLKCTL_BUSMODE(2) /*!< 8-bit SDIO card bus mode */ + +/* SDIO direction polarity of data and command */ +#define SDIO_DIRECTION_SIGNAL_LOW (uint32_t)0x00000000U /*!< direction signal is low, the voltage transceiver IOs driven as output */ +#define SDIO_DIRECTION_SIGNAL_HIGH SDIO_PWRCTL_DIRPS /*!< direction signal is high, the voltage transceiver IOs driven as output */ + +/* SDIO boot mode */ +#define SDIO_BOOTMODE_NORMAL (uint32_t)0x00000000U /*!< normal boot mode */ +#define SDIO_BOOTMODE_ALTERNATIVE SDIO_CMDCTL_BOOTMOD /*!< alternative boot mode */ + +/* SDIO command response type */ +#define CMDCTL_CMDRESP(regval) (BITS(8, 9) & ((uint32_t)(regval) << 8)) +#define SDIO_RESPONSETYPE_NO CMDCTL_CMDRESP(0) /*!< no response */ +#define SDIO_RESPONSETYPE_SHORT CMDCTL_CMDRESP(1) /*!< short response */ +#define SDIO_RESPONSETYPE_SHORT_NOCRC CMDCTL_CMDRESP(2) /*!< short response without CRC */ +#define SDIO_RESPONSETYPE_LONG CMDCTL_CMDRESP(3) /*!< long response */ + +/* command state machine wait type */ +#define SDIO_WAITTYPE_NO (uint32_t)0x00000000U /*!< not wait interrupt */ +#define SDIO_WAITTYPE_INTERRUPT SDIO_CMDCTL_INTWAIT /*!< wait interrupt */ +#define SDIO_WAITTYPE_DATAEND SDIO_CMDCTL_WAITDEND /*!< wait the end of data transfer */ + +/* command type */ +#define SDIO_CMDTYPE_NO (uint32_t)0x00000000U /*!< just a command */ +#define SDIO_CMDTYPE_TRANSFER SDIO_CMDCTL_TREN /*!< command for transfer */ +#define SDIO_CMDTYPE_TRANSFERSTOP SDIO_CMDCTL_TRSTOP /*!< commang for stopping transfer */ +#define SDIO_CMDTYPE_SUSPEND SDIO_CMDCTL_CMDSR /*!< suspend command, or resume command */ + +/* short response and each part of the long response */ +#define SDIO_RESPONSE0 (uint32_t)0x00000000U /*!< card response[31:0]/card response[127:96] */ +#define SDIO_RESPONSE1 (uint32_t)0x00000001U /*!< card response[95:64] */ +#define SDIO_RESPONSE2 (uint32_t)0x00000002U /*!< card response[63:32] */ +#define SDIO_RESPONSE3 (uint32_t)0x00000003U /*!< card response[31:1], plus bit 0 */ + +/* SDIO data block size */ +#define DATACTL_BLKSZ(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define SDIO_DATABLOCKSIZE_1BYTE DATACTL_BLKSZ(0) /*!< block size = 1 byte */ +#define SDIO_DATABLOCKSIZE_2BYTES DATACTL_BLKSZ(1) /*!< block size = 2 bytes */ +#define SDIO_DATABLOCKSIZE_4BYTES DATACTL_BLKSZ(2) /*!< block size = 4 bytes */ +#define SDIO_DATABLOCKSIZE_8BYTES DATACTL_BLKSZ(3) /*!< block size = 8 bytes */ +#define SDIO_DATABLOCKSIZE_16BYTES DATACTL_BLKSZ(4) /*!< block size = 16 bytes */ +#define SDIO_DATABLOCKSIZE_32BYTES DATACTL_BLKSZ(5) /*!< block size = 32 bytes */ +#define SDIO_DATABLOCKSIZE_64BYTES DATACTL_BLKSZ(6) /*!< block size = 64 bytes */ +#define SDIO_DATABLOCKSIZE_128BYTES DATACTL_BLKSZ(7) /*!< block size = 128 bytes */ +#define SDIO_DATABLOCKSIZE_256BYTES DATACTL_BLKSZ(8) /*!< block size = 256 bytes */ +#define SDIO_DATABLOCKSIZE_512BYTES DATACTL_BLKSZ(9) /*!< block size = 512 bytes */ +#define SDIO_DATABLOCKSIZE_1024BYTES DATACTL_BLKSZ(10) /*!< block size = 1024 bytes */ +#define SDIO_DATABLOCKSIZE_2048BYTES DATACTL_BLKSZ(11) /*!< block size = 2048 bytes */ +#define SDIO_DATABLOCKSIZE_4096BYTES DATACTL_BLKSZ(12) /*!< block size = 4096 bytes */ +#define SDIO_DATABLOCKSIZE_8192BYTES DATACTL_BLKSZ(13) /*!< block size = 8192 bytes */ +#define SDIO_DATABLOCKSIZE_16384BYTES DATACTL_BLKSZ(14) /*!< block size = 16384 bytes */ + +/* SDIO data transfer mode */ +#define DATACTL_TRANSMODE(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define SDIO_TRANSMODE_BLOCKCOUNT DATACTL_TRANSMODE(0) /*!< block count data transfer */ +#define SDIO_TRANSMODE_MULTIBYTE DATACTL_TRANSMODE(1) /*!< multibyte data transfer (only SD/SD I/O) */ +#define SDIO_TRANSMODE_STREAM DATACTL_TRANSMODE(2) /*!< stream transfer (only eMMC) */ +#define SDIO_TRANSMODE_BLOCKCMD12 DATACTL_TRANSMODE(3) /*!< block data transfer ends with CMD12 */ + +/* SDIO data transfer direction */ +#define SDIO_TRANSDIRECTION_TOCARD (uint32_t)0x00000000U /*!< write data to card */ +#define SDIO_TRANSDIRECTION_TOSDIO SDIO_DATACTL_DATADIR /*!< read data from card */ + +/* SDIO idma buffer mode */ +#define SDIO_IDMA_SINGLE_BUFFER (uint32_t)0x00000000U /*!< single buffer mode */ +#define SDIO_IDMA_DOUBLE_BUFFER SDIO_IDMACTL_BUFMOD /*!< double buffer mode */ + +/* SDIO idma buffer selection */ +#define SDIO_IDMA_BUFFER0 (uint32_t)0x00000000U /*!< select buffer0 */ +#define SDIO_IDMA_BUFFER1 SDIO_IDMACTL_BUFSEL /*!< select buffer1 */ + +/* constants definitions */ +/* SDIO flags */ +#define SDIO_FLAG_CCRCERR BIT(0) /*!< command response received (CRC check failed) flag */ +#define SDIO_FLAG_DTCRCERR BIT(1) /*!< data block sent/received (CRC check failed) flag */ +#define SDIO_FLAG_CMDTMOUT BIT(2) /*!< command response timeout flag */ +#define SDIO_FLAG_DTTMOUT BIT(3) /*!< data timeout flag */ +#define SDIO_FLAG_TXURE BIT(4) /*!< transmit FIFO underrun error occurs flag */ +#define SDIO_FLAG_RXORE BIT(5) /*!< received FIFO overrun error occurs flag */ +#define SDIO_FLAG_CMDRECV BIT(6) /*!< command response received (CRC check passed) flag */ +#define SDIO_FLAG_CMDSEND BIT(7) /*!< command sent (no response required) flag */ +#define SDIO_FLAG_DTEND BIT(8) /*!< data end (data counter, SDIO_DATACNT is zero) flag */ +#define SDIO_FLAG_DTHOLD BIT(9) /*!< data transfer hold flag */ +#define SDIO_FLAG_DTBLKEND BIT(10) /*!< data block sent/received (CRC check passed) flag */ +#define SDIO_FLAG_DTABORT BIT(11) /*!< data transfer aborted by CMD12 flag */ +#define SDIO_FLAG_CMDSTA BIT(12) /*!< command path active state flag */ +#define SDIO_FLAG_DATSTA BIT(13) /*!< data path active state flag */ +#define SDIO_FLAG_TFH BIT(14) /*!< transmit FIFO is half empty flag: at least 8 words can be written into the FIFO */ +#define SDIO_FLAG_RFH BIT(15) /*!< receive FIFO is half full flag: at least 8 words can be read in the FIFO */ +#define SDIO_FLAG_TFF BIT(16) /*!< transmit FIFO is full flag */ +#define SDIO_FLAG_RFF BIT(17) /*!< receive FIFO is full flag */ +#define SDIO_FLAG_TFE BIT(18) /*!< transmit FIFO is empty flag */ +#define SDIO_FLAG_RFE BIT(19) /*!< receive FIFO is empty flag */ +#define SDIO_FLAG_DAT0BSY BIT(20) /*!< DAT0 line signal keep busy flag */ +#define SDIO_FLAG_DAT0BSYEND BIT(21) /*!< DAT0 line signal changed from busy to ready flag */ +#define SDIO_FLAG_SDIOINT BIT(22) /*!< SD I/O interrupt received flag */ +#define SDIO_FLAG_ACKFAIL BIT(23) /*!< boot acknowledgment received and check fail flag */ +#define SDIO_FLAG_ACKTO BIT(24) /*!< boot acknowledgment timeout flag */ +#define SDIO_FLAG_VOLSWEND BIT(25) /*!< voltage switch critical timing section end flag */ +#define SDIO_FLAG_CLKSTOP BIT(26) /*!< SDIO_CLK stopped in voltage switch procedure flag */ +#define SDIO_FLAG_IDMAERR BIT(27) /*!< IDMA transfer error flag */ +#define SDIO_FLAG_IDMAEND BIT(28) /*!< IDMA transfer end flag */ + +/* SDIO interrupt enable or disable */ +#define SDIO_INT_CCRCERR BIT(0) /*!< SDIO CCRCERR interrupt */ +#define SDIO_INT_DTCRCERR BIT(1) /*!< SDIO DTCRCERR interrupt */ +#define SDIO_INT_CMDTMOUT BIT(2) /*!< SDIO CMDTMOUT interrupt */ +#define SDIO_INT_DTTMOUT BIT(3) /*!< SDIO DTTMOUT interrupt */ +#define SDIO_INT_TXURE BIT(4) /*!< SDIO TXURE interrupt */ +#define SDIO_INT_RXORE BIT(5) /*!< SDIO RXORE interrupt */ +#define SDIO_INT_CMDRECV BIT(6) /*!< SDIO CMDRECV interrupt */ +#define SDIO_INT_CMDSEND BIT(7) /*!< SDIO CMDSEND interrupt */ +#define SDIO_INT_DTEND BIT(8) /*!< SDIO DTEND interrupt */ +#define SDIO_INT_DTHOLD BIT(9) /*!< SDIO DTHOLD interrupt */ +#define SDIO_INT_DTBLKEND BIT(10) /*!< SDIO DTBLKEND interrupt */ +#define SDIO_INT_DTABORT BIT(11) /*!< SDIO DTABORT interrupt */ +#define SDIO_INT_TFH BIT(14) /*!< SDIO TFH interrupt */ +#define SDIO_INT_RFH BIT(15) /*!< SDIO RFH interrupt */ +#define SDIO_INT_RFF BIT(17) /*!< SDIO RFF interrupt */ +#define SDIO_INT_TFE BIT(18) /*!< SDIO TFE interrupt */ +#define SDIO_INT_DAT0BSYEND BIT(21) /*!< SDIO DAT0BSYEND interrupt */ +#define SDIO_INT_SDIOINT BIT(22) /*!< SDIO SDIOINT interrupt */ +#define SDIO_INT_ACKFAIL BIT(23) /*!< SDIO ACKFAIL interrupt */ +#define SDIO_INT_ACKTO BIT(24) /*!< SDIO ACKTO interrupt */ +#define SDIO_INT_VOLSWEND BIT(25) /*!< SDIO VOLSWEND interrupt */ +#define SDIO_INT_CLKSTOP BIT(26) /*!< SDIO CLKSTOP interrupt */ +#define SDIO_INT_IDMAERR BIT(27) /*!< SDIO IDMAERR interrupt */ +#define SDIO_INT_IDMAEND BIT(28) /*!< SDIO IDMAEND interrupt */ + +/* SDIO interrupt flag: enable or disable */ +#define SDIO_INT_FLAG_CCRCERR BIT(0) /*!< SDIO CCRCERR interrupt flag */ +#define SDIO_INT_FLAG_DTCRCERR BIT(1) /*!< SDIO DTCRCERR interrupt flag */ +#define SDIO_INT_FLAG_CMDTMOUT BIT(2) /*!< SDIO CMDTMOUT interrupt flag */ +#define SDIO_INT_FLAG_DTTMOUT BIT(3) /*!< SDIO DTTMOUT interrupt flag */ +#define SDIO_INT_FLAG_TXURE BIT(4) /*!< SDIO TXURE interrupt flag */ +#define SDIO_INT_FLAG_RXORE BIT(5) /*!< SDIO RXORE interrupt flag */ +#define SDIO_INT_FLAG_CMDRECV BIT(6) /*!< SDIO CMDRECV interrupt flag */ +#define SDIO_INT_FLAG_CMDSEND BIT(7) /*!< SDIO CMDSEND interrupt flag */ +#define SDIO_INT_FLAG_DTEND BIT(8) /*!< SDIO DTEND interrupt flag */ +#define SDIO_INT_FLAG_DTHOLD BIT(9) /*!< SDIO DTHOLD interrupt flag */ +#define SDIO_INT_FLAG_DTBLKEND BIT(10) /*!< SDIO DTBLKEND interrupt flag */ +#define SDIO_INT_FLAG_DTABORT BIT(11) /*!< SDIO DTABORT interrupt flag */ +#define SDIO_INT_FLAG_TFH BIT(14) /*!< SDIO TFH interrupt flag */ +#define SDIO_INT_FLAG_RFH BIT(15) /*!< SDIO RFH interrupt flag */ +#define SDIO_INT_FLAG_RFF BIT(17) /*!< SDIO RFF interrupt flag */ +#define SDIO_INT_FLAG_TFE BIT(18) /*!< SDIO TFE interrupt flag */ +#define SDIO_INT_FLAG_DAT0BSYEND BIT(21) /*!< SDIO DAT0BSYEND interrupt flag */ +#define SDIO_INT_FLAG_SDIOINT BIT(22) /*!< SDIO SDIOINT interrupt flag */ +#define SDIO_INT_FLAG_ACKFAIL BIT(23) /*!< SDIO ACKFAIL interrupt flag */ +#define SDIO_INT_FLAG_ACKTO BIT(24) /*!< SDIO ACKTO interrupt flag */ +#define SDIO_INT_FLAG_VOLSWEND BIT(25) /*!< SDIO VOLSWEND interrupt flag */ +#define SDIO_INT_FLAG_CLKSTOP BIT(26) /*!< SDIO CLKSTOP interrupt flag */ +#define SDIO_INT_FLAG_IDMAERR BIT(27) /*!< SDIO IDMAERR interrupt flag */ +#define SDIO_INT_FLAG_IDMAEND BIT(28) /*!< SDIO IDMAEND interrupt flag */ + +/* SDIO read wait type */ +#define SDIO_READWAITTYPE_DAT2 (uint32_t)0x00000000U /*!< read wait control using SDIO_DAT[2] */ +#define SDIO_READWAITTYPE_CLK SDIO_DATACTL_RWTYPE /*!< read wait control by stopping SDIO_CLK */ + +/* function declarations */ +/* de/initialization functions, hardware clock, bus mode, power_state and SDIO clock configuration */ +/* deinitialize the SDIO */ +void sdio_deinit(uint32_t sdio_periph); +/* configure the SDIO clock */ +void sdio_clock_config(uint32_t sdio_periph, uint32_t clock_edge, uint32_t clock_powersave, uint32_t clock_division); +/* set receive clock */ +void sdio_clock_receive_set(uint32_t sdio_periph, uint32_t clock_receive); +/* enable hardware clock control */ +void sdio_hardware_clock_enable(uint32_t sdio_periph); +/* disable hardware clock control */ +void sdio_hardware_clock_disable(uint32_t sdio_periph); +/* set different SDIO card bus mode */ +void sdio_bus_mode_set(uint32_t sdio_periph, uint32_t bus_mode); +/* set SDIO bus speed */ +void sdio_bus_speed_set(uint32_t sdio_periph, uint32_t bus_speed); +/* set SDIO data rate */ +void sdio_data_rate_set(uint32_t sdio_periph, uint32_t data_rate); +/* set direction polarity of data and command */ +void sdio_direction_polarity_set(uint32_t sdio_periph, uint32_t dirpl); +/* set the SDIO power state */ +void sdio_power_state_set(uint32_t sdio_periph, uint32_t power_state); +/* get the SDIO power state */ +uint32_t sdio_power_state_get(uint32_t sdio_periph); + +/* configure the command index, argument, command type, response type, wait type and CSM(command state machine) to send command functions */ +/* configure the command and response */ +void sdio_command_response_config(uint32_t sdio_periph, uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type); +/* set the command state machine wait type */ +void sdio_wait_type_set(uint32_t sdio_periph, uint32_t wait_type); +/* enable the CSM transfer command mode(treats the command as a data transfer command) */ +void sdio_trans_start_enable(uint32_t sdio_periph); +/* disable the CSM transfer command mode(treats the command as a data transfer command) */ +void sdio_trans_start_disable(uint32_t sdio_periph); +/* enable the CSM stop command mode(treats the command as a data stop transfer command) */ +void sdio_trans_stop_enable(uint32_t sdio_periph); +/* disable the CSM stop command mode(treats the command as a data stop transfer command) */ +void sdio_trans_stop_disable(uint32_t sdio_periph); +/* enable the CSM(command state machine) */ +void sdio_csm_enable(uint32_t sdio_periph); +/* disable the CSM(command state machine) */ +void sdio_csm_disable(uint32_t sdio_periph); +/* get the last response command index */ +uint8_t sdio_command_index_get(uint32_t sdio_periph); +/* get the response for the last received command */ +uint32_t sdio_response_get(uint32_t sdio_periph, uint32_t sdio_responsex); +/* enable the data hold */ +void sdio_hold_enable(uint32_t sdio_periph); +/* disable the data hold */ +void sdio_hold_disable(uint32_t sdio_periph); +/* enable the SDIO suspend mode (the CSM treats the command as a Suspend command or Resume command) */ +void sdio_suspend_enable(uint32_t sdio_periph); +/* disable the SDIO suspend mode (the CSM treats the command as a Suspend command or Resume command) */ +void sdio_suspend_disable(uint32_t sdio_periph); + +/* configure the data timeout, length, block size, transfer mode, direction and DSM for data transfer functions */ +/* configure the data timeout, data length and data block size */ +void sdio_data_config(uint32_t sdio_periph, uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize); +/* configure the data transfer mode and direction */ +void sdio_data_transfer_config(uint32_t sdio_periph, uint32_t transfer_mode, uint32_t transfer_direction); +/* enable the DSM(data state machine) for data transfer */ +void sdio_dsm_enable(uint32_t sdio_periph); +/* disable the DSM(data state machine) for data transfer */ +void sdio_dsm_disable(uint32_t sdio_periph); +/* write data(one word) to the transmit FIFO */ +void sdio_data_write(uint32_t sdio_periph, uint32_t data); +/* read data(one word) from the receive FIFO */ +uint32_t sdio_data_read(uint32_t sdio_periph); +/* get the number of remaining data bytes to be transferred to card */ +uint32_t sdio_data_counter_get(uint32_t sdio_periph); +/* enable the FIFO buffer reset */ +void sdio_fifo_reset_enable(uint32_t sdio_periph); +/* disable the FIFO buffer reset */ +void sdio_fifo_reset_disable(uint32_t sdio_periph); + +/* configure the IMDA */ +/* set IDMA buffer mode and size */ +void sdio_idma_set(uint32_t sdio_periph, uint32_t buffer_mode, uint32_t buffer_size); +/* set IDMA buffer0 address */ +void sdio_idma_buffer0_address_set(uint32_t sdio_periph, uint32_t buffer_address); +/* set IDMA buffer1 address */ +void sdio_idma_buffer1_address_set(uint32_t sdio_periph, uint32_t buffer_address); +/* get the IDMA double buffer address selection bit */ +uint32_t sdio_buffer_selection_get(uint32_t sdio_periph); +/* select IDMA buffer */ +void sdio_idma_buffer_select(uint32_t sdio_periph, uint32_t buffer_select); +/* enable the IDMA request for SDIO */ +void sdio_idma_enable(uint32_t sdio_periph); +/* disable the IDMA request for SDIO */ +void sdio_idma_disable(uint32_t sdio_periph); + +/* flag and interrupt functions */ +/* get the flags state of SDIO */ +FlagStatus sdio_flag_get(uint32_t sdio_periph, uint32_t flag); +/* clear the pending flags of SDIO */ +void sdio_flag_clear(uint32_t sdio_periph, uint32_t flag); +/* enable the SDIO interrupt */ +void sdio_interrupt_enable(uint32_t sdio_periph, uint32_t int_flag); +/* disable the SDIO interrupt */ +void sdio_interrupt_disable(uint32_t sdio_periph, uint32_t int_flag); +/* get the interrupt flags state of SDIO */ +FlagStatus sdio_interrupt_flag_get(uint32_t sdio_periph, uint32_t int_flag); +/* clear the interrupt pending flags of SDIO */ +void sdio_interrupt_flag_clear(uint32_t sdio_periph, uint32_t int_flag); + +/* SDIO voltage switch functions */ +/* enable voltage switch */ +void sdio_voltage_switch_enable(uint32_t sdio_periph); +/* disable voltage switch */ +void sdio_voltage_switch_disable(uint32_t sdio_periph); +/* enable voltage switch sequence */ +void sdio_voltage_switch_sequence_enable(uint32_t sdio_periph); +/* disable voltage switch sequence */ +void sdio_voltage_switch_sequence_disable(uint32_t sdio_periph); + +/* SDIO boot function */ +/* set boot mode */ +void sdio_boot_mode_set(uint32_t sdio_periph, uint32_t boot_mode); +/* enbale DSM(data state machine) boot acknowledgment */ +void sdio_boot_ack_enable(uint32_t sdio_periph); +/* disbale DSM(data state machine) boot acknowledgment */ +void sdio_boot_ack_disable(uint32_t sdio_periph); +/* set boot ACK timeout period */ +void sdio_boot_acktimeout_set(uint32_t sdio_periph, uint32_t timeout); +/* enable boot operation */ +void sdio_boot_enable(uint32_t sdio_periph); +/* disable boot operation */ +void sdio_boot_disable(uint32_t sdio_periph); +#endif /* GD32H7XX_SDIO_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_spi.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_spi.h new file mode 100644 index 0000000000..97df7782a5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_spi.h @@ -0,0 +1,693 @@ +/*! + \file gd32h7xx_spi.h + \brief definitions for the SPI + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_SPI_H +#define GD32H7XX_SPI_H + +#include "gd32h7xx.h" + +/* SPIx(x=0,1,2,3,4,5) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE +#define SPI2 (SPI_BASE + 0x00000400U) +#define SPI3 (SPI_BASE + 0x0000FC00U) +#define SPI4 (SPI_BASE + 0x00011800U) +#define SPI5 (SPI_BASE + 0x00010000U) + +/* SPI registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_CFG0(spix) REG32((spix) + 0x08U) /*!< SPI configuration register 0 */ +#define SPI_CFG1(spix) REG32((spix) + 0x0CU) /*!< SPI configuration register 1 */ +#define SPI_INT(spix) REG32((spix) + 0x10U) /*!< SPI interrupt register */ +#define SPI_STAT(spix) REG32((spix) + 0x14U) /*!< SPI status register */ +#define SPI_STATC(spix) REG32((spix) + 0x18U) /*!< SPI interrupt/status flags clear register */ +#define SPI_TDATA(spix) REG32((spix) + 0x20U) /*!< SPI data transfer register */ +#define SPI_RDATA(spix) REG32((spix) + 0x30U) /*!< SPI data receive register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x40U) /*!< SPI CRC polynomial register */ +#define SPI_TCRC(spix) REG32((spix) + 0x44U) /*!< SPI TX CRC register */ +#define SPI_RCRC(spix) REG32((spix) + 0x48U) /*!< SPI RX CRC register */ +#define SPI_URDATA(spix) REG32((spix) + 0x4CU) /*!< SPI underrun data register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x50U) /*!< I2S control register */ +#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< quad_SPI mode control register(for SPI3/4) */ +#define SPI_RXDLYCK(spix) REG32((spix) + 0xFCU) /*!< SPI receive clock delay register */ + +/* bits definitions */ +/* SPI_CTL0 */ +#define SPI_CTL0_SPIEN BIT(0) /*!< SPI enable */ +#define SPI_CTL0_MASP BIT(8) /*!< the master is suspended automatically in receive mode */ +#define SPI_CTL0_MSTART BIT(9) /*!< master start transfer */ +#define SPI_CTL0_MSPDR BIT(10) /*!< suspend request in SPI master mode */ +#define SPI_CTL0_NSSI BIT(12) /*!< the input level to internal NSS signal */ +#define SPI_CTL0_CRCFS BIT(13) /*!< full scale CRC polynomial configuration */ +#define SPI_CTL0_RXCRCI BIT(14) /*!< the receiver CRC initialization configuration */ +#define SPI_CTL0_TXCRCI BIT(15) /*!< the transmitter CRC initialization configuration */ +#define SPI_CTL0_IOAFEN BIT(16) /*!< related IOs AF configuration enable */ + +/* SPI_CFG0 */ +#define SPI_CFG0_DZ BITS(0,4) /*!< data size */ +#define SPI_CFG0_FIFOLVL BITS(5,8) /*!< FIFO threshold level */ +#define SPI_CFG0_TXUROP BITS(9,10) /*!< operation of slave transmitter when underrun detected */ +#define SPI_CFG0_TXURDT BITS(11,12) /*!< detection of underrun error at slave transmitter */ +#define SPI_CFG0_DMAREN BIT(14) /*!< receive buffer DMA enable */ +#define SPI_CFG0_DMATEN BIT(15) /*!< transmit buffer DMA enable */ +#define SPI_CFG0_CRCSZ BITS(16,20) /*!< CRC size */ +#define SPI_CFG0_CRCEN BIT(22) /*!< CRC calculation enable */ +#define SPI_CFG0_BYTEN BIT(23) /*!< byte access enable */ +#define SPI_CFG0_WORDEN BIT(24) /*!< word access enable */ +#define SPI_CFG0_PSC BITS(28,30) /*!< master clock prescaler selection */ + +/* SPI_CFG1 */ +#define SPI_CFG1_MSSD BITS(0,3) /*!< delay between active edge of NSS and start transfer or receive data in SPI master mode */ +#define SPI_CFG1_MDFD BITS(4,7) /*!< delay between the data frames in SPI master mode */ +#define SPI_CFG1_SWPMIO BIT(15) /*!< MOSI and MISO pin swap */ +#define SPI_CFG1_RO BIT(16) /*!< receive only */ +#define SPI_CFG1_BDOEN BIT(17) /*!< bidirectional transmit output enable */ +#define SPI_CFG1_BDEN BIT(18) /*!< bidirectional enable */ +#define SPI_CFG1_TMOD BIT(21) /*!< SPI TI mode enable */ +#define SPI_CFG1_MSTMOD BIT(22) /*!< Master mode enable */ +#define SPI_CFG1_LF BIT(23) /*!< LSB first mode */ +#define SPI_CFG1_CKPH BIT(24) /*!< clock phase selection */ +#define SPI_CFG1_CKPL BIT(25) /*!< clock polarity selection */ +#define SPI_CFG1_NSSIM BIT(26) /*!< NSS input signal manage mode */ +#define SPI_CFG1_NSSIOPL BIT(28) /*!< NSS pin input/output polarity selection */ +#define SPI_CFG1_NSSDRV BIT(29) /*!< NSS pin output enable in master mode */ +#define SPI_CFG1_NSSCTL BIT(30) /*!< NSS pin output control in master mode */ +#define SPI_CFG1_AFCTL BIT(31) /*!< AF GPIOs control */ + +/* SPI_INT */ +#define SPI_INT_RPIE BIT(0) /*!< RP interrupt enable */ +#define SPI_INT_TPIE BIT(1) /*!< TP interrupt enable */ +#define SPI_INT_DPIE BIT(2) /*!< DP interrupt enable */ +#define SPI_INT_ESTCIE BIT(3) /*!< end of transfer or suspend or TXFIFO clear interrupt enable */ +#define SPI_INT_TXFIE BIT(4) /*!< transmission filled interrupt enable */ +#define SPI_INT_TXUREIE BIT(5) /*!< underrun error interrupt enable */ +#define SPI_INT_RXOREIE BIT(6) /*!< overrun error interrupt enable */ +#define SPI_INT_CRCERIE BIT(7) /*!< CRC error interrupt enable */ +#define SPI_INT_FEIE BIT(8) /*!< TI frame error interrupt enable */ +#define SPI_INT_CONFEIE BIT(9) /*!< SPI configuration error interrupt enable */ +#define SPI_INT_TXSERFIE BIT(10) /*!< TXSER reload interrupt enable */ + +/* SPI_STAT */ +#define SPI_STAT_RP BIT(0) /*!< RxFIFO packet space available flag */ +#define SPI_STAT_TP BIT(1) /*!< TxFIFO packet space available flag */ +#define SPI_STAT_DP BIT(2) /*!< duplex packet */ +#define SPI_STAT_ET BIT(3) /*!< End of transmission/reception flag */ +#define SPI_STAT_TXF BIT(4) /*!< TxFIFO transmission has been filled */ +#define SPI_STAT_TXURERR BIT(5) /*!< transmission underrun error */ +#define SPI_STAT_RXORERR BIT(6) /*!< reception overrun error */ +#define SPI_STAT_CRCERR BIT(7) /*!< SPI CRC error */ +#define SPI_STAT_FERR BIT(8) /*!< SPI TI format error */ +#define SPI_STAT_CONFERR BIT(9) /*!< SPI configuration error */ +#define SPI_STAT_TXSERF BIT(10) /*!< The additional SPI data has been reloaded */ +#define SPI_STAT_SPD BIT(11) /*!< suspend flsg */ +#define SPI_STAT_TC BIT(12) /*!< TxFIFO transmission complete flag */ +#define SPI_STAT_RPLVL BITS(13,14) /*!< RxFIFO packing level */ +#define SPI_STAT_RWNE BIT(15) /*!< the word of RXFIFO is not empty */ +#define SPI_STAT_CTXSIZE BITS(16,31) /*!< the number of data frames remaining in the TXSIZE session */ + +/* SPI_STATC */ +#define SPI_STATC_ETC BIT(3) /*!< Clear the end of transmission/reception flag */ +#define SPI_STATC_TXFC BIT(4) /*!< Clear the TxFIFO transmission filled flag */ +#define SPI_STATC_TXURERRC BIT(5) /*!< clear the transmission underrun error flag */ +#define SPI_STATC_RXORERRC BIT(6) /*!< clear the reception overrun error flag */ +#define SPI_STATC_CRCERRC BIT(7) /*!< clear the CRC error flag */ +#define SPI_STATC_FERRC BIT(8) /*!< clear the SPI TI format error flag */ +#define SPI_STATC_CONFERRC BIT(9) /*!< clear the configuration error flag */ +#define SPI_STATC_TXSERFC BIT(10) /*!< clear the TXSERF flag */ +#define SPI_STATC_SPDC BIT(11) /*!< clear the suspend flag */ + +/* SPI_TDATA */ +#define SPI_TDATA_TDATA BITS(0,31) /*!< data transfer register */ + +/* SPI_RDATA */ +#define SPI_RDATA_RDATA BITS(0,31) /*!< data receive register */ + +/* SPI_CRCPOLY */ +#define SPI_CRCPOLY_CRCPOLY BITS(0,31) /*!< CRC polynomial register */ + +/* SPI_TCRC */ +#define SPI_TCRC_TCRC BITS(0,31) /*!< Tx CRC register */ + +/* SPI_RCRC */ +#define SPI_RCRC_RCRC BITS(0,31) /*!< Rx CRC register */ + +/* SPI_URDATA */ +#define SPI_URDATA_URDATA BITS(0,31) /*!< transmission underrun data at slave mode */ + +/* SPI_I2SCTL */ +#define SPI_I2SCTL_CHLEN BIT(0) /*!< channel length */ +#define SPI_I2SCTL_DTLEN BITS(1,2) /*!< data length */ +#define SPI_I2SCTL_CKPL BIT(3) /*!< idle state clock polarity */ +#define SPI_I2SCTL_I2SSTD BITS(4,5) /*!< I2S standard selection */ +#define SPI_I2SCTL_PCMSMOD BIT(7) /*!< PCM frame synchronization mode */ +#define SPI_I2SCTL_I2SOPMOD BITS(8,9) /*!< I2S operation mode */ +#define SPI_I2SCTL_I2SEN BIT(10) /*!< I2S enable */ +#define SPI_I2SCTL_I2SSEL BIT(11) /*!< I2S mode selection */ +#define SPI_I2SCTL_DIV BITS(16,23) /*!< dividing factor for the prescaler */ +#define SPI_I2SCTL_OF BIT(24) /*!< odd factor for the prescaler */ +#define SPI_I2SCTL_MCKOEN BIT(25) /*!< I2S_MCK output enable */ +#define SPI_I2SCTL_I2SCH BIT(31) /*!< I2S Channel side */ + +/* SPI_QCTL(only for SPI3/4) */ +#define SPI_QCTL_QMOD BIT(0) /*!< quad-SPI mode enable */ +#define SPI_QCTL_QRD BIT(1) /*!< quad-SPI mode read select */ +#define SPI_QCTL_IO23_DRV BIT(2) /*!< drive SPI_IO2 and SPI_IO3 enable */ + +/* SPI_RXDLYCK */ +#define SPI_RXDLYCK_SRXD BITS(0,4) /*!< slave mode receive clock delay units*/ +#define SPI_RXDLYCK_SRXDEN BIT(5) /*!< slave mode receive clock delay enable*/ +#define SPI_RXDLYCK_MRXD BITS(6,10) /*!< master mode receive clock delay units*/ +#define SPI_RXDLYCK_MRXDEN BIT(11) /*!< master mode receive clock delay enable*/ + +/* constants definitions */ +/* SPI and I2S parameter struct definitions */ +typedef struct +{ + uint32_t device_mode; /*!< SPI master or slave */ + uint32_t trans_mode; /*!< SPI transtype */ + uint32_t data_size; /*!< SPI data frame size */ + uint32_t nss; /*!< SPI NSS control by handware or software */ + uint32_t endian; /*!< SPI big endian or little endian */ + uint32_t clock_polarity_phase; /*!< SPI clock phase and polarity */ + uint32_t prescale; /*!< SPI prescale factor */ +}spi_parameter_struct; + +/* SPI suspend in receive mode */ +#define SPI_AUTO_SUSPEND SPI_CTL0_MASP /*!< until the overrun condition is reached, the SPI stream is suspended in the full RxFIFO state */ +#define SPI_CONTINUOUS ((uint32_t)0x00000000U) /*!< SPI stream/clock generation is continuous whether or not an overrun occurs */ + +/* SPI master start transfer */ +#define SPI_TRANS_START SPI_CTL0_MSTART /*!< the master transmission is occurring, or has been temporarily suspended by automatic suspend */ +#define SPI_TRANS_IDLE ((uint32_t)0x00000000U) /*!< the master transfer is idle status */ + +/* SPI NSS input level */ +#define SPI_NSS_LEVEL_HIGH SPI_CTL0_NSSI /*!< NSS pin is pulled high */ +#define SPI_NSS_LEVEL_LOW ((uint32_t)0x00000000U) /*!< NSS pin is pulled low */ + +/* SPI TCRC init pattern */ +#define SPI_TCRC_INIT_1 SPI_CTL0_TXCRCI /*!< use all 1 pattern */ +#define SPI_TCRC_INIT_0 ((uint32_t)0x00000000U) /*!< use all 0 pattern */ + +/* SPI RCRC init pattern */ +#define SPI_RCRC_INIT_1 SPI_CTL0_RXCRCI /*!< use all 1 pattern */ +#define SPI_RCRC_INIT_0 ((uint32_t)0x00000000U) /*!< use all 0 pattern */ + +/* SPI data frame size */ +#define CFG0_DZ(regval) (BITS(0,4) & ((uint32_t)(regval) << 0)) +#define SPI_DATASIZE_4BIT CFG0_DZ(3) /*!< SPI data frame size is 4-bit */ +#define SPI_DATASIZE_5BIT CFG0_DZ(4) /*!< SPI data frame size is 5-bit */ +#define SPI_DATASIZE_6BIT CFG0_DZ(5) /*!< SPI data frame size is 6-bit */ +#define SPI_DATASIZE_7BIT CFG0_DZ(6) /*!< SPI data frame size is 7-bit */ +#define SPI_DATASIZE_8BIT CFG0_DZ(7) /*!< SPI data frame size is 8-bit */ +#define SPI_DATASIZE_9BIT CFG0_DZ(8) /*!< SPI data frame size is 9-bit */ +#define SPI_DATASIZE_10BIT CFG0_DZ(9) /*!< SPI data frame size is 10-bit */ +#define SPI_DATASIZE_11BIT CFG0_DZ(10) /*!< SPI data frame size is 11-bit */ +#define SPI_DATASIZE_12BIT CFG0_DZ(11) /*!< SPI data frame size is 12-bit */ +#define SPI_DATASIZE_13BIT CFG0_DZ(12) /*!< SPI data frame size is 13-bit */ +#define SPI_DATASIZE_14BIT CFG0_DZ(13) /*!< SPI data frame size is 14-bit */ +#define SPI_DATASIZE_15BIT CFG0_DZ(14) /*!< SPI data frame size is 15-bit */ +#define SPI_DATASIZE_16BIT CFG0_DZ(15) /*!< SPI data frame size is 16-bit */ +#define SPI_DATASIZE_17BIT CFG0_DZ(16) /*!< SPI data frame size is 17-bit */ +#define SPI_DATASIZE_18BIT CFG0_DZ(17) /*!< SPI data frame size is 18-bit */ +#define SPI_DATASIZE_19BIT CFG0_DZ(18) /*!< SPI data frame size is 19-bit */ +#define SPI_DATASIZE_20BIT CFG0_DZ(19) /*!< SPI data frame size is 20-bit */ +#define SPI_DATASIZE_21BIT CFG0_DZ(20) /*!< SPI data frame size is 21-bit */ +#define SPI_DATASIZE_22BIT CFG0_DZ(21) /*!< SPI data frame size is 22-bit */ +#define SPI_DATASIZE_23BIT CFG0_DZ(22) /*!< SPI data frame size is 23-bit */ +#define SPI_DATASIZE_24BIT CFG0_DZ(23) /*!< SPI data frame size is 24-bit */ +#define SPI_DATASIZE_25BIT CFG0_DZ(24) /*!< SPI data frame size is 25-bit */ +#define SPI_DATASIZE_26BIT CFG0_DZ(25) /*!< SPI data frame size is 26-bit */ +#define SPI_DATASIZE_27BIT CFG0_DZ(26) /*!< SPI data frame size is 27-bit */ +#define SPI_DATASIZE_28BIT CFG0_DZ(27) /*!< SPI data frame size is 28-bit */ +#define SPI_DATASIZE_29BIT CFG0_DZ(28) /*!< SPI data frame size is 29-bit */ +#define SPI_DATASIZE_30BIT CFG0_DZ(29) /*!< SPI data frame size is 30-bit */ +#define SPI_DATASIZE_31BIT CFG0_DZ(30) /*!< SPI data frame size is 31-bit */ +#define SPI_DATASIZE_32BIT CFG0_DZ(31) /*!< SPI data frame size is 32-bit */ + +/* SPI FIFO threshold level */ +#define CFG0_FIFOLVL(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#define SPI_FIFO_TH_01DATA CFG0_FIFOLVL(0) /*!< set FIFO threshold level = 1-data frame */ +#define SPI_FIFO_TH_02DATA CFG0_FIFOLVL(1) /*!< set FIFO threshold level = 2-data frame */ +#define SPI_FIFO_TH_03DATA CFG0_FIFOLVL(2) /*!< set FIFO threshold level = 3-data frame */ +#define SPI_FIFO_TH_04DATA CFG0_FIFOLVL(3) /*!< set FIFO threshold level = 4-data frame */ +#define SPI_FIFO_TH_05DATA CFG0_FIFOLVL(4) /*!< set FIFO threshold level = 5-data frame */ +#define SPI_FIFO_TH_06DATA CFG0_FIFOLVL(5) /*!< set FIFO threshold level = 6-data frame */ +#define SPI_FIFO_TH_07DATA CFG0_FIFOLVL(6) /*!< set FIFO threshold level = 7-data frame */ +#define SPI_FIFO_TH_08DATA CFG0_FIFOLVL(7) /*!< set FIFO threshold level = 8-data frame */ +#define SPI_FIFO_TH_09DATA CFG0_FIFOLVL(8) /*!< set FIFO threshold level = 9-data frame */ +#define SPI_FIFO_TH_10DATA CFG0_FIFOLVL(9) /*!< set FIFO threshold level = 10-data frame */ +#define SPI_FIFO_TH_11DATA CFG0_FIFOLVL(10) /*!< set FIFO threshold level = 11-data frame */ +#define SPI_FIFO_TH_12DATA CFG0_FIFOLVL(11) /*!< set FIFO threshold level = 12-data frame */ +#define SPI_FIFO_TH_13DATA CFG0_FIFOLVL(12) /*!< set FIFO threshold level = 13-data frame */ +#define SPI_FIFO_TH_14DATA CFG0_FIFOLVL(13) /*!< set FIFO threshold level = 14-data frame */ +#define SPI_FIFO_TH_15DATA CFG0_FIFOLVL(14) /*!< set FIFO threshold level = 15-data frame */ +#define SPI_FIFO_TH_16DATA CFG0_FIFOLVL(15) /*!< set FIFO threshold level = 16-data frame */ + +/* SPI slave transmitter underrun detected operation */ +#define CFG0_TXUROP(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define SPI_CONFIG_REGISTER_PATTERN CFG0_TXUROP(0) /*!< slave send a constant value defined by the SPI_URDATA register */ +#define SPI_CONFIG_LAST_RECEIVED CFG0_TXUROP(1) /*!< slave send the data frame received from master lastly */ +#define SPI_CONFIG_LAST_TRANSMITTED CFG0_TXUROP(2) /*!< Slave send the data frame which is lastly transmitted by itself */ + +/* SPI slave transmitter underrun detected config */ +#define CFG0_TXURDT(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) +#define SPI_DETECT_BEGIN_DATA_FRAME CFG0_TXURDT(0) /*!< underrun detected at start of data frame (no bit 1 protection) */ +#define SPI_DETECT_END_DATA_FRAME CFG0_TXURDT(1) /*!< underrun detected at end of last data frame */ +#define SPI_DETECT_BEGIN_ACTIVE_NSS CFG0_TXURDT(2) /*!< underrun detected at start of NSS signal */ + +/* SPI CRC size */ +#define CFG0_CRCSZ(regval) (BITS(16,20) & ((uint32_t)(regval) << 16)) +#define SPI_CRCSIZE_4BIT CFG0_CRCSZ(3) /*!< SPI crc size is 4-bit */ +#define SPI_CRCSIZE_5BIT CFG0_CRCSZ(4) /*!< SPI crc size is 5-bit */ +#define SPI_CRCSIZE_6BIT CFG0_CRCSZ(5) /*!< SPI crc size is 6-bit */ +#define SPI_CRCSIZE_7BIT CFG0_CRCSZ(6) /*!< SPI crc size is 7-bit */ +#define SPI_CRCSIZE_8BIT CFG0_CRCSZ(7) /*!< SPI crc size is 8-bit */ +#define SPI_CRCSIZE_9BIT CFG0_CRCSZ(8) /*!< SPI crc size is 9-bit */ +#define SPI_CRCSIZE_10BIT CFG0_CRCSZ(9) /*!< SPI crc size is 10-bit */ +#define SPI_CRCSIZE_11BIT CFG0_CRCSZ(10) /*!< SPI crc size is 11-bit */ +#define SPI_CRCSIZE_12BIT CFG0_CRCSZ(11) /*!< SPI crc size is 12-bit */ +#define SPI_CRCSIZE_13BIT CFG0_CRCSZ(12) /*!< SPI crc size is 13-bit */ +#define SPI_CRCSIZE_14BIT CFG0_CRCSZ(13) /*!< SPI crc size is 14-bit */ +#define SPI_CRCSIZE_15BIT CFG0_CRCSZ(14) /*!< SPI crc size is 15-bit */ +#define SPI_CRCSIZE_16BIT CFG0_CRCSZ(15) /*!< SPI crc size is 16-bit */ +#define SPI_CRCSIZE_17BIT CFG0_CRCSZ(16) /*!< SPI crc size is 17-bit */ +#define SPI_CRCSIZE_18BIT CFG0_CRCSZ(17) /*!< SPI crc size is 18-bit */ +#define SPI_CRCSIZE_19BIT CFG0_CRCSZ(18) /*!< SPI crc size is 19-bit */ +#define SPI_CRCSIZE_20BIT CFG0_CRCSZ(19) /*!< SPI crc size is 20-bit */ +#define SPI_CRCSIZE_21BIT CFG0_CRCSZ(20) /*!< SPI crc size is 21-bit */ +#define SPI_CRCSIZE_22BIT CFG0_CRCSZ(21) /*!< SPI crc size is 22-bit */ +#define SPI_CRCSIZE_23BIT CFG0_CRCSZ(22) /*!< SPI crc size is 23-bit */ +#define SPI_CRCSIZE_24BIT CFG0_CRCSZ(23) /*!< SPI crc size is 24-bit */ +#define SPI_CRCSIZE_25BIT CFG0_CRCSZ(24) /*!< SPI crc size is 25-bit */ +#define SPI_CRCSIZE_26BIT CFG0_CRCSZ(25) /*!< SPI crc size is 26-bit */ +#define SPI_CRCSIZE_27BIT CFG0_CRCSZ(26) /*!< SPI crc size is 27-bit */ +#define SPI_CRCSIZE_28BIT CFG0_CRCSZ(27) /*!< SPI crc size is 28-bit */ +#define SPI_CRCSIZE_29BIT CFG0_CRCSZ(28) /*!< SPI crc size is 29-bit */ +#define SPI_CRCSIZE_30BIT CFG0_CRCSZ(29) /*!< SPI crc size is 30-bit */ +#define SPI_CRCSIZE_31BIT CFG0_CRCSZ(30) /*!< SPI crc size is 31-bit */ +#define SPI_CRCSIZE_32BIT CFG0_CRCSZ(31) /*!< SPI crc size is 32-bit */ + +/* SPI clock prescale factor */ +#define CFG0_PSC(regval) (BITS(28,30) & ((uint32_t)(regval) << 28)) +#define SPI_PSC_2 CFG0_PSC(0) /*!< SPI clock prescale factor is 2 */ +#define SPI_PSC_4 CFG0_PSC(1) /*!< SPI clock prescale factor is 4 */ +#define SPI_PSC_8 CFG0_PSC(2) /*!< SPI clock prescale factor is 8 */ +#define SPI_PSC_16 CFG0_PSC(3) /*!< SPI clock prescale factor is 16 */ +#define SPI_PSC_32 CFG0_PSC(4) /*!< SPI clock prescale factor is 32 */ +#define SPI_PSC_64 CFG0_PSC(5) /*!< SPI clock prescale factor is 64 */ +#define SPI_PSC_128 CFG0_PSC(6) /*!< SPI clock prescale factor is 128 */ +#define SPI_PSC_256 CFG0_PSC(7) /*!< SPI clock prescale factor is 256 */ + +/* SPI NSS idleness delay */ +#define CFG1_MSSD(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define SPI_NSS_IDLENESS_00CYCLE CFG1_MSSD(0) /*!< no delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_01CYCLE CFG1_MSSD(1) /*!< 1 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_02CYCLE CFG1_MSSD(2) /*!< 2 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_03CYCLE CFG1_MSSD(3) /*!< 3 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_04CYCLE CFG1_MSSD(4) /*!< 4 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_05CYCLE CFG1_MSSD(5) /*!< 5 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_06CYCLE CFG1_MSSD(6) /*!< 6 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_07CYCLE CFG1_MSSD(7) /*!< 7 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_08CYCLE CFG1_MSSD(8) /*!< 8 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_09CYCLE CFG1_MSSD(9) /*!< 9 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_10CYCLE CFG1_MSSD(10) /*!< 10 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_11CYCLE CFG1_MSSD(11) /*!< 11 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_12CYCLE CFG1_MSSD(12) /*!< 12 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_13CYCLE CFG1_MSSD(13) /*!< 13 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_14CYCLE CFG1_MSSD(14) /*!< 14 clock cycle delay between active edge of NSS and transmittion */ +#define SPI_NSS_IDLENESS_15CYCLE CFG1_MSSD(15) /*!< 15 clock cycle delay between active edge of NSS and transmittion */ + +/* SPI master data frame delay */ +#define CFG1_MDFD(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define SPI_DATA_IDLENESS_00CYCLE CFG1_MDFD(0) /*!< no delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_01CYCLE CFG1_MDFD(1) /*!< 1 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_02CYCLE CFG1_MDFD(2) /*!< 2 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_03CYCLE CFG1_MDFD(3) /*!< 3 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_04CYCLE CFG1_MDFD(4) /*!< 4 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_05CYCLE CFG1_MDFD(5) /*!< 5 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_06CYCLE CFG1_MDFD(6) /*!< 6 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_07CYCLE CFG1_MDFD(7) /*!< 7 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_08CYCLE CFG1_MDFD(8) /*!< 8 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_09CYCLE CFG1_MDFD(9) /*!< 9 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_10CYCLE CFG1_MDFD(10) /*!< 10 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_11CYCLE CFG1_MDFD(11) /*!< 11 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_12CYCLE CFG1_MDFD(12) /*!< 12 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_13CYCLE CFG1_MDFD(13) /*!< 13 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_14CYCLE CFG1_MDFD(14) /*!< 14 clock cycle delay between data frames in SPI master mode */ +#define SPI_DATA_IDLENESS_15CYCLE CFG1_MDFD(15) /*!< 15 clock cycle delay between data frames in SPI master mode */ + +/* SPI IO swap */ +#define SPI_IO_SWAP SPI_CFG1_SWPMIO /*!< SPI MOSI and MISO swap */ +#define SPI_IO_NORMAL (~SPI_CFG1_SWPMIO) /*!< SPI MOSI and MISO no swap */ + +/* SPI bidirectional transfer direction */ +#define SPI_BIDIRECTIONAL_TRANSMIT SPI_CFG1_BDOEN /*!< SPI work in transmit-only mode */ +#define SPI_BIDIRECTIONAL_RECEIVE (~SPI_CFG1_BDOEN) /*!< SPI work in receive-only mode */ + +/* SPI transmit type */ +#define SPI_TRANSMODE_FULLDUPLEX ((uint32_t)0x00000000U) /*!< SPI receive and send data at fullduplex communication */ +#define SPI_TRANSMODE_RECEIVEONLY SPI_CFG1_RO /*!< SPI only receive data */ +#define SPI_TRANSMODE_BDRECEIVE SPI_CFG1_BDEN /*!< bidirectional receive data */ +#define SPI_TRANSMODE_BDTRANSMIT (SPI_CFG1_BDEN | SPI_CFG1_BDOEN) /*!< bidirectional transmit data*/ + +/* SPI mode definitions */ +#define SPI_MASTER SPI_CFG1_MSTMOD /*!< SPI as master */ +#define SPI_SLAVE ((uint32_t)0x00000000U) /*!< SPI as slave */ + +/* SPI transmit way */ +#define SPI_ENDIAN_MSB ((uint32_t)0x00000000U) /*!< SPI transmit way is big endian: transmit MSB first */ +#define SPI_ENDIAN_LSB SPI_CFG1_LF /*!< SPI transmit way is little endian: transmit LSB first */ + +/* SPI clock phase and polarity */ +#define SPI_CK_PL_LOW_PH_1EDGE ((uint32_t)0x00000000U) /*!< SPI clock polarity is low level and phase is first edge */ +#define SPI_CK_PL_HIGH_PH_1EDGE SPI_CFG1_CKPL /*!< SPI clock polarity is high level and phase is first edge */ +#define SPI_CK_PL_LOW_PH_2EDGE SPI_CFG1_CKPH /*!< SPI clock polarity is low level and phase is second edge */ +#define SPI_CK_PL_HIGH_PH_2EDGE (SPI_CFG1_CKPL | SPI_CFG1_CKPH) /*!< SPI clock polarity is high level and phase is second edge */ + +/* SPI NSS control mode */ +#define SPI_NSS_SOFT SPI_CFG1_NSSIM /*!< SPI NSS control by sofrware */ +#define SPI_NSS_HARD ((uint32_t)0x00000000U) /*!< SPI NSS control by hardware */ + +/* SPI NSS polarity */ +#define SPI_NSS_POLARITY_HIGH SPI_CFG1_NSSIOPL /*!< SPI NSS high level is active */ +#define SPI_NSS_POLARITY_LOW ((uint32_t)0x00000000U) /*!< SPI NSS low level is active */ + +/* SPI NSS output control */ +#define SPI_NSS_INVALID_PULSE SPI_CFG1_NSSCTL /*!< SPI data frames are interleaved with NSS invalid pulses */ +#define SPI_NSS_HOLD_UNTIL_TRANS_END ((uint32_t)0x00000000U) /*!< SPI NSS remains active level until data transfer complete */ + +/* SPI af gpio control */ +#define SPI_GPIO_CONTROL SPI_CFG1_AFCTL /*!< SPI always control all associated GPIO */ +#define SPI_GPIO_FREE ((uint32_t)0x00000000U) /*!< SPI do not control GPIO when disabled */ + +/* SPI RxFIFO packing level */ +#define STAT_RPLVL(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) +#define SPI_RX_FIFO_0PACKET STAT_RPLVL(0) /*!< no frame or 4 frames stored in RxFIFO */ +#define SPI_RX_FIFO_1PACKET STAT_RPLVL(1) /*!< 1 frame stored in RxFIFO */ +#define SPI_RX_FIFO_2PACKET STAT_RPLVL(2) /*!< 2 frames stored in RxFIFO */ +#define SPI_RX_FIFO_3PACKET STAT_RPLVL(3) /*!< 3 frames stored in RxFIFO */ + +/* I2S audio sample rate */ +#define I2S_AUDIOSAMPLE_8K ((uint32_t)8000U) /*!< I2S audio sample rate is 8KHz */ +#define I2S_AUDIOSAMPLE_11K ((uint32_t)11025U) /*!< I2S audio sample rate is 11KHz */ +#define I2S_AUDIOSAMPLE_16K ((uint32_t)16000U) /*!< I2S audio sample rate is 16KHz */ +#define I2S_AUDIOSAMPLE_22K ((uint32_t)22050U) /*!< I2S audio sample rate is 22KHz */ +#define I2S_AUDIOSAMPLE_32K ((uint32_t)32000U) /*!< I2S audio sample rate is 32KHz */ +#define I2S_AUDIOSAMPLE_44K ((uint32_t)44100U) /*!< I2S audio sample rate is 44KHz */ +#define I2S_AUDIOSAMPLE_48K ((uint32_t)48000U) /*!< I2S audio sample rate is 48KHz */ +#define I2S_AUDIOSAMPLE_96K ((uint32_t)96000U) /*!< I2S audio sample rate is 96KHz */ +#define I2S_AUDIOSAMPLE_192K ((uint32_t)192000U) /*!< I2S audio sample rate is 192KHz */ + +/* I2S frame format */ +#define I2SCTL_DTLEN(regval) (BITS(1,2) & ((uint32_t)(regval) << 1)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 32 bit and channel length is 32 bit */ + +/* I2S master clock output */ +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SCTL_MCKOEN /*!< I2S master clock output enable */ + +/* I2S operation mode */ +#define I2SCTL_I2SOPMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */ + +/* I2S clock polarity */ +#define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ +#define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ + +/* SPI DMA constants definitions */ +#define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ + +/* SPI CRC constants definitions */ +#define SPI_CRC_TX ((uint8_t)0x00U) /*!< SPI transmit CRC value */ +#define SPI_CRC_RX ((uint8_t)0x01U) /*!< SPI receive CRC value */ + +/* SPI/I2S interrupt enable/disable constants definitions */ +#define SPI_I2S_INT_RP ((uint8_t)0x00U) /*!< RP interrupt */ +#define SPI_I2S_INT_TP ((uint8_t)0x01U) /*!< TP interrupt */ +#define SPI_I2S_INT_DP ((uint8_t)0x02U) /*!< DP interrupt */ +#define SPI_I2S_INT_ESTC ((uint8_t)0x03U) /*!< end of transfer or suspend or TXFIFO clear interrupt */ +#define SPI_I2S_INT_TXF ((uint8_t)0x04U) /*!< transmission filled interrupt */ +#define SPI_I2S_INT_TXURE ((uint8_t)0x05U) /*!< underrun error interrupt */ +#define SPI_I2S_INT_RXORE ((uint8_t)0x06U) /*!< overrun error interrupt */ +#define SPI_I2S_INT_CRCER ((uint8_t)0x07U) /*!< CRC error interrupt */ +#define SPI_I2S_INT_FE ((uint8_t)0x08U) /*!< TI frame error interrupt */ +#define SPI_I2S_INT_CONFE ((uint8_t)0x09U) /*!< mode error interrupt */ +#define SPI_I2S_INT_TXSERF ((uint8_t)0x0AU) /*!< TXSER reload interrupt */ + +/* SPI/I2S interrupt flag constants definitions */ +#define SPI_I2S_INT_FLAG_RP ((uint8_t)0x00U) /*!< RP interrupt flag */ +#define SPI_I2S_INT_FLAG_TP ((uint8_t)0x01U) /*!< TP interrupt flag */ +#define SPI_I2S_INT_FLAG_DP ((uint8_t)0x02U) /*!< DP interrupt flag */ +#define SPI_I2S_INT_FLAG_ET ((uint8_t)0x03U) /*!< end of transfer or receive interrupt flag */ +#define SPI_I2S_INT_FLAG_TXF ((uint8_t)0x04U) /*!< transmission filled interrupt flag */ +#define SPI_I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */ +#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x06U) /*!< overrun error interrupt flag */ +#define SPI_I2S_INT_FLAG_CRCERR ((uint8_t)0x07U) /*!< CRC error interrupt flag */ +#define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x08U) /*!< TI frame error interrupt flag */ +#define SPI_I2S_INT_FLAG_CONFERR ((uint8_t)0x09U) /*!< mode error interrupt flag */ +#define SPI_I2S_INT_FLAG_TXSERF ((uint8_t)0x0AU) /*!< TXSER reload interrupt flag */ +#define SPI_I2S_INT_FLAG_SPD ((uint8_t)0x0BU) /*!< suspend interrupt flag */ +#define SPI_I2S_INT_FLAG_TC ((uint8_t)0x0CU) /*!< TXFIFO clear interrupt flag */ + +/* SPI/I2S flag definitions */ +#define SPI_FLAG_RP SPI_STAT_RP /*!< RP flag */ +#define SPI_FLAG_TP SPI_STAT_TP /*!< TP flag */ +#define SPI_FLAG_DP SPI_STAT_DP /*!< DP flag */ +#define SPI_FLAG_ET SPI_STAT_ET /*!< end of transfer or receive flag */ +#define SPI_FLAG_TXF SPI_STAT_TXF /*!< transmission filled flag */ +#define SPI_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define SPI_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error flag */ +#define SPI_FLAG_CRCERR SPI_STAT_CRCERR /*!< CRC error flag */ +#define SPI_FLAG_FERR SPI_STAT_FERR /*!< TI frame error flag */ +#define SPI_FLAG_CONFERR SPI_STAT_CONFERR /*!< mode error flag */ +#define SPI_FLAG_TXSERF SPI_STAT_TXSERF /*!< TXSER reload flag */ +#define SPI_FLAG_SPD SPI_STAT_SPD /*!< suspend flag */ +#define SPI_FLAG_TC SPI_STAT_TC /*!< TXFIFO clear flag */ +#define SPI_FLAG_RPLVL SPI_STAT_RPLVL /*!< RxFIFO packing level flag */ +#define SPI_FLAG_RWNE SPI_STAT_RWNE /*!< the word of RXFIFO is not empty flag */ +#define SPI_FLAG_CTXSIZE SPI_STAT_CTXSIZE /*!< the number of data frames remaining in the TXSIZE session flag */ + +#define I2S_FLAG_RP SPI_STAT_RP /*!< RP flag */ +#define I2S_FLAG_TP SPI_STAT_TP /*!< TP flag */ +#define I2S_FLAG_DP SPI_STAT_DP /*!< DP flag */ +#define I2S_FLAG_ET SPI_STAT_ET /*!< end of transfer or suspend or TXFIFO clear flag */ +#define I2S_FLAG_TXF SPI_STAT_TXF /*!< transmission filled flag */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error flag */ + +/* function declarations */ +/* initialization functions */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize the parameters of SPI struct with the default values */ +void spi_struct_para_init(spi_parameter_struct* spi_struct); +/* initialize SPI parameter */ +void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl); +/* configure I2S prescaler */ +void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout); +/* enable I2S */ +void i2s_enable(uint32_t spi_periph); +/* disable I2S */ +void i2s_disable(uint32_t spi_periph); + +/* IO swap functions */ +/* SPI MOSI and MISO pin swap */ +void spi_io_config(uint32_t spi_periph, uint32_t io_cfg); + +/* SPI delay config functions */ +/* set delay between active edge of NSS and start transfer or receive data in SPI master mode */ +void spi_nss_idleness_delay_set(uint32_t spi_periph, uint32_t delay_cycle); +/* set SPI master data frame delay */ +void spi_data_frame_delay_set(uint32_t spi_periph, uint32_t delay_cycle); +/* set SPI master mode rx clock delay */ +void spi_master_receive_clock_delay_set(uint32_t spi_periph, uint32_t delay_unit); +/* set SPI slave mode rx clock delay */ +void spi_slave_receive_clock_delay_set(uint32_t spi_periph, uint32_t delay_unit); +/* clear SPI master mode rx clock delay */ +void spi_master_receive_clock_delay_clear(uint32_t spi_periph); +/* clear SPI slave mode rx clock delay */ +void spi_slave_receive_clock_delay_clear(uint32_t spi_periph); + +/* NSS functions */ +/* NSS output control */ +void spi_nss_output_control(uint32_t spi_periph, uint32_t nss_ctl); +/* set SPI NSS active polarity */ +void spi_nss_polarity_set(uint32_t spi_periph, uint32_t polarity); +/* enable SPI NSS output */ +void spi_nss_output_enable(uint32_t spi_periph); +/* disable SPI NSS output */ +void spi_nss_output_disable(uint32_t spi_periph); +/* SPI NSS pin high level in software mode */ +void spi_nss_internal_high(uint32_t spi_periph); +/* SPI NSS pin low level in software mode */ +void spi_nss_internal_low(uint32_t spi_periph); + +/* SPI DMA functions */ +/* enable SPI DMA */ +void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma); + +/* SPI/I2S transfer configure functions */ +/* configure SPI/I2S data frame size */ +void spi_i2s_data_frame_size_config(uint32_t spi_periph, uint32_t frame_size); +/* SPI/I2S transmit data */ +void spi_i2s_data_transmit(uint32_t spi_periph, uint32_t data); +/* SPI/I2S receive data */ +uint32_t spi_i2s_data_receive(uint32_t spi_periph); +/* configure SPI bidirectional transfer direction */ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction); +/* SPI/I2S master start transfer */ +void spi_master_transfer_start(uint32_t spi_periph, uint32_t transfer_start); +/* configure SPI current data number */ +void spi_current_data_num_config(uint32_t spi_periph, uint32_t current_num); +/* configure SPI reload data number */ +void spi_reload_data_num_config(uint32_t spi_periph, uint32_t reload_num); + +/* SPI CRC functions */ +/* set SPI CRC polynomial */ +void spi_crc_polynomial_set(uint32_t spi_periph, uint32_t crc_poly); +/* get SPI CRC polynomial */ +uint32_t spi_crc_polynomial_get(uint32_t spi_periph); +/* configure SPI CRC length */ +void spi_crc_length_config(uint32_t spi_periph, uint32_t crc_size); +/* turn on SPI CRC function */ +void spi_crc_on(uint32_t spi_periph); +/* turn off SPI CRC function */ +void spi_crc_off(uint32_t spi_periph); +/* get SPI CRC send value or receive value */ +uint32_t spi_crc_get(uint32_t spi_periph, uint8_t crc); +/* enable SPI CRC full size(33 bit or 17 bit) polynomial */ +void spi_crc_full_size_enable(uint32_t spi_periph); +/* disable SPI CRC full size(33 bit or 17 bit) polynomial */ +void spi_crc_full_size_disable(uint32_t spi_periph); +/* configure SPI TCRC init pattern */ +void spi_tcrc_init_pattern(uint32_t spi_periph, uint32_t init_pattern); +/* configure SPI RCRC init pattern */ +void spi_rcrc_init_pattern(uint32_t spi_periph, uint32_t init_pattern); + +/* SPI TI mode functions */ +/* enable SPI TI mode */ +void spi_ti_mode_enable(uint32_t spi_periph); +/* disable SPI TI mode */ +void spi_ti_mode_disable(uint32_t spi_periph); + +/* quad wire SPI functions */ +/* enable quad wire SPI */ +void spi_quad_enable(uint32_t spi_periph); +/* disable quad wire SPI */ +void spi_quad_disable(uint32_t spi_periph); +/* enable quad wire SPI write */ +void spi_quad_write_enable(uint32_t spi_periph); +/* enable quad wire SPI read */ +void spi_quad_read_enable(uint32_t spi_periph); +/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_enable(uint32_t spi_periph); +/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_disable(uint32_t spi_periph); + +/* SPI underrun functions */ +/* slave transmitter underrun detected operation */ +void spi_underrun_operation(uint32_t spi_periph, uint32_t ur_ope); +/* configure slave transmitter underrun detected */ +void spi_underrun_config(uint32_t spi_periph, uint32_t ur_cfg); +/* configure underrun data at slave mode */ +void spi_underrun_data_config(uint32_t spi_periph, uint32_t udata); + +/* SPI suspend functions */ +/* configure SPI suspend in receive mode */ +void spi_suspend_mode_config(uint32_t spi_periph, uint32_t sus_mode); +/* SPI master mode suspend request */ +void spi_suspend_request(uint32_t spi_periph); + +/* SPI Related IOS AF functions */ +/* enable SPI related IOs AF */ +void spi_related_ios_af_enable(uint32_t spi_periph); +/* disable SPI related IOs AF */ +void spi_related_ios_af_disable(uint32_t spi_periph); +/* SPI af gpio control */ +void spi_af_gpio_control(uint32_t spi_periph, uint32_t ctl); + +/* flag and interrupt functions */ +/* enable SPI and I2S interrupt */ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt); +/* disable SPI and I2S interrupt */ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S interrupt flag status */ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag); +/* clear SPI and I2S flag status */ +void spi_i2s_flag_clear(uint32_t spi_periph, uint32_t flag); +/* get SPI and I2S RXFIFO packing level */ +uint32_t spi_i2s_rxfifo_plevel_get(uint32_t spi_periph); +/* get SPI and I2S remaining data frames number in the TXSIZE session */ +uint32_t spi_i2s_remain_data_num_get(uint32_t spi_periph); + +/* SPI FIFO configure */ +/* set SPI FIFO threshold level */ +void spi_fifo_threshold_level_set(uint32_t spi_periph, uint32_t fifo_thl); +/* enable SPI word access */ +void spi_word_access_enable(uint32_t spi_periph); +/* disable SPI word access */ +void spi_word_access_disable(uint32_t spi_periph); +/* enable SPI byte access */ +void spi_byte_access_enable(uint32_t spi_periph); +/* disable SPI byte access */ +void spi_byte_access_disable(uint32_t spi_periph); + +#endif /* GD32H7XX_SPI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_syscfg.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_syscfg.h new file mode 100644 index 0000000000..03d275dc2c --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_syscfg.h @@ -0,0 +1,633 @@ +/*! + \file gd32h7xx_syscfg.h + \brief definitions for the SYSCFG + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_SYSCFG_H +#define GD32H7XX_SYSCFG_H + +#include "gd32h7xx.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE /*!< SYSCFG base address */ + +/* registers definitions */ +#define SYSCFG_PMCFG REG32(SYSCFG + 0x00000004U) /*!< SYSCFG peripheral mode configuration register */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x00000008U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0000000CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x00000010U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x00000014U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_LKCTL REG32(SYSCFG + 0x00000018U) /*!< SYSCFG lock control register */ +#define SYSCFG_CPSCTL REG32(SYSCFG + 0x00000020U) /*!< SYSCFG I/O compensation control register */ +#define SYSCFG_CPSCCCFG REG32(SYSCFG + 0x00000028U) /*!< SYSCFG I/O compensation cell code configuration */ +#define SYSCFG_TIMERCISEL0 REG32(SYSCFG + 0x00000034U) /*!< SYSCFG timer input selection register 0 */ +#define SYSCFG_TIMERCISEL1 REG32(SYSCFG + 0x00000038U) /*!< SYSCFG timer input selection register 1 */ +#define SYSCFG_TIMERCISEL2 REG32(SYSCFG + 0x0000003CU) /*!< SYSCFG timer input selection register 2 */ +#define SYSCFG_TIMERCISEL3 REG32(SYSCFG + 0x00000040U) /*!< SYSCFG timer input selection register 3 */ +#define SYSCFG_TIMERCISEL4 REG32(SYSCFG + 0x00000044U) /*!< SYSCFG timer input selection register 4 */ +#define SYSCFG_TIMERCISEL5 REG32(SYSCFG + 0x00000048U) /*!< SYSCFG timer input selection register 5 */ +#define SYSCFG_TIMERCISEL6 REG32(SYSCFG + 0x0000004CU) /*!< SYSCFG timer input selection register 6 */ +#define SYSCFG_CPUICAC REG32(SYSCFG + 0x00000054U) /*!< SYSCFG CPU icache error status register */ +#define SYSCFG_CPUDCAC REG32(SYSCFG + 0x00000058U) /*!< SYSCFG CPU dcache error status register */ +#define SYSCFG_FPUINTEN REG32(SYSCFG + 0x0000005CU) /*!< SYSCFG FPU interrupt enable register */ +#define SYSCFG_SRAMCFG0 REG32(SYSCFG + 0x00000064U) /*!< SYSCFG SRAM configuration register 0*/ +#define SYSCFG_SRAMCFG1 REG32(SYSCFG + 0x00000068U) /*!< SYSCFG SRAM configuration register 1*/ +#define SYSCFG_USERCFG REG32(SYSCFG + 0x00000300U) /*!< SYSCFG user configuration register */ + +/* SYSCFG_PMCFG bits definitions */ +#define SYSCFG_PMCFG_I2C0FMPEN BIT(0) /*!< I2C0 fast mode plus enable */ +#define SYSCFG_PMCFG_I2C1FMPEN BIT(1) /*!< I2C1 fast mode plus enable */ +#define SYSCFG_PMCFG_I2C2FMPEN BIT(2) /*!< I2C2 fast mode plus enable */ +#define SYSCFG_PMCFG_I2C3FMPEN BIT(3) /*!< I2C3 fast mode plus enable */ +#define SYSCFG_PMCFG_PB6FMPEN BIT(4) /*!< I2C fast mode plus on PB6 pin enable */ +#define SYSCFG_PMCFG_PB7FMPEN BIT(5) /*!< I2C fast mode plus on PB7 pin enable */ +#define SYSCFG_PMCFG_PB8FMPEN BIT(6) /*!< I2C fast mode plus on PB8 pin enable */ +#define SYSCFG_PMCFG_PB9FMPEN BIT(7) /*!< I2C fast mode plus on PB9 pin enable */ +#define SYSCFG_PMCFG_ENET1_PHY_SEL BIT(22) /*!< Ethernet1 PHY interface selection */ +#define SYSCFG_PMCFG_ENET0_PHY_SEL BIT(23) /*!< Ethernet0 PHY interface selection */ +#define SYSCFG_PMCFG_PA0SWON BIT(24) /*!< PA0 switch open */ +#define SYSCFG_PMCFG_PA1SWON BIT(25) /*!< PA1 switch open */ +#define SYSCFG_PMCFG_PC2SWON BIT(26) /*!< PC2 switch open */ +#define SYSCFG_PMCFG_PC3SWON BIT(27) /*!< PC3 switch open */ + +/* SYSCFG_EXTISS0 bits definitions */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,3) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,7) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,11) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,15) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 bits definitions */ +#define SYSCFG_EXTISS1_EXTI4_SS BITS(0,3) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BITS(4,7) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,11) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,15) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 bits definitions */ +#define SYSCFG_EXTISS2_EXTI8_SS BITS(0,3) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BITS(4,7) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BITS(8,11) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BITS(12,15) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 bits definitions */ +#define SYSCFG_EXTISS3_EXTI12_SS BITS(0,3) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,7) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,11) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,15) /*!< EXTI 15 configuration */ + +/* SYSCFG_LKCTL bits definitions */ +#define SYSCFG_LKCTL_LVD_LOCK BIT(2) /*!< programmable voltage detector lockup */ +#define SYSCFG_LKCTL_CPU_LOCK BIT(6) /*!< CPU lockup */ +#define SYSCFG_LKCTL_BKPRAM_LOCK BIT(7) /*!< Region 2 backup SRAM ECC double error lockup */ +#define SYSCFG_LKCTL_SRAM1_LOCK BIT(11) /*!< Region 1 SRAM1 ECC double error lockup */ +#define SYSCFG_LKCTL_SRAM0_LOCK BIT(12) /*!< Region 1 SRAM0 ECC double error lockup */ +#define SYSCFG_LKCTL_DTCM_LOCK BIT(13) /*!< Region 0 DTCM ECC double error lock */ +#define SYSCFG_LKCTL_ITCM_LOCK BIT(14) /*!< Region 0 ITCM-RAM ECC double error lock */ +#define SYSCFG_LKCTL_AXIRAM_LOCK BIT(15) /*!< Region 0 AXI-SRAM ECC double error lock */ + +/* SYSCFG_CPSCTL bits definitions */ +#define SYSCFG_CPSCTL_CPS_EN BIT(0) /*!< I/O compensation cell enable */ +#define SYSCFG_CPSCTL_CPS_RDY BIT(8) /*!< Compensation cell ready flag */ +#define SYSCFG_CPSCTL_IOSPDOP BIT(16) /*!< I/O speed optimization, high-speed at low-voltage */ +#define SYSCFG_CPSCTL_IOLV BIT(23) /*!< I/O in low voltage state */ + +/* SYSCFG_CPSCCCFG bits definitions */ +#define SYSCFG_CPSCCCFG_NCPSCC BITS(0,3) /*!< NMOS compensation cell code */ +#define SYSCFG_CPSCCCFG_PCPSCC BITS(4,7) /*!< PMOS compensation cell code */ + +/* SYSCFG_TIMERCISEL0 bits definitions */ +#define SYSCFG_TIMER7_CI0_SEL BITS(0,3) /*!< selects TIMER7_CI0 input */ +#define SYSCFG_TIMER7_CI1_SEL BITS(4,7) /*!< selects TIMER7_CI1 input */ +#define SYSCFG_TIMER7_CI2_SEL BITS(8,11) /*!< selects TIMER7_CI2 input */ +#define SYSCFG_TIMER7_CI3_SEL BITS(12,15) /*!< selects TIMER7_CI3 input */ +#define SYSCFG_TIMER0_CI0_SEL BITS(16,19) /*!< selects TIMER0_CI0 input */ +#define SYSCFG_TIMER0_CI1_SEL BITS(20,23) /*!< selects TIMER0_CI1 input */ +#define SYSCFG_TIMER0_CI2_SEL BITS(24,27) /*!< selects TIMER0_CI2 input */ +#define SYSCFG_TIMER0_CI3_SEL BITS(28,31) /*!< selects TIMER0_CI3 input */ + +/* SYSCFG_TIMERCISEL1 bits definitions */ +#define SYSCFG_TIMER2_CI0_SEL BITS(0,3) /*!< selects TIMER2_CI0 input */ +#define SYSCFG_TIMER2_CI1_SEL BITS(4,7) /*!< selects TIMER2_CI1 input */ +#define SYSCFG_TIMER2_CI2_SEL BITS(8,11) /*!< selects TIMER2_CI2 input */ +#define SYSCFG_TIMER2_CI3_SEL BITS(12,15) /*!< selects TIMER2_CI3 input */ +#define SYSCFG_TIMER1_CI0_SEL BITS(16,19) /*!< selects TIMER1_CI0 input */ +#define SYSCFG_TIMER1_CI1_SEL BITS(20,23) /*!< selects TIMER1_CI1 input */ +#define SYSCFG_TIMER1_CI2_SEL BITS(24,27) /*!< selects TIMER1_CI2 input */ +#define SYSCFG_TIMER1_CI3_SEL BITS(28,31) /*!< selects TIMER1_CI3 input */ + +/* SYSCFG_TIMERCISEL2 bits definitions */ +#define SYSCFG_TIMER4_CI0_SEL BITS(0,3) /*!< selects TIMER4_CI0 input */ +#define SYSCFG_TIMER4_CI1_SEL BITS(4,7) /*!< selects TIMER4_CI1 input */ +#define SYSCFG_TIMER4_CI2_SEL BITS(8,11) /*!< selects TIMER4_CI2 input */ +#define SYSCFG_TIMER4_CI3_SEL BITS(12,15) /*!< selects TIMER4_CI3 input */ +#define SYSCFG_TIMER3_CI0_SEL BITS(16,19) /*!< selects TIMER3_CI0 input */ +#define SYSCFG_TIMER3_CI1_SEL BITS(20,23) /*!< selects TIMER3_CI1 input */ +#define SYSCFG_TIMER3_CI2_SEL BITS(24,27) /*!< selects TIMER3_CI2 input */ +#define SYSCFG_TIMER3_CI3_SEL BITS(28,31) /*!< selects TIMER3_CI3 input */ + +/* SYSCFG_TIMERCISEL3 bits definitions */ +#define SYSCFG_TIMER23_CI0_SEL BITS(0,3) /*!< selects TIMER23_CI0 input */ +#define SYSCFG_TIMER23_CI1_SEL BITS(4,7) /*!< selects TIMER23_CI1 input */ +#define SYSCFG_TIMER23_CI2_SEL BITS(8,11) /*!< selects TIMER23_CI2 input */ +#define SYSCFG_TIMER23_CI3_SEL BITS(12,15) /*!< selects TIMER23_CI3 input */ +#define SYSCFG_TIMER22_CI0_SEL BITS(16,19) /*!< selects TIMER22_CI0 input */ +#define SYSCFG_TIMER22_CI1_SEL BITS(20,23) /*!< selects TIMER22_CI1 input */ +#define SYSCFG_TIMER22_CI2_SEL BITS(24,27) /*!< selects TIMER22_CI2 input */ +#define SYSCFG_TIMER22_CI3_SEL BITS(28,31) /*!< selects TIMER22_CI3 input */ + +/* SYSCFG_TIMERCISEL4 bits definitions */ +#define SYSCFG_TIMER31_CI0_SEL BITS(0,3) /*!< selects TIMER31_CI0 input */ +#define SYSCFG_TIMER31_CI1_SEL BITS(4,7) /*!< selects TIMER31_CI1 input */ +#define SYSCFG_TIMER31_CI2_SEL BITS(8,11) /*!< selects TIMER31_CI2 input */ +#define SYSCFG_TIMER31_CI3_SEL BITS(12,15) /*!< selects TIMER31_CI3 input */ +#define SYSCFG_TIMER30_CI0_SEL BITS(16,19) /*!< selects TIMER30_CI0 input */ +#define SYSCFG_TIMER30_CI1_SEL BITS(20,23) /*!< selects TIMER30_CI1 input */ +#define SYSCFG_TIMER30_CI2_SEL BITS(24,27) /*!< selects TIMER30_CI2 input */ +#define SYSCFG_TIMER30_CI3_SEL BITS(28,31) /*!< selects TIMER30_CI3 input */ + +/* SYSCFG_TIMERCISEL5 bits definitions */ +#define SYSCFG_TIMER14_CI0_SEL BITS(0,3) /*!< selects TIMER14_CI0 input */ +#define SYSCFG_TIMER14_CI1_SEL BITS(4,7) /*!< selects TIMER14_CI1 input */ +#define SYSCFG_TIMER40_CI0_SEL BITS(8,11) /*!< selects TIMER40_CI0 input */ +#define SYSCFG_TIMER40_CI1_SEL BITS(12,15) /*!< selects TIMER40_CI1 input */ +#define SYSCFG_TIMER41_CI0_SEL BITS(16,19) /*!< selects TIMER41_CI0 input */ +#define SYSCFG_TIMER41_CI1_SEL BITS(20,23) /*!< selects TIMER41_CI1 input */ +#define SYSCFG_TIMER42_CI0_SEL BITS(24,27) /*!< selects TIMER42_CI0 input */ +#define SYSCFG_TIMER42_CI1_SEL BITS(28,31) /*!< selects TIMER42_CI1 input */ + +/* SYSCFG_TIMERCISEL6 bits definitions */ +#define SYSCFG_TIMER15_CI0_SEL BITS(0,3) /*!< selects TIMER15_CI0 input */ +#define SYSCFG_TIMER16_CI0_SEL BITS(4,7) /*!< selects TIMER16_CI0 input */ +#define SYSCFG_TIMER43_CI0_SEL BITS(8,11) /*!< selects TIMER43_CI0 input */ +#define SYSCFG_TIMER43_CI1_SEL BITS(12,15) /*!< selects TIMER43_CI1 input */ +#define SYSCFG_TIMER44_CI0_SEL BITS(16,19) /*!< selects TIMER44_CI0 input */ +#define SYSCFG_TIMER44_CI1_SEL BITS(20,23) /*!< selects TIMER44_CI1 input */ + +/* CPU ICACHE error status bits definitions */ +#define SYSCFG_CPUICAC_CPU_ICERR BITS(6,27) /*!< CPU ICACHE error bank information */ +#define SYSCFG_CPUICAC_CPU_ICDET BITS(28,31) /*!< CPU ICACHE error detection information */ + +/* CPU DCACHE error status bits definitions */ +#define SYSCFG_CPUDCAC_CPU_DCERR BITS(6,27) /*!< CPU DCACHE error bank information */ +#define SYSCFG_CPUDCAC_CPU_DCDET BITS(28,31) /*!< CPU DCACHE error detection information */ + +/* floating point unit interrupt enable bits definitions */ +#define SYSCFG_FPUINTEN_IOPIE BIT(0) /*!< invalid operation interrupt enable */ +#define SYSCFG_FPUINTEN_DZIE BIT(1) /*!< divide-by-zero interrupt enable */ +#define SYSCFG_FPUINTEN_UFIE BIT(2) /*!< underflow interrupt enable */ +#define SYSCFG_FPUINTEN_OVFIE BIT(3) /*!< overflow interrupt enable */ +#define SYSCFG_FPUINTEN_IDIE BIT(4) /*!< input abnormal interrupt enable */ +#define SYSCFG_FPUINTEN_IXIE BIT(5) /*!< inexact interrupt enable */ + +/* SRAM configuration register 0 */ +#define SYSCFG_SRAMCFG0_SECURE_SRAM_SIZE BITS(0,1) /*!< size of secure sram */ + +/* SRAM configuration register 1 */ +#define SYSCFG_SRAMCFG1_TCM_WAITSTATE BIT(0) /*!< TCM wait state configuration */ + +/* TIMER trigger selection register */ +#define SYSCFG_TIMERCFG_TSCFG0 BITS(0,4) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG1 BITS(5,9) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG2 BITS(10,14) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG3 BITS(16,20) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG4 BITS(21,25) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG5 BITS(26,30) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG6 BITS(0,4) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG7 BITS(5,9) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG8 BITS(10,14) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG9 BITS(16,20) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG10 BITS(21,25) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG11 BITS(26,30) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG12 BITS(0,4) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG13 BITS(5,9) /*!< TIMER trigger selection */ +#define SYSCFG_TIMERCFG_TSCFG14 BITS(10,14) /*!< TIMER trigger selection */ + +/* SYSCFG_USERCFG bits definitions */ +#define SYSCFG_USERCFG_BOR_TH BITS(0,1) /*!< BOR threshold status bits */ +#define SYSCFG_USERCFG_BOOT_MODE BITS(4,6) /*!< BOOT mode */ + +/* constants definitions */ +/* I2Cx fast mode plus enable definitions */ +#define SYSCFG_I2C0_FMP SYSCFG_PMCFG_I2C0FMPEN /*!< I2C0 fast mode plus */ +#define SYSCFG_I2C1_FMP SYSCFG_PMCFG_I2C1FMPEN /*!< I2C1 fast mode plus */ +#define SYSCFG_I2C2_FMP SYSCFG_PMCFG_I2C2FMPEN /*!< I2C2 fast mode plus */ +#define SYSCFG_I2C3_FMP SYSCFG_PMCFG_I2C3FMPEN /*!< I2C3 fast mode plus */ +#define SYSCFG_I2C_FMP_PB6 SYSCFG_PMCFG_PB6FMPEN /*!< I2C fast mode plus on PB6 pin */ +#define SYSCFG_I2C_FMP_PB7 SYSCFG_PMCFG_PB7FMPEN /*!< I2C fast mode plus on PB7 pin */ +#define SYSCFG_I2C_FMP_PB8 SYSCFG_PMCFG_PB8FMPEN /*!< I2C fast mode plus on PB8 pin */ +#define SYSCFG_I2C_FMP_PB9 SYSCFG_PMCFG_PB9FMPEN /*!< I2C fast mode plus on PB9 pin */ + +/* pin analog switch definitions */ +#define SYSCFG_PA0_ANALOG_SWITCH SYSCFG_PMCFG_PA0SWON /*!< PA0 analog switch */ +#define SYSCFG_PA1_ANALOG_SWITCH SYSCFG_PMCFG_PA1SWON /*!< PA1 analog switch */ +#define SYSCFG_PC2_ANALOG_SWITCH SYSCFG_PMCFG_PC2SWON /*!< PC2 analog switch */ +#define SYSCFG_PC3_ANALOG_SWITCH SYSCFG_PMCFG_PC3SWON /*!< PC3 analog switch */ + +/* Ethernet PHY mode definitions */ +#define SYSCFG_ENET_PHY_MII ((uint32_t)0x00000000U) /*!< Ethernet PHY interface */ +#define SYSCFG_ENET_PHY_RMII ((uint32_t)0x00000001U) /*!< Ethernet PHY interface */ + +/* Ethernet 0 PHY interface selection */ +#define ENET0_MEDIA_INTERFACE(regval) (SYSCFG_PMCFG_ENET0_PHY_SEL & ((uint32_t)(regval) << 23U)) +/* Ethernet 1 PHY interface selection */ +#define ENET1_MEDIA_INTERFACE(regval) (SYSCFG_PMCFG_ENET1_PHY_SEL & ((uint32_t)(regval) << 22U)) + +/* EXTI source select definitions */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select register 0 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select register 1 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select register 2 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select register 3 */ + +/* EXTI source select mask bits definition */ +#define EXTI_SS_MASK BITS(0,3) /*!< EXTI source select mask */ + +/* EXTI source select jumping step definition */ +#define EXTI_SS_JSTEP ((uint8_t)(0x04U)) /*!< EXTI source select jumping step */ + +/* EXTI source select moving step definition */ +#define EXTI_SS_MSTEP(pin) (EXTI_SS_JSTEP * ((pin) % EXTI_SS_JSTEP)) /*!< EXTI source select moving step */ + +/* EXTI source port definitions */ +#define EXTI_SOURCE_GPIOA ((uint8_t)0x00U) /*!< EXTI GPIOA configuration */ +#define EXTI_SOURCE_GPIOB ((uint8_t)0x01U) /*!< EXTI GPIOB configuration */ +#define EXTI_SOURCE_GPIOC ((uint8_t)0x02U) /*!< EXTI GPIOC configuration */ +#define EXTI_SOURCE_GPIOD ((uint8_t)0x03U) /*!< EXTI GPIOD configuration */ +#define EXTI_SOURCE_GPIOE ((uint8_t)0x04U) /*!< EXTI GPIOE configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ +#define EXTI_SOURCE_GPIOG ((uint8_t)0x06U) /*!< EXTI GPIOG configuration */ +#define EXTI_SOURCE_GPIOH ((uint8_t)0x07U) /*!< EXTI GPIOH configuration */ +#define EXTI_SOURCE_GPIOJ ((uint8_t)0x09U) /*!< EXTI GPIOJ configuration */ +#define EXTI_SOURCE_GPIOK ((uint8_t)0x0AU) /*!< EXTI GPIOK configuration */ + +/* EXTI source pin definitions */ +#define EXTI_SOURCE_PIN0 ((uint8_t)0x00U) /*!< EXTI GPIO pin0 configuration */ +#define EXTI_SOURCE_PIN1 ((uint8_t)0x01U) /*!< EXTI GPIO pin1 configuration */ +#define EXTI_SOURCE_PIN2 ((uint8_t)0x02U) /*!< EXTI GPIO pin2 configuration */ +#define EXTI_SOURCE_PIN3 ((uint8_t)0x03U) /*!< EXTI GPIO pin3 configuration */ +#define EXTI_SOURCE_PIN4 ((uint8_t)0x04U) /*!< EXTI GPIO pin4 configuration */ +#define EXTI_SOURCE_PIN5 ((uint8_t)0x05U) /*!< EXTI GPIO pin5 configuration */ +#define EXTI_SOURCE_PIN6 ((uint8_t)0x06U) /*!< EXTI GPIO pin6 configuration */ +#define EXTI_SOURCE_PIN7 ((uint8_t)0x07U) /*!< EXTI GPIO pin7 configuration */ +#define EXTI_SOURCE_PIN8 ((uint8_t)0x08U) /*!< EXTI GPIO pin8 configuration */ +#define EXTI_SOURCE_PIN9 ((uint8_t)0x09U) /*!< EXTI GPIO pin9 configuration */ +#define EXTI_SOURCE_PIN10 ((uint8_t)0x0AU) /*!< EXTI GPIO pin10 configuration */ +#define EXTI_SOURCE_PIN11 ((uint8_t)0x0BU) /*!< EXTI GPIO pin11 configuration */ +#define EXTI_SOURCE_PIN12 ((uint8_t)0x0CU) /*!< EXTI GPIO pin12 configuration */ +#define EXTI_SOURCE_PIN13 ((uint8_t)0x0DU) /*!< EXTI GPIO pin13 configuration */ +#define EXTI_SOURCE_PIN14 ((uint8_t)0x0EU) /*!< EXTI GPIO pin14 configuration */ +#define EXTI_SOURCE_PIN15 ((uint8_t)0x0FU) /*!< EXTI GPIO pin15 configuration */ + +/* MOS mode definitions */ +#define PMOS_COMPENSATION ((uint8_t)0x00U) /*!< PMOS compensation */ +#define NMOS_COMPENSATION ((uint8_t)0x01U) /*!< NMOS compensation */ + +/* timer input select definition */ +#define TIMERCISEL0 ((uint8_t)0x00U) /*!< TIMER input select register 0 */ +#define TIMERCISEL1 ((uint8_t)0x01U) /*!< TIMER input select register 1 */ +#define TIMERCISEL2 ((uint8_t)0x02U) /*!< TIMER input select register 2 */ +#define TIMERCISEL3 ((uint8_t)0x03U) /*!< TIMER input select register 3 */ +#define TIMERCISEL4 ((uint8_t)0x04U) /*!< TIMER input select register 4 */ +#define TIMERCISEL5 ((uint8_t)0x05U) /*!< TIMER input select register 5 */ +#define TIMERCISEL6 ((uint8_t)0x06U) /*!< TIMER input select register 6 */ + +/* define the timer bit position and its register index offset */ +#define TIMER_REGIDX_BIT(regidx, bitpos, value) (((uint32_t)(regidx) << 24U) | (uint32_t)((bitpos) << 16U)\ + | ((uint32_t)(value))) +#define TIMER_REG_INDEX(val) (((uint32_t)(val) & 0xFF000000U) >> 24U) +#define TIMER_BIT_POS(val) (((uint32_t)(val) & 0x00FF0000U) >> 16U) +#define TIMER_SEL_VAL(val) ((uint32_t)(val) & 0x000000FFU) + +/* TIMERx channel input select definitions */ +typedef enum { + TIMER7_CI0_INPUT_TIMER7_CH0 = TIMER_REGIDX_BIT(TIMERCISEL0, 0U, 0U), /*!< select CMP1 output as TIMER7 CI0 */ + TIMER7_CI0_INPUT_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL0, 0U, 1U), /*!< select TIMER7 CH0 as TIMER7 CI0 */ + TIMER7_CI1_INPUT_TIMER7_CH1 = TIMER_REGIDX_BIT(TIMERCISEL0, 4U, 0U), /*!< select TIMER7 CH1 as TIMER7 CI1 */ + TIMER7_CI2_INPUT_TIMER7_CH2 = TIMER_REGIDX_BIT(TIMERCISEL0, 8U, 0U), /*!< select TIMER7 CH2 as TIMER7 CI2 */ + TIMER7_CI3_INPUT_TIMER7_CH3 = TIMER_REGIDX_BIT(TIMERCISEL0, 12U, 0U), /*!< select TIMER7 CH3 as TIMER7 CI3 */ + TIMER0_CI0_INPUT_TIMER0_CH0 = TIMER_REGIDX_BIT(TIMERCISEL0, 16U, 0U), /*!< select CMP0 output as TIMER0 CI0 */ + TIMER0_CI0_INPUT_CMP0_OUT = TIMER_REGIDX_BIT(TIMERCISEL0, 16U, 1U), /*!< select TIMER0 CH0 as TIMER0 CI0 */ + TIMER0_CI1_INPUT_TIMER0_CH1 = TIMER_REGIDX_BIT(TIMERCISEL0, 20U, 0U), /*!< select TIMER0 CH1 as TIMER0 CI1 */ + TIMER0_CI2_INPUT_TIMER0_CH2 = TIMER_REGIDX_BIT(TIMERCISEL0, 24U, 0U), /*!< select TIMER0 CH2 as TIMER0 CI2 */ + TIMER0_CI3_INPUT_TIMER0_CH3 = TIMER_REGIDX_BIT(TIMERCISEL0, 28U, 0U), /*!< select TIMER0 CH3 as TIMER0 CI3 */ + TIMER2_CI0_INPUT_TIMER2_CH0 = TIMER_REGIDX_BIT(TIMERCISEL1, 0U, 0U), /*!< select TIMER2 CH0 as TIMER2 CI0 */ + TIMER2_CI0_INPUT_CMP0_OUT = TIMER_REGIDX_BIT(TIMERCISEL1, 0U, 1U), /*!< select CMP0 as TIMER2 CI0 */ + TIMER2_CI0_INPUT_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL1, 0U, 2U), /*!< select CMP1 as TIMER2 CI0 */ + TIMER2_CI0_INPUT_CMP0_OR_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL1, 0U, 3U), /*!< select CMP0 or CMP1 as TIMER2 CI0 */ + TIMER2_CI1_INPUT_TIMER2_CH1 = TIMER_REGIDX_BIT(TIMERCISEL1, 4U, 0U), /*!< select TIMER2 CH1 as TIMER2 CI1 */ + TIMER2_CI2_INPUT_TIMER2_CH2 = TIMER_REGIDX_BIT(TIMERCISEL1, 8U, 0U), /*!< select TIMER2 CH2 as TIMER2 CI2 */ + TIMER2_CI3_INPUT_TIMER2_CH3 = TIMER_REGIDX_BIT(TIMERCISEL1, 12U, 0U), /*!< select TIMER2 CH3 as TIMER2 CI3 */ + TIMER1_CI0_INPUT_TIMER1_CH0 = TIMER_REGIDX_BIT(TIMERCISEL1, 16U, 0U), /*!< select TIMER1 CH0 as TIMER1 CI0 */ + TIMER1_CI1_INPUT_TIMER1_CH1 = TIMER_REGIDX_BIT(TIMERCISEL1, 20U, 0U), /*!< select TIMER1 CH1 as TIMER1 CI1 */ + TIMER1_CI2_INPUT_TIMER1_CH2 = TIMER_REGIDX_BIT(TIMERCISEL1, 24U, 0U), /*!< select TIMER1 CH2 as TIMER1 CI2 */ + TIMER1_CI3_INPUT_TIMER1_CH3 = TIMER_REGIDX_BIT(TIMERCISEL1, 28U, 0U), /*!< select TIMER1 CH3 as TIMER1 CI3 */ + TIMER1_CI3_INPUT_CMP0_OUT = TIMER_REGIDX_BIT(TIMERCISEL1, 28U, 1U), /*!< select CMP0 output as TIMER1 CI3 */ + TIMER1_CI3_INPUT_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL1, 28U, 2U), /*!< select CMP1 output as TIMER1 CI3 */ + TIMER1_CI3_INPUT_CMP0_OR_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL1, 28U, 3U), /*!< select CMP0 or CMP1 output as TIMER1 CI3 */ + TIMER4_CI0_INPUT_TIMER4_CH0 = TIMER_REGIDX_BIT(TIMERCISEL2, 0U, 0U), /*!< select TIMER4 CH0 as TIMER4 CI0 */ + TIMER4_CI1_INPUT_TIMER4_CH1 = TIMER_REGIDX_BIT(TIMERCISEL2, 4U, 0U), /*!< select TIMER4 CH1 as TIMER4 CI1 */ + TIMER4_CI2_INPUT_TIMER4_CH2 = TIMER_REGIDX_BIT(TIMERCISEL2, 8U, 0U), /*!< select TIMER4 CH2 as TIMER4 CI2 */ + TIMER4_CI3_INPUT_TIMER4_CH3 = TIMER_REGIDX_BIT(TIMERCISEL2, 12U, 0U), /*!< select TIMER4 CH3 as TIMER4 CI3 */ + TIMER3_CI0_INPUT_TIMER3_CH0 = TIMER_REGIDX_BIT(TIMERCISEL2, 16U, 0U), /*!< select TIMER3 CH0 as TIMER3 CI0 */ + TIMER3_CI1_INPUT_TIMER3_CH1 = TIMER_REGIDX_BIT(TIMERCISEL2, 20U, 0U), /*!< select TIMER3 CH1 as TIMER3 CI1 */ + TIMER3_CI2_INPUT_TIMER3_CH2 = TIMER_REGIDX_BIT(TIMERCISEL2, 24U, 0U), /*!< select TIMER3 CH2 as TIMER3 CI2 */ + TIMER3_CI3_INPUT_TIMER3_CH3 = TIMER_REGIDX_BIT(TIMERCISEL2, 28U, 0U), /*!< select TIMER3 CH3 as TIMER3 CI3 */ + TIMER23_CI0_INPUT_TIMER23_CH0 = TIMER_REGIDX_BIT(TIMERCISEL3, 0U, 0U), /*!< select TIMER23 CH0 as TIMER23 CI0 */ + TIMER23_CI1_INPUT_TIMER23_CH1 = TIMER_REGIDX_BIT(TIMERCISEL3, 4U, 0U), /*!< select TIMER23 CH1 as TIMER23 CI1 */ + TIMER23_CI2_INPUT_TIMER23_CH2 = TIMER_REGIDX_BIT(TIMERCISEL3, 8U, 0U), /*!< select TIMER23 CH2 as TIMER23 CI2 */ + TIMER23_CI3_INPUT_TIMER23_CH3 = TIMER_REGIDX_BIT(TIMERCISEL3, 12U, 0U), /*!< select TIMER23 CH3 as TIMER23 CI3 */ + TIMER22_CI0_INPUT_TIMER22_CH0 = TIMER_REGIDX_BIT(TIMERCISEL3, 16U, 0U), /*!< select TIMER22 CH0 as TIMER22 CI0 */ + TIMER22_CI1_INPUT_TIMER22_CH1 = TIMER_REGIDX_BIT(TIMERCISEL3, 20U, 0U), /*!< select TIMER22 CH1 as TIMER22 CI1 */ + TIMER22_CI2_INPUT_TIMER22_CH2 = TIMER_REGIDX_BIT(TIMERCISEL3, 24U, 0U), /*!< select TIMER22 CH2 as TIMER22 CI2 */ + TIMER22_CI3_INPUT_TIMER22_CH3 = TIMER_REGIDX_BIT(TIMERCISEL3, 28U, 0U), /*!< select TIMER22 CH3 as TIMER22 CI3 */ + TIMER22_CI3_INPUT_CMP0_OUT = TIMER_REGIDX_BIT(TIMERCISEL3, 28U, 1U), /*!< select CMP0 output as TIMER22 CI3 */ + TIMER22_CI3_INPUT_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL3, 28U, 2U), /*!< select CMP1 output as TIMER22 CI3 */ + TIMER22_CI3_INPUT_CMP0_OR_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL3, 28U, 3U), /*!< select CMP0 or CMP1 output as TIMER22 CI3 */ + TIMER31_CI0_INPUT_TIMER31_CH0 = TIMER_REGIDX_BIT(TIMERCISEL4, 0U, 0U), /*!< select TIMER31 CH0 as TIMER31 CI0 */ + TIMER31_CI0_INPUT_CMP0_OUT = TIMER_REGIDX_BIT(TIMERCISEL4, 0U, 1U), /*!< select CMP0 output as TIMER31 CI0 */ + TIMER31_CI0_INPUT_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL4, 0U, 2U), /*!< select CMP1 output as TIMER31 CI0 */ + TIMER31_CI0_INPUT_CMP0_OR_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL4, 0U, 3U), /*!< select CMP0 or CMP1 output as TIMER31 CI0 */ + TIMER31_CI1_INPUT_TIMER31_CH1 = TIMER_REGIDX_BIT(TIMERCISEL4, 4U, 0U), /*!< select TIMER31 CH1 as TIMER31 CI1 */ + TIMER31_CI2_INPUT_TIMER31_CH2 = TIMER_REGIDX_BIT(TIMERCISEL4, 8U, 0U), /*!< select TIMER31 CH2 as TIMER31 CI2 */ + TIMER31_CI3_INPUT_TIMER31_CH3 = TIMER_REGIDX_BIT(TIMERCISEL4, 12U, 0U), /*!< select TIMER31 CH3 as TIMER31 CI3 */ + TIMER30_CI0_INPUT_TIMER30_CH0 = TIMER_REGIDX_BIT(TIMERCISEL4, 16U, 0U), /*!< select TIMER30 CH0 as TIMER30 CI0 */ + TIMER30_CI0_INPUT_CMP0_OUT = TIMER_REGIDX_BIT(TIMERCISEL4, 16U, 1U), /*!< select CMP0 output as TIMER30 CI0 */ + TIMER30_CI0_INPUT_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL4, 16U, 2U), /*!< select CMP1 output as TIMER30 CI0 */ + TIMER30_CI0_INPUT_CMP0_OR_CMP1_OUT = TIMER_REGIDX_BIT(TIMERCISEL4, 16U, 3U), /*!< select CMP0 or CMP1 output as TIMER30 CI0 */ + TIMER30_CI1_INPUT_TIMER30_CH1 = TIMER_REGIDX_BIT(TIMERCISEL4, 20U, 0U), /*!< select TIMER30 CH1 as TIMER30 CI1 */ + TIMER30_CI2_INPUT_TIMER30_CH2 = TIMER_REGIDX_BIT(TIMERCISEL4, 24U, 0U), /*!< select TIMER30 CH2 as TIMER30 CI2 */ + TIMER30_CI3_INPUT_TIMER30_CH3 = TIMER_REGIDX_BIT(TIMERCISEL4, 28U, 0U), /*!< select TIMER30 CH3 as TIMER30 CI3 */ + TIMER14_CI0_INPUT_TIMER14_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 0U, 0U), /*!< select TIMER14 CH0 as TIMER14 CI0 */ + TIMER14_CI0_INPUT_TIMER1_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 0U, 1U), /*!< select TIMER1 CH0 as TIMER14 CI0 */ + TIMER14_CI0_INPUT_TIMER2_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 0U, 2U), /*!< select TIMER2 CH0 as TIMER14 CI0 */ + TIMER14_CI0_INPUT_TIMER3_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 0U, 3U), /*!< select TIMER3 CH0 as TIMER14 CI0 */ + TIMER14_CI0_INPUT_LXTAL = TIMER_REGIDX_BIT(TIMERCISEL5, 0U, 4U), /*!< select LXTAL as TIMER14 CI0 */ + TIMER14_CI0_INPUT_LPIRC4M = TIMER_REGIDX_BIT(TIMERCISEL5, 0U, 5U), /*!< select LPIRC4M as TIMER14 CI0 */ + TIMER14_CI0_INPUT_CKOUT1 = TIMER_REGIDX_BIT(TIMERCISEL5, 0U, 6U), /*!< select CKOUT1 as TIMER14 CI0 */ + TIMER14_CI1_INPUT_TIMER14_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 4U, 0U), /*!< select TIMER14 CH1 as TIMER14 CI1 */ + TIMER14_CI1_INPUT_TIMER1_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 4U, 1U), /*!< select TIMER1 CH1 as TIMER14 CI1 */ + TIMER14_CI1_INPUT_TIMER2_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 4U, 2U), /*!< select TIMER2 CH1 as TIMER14 CI1 */ + TIMER14_CI1_INPUT_TIMER3_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 4U, 3U), /*!< select TIMER3 CH1 as TIMER14 CI1 */ + TIMER40_CI0_INPUT_TIMER40_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 8U, 0U), /*!< select TIMER40 CH0 as TIMER40 CI0 */ + TIMER40_CI0_INPUT_TIMER2_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 8U, 1U), /*!< select TIMER2 CH0 as TIMER40 CI0 */ + TIMER40_CI0_INPUT_TIMER3_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 8U, 2U), /*!< select TIMER3 CH0 as TIMER40 CI0 */ + TIMER40_CI0_INPUT_TIMER4_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 8U, 3U), /*!< select TIMER4 CH0 as TIMER40 CI0 */ + TIMER40_CI0_INPUT_LXTAL = TIMER_REGIDX_BIT(TIMERCISEL5, 8U, 4U), /*!< select LXTAL as TIMER40 CI0 */ + TIMER40_CI0_INPUT_LPIRC4M = TIMER_REGIDX_BIT(TIMERCISEL5, 8U, 5U), /*!< select LPIRC4M as TIMER40 CI0 */ + TIMER40_CI0_INPUT_CKOUT1 = TIMER_REGIDX_BIT(TIMERCISEL5, 8U, 6U), /*!< select CKOUT1 as TIMER40 CI0 */ + TIMER40_CI1_INPUT_TIMER40_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 12U, 0U), /*!< select TIMER40 CH1 as TIMER40 CI0 */ + TIMER40_CI1_INPUT_TIMER2_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 12U, 1U), /*!< select TIMER2 CH1 as TIMER40 CI0 */ + TIMER40_CI1_INPUT_TIMER3_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 12U, 2U), /*!< select TIMER3 CH1 as TIMER40 CI0 */ + TIMER40_CI1_INPUT_TIMER4_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 12U, 3U), /*!< select TIMER4 CH1 as TIMER40 CI0 */ + TIMER41_CI0_INPUT_TIMER41_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 16U, 0U), /*!< select TIMER41 CH0 as TIMER41 CI0 */ + TIMER41_CI0_INPUT_TIMER3_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 16U, 1U), /*!< select TIMER3 CH0 as TIMER41 CI0 */ + TIMER41_CI0_INPUT_TIMER4_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 16U, 2U), /*!< select TIMER4 CH0 as TIMER41 CI0 */ + TIMER41_CI0_INPUT_TIMER22_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 16U, 3U), /*!< select TIMER22 CH0 as TIMER41 CI0 */ + TIMER41_CI0_INPUT_LXTAL = TIMER_REGIDX_BIT(TIMERCISEL5, 16U, 4U), /*!< select LXTAL as TIMER41 CI0 */ + TIMER41_CI0_INPUT_LPIRC4M = TIMER_REGIDX_BIT(TIMERCISEL5, 16U, 5U), /*!< select LPIRC4M as TIMER41 CI0 */ + TIMER41_CI0_INPUT_CKOUT1 = TIMER_REGIDX_BIT(TIMERCISEL5, 16U, 6U), /*!< select CKOUT1 as TIMER41 CI0 */ + TIMER41_CI1_INPUT_TIMER41_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 20U, 0U), /*!< select TIMER41 CH1 as TIMER41 CI1 */ + TIMER41_CI1_INPUT_TIMER3_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 20U, 1U), /*!< select TIMER3 CH1 as TIMER41 CI1 */ + TIMER41_CI1_INPUT_TIMER4_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 20U, 2U), /*!< select TIMER4 CH1 as TIMER41 CI1 */ + TIMER41_CI1_INPUT_TIMER22_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 20U, 3U), /*!< select TIMER22 CH1 as TIMER41 CI1 */ + TIMER42_CI0_INPUT_TIMER42_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 24U, 0U), /*!< select TIMER42 CH0 as TIMER42 CI0 */ + TIMER42_CI0_INPUT_TIMER4_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 24U, 1U), /*!< select TIMER4 CH0 as TIMER42 CI0 */ + TIMER42_CI0_INPUT_TIMER22_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 24U, 2U), /*!< select TIMER22 CH0 as TIMER42 CI0 */ + TIMER42_CI0_INPUT_TIMER23_CH0 = TIMER_REGIDX_BIT(TIMERCISEL5, 24U, 3U), /*!< select TIMER23 CH0 as TIMER42 CI0 */ + TIMER42_CI0_INPUT_LXTAL = TIMER_REGIDX_BIT(TIMERCISEL5, 24U, 4U), /*!< select LXTAL as TIMER42 CI0 */ + TIMER42_CI0_INPUT_LPIRC4M = TIMER_REGIDX_BIT(TIMERCISEL5, 24U, 5U), /*!< select LPIRC4M as TIMER42 CI0 */ + TIMER42_CI0_INPUT_CKOUT1 = TIMER_REGIDX_BIT(TIMERCISEL5, 24U, 6U), /*!< select CKOUT1 as TIMER42 CI0 */ + TIMER42_CI1_INPUT_TIMER42_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 28U, 0U), /*!< select TIMER42 CH1 as TIMER42 CI1 */ + TIMER42_CI1_INPUT_TIMER4_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 28U, 1U), /*!< select TIMER4 CH1 as TIMER42 CI1 */ + TIMER42_CI1_INPUT_TIMER22_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 28U, 2U), /*!< select TIMER22 CH1 as TIMER42 CI1 */ + TIMER42_CI1_INPUT_TIMER23_CH1 = TIMER_REGIDX_BIT(TIMERCISEL5, 28U, 3U), /*!< select TIMER23 CH1 as TIMER42 CI1 */ + TIMER15_CI0_INPUT_TIMER15_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 0U, 0U), /*!< select TIMER15 CH0 as TIMER15 CI0 */ + TIMER15_CI0_INPUT_IRC32K = TIMER_REGIDX_BIT(TIMERCISEL6, 0U, 1U), /*!< select IRC32K as TIMER15 CI0 */ + TIMER15_CI0_INPUT_LXTAL = TIMER_REGIDX_BIT(TIMERCISEL6, 0U, 2U), /*!< select LXTAL as TIMER15 CI0 */ + TIMER15_CI0_INPUT_WKUP_IT = TIMER_REGIDX_BIT(TIMERCISEL6, 0U, 3U), /*!< select WKUP IT as TIMER15 CI0 */ + TIMER16_CI0_INPUT_TIMER16_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 4U, 0U), /*!< select TIMER16 CH0 as TIMER16 CI0 */ + TIMER16_CI0_INPUT_HXTAL_RTCDIV = TIMER_REGIDX_BIT(TIMERCISEL6, 4U, 2U), /*!< select HXTAL/RTCDIV 1M as TIMER16 CI0 */ + TIMER16_CI0_INPUT_CKOUT0 = TIMER_REGIDX_BIT(TIMERCISEL6, 4U, 3U), /*!< select CKOUT0 as TIMER16 CI0 */ + TIMER43_CI0_INPUT_TIMER43_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 8U, 0U), /*!< select TIMER43 CH0 as TIMER43 CI0 */ + TIMER43_CI0_INPUT_TIMER22_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 8U, 1U), /*!< select TIMER22 CH0 as TIMER43 CI0 */ + TIMER43_CI0_INPUT_TIMER23_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 8U, 2U), /*!< select TIMER23 CH0 as TIMER43 CI0 */ + TIMER43_CI0_INPUT_TIMER30_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 8U, 3U), /*!< select TIMER30 CH0 as TIMER43 CI0 */ + TIMER43_CI0_INPUT_LXTAL = TIMER_REGIDX_BIT(TIMERCISEL6, 8U, 4U), /*!< select LXTAL as TIMER43 CI0 */ + TIMER43_CI0_INPUT_LPIRC4M = TIMER_REGIDX_BIT(TIMERCISEL6, 8U, 5U), /*!< select LPIRC4M as TIMER43 CI0 */ + TIMER43_CI0_INPUT_CKOUT1 = TIMER_REGIDX_BIT(TIMERCISEL6, 8U, 6U), /*!< select CKOUT1 as TIMER43 CI0 */ + TIMER43_CI1_INPUT_TIMER43_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 12U, 0U), /*!< select TIMER43 CH1 as TIMER43 CI1 */ + TIMER43_CI1_INPUT_TIMER22_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 12U, 1U), /*!< select TIMER22 CH1 as TIMER43 CI1 */ + TIMER43_CI1_INPUT_TIMER23_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 12U, 2U), /*!< select TIMER23 CH1 as TIMER43 CI1 */ + TIMER43_CI1_INPUT_TIMER30_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 12U, 3U), /*!< select TIMER30 CH1 as TIMER43 CI1 */ + TIMER44_CI0_INPUT_TIMER44_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 16U, 0U), /*!< select TIMER44 CH0 as TIMER44 CI0 */ + TIMER44_CI0_INPUT_TIMER23_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 16U, 1U), /*!< select TIMER23 CH0 as TIMER44 CI0 */ + TIMER44_CI0_INPUT_TIMER30_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 16U, 2U), /*!< select TIMER30 CH0 as TIMER44 CI0 */ + TIMER44_CI0_INPUT_TIMER31_CH0 = TIMER_REGIDX_BIT(TIMERCISEL6, 16U, 3U), /*!< select TIMER31 CH0 as TIMER44 CI0 */ + TIMER44_CI0_INPUT_LXTAL = TIMER_REGIDX_BIT(TIMERCISEL6, 16U, 4U), /*!< select LXTAL as TIMER44 CI0 */ + TIMER44_CI0_INPUT_LPIRC4M = TIMER_REGIDX_BIT(TIMERCISEL6, 16U, 5U), /*!< select LPIRC4M as TIMER44 CI0 */ + TIMER44_CI0_INPUT_CKOUT1 = TIMER_REGIDX_BIT(TIMERCISEL6, 16U, 6U), /*!< select CKOUT1 as TIMER44 CI0 */ + TIMER44_CI1_INPUT_TIMER44_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 20U, 0U), /*!< select TIMER44 CH1 as TIMER44 CI1 */ + TIMER44_CI1_INPUT_TIMER23_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 20U, 1U), /*!< select TIMER23 CH1 as TIMER44 CI1 */ + TIMER44_CI1_INPUT_TIMER30_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 20U, 2U), /*!< select TIMER30 CH1 as TIMER44 CI1 */ + TIMER44_CI1_INPUT_TIMER31_CH1 = TIMER_REGIDX_BIT(TIMERCISEL6, 20U, 3U), /*!< select TIMER31 CH1 as TIMER44 CI1 */ +} timer_channel_input_enum; + +/* timer tigger source select definition */ +#define TIMER_SMCFG_TRGSEL_NONE ((uint8_t)0x00U) /*!< trigger input is none */ +#define TIMER_SMCFG_TRGSEL_ITI0 ((uint8_t)0x01U) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI1 ((uint8_t)0x02U) /*!< internal trigger 1 */ +#define TIMER_SMCFG_TRGSEL_ITI2 ((uint8_t)0x03U) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 ((uint8_t)0x04U) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED ((uint8_t)0x05U) /*!< TI0 edge detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 ((uint8_t)0x06U) /*!< filtered TIMER input 0 */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 ((uint8_t)0x07U) /*!< filtered TIMER input 1 */ +#define TIMER_SMCFG_TRGSEL_ETIFP ((uint8_t)0x08U) /*!< external trigger */ +#define TIMER_SMCFG_TRGSEL_CI2FE2 ((uint8_t)0x09U) /*!< filtered TIMER input 2 */ +#define TIMER_SMCFG_TRGSEL_CI3FE3 ((uint8_t)0x0AU) /*!< filtered TIMER input 3 */ +#define TIMER_SMCFG_TRGSEL_MCI0FEM0 ((uint8_t)0x0BU) /*!< filtered output of multi mode channel 0 */ +#define TIMER_SMCFG_TRGSEL_MCI1FEM1 ((uint8_t)0x0CU) /*!< filtered output of multi mode channel 1 */ +#define TIMER_SMCFG_TRGSEL_MCI2FEM2 ((uint8_t)0x0DU) /*!< filtered output of multi mode channel 2 */ +#define TIMER_SMCFG_TRGSEL_MCI3FEM3 ((uint8_t)0x0EU) /*!< filtered output of multi mode channel 3 */ +#define TIMER_SMCFG_TRGSEL_ITI12 ((uint8_t)0x11U) /*!< internal trigger input 12 */ +#define TIMER_SMCFG_TRGSEL_ITI13 ((uint8_t)0x12U) /*!< internal trigger input 13 */ +#define TIMER_SMCFG_TRGSEL_ITI14 ((uint8_t)0x13U) /*!< internal trigger input 14 */ +#define TIMER_L0_SMCFG_TRGSEL_ITI4 ((uint8_t)0x09U) /*!< internal trigger 4 for General-L0 timer */ +#define TIMER_L0_SMCFG_TRGSEL_ITI5 ((uint8_t)0x0AU) /*!< internal trigger 5 for General-L0 timer */ +#define TIMER_L0_SMCFG_TRGSEL_ITI7 ((uint8_t)0x0CU) /*!< internal trigger 7 for General-L0 timer */ +#define TIMER_L0_SMCFG_TRGSEL_ITI9 ((uint8_t)0x0EU) /*!< internal trigger 9 for General-L0 timer */ +#define TIMER_L0_SMCFG_TRGSEL_ITI10 ((uint8_t)0x0FU) /*!< internal trigger 10 for General-L0 timer */ +#define TIMER_L0_SMCFG_TRGSEL_ITI11 ((uint8_t)0x10U) /*!< internal trigger 11 for General-L0 timer */ + +/* timer tigger mode select definition */ +#define TIMER_QUAD_DECODER_MODE0 ((uint8_t)0x00U) /*!< quadrature decoder mode 0 */ +#define TIMER_QUAD_DECODER_MODE1 ((uint8_t)0x01U) /*!< quadrature decoder mode 1 */ +#define TIMER_QUAD_DECODER_MODE2 ((uint8_t)0x02U) /*!< quadrature decoder mode 2 */ +#define TIMER_SLAVE_MODE_RESTART ((uint8_t)0x03U) /*!< restart mode */ +#define TIMER_SLAVE_MODE_PAUSE ((uint8_t)0x04U) /*!< pause mode */ +#define TIMER_SLAVE_MODE_EVENT ((uint8_t)0x05U) /*!< event mode */ +#define TIMER_SLAVE_MODE_EXTERNAL0 ((uint8_t)0x06U) /*!< external clock mode 0 */ +#define TIMER_SLAVE_MODE_RESTART_EVENT ((uint8_t)0x07U) /*!< restart + event mode */ +#define TIMER_NONQUAD_DECODER_MODE0 ((uint8_t)0x08U) /*!< non-quadrature decoder mode 0 */ +#define TIMER_NONQUAD_DECODER_MODE1 ((uint8_t)0x09U) /*!< non-quadrature decoder mode 1 */ +#define TIMER_SLAVE_MODE_DISABLE ((uint8_t)0x0FU) /*!< slave mode disable */ + +#define SYSCFG_TIMERCFG0(syscfg_timerx) REG32(SYSCFG + 0x100U + (syscfg_timerx) * 0x0CU)/*!< TIMERx configuration register */ +#define SYSCFG_TIMERCFG1(syscfg_timerx) REG32(SYSCFG + 0x104U + (syscfg_timerx) * 0x0CU)/*!< TIMERx configuration register */ +#define SYSCFG_TIMERCFG2(syscfg_timerx) REG32(SYSCFG + 0x108U + (syscfg_timerx) * 0x0CU)/*!< TIMERx configuration register */ + +#define SYSCFG_TIMER0 ((uint8_t)0x00U) /*!< SYSCFG TIMER0 */ +#define SYSCFG_TIMER1 ((uint8_t)0x01U) /*!< SYSCFG TIMER1 */ +#define SYSCFG_TIMER2 ((uint8_t)0x02U) /*!< SYSCFG TIMER2 */ +#define SYSCFG_TIMER3 ((uint8_t)0x03U) /*!< SYSCFG TIMER3 */ +#define SYSCFG_TIMER4 ((uint8_t)0x04U) /*!< SYSCFG TIMER4 */ +#define SYSCFG_TIMER7 ((uint8_t)0x05U) /*!< SYSCFG TIMER5 */ +#define SYSCFG_TIMER14 ((uint8_t)0x06U) /*!< SYSCFG TIMER6 */ +#define SYSCFG_TIMER22 ((uint8_t)0x07U) /*!< SYSCFG TIMER7 */ +#define SYSCFG_TIMER23 ((uint8_t)0x08U) /*!< SYSCFG TIMER8 */ +#define SYSCFG_TIMER30 ((uint8_t)0x09U) /*!< SYSCFG TIMER9 */ +#define SYSCFG_TIMER31 ((uint8_t)0x0AU) /*!< SYSCFG TIMER10 */ +#define SYSCFG_TIMER40 ((uint8_t)0x0BU) /*!< SYSCFG TIMER11 */ +#define SYSCFG_TIMER41 ((uint8_t)0x0CU) /*!< SYSCFG TIMER12 */ +#define SYSCFG_TIMER42 ((uint8_t)0x0DU) /*!< SYSCFG TIMER13 */ +#define SYSCFG_TIMER43 ((uint8_t)0x0EU) /*!< SYSCFG TIMER14 */ +#define SYSCFG_TIMER44 ((uint8_t)0x0FU) /*!< SYSCFG TIMER15 */ + +/* TIMER input select mask bits definition */ +#define TIMER_IS_MASK BITS(0,3) /*!< TIMER source select mask */ + +/* CACHE mode definitions */ +#define ICACHE_STATUS ((uint32_t)0x00000000U) /*!< select ICACHE */ +#define DCACHE_STATUS ((uint32_t)0x00000001U) /*!< select DCACHE */ + +/* CACHE status definitions */ +#define CPU_CACHE_ERROR_DETECTION ((uint32_t)0x00000000U) /*!< select detection information */ +#define CPU_CACHE_ERROR_BANK ((uint32_t)0x00000001U) /*!< select error information */ + +/* Secure SRAM size definition */ +#define SECURE_SRAM_SIZE_0KB ((uint32_t)0x00000000U) /*!< secure SRAM size is 0KB */ +#define SECURE_SRAM_SIZE_32KB ((uint32_t)0x00000001U) /*!< secure SRAM size is 32KB */ +#define SECURE_SRAM_SIZE_64KB ((uint32_t)0x00000002U) /*!< secure SRAM size is 64KB */ +#define SECURE_SRAM_SIZE_128KB ((uint32_t)0x00000003U) /*!< secure SRAM size is 128KB */ + +/* I/O compensation cell enable/disable */ +#define SYSCFG_IO_COMPENSATION_ENABLE ((uint32_t)0x00000001U) /*!< I/O compensation cell enable */ +#define SYSCFG_IO_COMPENSATION_DISABLE ((uint32_t)0x00000000U) /*!< I/O compensation cell disable */ + +/* module lockup */ +#define SYSCFG_LVD_LOCKUP SYSCFG_LKCTL_LVD_LOCK /*!< LVD signal connected */ +#define SYSCFG_CPU_LOCKUP SYSCFG_LKCTL_CPU_LOCK /*!< CPU lockup signal connected */ +#define SYSCFG_BKPRAM_LOCKUP SYSCFG_LKCTL_BKPRAM_LOCK /*!< Region 2 backup SRAM ECC double error signal connected */ +#define SYSCFG_SRAM1_LOCKUP SYSCFG_LKCTL_SRAM1_LOCK /*!< Region 1 SRAM1 ECC double error signal connected */ +#define SYSCFG_SRAM0_LOCKUP SYSCFG_LKCTL_SRAM0_LOCK /*!< Region 1 SRAM0 ECC double error signal connected */ +#define SYSCFG_DTCM_LOCKUP SYSCFG_LKCTL_DTCM_LOCK /*!< Region 0 DTCM ECC double error signal connected */ +#define SYSCFG_ITCM_LOCKUP SYSCFG_LKCTL_ITCM_LOCK /*!< Region 0 ITCM-RAM ECC double error signal connected */ +#define SYSCFG_AXIRAM_LOCKUP SYSCFG_LKCTL_AXIRAM_LOCK /*!< Region 0 AXI-SRAM ECC double error signal connected */ + +/* SYSCFG compensation flag definitions */ +#define SYSCFG_FLAG_IO_LOW_VOLTAGE SYSCFG_CPSCTL_IOLV /*!< I/O in low voltage state flag, product supply voltage is working below 2.5V */ +#define SYSCFG_FLAG_COMPENSATION_READY SYSCFG_CPSCTL_CPS_RDY /*!< I/O compensation cell ready flag */ + +/* SYSCFG FPU interrupt definitions */ +#define SYSCFG_FPUINT_INEXACT SYSCFG_FPUINTEN_IXIE /*!< inexact interrupt */ +#define SYSCFG_FPUINT_INPUT_ABNORMAL SYSCFG_FPUINTEN_IDIE /*!< input abnormal interrupt */ +#define SYSCFG_FPUINT_OVERFLOW SYSCFG_FPUINTEN_OVFIE /*!< overflow interrupt */ +#define SYSCFG_FPUINT_UNDERFLOW SYSCFG_FPUINTEN_UFIE /*!< underflow interrupt */ +#define SYSCFG_FPUINT_DIV0 SYSCFG_FPUINTEN_DZIE /*!< divide-by-zero interrupt */ +#define SYSCFG_FPUINT_INVALID_OPERATION SYSCFG_FPUINTEN_IOPIE /*!< invalid operation interrupt */ + +/* BOOT modes definitions */ +#define BOOT_SRAM ((uint32_t)0x00000000U) /*!< BOOT from SRAM (ITCM/DTCM/RAM shared/AXI SRAM) */ +#define BOOT_SECURITY ((uint32_t)0x00000001U) /*!< BOOT from Security */ +#define BOOT_SYSTEM ((uint32_t)0x00000002U) /*!< BOOT_SYS (BootLoader) */ +#define BOOT_USER_FLASH ((uint32_t)0x00000003U) /*!< BOOT_USER (User flash OSPI0/1) */ + +/* BOR threshold level definitions */ +#define BOR_OFF ((uint32_t)0x00000000U) /*!< no BOR function */ +#define BOR_THRESHOLD_VAL1 ((uint32_t)0x00000001U) /*!< BOR threshold value 1 */ +#define BOR_THRESHOLD_VAL2 ((uint32_t)0x00000002U) /*!< BOR threshold value 2 */ +#define BOR_THRESHOLD_VAL3 ((uint32_t)0x00000003U) /*!< BOR threshold value 3 */ + +/* function declarations */ +/* initialization functions */ +/* reset the SYSCFG registers */ +void syscfg_deinit(void); + +/* peripheral SYSCFG configuration functions */ +/* enable I2Cx(x=0,1,2,3) fast mode plus or I2C fast mode plus PBx(x=6,7,8,9) */ +void syscfg_i2c_fast_mode_plus_enable(uint32_t i2c_fmp); +/* disable I2Cx(x=0,1,2,3) fast mode plus or I2C fast mode plus PBx(x=6,7,8,9) */ +void syscfg_i2c_fast_mode_plus_disable(uint32_t i2c_fmp); +/* open analog switch (Pxy_C and Pxy are separated pads) */ +void syscfg_analog_switch_enable(uint32_t gpio_answ); +/* close analog switch (Pxy_C and Pxy are connected through the analog switch) */ +void syscfg_analog_switch_disable(uint32_t gpio_answ); +/* configure the PHY interface for the Ethernet MAC */ +void syscfg_enet_phy_interface_config(uint32_t ethernet, uint32_t phy_interface); +/* configure the GPIO pin as EXTI line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); +/* enable module lockup function (function can be disabled by system reset) */ +void syscfg_lockup_enable(uint32_t lockup); +/* select timer channel input source */ +void syscfg_timer_input_source_select(timer_channel_input_enum timer_input); + +/* I/O compensation cell functions */ +/* configure the I/O compensation cell */ +void syscfg_io_compensation_config(uint32_t syscfg_cps); +/* enable I/O speed optimization, high-speed at low-voltage */ +void syscfg_io_low_voltage_speed_optimization_enable(void); +/* disable I/O speed optimization, high-speed at low-voltage */ +void syscfg_io_low_voltage_speed_optimization_disable(void); +/* set P/N MOS compensation value */ +void syscfg_pnmos_compensation_code_set(uint32_t mos, uint32_t code); + +/* secure and boot functions */ +/* set secure SRAM size */ +void syscfg_secure_sram_size_set(uint32_t size); +/* get secure SRAM size */ +uint32_t syscfg_secure_sram_size_get(void); +/* get BOOT mode */ +uint32_t syscfg_bootmode_get(void); +/* enable TCM wait state */ +void syscfg_tcm_wait_state_enable(void); +/* disable TCM wait state */ +void syscfg_tcm_wait_state_disable(void); + +/* flag and interrupt functions */ +/* FPU interrupt enable */ +void syscfg_fpu_interrupt_enable(uint32_t fpu_int); +/* FPU interrupt disable */ +void syscfg_fpu_interrupt_disable(uint32_t fpu_int); +/* get compensation cell flags */ +FlagStatus syscfg_compensation_flag_get(uint32_t cps_flag); +/* get ICACHE or DCACHE status */ +uint32_t syscfg_cpu_cache_status_get(uint32_t cache, uint32_t status); +/* get brownout reset threshold level */ +uint32_t syscfg_brownout_reset_threshold_level_get(void); +#endif /* GD32H7XX_SYSCFG_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_timer.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_timer.h new file mode 100644 index 0000000000..51a4e1a909 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_timer.h @@ -0,0 +1,1265 @@ +/*! + \file gd32h7xx_timer.h + \brief definitions for the TIMER + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + + +#ifndef GD32H7XX_TIMER_H +#define GD32H7XX_TIMER_H + +#include "gd32h7xx.h" + +/* TIMER definitions */ +#define TIMER0 (TIMER_BASE + 0x00010000U) /*!< TIMER0 base address */ +#define TIMER1 (TIMER_BASE + 0x00000000U) /*!< TIMER1 base address */ +#define TIMER2 (TIMER_BASE + 0x00000400U) /*!< TIMER2 base address */ +#define TIMER3 (TIMER_BASE + 0x00000800U) /*!< TIMER3 base address */ +#define TIMER4 (TIMER_BASE + 0x00000C00U) /*!< TIMER4 base address */ +#define TIMER5 (TIMER_BASE + 0x00001000U) /*!< TIMER5 base address */ +#define TIMER6 (TIMER_BASE + 0x00001400U) /*!< TIMER6 base address */ +#define TIMER7 (TIMER_BASE + 0x00010400U) /*!< TIMER7 base address */ +#define TIMER14 (TIMER_BASE + 0x00014000U) /*!< TIMER14 base address */ +#define TIMER15 (TIMER_BASE + 0x00014400U) /*!< TIMER15 base address */ +#define TIMER16 (TIMER_BASE + 0x00014800U) /*!< TIMER16 base address */ +#define TIMER22 (TIMER_BASE + 0x0000E000U) /*!< TIMER22 base address */ +#define TIMER23 (TIMER_BASE + 0x0000E400U) /*!< TIMER23 base address */ +#define TIMER30 (TIMER_BASE + 0x0000E800U) /*!< TIMER30 base address */ +#define TIMER31 (TIMER_BASE + 0x0000EC00U) /*!< TIMER31 base address */ +#define TIMER40 (TIMER_BASE + 0x0001D000U) /*!< TIMER40 base address */ +#define TIMER41 (TIMER_BASE + 0x0001D400U) /*!< TIMER41 base address */ +#define TIMER42 (TIMER_BASE + 0x0001D800U) /*!< TIMER42 base address */ +#define TIMER43 (TIMER_BASE + 0x0001DC00U) /*!< TIMER43 base address */ +#define TIMER44 (TIMER_BASE + 0x0001F000U) /*!< TIMER44 base address */ +#define TIMER50 (TIMER_BASE + 0x0000F000U) /*!< TIMER50 base address */ +#define TIMER51 (TIMER_BASE + 0x0000F400U) /*!< TIMER51 base address */ + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00000000U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x00000004U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x00000008U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0000000CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x00000010U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x00000014U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x00000018U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x0000001CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x00000020U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x00000024U) /*!< TIMER counter register */ +#define TIMER_CNTL(timerx) REG32((timerx) + 0x00000024U) /*!< TIMER counter low register (only for TIMERx, x=50,51) */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x00000028U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x0000002CU) /*!< TIMER counter auto reload register */ +#define TIMER_CARL(timerx) REG32((timerx) + 0x0000002CU) /*!< TIMER counter auto reload low register (only for TIMERx, x=50,51) */ +#define TIMER_CREP0(timerx) REG32((timerx) + 0x00000030U) /*!< TIMER counter repetition register 0 */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x00000034U) /*!< TIMER channel 0 capture or compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x00000038U) /*!< TIMER channel 1 capture or compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x0000003CU) /*!< TIMER channel 2 capture or compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x00000040U) /*!< TIMER channel 3 capture or compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x00000044U) /*!< TIMER channel complementary protection register */ +#define TIMER_MCHCTL0(timerx) REG32((timerx) + 0x00000048U) /*!< TIMER multi mode channel control register 0 */ +#define TIMER_MCHCTL1(timerx) REG32((timerx) + 0x0000004CU) /*!< TIMER multi mode channel control register 1 */ +#define TIMER_MCHCTL2(timerx) REG32((timerx) + 0x00000050U) /*!< TIMER multi mode channel control register 2 */ +#define TIMER_MCH0CV(timerx) REG32((timerx) + 0x00000054U) /*!< TIMER multi mode channel 0 capture or compare value register */ +#define TIMER_MCH1CV(timerx) REG32((timerx) + 0x00000058U) /*!< TIMER multi mode channel 1 capture or compare value register */ +#define TIMER_MCH2CV(timerx) REG32((timerx) + 0x0000005CU) /*!< TIMER multi mode channel 2 capture or compare value register */ +#define TIMER_MCH3CV(timerx) REG32((timerx) + 0x00000060U) /*!< TIMER multi mode channel 3 capture or compare value register */ +#define TIMER_CH0COMV_ADD(timerx) REG32((timerx) + 0x00000064U) /*!< TIMER channel 0 additional compare value register */ +#define TIMER_CH1COMV_ADD(timerx) REG32((timerx) + 0x00000068U) /*!< TIMER channel 1 additional compare value register */ +#define TIMER_CH2COMV_ADD(timerx) REG32((timerx) + 0x0000006CU) /*!< TIMER channel 2 additional compare value register */ +#define TIMER_CH3COMV_ADD(timerx) REG32((timerx) + 0x00000070U) /*!< TIMER channel 3 additional compare value register */ +#define TIMER_CTL2(timerx) REG32((timerx) + 0x00000074U) /*!< TIMER control register 2 */ +#define TIMER_FCCHP0(timerx) REG32((timerx) + 0x0000007CU) /*!< TIMER free complementary channel protection register 0 */ +#define TIMER_FCCHP1(timerx) REG32((timerx) + 0x00000080U) /*!< TIMER free complementary channel protection register 1 */ +#define TIMER_FCCHP2(timerx) REG32((timerx) + 0x00000084U) /*!< TIMER free complementary channel protection register 2 */ +#define TIMER_FCCHP3(timerx) REG32((timerx) + 0x00000088U) /*!< TIMER free complementary channel protection register 3 */ +#define TIMER_AFCTL0(timerx) REG32((timerx) + 0x0000008CU) /*!< TIMER alternate function control register 0 */ +#define TIMER_AFCTL1(timerx) REG32((timerx) + 0x00000090U) /*!< TIMER alternate function control register 1 */ +#define TIMER_WDGPER(timerx) REG32((timerx) + 0x00000094U) /*!< TIMER watchdog counter period register */ +#define TIMER_CREP1(timerx) REG32((timerx) + 0x00000098U) /*!< TIMER counter repetition register 1 */ +#define TIMER_CNTH(timerx) REG32((timerx) + 0x000000D0U) /*!< TIMER counter high register (only for TIMERx, x=50,51) */ +#define TIMER_CARH(timerx) REG32((timerx) + 0x000000D4U) /*!< TIMER counter auto reload high register (only for TIMERx, x=50,51) */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x000000E0U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x000000E4U) /*!< TIMER DMA transfer buffer register */ +#define TIMER_CFG(timerx) REG32((timerx) + 0x000000FCU) /*!< TIMER configuration register */ + +/* bits definitions */ +/* TIMER_CTL0 */ +#define TIMER_CTL0_CEN BIT(0) /*!< TIMER counter enable */ +#define TIMER_CTL0_UPDIS BIT(1) /*!< update disable */ +#define TIMER_CTL0_UPS BIT(2) /*!< update source */ +#define TIMER_CTL0_SPM BIT(3) /*!< single pulse mode */ +#define TIMER_CTL0_DIR BIT(4) /*!< timer counter direction */ +#define TIMER_CTL0_CAM BITS(5,6) /*!< counter aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ +#define TIMER_CTL0_UPIFBUEN BIT(11) /*!< UPIF bit backup enable */ + +/* TIMER_CTL1 */ +#define TIMER_CTL1_CCSE BIT(0) /*!< commutation control shadow enable */ +#define TIMER_CTL1_CCUC (BIT(2) | BITS(30,31)) /*!< commutation control shadow register update control */ +#define TIMER_CTL1_DMAS BIT(3) /*!< DMA request source selection */ +#define TIMER_CTL1_MMC0 BITS(4,6) /*!< master mode control 0 */ +#define TIMER_CTL1_TI0S BIT(7) /*!< channel 0 trigger input selection(hall mode selection) */ +#define TIMER_CTL1_ISO0 BIT(8) /*!< idle state of channel 0 output */ +#define TIMER_CTL1_ISO0N BIT(9) /*!< idle state of channel 0 complementary output */ +#define TIMER_CTL1_ISO1 BIT(10) /*!< idle state of channel 1 output */ +#define TIMER_CTL1_ISO1N BIT(11) /*!< idle state of channel 1 complementary output */ +#define TIMER_CTL1_ISO2 BIT(12) /*!< idle state of channel 2 output */ +#define TIMER_CTL1_ISO2N BIT(13) /*!< idle state of channel 2 complementary output */ +#define TIMER_CTL1_ISO3 BIT(14) /*!< idle state of channel 3 output */ +#define TIMER_CTL1_ISO3N BIT(15) /*!< idle state of channel 3 complementary output */ +#define TIMER_CTL1_MMC1 BITS(20,22) /*!< master mode control 1 */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CMTIE BIT(5) /*!< commutation interrupt request enable */ +#define TIMER_DMAINTEN_TRGIE BIT(6) /*!< trigger interrupt enable */ +#define TIMER_DMAINTEN_BRKIE BIT(7) /*!< break interrupt enable */ +#define TIMER_DMAINTEN_UPDEN BIT(8) /*!< update DMA request enable */ +#define TIMER_DMAINTEN_CH0DEN BIT(9) /*!< channel 0 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< commutation DMA request enable */ +#define TIMER_DMAINTEN_TRGDEN BIT(14) /*!< trigger DMA request enable */ +#define TIMER_DMAINTEN_DECJIE BIT(16) /*!< quadrature decoder signal jump (the two signals jump at the same time) interrupt enable */ +#define TIMER_DMAINTEN_DECDISIE BIT(17) /*!< quadrature decoder signal disconnection interrupt enable */ +#define TIMER_DMAINTEN_MCH0IE BIT(20) /*!< multi mode channel 0 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH1IE BIT(21) /*!< multi mode channel 1 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH2IE BIT(22) /*!< multi mode channel 2 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH3IE BIT(23) /*!< multi mode channel 3 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH0DEN BIT(24) /*!< multi mode channel 0 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_MCH1DEN BIT(25) /*!< multi mode channel 1 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_MCH2DEN BIT(26) /*!< multi mode channel 2 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_MCH3DEN BIT(27) /*!< multi mode channel 3 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH0COMADDIE BIT(28) /*!< channel 0 additional compare interrupt enable */ +#define TIMER_DMAINTEN_CH1COMADDIE BIT(29) /*!< channel 1 additional compare interrupt enable */ +#define TIMER_DMAINTEN_CH2COMADDIE BIT(30) /*!< channel 2 additional compare interrupt enable */ +#define TIMER_DMAINTEN_CH3COMADDIE BIT(31) /*!< channel 3 additional compare interrupt enable */ + +/* TIMER_INTF */ +#define TIMER_INTF_UPIF BIT(0) /*!< update interrupt flag */ +#define TIMER_INTF_CH0IF BIT(1) /*!< channel 0 capture or compare interrupt flag */ +#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 capture or compare interrupt flag */ +#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 capture or compare interrupt flag */ +#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 capture or compare interrupt flag */ +#define TIMER_INTF_CMTIF BIT(5) /*!< channel commutation interrupt flag */ +#define TIMER_INTF_TRGIF BIT(6) /*!< trigger interrupt flag */ +#define TIMER_INTF_BRK0IF BIT(7) /*!< BREAK0 interrupt flag */ +#define TIMER_INTF_BRK1IF BIT(8) /*!< BREAK1 interrupt flag */ +#define TIMER_INTF_CH0OF BIT(9) /*!< channel 0 over capture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 over capture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 over capture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 over capture flag */ +#define TIMER_INTF_SYSBIF BIT(13) /*!< system source break interrupt flag */ +#define TIMER_INTF_DECJIF BIT(16) /*!< quadrature decoder signal jump (the two signals jump at the same time) interrupt flag */ +#define TIMER_INTF_DECDISIF BIT(17) /*!< quadrature decoder signal disconnection interrupt flag */ +#define TIMER_INTF_MCH0IF BIT(20) /*!< multi mode channel 0 capture or compare interrupt flag */ +#define TIMER_INTF_MCH1IF BIT(21) /*!< multi mode channel 1 capture or compare interrupt flag */ +#define TIMER_INTF_MCH2IF BIT(22) /*!< multi mode channel 2 capture or compare interrupt flag */ +#define TIMER_INTF_MCH3IF BIT(23) /*!< multi mode channel 3 capture or compare interrupt flag */ +#define TIMER_INTF_MCH0OF BIT(24) /*!< multi mode channel 0 over capture flag */ +#define TIMER_INTF_MCH1OF BIT(25) /*!< multi mode channel 1 over capture flag */ +#define TIMER_INTF_MCH2OF BIT(26) /*!< multi mode channel 2 over capture flag */ +#define TIMER_INTF_MCH3OF BIT(27) /*!< multi mode channel 3 over capture flag */ +#define TIMER_INTF_CH0COMADDIF BIT(28) /*!< channel 0 additional compare interrupt flag */ +#define TIMER_INTF_CH1COMADDIF BIT(29) /*!< channel 1 additional compare interrupt flag */ +#define TIMER_INTF_CH2COMADDIF BIT(30) /*!< channel 2 additional compare interrupt flag */ +#define TIMER_INTF_CH3COMADDIF BIT(31) /*!< channel 3 additional compare interrupt flag */ + +/* TIMER_SWEVG */ +#define TIMER_SWEVG_UPG BIT(0) /*!< update event generate */ +#define TIMER_SWEVG_CH0G BIT(1) /*!< channel 0 capture or compare event generation */ +#define TIMER_SWEVG_CH1G BIT(2) /*!< channel 1 capture or compare event generation */ +#define TIMER_SWEVG_CH2G BIT(3) /*!< channel 2 capture or compare event generation */ +#define TIMER_SWEVG_CH3G BIT(4) /*!< channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CMTG BIT(5) /*!< channel commutation event generation */ +#define TIMER_SWEVG_TRGG BIT(6) /*!< trigger event generation */ +#define TIMER_SWEVG_BRK0G BIT(7) /*!< BREAK0 event generation */ +#define TIMER_SWEVG_BRK1G BIT(8) /*!< BREAK1 event generation */ +#define TIMER_SWEVG_MCH0G BIT(20) /*!< multi mode channel 0 capture or compare event generation */ +#define TIMER_SWEVG_MCH1G BIT(21) /*!< multi mode channel 1 capture or compare event generation */ +#define TIMER_SWEVG_MCH2G BIT(22) /*!< multi mode channel 2 capture or compare event generation */ +#define TIMER_SWEVG_MCH3G BIT(23) /*!< multi mode channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CH0COMADDG BIT(28) /*!< channel 0 additional compare event generation */ +#define TIMER_SWEVG_CH1COMADDG BIT(29) /*!< channel 1 additional compare event generation */ +#define TIMER_SWEVG_CH2COMADDG BIT(30) /*!< channel 2 additional compare event generation */ +#define TIMER_SWEVG_CH3COMADDG BIT(31) /*!< channel 3 additional compare event generation */ + +/* TIMER_CHCTL0 */ +/* output compare mode */ +#define TIMER_CHCTL0_CH0MS (BITS(0,1) | BIT(30)) /*!< channel 0 mode selection */ +#define TIMER_CHCTL0_CH0COMSEN BIT(3) /*!< channel 0 output compare shadow enable */ +#define TIMER_CHCTL0_CH0COMCTL (BITS(4,6) | BIT(16)) /*!< channel 0 output compare control */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS (BITS(8,9) | BIT(31)) /*!< channel 1 mode selection */ +#define TIMER_CHCTL0_CH1COMSEN BIT(11) /*!< channel 1 output compare shadow enable */ +#define TIMER_CHCTL0_CH1COMCTL (BITS(12,14) | BIT(24)) /*!< channel 1 output compare control */ +#define TIMER_CHCTL0_CH1COMCEN BIT(15) /*!< channel 1 output compare clear enable */ +#define TIMER_CHCTL0_CH0COMADDSEN BIT(28) /*!< channel 0 additional compare output shadow enable */ +#define TIMER_CHCTL0_CH1COMADDSEN BIT(29) /*!< channel 1 additional compare output shadow enable */ +/* input capture mode */ +#define TIMER_CHCTL0_CH0CAPPSC BITS(2,3) /*!< channel 0 input capture prescaler */ +#define TIMER_CHCTL0_CH0CAPFLT BITS(4,7) /*!< channel 0 input capture filter control */ +#define TIMER_CHCTL0_CH1CAPPSC BITS(10,11) /*!< channel 1 input capture prescaler */ +#define TIMER_CHCTL0_CH1CAPFLT BITS(12,15) /*!< channel 1 input capture filter control */ + +/* TIMER_CHCTL1 */ +/* output compare mode */ +#define TIMER_CHCTL1_CH2MS (BITS(0,1) | BIT(30)) /*!< channel 2 mode selection */ +#define TIMER_CHCTL1_CH2COMSEN BIT(3) /*!< channel 2 output compare shadow enable */ +#define TIMER_CHCTL1_CH2COMCTL (BITS(4,6) | BIT(16)) /*!< channel 2 output compare control */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS (BITS(8,9) | BIT(31)) /*!< channel 3 mode selection */ +#define TIMER_CHCTL1_CH3COMSEN BIT(11) /*!< channel 3 output compare shadow enable */ +#define TIMER_CHCTL1_CH3COMCTL (BITS(12,14) | BIT(24)) /*!< channel 3 output compare control */ +#define TIMER_CHCTL1_CH3COMCEN BIT(15) /*!< channel 3 output compare clear enable */ +#define TIMER_CHCTL1_CH2COMADDSEN BIT(28) /*!< channel 2 additional compare output shadow enable */ +#define TIMER_CHCTL1_CH3COMADDSEN BIT(29) /*!< channel 3 additional compare output shadow enable */ +/* input capture mode */ +#define TIMER_CHCTL1_CH2CAPPSC BITS(2,3) /*!< channel 2 input capture prescaler */ +#define TIMER_CHCTL1_CH2CAPFLT BITS(4,7) /*!< channel 2 input capture filter control */ +#define TIMER_CHCTL1_CH3CAPPSC BITS(10,11) /*!< channel 3 input capture prescaler */ +#define TIMER_CHCTL1_CH3CAPFLT BITS(12,15) /*!< channel 3 input capture filter control */ + +/* TIMER_CHCTL2 */ +#define TIMER_CHCTL2_CH0EN BIT(0) /*!< channel 0 capture or compare function enable */ +#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 capture or compare function polarity */ +#define TIMER_CHCTL2_CH0NEN BIT(2) /*!< channel 0 complementary output enable */ +#define TIMER_CHCTL2_CH0NP BIT(3) /*!< channel 0 complementary output polarity */ +#define TIMER_CHCTL2_CH1EN BIT(4) /*!< channel 1 capture or compare function enable */ +#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 capture or compare function polarity */ +#define TIMER_CHCTL2_CH1NEN BIT(6) /*!< channel 1 complementary output enable */ +#define TIMER_CHCTL2_CH1NP BIT(7) /*!< channel 1 complementary output polarity */ +#define TIMER_CHCTL2_CH2EN BIT(8) /*!< channel 2 capture or compare function enable */ +#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 capture or compare function polarity */ +#define TIMER_CHCTL2_CH2NEN BIT(10) /*!< channel 2 complementary output enable */ +#define TIMER_CHCTL2_CH2NP BIT(11) /*!< channel 2 complementary output polarity */ +#define TIMER_CHCTL2_CH3EN BIT(12) /*!< channel 3 capture or compare function enable */ +#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 capture or compare function polarity */ +#define TIMER_CHCTL2_CH3NEN BIT(14) /*!< channel 3 complementary output enable */ +#define TIMER_CHCTL2_CH3NP BIT(15) /*!< channel 3 complementary output polarity */ + +#define TIMER_CHCTL2_MCH0EN BIT(2) /*!< multi mode channel 0 capture or compare function enable */ +#define TIMER_CHCTL2_MCH0P BIT(3) /*!< multi mode channel 0 complementary output polarity */ +#define TIMER_CHCTL2_MCH1EN BIT(6) /*!< multi mode channel 1 capture or compare function enable */ +#define TIMER_CHCTL2_MCH1P BIT(7) /*!< multi mode channel 1 complementary output polarity */ +#define TIMER_CHCTL2_MCH2EN BIT(10) /*!< multi mode channel 2 capture or compare function enable */ +#define TIMER_CHCTL2_MCH2P BIT(11) /*!< multi mode channel 2 complementary output polarity */ +#define TIMER_CHCTL2_MCH3EN BIT(14) /*!< multi mode channel 3 capture or compare function enable */ +#define TIMER_CHCTL2_MCH3P BIT(15) /*!< multi mode channel 3 complementary output polarity */ + +/* TIMER_CNT */ +#define TIMER_CNT_UPIFBU BIT(31) /*!< UPIF bit backup */ +#define TIMER_CNT_CNT BITS(0,15) /*!< 16 bit timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL BITS(0,15) /*!< 16 bit counter auto reload value */ + +/* TIMER_CREP0 */ +#define TIMER_CREP0_CREP0 BITS(0,7) /*!< counter repetition value 0 */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRK0EN BIT(12) /*!< BREAK0 input signal enable */ +#define TIMER_CCHP_BRK0P BIT(13) /*!< BREAK0 input signal polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ +#define TIMER_CCHP_BRK0F BITS(16,19) /*!< BREAK0 input signal filter */ +#define TIMER_CCHP_BRK1F BITS(20,23) /*!< BREAK1 input signal filter */ +#define TIMER_CCHP_BRK1EN BIT(24) /*!< BREAK1 input signal enable */ +#define TIMER_CCHP_BRK1P BIT(25) /*!< BREAK1 input signal polarity */ +#define TIMER_CCHP_BRK0REL BIT(26) /*!< BREAK0 input released */ +#define TIMER_CCHP_BRK1REL BIT(27) /*!< BREAK1 input released */ +#define TIMER_CCHP_BRK0LK BIT(28) /*!< BREAK0 input locked */ +#define TIMER_CCHP_BRK1LK BIT(29) /*!< BREAK1 input locked */ + +/* TIMER_MCHCTL0 */ +/* output compare mode */ +#define TIMER_MCHCTL0_MCH0MS (BITS(0,1) | BIT(30)) /*!< multi mode channel 0 I/O mode selection */ +#define TIMER_MCHCTL0_MCH0COMSEN BIT(3) /*!< multi mode channel 0 output compare shadow enable */ +#define TIMER_MCHCTL0_MCH0COMCTL (BITS(4,6) | BIT(16)) /*!< multi mode channel 0 compare output control */ +#define TIMER_MCHCTL0_MCH0COMCEN BIT(7) /*!< multi mode channel 0 output compare clear enable */ +#define TIMER_MCHCTL0_MCH1MS (BITS(8,9) | BIT(31)) /*!< multi mode channel 1 I/O mode selection */ +#define TIMER_MCHCTL0_MCH1COMSEN BIT(11) /*!< multi mode channel 1 output compare shadow enable */ +#define TIMER_MCHCTL0_MCH1COMCTL (BITS(12,14) | BIT(24)) /*!< multi mode channel 1 compare output control */ +#define TIMER_MCHCTL0_MCH1COMCEN BIT(15) /*!< multi mode channel 1 output compare clear enable */ +/* input capture mode */ +#define TIMER_MCHCTL0_MCH0CAPPSC BITS(2,3) /*!< multi mode channel 0 input capture prescaler */ +#define TIMER_MCHCTL0_MCH0CAPFLT BITS(4,7) /*!< multi mode channel 0 input capture filter control */ +#define TIMER_MCHCTL0_MCH1CAPPSC BITS(10,11) /*!< multi mode channel 1 input capture prescaler */ +#define TIMER_MCHCTL0_MCH1CAPFLT BITS(12,15) /*!< multi mode channel 1 input capture filter control */ + +/* TIMER_MCHCTL1 */ +/* output compare mode */ +#define TIMER_MCHCTL1_MCH2MS (BITS(0,1) | BIT(30)) /*!< multi mode channel 2 I/O mode selection */ +#define TIMER_MCHCTL1_MCH2COMSEN BIT(3) /*!< multi mode channel 2 output compare shadow enable */ +#define TIMER_MCHCTL1_MCH2COMCTL (BITS(4,6) | BIT(16)) /*!< multi mode channel 2 compare output control */ +#define TIMER_MCHCTL1_MCH2COMCEN BIT(7) /*!< multi mode channel 2 output compare clear enable */ +#define TIMER_MCHCTL1_MCH3MS (BITS(8,9) | BIT(31)) /*!< multi mode channel 3 I/O mode selection */ +#define TIMER_MCHCTL1_MCH3COMSEN BIT(11) /*!< multi mode channel 3 output compare shadow enable */ +#define TIMER_MCHCTL1_MCH3COMCTL (BITS(12,14) | BIT(24)) /*!< multi mode channel 3 compare output control */ +#define TIMER_MCHCTL1_MCH3COMCEN BIT(15) /*!< multi mode channel 3 output compare clear enable */ +/* input capture mode */ +#define TIMER_MCHCTL1_MCH2CAPPSC BITS(2,3) /*!< multi mode channel 2 input capture prescaler */ +#define TIMER_MCHCTL1_MCH2CAPFLT BITS(4,7) /*!< multi mode channel 2 input capture filter control */ +#define TIMER_MCHCTL1_MCH3CAPPSC BITS(10,11) /*!< multi mode channel 3 input capture prescaler */ +#define TIMER_MCHCTL1_MCH3CAPFLT BITS(12,15) /*!< multi mode channel 3 input capture filter control */ + +/* TIMER_MCHCTL2 */ +#define TIMER_MCHCTL2_MCH0FP BITS(0,1) /*!< multi mode channel 0 capture or compare function polarity */ +#define TIMER_MCHCTL2_MCH1FP BITS(2,3) /*!< multi mode channel 1 capture or compare function polarity */ +#define TIMER_MCHCTL2_MCH2FP BITS(4,5) /*!< multi mode channel 2 capture or compare function polarity */ +#define TIMER_MCHCTL2_MCH3FP BITS(6,7) /*!< multi mode channel 3 capture or compare function polarity */ + +/* TIMER_MCH0CV */ +#define TIMER_MCH0CV_MCH0VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 0 */ + +/* TIMER_MCH1CV */ +#define TIMER_MCH1CV_MCH1VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 1 */ + +/* TIMER_MCH2CV */ +#define TIMER_MCH2CV_MCH2VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 2 */ + +/* TIMER_MCH3CV */ +#define TIMER_MCH3CV_MCH3VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 3 */ + +/* TIMER_CH0COMV_ADD */ +#define TIMER_CH0COMV_ADD_CH0COMVAL BITS(0,15) /*!< additional compare value of channel 0 */ + +/* TIMER_CH1COMV_ADD */ +#define TIMER_CH1COMV_ADD_CH1COMVAL BITS(0,15) /*!< additional compare value of channel 1 */ + +/* TIMER_CH2COMV_ADD */ +#define TIMER_CH2COMV_ADD_CH2COMVAL BITS(0,15) /*!< additional compare value of channel 2 */ + +/* TIMER_CH3COMV_ADD */ +#define TIMER_CH3COMV_ADD_CH3COMVAL BITS(0,15) /*!< additional compare value of channel 3 */ + +/* TIMER_CTL2 */ +#define TIMER_CTL2_DTIENCH0 BIT(0) /*!< dead time inserted enable for channel 0 and channel 0N */ +#define TIMER_CTL2_DTIENCH1 BIT(1) /*!< dead time inserted enable for channel 1 and channel 1N */ +#define TIMER_CTL2_DTIENCH2 BIT(2) /*!< dead time inserted enable for channel 2 and channel 2N */ +#define TIMER_CTL2_DTIENCH3 BIT(3) /*!< dead time inserted enable for channel 3 and channel 3N */ +#define TIMER_CTL2_BRKENCH0 BIT(4) /*!< break control enable for channel 0 and multi mode channel 0 */ +#define TIMER_CTL2_BRKENCH1 BIT(5) /*!< break control enable for channel 1 and multi mode channel 1 */ +#define TIMER_CTL2_BRKENCH2 BIT(6) /*!< break control enable for channel 2 and multi mode channel 2 */ +#define TIMER_CTL2_BRKENCH3 BIT(7) /*!< break control enable for channel 3 and multi mode channel 3 */ +#define TIMER_CTL2_CH0OMPSEL BITS(8,9) /*!< channel 0 output march pulse select */ +#define TIMER_CTL2_CH1OMPSEL BITS(10,11) /*!< channel 1 output march pulse select */ +#define TIMER_CTL2_CH2OMPSEL BITS(12,13) /*!< channel 2 output march pulse select */ +#define TIMER_CTL2_CH3OMPSEL BITS(14,15) /*!< channel 3 output march pulse select */ +#define TIMER_CTL2_DECJDEN BIT(18) /*!< quadrature decoder signal jump (the two signals jump at the same time) detection enable */ +#define TIMER_CTL2_DECDISDEN BIT(19) /*!< quadrature decoder signal disconnection detection enable */ +#define TIMER_CTL2_MCH0MSEL BITS(20,21) /*!< multi mode channel 0 mode select */ +#define TIMER_CTL2_MCH1MSEL BITS(22,23) /*!< multi mode channel 1 mode select */ +#define TIMER_CTL2_MCH2MSEL BITS(24,25) /*!< multi mode channel 2 mode select */ +#define TIMER_CTL2_MCH3MSEL BITS(26,27) /*!< multi mode channel 3 mode select */ +#define TIMER_CTL2_CH0CPWMEN BIT(28) /*!< channel 0 composite PWM mode enable */ +#define TIMER_CTL2_CH1CPWMEN BIT(29) /*!< channel 1 composite PWM mode enable */ +#define TIMER_CTL2_CH2CPWMEN BIT(30) /*!< channel 2 composite PWM mode enable */ +#define TIMER_CTL2_CH3CPWMEN BIT(31) /*!< channel 3 composite PWM mode enable */ + +/* TIMER_FCCHP0 */ +#define TIMER_FCCHP0_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP0_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP0_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP0_FCCHP0EN BIT(31) /*!< free complementary channel protection register 0 enable */ + +/* TIMER_FCCHP1 */ +#define TIMER_FCCHP1_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP1_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP1_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP1_FCCHP1EN BIT(31) /*!< free complementary channel protection register 1 enable */ + +/* TIMER_FCCHP2 */ +#define TIMER_FCCHP2_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP2_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP2_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP2_FCCHP2EN BIT(31) /*!< free complementary channel protection register 2 enable */ + +/* TIMER_FCCHP3 */ +#define TIMER_FCCHP3_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP3_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP3_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP3_FCCHP3EN BIT(31) /*!< free complementary channel protection register 3 enable */ + +/* TIMER_AFCTL0 */ +#define TIMER_AFCTL0_BRK0IN0EN BIT(0) /*!< BREAK0 BRKIN0 alternate function input enable */ +#define TIMER_AFCTL0_BRK0IN1EN BIT(1) /*!< BREAK0 BRKIN1 alternate function input enable */ +#define TIMER_AFCTL0_BRK0IN2EN BIT(2) /*!< BREAK0 BRKIN2 alternate function input enable */ +#define TIMER_AFCTL0_BRK0HPDFEN BIT(8) /*!< BREAK0 HPDF input enable */ +#define TIMER_AFCTL0_BRK0CMP0EN BIT(9) /*!< BREAK0 CMP0 enable */ +#define TIMER_AFCTL0_BRK0CMP1EN BIT(10) /*!< BREAK0 CMP1 enable */ +#define TIMER_AFCTL0_BRK0IN0P BIT(16) /*!< BREAK0 BRKIN0 alternate function input polarity */ +#define TIMER_AFCTL0_BRK0IN1P BIT(17) /*!< BREAK0 BRKIN1 alternate function input polarity */ +#define TIMER_AFCTL0_BRK0IN2P BIT(18) /*!< BREAK0 BRKIN2 alternate function input polarity */ +#define TIMER_AFCTL0_BRK0CMP0P BIT(25) /*!< BREAK0 CMP0 input polarity */ +#define TIMER_AFCTL0_BRK0CMP1P BIT(26) /*!< BREAK0 CMP1 input polarity */ + +/* TIMER_AFCTL1 */ +#define TIMER_AFCTL1_BRK1IN0EN BIT(0) /*!< BREAK1 BRKIN0 alternate function input enable */ +#define TIMER_AFCTL1_BRK1IN1EN BIT(1) /*!< BREAK1 BRKIN1 alternate function input enable */ +#define TIMER_AFCTL1_BRK1IN2EN BIT(2) /*!< BREAK1 BRKIN2 alternate function input enable */ +#define TIMER_AFCTL1_BRK1HPDFEN BIT(8) /*!< BREAK1 HPDF input enable */ +#define TIMER_AFCTL1_BRK1CMP0EN BIT(9) /*!< BREAK1 CMP0 enable */ +#define TIMER_AFCTL1_BRK1CMP1EN BIT(10) /*!< BREAK1 CMP1 enable */ +#define TIMER_AFCTL1_BRK1IN0P BIT(16) /*!< BREAK1 BRKIN0 alternate function input polarity */ +#define TIMER_AFCTL1_BRK1IN1P BIT(17) /*!< BREAK1 BRKIN1 alternate function input polarity */ +#define TIMER_AFCTL1_BRK1IN2P BIT(18) /*!< BREAK1 BRKIN2 alternate function input polarity */ +#define TIMER_AFCTL1_BRK1CMP0P BIT(25) /*!< BREAK1 CMP0 input polarity */ +#define TIMER_AFCTL1_BRK1CMP1P BIT(26) /*!< BREAK1 CMP1 input polarity */ + +/* TIMER_WDGPER */ +#define TIMER_WDGPER_WDGPER BITS(0,31) /*!< watchdog counter period value */ + +/* TIMER_CREP1 */ +#define TIMER_CREP1_CREP1 BITS(0,31) /*!< counter repetition value 1 */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,5) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,13) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,31) /*!< DMA transfer buffer */ + +/* TIMER_CFG */ +#define TIMER_CFG_OUTSEL BIT(0) /*!< the output value selection */ +#define TIMER_CFG_CHVSEL BIT(1) /*!< write CHxVAL register selection */ +#define TIMER_CFG_CREPSEL BIT(2) /*!< the counter repetition register selection */ +#define TIMER_CFG_CCUSEL BIT(3) /*!< commutation control shadow register update select */ + +/* constants definitions */ +/* UPIFBU bit state */ +typedef enum {VALID_RESET = 0, VALID_SET = 1, INVALID = 2} UPIFBUStatus; + +/* TIMER init parameter struct definitions */ +typedef struct { + uint16_t prescaler; /*!< prescaler value */ + uint16_t alignedmode; /*!< aligned mode */ + uint16_t counterdirection; /*!< counter direction */ + uint64_t period; /*!< period value */ + uint16_t clockdivision; /*!< clock division value */ + uint32_t repetitioncounter; /*!< the counter repetition value */ +} timer_parameter_struct; + +/* break parameter struct definitions */ +typedef struct { + uint32_t runoffstate; /*!< run mode off-state */ + uint32_t ideloffstate; /*!< idle mode off-state */ + uint32_t deadtime; /*!< dead time */ + uint32_t outputautostate; /*!< output automatic enable */ + uint32_t protectmode; /*!< complementary register protect control */ + uint32_t break0state; /*!< BREAK0 input enable */ + uint32_t break0filter; /*!< BREAK0 input filter */ + uint32_t break0polarity; /*!< BREAK0 input polarity */ + uint32_t break0lock; /*!< BREAK0 input lock */ + uint32_t break0release; /*!< BREAK0 input release */ + uint32_t break1state; /*!< BREAK1 input enable */ + uint32_t break1filter; /*!< BREAK1 input filter */ + uint32_t break1polarity; /*!< BREAK1 input polarity */ + uint32_t break1lock; /*!< BREAK1 input lock */ + uint32_t break1release; /*!< BREAK1 input release */ +} timer_break_parameter_struct; + +/* channel output parameter struct definitions */ +typedef struct { + uint16_t outputstate; /*!< channel output state */ + uint16_t outputnstate; /*!< channel complementary output state */ + uint16_t ocpolarity; /*!< channel output polarity */ + uint16_t ocnpolarity; /*!< channel complementary output polarity */ + uint16_t ocidlestate; /*!< idle state of channel output */ + uint16_t ocnidlestate; /*!< idle state of channel complementary output */ +} timer_oc_parameter_struct; + +/* multi mode channel output parameter struct definitions */ +typedef struct { + uint16_t outputmode; /*!< multi mode channel output mode selection */ + uint16_t outputstate; /*!< multi mode channel output state */ + uint16_t ocpolarity; /*!< multi mode channel output polarity */ +} timer_omc_parameter_struct; + +/* channel input parameter struct definitions */ +typedef struct { + uint16_t icpolarity; /*!< channel input polarity */ + uint16_t icselection; /*!< channel input mode selection */ + uint16_t icprescaler; /*!< channel input capture prescaler */ + uint16_t icfilter; /*!< channel input capture filter control */ +} timer_ic_parameter_struct; + +/* channel free complementary parameter struct definitions */ +typedef struct { + uint32_t freecomstate; /*!< free complementary channel protection enable */ + uint32_t runoffstate; /*!< run mode off-state */ + uint32_t ideloffstate; /*!< idle mode off-state */ + uint32_t deadtime; /*!< dead time */ +} timer_free_complementary_parameter_struct; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 capture or compare interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 capture or compare interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 capture or compare interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 capture or compare interrupt */ +#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */ +#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */ +#define TIMER_INT_DECJ TIMER_DMAINTEN_DECJIE /*!< quadrature decoder signal jump (the two signals jump at the same time) interrupt */ +#define TIMER_INT_DECDIS TIMER_DMAINTEN_DECDISIE /*!< quadrature decoder signal disconnection interrupt */ +#define TIMER_INT_MCH0 TIMER_DMAINTEN_MCH0IE /*!< multi mode channel 0 capture or compare interrupt */ +#define TIMER_INT_MCH1 TIMER_DMAINTEN_MCH1IE /*!< multi mode channel 1 capture or compare interrupt */ +#define TIMER_INT_MCH2 TIMER_DMAINTEN_MCH2IE /*!< multi mode channel 2 capture or compare interrupt */ +#define TIMER_INT_MCH3 TIMER_DMAINTEN_MCH3IE /*!< multi mode channel 3 capture or compare interrupt */ +#define TIMER_INT_CH0COMADD TIMER_DMAINTEN_CH0COMADDIE /*!< channel 0 additional compare interrupt */ +#define TIMER_INT_CH1COMADD TIMER_DMAINTEN_CH1COMADDIE /*!< channel 1 additional compare interrupt */ +#define TIMER_INT_CH2COMADD TIMER_DMAINTEN_CH2COMADDIE /*!< channel 2 additional compare interrupt */ +#define TIMER_INT_CH3COMADD TIMER_DMAINTEN_CH3COMADDIE /*!< channel 3 additional compare interrupt */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INTF_UPIF /*!< update interrupt flag */ +#define TIMER_INT_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation interrupt flag */ +#define TIMER_INT_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger interrupt flag */ +#define TIMER_INT_FLAG_BRK0 TIMER_INTF_BRK0IF /*!< BREAK0 interrupt flag */ +#define TIMER_INT_FLAG_BRK1 TIMER_INTF_BRK1IF /*!< BREAK1 interrupt flag */ +#define TIMER_INT_FLAG_SYSB TIMER_INTF_SYSBIF /*!< system source break interrupt flag */ +#define TIMER_INT_FLAG_DECJ TIMER_INTF_DECJIF /*!< quadrature decoder signal jump (the two signals jump at the same time) interrupt flag */ +#define TIMER_INT_FLAG_DECDIS TIMER_INTF_DECDISIF /*!< quadrature decoder signal disconnection interrupt flag */ +#define TIMER_INT_FLAG_MCH0 TIMER_INTF_MCH0IF /*!< multi mode channel 0 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_MCH1 TIMER_INTF_MCH1IF /*!< multi mode channel 1 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_MCH2 TIMER_INTF_MCH2IF /*!< multi mode channel 2 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_MCH3 TIMER_INTF_MCH3IF /*!< multi mode channel 3 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_CH0COMADD TIMER_INTF_CH0COMADDIF /*!< channel 0 additional compare interrupt flag */ +#define TIMER_INT_FLAG_CH1COMADD TIMER_INTF_CH1COMADDIF /*!< channel 1 additional compare interrupt flag */ +#define TIMER_INT_FLAG_CH2COMADD TIMER_INTF_CH2COMADDIF /*!< channel 2 additional compare interrupt flag */ +#define TIMER_INT_FLAG_CH3COMADD TIMER_INTF_CH3COMADDIF /*!< channel 3 additional compare interrupt flag */ + +/* TIMER flag */ +#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */ +#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 capture or compare flag */ +#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 capture or compare flag */ +#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 capture or compare flag */ +#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 capture or compare flag */ +#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation flag */ +#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */ +#define TIMER_FLAG_BRK0 TIMER_INTF_BRK0IF /*!< BREAK0 flag */ +#define TIMER_FLAG_BRK1 TIMER_INTF_BRK1IF /*!< BREAK1 flag */ +#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */ +#define TIMER_FLAG_SYSB TIMER_INTF_SYSBIF /*!< system source break flag */ +#define TIMER_FLAG_DECJ TIMER_INTF_DECJIF /*!< quadrature decoder signal jump (the two signals jump at the same time) flag */ +#define TIMER_FLAG_DECDIS TIMER_INTF_DECDISIF /*!< quadrature decoder signal disconnection flag */ +#define TIMER_FLAG_MCH0 TIMER_INTF_MCH0IF /*!< multi mode channel 0 capture or compare flag */ +#define TIMER_FLAG_MCH1 TIMER_INTF_MCH1IF /*!< multi mode channel 1 capture or compare flag */ +#define TIMER_FLAG_MCH2 TIMER_INTF_MCH2IF /*!< multi mode channel 2 capture or compare flag */ +#define TIMER_FLAG_MCH3 TIMER_INTF_MCH3IF /*!< multi mode channel 3 capture or compare flag */ +#define TIMER_FLAG_MCH0O TIMER_INTF_MCH0OF /*!< multi mode channel 0 overcapture flag */ +#define TIMER_FLAG_MCH1O TIMER_INTF_MCH1OF /*!< multi mode channel 1 overcapture flag */ +#define TIMER_FLAG_MCH2O TIMER_INTF_MCH2OF /*!< multi mode channel 2 overcapture flag */ +#define TIMER_FLAG_MCH3O TIMER_INTF_MCH3OF /*!< multi mode channel 3 overcapture flag */ +#define TIMER_FLAG_CH0COMADD TIMER_INTF_CH0COMADDIF /*!< channel 0 additional compare flag */ +#define TIMER_FLAG_CH1COMADD TIMER_INTF_CH1COMADDIF /*!< channel 1 additional compare flag */ +#define TIMER_FLAG_CH2COMADD TIMER_INTF_CH2COMADDIF /*!< channel 2 additional compare flag */ +#define TIMER_FLAG_CH3COMADD TIMER_INTF_CH3COMADDIF /*!< channel 3 additional compare flag */ + +/* TIMER DMA source */ +#define TIMER_DMA_UPD TIMER_DMAINTEN_UPDEN /*!< update DMA request */ +#define TIMER_DMA_CH0D TIMER_DMAINTEN_CH0DEN /*!< channel 0 capture or compare DMA request */ +#define TIMER_DMA_CH1D TIMER_DMAINTEN_CH1DEN /*!< channel 1 capture or compare DMA request */ +#define TIMER_DMA_CH2D TIMER_DMAINTEN_CH2DEN /*!< channel 2 capture or compare DMA request */ +#define TIMER_DMA_CH3D TIMER_DMAINTEN_CH3DEN /*!< channel 3 capture or compare DMA request */ +#define TIMER_DMA_CMTD TIMER_DMAINTEN_CMTDEN /*!< commutation DMA request */ +#define TIMER_DMA_TRGD TIMER_DMAINTEN_TRGDEN /*!< trigger DMA request */ +#define TIMER_DMA_MCH0D TIMER_DMAINTEN_MCH0DEN /*!< multi mode channel 0 capture or compare DMA request */ +#define TIMER_DMA_MCH1D TIMER_DMAINTEN_MCH1DEN /*!< multi mode channel 1 capture or compare DMA request */ +#define TIMER_DMA_MCH2D TIMER_DMAINTEN_MCH2DEN /*!< multi mode channel 2 capture or compare DMA request */ +#define TIMER_DMA_MCH3D TIMER_DMAINTEN_MCH3DEN /*!< multi mode channel 3 capture or compare DMA request */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT TIMER_CTL1_DMAS /*!< DMA request of channel n is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint32_t)0x00000000U) /*!< DMA request of channel n is sent when channel n event occurs */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_CREP0 DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP0 */ +#define TIMER_DMACFG_DMATA_CH0CV DMACFG_DMATA(13) /*!< DMA transfer address is TIMER_CH0CV */ +#define TIMER_DMACFG_DMATA_CH1CV DMACFG_DMATA(14) /*!< DMA transfer address is TIMER_CH1CV */ +#define TIMER_DMACFG_DMATA_CH2CV DMACFG_DMATA(15) /*!< DMA transfer address is TIMER_CH2CV */ +#define TIMER_DMACFG_DMATA_CH3CV DMACFG_DMATA(16) /*!< DMA transfer address is TIMER_CH3CV */ +#define TIMER_DMACFG_DMATA_CCHP DMACFG_DMATA(17) /*!< DMA transfer address is TIMER_CCHP */ +#define TIMER_DMACFG_DMATA_MCHCTL0 DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_MCHCTL0 */ +#define TIMER_DMACFG_DMATA_MCHCTL1 DMACFG_DMATA(19) /*!< DMA transfer address is TIMER_MCHCTL1 */ +#define TIMER_DMACFG_DMATA_MCHCTL2 DMACFG_DMATA(20) /*!< DMA transfer address is TIMER_MCHCTL2 */ +#define TIMER_DMACFG_DMATA_MCH0CV DMACFG_DMATA(21) /*!< DMA transfer address is TIMER_MCH0CV */ +#define TIMER_DMACFG_DMATA_MCH1CV DMACFG_DMATA(22) /*!< DMA transfer address is TIMER_MCH1CV */ +#define TIMER_DMACFG_DMATA_MCH2CV DMACFG_DMATA(23) /*!< DMA transfer address is TIMER_MCH2CV */ +#define TIMER_DMACFG_DMATA_MCH3CV DMACFG_DMATA(24) /*!< DMA transfer address is TIMER_MCH3CV */ +#define TIMER_DMACFG_DMATA_CH0COMV_ADD DMACFG_DMATA(25) /*!< DMA transfer address is TIMER_CH0COMV_ADD */ +#define TIMER_DMACFG_DMATA_CH1COMV_ADD DMACFG_DMATA(26) /*!< DMA transfer address is TIMER_CH1COMV_ADD */ +#define TIMER_DMACFG_DMATA_CH2COMV_ADD DMACFG_DMATA(27) /*!< DMA transfer address is TIMER_CH2COMV_ADD */ +#define TIMER_DMACFG_DMATA_CH3COMV_ADD DMACFG_DMATA(28) /*!< DMA transfer address is TIMER_CH3COMV_ADD */ +#define TIMER_DMACFG_DMATA_CTL2 DMACFG_DMATA(29) /*!< DMA transfer address is TIMER_CTL2 */ +#define TIMER_DMACFG_DMATA_FCCHP0 DMACFG_DMATA(30) /*!< DMA transfer address is TIMER_FCCHP0 */ +#define TIMER_DMACFG_DMATA_FCCHP1 DMACFG_DMATA(31) /*!< DMA transfer address is TIMER_FCCHP1 */ +#define TIMER_DMACFG_DMATA_FCCHP2 DMACFG_DMATA(32) /*!< DMA transfer address is TIMER_FCCHP2 */ +#define TIMER_DMACFG_DMATA_FCCHP3 DMACFG_DMATA(33) /*!< DMA transfer address is TIMER_FCCHP3 */ +#define TIMER_DMACFG_DMATA_AFCTL0 DMACFG_DMATA(34) /*!< DMA transfer address is TIMER_AFCTL0 */ +#define TIMER_DMACFG_DMATA_AFCTL1 DMACFG_DMATA(35) /*!< DMA transfer address is TIMER_AFCTL1 */ +#define TIMER_DMACFG_DMATA_WDGPER DMACFG_DMATA(36) /*!< DMA transfer address is TIMER_WDGPER */ +#define TIMER_DMACFG_DMATA_CREP1 DMACFG_DMATA(37) /*!< DMA transfer address is TIMER_CREP1 */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8,13) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ +#define TIMER_DMACFG_DMATC_19TRANSFER DMACFG_DMATC(18) /*!< DMA transfer 19 times */ +#define TIMER_DMACFG_DMATC_20TRANSFER DMACFG_DMATC(19) /*!< DMA transfer 20 times */ +#define TIMER_DMACFG_DMATC_21TRANSFER DMACFG_DMATC(20) /*!< DMA transfer 21 times */ +#define TIMER_DMACFG_DMATC_22TRANSFER DMACFG_DMATC(21) /*!< DMA transfer 22 times */ +#define TIMER_DMACFG_DMATC_23TRANSFER DMACFG_DMATC(22) /*!< DMA transfer 23 times */ +#define TIMER_DMACFG_DMATC_24TRANSFER DMACFG_DMATC(23) /*!< DMA transfer 24 times */ +#define TIMER_DMACFG_DMATC_25TRANSFER DMACFG_DMATC(24) /*!< DMA transfer 25 times */ +#define TIMER_DMACFG_DMATC_26TRANSFER DMACFG_DMATC(25) /*!< DMA transfer 26 times */ +#define TIMER_DMACFG_DMATC_27TRANSFER DMACFG_DMATC(26) /*!< DMA transfer 27 times */ +#define TIMER_DMACFG_DMATC_28TRANSFER DMACFG_DMATC(27) /*!< DMA transfer 28 times */ +#define TIMER_DMACFG_DMATC_29TRANSFER DMACFG_DMATC(28) /*!< DMA transfer 29 times */ +#define TIMER_DMACFG_DMATC_30TRANSFER DMACFG_DMATC(29) /*!< DMA transfer 30 times */ +#define TIMER_DMACFG_DMATC_31TRANSFER DMACFG_DMATC(30) /*!< DMA transfer 31 times */ +#define TIMER_DMACFG_DMATC_32TRANSFER DMACFG_DMATC(31) /*!< DMA transfer 32 times */ +#define TIMER_DMACFG_DMATC_33TRANSFER DMACFG_DMATC(32) /*!< DMA transfer 33 times */ +#define TIMER_DMACFG_DMATC_34TRANSFER DMACFG_DMATC(33) /*!< DMA transfer 34 times */ +#define TIMER_DMACFG_DMATC_35TRANSFER DMACFG_DMATC(34) /*!< DMA transfer 35 times */ +#define TIMER_DMACFG_DMATC_36TRANSFER DMACFG_DMATC(35) /*!< DMA transfer 36 times */ +#define TIMER_DMACFG_DMATC_37TRANSFER DMACFG_DMATC(36) /*!< DMA transfer 37 times */ +#define TIMER_DMACFG_DMATC_38TRANSFER DMACFG_DMATC(37) /*!< DMA transfer 38 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG TIMER_SWEVG_UPG /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G TIMER_SWEVG_CH0G /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G TIMER_SWEVG_CH1G /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G TIMER_SWEVG_CH2G /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G TIMER_SWEVG_CH3G /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG TIMER_SWEVG_CMTG /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG TIMER_SWEVG_TRGG /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRK0G TIMER_SWEVG_BRK0G /*!< BREAK0 event generation */ +#define TIMER_EVENT_SRC_BRK1G TIMER_SWEVG_BRK1G /*!< BREAK1 event generation */ +#define TIMER_EVENT_SRC_MCH0G TIMER_SWEVG_MCH0G /*!< multi mode channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_MCH1G TIMER_SWEVG_MCH1G /*!< multi mode channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_MCH2G TIMER_SWEVG_MCH2G /*!< multi mode channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_MCH3G TIMER_SWEVG_MCH3G /*!< multi mode channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH0COMADDG TIMER_SWEVG_CH0COMADDG /*!< channel 0 additional compare event generation */ +#define TIMER_EVENT_SRC_CH1COMADDG TIMER_SWEVG_CH1COMADDG /*!< channel 1 additional compare event generation */ +#define TIMER_EVENT_SRC_CH2COMADDG TIMER_SWEVG_CH2COMADDG /*!< channel 2 additional compare event generation */ +#define TIMER_EVENT_SRC_CH3COMADDG TIMER_SWEVG_CH3COMADDG /*!< channel 3 additional compare event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5,6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW TIMER_SWEVG_UPG /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000000U) /*!< the prescaler is loaded at the next update event */ + +/* count direction */ +#define TIMER_COUNTER_UP ((uint16_t)0x0000U) /*!< counter up direction */ +#define TIMER_COUNTER_DOWN ((uint16_t)TIMER_CTL0_DIR) /*!< counter down direction */ + +/* specify division ratio between TIMER clock and dead-time and sampling clock */ +#define CTL0_CKDIV(regval) ((uint16_t)(BITS(8,9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CKDIV_DIV1 CTL0_CKDIV(0) /*!< clock division value is 1, fDTS = fTIMER_CK */ +#define TIMER_CKDIV_DIV2 CTL0_CKDIV(1) /*!< clock division value is 2, fDTS = fTIMER_CK/2 */ +#define TIMER_CKDIV_DIV4 CTL0_CKDIV(2) /*!< clock division value is 4, fDTS = fTIMER_CK/4 */ + +/* single pulse mode */ +#define TIMER_SP_MODE_SINGLE TIMER_CTL0_SPM /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000000U) /*!< repetitive pulse mode */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR TIMER_CTL0_UPS /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000000U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ + +/* run mode off-state configure */ +#define TIMER_ROS_STATE_ENABLE ((uint32_t)TIMER_CCHP_ROS) /*!< when POEN bit is set, the channel output signals(CHx_O/MCHx_O) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_ROS_STATE_DISABLE ((uint32_t)0x00000000U) /*!< when POEN bit is set, the channel output signals(CHx_O/MCHx_O) are disabled */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint32_t)TIMER_CCHP_IOS) /*!< when POEN bit is reset, the channel output signals(CHx_O/MCHx_O) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_IOS_STATE_DISABLE ((uint32_t)0x00000000U) /*!< when POEN bit is reset, the channel output signals(CHx_O/MCHx_O) are disabled */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint32_t)TIMER_CCHP_OAEN) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint32_t)0x00000000U) /*!< output automatic disable */ + +/* complementary register protect control */ +#define CCHP_PROT(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CCHP_PROT_OFF CCHP_PROT(0) /*!< protect disable */ +#define TIMER_CCHP_PROT_0 CCHP_PROT(1) /*!< PROT mode 0 */ +#define TIMER_CCHP_PROT_1 CCHP_PROT(2) /*!< PROT mode 1 */ +#define TIMER_CCHP_PROT_2 CCHP_PROT(3) /*!< PROT mode 2 */ + +/* BREAK0 input signal enable */ +#define TIMER_BREAK0_ENABLE ((uint32_t)TIMER_CCHP_BRK0EN) /*!< BREAK0 input signal enable */ +#define TIMER_BREAK0_DISABLE ((uint32_t)0x00000000U) /*!< BREAK0 input signal disable */ + +/* BREAK0 input signal polarity */ +#define TIMER_BREAK0_POLARITY_LOW ((uint32_t)0x00000000U) /*!< BREAK0 input signal polarity is low */ +#define TIMER_BREAK0_POLARITY_HIGH ((uint32_t)TIMER_CCHP_BRK0P) /*!< BREAK0 input signal polarity is high */ + +/* BREAK1 input signal enable */ +#define TIMER_BREAK1_ENABLE ((uint32_t)TIMER_CCHP_BRK1EN) /*!< BREAK1 input signal enable */ +#define TIMER_BREAK1_DISABLE ((uint32_t)0x00000000U) /*!< BREAK1 input signal disable */ + +/* BREAK1 input signal polarity */ +#define TIMER_BREAK1_POLARITY_LOW ((uint32_t)0x00000000U) /*!< BREAK1 input signal polarity is low */ +#define TIMER_BREAK1_POLARITY_HIGH ((uint32_t)TIMER_CCHP_BRK1P) /*!< BREAK1 input signal polarity is high */ + +/* BREAK0 input released */ +#define TIMER_BREAK0_RELEASE ((uint32_t)TIMER_CCHP_BRK0REL) /*!< BREAK0 input is released */ +#define TIMER_BREAK0_UNRELEASE ((uint32_t)0x00000000U) /*!< BREAK0 input is unreleased */ + +/* BREAK1 input released */ +#define TIMER_BREAK1_RELEASE ((uint32_t)TIMER_CCHP_BRK1REL) /*!< BREAK1 input is released */ +#define TIMER_BREAK1_UNRELEASE ((uint32_t)0x00000000U) /*!< BREAK1 input is unreleased */ + +/* BREAK0 input locked */ +#define TIMER_BREAK0_LK_ENABLE ((uint32_t)TIMER_CCHP_BRK0LK) /*!< BREAK0 input locked enable */ +#define TIMER_BREAK0_LK_DISABLE ((uint32_t)0x00000000U) /*!< BREAK0 input locked disable */ + +/* BREAK1 input locked */ +#define TIMER_BREAK1_LK_ENABLE ((uint32_t)TIMER_CCHP_BRK1LK) /*!< BREAK1 input locked enable */ +#define TIMER_BREAK1_LK_DISABLE ((uint32_t)0x00000000U) /*!< BREAK1 input locked disable */ + +/* free complementary channel protection configure */ +#define TIMER_FCCHP_STATE_ENABLE ((uint32_t)TIMER_FCCHP0_FCCHP0EN) /*!< free complementary channel protection enable */ +#define TIMER_FCCHP_STATE_DISABLE ((uint32_t)0x00000000U) /*!< free complementary channel protection disable */ + +/* TIMER BREAK0/BREAK1 */ +#define TIMER_BREAK0 ((uint16_t)0x0000U) /*!< TIMER BREAK0 */ +#define TIMER_BREAK1 ((uint16_t)0x0001U) /*!< TIMER BREAK1 */ + +/* TIMER break input enable */ +#define TIMER_BRKIN0 TIMER_AFCTL0_BRK0IN0EN /*!< BREAKx BRKIN0 alternate function input enable */ +#define TIMER_BRKIN1 TIMER_AFCTL0_BRK0IN1EN /*!< BREAKx BRKIN1 alternate function input enable */ +#define TIMER_BRKIN2 TIMER_AFCTL0_BRK0IN2EN /*!< BREAKx BRKIN2 alternate function input enable */ +#define TIMER_BRKCMP0 TIMER_AFCTL0_BRK0CMP0EN /*!< BREAKx CMP0 input enable */ +#define TIMER_BRKCMP1 TIMER_AFCTL0_BRK0CMP1EN /*!< BREAKx CMP1 input enable */ +#define TIMER_BRKHPDF TIMER_AFCTL0_BRK0HPDFEN /*!< BREAKx HPDF input enable */ + +/* TIMER external break input polarity */ +#define TIMER_BRKIN0P TIMER_AFCTL0_BRK0IN0P /*!< BREAKx BRKIN0 polarity */ +#define TIMER_BRKIN1P TIMER_AFCTL0_BRK0IN1P /*!< BREAKx BRKIN1 polarity */ +#define TIMER_BRKIN2P TIMER_AFCTL0_BRK0IN2P /*!< BREAKx BRKIN2 polarity */ +#define TIMER_BRKCMP0P TIMER_AFCTL0_BRK0CMP0P /*!< BREAKx CMP0 polarity */ +#define TIMER_BRKCMP1P TIMER_AFCTL0_BRK0CMP1P /*!< BREAKx CMP1 polarity */ + +/* TIMER break external input polarity*/ +#define TIMER_BRKIN_POLARITY_LOW ((uint16_t)0x0000U) /*!< TIMER break external input signal will not be inverted */ +#define TIMER_BRKIN_POLARITY_HIGH ((uint16_t)0x0001U) /*!< TIMER break external input signal will be inverted */ + +/* TIMER channel n(n=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel 0 */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1 */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2 */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3 */ +#define TIMER_MCH_0 ((uint16_t)0x0010U) /*!< TIMER multi mode channel 0 */ +#define TIMER_MCH_1 ((uint16_t)0x0011U) /*!< TIMER multi mode channel 1 */ +#define TIMER_MCH_2 ((uint16_t)0x0012U) /*!< TIMER multi mode channel 2 */ +#define TIMER_MCH_3 ((uint16_t)0x0013U) /*!< TIMER multi mode channel 3 */ + +/* channel enable state */ +#define TIMER_CCX_ENABLE ((uint16_t)0x0001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint16_t)0x0000U) /*!< channel disable */ + +/* channel complementary output enable state */ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* multi mode channel enable state */ +#define TIMER_MCCX_ENABLE ((uint16_t)0x0004U) /*!< multi mode channel enable */ +#define TIMER_MCCX_DISABLE ((uint16_t)0x0000U) /*!< multi mode channel disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* multi mode channel output polarity */ +#define TIMER_OMC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< multi mode channel output polarity is high */ +#define TIMER_OMC_POLARITY_LOW ((uint16_t)0x0001U) /*!< multi mode channel output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)0x0100U) /*!< idle state of channel output is high */ +#define TIMER_OC_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel output is low */ + +/* idle state of channel complementary output */ +#define TIMER_OCN_IDLE_STATE_HIGH ((uint16_t)0x0200U) /*!< idle state of channel complementary output is high */ +#define TIMER_OCN_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel complementary output is low */ + +/* idle state of multi mode channel output */ +#define TIMER_OMC_IDLE_STATE_HIGH ((uint16_t)0x0100U) /*!< idle state of multi mode channel output is high */ +#define TIMER_OMC_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of multi mode channel output is low */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint32_t)0x00000000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint32_t)0x00000010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint32_t)0x00000020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint32_t)0x00000030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint32_t)0x00000040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint32_t)0x00000050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint32_t)0x00000060U) /*!< PWM mode 0 */ +#define TIMER_OC_MODE_PWM1 ((uint32_t)0x00000070U) /*!< PWM mode 1 */ +#define TIMER_OC_MODE_DSPM0 ((uint32_t)0x00010000U) /*!< delayable SPM mode 0 */ +#define TIMER_OC_MODE_DSPM1 ((uint32_t)0x00010010U) /*!< delayable SPM mode 1 */ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output compare shadow enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output compare shadow disable */ + +/* channel output compare clear enable */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define CTL1_CCUC(regval) ((BIT(2) & ((uint32_t)(regval) << 2U)) | (BITS(30,31) & ((uint32_t)(regval) << 29U))) +#define TIMER_UPDATECTL_CCU CTL1_CCUC(0) /*!< the shadow registers update by when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI CTL1_CCUC(1) /*!< the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs */ +#define TIMER_UPDATECTL_CCUOVER CTL1_CCUC(4) /*!< the shadow registers update by when the overflow event occurs */ +#define TIMER_UPDATECTL_CCUUNDER CTL1_CCUC(5) /*!< the shadow registers update by when the underflow event occurs */ +#define TIMER_UPDATECTL_CCUOVERUNDER CTL1_CCUC(6) /*!< the shadow registers update by when the overflow or underflow event occurs */ + +/* channel input capture polarity */ +#define TIMER_IC_POLARITY_RISING ((uint16_t)0x0000U) /*!< input capture rising edge */ +#define TIMER_IC_POLARITY_FALLING ((uint16_t)0x0002U) /*!< input capture falling edge*/ +#define TIMER_IC_POLARITY_BOTH_EDGE ((uint16_t)0x000AU) /*!< input capture both edge */ + +/* TIMER input capture selection */ +#define TIMER_IC_SELECTION_DIRECTTI ((uint16_t)0x0001U) /*!< channel n is configured as input and icy is mapped on CIy / CINy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel n is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel n is configured as input and icy is mapped on ITS */ +#define TIMER_IC_SELECTION_PAIR ((uint16_t)0x0004U) /*!< channel n is configured as input and icy is mapped on the other channel of same pair */ + +/* channel input capture prescaler */ +#define TIMER_IC_PSC_DIV1 ((uint16_t)0x0000U) /*!< no prescaler */ +#define TIMER_IC_PSC_DIV2 ((uint16_t)0x0004U) /*!< divided by 2 */ +#define TIMER_IC_PSC_DIV4 ((uint16_t)0x0008U) /*!< divided by 4 */ +#define TIMER_IC_PSC_DIV8 ((uint16_t)0x000CU) /*!< divided by 8 */ + +/* master mode control 0 */ +#define CTL1_MMC0(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) +#define TIMER_TRI_OUT0_SRC_RESET CTL1_MMC0(0) /*!< the UPG bit as trigger output 0 */ +#define TIMER_TRI_OUT0_SRC_ENABLE CTL1_MMC0(1) /*!< the counter enable signal as trigger output 0 */ +#define TIMER_TRI_OUT0_SRC_UPDATE CTL1_MMC0(2) /*!< update event as trigger output 0 */ +#define TIMER_TRI_OUT0_SRC_CH0 CTL1_MMC0(3) /*!< a capture or a compare match occurred in channel 0 as trigger output 0 */ +#define TIMER_TRI_OUT0_SRC_O0CPRE CTL1_MMC0(4) /*!< O0CPRE as trigger output 0 */ +#define TIMER_TRI_OUT0_SRC_O1CPRE CTL1_MMC0(5) /*!< O1CPRE as trigger output 0 */ +#define TIMER_TRI_OUT0_SRC_O2CPRE CTL1_MMC0(6) /*!< O2CPRE as trigger output 0 */ +#define TIMER_TRI_OUT0_SRC_O3CPRE CTL1_MMC0(7) /*!< O3CPRE as trigger output 0 */ + +/* master mode control 1 */ +#define CTL1_MMC1(regval) (BITS(20,22) & ((uint32_t)(regval) << 20U)) +#define TIMER_TRI_OUT1_SRC_RESET CTL1_MMC1(0) /*!< the UPG bit as trigger output 1 */ +#define TIMER_TRI_OUT1_SRC_ENABLE CTL1_MMC1(1) /*!< the counter enable signal TIMER_CTL0_CEN as trigger output 1 */ +#define TIMER_TRI_OUT1_SRC_UPDATE CTL1_MMC1(2) /*!< update event as trigger output 1 */ +#define TIMER_TRI_OUT1_SRC_CH0 CTL1_MMC1(3) /*!< a capture or a compare match occurred in channel 0 as trigger output 1 */ +#define TIMER_TRI_OUT1_SRC_O0CPRE CTL1_MMC1(4) /*!< O0CPRE as trigger output 1 */ +#define TIMER_TRI_OUT1_SRC_O1CPRE CTL1_MMC1(5) /*!< O1CPRE as trigger output 1 */ +#define TIMER_TRI_OUT1_SRC_O2CPRE CTL1_MMC1(6) /*!< O2CPRE as trigger output 1 */ +#define TIMER_TRI_OUT1_SRC_O3CPRE CTL1_MMC1(7) /*!< O3CPRE as trigger output 1 */ + +/* TIMER decoder detection enable */ +#define TIMER_DECJUMPDEN TIMER_CTL2_DECJDEN /*!< quadrature decoder signal jump (the two signals jump at the same time) detection enable */ +#define TIMER_DECDISCONNECTDEN TIMER_CTL2_DECDISDEN /*!< quadrature decoder signal disconnection detection enable */ + +/* master slave mode selection */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE TIMER_SMCFG_MSM /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000000U) /*!< master slave mode disable */ + +/* external trigger prescaler */ +#define SMCFG_ETPSC(regval) (BITS(12,13) & ((uint32_t)(regval) << 12U)) +#define TIMER_EXT_TRI_PSC_OFF SMCFG_ETPSC(0) /*!< no divided */ +#define TIMER_EXT_TRI_PSC_DIV2 SMCFG_ETPSC(1) /*!< divided by 2 */ +#define TIMER_EXT_TRI_PSC_DIV4 SMCFG_ETPSC(2) /*!< divided by 4 */ +#define TIMER_EXT_TRI_PSC_DIV8 SMCFG_ETPSC(3) /*!< divided by 8 */ + +/* external trigger polarity */ +#define TIMER_ETP_FALLING TIMER_SMCFG_ETP /*!< active low or falling edge active */ +#define TIMER_ETP_RISING ((uint32_t)0x00000000U) /*!< active high or rising edge active */ + +/* channel 0 trigger input selection */ +#define TIMER_HALLINTERFACE_ENABLE TIMER_CTL1_TI0S /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode disable */ + +/* TIMER write CHxVAL register selection */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)TIMER_CFG_CHVSEL) /*!< write CHxVAL register selection enable */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ + +/* TIMER output value selection enable */ +#define TIMER_OUTSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< output value selection enable */ +#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection disable */ + +/* TIMER commutation control shadow register update selection enable */ +#define TIMER_CCUSEL_ENABLE ((uint16_t)TIMER_CFG_CCUSEL) /*!< commutation control shadow register update selection enable */ +#define TIMER_CCUSEL_DISABLE ((uint16_t)0x0000U) /*!< commutation control shadow register update selection disable */ + +/* channel additional output compare shadow enable */ +#define TIMER_ADD_SHADOW_ENABLE ((uint16_t)0x0001U) /*!< channel additional output shadow state enable */ +#define TIMER_ADD_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel additional output shadow state disable */ + +/* channel output compare shadow enable */ +#define TIMER_OMC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< multi mode channel output shadow state enable */ +#define TIMER_OMC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< multi mode channel output shadow state disable */ + +/* channel output compare clear enable */ +#define TIMER_OMC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< multi mode channel output clear function enable */ +#define TIMER_OMC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< multi mode channel output clear function disable */ + +/* TIMER counter repetition register selection */ +#define TIMER_CREP1_ENABLE ((uint16_t)TIMER_CFG_CREPSEL) /*!< the update event rate is depended to TIMERx_CREP1 register */ +#define TIMER_CREP0_ENABLE ((uint16_t)0x0000U) /*!< the update event rate is depended to TIMERx_CREP0 register */ + +/* TIMER output value selection */ +#define TIMER_PULSE_OUTPUT_NORMAL ((uint16_t)0x0000U) /*!< channel output normal */ +#define TIMER_PULSE_OUTPUT_CNT_UP ((uint16_t)0x0001U) /*!< pulse output only when counting up */ +#define TIMER_PULSE_OUTPUT_CNT_DOWN ((uint16_t)0x0002U) /*!< pulse output only when counting down */ +#define TIMER_PULSE_OUTPUT_CNT_BOTH ((uint16_t)0x0003U) /*!< pulse output when counting up or down */ +#define TIMER_PULSE_OUTPUT_MASK ((uint16_t)0x0003U) /*!< pulse output mode mask */ + +/* multi mode channel input capture polarity */ +#define TIMER_IMC_POLARITY_RISING ((uint16_t)0x0000U) /*!< multi mode channel input capture rising edge */ +#define TIMER_IMC_POLARITY_FALLING ((uint16_t)0x0001U) /*!< multi mode channel input capture falling edge */ +#define TIMER_IMC_POLARITY_BOTH_EDGE ((uint16_t)0x0003U) /*!< multi mode channel input capture both edge */ + +/* channel output polarity */ +#define TIMER_OC_MCH_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_MCH_POLARITY_LOW ((uint16_t)0x0001U) /*!< channel output polarity is low */ + +/* TIMER multi mode channel mode selection */ +#define TIMER_MCH_MODE_INDEPENDENTLY ((uint16_t)0x0000U) /*!< multi mode channel work in independently mode */ +#define TIMER_MCH_MODE_COMPLEMENTARY ((uint16_t)0x0003U) /*!< multi mode channel work in complementary output mode */ +#define TIMER_MCH_MODE_MASK ((uint16_t)0x0003U) /*!< multi mode channel mode mask */ + +/* function declarations */ +/* TIMER timebase */ +/* deinit a TIMER */ +void timer_deinit(uint32_t timer_periph); +/* initialize TIMER init parameter struct */ +void timer_struct_para_init(timer_parameter_struct *initpara); +/* initialize TIMER counter */ +void timer_init(uint32_t timer_periph, timer_parameter_struct *initpara); +/* enable a TIMER */ +void timer_enable(uint32_t timer_periph); +/* disable a TIMER */ +void timer_disable(uint32_t timer_periph); +/* enable the auto reload shadow function */ +void timer_auto_reload_shadow_enable(uint32_t timer_periph); +/* disable the auto reload shadow function */ +void timer_auto_reload_shadow_disable(uint32_t timer_periph); +/* enable the update event */ +void timer_update_event_enable(uint32_t timer_periph); +/* disable the update event */ +void timer_update_event_disable(uint32_t timer_periph); +/* set TIMER counter alignment mode */ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned); +/* set TIMER counter up direction */ +void timer_counter_up_direction(uint32_t timer_periph); +/* set TIMER counter down direction */ +void timer_counter_down_direction(uint32_t timer_periph); + +/* configure TIMER prescaler */ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint32_t pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t ccsel, uint32_t repetition); +/* configure TIMER runtime repetition register value */ +uint32_t timer_runtime_repetition_value_read(uint32_t timer_periph); +/* configure TIMER autoreload register value */ +void timer_autoreload_value_config(uint32_t timer_periph, uint64_t autoreload); +/* read TIMER autoreload register value */ +uint64_t timer_autoreload_value_read(uint32_t timer_periph); +/* configure TIMER counter register value */ +void timer_counter_value_config(uint32_t timer_periph, uint64_t counter); +/* read TIMER counter value */ +uint64_t timer_counter_read(uint32_t timer_periph); +/* read TIMER prescaler value */ +uint16_t timer_prescaler_read(uint32_t timer_periph); +/* configure TIMER single pulse mode */ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode); +/* configure timer delayable single pulse mode */ +void timer_delayable_single_pulse_mode_config(uint32_t timer_periph, uint16_t channel, uint32_t dspmode, uint16_t cnt_dir); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint32_t update); + +/* TIMER DMA and event */ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph, uint32_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint32_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_t dma_request); +/* configure the TIMER DMA transfer */ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth); +/* software generate events */ +void timer_event_software_generate(uint32_t timer_periph, uint32_t event); + +/* TIMER channel complementary protection */ +/* initialize TIMER break parameter struct */ +void timer_break_struct_para_init(timer_break_parameter_struct *breakpara); +/* configure TIMER break function */ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara); +/* enable TIMER break function */ +void timer_break_enable(uint32_t timer_periph, uint16_t break_num); +/* disable TIMER break function */ +void timer_break_disable(uint32_t timer_periph, uint16_t break_num); +/* enable TIMER output automatic function */ +void timer_automatic_output_enable(uint32_t timer_periph); +/* disable TIMER output automatic function */ +void timer_automatic_output_disable(uint32_t timer_periph); +/* configure TIMER primary output function */ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure channel commutation control shadow register */ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure TIMER channel control shadow register update control */ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint32_t ccuctl); + +/* TIMER channel output */ +/* initialize TIMER channel output parameter struct */ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara); +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct *ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint32_t ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse); +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear); +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state); +/* configure TIMER channel complementary output enable state */ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate); + +/* TIMER channel input */ +/* initialize TIMER channel input parameter struct */ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct *icpara); +/* configure TIMER input capture parameter */ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpara); +/* configure TIMER channel input capture prescaler value */ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler); +/* read TIMER channel capture compare register value */ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel); +/* configure TIMER input pwm capture function */ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpwm); +/* configure TIMER hall sensor mode */ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode); + +/* TIMER multi mode channel */ +/* initialize TIMER multi mode channel output parameter struct */ +void timer_multi_mode_channel_output_parameter_struct_init(timer_omc_parameter_struct *omcpara); +/* configure TIMER multi mode channel output function */ +void timer_multi_mode_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_omc_parameter_struct *omcpara); +/* multi mode channel mode select */ +void timer_multi_mode_channel_mode_config(uint32_t timer_periph, uint32_t channel, uint32_t multi_mode_sel); + +/* TIMER master and slave mode */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output 0 trigger source */ +void timer_master_output0_trigger_source_select(uint32_t timer_periph, uint32_t outrigger); +/* select TIMER master mode output 1 trigger source */ +void timer_master_output1_trigger_source_select(uint32_t timer_periph, uint32_t outrigger); +/* select TIMER slave mode */ +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode); +/* configure TIMER master slave mode */ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave); + +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER quadrature decoder mode */ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity); +/* configure TIMER non-quadrature decoder mode */ +void timer_non_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic1polarity); +/* configure TIMER internal clock mode */ +void timer_internal_clock_config(uint32_t timer_periph); +/* configure TIMER the internal trigger as external clock input */ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger); +/* configure TIMER the external trigger as external clock input */ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 0 */ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 1 */ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); + +/* TIMER configure */ +/* configure TIMER write CHxVAL register selection */ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel); +/* configure TIMER output value selection */ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel); +/* configure commutation control shadow register update selection */ +void timer_commutation_control_shadow_register_config(uint32_t timer_periph, uint16_t ccssel); +/* configure TIMER output match pulse selection */ +void timer_output_match_pulse_select(uint32_t timer_periph, uint32_t channel, uint16_t pulsesel); + +/* TIMER composite PWM mode */ +/* configure the TIMER composite PWM mode */ +void timer_channel_composite_pwm_mode_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue); +/* configure the TIMER composite PWM mode output pulse value */ +void timer_channel_composite_pwm_mode_output_pulse_value_config(uint32_t timer_periph, uint32_t channel, uint32_t pulse, uint32_t add_pulse); +/* configure TIMER channel additional compare value */ +void timer_channel_additional_compare_value_config(uint32_t timer_periph, uint16_t channel, uint32_t value); +/* configure TIMER channel additional output shadow function */ +void timer_channel_additional_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t aocshadow); +/* read TIMER channel additional compare value */ +uint32_t timer_channel_additional_compare_value_read(uint32_t timer_periph, uint16_t channel); + +/* TIMER break external inputs */ +/* configure TIMER break external source */ +void timer_break_external_source_config(uint32_t timer_periph, uint16_t break_num, uint32_t break_src, ControlStatus newvalue); +/* configure TIMER break polarity */ +void timer_break_external_polarity_config(uint32_t timer_periph, uint16_t break_num, uint32_t break_src, uint16_t bkinpolarity); +/* configure TIMER break lock function */ +void timer_break_lock_config(uint32_t timer_periph, uint16_t break_num, ControlStatus newvalue); +/* configure the TIMER break lock release function */ +void timer_break_lock_release_config(uint32_t timer_periph, uint16_t break_num, ControlStatus newvalue); + +/* TIMER channel free complementary protection */ +/* configure the TIMER channel break function */ +void timer_channel_break_control_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue); +/* configure the TIMER channel dead time function */ +void timer_channel_dead_time_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue); +/* initialize TIMER channel free complementary parameter struct with a default value */ +void timer_free_complementary_struct_para_init(timer_free_complementary_parameter_struct *freecompara); +/* configure channel free complementary protection */ +void timer_channel_free_complementary_config(uint32_t timer_periph, uint16_t channel, timer_free_complementary_parameter_struct *fcpara); + +/* TIMER quadrature decoder signal detection function */ +/* configure quadrature decoder signal disconnection detection watchdog value */ +void timer_watchdog_value_config(uint32_t timer_periph, uint32_t value); +/* read quadrature decoder signal disconnection detection watchdog value */ +uint32_t timer_watchdog_value_read(uint32_t timer_periph); +/* configure quadrature decoder signal disconnection detection function */ +void timer_decoder_disconnection_detection_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure decoder signal jump detection function */ +void timer_decoder_jump_detection_config(uint32_t timer_periph, ControlStatus newvalue); + +/* TIMER UPIF bit backup function */ +/* configure the UPIF bit backup function */ +void timer_upif_backup_config(uint32_t timer_periph, ControlStatus newvalue); +/* get the UPIFBU bit in the TIMERx_CNT register */ +UPIFBUStatus timer_upifbu_bit_get(uint32_t timer_periph); + +/* TIMER interrupt and flag */ +/* get TIMER flags */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flags */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER interrupt flags */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t int_flag); +/* clear TIMER interrupt flags */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t int_flag); + +#endif /* GD32H7XX_TIMER_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tli.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tli.h new file mode 100644 index 0000000000..69a0a162f5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tli.h @@ -0,0 +1,374 @@ +/*! + \file gd32h7xx_tli.h + \brief definitions for the TLI + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_TLI_H +#define GD32H7XX_TLI_H + +#include "gd32h7xx.h" + +/* TLI definitions */ +#define TLI TLI_BASE /*!< TLI base address */ +/* TLI layer definitions */ +#define LAYER0 (TLI_BASE + 0x00000084U) /*!< TLI layer0 base address */ +#define LAYER1 (TLI_BASE + 0x00000104U) /*!< TLI layer1 base address */ + +/* registers definitions */ +#define TLI_SPSZ REG32(TLI + 0x00000008U) /*!< TLI synchronous pulse size register */ +#define TLI_BPSZ REG32(TLI + 0x0000000CU) /*!< TLI back-porch size register */ +#define TLI_ASZ REG32(TLI + 0x00000010U) /*!< TLI active size register */ +#define TLI_TSZ REG32(TLI + 0x00000014U) /*!< TLI total size register */ +#define TLI_CTL REG32(TLI + 0x00000018U) /*!< TLI control register */ +#define TLI_RL REG32(TLI + 0x00000024U) /*!< TLI reload Layer register */ +#define TLI_BGC REG32(TLI + 0x0000002CU) /*!< TLI background color register */ +#define TLI_INTEN REG32(TLI + 0x00000034U) /*!< TLI interrupt enable register */ +#define TLI_INTF REG32(TLI + 0x00000038U) /*!< TLI interrupt flag register */ +#define TLI_INTC REG32(TLI + 0x0000003CU) /*!< TLI interrupt flag clear register */ +#define TLI_LM REG32(TLI + 0x00000040U) /*!< TLI line mark register */ +#define TLI_CPPOS REG32(TLI + 0x00000044U) /*!< TLI current pixel position register */ +#define TLI_STAT REG32(TLI + 0x00000048U) /*!< TLI status register */ +#define TLI_LXCTL(layerx) REG32((layerx) + 0x00000000U) /*!< TLI layer x control register */ +#define TLI_LXHPOS(layerx) REG32((layerx) + 0x00000004U) /*!< TLI layer x horizontal position parameters register */ +#define TLI_LXVPOS(layerx) REG32((layerx) + 0x00000008U) /*!< TLI layer x vertical position parameters register */ +#define TLI_LXCKEY(layerx) REG32((layerx) + 0x0000000CU) /*!< TLI layer x color key register */ +#define TLI_LXPPF(layerx) REG32((layerx) + 0x00000010U) /*!< TLI layer x packeted pixel format register */ +#define TLI_LXSA(layerx) REG32((layerx) + 0x00000014U) /*!< TLI layer x specified alpha register */ +#define TLI_LXDC(layerx) REG32((layerx) + 0x00000018U) /*!< TLI layer x default color register */ +#define TLI_LXBLEND(layerx) REG32((layerx) + 0x0000001CU) /*!< TLI layer x blending register */ +#define TLI_LXFBADDR(layerx) REG32((layerx) + 0x00000028U) /*!< TLI layer x frame base address register */ +#define TLI_LXFLLEN(layerx) REG32((layerx) + 0x0000002CU) /*!< TLI layer x frame line length register */ +#define TLI_LXFTLN(layerx) REG32((layerx) + 0x00000030U) /*!< TLI layer x frame total line number register */ +#define TLI_LXLUT(layerx) REG32((layerx) + 0x00000040U) /*!< TLI layer x look up table register */ + +/* bits definitions */ +/* TLI_SPSZ */ +#define TLI_SPSZ_VPSZ BITS(0,11) /*!< size of the vertical synchronous pulse */ +#define TLI_SPSZ_HPSZ BITS(16,27) /*!< size of the horizontal synchronous pulse */ + +/* TLI_BPSZ */ +#define TLI_BPSZ_VBPSZ BITS(0,11) /*!< size of the vertical back porch plus synchronous pulse */ +#define TLI_BPSZ_HBPSZ BITS(16,27) /*!< size of the horizontal back porch plus synchronous pulse */ + +/* TLI_ASZ */ +#define TLI_ASZ_VASZ BITS(0,11) /*!< size of the vertical active area width plus back porch and synchronous pulse */ +#define TLI_ASZ_HASZ BITS(16,27) /*!< size of the horizontal active area width plus back porch and synchronous pulse */ + +/* TLI_SPSZ */ +#define TLI_TSZ_VTSZ BITS(0,11) /*!< vertical total size of the display, including active area, back porch, synchronous pulse and front porch */ +#define TLI_TSZ_HTSZ BITS(16,27) /*!< horizontal total size of the display, including active area, back porch, synchronous pulse and front porch */ + +/* TLI_CTL */ +#define TLI_CTL_TLIEN BIT(0) /*!< TLI enable bit */ +#define TLI_CTL_BDB BITS(4,6) /*!< blue channel dither bits number */ +#define TLI_CTL_GDB BITS(8,10) /*!< green channel dither bits number */ +#define TLI_CTL_RDB BITS(12,14) /*!< red channel dither bits number */ +#define TLI_CTL_DFEN BIT(16) /*!< dither function enable */ +#define TLI_CTL_CLKPS BIT(28) /*!< pixel clock polarity selection */ +#define TLI_CTL_DEPS BIT(29) /*!< data enable polarity selection */ +#define TLI_CTL_VPPS BIT(30) /*!< vertical pulse polarity selection */ +#define TLI_CTL_HPPS BIT(31) /*!< horizontal pulse polarity selection */ + +/* TLI_RL */ +#define TLI_RL_RQR BIT(0) /*!< request reload */ +#define TLI_RL_FBR BIT(1) /*!< frame blank reload */ + +/* TLI_BGC */ +#define TLI_BGC_BVB BITS(0,7) /*!< background value blue */ +#define TLI_BGC_BVG BITS(8,15) /*!< background value green */ +#define TLI_BGC_BVR BITS(16,23) /*!< background value red */ + +/* TLI_INTEN */ +#define TLI_INTEN_LMIE BIT(0) /*!< line mark interrupt enable */ +#define TLI_INTEN_FEIE BIT(1) /*!< FIFO error interrupt enable */ +#define TLI_INTEN_TEIE BIT(2) /*!< transaction error interrupt enable */ +#define TLI_INTEN_LCRIE BIT(3) /*!< layer configuration reloaded interrupt enable */ + +/* TLI_INTF */ +#define TLI_INTF_LMF BIT(0) /*!< line mark flag */ +#define TLI_INTF_FEF BIT(1) /*!< FIFO error flag */ +#define TLI_INTF_TEF BIT(2) /*!< transaction error flag */ +#define TLI_INTF_LCRF BIT(3) /*!< layer configuration reloaded flag */ + +/* TLI_INTC */ +#define TLI_INTC_LMC BIT(0) /*!< line mark flag clear */ +#define TLI_INTC_FEC BIT(1) /*!< FIFO error flag clear */ +#define TLI_INTC_TEC BIT(2) /*!< transaction error flag clear */ +#define TLI_INTC_LCRC BIT(3) /*!< layer configuration reloaded flag clear */ + +/* TLI_LM */ +#define TLI_LM_LM BITS(0,10) /*!< line mark value */ + +/* TLI_CPPOS */ +#define TLI_CPPOS_VPOS BITS(0,15) /*!< vertical position */ +#define TLI_CPPOS_HPOS BITS(16,31) /*!< horizontal position */ + +/* TLI_STAT */ +#define TLI_STAT_VDE BIT(0) /*!< current VDE status */ +#define TLI_STAT_HDE BIT(1) /*!< current HDE status */ +#define TLI_STAT_VS BIT(2) /*!< current VS status of the TLI */ +#define TLI_STAT_HS BIT(3) /*!< current HS status of the TLI */ + +/* TLI_LXCTL */ +#define TLI_LXCTL_LEN BIT(0) /*!< layer enable */ +#define TLI_LXCTL_CKEYEN BIT(1) /*!< color keying enable */ +#define TLI_LXCTL_LUTEN BIT(4) /*!< LUT enable */ + +/* TLI_LXHPOS */ +#define TLI_LXHPOS_WLP BITS(0,11) /*!< window left position */ +#define TLI_LXHPOS_WRP BITS(16,27) /*!< window right position */ + +/* TLI_LXVPOS */ +#define TLI_LXVPOS_WTP BITS(0,11) /*!< window top position */ +#define TLI_LXVPOS_WBP BITS(16,27) /*!< window bottom position */ + +/* TLI_LXCKEY */ +#define TLI_LXCKEY_CKEYB BITS(0,7) /*!< color key blue */ +#define TLI_LXCKEY_CKEYG BITS(8,15) /*!< color key green */ +#define TLI_LXCKEY_CKEYR BITS(16,23) /*!< color key red */ + +/* TLI_LXPPF */ +#define TLI_LXPPF_PPF BITS(0,2) /*!< packeted pixel format */ + +/* TLI_LXSA */ +#define TLI_LXSA_SA BITS(0,7) /*!< specified alpha */ + +/* TLI_LXDC */ +#define TLI_LXDC_DCB BITS(0,7) /*!< the default color blue */ +#define TLI_LXDC_DCG BITS(8,15) /*!< the default color green */ +#define TLI_LXDC_DCR BITS(16,23) /*!< the default color red */ +#define TLI_LXDC_DCA BITS(24,31) /*!< the default color alpha */ + +/* TLI_LXBLEND */ +#define TLI_LXBLEND_ACF2 BITS(0,2) /*!< alpha calculation factor 2 of blending method */ +#define TLI_LXBLEND_ACF1 BITS(8,10) /*!< alpha calculation factor 1 of blending method */ + +/* TLI_LXFBADDR */ +#define TLI_LXFBADDR_FBADD BITS(0,31) /*!< frame buffer base address */ + +/* TLI_LXFLLEN */ +#define TLI_LXFLLEN_FLL BITS(0,13) /*!< frame line length */ +#define TLI_LXFLLEN_STDOFF BITS(16,29) /*!< frame buffer stride offset */ + +/* TLI_LXFTLN */ +#define TLI_LXFTLN_FTLN BITS(0,10) /*!< frame total line number */ + +/* TLI_LXLUT */ +#define TLI_LXLUT_TB BITS(0,7) /*!< blue channel of a LUT entry */ +#define TLI_LXLUT_TG BITS(8,15) /*!< green channel of a LUT entry */ +#define TLI_LXLUT_TR BITS(16,23) /*!< red channel of a LUT entry */ +#define TLI_LXLUT_TADD BITS(24,31) /*!< look up table write address */ + +/* constants definitions */ +/* TLI parameter struct definitions */ +typedef struct +{ + uint16_t synpsz_vpsz; /*!< size of the vertical synchronous pulse */ + uint16_t synpsz_hpsz; /*!< size of the horizontal synchronous pulse */ + uint16_t backpsz_vbpsz; /*!< size of the vertical back porch plus synchronous pulse */ + uint16_t backpsz_hbpsz; /*!< size of the horizontal back porch plus synchronous pulse */ + uint32_t activesz_vasz; /*!< size of the vertical active area width plus back porch and synchronous pulse */ + uint32_t activesz_hasz; /*!< size of the horizontal active area width plus back porch and synchronous pulse */ + uint32_t totalsz_vtsz; /*!< vertical total size of the display */ + uint32_t totalsz_htsz; /*!< horizontal total size of the display */ + uint32_t backcolor_red; /*!< background value red */ + uint32_t backcolor_green; /*!< background value green */ + uint32_t backcolor_blue; /*!< background value blue */ + uint32_t signalpolarity_hs; /*!< horizontal pulse polarity selection */ + uint32_t signalpolarity_vs; /*!< vertical pulse polarity selection */ + uint32_t signalpolarity_de; /*!< data enable polarity selection */ + uint32_t signalpolarity_pixelck; /*!< pixel clock polarity selection */ +}tli_parameter_struct; + +/* TLI layer parameter struct definitions */ +typedef struct +{ + uint16_t layer_window_rightpos; /*!< window right position */ + uint16_t layer_window_leftpos; /*!< window left position */ + uint16_t layer_window_bottompos; /*!< window bottom position */ + uint16_t layer_window_toppos; /*!< window top position */ + uint32_t layer_ppf; /*!< packeted pixel format */ + uint8_t layer_sa; /*!< specified alpha */ + uint8_t layer_default_alpha; /*!< the default color alpha */ + uint8_t layer_default_red; /*!< the default color red */ + uint8_t layer_default_green; /*!< the default color green */ + uint8_t layer_default_blue; /*!< the default color blue */ + uint32_t layer_acf1; /*!< alpha calculation factor 1 of blending method */ + uint32_t layer_acf2; /*!< alpha calculation factor 2 of blending method */ + uint32_t layer_frame_bufaddr; /*!< frame buffer base address */ + uint16_t layer_frame_buf_stride_offset; /*!< frame buffer stride offset */ + uint16_t layer_frame_line_length; /*!< frame line length */ + uint16_t layer_frame_total_line_number; /*!< frame total line number */ +}tli_layer_parameter_struct; + +/* TLI layer LUT parameter struct definitions */ +typedef struct +{ + uint32_t layer_table_addr; /*!< look up table write address */ + uint8_t layer_lut_channel_red; /*!< red channel of a LUT entry */ + uint8_t layer_lut_channel_green; /*!< green channel of a LUT entry */ + uint8_t layer_lut_channel_blue; /*!< blue channel of a LUT entry */ +}tli_layer_lut_parameter_struct; + +/* packeted pixel format */ +typedef enum +{ + LAYER_PPF_ARGB8888, /*!< layerx pixel format ARGB8888 */ + LAYER_PPF_RGB888, /*!< layerx pixel format RGB888 */ + LAYER_PPF_RGB565, /*!< layerx pixel format RGB565 */ + LAYER_PPF_ARGB1555, /*!< layerx pixel format ARGB1555 */ + LAYER_PPF_ARGB4444, /*!< layerx pixel format ARGB4444 */ + LAYER_PPF_L8, /*!< layerx pixel format L8 */ + LAYER_PPF_AL44, /*!< layerx pixel format AL44 */ + LAYER_PPF_AL88 /*!< layerx pixel format AL88 */ +}tli_layer_ppf_enum; + +/* TLI flags */ +#define TLI_FLAG_VDE TLI_STAT_VDE /*!< current VDE status */ +#define TLI_FLAG_HDE TLI_STAT_HDE /*!< current HDE status */ +#define TLI_FLAG_VS TLI_STAT_VS /*!< current VS status of the TLI */ +#define TLI_FLAG_HS TLI_STAT_HS /*!< current HS status of the TLI */ +#define TLI_FLAG_LM BIT(0) | BIT(31) /*!< line mark interrupt flag */ +#define TLI_FLAG_FE BIT(1) | BIT(31) /*!< FIFO error interrupt flag */ +#define TLI_FLAG_TE BIT(2) | BIT(31) /*!< transaction error interrupt flag */ +#define TLI_FLAG_LCR BIT(3) | BIT(31) /*!< layer configuration reloaded interrupt flag */ + +/* TLI interrupt enable or disable */ +#define TLI_INT_LM BIT(0) /*!< line mark interrupt */ +#define TLI_INT_FE BIT(1) /*!< FIFO error interrupt */ +#define TLI_INT_TE BIT(2) /*!< transaction error interrupt */ +#define TLI_INT_LCR BIT(3) /*!< layer configuration reloaded interrupt */ + +/* TLI interrupt flag */ +#define TLI_INT_FLAG_LM BIT(0) /*!< line mark interrupt flag */ +#define TLI_INT_FLAG_FE BIT(1) /*!< FIFO error interrupt flag */ +#define TLI_INT_FLAG_TE BIT(2) /*!< transaction error interrupt flag */ +#define TLI_INT_FLAG_LCR BIT(3) /*!< layer configuration reloaded interrupt flag */ + +/* layer reload configure */ +#define TLI_FRAME_BLANK_RELOAD_EN ((uint8_t)0x00U) /*!< the layer configuration will be reloaded at frame blank */ +#define TLI_REQUEST_RELOAD_EN ((uint8_t)0x01U) /*!< the layer configuration will be reloaded after this bit sets */ + +/* dither function */ +#define TLI_DITHER_DISABLE ((uint8_t)0x00U) /*!< dither function disable */ +#define TLI_DITHER_ENABLE ((uint8_t)0x01U) /*!< dither function enable */ + +/* horizontal pulse polarity selection */ +#define TLI_HSYN_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< horizontal synchronous pulse active low */ +#define TLI_HSYN_ACTLIVE_HIGH TLI_CTL_HPPS /*!< horizontal synchronous pulse active high */ + +/* vertical pulse polarity selection */ +#define TLI_VSYN_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< vertical synchronous pulse active low */ +#define TLI_VSYN_ACTLIVE_HIGH TLI_CTL_VPPS /*!< vertical synchronous pulse active high */ + +/* pixel clock polarity selection */ +#define TLI_PIXEL_CLOCK_TLI ((uint32_t)0x00000000U) /*!< pixel clock is TLI clock */ +#define TLI_PIXEL_CLOCK_INVERTEDTLI TLI_CTL_CLKPS /*!< pixel clock is inverted TLI clock */ + +/* data enable polarity selection */ +#define TLI_DE_ACTLIVE_LOW ((uint32_t)0x00000000U) /*!< data enable active low */ +#define TLI_DE_ACTLIVE_HIGHT TLI_CTL_DEPS /*!< data enable active high */ + +/* alpha calculation factor 1 of blending method */ +#define LXBLEND_ACF1(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) +#define LAYER_ACF1_SA LXBLEND_ACF1(4) /*!< normalization specified alpha */ +#define LAYER_ACF1_PASA LXBLEND_ACF1(6) /*!< normalization pixel alpha * normalization specified alpha */ + +/* alpha calculation factor 2 of blending method */ +#define LXBLEND_ACF2(regval) (BITS(0,2) & ((uint32_t)(regval))) +#define LAYER_ACF2_SA LXBLEND_ACF2(5) /*!< normalization specified alpha */ +#define LAYER_ACF2_PASA LXBLEND_ACF2(7) /*!< normalization pixel alpha * normalization specified alpha */ + +/* function declarations */ +/* initialization functions, TLI enable or disable, TLI reload mode configuration */ +/* deinitialize TLI registers */ +void tli_deinit(void); +/* initialize the parameters of TLI parameter structure with the default values, it is suggested + that call this function after a tli_parameter_struct structure is defined */ +void tli_struct_para_init(tli_parameter_struct *tli_struct); +/* initialize TLI */ +void tli_init(tli_parameter_struct *tli_struct); +/* configure TLI dither function */ +void tli_dither_config(uint8_t dither_stat); +/* enable TLI */ +void tli_enable(void); +/* disable TLI */ +void tli_disable(void); +/* configure TLI reload mode */ +void tli_reload_config(uint8_t reload_mod); + +/* TLI layer configuration functions */ +/* initialize the parameters of TLI layer structure with the default values, it is suggested + that call this function after a tli_layer_parameter_struct structure is defined */ +void tli_layer_struct_para_init(tli_layer_parameter_struct *layer_struct); +/* initialize TLI layer */ +void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct); +/* reconfigure window position */ +void tli_layer_window_offset_modify(uint32_t layerx,uint16_t offset_x,uint16_t offset_y); +/* initialize the parameters of TLI layer LUT structure with the default values, it is suggested + that call this function after a tli_layer_lut_parameter_struct structure is defined */ +void tli_lut_struct_para_init(tli_layer_lut_parameter_struct *lut_struct); +/* initialize TLI layer LUT */ +void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct); +/* initialize TLI layer color key */ +void tli_color_key_init(uint32_t layerx,uint8_t redkey,uint8_t greenkey,uint8_t bluekey); +/* enable TLI layer */ +void tli_layer_enable(uint32_t layerx); +/* disable TLI layer */ +void tli_layer_disable(uint32_t layerx); +/* enable TLI layer color keying */ +void tli_color_key_enable(uint32_t layerx); +/* disable TLI layer color keying */ +void tli_color_key_disable(uint32_t layerx); +/* enable TLI layer LUT */ +void tli_lut_enable(uint32_t layerx); +/* disable TLI layer LUT */ +void tli_lut_disable(uint32_t layerx); + +/* set line mark value */ +void tli_line_mark_set(uint16_t line_num); +/* get current displayed position */ +uint32_t tli_current_pos_get(void); + +/* flag and interrupt functions */ +/* enable TLI interrupt */ +void tli_interrupt_enable(uint32_t int_flag); +/* disable TLI interrupt */ +void tli_interrupt_disable(uint32_t int_flag); +/* get TLI interrupt flag */ +FlagStatus tli_interrupt_flag_get(uint32_t int_flag); +/* clear TLI interrupt flag */ +void tli_interrupt_flag_clear(uint32_t int_flag); +/* get TLI flag or state in TLI_INTF register or TLI_STAT register */ +FlagStatus tli_flag_get(uint32_t flag); + +#endif /* GD32H7XX_TLI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tmu.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tmu.h new file mode 100644 index 0000000000..899d7015d1 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_tmu.h @@ -0,0 +1,177 @@ +/*! + \file gd32h7xx_tmu.h + \brief definitions for the TMU + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_TMU_H +#define GD32H7XX_TMU_H + +#include "gd32h7xx.h" + +/* TMU definitions */ +#define TMU TMU_BASE + +/* registers definitions */ +#define TMU_CS REG32(TMU + 0x00000000U) /*!< TMU control and status register */ +#define TMU_IDATA REG32(TMU + 0x00000004U) /*!< TMU input data register */ +#define TMU_ODATA REG32(TMU + 0x00000008U) /*!< TMU output data register */ + +/* bits definitions */ +/* TMU_CS */ +#define TMU_CS_MODE BITS(0,3) /*!< TMU operation mode selection */ +#define TMU_CS_ITRTNUM BITS(4,7) /*!< number of iterations selection */ +#define TMU_CS_FACTOR BITS(8,10) /*!< scaling factor */ +#define TMU_CS_RIE BIT(16) /*!< read TMU_ODATA interrupt enable */ +#define TMU_CS_RDEN BIT(17) /*!< read TMU_ODATA DMA request enable */ +#define TMU_CS_WDEN BIT(18) /*!< write TMU_IDATA DMA request enable */ +#define TMU_CS_ONUM BIT(19) /*!< times the TMU_ODATA needs to be read */ +#define TMU_CS_INUM BIT(20) /*!< times the TMU_IDATA needs to be write */ +#define TMU_CS_OWIDTH BIT(21) /*!< width of output data */ +#define TMU_CS_IWIDTH BIT(22) /*!< width of input data */ +#define TMU_CS_ENDF BIT(31) /*!< end of TMU operation flag */ + +/* TMU_IDATA */ +#define TMU_IDATA_IDATA BITS(0,31) /*!< the input data of TMU operation */ + +/* TMU_ODATA */ +#define TMU_ODATA_ODATA BITS(0,31) /*!< the output data of TMU operation */ + +/* constants definitions */ +/* TMU init parameter struct definitions */ +typedef struct +{ + uint32_t mode; /*!< mode of TMU operation */ + uint32_t iterations_number; /*!< number of iterations selection */ + uint32_t scale; /*!< scaling factor */ + uint32_t dma_read; /*!< DMA request to read TMU_ODATA */ + uint32_t dma_write; /*!< DMA request to write TMU_IDATA */ + uint32_t read_times; /*!< times the TMU_ODATA needs to be read */ + uint32_t write_times; /*!< times the TMU_IDATA needs to be write */ + uint32_t output_width; /*!< width of output data */ + uint32_t input_width; /*!< width of input data */ +}tmu_parameter_struct; + +/* TMU mode definitions */ +#define TMU_MODE(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define TMU_MODE_COS TMU_MODE(0) /*!< mode0: m*cos(��) */ +#define TMU_MODE_SIN TMU_MODE(1) /*!< mode1: m*sin(��) */ +#define TMU_MODE_ATAN2 TMU_MODE(2) /*!< mode2: atan2(y,x) */ +#define TMU_MODE_MODULUS TMU_MODE(3) /*!< mode3: sqrt(x^2+y^2) */ +#define TMU_MODE_ATAN TMU_MODE(4) /*!< mode4: atan(x) */ +#define TMU_MODE_COSH TMU_MODE(5) /*!< mode5: cosh(x) */ +#define TMU_MODE_SINH TMU_MODE(6) /*!< mode6: sinh(x) */ +#define TMU_MODE_ATANH TMU_MODE(7) /*!< mode7: atanh(x) */ +#define TMU_MODE_LN TMU_MODE(8) /*!< mode8: ln(x) */ +#define TMU_MODE_SQRT TMU_MODE(9) /*!< mode9: sqrt(x) */ + +/* TMU number of iterations definitions */ +#define ITERATIONS(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define TMU_ITERATION_STEPS_4 ITERATIONS(1) /*!< 4 iteration steps */ +#define TMU_ITERATION_STEPS_8 ITERATIONS(2) /*!< 8 iteration steps */ +#define TMU_ITERATION_STEPS_12 ITERATIONS(3) /*!< 12 iteration steps */ +#define TMU_ITERATION_STEPS_16 ITERATIONS(4) /*!< 16 iteration steps */ +#define TMU_ITERATION_STEPS_20 ITERATIONS(5) /*!< 20 iteration steps */ +#define TMU_ITERATION_STEPS_24 ITERATIONS(6) /*!< 24 iteration steps */ + +/* TMU scaling factor definitions */ +#define SCALE(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) +#define TMU_SCALING_FACTOR_1 SCALE(0) /*!< scaling factor = 1 */ +#define TMU_SCALING_FACTOR_2 SCALE(1) /*!< scaling factor = 2 */ +#define TMU_SCALING_FACTOR_4 SCALE(2) /*!< scaling factor = 4 */ +#define TMU_SCALING_FACTOR_8 SCALE(3) /*!< scaling factor = 8 */ +#define TMU_SCALING_FACTOR_16 SCALE(4) /*!< scaling factor = 16 */ +#define TMU_SCALING_FACTOR_32 SCALE(5) /*!< scaling factor = 32 */ +#define TMU_SCALING_FACTOR_64 SCALE(6) /*!< scaling factor = 64 */ +#define TMU_SCALING_FACTOR_128 SCALE(7) /*!< scaling factor = 128 */ + +/* TMU DMA read enable definitions */ +#define TMU_READ_DMA_DISABLE ((uint32_t)0x00000000U) /*!< disable DMA request to read TMU_ODATA */ +#define TMU_READ_DMA_ENABLE TMU_CS_RDEN /*!< enable DMA request to read TMU_ODATA */ + +/* TMU DMA write enable definitions */ +#define TMU_WRITE_DMA_DISABLE ((uint32_t)0x00000000U) /*!< disable DMA request to write TMU_IDATA */ +#define TMU_WRITE_DMA_ENABLE TMU_CS_WDEN /*!< enable DMA request to write TMU_IDATA */ + +/* TMU_ODATA read times definitions */ +#define TMU_READ_TIMES_1 ((uint32_t)0x00000000U) /*!< one 32-bit read operation */ +#define TMU_READ_TIMES_2 TMU_CS_ONUM /*!< two 32-bit read operation */ + +/* TMU_IDATA write times definitions */ +#define TMU_WRITE_TIMES_1 ((uint32_t)0x00000000U) /*!< one 32-bit write operation */ +#define TMU_WRITE_TIMES_2 TMU_CS_INUM /*!< two 32-bit write operation */ + +/* TMU output data width definitions */ +#define TMU_OUTPUT_WIDTH_32 ((uint32_t)0x00000000U) /*!< TMU_ODATA contains the output data in q1.31 format */ +#define TMU_OUTPUT_WIDTH_16 TMU_CS_OWIDTH /*!< TMU_ODATA contains the output data in q1.15 format */ + +/* TMU input data width definitions */ +#define TMU_INPUT_WIDTH_32 ((uint32_t)0x00000000U) /*!< TMU_IDATA contains the input data in q1.31 format */ +#define TMU_INPUT_WIDTH_16 TMU_CS_IWIDTH /*!< TMU_IDATA contains the input data in q1.15 format */ + +/* function declarations */ +/* initialization functions */ +/* reset the TMU registers */ +void tmu_deinit(void); +/* initialize the parameters of TMU struct with the default values */ +void tmu_struct_para_init(tmu_parameter_struct* init_struct); +/* initialize TMU */ +void tmu_init(tmu_parameter_struct* init_struct); + +/* interrupt and dma configuration */ +/* enable TMU read interrupt */ +void tmu_read_interrupt_enable(void); +/* disable TMU read interrupt */ +void tmu_read_interrupt_disable(void); +/* enable TMU DMA read request */ +void tmu_dma_read_enable(void); +/* disable TMU DMA read request */ +void tmu_dma_read_disable(void); +/* enable TMU DMA write request */ +void tmu_dma_write_enable(void); +/* disable TMU DMA write request */ +void tmu_dma_write_disable(void); + +/* TMU data write and read */ +/* write one data in q1.31 format */ +void tmu_one_q31_write(uint32_t data); +/* write two data in q1.31 format */ +void tmu_two_q31_write(uint32_t data1, uint32_t data2); +/* write two data in q1.15 format */ +void tmu_two_q15_write(uint16_t data1, uint16_t data2); +/* read one data in q1.31 format */ +void tmu_one_q31_read(uint32_t* p); +/* read two data in q1.31 format */ +void tmu_two_q31_read(uint32_t* p1, uint32_t* p2); +/* read two data in q1.15 format */ +void tmu_two_q15_read(uint16_t* p1, uint16_t* p2); + +#endif /* GD32H7XX_TMU_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trigsel.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trigsel.h new file mode 100644 index 0000000000..97b28ba7e7 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trigsel.h @@ -0,0 +1,338 @@ +/*! + \file gd32h7xx_trigsel.h + \brief definitions for the TRIGSEL + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_TRIGSEL_H +#define GD32H7XX_TRIGSEL_H + +#include "gd32h7xx.h" + +/* TRIGSEL definitions */ +#define TRIGSEL TRIGSEL_BASE /*!< TRIGSEL base address */ + +/* register definitions */ +#define TRIGSEL_EXTOUT0 REG32((TRIGSEL) + 0x00000000U) /*!< TRIGSEL trigger selection for EXTOUT0 register */ +#define TRIGSEL_EXTOUT1 REG32((TRIGSEL) + 0x00000004U) /*!< TRIGSEL trigger selection for EXTOUT1 register */ +#define TRIGSEL_EXTOUT2 REG32((TRIGSEL) + 0x00000008U) /*!< TRIGSEL trigger selection for EXTOUT2 register */ +#define TRIGSEL_EXTOUT3 REG32((TRIGSEL) + 0x0000000CU) /*!< TRIGSEL trigger selection for EXTOUT3 register */ +#define TRIGSEL_ADC0 REG32((TRIGSEL) + 0x00000010U) /*!< TRIGSEL trigger selection for ADC0 register */ +#define TRIGSEL_ADC1 REG32((TRIGSEL) + 0x00000014U) /*!< TRIGSEL trigger selection for ADC1 register */ +#define TRIGSEL_ADC2 REG32((TRIGSEL) + 0x00000018U) /*!< TRIGSEL trigger selection for ADC2 register */ +#define TRIGSEL_DACOUT0 REG32((TRIGSEL) + 0x0000001CU) /*!< TRIGSEL trigger selection for DAC_OUT0 register */ +#define TRIGSEL_DACOUT1 REG32((TRIGSEL) + 0x00000020U) /*!< TRIGSEL trigger selection for DAC_OUT1 register */ +#define TRIGSEL_TIMER0BRKIN REG32((TRIGSEL) + 0x00000024U) /*!< TRIGSEL trigger selection for TIMER0_BRKIN register */ +#define TRIGSEL_TIMER7BRKIN REG32((TRIGSEL) + 0x00000028U) /*!< TRIGSEL trigger selection for TIMER7_BRKIN register */ +#define TRIGSEL_TIMER14BRKIN REG32((TRIGSEL) + 0x0000002CU) /*!< TRIGSEL trigger selection for TIMER14_BRKIN register */ +#define TRIGSEL_TIMER15BRKIN REG32((TRIGSEL) + 0x00000030U) /*!< TRIGSEL trigger selection for TIMER15_BRKIN register */ +#define TRIGSEL_TIMER16BRKIN REG32((TRIGSEL) + 0x00000034U) /*!< TRIGSEL trigger selection for TIMER16_BRKIN register */ +#define TRIGSEL_TIMER40BRKIN REG32((TRIGSEL) + 0x00000038U) /*!< TRIGSEL trigger selection for TIMER40_BRKIN register */ +#define TRIGSEL_TIMER41BRKIN REG32((TRIGSEL) + 0x0000003CU) /*!< TRIGSEL trigger selection for TIMER41_BRKIN register */ +#define TRIGSEL_TIMER42BRKIN REG32((TRIGSEL) + 0x00000040U) /*!< TRIGSEL trigger selection for TIMER42_BRKIN register */ +#define TRIGSEL_TIMER43BRKIN REG32((TRIGSEL) + 0x00000044U) /*!< TRIGSEL trigger selection for TIMER43_BRKIN register */ +#define TRIGSEL_TIMER44BRKIN REG32((TRIGSEL) + 0x00000048U) /*!< TRIGSEL trigger selection for TIMER44_BRKIN register */ +#define TRIGSEL_CAN0 REG32((TRIGSEL) + 0x0000004CU) /*!< TRIGSEL trigger selection for CAN0 register */ +#define TRIGSEL_CAN1 REG32((TRIGSEL) + 0x00000050U) /*!< TRIGSEL trigger selection for CAN1 register */ +#define TRIGSEL_CAN2 REG32((TRIGSEL) + 0x00000054U) /*!< TRIGSEL trigger selection for CAN2 register */ +#define TRIGSEL_LPDTS REG32((TRIGSEL) + 0x00000058U) /*!< TRIGSEL trigger selection for LPDTS register */ +#define TRIGSEL_TIMER0ETI REG32((TRIGSEL) + 0x0000005CU) /*!< TRIGSEL trigger selection for TIMER0_ETI register */ +#define TRIGSEL_TIMER1ETI REG32((TRIGSEL) + 0x00000060U) /*!< TRIGSEL trigger selection for TIMER1_ETI register */ +#define TRIGSEL_TIMER2ETI REG32((TRIGSEL) + 0x00000064U) /*!< TRIGSEL trigger selection for TIMER2_ETI register */ +#define TRIGSEL_TIMER3ETI REG32((TRIGSEL) + 0x00000068U) /*!< TRIGSEL trigger selection for TIMER3_ETI register */ +#define TRIGSEL_TIMER4ETI REG32((TRIGSEL) + 0x0000006CU) /*!< TRIGSEL trigger selection for TIMER4_ETI register */ +#define TRIGSEL_TIMER7ETI REG32((TRIGSEL) + 0x00000070U) /*!< TRIGSEL trigger selection for TIMER7_ETI register */ +#define TRIGSEL_TIMER22ETI REG32((TRIGSEL) + 0x00000074U) /*!< TRIGSEL trigger selection for TIMER22_ETI register */ +#define TRIGSEL_TIMER23ETI REG32((TRIGSEL) + 0x00000078U) /*!< TRIGSEL trigger selection for TIMER23_ETI register */ +#define TRIGSEL_TIMER30ETI REG32((TRIGSEL) + 0x0000007CU) /*!< TRIGSEL trigger selection for TIMER30_ETI register */ +#define TRIGSEL_TIMER31ETI REG32((TRIGSEL) + 0x00000080U) /*!< TRIGSEL trigger selection for TIMER31_ETI register */ +#define TRIGSEL_EDOUT REG32((TRIGSEL) + 0x00000084U) /*!< TRIGSEL trigger selection for EDOUT register */ +#define TRIGSEL_HPDF REG32((TRIGSEL) + 0x00000088U) /*!< TRIGSEL trigger selection for HPDF register */ +#define TRIGSEL_TIMER0ITI14 REG32((TRIGSEL) + 0x0000008CU) /*!< TRIGSEL trigger selection for TIMER0_ITI14 register */ +#define TRIGSEL_TIMER1ITI14 REG32((TRIGSEL) + 0x00000090U) /*!< TRIGSEL trigger selection for TIMER1_ITI14 register */ +#define TRIGSEL_TIMER2ITI14 REG32((TRIGSEL) + 0x00000094U) /*!< TRIGSEL trigger selection for TIMER2_ITI14 register */ +#define TRIGSEL_TIMER3ITI14 REG32((TRIGSEL) + 0x00000098U) /*!< TRIGSEL trigger selection for TIMER3_ITI14 register */ +#define TRIGSEL_TIMER4ITI14 REG32((TRIGSEL) + 0x0000009CU) /*!< TRIGSEL trigger selection for TIMER4_ITI14 register */ +#define TRIGSEL_TIMER7ITI14 REG32((TRIGSEL) + 0x000000A0U) /*!< TRIGSEL trigger selection for TIMER7_ITI14 register */ +#define TRIGSEL_TIMER14ITI14 REG32((TRIGSEL) + 0x000000A4U) /*!< TRIGSEL trigger selection for TIMER14_ITI14 register */ +#define TRIGSEL_TIMER22ITI14 REG32((TRIGSEL) + 0x000000A8U) /*!< TRIGSEL trigger selection for TIMER22_ITI14 register */ +#define TRIGSEL_TIMER23ITI14 REG32((TRIGSEL) + 0x000000ACU) /*!< TRIGSEL trigger selection for TIMER23_ITI14 register */ +#define TRIGSEL_TIMER30ITI14 REG32((TRIGSEL) + 0x000000B0U) /*!< TRIGSEL trigger selection for TIMER30_ITI14 register */ +#define TRIGSEL_TIMER31ITI14 REG32((TRIGSEL) + 0x000000B4U) /*!< TRIGSEL trigger selection for TIMER31_ITI14 register */ +#define TRIGSEL_TIMER40ITI14 REG32((TRIGSEL) + 0x000000B8U) /*!< TRIGSEL trigger selection for TIMER40_ITI14 register */ +#define TRIGSEL_TIMER41ITI14 REG32((TRIGSEL) + 0x000000BCU) /*!< TRIGSEL trigger selection for TIMER41_ITI14 register */ +#define TRIGSEL_TIMER42ITI14 REG32((TRIGSEL) + 0x000000C0U) /*!< TRIGSEL trigger selection for TIMER42_ITI14 register */ +#define TRIGSEL_TIMER43ITI14 REG32((TRIGSEL) + 0x000000C4U) /*!< TRIGSEL trigger selection for TIMER43_ITI14 register */ +#define TRIGSEL_TIMER44ITI14 REG32((TRIGSEL) + 0x000000C8U) /*!< TRIGSEL trigger selection for TIMER44_ITI14 register */ + +/* bit definitions */ +/* trigger input source selection */ +#define TRIGSEL_TARGET_INSEL0 BITS(0,7) /*!< trigger input source selection for output0 */ +#define TRIGSEL_TARGET_INSEL1 BITS(8,15) /*!< trigger input source selection for output1 */ +#define TRIGSEL_TARGET_INSEL2 BITS(16,23) /*!< trigger input source selection for output2 */ +#define TRIGSEL_TARGET_LK BIT(31) /*!< TRIGSEL register lock */ + +/* constants definitions */ +/* trigger source definitions */ +typedef enum +{ + TRIGSEL_INPUT_0 = ((uint8_t)0x00U), /*!< trigger input source 0 */ + TRIGSEL_INPUT_1 = ((uint8_t)0x01U), /*!< trigger input source 1 */ + TRIGSEL_INPUT_TRIGSEL_IN0 = ((uint8_t)0x02U), /*!< trigger input source TRIGSEL_IN0 pin */ + TRIGSEL_INPUT_TRIGSEL_IN1 = ((uint8_t)0x03U), /*!< trigger input source TRIGSEL_IN1 pin */ + TRIGSEL_INPUT_TRIGSEL_IN2 = ((uint8_t)0x04U), /*!< trigger input source TRIGSEL_IN2 pin */ + TRIGSEL_INPUT_TRIGSEL_IN3 = ((uint8_t)0x05U), /*!< trigger input source TRIGSEL_IN3 pin */ + TRIGSEL_INPUT_TRIGSEL_IN4 = ((uint8_t)0x06U), /*!< trigger input source TRIGSEL_IN4 pin */ + TRIGSEL_INPUT_TRIGSEL_IN5 = ((uint8_t)0x07U), /*!< trigger input source TRIGSEL_IN5 pin */ + TRIGSEL_INPUT_TRIGSEL_IN6 = ((uint8_t)0x08U), /*!< trigger input source TRIGSEL_IN6 pin */ + TRIGSEL_INPUT_TRIGSEL_IN7 = ((uint8_t)0x09U), /*!< trigger input source TRIGSEL_IN7 pin */ + TRIGSEL_INPUT_TRIGSEL_IN8 = ((uint8_t)0x0AU), /*!< trigger input source TRIGSEL_IN8 pin */ + TRIGSEL_INPUT_TRIGSEL_IN9 = ((uint8_t)0x0BU), /*!< trigger input source TRIGSEL_IN9 pin */ + TRIGSEL_INPUT_TRIGSEL_IN10 = ((uint8_t)0x0CU), /*!< trigger input source TRIGSEL_IN10 pin */ + TRIGSEL_INPUT_TRIGSEL_IN11 = ((uint8_t)0x0DU), /*!< trigger input source TRIGSEL_IN11 pin */ + TRIGSEL_INPUT_TRIGSEL_IN12 = ((uint8_t)0x0EU), /*!< trigger input source TRIGSEL_IN12 pin */ + TRIGSEL_INPUT_TRIGSEL_IN13 = ((uint8_t)0x0FU), /*!< trigger input source TRIGSEL_IN13 pin */ + TRIGSEL_INPUT_LXTAL_TRG = ((uint8_t)0x10U), /*!< trigger input source LXTAL_TRG */ + TRIGSEL_INPUT_TIMER0_TRGO0 = ((uint8_t)0x11U), /*!< trigger input source TIMER0 TRGO0 */ + TRIGSEL_INPUT_TIMER0_TRGO1 = ((uint8_t)0x12U), /*!< trigger input source TIMER0 TRGO1 */ + TRIGSEL_INPUT_TIMER0_CH0 = ((uint8_t)0x13U), /*!< trigger input source TIMER0 CH0 */ + TRIGSEL_INPUT_TIMER0_CH1 = ((uint8_t)0x14U), /*!< trigger input source TIMER0 CH1 */ + TRIGSEL_INPUT_TIMER0_CH2 = ((uint8_t)0x15U), /*!< trigger input source TIMER0 CH2 */ + TRIGSEL_INPUT_TIMER0_CH3 = ((uint8_t)0x16U), /*!< trigger input source TIMER0 CH3 */ + TRIGSEL_INPUT_TIMER0_MCH0 = ((uint8_t)0x17U), /*!< trigger input source TIMER0 MCH0 */ + TRIGSEL_INPUT_TIMER0_MCH1 = ((uint8_t)0x18U), /*!< trigger input source TIMER0 MCH1 */ + TRIGSEL_INPUT_TIMER0_MCH2 = ((uint8_t)0x19U), /*!< trigger input source TIMER0 MCH2 */ + TRIGSEL_INPUT_TIMER0_MCH3 = ((uint8_t)0x1AU), /*!< trigger input source TIMER0 MCH3 */ + TRIGSEL_INPUT_TIMER0_BRKIN0 = ((uint8_t)0x21U), /*!< trigger input source TIMER0 BRKIN0 */ + TRIGSEL_INPUT_TIMER0_BRKIN1 = ((uint8_t)0x22U), /*!< trigger input source TIMER0 BRKIN1 */ + TRIGSEL_INPUT_TIMER0_BRKIN2 = ((uint8_t)0x23U), /*!< trigger input source TIMER0 BRKIN2 */ + TRIGSEL_INPUT_TIMER0_ETI = ((uint8_t)0x24U), /*!< trigger input source TIMER0 ETI */ + TRIGSEL_INPUT_TIMER1_TRGO0 = ((uint8_t)0x25U), /*!< trigger input source TIMER1 TRGO0 */ + TRIGSEL_INPUT_TIMER1_CH0 = ((uint8_t)0x26U), /*!< trigger input source TIMER1 CH0 */ + TRIGSEL_INPUT_TIMER1_CH1 = ((uint8_t)0x27U), /*!< trigger input source TIMER1 CH1 */ + TRIGSEL_INPUT_TIMER1_CH2 = ((uint8_t)0x28U), /*!< trigger input source TIMER1 CH2 */ + TRIGSEL_INPUT_TIMER1_CH3 = ((uint8_t)0x29U), /*!< trigger input source TIMER1 CH3 */ + TRIGSEL_INPUT_TIMER1_ETI = ((uint8_t)0x2AU), /*!< trigger input source TIMER1 ETI */ + TRIGSEL_INPUT_TIMER2_TRGO0 = ((uint8_t)0x2BU), /*!< trigger input source TIMER2 TRGO0 */ + TRIGSEL_INPUT_TIMER2_CH0 = ((uint8_t)0x2CU), /*!< trigger input source TIMER2 CH0 */ + TRIGSEL_INPUT_TIMER2_CH1 = ((uint8_t)0x2DU), /*!< trigger input source TIMER2 CH1 */ + TRIGSEL_INPUT_TIMER2_CH2 = ((uint8_t)0x2EU), /*!< trigger input source TIMER2 CH2 */ + TRIGSEL_INPUT_TIMER2_CH3 = ((uint8_t)0x2FU), /*!< trigger input source TIMER2 CH3 */ + TRIGSEL_INPUT_TIMER2_ETI = ((uint8_t)0x30U), /*!< trigger input source TIMER2 ETI */ + TRIGSEL_INPUT_TIMER3_TRGO0 = ((uint8_t)0x31U), /*!< trigger input source TIMER3 TRGO0 */ + TRIGSEL_INPUT_TIMER3_CH0 = ((uint8_t)0x32U), /*!< trigger input source TIMER3 CH0 */ + TRIGSEL_INPUT_TIMER3_CH1 = ((uint8_t)0x33U), /*!< trigger input source TIMER3 CH1 */ + TRIGSEL_INPUT_TIMER3_CH2 = ((uint8_t)0x34U), /*!< trigger input source TIMER3 CH2 */ + TRIGSEL_INPUT_TIMER3_CH3 = ((uint8_t)0x35U), /*!< trigger input source TIMER3 CH3 */ + TRIGSEL_INPUT_TIMER3_ETI = ((uint8_t)0x36U), /*!< trigger input source TIMER3 ETI */ + TRIGSEL_INPUT_TIMER4_TRGO0 = ((uint8_t)0x37U), /*!< trigger input source TIMER4 TRGO0 */ + TRIGSEL_INPUT_TIMER4_CH0 = ((uint8_t)0x38U), /*!< trigger input source TIMER4 CH0 */ + TRIGSEL_INPUT_TIMER4_CH1 = ((uint8_t)0x39U), /*!< trigger input source TIMER4 CH1 */ + TRIGSEL_INPUT_TIMER4_CH2 = ((uint8_t)0x3AU), /*!< trigger input source TIMER4 CH2 */ + TRIGSEL_INPUT_TIMER4_CH3 = ((uint8_t)0x3BU), /*!< trigger input source TIMER4 CH3 */ + TRIGSEL_INPUT_TIMER4_ETI = ((uint8_t)0x3CU), /*!< trigger input source TIMER4 ETI */ + TRIGSEL_INPUT_TIMER5_TRGO0 = ((uint8_t)0x3DU), /*!< trigger input source TIMER5 TRGO0 */ + TRIGSEL_INPUT_TIMER6_TRGO0 = ((uint8_t)0x3EU), /*!< trigger input source TIMER6 TRGO0 */ + TRIGSEL_INPUT_TIMER7_TRGO0 = ((uint8_t)0x3FU), /*!< trigger input source TIMER7 TRGO0 */ + TRIGSEL_INPUT_TIMER7_TRGO1 = ((uint8_t)0x40U), /*!< trigger input source TIMER7 TRGO1 */ + TRIGSEL_INPUT_TIMER7_CH0 = ((uint8_t)0x41U), /*!< trigger input source TIMER7 CH0 */ + TRIGSEL_INPUT_TIMER7_CH1 = ((uint8_t)0x42U), /*!< trigger input source TIMER7 CH1 */ + TRIGSEL_INPUT_TIMER7_CH2 = ((uint8_t)0x43U), /*!< trigger input source TIMER7 CH2 */ + TRIGSEL_INPUT_TIMER7_CH3 = ((uint8_t)0x44U), /*!< trigger input source TIMER7 CH3 */ + TRIGSEL_INPUT_TIMER7_MCH0 = ((uint8_t)0x45U), /*!< trigger input source TIMER7 MCH0 */ + TRIGSEL_INPUT_TIMER7_MCH1 = ((uint8_t)0x46U), /*!< trigger input source TIMER7 MCH1 */ + TRIGSEL_INPUT_TIMER7_MCH2 = ((uint8_t)0x47U), /*!< trigger input source TIMER7 MCH2 */ + TRIGSEL_INPUT_TIMER7_MCH3 = ((uint8_t)0x48U), /*!< trigger input source TIMER7 MCH3 */ + TRIGSEL_INPUT_TIMER7_BRKIN0 = ((uint8_t)0x4FU), /*!< trigger input source TIMER7 BRKIN0 */ + TRIGSEL_INPUT_TIMER7_BRKIN1 = ((uint8_t)0x50U), /*!< trigger input source TIMER7 BRKIN1 */ + TRIGSEL_INPUT_TIMER7_BRKIN2 = ((uint8_t)0x51U), /*!< trigger input source TIMER7 BRKIN2 */ + TRIGSEL_INPUT_TIMER7_ETI = ((uint8_t)0x52U), /*!< trigger input source TIMER7 ETI */ + TRIGSEL_INPUT_TIMER14_TRGO0 = ((uint8_t)0x53U), /*!< trigger input source TIMER14 TRGO0 */ + TRIGSEL_INPUT_TIMER14_CH0 = ((uint8_t)0x54U), /*!< trigger input source TIMER14 CH0 */ + TRIGSEL_INPUT_TIMER14_CH1 = ((uint8_t)0x55U), /*!< trigger input source TIMER14 CH1 */ + TRIGSEL_INPUT_TIMER14_MCH0 = ((uint8_t)0x56U), /*!< trigger input source TIMER14 MCH0 */ + TRIGSEL_INPUT_TIMER14_BRKIN = ((uint8_t)0x59U), /*!< trigger input source TIMER14 BRKIN */ + TRIGSEL_INPUT_TIMER15_CH0 = ((uint8_t)0x5AU), /*!< trigger input source TIMER15 CH0 */ + TRIGSEL_INPUT_TIMER15_MCH0 = ((uint8_t)0x5BU), /*!< trigger input source TIMER15 MCH0 */ + TRIGSEL_INPUT_TIMER15_BRKIN = ((uint8_t)0x5EU), /*!< trigger input source TIMER15 BRKIN */ + TRIGSEL_INPUT_TIMER16_CH0 = ((uint8_t)0x5FU), /*!< trigger input source TIMER16 CH0 */ + TRIGSEL_INPUT_TIMER16_MCH0 = ((uint8_t)0x60U), /*!< trigger input source TIMER16 MCH0 */ + TRIGSEL_INPUT_TIMER16_BRKIN = ((uint8_t)0x63U), /*!< trigger input source TIMER16 BRKIN */ + TRIGSEL_INPUT_TIMER22_TRGO0 = ((uint8_t)0x64U), /*!< trigger input source TIMER22 TRGO0 */ + TRIGSEL_INPUT_TIMER22_CH0 = ((uint8_t)0x65U), /*!< trigger input source TIMER22 CH0 */ + TRIGSEL_INPUT_TIMER22_CH1 = ((uint8_t)0x66U), /*!< trigger input source TIMER22 CH1 */ + TRIGSEL_INPUT_TIMER22_CH2 = ((uint8_t)0x67U), /*!< trigger input source TIMER22 CH2 */ + TRIGSEL_INPUT_TIMER22_CH3 = ((uint8_t)0x68U), /*!< trigger input source TIMER22 CH3 */ + TRIGSEL_INPUT_TIMER22_ETI = ((uint8_t)0x69U), /*!< trigger input source TIMER22 ETI */ + TRIGSEL_INPUT_TIMER23_TRGO0 = ((uint8_t)0x6AU), /*!< trigger input source TIMER23 TRGO0 */ + TRIGSEL_INPUT_TIMER23_CH0 = ((uint8_t)0x6BU), /*!< trigger input source TIMER23 CH0 */ + TRIGSEL_INPUT_TIMER23_CH1 = ((uint8_t)0x6CU), /*!< trigger input source TIMER23 CH1 */ + TRIGSEL_INPUT_TIMER23_CH2 = ((uint8_t)0x6DU), /*!< trigger input source TIMER23 CH2 */ + TRIGSEL_INPUT_TIMER23_CH3 = ((uint8_t)0x6EU), /*!< trigger input source TIMER23 CH3 */ + TRIGSEL_INPUT_TIMER23_ETI = ((uint8_t)0x6FU), /*!< trigger input source TIMER23 ETI */ + TRIGSEL_INPUT_TIMER30_TRGO0 = ((uint8_t)0x70U), /*!< trigger input source TIMER30 TRGO0 */ + TRIGSEL_INPUT_TIMER30_CH0 = ((uint8_t)0x71U), /*!< trigger input source TIMER30 CH0 */ + TRIGSEL_INPUT_TIMER30_CH1 = ((uint8_t)0x72U), /*!< trigger input source TIMER30 CH1 */ + TRIGSEL_INPUT_TIMER30_CH2 = ((uint8_t)0x73U), /*!< trigger input source TIMER30 CH2 */ + TRIGSEL_INPUT_TIMER30_CH3 = ((uint8_t)0x74U), /*!< trigger input source TIMER30 CH3 */ + TRIGSEL_INPUT_TIMER30_ETI = ((uint8_t)0x75U), /*!< trigger input source TIMER30 ETI */ + TRIGSEL_INPUT_TIMER31_TRGO0 = ((uint8_t)0x76U), /*!< trigger input source TIMER31 TRGO0 */ + TRIGSEL_INPUT_TIMER31_CH0 = ((uint8_t)0x77U), /*!< trigger input source TIMER31 CH0 */ + TRIGSEL_INPUT_TIMER31_CH1 = ((uint8_t)0x78U), /*!< trigger input source TIMER31 CH1 */ + TRIGSEL_INPUT_TIMER31_CH2 = ((uint8_t)0x79U), /*!< trigger input source TIMER31 CH2 */ + TRIGSEL_INPUT_TIMER31_CH3 = ((uint8_t)0x7AU), /*!< trigger input source TIMER31 CH3 */ + TRIGSEL_INPUT_TIMER31_ETI = ((uint8_t)0x7BU), /*!< trigger input source TIMER31 ETI */ + TRIGSEL_INPUT_TIMER40_TRGO0 = ((uint8_t)0x7CU), /*!< trigger input source TIMER40 TRGO0 */ + TRIGSEL_INPUT_TIMER40_CH0 = ((uint8_t)0x7DU), /*!< trigger input source TIMER40 CH0 */ + TRIGSEL_INPUT_TIMER40_CH1 = ((uint8_t)0x7EU), /*!< trigger input source TIMER40 CH1 */ + TRIGSEL_INPUT_TIMER40_MCH0 = ((uint8_t)0x7FU), /*!< trigger input source TIMER40 MCH0 */ + TRIGSEL_INPUT_TIMER40_BRKIN = ((uint8_t)0x82U), /*!< trigger input source TIMER40 BRKIN */ + TRIGSEL_INPUT_TIMER41_TRGO0 = ((uint8_t)0x83U), /*!< trigger input source TIMER41 TRGO0 */ + TRIGSEL_INPUT_TIMER41_CH0 = ((uint8_t)0x84U), /*!< trigger input source TIMER41 CH0 */ + TRIGSEL_INPUT_TIMER41_CH1 = ((uint8_t)0x85U), /*!< trigger input source TIMER41 CH1 */ + TRIGSEL_INPUT_TIMER41_MCH0 = ((uint8_t)0x86U), /*!< trigger input source TIMER41 MCH0 */ + TRIGSEL_INPUT_TIMER41_BRKIN = ((uint8_t)0x89U), /*!< trigger input source TIMER41 BRKIN */ + TRIGSEL_INPUT_TIMER42_TRGO0 = ((uint8_t)0x8AU), /*!< trigger input source TIMER42 TRGO0 */ + TRIGSEL_INPUT_TIMER42_CH0 = ((uint8_t)0x8BU), /*!< trigger input source TIMER42 CH0 */ + TRIGSEL_INPUT_TIMER42_CH1 = ((uint8_t)0x8CU), /*!< trigger input source TIMER42 CH1 */ + TRIGSEL_INPUT_TIMER42_MCH0 = ((uint8_t)0x8DU), /*!< trigger input source TIMER42 MCH0 */ + TRIGSEL_INPUT_TIMER42_BRKIN = ((uint8_t)0x90U), /*!< trigger input source TIMER42 BRKIN */ + TRIGSEL_INPUT_TIMER43_TRGO0 = ((uint8_t)0x91U), /*!< trigger input source TIMER43 TRGO0 */ + TRIGSEL_INPUT_TIMER43_CH0 = ((uint8_t)0x92U), /*!< trigger input source TIMER43 CH0 */ + TRIGSEL_INPUT_TIMER43_CH1 = ((uint8_t)0x93U), /*!< trigger input source TIMER43 CH1 */ + TRIGSEL_INPUT_TIMER43_MCH0 = ((uint8_t)0x94U), /*!< trigger input source TIMER43 MCH0 */ + TRIGSEL_INPUT_TIMER43_BRKIN = ((uint8_t)0x97U), /*!< trigger input source TIMER43 BRKIN */ + TRIGSEL_INPUT_TIMER44_TRGO0 = ((uint8_t)0x98U), /*!< trigger input source TIMER44 TRGO0 */ + TRIGSEL_INPUT_TIMER44_CH0 = ((uint8_t)0x99U), /*!< trigger input source TIMER44 CH0 */ + TRIGSEL_INPUT_TIMER44_CH1 = ((uint8_t)0x9AU), /*!< trigger input source TIMER44 CH1 */ + TRIGSEL_INPUT_TIMER44_MCH0 = ((uint8_t)0x9BU), /*!< trigger input source TIMER44 MCH0 */ + TRIGSEL_INPUT_TIMER44_BRKIN = ((uint8_t)0x9EU), /*!< trigger input source TIMER44 BRKIN */ + TRIGSEL_INPUT_TIMER50_TRGO0 = ((uint8_t)0x9FU), /*!< trigger input source TIMER50 TRGO0 */ + TRIGSEL_INPUT_TIMER51_TRGO0 = ((uint8_t)0xA0U), /*!< trigger input source TIMER51 TRGO0 */ + TRIGSEL_INPUT_RTC_ALARM = ((uint8_t)0xA1U), /*!< trigger input source RTC alarm */ + TRIGSEL_INPUT_RTC_TPTS = ((uint8_t)0xA2U), /*!< trigger input source RTC TPTS */ + TRIGSEL_INPUT_ADC0_WD0_OUT = ((uint8_t)0xA3U), /*!< trigger input source ADC0 watchdog0 output */ + TRIGSEL_INPUT_ADC0_WD1_OUT = ((uint8_t)0xA4U), /*!< trigger input source ADC0 watchdog1 output */ + TRIGSEL_INPUT_ADC0_WD2_OUT = ((uint8_t)0xA5U), /*!< trigger input source ADC0 watchdog2 output */ + TRIGSEL_INPUT_ADC1_WD0_OUT = ((uint8_t)0xA6U), /*!< trigger input source ADC1 watchdog0 output */ + TRIGSEL_INPUT_ADC1_WD1_OUT = ((uint8_t)0xA7U), /*!< trigger input source ADC1 watchdog1 output */ + TRIGSEL_INPUT_ADC1_WD2_OUT = ((uint8_t)0xA8U), /*!< trigger input source ADC1 watchdog2 output */ + TRIGSEL_INPUT_ADC2_WD0_OUT = ((uint8_t)0xA9U), /*!< trigger input source ADC2 watchdog0 output */ + TRIGSEL_INPUT_ADC2_WD1_OUT = ((uint8_t)0xAAU), /*!< trigger input source ADC2 watchdog1 output */ + TRIGSEL_INPUT_ADC2_WD2_OUT = ((uint8_t)0xABU), /*!< trigger input source ADC2 watchdog2 output */ + TRIGSEL_INPUT_CMP0_OUT = ((uint8_t)0xACU), /*!< trigger input source CMP0_OUT */ + TRIGSEL_INPUT_CMP1_OUT = ((uint8_t)0xADU), /*!< trigger input source CMP1_OUT */ + TRIGSEL_INPUT_SAI0_AFS_OUT = ((uint8_t)0xAEU), /*!< trigger input source SAI0_AFS_OUT */ + TRIGSEL_INPUT_SAI0_BFS_OUT = ((uint8_t)0xAFU), /*!< trigger input source SAI0_BFS_OUT */ + TRIGSEL_INPUT_SAI2_AFS_OUT = ((uint8_t)0xB0U), /*!< trigger input source SAI2_AFS_OUT */ + TRIGSEL_INPUT_SAI2_BFS_OUT = ((uint8_t)0xB1U), /*!< trigger input source SAI2_BFS_OUT */ +}trigsel_source_enum; + +/* target peripheral definitions */ +typedef enum +{ + TRIGSEL_OUTPUT_TRIGSEL_OUT0 = ((uint8_t)0x00U), /*!< output target peripheral TRIGSEL_OUT0 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT1 = ((uint8_t)0x01U), /*!< output target peripheral TRIGSEL_OUT1 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT2 = ((uint8_t)0x04U), /*!< output target peripheral TRIGSEL_OUT2 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT3 = ((uint8_t)0x05U), /*!< output target peripheral TRIGSEL_OUT3 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT4 = ((uint8_t)0x08U), /*!< output target peripheral TRIGSEL_OUT4 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT5 = ((uint8_t)0x09U), /*!< output target peripheral TRIGSEL_OUT5 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT6 = ((uint8_t)0x0CU), /*!< output target peripheral TRIGSEL_OUT6 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT7 = ((uint8_t)0x0DU), /*!< output target peripheral TRIGSEL_OUT7 pin */ + TRIGSEL_OUTPUT_ADC0_REGTRG = ((uint8_t)0x10U), /*!< output target peripheral ADC0_REGTRG */ + TRIGSEL_OUTPUT_ADC0_INSTRG = ((uint8_t)0x11U), /*!< output target peripheral ADC0_INSTRG */ + TRIGSEL_OUTPUT_ADC1_REGTRG = ((uint8_t)0x14U), /*!< output target peripheral ADC1_REGTRG */ + TRIGSEL_OUTPUT_ADC1_INSTRG = ((uint8_t)0x15U), /*!< output target peripheral ADC1_INSTRG */ + TRIGSEL_OUTPUT_ADC2_REGTRG = ((uint8_t)0x18U), /*!< output target peripheral ADC2_REGTRG */ + TRIGSEL_OUTPUT_ADC2_INSTRG = ((uint8_t)0x19U), /*!< output target peripheral ADC2_INSTRG */ + TRIGSEL_OUTPUT_DAC_OUT0_EXTRG = ((uint8_t)0x1CU), /*!< output target peripheral DAC_OUT0_EXTRG */ + TRIGSEL_OUTPUT_DAC_OUT1_EXTRG = ((uint8_t)0x20U), /*!< output target peripheral DAC_OUT1_EXTRG */ + TRIGSEL_OUTPUT_TIMER0_BRKIN0 = ((uint8_t)0x24U), /*!< output target peripheral TIMER0_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER0_BRKIN1 = ((uint8_t)0x25U), /*!< output target peripheral TIMER0_BRKIN1 */ + TRIGSEL_OUTPUT_TIMER0_BRKIN2 = ((uint8_t)0x26U), /*!< output target peripheral TIMER0_BRKIN2 */ + TRIGSEL_OUTPUT_TIMER7_BRKIN0 = ((uint8_t)0x28U), /*!< output target peripheral TIMER7_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER7_BRKIN1 = ((uint8_t)0x29U), /*!< output target peripheral TIMER7_BRKIN1 */ + TRIGSEL_OUTPUT_TIMER7_BRKIN2 = ((uint8_t)0x2AU), /*!< output target peripheral TIMER7_BRKIN2 */ + TRIGSEL_OUTPUT_TIMER14_BRKIN0 = ((uint8_t)0x2CU), /*!< output target peripheral TIMER14_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER15_BRKIN0 = ((uint8_t)0x30U), /*!< output target peripheral TIMER15_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER16_BRKIN0 = ((uint8_t)0x34U), /*!< output target peripheral TIMER16_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER40_BRKIN0 = ((uint8_t)0x38U), /*!< output target peripheral TIMER40_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER41_BRKIN0 = ((uint8_t)0x3CU), /*!< output target peripheral TIMER41_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER42_BRKIN0 = ((uint8_t)0x40U), /*!< output target peripheral TIMER42_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER43_BRKIN0 = ((uint8_t)0x44U), /*!< output target peripheral TIMER43_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER44_BRKIN0 = ((uint8_t)0x48U), /*!< output target peripheral TIMER44_BRKIN0 */ + TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK = ((uint8_t)0x4CU), /*!< output target peripheral CAN0_EX_TIME_TICK */ + TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK = ((uint8_t)0x50U), /*!< output target peripheral CAN1_EX_TIME_TICK */ + TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK = ((uint8_t)0x54U), /*!< output target peripheral CAN2_EX_TIME_TICK */ + TRIGSEL_OUTPUT_LPDTS_TRG = ((uint8_t)0x58U), /*!< output target peripheral LPDTS_TRG */ + TRIGSEL_OUTPUT_TIMER0_ETI = ((uint8_t)0x5CU), /*!< output target peripheral TIMER0_ETI */ + TRIGSEL_OUTPUT_TIMER1_ETI = ((uint8_t)0x60U), /*!< output target peripheral TIMER1_ETI */ + TRIGSEL_OUTPUT_TIMER2_ETI = ((uint8_t)0x64U), /*!< output target peripheral TIMER2_ETI */ + TRIGSEL_OUTPUT_TIMER3_ETI = ((uint8_t)0x68U), /*!< output target peripheral TIMER3_ETI */ + TRIGSEL_OUTPUT_TIMER4_ETI = ((uint8_t)0x6CU), /*!< output target peripheral TIMER4_ETI */ + TRIGSEL_OUTPUT_TIMER7_ETI = ((uint8_t)0x70U), /*!< output target peripheral TIMER7_ETI */ + TRIGSEL_OUTPUT_TIMER22_ETI = ((uint8_t)0x74U), /*!< output target peripheral TIMER22_ETI */ + TRIGSEL_OUTPUT_TIMER23_ETI = ((uint8_t)0x78U), /*!< output target peripheral TIMER23_ETI */ + TRIGSEL_OUTPUT_TIMER30_ETI = ((uint8_t)0x7CU), /*!< output target peripheral TIMER30_ETI */ + TRIGSEL_OUTPUT_TIMER31_ETI = ((uint8_t)0x80U), /*!< output target peripheral TIMER31_ETI */ + TRIGSEL_OUTPUT_EDOUT_TRG = ((uint8_t)0x84U), /*!< output target peripheral EDOUT_TRG */ + TRIGSEL_OUTPUT_HPDF_ITR = ((uint8_t)0x88U), /*!< output target peripheral HPDF_ITR */ + TRIGSEL_OUTPUT_TIMER0_ITI14 = ((uint8_t)0x8CU), /*!< output target peripheral TIMER0_ITI14 */ + TRIGSEL_OUTPUT_TIMER1_ITI14 = ((uint8_t)0x90U), /*!< output target peripheral TIMER1_ITI14 */ + TRIGSEL_OUTPUT_TIMER2_ITI14 = ((uint8_t)0x94U), /*!< output target peripheral TIMER2_ITI14 */ + TRIGSEL_OUTPUT_TIMER3_ITI14 = ((uint8_t)0x98U), /*!< output target peripheral TIMER3_ITI14 */ + TRIGSEL_OUTPUT_TIMER4_ITI14 = ((uint8_t)0x9CU), /*!< output target peripheral TIMER4_ITI14 */ + TRIGSEL_OUTPUT_TIMER7_ITI14 = ((uint8_t)0xA0U), /*!< output target peripheral TIMER7_ITI14 */ + TRIGSEL_OUTPUT_TIMER14_ITI14 = ((uint8_t)0xA4U), /*!< output target peripheral TIMER14_ITI14 */ + TRIGSEL_OUTPUT_TIMER22_ITI14 = ((uint8_t)0xA8U), /*!< output target peripheral TIMER22_ITI14 */ + TRIGSEL_OUTPUT_TIMER23_ITI14 = ((uint8_t)0xACU), /*!< output target peripheral TIMER23_ITI14 */ + TRIGSEL_OUTPUT_TIMER30_ITI14 = ((uint8_t)0xB0U), /*!< output target peripheral TIMER30_ITI14 */ + TRIGSEL_OUTPUT_TIMER31_ITI14 = ((uint8_t)0xB4U), /*!< output target peripheral TIMER31_ITI14 */ + TRIGSEL_OUTPUT_TIMER40_ITI14 = ((uint8_t)0xB8U), /*!< output target peripheral TIMER40_ITI14 */ + TRIGSEL_OUTPUT_TIMER41_ITI14 = ((uint8_t)0xBCU), /*!< output target peripheral TIMER41_ITI14 */ + TRIGSEL_OUTPUT_TIMER42_ITI14 = ((uint8_t)0xC0U), /*!< output target peripheral TIMER42_ITI14 */ + TRIGSEL_OUTPUT_TIMER43_ITI14 = ((uint8_t)0xC4U), /*!< output target peripheral TIMER43_ITI14 */ + TRIGSEL_OUTPUT_TIMER44_ITI14 = ((uint8_t)0xC8U), /*!< output target peripheral TIMER44_ITI14 */ +}trigsel_periph_enum; + +/* function declarations */ +/* deinitialize TRIGSEL */ +void trigsel_deinit(void); +/* set the trigger input signal for target peripheral */ +void trigsel_init(trigsel_periph_enum target_periph, trigsel_source_enum trigger_source); +/* get the trigger input signal for target peripheral */ +trigsel_source_enum trigsel_trigger_source_get(trigsel_periph_enum target_periph); +/* lock the trigger register */ +void trigsel_register_lock_set(trigsel_periph_enum target_periph); +/* get the trigger register lock status */ +FlagStatus trigsel_register_lock_get(trigsel_periph_enum target_periph); + +#endif /* GD32H7XX_TRIGSEL_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trng.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trng.h new file mode 100644 index 0000000000..979c8b7eef --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_trng.h @@ -0,0 +1,218 @@ +/*! + \file gd32h7xx_trng.h + \brief definitions for the TRNG + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_TRNG_H +#define GD32H7XX_TRNG_H + +#include "gd32h7xx.h" + +/* TRNG definitions */ +#define TRNG TRNG_BASE + +/* registers definitions */ +#define TRNG_CTL REG32(TRNG + 0x00000000U) /*!< control register */ +#define TRNG_STAT REG32(TRNG + 0x00000004U) /*!< status register */ +#define TRNG_DATA REG32(TRNG + 0x00000008U) /*!< data register */ +#define TRNG_HTCFG REG32(TRNG + 0x00000010U) /*!< health tests configure register */ + +/* bits definitions */ +/* TRNG_CTL */ +#define TRNG_CTL_TRNGEN BIT(2) /*!< TRNG enable bit */ +#define TRNG_CTL_IE BIT(3) /*!< interrupt enable bit */ +#define TRNG_CTL_MODSEL BIT(4) /*!< TRNG working mode config bit */ +#define TRNG_CTL_CED BIT(5) /*!< clock error detect enable bit */ +#define TRNG_CTL_RTEN BIT(7) /*!< replace test enable */ +#define TRNG_CTL_INIT BIT(8) /*!< HASH algorithm init */ +#define TRNG_CTL_PPEN BIT(9) /*!< TRNG post-porcessing module enable */ +#define TRNG_CTL_CONDEN BIT(10) /*!< TRNG conditioning module enable */ +#define TRNG_CTL_ALGO BITS(12,13) /*!< TRNG conditioning module hash algo select */ +#define TRNG_CTL_OUTMOD BIT(14) /*!< TRNG conditioning output width config bit */ +#define TRNG_CTL_INMOD BIT(15) /*!< TRNG conditioning input width config bit */ +#define TRNG_CTL_CLKDIV BITS(16,19) /*!< TRNG clock divider */ +#define TRNG_CTL_NR BITS(24,25) /*!< TRNG analog power mode bits */ +#define TRNG_CTL_CONDRST BIT(30) /*!< reset TRNG conditioning logic */ +#define TRNG_CTL_LK BIT(31) /*!< TRNG_CTL register lock bit */ + +/* TRNG_STAT */ +#define TRNG_STAT_DRDY BIT(0) /*!< random data ready status bit */ +#define TRNG_STAT_CECS BIT(1) /*!< clock error current status */ +#define TRNG_STAT_SECS BIT(2) /*!< seed error current status */ +#define TRNG_STAT_ERRSTA BIT(3) /*!< NIST mode error status */ +#define TRNG_STAT_CEIF BIT(5) /*!< clock error interrupt flag */ +#define TRNG_STAT_SEIF BIT(6) /*!< seed error interrupt flag */ + +/* TRNG_DATA */ +#define TRNG_DATA_TRNDATA BITS(0,31) /*!< 32-Bit Random data */ + +/* TRNG_HTCFG */ +#define TRNG_HTCFG_RCTTH BITS(0,6) /*!< repetition (00/11) count test threshold */ +#define TRNG_HTCFG_APTTH BITS(16,25) /*!< adaptive proportion test threshold */ + +/* TRNG clock division */ +#define CTL_ALGO(regval) (BITS(12,13) & ((uint32_t)(regval) << 12U)) +#define TRNG_ALGO_SHA1 CTL_ALGO(0) /*!< TRNG conditioning module hash SHA1 */ +#define TRNG_ALGO_MD5 CTL_ALGO(1) /*!< TRNG conditioning module hash MD5 */ +#define TRNG_ALGO_SHA224 CTL_ALGO(2) /*!< TRNG conditioning module hash SHA224 */ +#define TRNG_ALGO_SHA256 CTL_ALGO(3) /*!< TRNG conditioning module hash SHA256 */ + +/* TRNG clock division */ +#define CTL_CLKDIV(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) +#define TRNG_CLK_DIV1 CTL_CLKDIV(0) /*!< TRNG clock TRNG_CLK divider 1 */ +#define TRNG_CLK_DIV2 CTL_CLKDIV(1) /*!< TRNG clock TRNG_CLK divider 2 */ +#define TRNG_CLK_DIV4 CTL_CLKDIV(2) /*!< TRNG clock TRNG_CLK divider 4 */ +#define TRNG_CLK_DIV8 CTL_CLKDIV(3) /*!< TRNG clock TRNG_CLK divider 8 */ +#define TRNG_CLK_DIV16 CTL_CLKDIV(4) /*!< TRNG clock TRNG_CLK divider 16 */ +#define TRNG_CLK_DIV32 CTL_CLKDIV(5) /*!< TRNG clock TRNG_CLK divider 32 */ +#define TRNG_CLK_DIV64 CTL_CLKDIV(6) /*!< TRNG clock TRNG_CLK divider 64 */ +#define TRNG_CLK_DIV128 CTL_CLKDIV(7) /*!< TRNG clock TRNG_CLK divider 128 */ +#define TRNG_CLK_DIV256 CTL_CLKDIV(8) /*!< TRNG clock TRNG_CLK divider 256 */ +#define TRNG_CLK_DIV512 CTL_CLKDIV(9) /*!< TRNG clock TRNG_CLK divider 512 */ +#define TRNG_CLK_DIV1024 CTL_CLKDIV(10) /*!< TRNG clock TRNG_CLK divider 1024 */ +#define TRNG_CLK_DIV2048 CTL_CLKDIV(11) /*!< TRNG clock TRNG_CLK divider 2048 */ +#define TRNG_CLK_DIV4096 CTL_CLKDIV(12) /*!< TRNG clock TRNG_CLK divider 4096 */ +#define TRNG_CLK_DIV8192 CTL_CLKDIV(13) /*!< TRNG clock TRNG_CLK divider 8192 */ +#define TRNG_CLK_DIV16384 CTL_CLKDIV(14) /*!< TRNG clock TRNG_CLK divider 16384 */ +#define TRNG_CLK_DIV32768 CTL_CLKDIV(15) /*!< TRNG clock TRNG_CLK divider 32768 */ + +/* TRNG power mode */ +#define CTL_NR(regval) (BITS(24,25) & ((uint32_t)(regval) << 24U)) +#define TRNG_NR_ULTRALOW CTL_NR(0) /*!< TRNG analog power mode ultralow */ +#define TRNG_NR_LOW CTL_NR(1) /*!< TRNG analog power mode low */ +#define TRNG_NR_MEDIUM CTL_NR(2) /*!< TRNG analog power mode medium */ +#define TRNG_NR_HIGH CTL_NR(3) /*!< TRNG analog power mode high */ + +/* constants definitions */ +/* trng input mode */ +typedef enum +{ + TRNG_INMOD_256BIT = 0, /*!< conditioning module input bitwidth 256bits */ + TRNG_INMOD_440BIT = TRNG_CTL_INMOD /*!< conditioning module input bitwidth 440bits */ +}trng_inmod_enum; + +/* trng output mode */ +typedef enum +{ + TRNG_OUTMOD_128BIT = 0, /*!< conditioning module output bitwidth 128bits */ + TRNG_OUTMOD_256BIT = TRNG_CTL_OUTMOD /*!< conditioning module output bitwidth 256bits */ +}trng_outmod_enum; + +/* trng working mode */ +typedef enum +{ + TRNG_MODSEL_LFSR = 0, /*!< TRNG working in LFSR mode */ + TRNG_MODSEL_NIST = TRNG_CTL_MODSEL /*!< TRNG working in NIST mode */ +}trng_modsel_enum; + +/* trng status flag */ +typedef enum +{ + TRNG_FLAG_DRDY = TRNG_STAT_DRDY, /*!< random Data ready status */ + TRNG_FLAG_CECS = TRNG_STAT_CECS, /*!< clock error current status */ + TRNG_FLAG_SECS = TRNG_STAT_SECS /*!< seed error current status */ +}trng_flag_enum; + +/* trng interrupt flag */ +typedef enum +{ + TRNG_INT_FLAG_CEIF = TRNG_STAT_CEIF, /*!< clock error interrupt flag */ + TRNG_INT_FLAG_SEIF = TRNG_STAT_SEIF /*!< seed error interrupt flag */ +}trng_int_flag_enum; + + +/* function declarations */ +/* initialization functions */ +/* deinitialize the TRNG */ +void trng_deinit(void); +/* enable the TRNG interface */ +void trng_enable(void); +/* disable the TRNG interface */ +void trng_disable(void); +/* lock the TRNG control bits */ +void trng_lock(void); +/* configure TRNG working mode */ +void trng_mode_config(trng_modsel_enum mode_select); +/* enable the TRNG post-processing module */ +void trng_postprocessing_enable(void); +/* disable the TRNG post-processing module */ +void trng_postprocessing_disable(void); +/* enable the TRNG conditioning module */ +void trng_conditioning_enable(void); +/* disable the TRNG conditioning module */ +void trng_conditioning_disable(void); +/* configure TRNG conditioning module input bitwidth */ +void trng_conditioning_input_bitwidth(trng_inmod_enum input_bitwidth); +/* configure TRNG conditioning module output bitwidth */ +void trng_conditioning_output_bitwidth(trng_outmod_enum output_bitwidth); +/* enable TRNG replace test */ +void trng_replace_test_enable(void); +/* disable TRNG replace test */ +void trng_replace_test_disable(void); +/* enable hash algorithm init when conditioning module enabled */ +void trng_hash_init_enable(void); +/* disable hash algorithm init when conditioning module enabled */ +void trng_hash_init_disable(void); +/* configure TRNG analog power mode */ +void trng_powermode_config(uint32_t powermode); +/* configure TRNG clock divider */ +void trng_clockdiv_config(uint32_t clkdiv); +/* enable the TRNG clock error detection */ +void trng_clockerror_detection_enable(void); +/* disable the TRNG clock error detection */ +void trng_clockerror_detection_disable(void); +/* get the true random data */ +uint32_t trng_get_true_random_data(void); + +/* conditioning configration */ +/* enable the conditioning logic reset */ +void trng_conditioning_reset_enable(void); +/* disable the conditioning logic reset */ +void trng_conditioning_reset_disable(void); +/* configure the conditioning module hash algorithm */ +void trng_conditioning_algo_config(uint32_t module_algo); +/* configure health tests default value */ +void trng_health_tests_config(uint32_t adpo_threshold, uint8_t rep_threshold); + +/* flag & interrupt functions */ +/* get the TRNG status flags */ +FlagStatus trng_flag_get(trng_flag_enum flag); +/* enable TRNG interrupt */ +void trng_interrupt_enable(void); +/* disable TRNG interrupt */ +void trng_interrupt_disable(void); +/* get the TRNG interrupt flags */ +FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag); +/* clear the TRNG interrupt flags */ +void trng_interrupt_flag_clear(trng_int_flag_enum int_flag); + +#endif /* GD32H7XX_TRNG_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_usart.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_usart.h new file mode 100644 index 0000000000..48d8f223f2 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_usart.h @@ -0,0 +1,683 @@ +/*! + \file gd32h7xx_usart.h + \brief definitions for the USART + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_USART_H +#define GD32H7XX_USART_H + +#include "gd32h7xx.h" + +/* USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) definitions */ +#define USART0 (USART_BASE + 0x0000CC00U) /*!< USART0 base address */ +#define USART1 USART_BASE /*!< USART1 base address */ +#define USART2 (USART_BASE + 0x00000400U) /*!< USART2 base address */ +#define UART3 (USART_BASE + 0x00000800U) /*!< UART3 base address */ +#define UART4 (USART_BASE + 0x00000C00U) /*!< UART4 base address */ +#define USART5 (USART_BASE + 0x0000D000U) /*!< USART5 base address */ +#define UART6 (USART_BASE + 0x00003400U) /*!< UART6 base address */ +#define UART7 (USART_BASE + 0x00003800U) /*!< UART7 base address */ + +/* registers definitions */ +#define USART_CTL0(usartx) REG32((usartx) + 0x00000000U) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x00000004U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x00000008U) /*!< USART control register 2 */ +#define USART_BAUD(usartx) REG32((usartx) + 0x0000000CU) /*!< USART baud rate generator register */ +#define USART_GP(usartx) REG32((usartx) + 0x00000010U) /*!< USART prescaler and guard time configuration register */ +#define USART_RT(usartx) REG32((usartx) + 0x00000014U) /*!< USART receiver timeout register */ +#define USART_CMD(usartx) REG32((usartx) + 0x00000018U) /*!< USART command register */ +#define USART_STAT(usartx) REG32((usartx) + 0x0000001CU) /*!< USART status register */ +#define USART_INTC(usartx) REG32((usartx) + 0x00000020U) /*!< USART interrupt status clear register */ +#define USART_RDATA(usartx) REG32((usartx) + 0x00000024U) /*!< USART receive data register */ +#define USART_TDATA(usartx) REG32((usartx) + 0x00000028U) /*!< USART transmit data register */ +#define USART_CHC(usartx) REG32((usartx) + 0x000000C0U) /*!< USART coherence control register */ +#define USART_FCS(usartx) REG32((usartx) + 0x000000D0U) /*!< USART FIFO control and status register */ + +/* bits definitions */ +/* USARTx_CTL0 */ +#define USART_CTL0_UEN BIT(0) /*!< enable USART */ +#define USART_CTL0_UESM BIT(1) /*!< enable USART in deep-sleep mode */ +#define USART_CTL0_REN BIT(2) /*!< enable receiver */ +#define USART_CTL0_TEN BIT(3) /*!< enable transmitter */ +#define USART_CTL0_IDLEIE BIT(4) /*!< enable idle line detected interrupt */ +#define USART_CTL0_RBNEIE BIT(5) /*!< enable read data buffer not empty interrupt and overrun error interrupt (when FIFO is disabled) */ +#define USART_CTL0_RFNEIE BIT(5) /*!< enable receive FIFO not empty interrupt and overrun error interrupt (when FIFO is enabled) */ +#define USART_CTL0_TCIE BIT(6) /*!< enable transmission complete interrupt */ +#define USART_CTL0_TBEIE BIT(7) /*!< enable transmitter register empty interrupt (when FIFO is disabled) */ +#define USART_CTL0_TFNFIE BIT(7) /*!< enable transmit FIFO not full interrupt (when FIFO is enabled) */ +#define USART_CTL0_PERRIE BIT(8) /*!< enable parity error interrupt */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< enable parity control */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL0 BIT(12) /*!< word length 0 */ +#define USART_CTL0_MEN BIT(13) /*!< enable mute mode */ +#define USART_CTL0_AMIE0 BIT(14) /*!< enable address 0 character match interrupt */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_DED BITS(16,20) /*!< enable driver deassertion time */ +#define USART_CTL0_DEA BITS(21,25) /*!< enable driver assertion time */ +#define USART_CTL0_RTIE BIT(26) /*!< enable receiver timeout interrupt */ +#define USART_CTL0_EBIE BIT(27) /*!< enable end of block interrupt */ +#define USART_CTL0_WL1 BIT(28) /*!< word length 1 */ +#define USART_CTL0_AMIE1 BIT(31) /*!< enable address 1 character match interrupt */ + +/* USARTx_CTL1 */ +#define USART_CTL1_AMEN0 BIT(0) /*!< enable address 0 match mode */ +#define USART_CTL1_ADDM0 BIT(4) /*!< address 0 detection mode */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< enable LIN break detection interrupt */ +#define USART_CTL1_CLEN BIT(8) /*!< last bit clock pulse */ +#define USART_CTL1_CPH BIT(9) /*!< clock phase */ +#define USART_CTL1_CPL BIT(10) /*!< clock polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< enable ck pin */ +#define USART_CTL1_STB BITS(12,13) /*!< stop bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< enable LIN mode */ +#define USART_CTL1_STRP BIT(15) /*!< swap TX/RX pins */ +#define USART_CTL1_RINV BIT(16) /*!< RX pin level inversion */ +#define USART_CTL1_TINV BIT(17) /*!< TX pin level inversion */ +#define USART_CTL1_DINV BIT(18) /*!< data bit level inversion */ +#define USART_CTL1_MSBF BIT(19) /*!< most significant bit first */ +#define USART_CTL1_RTEN BIT(23) /*!< enable receiver timeout */ +#define USART_CTL1_ADDR0 BITS(24,31) /*!< address 0 of the USART terminal */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< enable error interrupt in multibuffer communication */ +#define USART_CTL2_IREN BIT(1) /*!< enable IrDA mode */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< enable half-duplex */ +#define USART_CTL2_NKEN BIT(4) /*!< enable NACK in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< enable smartcard mode */ +#define USART_CTL2_DENR BIT(6) /*!< enable DMA for reception */ +#define USART_CTL2_DENT BIT(7) /*!< enable DMA for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< enable RTS */ +#define USART_CTL2_CTSEN BIT(9) /*!< enable CTS */ +#define USART_CTL2_CTSIE BIT(10) /*!< enable CTS interrupt */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit mode */ +#define USART_CTL2_OVRD BIT(12) /*!< disable overrun */ +#define USART_CTL2_DDRE BIT(13) /*!< disable DMA on reception error */ +#define USART_CTL2_DEM BIT(14) /*!< enable driver mode */ +#define USART_CTL2_DEP BIT(15) /*!< enable driver polarity mode */ +#define USART_CTL2_AMEN1 BIT(16) /*!< enable address 1 match mode */ +#define USART_CTL2_SCRTNUM BITS(17,19) /*!< smartcard auto-retry number */ +#define USART_CTL2_WUM BITS(20,21) /*!< wakeup mode from deep-sleep mode */ +#define USART_CTL2_WUIE BIT(22) /*!< enable wakeup from deep-sleep mode interrupt */ +#define USART_CTL2_ADDM1 BIT(23) /*!< address 1 detection mode */ +#define USART_CTL2_ADDR1 BITS(24,31) /*!< address 1 of the USART terminal */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer of baud-rate divider */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_CMD */ +#define USART_CMD_SBKCMD BIT(1) /*!< send break command */ +#define USART_CMD_MMCMD BIT(2) /*!< mute mode command */ +#define USART_CMD_RXFCMD BIT(3) /*!< receive data flush command */ +#define USART_CMD_TXFCMD BIT(4) /*!< transmit data flush request */ + +/* USARTx_STAT */ +#define USART_STAT_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT_IDLEF BIT(4) /*!< idle line detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty(when FIFO is disabled) */ +#define USART_STAT_RFNE BIT(5) /*!< receive FIFO not empty(when FIFO is enabled) */ +#define USART_STAT_TC BIT(6) /*!< transmission completed */ +#define USART_STAT_TBE BIT(7) /*!< transmit data register empty(when FIFO is disabled) */ +#define USART_STAT_TFNF BIT(7) /*!< transmit FIFO not full(when FIFO is enabled) */ +#define USART_STAT_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT_CTSF BIT(9) /*!< CTS change flag */ +#define USART_STAT_CTS BIT(10) /*!< CTS level */ +#define USART_STAT_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT_AMF1 BIT(13) /*!< address 1 character match flag */ +#define USART_STAT_BSY BIT(16) /*!< busy flag */ +#define USART_STAT_AMF0 BIT(17) /*!< address 0 character match flag */ +#define USART_STAT_SBF BIT(18) /*!< send break flag */ +#define USART_STAT_RWU BIT(19) /*!< receiver wakeup from mute mode */ +#define USART_STAT_WUF BIT(20) /*!< wakeup from deep-sleep mode flag */ +#define USART_STAT_TEA BIT(21) /*!< transmit enable acknowledge flag */ +#define USART_STAT_REA BIT(22) /*!< receive enable acknowledge flag */ + +/* USARTx_INTC */ +#define USART_INTC_PEC BIT(0) /*!< clear parity error */ +#define USART_INTC_FEC BIT(1) /*!< clear frame error flag */ +#define USART_INTC_NEC BIT(2) /*!< clear noise detected */ +#define USART_INTC_OREC BIT(3) /*!< clear overrun error */ +#define USART_INTC_IDLEC BIT(4) /*!< clear idle line detected */ +#define USART_INTC_TCC BIT(6) /*!< clear transmission complete */ +#define USART_INTC_LBDC BIT(8) /*!< clear LIN break detected */ +#define USART_INTC_CTSC BIT(9) /*!< clear CTS change */ +#define USART_INTC_RTC BIT(11) /*!< clear receiver timeout */ +#define USART_INTC_EBC BIT(12) /*!< clear end of timeout */ +#define USART_INTC_AMC1 BIT(16) /*!< clear address 1 character match */ +#define USART_INTC_AMC0 BIT(17) /*!< clear address 0 character match */ +#define USART_INTC_WUC BIT(20) /*!< clear wakeup from deep-sleep mode */ + +/* USARTx_RDATA */ +#define USART_RDATA_RDATA BITS(0,9) /*!< receive data value */ + +/* USARTx_TDATA */ +#define USART_TDATA_TDATA BITS(0,9) /*!< transmit data value */ + +/* USARTx_CHC */ +#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ +#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ + +/* USARTx_FCS */ +#define USART_FCS_ELNACK BIT(0) /*!< early NACK when smartcard mode is selected */ +#define USART_FCS_RFCNT3_4 BITS(1,2) /*!< receive FIFO counter number RFCNT[4:3] */ +#define USART_FCS_RFT BIT(4) /*!< receive FIFO threshold flag */ +#define USART_FCS_TFT BIT(5) /*!< transmit FIFO threshold flag */ +#define USART_FCS_TFE BIT(6) /*!< transmit FIFO empty flag */ +#define USART_FCS_TFF BIT(7) /*!< transmit FIFO full flag */ +#define USART_FCS_FEN BIT(8) /*!< enable FIFO */ +#define USART_FCS_RFFIE BIT(9) /*!< enable receive FIFO full interrupt */ +#define USART_FCS_RFE BIT(10) /*!< receive FIFO empty flag */ +#define USART_FCS_RFF BIT(11) /*!< receive FIFO full flag */ +#define USART_FCS_RFCNT0_2 BITS(12,14) /*!< receive FIFO counter number RFCNT[2:0] */ +#define USART_FCS_RFFIF BIT(15) /*!< receive FIFO full interrupt flag */ +#define USART_FCS_RFTCFG BITS(16,18) /*!< receive FIFO threshold configuration */ +#define USART_FCS_TFTCFG BITS(19,21) /*!< transmit FIFO threshold configuration */ +#define USART_FCS_RFTIF BIT(22) /*!< receive FIFO threshold interrupt flag */ +#define USART_FCS_TFEIF BIT(24) /*!< transmit FIFO empty interrupt flag */ +#define USART_FCS_TFTIF BIT(25) /*!< transmit FIFO threshold interrupt flag */ +#define USART_FCS_TFEC BIT(26) /*!< clear transmit FIFO empty flag */ +#define USART_FCS_RFTIE BIT(27) /*!< enable receive FIFO threshold interrupt */ +#define USART_FCS_TFTIE BIT(29) /*!< enable transmit FIFO threshold interrupt */ +#define USART_FCS_TFEIE BIT(31) /*!< enable transmit FIFO empty interrupt */ + +/* constants definitions */ +/* define the USART bit position and its register index offset */ +#define USART_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define USART_REG_VAL(usartx, offset) (REG32((usartx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define USART_REG_VAL2(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 22))) +#define USART_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define USART_CTL0_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET ((uint32_t)0x00000004U) /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET ((uint32_t)0x00000008U) /*!< CTL2 register offset */ +#define USART_STAT_REG_OFFSET ((uint32_t)0x0000001CU) /*!< STAT register offset */ +#define USART_CHC_REG_OFFSET ((uint32_t)0x000000C0U) /*!< CHC register offset */ +#define USART_FCS_REG_OFFSET ((uint32_t)0x000000D0U) /*!< FCS register offset */ + +/* USART flags */ +typedef enum{ + /* flags in STAT register */ + USART_FLAG_REA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 22U), /*!< receive enable acknowledge flag */ + USART_FLAG_TEA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 21U), /*!< transmit enable acknowledge flag */ + USART_FLAG_WU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 20U), /*!< wakeup from Deep-sleep mode flag */ + USART_FLAG_RWU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 19U), /*!< receiver wakeup from mute mode */ + USART_FLAG_SB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 18U), /*!< send break flag */ + USART_FLAG_AM0 = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 17U), /*!< ADDR0 match flag */ + USART_FLAG_BSY = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 16U), /*!< busy flag */ + USART_FLAG_AM1 = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 13U), /*!< ADDR1 match flag */ + USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout flag */ + USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 10U), /*!< CTS level */ + USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit data buffer empty(when FIFO is disabled) */ + USART_FLAG_TFNF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit FIFO not full(when FIFO is enabled) */ + USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty(when FIFO is disabled) */ + USART_FLAG_RFNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< receive FIFO not empty(when FIFO is enabled) */ + USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 0U), /*!< parity error flag */ + /* flags in CHC register */ + USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U), /*!< early parity error flag */ + /* flags in FCS register */ + USART_FLAG_RFF = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 11U), /*!< receive FIFO full flag */ + USART_FLAG_RFE = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 10U), /*!< receive FIFO empty flag */ + USART_FLAG_TFF = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 7U), /*!< transmit FIFO full flag */ + USART_FLAG_TFE = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 6U), /*!< transmit FIFO empty flag */ + USART_FLAG_TFT = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 5U), /*!< transmit FIFO threshold reach flag */ + USART_FLAG_RFT = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 4U) /*!< receive FIFO threshold reach flag */ +}usart_flag_enum; + +/* USART interrupt flags */ +typedef enum +{ + /* interrupt flags in CTL0 register */ + USART_INT_FLAG_AM1 = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 31U, USART_STAT_REG_OFFSET, 13U), /*!< address 1 match interrupt and flag */ + USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 27U, USART_STAT_REG_OFFSET, 12U), /*!< end of block interrupt and flag */ + USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 26U, USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout interrupt and flag */ + USART_INT_FLAG_AM0 = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 14U, USART_STAT_REG_OFFSET, 17U), /*!< address 0 match interrupt and flag */ + USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT_REG_OFFSET, 0U), /*!< parity error interrupt and flag */ + USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag(when FIFO is disabled) */ + USART_INT_FLAG_TFNF = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U), /*!< transmit FIFO not full interrupt and flag(when FIFO is enabled) */ + USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 6U), /*!< transmission complete interrupt and flag */ + USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and flag(when FIFO is disabled) */ + USART_INT_FLAG_RFNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U), /*!< receive FIFO not empty interrupt and flag(when FIFO is enabled) */ + USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag(when FIFO is disabled) */ + USART_INT_FLAG_RFNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< receive FIFO not empty interrupt and overrun error flag(when FIFO is enabled) */ + USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected interrupt and flag */ + /* interrupt flags in CTL1 register */ + USART_INT_FLAG_LBD = USART_REGIDX_BIT2(USART_CTL1_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected interrupt and flag */ + /* interrupt flags in CTL2 register */ + USART_INT_FLAG_WU = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 22U, USART_STAT_REG_OFFSET, 20U), /*!< wakeup from deep-sleep mode interrupt and flag */ + USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT_REG_OFFSET, 9U), /*!< CTS interrupt and flag */ + USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 2U), /*!< error interrupt and noise error flag */ + USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 3U), /*!< error interrupt and overrun error */ + USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 1U), /*!< error interrupt and frame error flag */ + /* interrupt flags in FCS register */ + USART_INT_FLAG_TFT = USART_REGIDX_BIT2(USART_FCS_REG_OFFSET, 29U, USART_FCS_REG_OFFSET, 25U), /*!< transmit FIFO threshold reach interrupt and flag */ + USART_INT_FLAG_TFE = USART_REGIDX_BIT2(USART_FCS_REG_OFFSET, 31U, USART_FCS_REG_OFFSET, 24U), /*!< transmit FIFO empty interrupt and flag */ + USART_INT_FLAG_RFT = USART_REGIDX_BIT2(USART_FCS_REG_OFFSET, 27U, USART_FCS_REG_OFFSET, 22U), /*!< receive FIFO threshold reach interrupt and flag */ + USART_INT_FLAG_RFF = USART_REGIDX_BIT2(USART_FCS_REG_OFFSET, 9U, USART_FCS_REG_OFFSET, 15U) /*!< receive FIFO full interrupt and flag */ +}usart_interrupt_flag_enum; + +/* enable or disable USART interrupt */ +typedef enum +{ + /* interrupt in CTL0 register */ + USART_INT_AM1 = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 31U), /*!< address 1 match interrupt */ + USART_INT_EB = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 27U), /*!< end of block interrupt */ + USART_INT_RT = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 26U), /*!< receiver timeout interrupt */ + USART_INT_AM0 = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 14U), /*!< address 0 match interrupt */ + USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ + USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt(when FIFO is disabled) */ + USART_INT_TFNF = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmit FIFO not full interrupt(when FIFO is enabled) */ + USART_INT_TC = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 6U), /*!< transmission complete interrupt */ + USART_INT_RBNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and overrun error interrupt(when FIFO is disabled) */ + USART_INT_RFNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U), /*!< receive FIFO not empty interrupt and overrun error interrupt(when FIFO is enabled) */ + USART_INT_IDLE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt */ + /* interrupt in CTL1 register */ + USART_INT_LBD = USART_REGIDX_BIT(USART_CTL1_REG_OFFSET, 6U), /*!< LIN break detected interrupt */ + /* interrupt in CTL2 register */ + USART_INT_WU = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 22U), /*!< wakeup from deep-sleep mode interrupt */ + USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */ + /* interrupt in FCS register */ + USART_INT_TFE = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 31U), /*!< transmit FIFO empty interrupt */ + USART_INT_TFT = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 29U), /*!< transmit FIFO threshold interrupt */ + USART_INT_RFT = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 27U), /*!< receive FIFO threshold interrupt */ + USART_INT_RFF = USART_REGIDX_BIT(USART_FCS_REG_OFFSET, 9U) /*!< receive FIFO full interrupt */ +}usart_interrupt_enum; + +/* configure USART invert */ +typedef enum { + /* data bit level inversion */ + USART_DINV_ENABLE, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ + /* swap TX/RX pins */ + USART_SWAP_ENABLE, /*!< swap TX/RX pins */ + USART_SWAP_DISABLE /*!< not swap TX/RX pins */ +}usart_invert_enum; + +/* configure USART receiver */ +#define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ +#define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ + +/* configure USART transmitter */ +#define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) +#define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ +#define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ + +/* USART parity bits definitions */ +#define CTL0_PM(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define USART_PM_NONE CTL0_PM(0) /*!< no parity */ +#define USART_PM_EVEN CTL0_PM(2) /*!< even parity */ +#define USART_PM_ODD CTL0_PM(3) /*!< odd parity */ + +/* USART wakeup method in mute mode */ +#define CTL0_WM(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_WM_IDLE CTL0_WM(0) /*!< idle line */ +#define USART_WM_ADDR CTL0_WM(1) /*!< address match */ + +/* USART word length definitions */ +#define CTL0_WL(regval1, regval2) ((BIT(28) & ((uint32_t)(regval1) << 28)) | (BIT(12) & ((uint32_t)(regval2) << 12))) +#define USART_WL_8BIT CTL0_WL(0, 0) /*!< 8 bits */ +#define USART_WL_9BIT CTL0_WL(0, 1) /*!< 9 bits */ +#define USART_WL_7BIT CTL0_WL(1, 0) /*!< 7 bits */ +#define USART_WL_10BIT CTL0_WL(1, 1) /*!< 10 bits */ + +/* USART oversample mode */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< oversampling by 8 */ +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< oversampling by 16 */ + +/* USART LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits break detection */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits break detection */ + +/* USART last bit clock pulse */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< clock pulse of the last data bit (MSB) is not output to the CK pin */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< clock pulse of the last data bit (MSB) is output to the CK pin */ + +/* USART clock phase */ +#define CTL1_CPH(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CPH_1CK CTL1_CPH(0) /*!< first clock transition is the first data capture edge */ +#define USART_CPH_2CK CTL1_CPH(1) /*!< second clock transition is the first data capture edge */ + +/* USART clock polarity */ +#define CTL1_CPL(regval) (BIT(10) & ((uint32_t)(regval) << 10)) +#define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ +#define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ + +/* USART stop bits definitions */ +#define CTL1_STB(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define USART_STB_1BIT CTL1_STB(0) /*!< 1 bit */ +#define USART_STB_0_5BIT CTL1_STB(1) /*!< 0.5 bit */ +#define USART_STB_2BIT CTL1_STB(2) /*!< 2 bits */ +#define USART_STB_1_5BIT CTL1_STB(3) /*!< 1.5 bits */ + +/* USART data is transmitted/received with the LSB/MSB first */ +#define CTL1_MSBF(regval) (BIT(19) & ((uint32_t)(regval) << 19)) +#define USART_MSBF_LSB CTL1_MSBF(0) /*!< LSB first */ +#define USART_MSBF_MSB CTL1_MSBF(1) /*!< MSB first */ + +/* enable USART IrDA low-power */ +#define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ +#define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ + +/* USART DMA request for receive configure */ +#define CTL2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_RECEIVE_DMA_ENABLE CTL2_DENR(1) /*!< DMA request enable for reception */ +#define USART_RECEIVE_DMA_DISABLE CTL2_DENR(0) /*!< DMA request disable for reception */ + +/* USART DMA request for transmission configure */ +#define CTL2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_TRANSMIT_DMA_ENABLE CTL2_DENT(1) /*!< DMA request enable for transmission */ +#define USART_TRANSMIT_DMA_DISABLE CTL2_DENT(0) /*!< DMA request disable for transmission */ + +/* configure USART RTS hardware flow control */ +#define CTL2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CTL2_RTSEN(1) /*!< RTS hardware flow control enabled */ +#define USART_RTS_DISABLE CTL2_RTSEN(0) /*!< RTS hardware flow control disabled */ + +/* configure USART CTS hardware flow control */ +#define CTL2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CTL2_CTSEN(1) /*!< CTS hardware flow control enabled */ +#define USART_CTS_DISABLE CTL2_CTSEN(0) /*!< CTS hardware flow control disabled */ + +/* configure USART one sample bit method */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1BIT CTL2_OSB(1) /*!< 1 sample bit */ +#define USART_OSB_3BIT CTL2_OSB(0) /*!< 3 sample bits */ + +/* USART driver enable polarity mode */ +#define CTL2_DEP(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_DEP_HIGH CTL2_DEP(0) /*!< DE signal is active high */ +#define USART_DEP_LOW CTL2_DEP(1) /*!< DE signal is active low */ + +/* USART wakeup mode from deep-sleep mode */ +#define CTL2_WUM(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define USART_WUM_ADDR CTL2_WUM(0) /*!< WUF active on address match */ +#define USART_WUM_STARTB CTL2_WUM(2) /*!< WUF active on start bit */ +#define USART_WUM_RBNE CTL2_WUM(3) /*!< WUF active on RBNE */ + +/* USART address 0 detection mode */ +#define CTL1_ADDM0(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define USART_ADDM0_4BIT CTL1_ADDM0(0) /*!< 4-bit address detection */ +#define USART_ADDM0_FULLBIT CTL1_ADDM0(1) /*!< full-bit address detection */ + +/* USART address 1 detection mode */ +#define CTL2_ADDM1(regval) (BIT(23) & ((uint32_t)(regval) << 23)) +#define USART_ADDM1_4BIT CTL2_ADDM1(0) /*!< 4-bit address detection */ +#define USART_ADDM1_FULLBIT CTL2_ADDM1(1) /*!< full-bit address detection */ + +/* USART hardware flow control coherence mode */ +#define CHC_HCM(regval) (BIT(0) & ((uint32_t)(regval) << 0)) +#define USART_HCM_NONE CHC_HCM(0) /*!< nRTS signal equals to the rxne status register */ +#define USART_HCM_EN CHC_HCM(1) /*!< nRTS signal is set when the last data bit has been sampled */ + +/* configure USART transmit FIFO threshold */ +#define FCS_TFTCFG(regval) (BITS(19,21) & ((uint32_t)(regval) << 19)) +#define USART_TFTCFG_THRESHOLD_1_8 FCS_TFTCFG(0) /*!< transmit FIFO reaches 1/8 of its depth */ +#define USART_TFTCFG_THRESHOLD_1_4 FCS_TFTCFG(1) /*!< transmit FIFO reaches 1/4 of its depth */ +#define USART_TFTCFG_THRESHOLD_1_2 FCS_TFTCFG(2) /*!< transmit FIFO reaches 1/2 of its depth */ +#define USART_TFTCFG_THRESHOLD_3_4 FCS_TFTCFG(3) /*!< transmit FIFO reaches 3/4 of its depth */ +#define USART_TFTCFG_THRESHOLD_7_8 FCS_TFTCFG(4) /*!< transmit FIFO reaches 7/8 of its depth */ +#define USART_TFTCFG_THRESHOLD_EMPTY FCS_TFTCFG(5) /*!< transmit FIFO becomes empty */ + +/* configure USART receive FIFO threshold */ +#define FCS_RFTCFG(regval) (BITS(16,18) & ((uint32_t)(regval) << 16)) +#define USART_RFTCFG_THRESHOLD_1_8 FCS_RFTCFG(0) /*!< receive FIFO reaches 1/8 of its depth */ +#define USART_RFTCFG_THRESHOLD_1_4 FCS_RFTCFG(1) /*!< receive FIFO reaches 1/4 of its depth */ +#define USART_RFTCFG_THRESHOLD_1_2 FCS_RFTCFG(2) /*!< receive FIFO reaches 1/2 of its depth */ +#define USART_RFTCFG_THRESHOLD_3_4 FCS_RFTCFG(3) /*!< receive FIFO reaches 3/4 of its depth */ +#define USART_RFTCFG_THRESHOLD_7_8 FCS_RFTCFG(4) /*!< receive FIFO reaches 7/8 of its depth */ +#define USART_RFTCFG_THRESHOLD_FULL FCS_RFTCFG(5) /*!< receive FIFO becomes full */ + +/* function declarations */ +/* initialization functions */ +/* reset USART */ +void usart_deinit(uint32_t usart_periph); +/* configure USART baud rate value */ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval); +/* configure USART parity function */ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg); +/* configure USART word length */ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen); +/* configure USART stop bit length */ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen); +/* enable USART */ +void usart_enable(uint32_t usart_periph); +/* disable USART */ +void usart_disable(uint32_t usart_periph); +/* configure USART transmitter */ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig); +/* configure USART receiver */ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig); + +/* USART normal mode communication */ +/* data is transmitted/received with the LSB/MSB first */ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf); +/* USART inverted configure */ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara); +/* enable the USART overrun function */ +void usart_overrun_enable(uint32_t usart_periph); +/* disable the USART overrun function */ +void usart_overrun_disable(uint32_t usart_periph); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* configure sample bit method */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb); +/* enable receiver timeout */ +void usart_receiver_timeout_enable(uint32_t usart_periph); +/* disable receiver timeout */ +void usart_receiver_timeout_disable(uint32_t usart_periph); +/* configure receiver timeout threshold */ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout); +/* USART transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint16_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); +/* enable USART command */ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype); + +/* multi-processor communication */ +/* enable address 0 match mode */ +void usart_address_0_match_mode_enable(uint32_t usart_periph); +/* disable address 0 match mode */ +void usart_address_0_match_mode_disable(uint32_t usart_periph); +/* enable address 1 match mode */ +void usart_address_1_match_mode_enable(uint32_t usart_periph); +/* disable address 1 match mode */ +void usart_address_1_match_mode_disable(uint32_t usart_periph); +/* configure address 0 of the USART */ +void usart_address_0_config(uint32_t usart_periph, uint8_t addr); +/* configure address 1 of the USART */ +void usart_address_1_config(uint32_t usart_periph, uint8_t addr); +/* configure address 0 detection mode */ +void usart_address_0_detection_mode_config(uint32_t usart_periph, uint32_t addmod); +/* configure address 1 detection mode */ +void usart_address_1_detection_mode_config(uint32_t usart_periph, uint32_t addmod); +/* enable mute mode */ +void usart_mute_mode_enable(uint32_t usart_periph); +/* disable mute mode */ +void usart_mute_mode_disable(uint32_t usart_periph); +/* configure wakeup method in mute mode */ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod); + +/* LIN mode communication */ +/* enable LIN mode */ +void usart_lin_mode_enable(uint32_t usart_periph); +/* disable LIN mode */ +void usart_lin_mode_disable(uint32_t usart_periph); +/* LIN break detection length */ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen); + +/* half-duplex communication */ +/* enable half-duplex mode */ +void usart_halfduplex_enable(uint32_t usart_periph); +/* disable half-duplex mode */ +void usart_halfduplex_disable(uint32_t usart_periph); + +/* synchronous communication */ +/* enable clock */ +void usart_clock_enable(uint32_t usart_periph); +/* disable clock */ +void usart_clock_disable(uint32_t usart_periph); +/* configure USART synchronous mode parameters */ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl); + +/* smartcard communication */ +/* configure guard time value in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat); +/* enable smartcard mode */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* disable smartcard mode */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* enable NACK in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* disable NACK in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* enable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph); +/* disable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph); +/* configure smartcard auto-retry number */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); +/* configure block length */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler in USART IrDA low-power or SmartCard mode */ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc); +/* configure IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); + +/* hardware flow communication */ +/* configure hardware flow control RTS */ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig); +/* configure hardware flow control CTS */ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig); + +/* coherence control */ +/* configure hardware flow control coherence mode */ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm); + +/* enable RS485 driver */ +void usart_rs485_driver_enable(uint32_t usart_periph); +/* disable RS485 driver */ +void usart_rs485_driver_disable(uint32_t usart_periph); +/* configure driver enable assertion time */ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime); +/* configure driver enable de-assertion time */ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime); +/* configure driver enable polarity mode */ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep); + +/* USART DMA */ +/* configure USART DMA reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd); +/* configure USART DMA transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd); +/* disable DMA on reception error */ +void usart_reception_error_dma_disable(uint32_t usart_periph); +/* enable DMA on reception error */ +void usart_reception_error_dma_enable(uint32_t usart_periph); + +/* enable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_enable(uint32_t usart_periph); +/* disable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_disable(uint32_t usart_periph); +/* configure the USART wakeup mode from deep-sleep mode */ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum); + +/* USART FIFO */ +/* enable FIFO */ +void usart_fifo_enable(uint32_t usart_periph); +/* disable FIFO */ +void usart_fifo_disable(uint32_t usart_periph); +/* configure transmit FIFO threshold */ +void usart_transmit_fifo_threshold_config(uint32_t usart_periph, uint32_t txthreshold); +/* configure receive FIFO threshold */ +void usart_receive_fifo_threshold_config(uint32_t usart_periph, uint32_t rxthreshold); +/* read receive FIFO counter number */ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph); + +/* flag & interrupt functions */ +/* get flag in STAT/FCS register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear USART status */ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt); +/* get USART interrupt and flag status */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); +/* clear USART interrupt flag */ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); + +#endif /* GD32H7XX_USART_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_vref.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_vref.h new file mode 100644 index 0000000000..b5ce8070ad --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_vref.h @@ -0,0 +1,90 @@ +/*! + \file gd32h7xx_vref.h + \brief definitions for the VREF + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_VREF_H +#define GD32H7XX_VREF_H + +#include "gd32h7xx.h" + +/* VREF definitions */ +#define VREF VREF_BASE /*!< VREF base address */ + +/* registers definitions */ +#define VREF_CS REG32(VREF + 0x00000000U) /*!< VREF Control and status register */ +#define VREF_CALIB REG32(VREF + 0x00000004U) /*!< VREF Calibration register */ + +/* bits definitions */ +/* VREF_CS */ +#define VREF_CS_VREFEN BIT(0) /*!< VREF enable */ +#define VREF_CS_HIPM BIT(1) /*!< High impedance mode */ +#define VREF_CS_VREFRDY BIT(3) /*!< VREF ready */ +#define VREF_CS_VREFS BITS(4,5) /*!< VREF voltage reference select */ + +/* VREF_CALIB */ +#define VREF_CALIB_VREFCAL BITS(0,5) /*!< VREF calibration */ + +/* constants definitions */ +/* VREF bit devinitions */ +#define VREF_EN VREF_CS_VREFEN /*!< VREF enable */ +#define VREF_HIGH_IMPEDANCE_MODE VREF_CS_HIPM /*!< High impedance mode */ +#define VREF_RDY VREF_CS_VREFRDY /*!< VREF ready */ + +/* VREF voltage reference select */ +#define CS_VREFS(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define VREF_VOLTAGE_SEL_2_5V CS_VREFS(0) /*!< VREF voltage reference select 2.5 V */ +#define VREF_VOLTAGE_SEL_2_048V CS_VREFS(1) /*!< VREF voltage reference select 2.048 V */ +#define VREF_VOLTAGE_SEL_1_8V CS_VREFS(2) /*!< VREF voltage reference select 1.8 V */ +#define VREF_VOLTAGE_SEL_1_5V CS_VREFS(3) /*!< VREF voltage reference select 1.5 V */ + +/* function declarations */ +/* deinitialize the VREF */ +void vref_deinit(void); +/* enable VREF */ +void vref_enable(void); +/* disable VREF */ +void vref_disable(void); +/* enable VREF high impendance mode */ +void vref_high_impedance_mode_enable(void); +/* disable VREF high impendance mode */ +void vref_high_impedance_mode_disable(void); +/* get the status of VREF */ +FlagStatus vref_status_get(void); +/* select the VREF voltage reference */ +void vref_voltage_select(uint32_t vref_voltage); +/* set the calibration value of VREF */ +void vref_calib_value_set(uint8_t value); +/* get the calibration value of VREF */ +uint8_t vref_calib_value_get(void); + +#endif /* GD32H7XX_VREF_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_wwdgt.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_wwdgt.h new file mode 100644 index 0000000000..a721911a5e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Include/gd32h7xx_wwdgt.h @@ -0,0 +1,86 @@ +/*! + \file gd32h7xx_wwdgt.h + \brief definitions for the WWDGT + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32H7XX_WWDGT_H +#define GD32H7XX_WWDGT_H + +#include "gd32h7xx.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00000000U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x00000004U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x00000008U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC BITS(7,8) /*!< WWDGT prescaler divider value */ +#define WWDGT_CFG_EWIE BIT(9) /*!< WWDGT early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< WWDGT early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval) (BITS(7,8) & ((uint32_t)(regval) << 7U)) /*!< write value to WWDGT_CFG_PSC bit field */ +#define WWDGT_CFG_PSC_DIV1 ((uint32_t)CFG_PSC(0)) /*!< the time base of WWDGT = (PCLK3/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 ((uint32_t)CFG_PSC(1)) /*!< the time base of WWDGT = (PCLK3/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 ((uint32_t)CFG_PSC(2)) /*!< the time base of WWDGT = (PCLK3/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 ((uint32_t)CFG_PSC(3)) /*!< the time base of WWDGT = (PCLK3/4096)/8 */ + +/* function declarations */ +/* reset the WWDGT configuration */ +void wwdgt_deinit(void); +/* start the WWDGT counter */ +void wwdgt_enable(void); + +/* configure the WWDGT counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); + +#endif /* GD32H7XX_WWDGT_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_adc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_adc.c new file mode 100644 index 0000000000..9f3400649e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_adc.c @@ -0,0 +1,1300 @@ +/*! + \file gd32h7xx_adc.c + \brief ADC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_adc.h" + +/* discontinuous mode macro */ +#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U) + +/* ADC regular channel macro */ +#define ADC_REGULAR_CHANNEL_RANK_ONE ((uint8_t)1U) +#define ADC_REGULAR_CHANNEL_RANK_THREE ((uint8_t)3U) +#define ADC_REGULAR_CHANNEL_RANK_FIVE ((uint8_t)5U) +#define ADC_REGULAR_CHANNEL_RANK_SEVEN ((uint8_t)7U) +#define ADC_REGULAR_CHANNEL_RANK_NINE ((uint8_t)9U) +#define ADC_REGULAR_CHANNEL_RANK_ELEVEN ((uint8_t)11U) +#define ADC_REGULAR_CHANNEL_RANK_THIRTEEN ((uint8_t)13U) +#define ADC_REGULAR_CHANNEL_RANK_FIFTEEN ((uint8_t)15U) +#define ADC_REGULAR_CHANNEL_RANK_SIXTEEN ((uint8_t)16U) +#define ADC_REGULAR_CHANNEL_SHIFT_LENGTH ((uint8_t)16U) + +/* ADC inserted channel macro */ +#define ADC_INSERTED_CHANNEL_RANK_ONE ((uint8_t)1U) +#define ADC_INSERTED_CHANNEL_RANK_THREE ((uint8_t)3U) +#define ADC_INSERTED_CHANNEL_RANK_FOUR ((uint8_t)4U) +#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)16U) + +/* ADC inserted channel offset macro */ +#define ADC_OFFSET_LENGTH ((uint8_t)3U) +#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U) + +/* ADC IOFF0 reg offset address macro */ +#define ADC_IOFF0_OFFSET ((uint32_t)0x0000000CU) + +/* external trigger mode macro */ +#define REGULAR_TRIGGER_MODE ((uint8_t)28U) +#define INSERTED_TRIGGER_MODE ((uint8_t)20U) + +/*! + \brief reset ADC + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_deinit(uint32_t adc_periph) +{ + switch(adc_periph) { + case ADC0: + rcu_periph_reset_enable(RCU_ADC0RST); + rcu_periph_reset_disable(RCU_ADC0RST); + break; + case ADC1: + rcu_periph_reset_enable(RCU_ADC1RST); + rcu_periph_reset_disable(RCU_ADC1RST); + break; + case ADC2: + rcu_periph_reset_enable(RCU_ADC2RST); + rcu_periph_reset_disable(RCU_ADC2RST); + break; + default: + break; + } +} + +/*! + \brief configure the ADC clock + \param[in] adc_periph: ADCx, x=0,2 + \param[in] prescaler: configure ADCs prescaler ratio + only one parameter can be selected which is shown as below: + \arg ADC_CLK_SYNC_HCLK_DIV2: ADC sync clock mode HCLK div2 + \arg ADC_CLK_SYNC_HCLK_DIV4: ADC sync clock mode HCLK div4 + \arg ADC_CLK_SYNC_HCLK_DIV8: ADC sync clock mode HCLK div8 + \arg ADC_CLK_SYNC_HCLK_DIV10: ADC sync clock mode HCLK div10 + \arg ADC_CLK_SYNC_HCLK_DIV12: ADC sync clock mode HCLK div12 + \arg ADC_CLK_SYNC_HCLK_DIV14: ADC sync clock mode HCLK div14 + \arg ADC_CLK_SYNC_HCLK_DIV16: ADC sync clock mode HCLK div16 + \arg ADC_CLK_ASYNC_DIV1: ADC async clock mode div1 + \arg ADC_CLK_ASYNC_DIV2: ADC async clock mode div2 + \arg ADC_CLK_ASYNC_DIV4: ADC async clock mode div4 + \arg ADC_CLK_ASYNC_DIV6: ADC async clock mode div6 + \arg ADC_CLK_ASYNC_DIV8: ADC async clock mode div8 + \arg ADC_CLK_ASYNC_DIV10: ADC async clock mode div10 + \arg ADC_CLK_ASYNC_DIV12: ADC async clock mode div12 + \arg ADC_CLK_ASYNC_DIV16: ADC async clock mode div16 + \arg ADC_CLK_ASYNC_DIV32: ADC async clock mode div32 + \arg ADC_CLK_ASYNC_DIV64: ADC async clock mode div64 + \arg ADC_CLK_ASYNC_DIV128: ADC async clock mode div128 + \arg ADC_CLK_ASYNC_DIV256: ADC async clock mode div256 + \param[out] none + \retval none +*/ +void adc_clock_config(uint32_t adc_periph, uint32_t prescaler) +{ + if(ADC2 == adc_periph) { + ADC_SYNCCTL(ADC2) &= ~((uint32_t)(ADC_SYNCCTL_ADCCK | ADC_SYNCCTL_ADCSCK)); + ADC_SYNCCTL(ADC2) |= (uint32_t)prescaler; + } else { + ADC_SYNCCTL(ADC0) &= ~((uint32_t)(ADC_SYNCCTL_ADCCK | ADC_SYNCCTL_ADCSCK)); + ADC_SYNCCTL(ADC0) |= (uint32_t)prescaler; + } +} + +/*! + \brief enable or disable ADC special function + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] function: the function to config + only one parameter can be selected which is shown as below: + \arg ADC_SCAN_MODE: scan mode select + \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + if(RESET != (function & ADC_SCAN_MODE)) { + /* enable scan mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_SCAN_MODE; + } + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)) { + /* enable inserted channel group convert automatically */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_INSERTED_CHANNEL_AUTO; + } + if(RESET != (function & ADC_CONTINUOUS_MODE)) { + /* enable continuous mode */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CONTINUOUS_MODE; + } + } else { + if(RESET != (function & ADC_SCAN_MODE)) { + /* disable scan mode */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_SCAN_MODE); + } + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)) { + /* disable inserted channel group convert automatically */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_INSERTED_CHANNEL_AUTO); + } + if(RESET != (function & ADC_CONTINUOUS_MODE)) { + /* disable continuous mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CONTINUOUS_MODE); + } + } +} + +/*! + \brief configure ADC data alignment + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] data_alignment: data alignment select + only one parameter can be selected which is shown as below: + \arg ADC_DATAALIGN_RIGHT: LSB alignment + \arg ADC_DATAALIGN_LEFT: MSB alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment) +{ + if(ADC_DATAALIGN_RIGHT == data_alignment) { + /* LSB alignment */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL); + } else if(ADC_DATAALIGN_LEFT == data_alignment) { + /* MSB alignment */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_DAL; + } else { + /* illegal parameters */ + } +} + +/*! + \brief enable ADC interface + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_enable(uint32_t adc_periph) +{ + if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)) { + /* enable ADC */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_disable(uint32_t adc_periph) +{ + /* disable ADC */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON); +} + +/*! + \brief configure ADC calibration mode + \param[in] adc_periph: ADCx, x=0,1 + \param[in] clb_mode: calibration mode + only one parameter can be selected which is shown as below: + \arg ADC_CALIBRATION_OFFSET_MISMATCH: ADC calibration offset and mismatch mode + \arg ADC_CALIBRATION_OFFSET: ADC calibration offset mode + \param[out] none + \retval none +*/ +void adc_calibration_mode_config(uint32_t adc_periph, uint32_t clb_mode) +{ + if(ADC_CALIBRATION_OFFSET_MISMATCH == clb_mode) { + /* offset and mismatch mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_CALMOD); + } else if(ADC_CALIBRATION_OFFSET == clb_mode) { + /* offset mode */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_CALMOD; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure ADC calibration number + \param[in] adc_periph: ADCx, x=0,1 + \param[in] clb_num: calibration number + only one parameter can be selected which is shown as below: + \arg ADC_CALIBRATION_NUM1: calibrate once + \arg ADC_CALIBRATION_NUM2: calibrate twice + \arg ADC_CALIBRATION_NUM4: calibrate 4 times + \arg ADC_CALIBRATION_NUM8: calibrate 8 times + \arg ADC_CALIBRATION_NUM16: calibrate 16 times + \arg ADC_CALIBRATION_NUM32: calibrate 32 times + \param[out] none + \retval none +*/ +void adc_calibration_number(uint32_t adc_periph, uint32_t clb_num) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_CALNUM); + ADC_CTL1(adc_periph) |= (uint32_t)clb_num; +} + +/*! + \brief ADC calibration and reset calibration + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_calibration_enable(uint32_t adc_periph) +{ + /* reset the selected ADC calibration registers */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) { + } + /* enable ADC calibration process */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_CLB; + /* check the CLB bit state */ + while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) { + } +} + +/*! + \brief configure ADC resolution + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] resolution: ADC resolution + only one parameter can be selected which is shown as below: + \arg ADC_RESOLUTION_14B: 14-bit ADC resolution, for ADC0/ADC1 + \arg ADC_RESOLUTION_12B: 12-bit ADC resolution, for all ADCs + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution, for all ADCs + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution, for all ADCs + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution, only for ADC2 + \param[out] none + \retval none +*/ +void adc_resolution_config(uint32_t adc_periph, uint32_t resolution) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DRES); + + if(ADC2 == adc_periph) { + if(ADC_RESOLUTION_14B == resolution) { + /* illegal parameters */ + } else { + ADC_CTL0(adc_periph) |= (uint32_t)CTL0_DRES(resolution - 1U); + } + } else { + if(ADC_RESOLUTION_6B == resolution) { + /* illegal parameters */ + } else { + ADC_CTL0(adc_periph) |= (uint32_t)CTL0_DRES(resolution); + } + } +} + +/*! + \brief enable or disable ADC internal channels + \param[in] internal_channel: the internal channels + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_INTERNAL_TEMPSENSOR: temperature sensor channel + \arg ADC_CHANNEL_INTERNAL_VREFINT: vrefint channel + \arg ADC_CHANNEL_INTERNAL_VBAT: vbat channel + \arg ADC_CHANNEL_INTERNAL_HP_TEMPSENSOR: high-precision temperature sensor channel + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_internal_channel_config(uint32_t internal_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + ADC_CTL1(ADC2) |= (uint32_t)internal_channel; + } else { + ADC_CTL1(ADC2) &= ~((uint32_t)internal_channel); + } +} + +/*! + \brief enable DMA request + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(uint32_t adc_periph) +{ + /* enable DMA request */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_DMA; +} + +/*! + \brief disable DMA request + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(uint32_t adc_periph) +{ + /* disable DMA request */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief when DMA=1, the DMA engine issues a request at end of each regular conversion + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_request_after_last_enable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_DDM; +} + +/*! + \brief the DMA engine is disabled after the end of transfer signal from DMA controller is detected + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_request_after_last_disable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DDM); +} + +/*! + \brief enable hpdf mode + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_hpdf_mode_enable(uint32_t adc_periph) +{ + /* enable hpdf mode */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_HPDFCFG; +} + +/*! + \brief disable hpdf mode + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_hpdf_mode_disable(uint32_t adc_periph) +{ + /* disable hpdf mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_HPDFCFG); +} + +/*! + \brief configure ADC discontinuous mode + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel + \param[in] length: number of conversions in discontinuous mode, the number can be 1..8 + for regular channel, the number has no effect for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length) +{ + /* disable discontinuous mode of regular & inserted channel */ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + switch(adc_channel_group) { + case ADC_REGULAR_CHANNEL: + /* config the number of conversions in discontinuous mode */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM); + if((length <= 8U) && (length >= 1U)) { + ADC_CTL0(adc_periph) |= CTL0_DISNUM((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + /* enable regular channel group discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + /* enable inserted channel group discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + /* disable discontinuous mode of regular & inserted channel */ + default: + break; + } +} + +/*! + \brief configure the length of regular channel group or inserted channel group + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: the length of the channel + regular channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length) +{ + switch(adc_channel_group) { + case ADC_REGULAR_CHANNEL: + if((length >= 1U) && (length <= 16U)) { + ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + break; + case ADC_INSERTED_CHANNEL: + if((length >= 1U) && (length <= 4U)) { + ADC_ISQ0(adc_periph) &= ~((uint32_t)ADC_ISQ0_IL); + ADC_ISQ0(adc_periph) |= ISQ0_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + break; + default: + break; + } +} + +/*! + \brief configure ADC regular channel + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] rank: the regular group sequencer rank,this parameter must be between 0 to 15 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..20): ADC Channelx + \param[in] sample_time: the sample time value, 0..809 for ADC0/ADC1, 0..638 for ADC2 + \param[out] none + \retval none +*/ +void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint32_t rsq; + + /* configure ADC regular sequence */ + if(rank < ADC_REGULAR_CHANNEL_RANK_ONE) { + /* the regular group sequence rank is smaller than one */ + rsq = ADC_RSQ8(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * rank))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + rank)); + ADC_RSQ8(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_THREE) { + /* the regular group sequence rank is smaller than three */ + rsq = ADC_RSQ7(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_ONE)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_ONE))); + ADC_RSQ7(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_FIVE) { + /* the regular group sequence rank is smaller than five */ + rsq = ADC_RSQ6(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_THREE)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_THREE))); + ADC_RSQ6(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_SEVEN) { + /* the regular group sequence rank is smaller than seven */ + rsq = ADC_RSQ5(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_FIVE)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_FIVE))); + ADC_RSQ5(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_NINE) { + /* the regular group sequence rank is smaller than nine */ + rsq = ADC_RSQ4(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_SEVEN)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_SEVEN))); + ADC_RSQ4(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_ELEVEN) { + /* the regular group sequence rank is smaller than eleven */ + rsq = ADC_RSQ3(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_NINE)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_NINE))); + ADC_RSQ3(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_THIRTEEN) { + /* the regular group sequence rank is smaller than thirteen */ + rsq = ADC_RSQ2(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_ELEVEN)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_ELEVEN))); + ADC_RSQ2(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_FIFTEEN) { + /* the regular group sequence rank is smaller than fifteen */ + rsq = ADC_RSQ1(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_THIRTEEN)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_THIRTEEN))); + ADC_RSQ1(adc_periph) = rsq; + } else if(rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN) { + /* the regular group sequence rank is smaller than sixteen */ + rsq = ADC_RSQ0(adc_periph); + rsq &= ~((uint32_t)((ADC_RSQX_RSMPN | ADC_RSQX_RSQN) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_FIFTEEN)))); + rsq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_REGULAR_CHANNEL_SHIFT_LENGTH * + (rank - ADC_REGULAR_CHANNEL_RANK_FIFTEEN))); + ADC_RSQ0(adc_periph) = rsq; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure ADC inserted channel + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..20): ADC Channelx + \param[in] sample_time: The sample time value, 0..809 for ADC0/ADC1, 0..638 for ADC2 + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint8_t inserted_length, rankx; + uint32_t isq; + + /* get inserted channel group length */ + inserted_length = (uint8_t)GET_BITS(ADC_ISQ0(adc_periph), 20U, 21U); + rankx = ADC_OFFSET_LENGTH - inserted_length + rank; + + /* configure ADC inserted sequence */ + if(rankx < ADC_INSERTED_CHANNEL_RANK_ONE) { + /* the inserted group sequence rank is smaller than one */ + isq = ADC_ISQ2(adc_periph); + isq &= ~((uint32_t)((ADC_ISQX_ISMPN | ADC_ISQX_ISQN) << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH * rankx))); + isq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH * rankx)); + ADC_ISQ2(adc_periph) = isq; + } else if(rankx < ADC_INSERTED_CHANNEL_RANK_THREE) { + /* the inserted group sequence rank is smaller than three */ + isq = ADC_ISQ1(adc_periph); + isq &= ~((uint32_t)((ADC_ISQX_ISMPN | ADC_ISQX_ISQN) << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH * + (rankx - ADC_INSERTED_CHANNEL_RANK_ONE)))); + isq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH * + (rankx - ADC_INSERTED_CHANNEL_RANK_ONE))); + ADC_ISQ1(adc_periph) = isq; + } else if(rankx < ADC_INSERTED_CHANNEL_RANK_FOUR) { + /* the inserted group sequence rank is smaller than four */ + isq = ADC_ISQ0(adc_periph); + isq &= ~((uint32_t)((ADC_ISQX_ISMPN | ADC_ISQX_ISQN) << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH * + (rankx - ADC_INSERTED_CHANNEL_RANK_THREE)))); + isq |= ((uint32_t)(SQX_SMP(sample_time) | adc_channel) << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH * + (rankx - ADC_INSERTED_CHANNEL_RANK_THREE))); + ADC_ISQ0(adc_periph) = isq; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure ADC inserted channel offset + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] inserted_channel : insert channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted channel3 + \param[in] offset : the offset data + \param[out] none + \retval none +*/ +void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint32_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ0(adc_periph), 20U, 21U); + num = ((uint32_t)ADC_OFFSET_LENGTH - ((uint32_t)inserted_length - (uint32_t)inserted_channel)); + + if(num <= ADC_OFFSET_LENGTH) { + /* calculate the offset of the register */ + num = num * ADC_OFFSET_SHIFT_LENGTH; + /* config the offset of the selected channels */ + REG32((adc_periph) + ADC_IOFF0_OFFSET + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief configure differential mode for ADC channel + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_channel: the channel use differential mode + one or more parameters can be selected which is shown as below: + \arg ADC_DIFFERENTIAL_MODE_CHANNEL_x(x=0..21), ADC_DIFFERENTIAL_MODE_CHANNEL_ALL: ADC channel for differential mode + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_channel_differential_mode_config(uint32_t adc_periph, uint32_t adc_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + ADC_DIFCTL(adc_periph) |= (uint32_t)adc_channel; + } else { + ADC_DIFCTL(adc_periph) &= ~((uint32_t)adc_channel); + } +} + +/*! + \brief enable ADC external trigger + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] trigger_mode: external trigger mode + only one parameter can be selected which is shown as below: + \arg EXTERNAL_TRIGGER_DISABLE: external trigger disable + \arg EXTERNAL_TRIGGER_RISING: rising edge of external trigger + \arg EXTERNAL_TRIGGER_FALLING: falling edge of external trigger + \arg EXTERNAL_TRIGGER_RISING_FALLING: rising and falling edge of external trigger + \param[out] none + \retval none +*/ +void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t trigger_mode) +{ + switch(adc_channel_group) { + case ADC_REGULAR_CHANNEL: + /* configure ADC regular channel group external trigger mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC); + ADC_CTL1(adc_periph) |= (uint32_t)(trigger_mode << REGULAR_TRIGGER_MODE); + break; + case ADC_INSERTED_CHANNEL: + /* configure ADC inserted channel group external trigger mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMIC); + ADC_CTL1(adc_periph) |= (uint32_t)(trigger_mode << INSERTED_TRIGGER_MODE); + break; + default: + break; + } +} + +/*! + \brief enable ADC software trigger + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group) +{ + /* enable regular group channel software trigger */ + if(RESET != (adc_channel_group & ADC_REGULAR_CHANNEL)) { + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST; + } + /* enable inserted channel group software trigger */ + if(RESET != (adc_channel_group & ADC_INSERTED_CHANNEL)) { + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWICST; + } +} + +/*! + \brief configure end of conversion mode + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] end_selection: end of conversion mode + only one parameter can be selected which is shown as below: + \arg ADC_EOC_SET_SEQUENCE: only at the end of a sequence of regular conversions, the EOC bit is set. Overflow detection is disabled unless DMA=1. + \arg ADC_EOC_SET_CONVERSION: at the end of each regular conversion, the EOC bit is set. Overflow is detected automatically. + \param[out] none + \retval none +*/ +void adc_end_of_conversion_config(uint32_t adc_periph, uint32_t end_selection) +{ + if(ADC_EOC_SET_SEQUENCE == end_selection) { + /* only at the end of a sequence of regular conversions, the EOC bit is set */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_EOCM); + } else if(ADC_EOC_SET_CONVERSION == end_selection) { + /* at the end of each regular conversion, the EOC bit is set. Overflow is detected automatically */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_EOCM; + } else { + /* illegal parameters */ + } +} + +/*! + \brief read ADC regular group data register + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint32_t adc_regular_data_read(uint32_t adc_periph) +{ + return (uint32_t)(ADC_RDATA(adc_periph)); +} + +/*! + \brief read ADC inserted group data register + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] inserted_channel : insert channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: inserted Channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted Channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted Channel3 + \param[out] none + \retval the conversion value +*/ +uint32_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel) +{ + uint32_t idata; + /* read the data of the selected channel */ + switch(inserted_channel) { + case ADC_INSERTED_CHANNEL_0: + /* read the data of channel 0 */ + idata = ADC_IDATA0(adc_periph); + break; + case ADC_INSERTED_CHANNEL_1: + /* read the data of channel 1 */ + idata = ADC_IDATA1(adc_periph); + break; + case ADC_INSERTED_CHANNEL_2: + /* read the data of channel 2 */ + idata = ADC_IDATA2(adc_periph); + break; + case ADC_INSERTED_CHANNEL_3: + /* read the data of channel 3 */ + idata = ADC_IDATA3(adc_periph); + break; + default: + idata = 0U; + break; + } + return (uint32_t)idata; +} + +/*! + \brief configure ADC analog watchdog 0 single channel + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x: ADC Channelx(x=0..20) + \param[out] none + \retval none +*/ +void adc_watchdog0_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC | + ADC_CTL0_WD0CHSEL)); + + ADC_CTL0(adc_periph) |= (uint32_t)adc_channel; + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC); +} + +/*! + \brief configure ADC analog watchdog 0 group channel + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_channel_group: the channel group use analog watchdog 0 + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog0_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC)); + /* select the group */ + switch(adc_channel_group) { + case ADC_REGULAR_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_RWD0EN; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_IWD0EN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN); + break; + default: + break; + } +} + +/*! + \brief disable ADC analog watchdog 0 + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_watchdog0_disable(uint32_t adc_periph) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC | + ADC_CTL0_WD0CHSEL)); +} + +/*! + \brief configure ADC analog watchdog 1 channel + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] selection_channel: the channel use analog watchdog 1 + one or more parameters can be selected which is shown as below: + \arg ADC_AWD1_2_SELECTION_CHANNEL_x, ADC_AWD1_2_SELECTION_CHANNEL_ALL: ADC channel analog watchdog 1/2 selection + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_watchdog1_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + ADC_WD1SR(adc_periph) |= (uint32_t)selection_channel; + } else { + ADC_WD1SR(adc_periph) &= ~((uint32_t)selection_channel); + } +} + +/*! + \brief configure ADC analog watchdog 2 channel + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] selection_channel: the channel use analog watchdog 2 + one or more parameters can be selected which is shown as below: + \arg ADC_AWD1_2_SELECTION_CHANNEL_x, ADC_AWD1_2_SELECTION_CHANNEL_ALL: ADC channel analog watchdog 1/2 selection + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_watchdog2_channel_config(uint32_t adc_periph, uint32_t selection_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + ADC_WD2SR(adc_periph) |= (uint32_t)selection_channel; + } else { + ADC_WD2SR(adc_periph) &= ~((uint32_t)selection_channel); + } +} + +/*! + \brief disable ADC analog watchdog 1 + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_watchdog1_disable(uint32_t adc_periph) +{ + ADC_WD1SR(adc_periph) &= ~((uint32_t)ADC_WD1SR_AWD1CS); +} + +/*! + \brief disable ADC analog watchdog 2 + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_watchdog2_disable(uint32_t adc_periph) +{ + ADC_WD2SR(adc_periph) &= ~((uint32_t)ADC_WD2SR_AWD2CS); +} + +/*! + \brief configure ADC analog watchdog 0 threshold + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] low_threshold: analog watchdog 0 low threshold, 0..0xFFFFFF for ADC0/ADC1, 0..0xFFF for ADC2 + \param[in] high_threshold: analog watchdog 0 high threshold, 0..0xFFFFFF for ADC0/ADC1, 0..0xFFF for ADC2 + \param[out] none + \retval none +*/ +void adc_watchdog0_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold) +{ + ADC_WDLT0(adc_periph) = (uint32_t)WDLT0_WDLT0(low_threshold); + ADC_WDHT0(adc_periph) = (uint32_t)WDHT0_WDHT0(high_threshold); +} + +/*! + \brief configure ADC analog watchdog 1 threshold + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] low_threshold: analog watchdog 1 low threshold, 0..0xFFFFFF for ADC0/ADC1, 0..0xFF for ADC2 + \param[in] high_threshold: analog watchdog 1 high threshold, 0..0xFFFFFF for ADC0/ADC1, 0..0xFF for ADC2 + \param[out] none + \retval none +*/ +void adc_watchdog1_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold) +{ + ADC_WDLT1(adc_periph) = (uint32_t)WDLT1_WDLT1(low_threshold); + ADC_WDHT1(adc_periph) = (uint32_t)WDHT1_WDHT1(high_threshold); +} + +/*! + \brief configure ADC analog watchdog 2 threshold + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] low_threshold: analog watchdog 2 low threshold, 0..0xFFFFFF for ADC0/ADC1, 0..0xFF for ADC2 + \param[in] high_threshold: analog watchdog 2 high threshold, 0..0xFFFFFF for ADC0/ADC1, 0..0xFF for ADC2 + \param[out] none + \retval none +*/ +void adc_watchdog2_threshold_config(uint32_t adc_periph, uint32_t low_threshold, uint32_t high_threshold) +{ + ADC_WDLT2(adc_periph) = (uint32_t)WDLT2_WDLT2(low_threshold); + ADC_WDHT2(adc_periph) = (uint32_t)WDHT2_WDHT2(high_threshold); +} + +/*! + \brief configure ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] mode: ADC oversampling mode + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger + \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger + \param[in] shift: ADC oversampling shift + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_4B: 4-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_9B: 9-bit oversampling shift, available for ADC0/ADC1 + \arg ADC_OVERSAMPLING_SHIFT_10B: 10-bit oversampling shift, available for ADC0/ADC1 + \arg ADC_OVERSAMPLING_SHIFT_11B: 11-bit oversampling shift, available for ADC0/ADC1 + \param[in] ratio: ADC oversampling ratio, 0..1023 for ADC0/ADC1, 0..255 for ADC2 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint16_t ratio) +{ + if(ADC_OVERSAMPLING_ALL_CONVERT == mode) { + /* all oversampled conversions for a channel are done consecutively after a trigger */ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } else if(ADC_OVERSAMPLING_ONE_CONVERT == mode) { + /* each oversampled conversion for a channel needs a trigger */ + ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS; + } else { + /* illegal parameters */ + } + /* config the shift and ratio */ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL(adc_periph) |= ((uint32_t)shift | (uint32_t)OVSCR_OVSR(ratio)); +} + +/*! + \brief enable ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(uint32_t adc_periph) +{ + ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief disable ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1,2 + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(uint32_t adc_periph) +{ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} + +/*! + \brief get the ADC flag bits + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] flag: the adc flag + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WDE0: analog watchdog 0 event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \arg ADC_FLAG_ROVF: regular data register overflow flag + \arg ADC_FLAG_WDE1: analog watchdog 1 event flag + \arg ADC_FLAG_WDE2: analog watchdog 2 event flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t flag) +{ + FlagStatus reval = RESET; + if(ADC_STAT(adc_periph) & flag) { + reval = SET; + } + return reval; +} + +/*! + \brief clear the ADC flag bits + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] flag: the adc flag + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WDE0: analog watchdog 0 event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \arg ADC_FLAG_ROVF: regular data register overflow flag + \arg ADC_FLAG_WDE1: analog watchdog 1 event flag + \arg ADC_FLAG_WDE2: analog watchdog 2 event flag + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t adc_periph, uint32_t flag) +{ + ADC_STAT(adc_periph) = ~((uint32_t)flag); +} + +/*! + \brief enable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_interrupt: the adc interrupt + only one parameter can be selected which is shown as below: + \arg ADC_INT_WDE0: analog watchdog 0 interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \arg ADC_INT_ROVF: regular data register overflow interrupt + \arg ADC_INT_WDE1: analog watchdog 1 interrupt + \arg ADC_INT_WDE2: analog watchdog 2 interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t adc_periph, uint32_t interrupt) +{ + ADC_CTL0(adc_periph) |= (uint32_t)interrupt; +} + +/*! + \brief disable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] adc_interrupt: the adc interrupt + only one parameter can be selected which is shown as below: + \arg ADC_INT_WDE0: analog watchdog 0 interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \arg ADC_INT_ROVF: regular data register overflow interrupt + \arg ADC_INT_WDE1: analog watchdog 1 interrupt + \arg ADC_INT_WDE2: analog watchdog 2 interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t adc_periph, uint32_t interrupt) +{ + ADC_CTL0(adc_periph) &= ~(uint32_t)interrupt; +} + +/*! + \brief get the ADC interrupt bits + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] int_flag: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE0: analog watchdog 0 interrupt + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt + \arg ADC_INT_FLAG_ROVF: regular data register overflow interrupt + \arg ADC_INT_FLAG_WDE1: analog watchdog 1 interrupt + \arg ADC_INT_FLAG_WDE2: analog watchdog 2 interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t int_flag) +{ + FlagStatus reval = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(int_flag) { + case ADC_INT_FLAG_WDE0: + /* get the ADC analog watchdog 0 interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_WDE0; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDE0IE) && state) { + reval = SET; + } + break; + case ADC_INT_FLAG_EOC: + /* get the ADC end of group conversion interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_EOC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state) { + reval = SET; + } + break; + case ADC_INT_FLAG_EOIC: + /* get the ADC end of inserted group conversion interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_EOIC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state) { + reval = SET; + } + break; + case ADC_INT_FLAG_ROVF: + /* get the ADC regular data register overflow interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_ROVF; + if((ADC_CTL0(adc_periph) & ADC_CTL0_ROVFIE) && state) { + reval = SET; + } + break; + case ADC_INT_FLAG_WDE1: + /* get the ADC analog watchdog 1 interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_WDE1; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDE1IE) && state) { + reval = SET; + } + break; + case ADC_INT_FLAG_WDE2: + /* get the ADC analog watchdog 2 interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_WDE2; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDE2IE) && state) { + reval = SET; + } + break; + default: + break; + } + return reval; +} + +/*! + \brief clear the ADC flag + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] int_flag: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE0: analog watchdog 0 interrupt flag + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_FLAG_ROVF: regular data register overflow interrupt flag + \arg ADC_INT_FLAG_WDE1: analog watchdog 1 interrupt flag + \arg ADC_INT_FLAG_WDE2: analog watchdog 2 interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t int_flag) +{ + ADC_STAT(adc_periph) = ~((uint32_t)int_flag); +} + +/*! + \brief configure the ADC sync mode + \param[in] sync_mode: ADC sync mode + only one parameter can be selected which is shown as below: + \arg ADC_SYNC_MODE_INDEPENDENT: all the ADCs work independently + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: combined regular parallel & inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: combined regular parallel & trigger rotation mode + \arg ADC_DAUL_INSERTED_PARALLEL: inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL: regular parallel mode + \arg ADC_DAUL_REGULAL_FOLLOW_UP: follow-up mode + \arg ADC_DAUL_INSERTED_TRIGGER_ROTATION: trigger rotation mode + \param[out] none + \retval none +*/ +void adc_sync_mode_config(uint32_t sync_mode) +{ + ADC_SYNCCTL(ADC0) &= ~((uint32_t)ADC_SYNCCTL_SYNCM); + ADC_SYNCCTL(ADC0) |= (uint32_t)sync_mode; +} + +/*! + \brief configure the delay between 2 sampling phases in ADC sync modes + \param[in] sample_delay: the delay between 2 sampling phases in ADC sync modes + only one parameter can be selected which is shown as below: + \arg ADC_SYNC_DELAY_xCYCLE: x=5..20,the delay between 2 sampling phases in ADC sync modes is x ADC clock cycles + \param[out] none + \retval none +*/ +void adc_sync_delay_config(uint32_t sample_delay) +{ + ADC_SYNCCTL(ADC0) &= ~((uint32_t)ADC_SYNCCTL_SYNCDLY); + ADC_SYNCCTL(ADC0) |= (uint32_t)sample_delay; +} + +/*! + \brief configure ADC sync DMA mode selection + \param[in] dma_mode: ADC sync DMA mode + only one parameter can be selected which is shown as below: + \arg ADC_SYNC_DMA_DISABLE: ADC sync DMA disabled + \arg ADC_SYNC_DMA_MODE0: ADC sync DMA mode 0 + \arg ADC_SYNC_DMA_MODE1: ADC sync DMA mode 1 + \param[out] none + \retval none +*/ +void adc_sync_dma_config(uint32_t dma_mode) +{ + ADC_SYNCCTL(ADC0) &= ~((uint32_t)ADC_SYNCCTL_SYNCDMA); + ADC_SYNCCTL(ADC0) |= (uint32_t)dma_mode; +} + +/*! + \brief configure ADC sync DMA engine issues requests according to the SYNCDMA bits + \param[in] none + \param[out] none + \retval none +*/ +void adc_sync_dma_request_after_last_enable(void) +{ + ADC_SYNCCTL(ADC0) |= (uint32_t)ADC_SYNCCTL_SYNCDDM; +} + +/*! + \brief configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected + \param[in] none + \param[out] none + \retval none +*/ +void adc_sync_dma_request_after_last_disable(void) +{ + ADC_SYNCCTL(ADC0) &= ~((uint32_t)ADC_SYNCCTL_SYNCDDM); +} + +/*! + \brief read ADC sync master adc regular data register 0 + \param[in] none + \param[out] none + \retval sync regular data 0 +*/ +uint32_t adc_sync_master_adc_regular_data0_read(void) +{ + return (uint32_t)(ADC_SYNCDATA0 & ADC_SYNCDATA0_SYNCDATA0); +} + +/*! + \brief read ADC sync slave adc regular data register 0 + \param[in] none + \param[out] none + \retval sync regular data 0 +*/ +uint32_t adc_sync_slave_adc_regular_data0_read(void) +{ + return (uint32_t)(ADC_SYNCDATA0 & ADC_SYNCDATA0_SYNCDATA1) >> 16; +} + +/*! + \brief read ADC sync regular data register 1 + \param[in] none + \param[out] none + \retval sync regular data 1 +*/ +uint32_t adc_sync_regular_data1_read(void) +{ + return (uint32_t)ADC_SYNCDATA1; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_can.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_can.c new file mode 100644 index 0000000000..281aca0422 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_can.c @@ -0,0 +1,1910 @@ +/*! + \file gd32h7xx_can.c + \brief CAN driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_can.h" + +/* DLC to data size in bytes definitions */ +static const uint8_t dlc_to_databytes[16] = {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U}; + +/* computes the maximum payload size (in bytes) */ +static uint32_t can_payload_size_compute(uint32_t mdes0); +/* swap data to little endian */ +static void can_data_to_little_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len); +/* swap data to big endian */ +static void can_data_to_big_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len); +/* computes the dlc field value, given a payload size (in bytes) */ +static uint32_t can_dlc_value_compute(uint32_t payload_size); + +/*! + \brief deinitialize CAN + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_deinit(uint32_t can_periph) +{ + if(CAN0 == can_periph) { + /* reset CAN0 */ + rcu_periph_reset_enable(RCU_CAN0RST); + rcu_periph_reset_disable(RCU_CAN0RST); + } + if(CAN1 == can_periph) { + /* reset CAN1 */ + rcu_periph_reset_enable(RCU_CAN1RST); + rcu_periph_reset_disable(RCU_CAN1RST); + } + if(CAN2 == can_periph) { + /* reset CAN2 */ + rcu_periph_reset_enable(RCU_CAN2RST); + rcu_periph_reset_disable(RCU_CAN2RST); + } +} + +/*! + \brief reset CAN internal state machines and CAN registers + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_software_reset(uint32_t can_periph) +{ + uint32_t timeout = CAN_DELAY; + + /* reset internal state machines and CAN registers */ + CAN_CTL0(can_periph) |= CAN_CTL0_SWRST; + /* wait reset complete */ + while((CAN_CTL0(can_periph) & CAN_CTL0_SWRST) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_SWRST) { + return ERROR; + } + return SUCCESS; +} + +/*! + \brief CAN module initialization + \param[in] can_periph: CANx(x=0,1,2) + \param[in] can_parameter_init: can parameter struct + internal_counter_source: CAN_TIMER_SOURCE_BIT_CLOCK, CAN_TIMER_SOURCE_EXTERNAL_TIME_TICK + self_reception: ENABLE, DISABLE + mb_tx_order: CAN_TX_HIGH_PRIORITY_MB_FIRST, CAN_TX_LOW_NUM_MB_FIRST + mb_tx_abort_enable: ENABLE, DISABLE + local_priority_enable: ENABLE, DISABLE + mb_rx_ide_rtr_type: CAN_IDE_RTR_COMPARED, CAN_IDE_RTR_FILTERED + mb_remote_frame: CAN_GEN_REMOTE_RESPONSE_FRAME, CAN_STORE_REMOTE_REQUEST_FRAME + rx_private_filter_queue_enable: ENABLE, DISABLE + edge_filter_enable: ENABLE, DISABLE + protocol_exception_enable: ENABLE, DISABLE + rx_filter_order: CAN_RX_FILTER_ORDER_FIFO_FIRST, CAN_RX_FILTER_ORDER_MAILBOX_FIRST + memory_size: CAN_MEMSIZE_1_UNIT, CAN_MEMSIZE_2_UNIT, CAN_MEMSIZE_3_UNIT, CAN_MEMSIZE_4_UNIT, + CAN_MEMSIZE_5_UNIT, CAN_MEMSIZE_6_UNIT, CAN_MEMSIZE_7_UNIT, CAN_MEMSIZE_8_UNIT, + CAN_MEMSIZE_9_UNIT, CAN_MEMSIZE_10_UNIT, CAN_MEMSIZE_11_UNIT, CAN_MEMSIZE_12_UNIT, + CAN_MEMSIZE_13_UNIT, CAN_MEMSIZE_14_UNIT, CAN_MEMSIZE_15_UNIT, CAN_MEMSIZE_16_UNIT, + CAN_MEMSIZE_17_UNIT, CAN_MEMSIZE_18_UNIT, CAN_MEMSIZE_19_UNIT, CAN_MEMSIZE_20_UNIT, + CAN_MEMSIZE_21_UNIT, CAN_MEMSIZE_22_UNIT, CAN_MEMSIZE_23_UNIT, CAN_MEMSIZE_24_UNIT, + CAN_MEMSIZE_25_UNIT, CAN_MEMSIZE_26_UNIT, CAN_MEMSIZE_27_UNIT, CAN_MEMSIZE_28_UNIT, + CAN_MEMSIZE_29_UNIT, CAN_MEMSIZE_30_UNIT, CAN_MEMSIZE_31_UNIT, CAN_MEMSIZE_32_UNIT + mb_public_filter: 0x00000000 ~ 0xFFFFFFFF + prescaler: 1~1024 + resync_jump_width: 1~32 + prop_time_segment: 1~64 + time_segment_1: 1~32 + time_segment_2: 1~32 + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init) +{ + uint32_t i; + uint32_t *canram = (uint32_t *)(CAN_RAM(can_periph)); + + /* clear CAN RAM */ + for(i = 0U; i < CAN_MAX_RAM_SIZE; i++) { + canram[i] = 0U; + } + /* reset CAN_RFIFOMPFx */ + for(i = 0U; i < CAN_MAX_MAILBOX_NUM; i++) { + CAN_RFIFOMPF(can_periph, i) = 0x00000000U; + } + + /* reset internal state machines and CAN registers */ + if(ERROR == can_software_reset(can_periph)) { + return ERROR; + } + + /* reset CAN_INTEN */ + CAN_INTEN(can_periph) = 0U; + /* reset CAN_STAT */ + CAN_STAT(can_periph) = (uint32_t)0xFFFFFFFFU; + CAN_TIMER(can_periph); + while(CAN_STAT(can_periph) & CAN_STAT_MS5_RFNE) { + CAN_STAT(can_periph) = CAN_STAT_MS5_RFNE; + } + + /* clear register bits */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_RFEN | CAN_CTL0_FDEN | CAN_CTL0_SRDIS | CAN_CTL0_LAPRIOEN | CAN_CTL0_MST | CAN_CTL0_RPFQEN | CAN_CTL0_MSZ); + CAN_CTL2(can_periph) &= ~(CAN_CTL2_ITSRC | CAN_CTL2_IDERTR_RMF | CAN_CTL2_RRFRMS | CAN_CTL2_RFO | CAN_CTL2_EFDIS | CAN_CTL2_PREEN); + CAN_CTL1(can_periph) &= ~CAN_CTL1_MTO; + CAN_BT(can_periph) &= ~(CAN_BT_BAUDPSC | CAN_BT_SJW | CAN_BT_PTS | CAN_BT_PBS1 | CAN_BT_PBS2); + + /* set self reception */ + if((uint8_t)DISABLE == can_parameter_init->self_reception) { + CAN_CTL0(can_periph) |= CAN_CTL0_SRDIS; + } + /* enable local arbitration priority */ + if((uint8_t)ENABLE == can_parameter_init->local_priority_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_LAPRIOEN; + } + /* set rx private filters and mailbox queue */ + if((uint8_t)ENABLE == can_parameter_init->rx_private_filter_queue_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_RPFQEN; + } + /* configure edge filtering */ + if((uint32_t)DISABLE == can_parameter_init->edge_filter_enable) { + CAN_CTL2(can_periph) |= CAN_CTL2_EFDIS; + } + /* configure protocol exception */ + if((uint32_t)ENABLE == can_parameter_init->protocol_exception_enable) { + CAN_CTL2(can_periph) |= CAN_CTL2_PREEN; + } + /* set mailbox stop transmission */ + if((uint8_t)ENABLE == can_parameter_init->mb_tx_abort_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_MST; + } + + /* set internal counter source */ + CAN_CTL2(can_periph) |= can_parameter_init->internal_counter_source; + /* set mailbox arbitration process order */ + CAN_CTL1(can_periph) |= can_parameter_init->mb_tx_order; + /* set IDE and RTR field filter type */ + CAN_CTL2(can_periph) |= can_parameter_init->mb_rx_ide_rtr_type; + /* configure remote request frame */ + CAN_CTL2(can_periph) |= can_parameter_init->mb_remote_frame; + /* set mailbox public filter */ + CAN_RMPUBF(can_periph) = can_parameter_init->mb_public_filter; + /* configure receive filter order */ + CAN_CTL2(can_periph) |= can_parameter_init->rx_filter_order; + /* set memory size */ + CAN_CTL0(can_periph) |= can_parameter_init->memory_size; + /* set time segment */ + CAN_BT(can_periph) |= (uint32_t)(BT_BAUDPSC(can_parameter_init->prescaler - 1U) | + BT_SJW((uint32_t)can_parameter_init->resync_jump_width - 1U) | + BT_PTS((uint32_t)can_parameter_init->prop_time_segment - 1U) | + BT_PBS1((uint32_t)can_parameter_init->time_segment_1 - 1U) | + BT_PBS2((uint32_t)can_parameter_init->time_segment_2 - 1U)); + + return SUCCESS; +} + +/*! + \brief initialize CAN parameter structure with a default value + \param[in] type: the type of CAN parameter struct + only one parameter can be selected which is shown as below: + \arg CAN_INIT_STRUCT: the CAN initial struct + \arg CAN_FD_INIT_STRUCT: the CAN FD initial struct + \arg CAN_FIFO_INIT_STRUCT: the CAN FIFO initial struct + \arg CAN_PN_MODE_INIT_STRUCT: the CAN Pretended Networking mode initial struct + \arg CAN_PN_MODE_FILTER_STRUCT: the CAN Pretended Networking mode filter struct + \arg CAN_MDSC_STRUCT: mailbox descriptor strcut + \arg CAN_FDES_STRUCT: Rx fifo descriptor strcut + \arg CAN_FIFO_ID_FILTER_STRUCT: Rx fifo id filter strcut + \arg CAN_CRC_STRUCT: CRC strcut + \arg CAN_ERRCNT_STRUCT: error counter strcut + \param[in] p_struct: the pointer of the specific struct + \param[out] none + \retval none +*/ +void can_struct_para_init(can_struct_type_enum type, void *p_struct) +{ + /* get type of the struct */ + switch(type) { + /* used for initialize can_parameter_struct */ + case CAN_INIT_STRUCT: + ((can_parameter_struct *)p_struct)->self_reception = (uint8_t)DISABLE; + ((can_parameter_struct *)p_struct)->internal_counter_source = CAN_TIMER_SOURCE_BIT_CLOCK; + ((can_parameter_struct *)p_struct)->mb_tx_order = CAN_TX_HIGH_PRIORITY_MB_FIRST; + ((can_parameter_struct *)p_struct)->mb_tx_abort_enable = (uint8_t)ENABLE; + ((can_parameter_struct *)p_struct)->local_priority_enable = (uint8_t)DISABLE; + ((can_parameter_struct *)p_struct)->mb_rx_ide_rtr_type = CAN_IDE_RTR_COMPARED; + ((can_parameter_struct *)p_struct)->mb_remote_frame = CAN_STORE_REMOTE_REQUEST_FRAME; + ((can_parameter_struct *)p_struct)->rx_private_filter_queue_enable = (uint8_t)DISABLE; + ((can_parameter_struct *)p_struct)->edge_filter_enable = (uint32_t)DISABLE; + ((can_parameter_struct *)p_struct)->protocol_exception_enable = (uint32_t)DISABLE; + ((can_parameter_struct *)p_struct)->rx_filter_order = CAN_RX_FILTER_ORDER_FIFO_FIRST; + ((can_parameter_struct *)p_struct)->memory_size = CAN_MEMSIZE_32_UNIT; + ((can_parameter_struct *)p_struct)->mb_public_filter = 0xFFFFFFFFU; + ((can_parameter_struct *)p_struct)->prescaler = 0x00000001U; + ((can_parameter_struct *)p_struct)->resync_jump_width = 0x01U; + ((can_parameter_struct *)p_struct)->prop_time_segment = 0x01U; + ((can_parameter_struct *)p_struct)->time_segment_1 = 0x01U; + ((can_parameter_struct *)p_struct)->time_segment_2 = 0x01U; + break; + /* used for initialize can_fd_parameter_struct */ + case CAN_FD_INIT_STRUCT: + ((can_fd_parameter_struct *)p_struct)->iso_can_fd_enable = (uint32_t)DISABLE; + ((can_fd_parameter_struct *)p_struct)->bitrate_switch_enable = (uint32_t)ENABLE; + ((can_fd_parameter_struct *)p_struct)->mailbox_data_size = CAN_MAILBOX_DATA_SIZE_8_BYTES; + ((can_fd_parameter_struct *)p_struct)->tdc_enable = (uint32_t)DISABLE; + ((can_fd_parameter_struct *)p_struct)->tdc_offset = 0x00U; + ((can_fd_parameter_struct *)p_struct)->prescaler = 0x00000001U; + ((can_fd_parameter_struct *)p_struct)->resync_jump_width = 0x01U; + ((can_fd_parameter_struct *)p_struct)->prop_time_segment = 0x00U; + ((can_fd_parameter_struct *)p_struct)->time_segment_1 = 0x01U; + ((can_fd_parameter_struct *)p_struct)->time_segment_2 = 0x01U; + break; + /* used for initialize can_fifo_parameter_struct */ + case CAN_FIFO_INIT_STRUCT: + ((can_fifo_parameter_struct *)p_struct)->dma_enable = (uint8_t)DISABLE; + ((can_fifo_parameter_struct *)p_struct)->filter_format_and_number = CAN_RXFIFO_FILTER_A_NUM_8; + ((can_fifo_parameter_struct *)p_struct)->fifo_public_filter = 0xFFFFFFFFU; + break; + /* used for initialize can_pn_mode_config_struct */ + case CAN_PN_MODE_INIT_STRUCT: + ((can_pn_mode_config_struct *)p_struct)->timeout_int = (uint32_t)DISABLE; + ((can_pn_mode_config_struct *)p_struct)->match_int = (uint32_t)DISABLE; + ((can_pn_mode_config_struct *)p_struct)->num_matches = 0x01U; + ((can_pn_mode_config_struct *)p_struct)->match_timeout = 0x0000U; + ((can_pn_mode_config_struct *)p_struct)->frame_filter = CAN_PN_FRAME_FILTERING_ID; + ((can_pn_mode_config_struct *)p_struct)->id_filter = CAN_PN_ID_FILTERING_EXACT; + ((can_pn_mode_config_struct *)p_struct)->data_filter = CAN_PN_DATA_FILTERING_EXACT; + break; + /* used for initialize can_pn_mode_filter_struct */ + case CAN_PN_MODE_FILTER_STRUCT: + ((can_pn_mode_filter_struct *)p_struct)->rtr = (uint32_t)RESET; + ((can_pn_mode_filter_struct *)p_struct)->ide = (uint32_t)RESET; + ((can_pn_mode_filter_struct *)p_struct)->id = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->dlc_high_threshold = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->dlc_low_threshold = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->payload[0] = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->payload[1] = 0x00000000U; + break; + /* used for initialize can_mailbox_descriptor_struct */ + case CAN_MDSC_STRUCT: + ((can_mailbox_descriptor_struct *)p_struct)->timestamp = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->dlc = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->rtr = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->ide = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->srr = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->reserve1 = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->code = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->reserve2 = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->esi = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->brs = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->fdf = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->id = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->prio = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->data = (void *)0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->data_bytes = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->padding = 0x0000U; + break; + /* used for initialize can_rx_fifo_struct */ + case CAN_FDES_STRUCT: + ((can_rx_fifo_struct *)p_struct)->timestamp = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->dlc = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->rtr = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->ide = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->srr = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->idhit = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->id = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->data[0] = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->data[1] = 0x00000000U; + break; + /* used for initialize can_rx_fifo_id_filter_struct */ + case CAN_FIFO_ID_FILTER_STRUCT: + ((can_rx_fifo_id_filter_struct *)p_struct)->remote_frame = 0x00000000U; + ((can_rx_fifo_id_filter_struct *)p_struct)->extended_frame = 0x00000000U; + ((can_rx_fifo_id_filter_struct *)p_struct)->id = 0x00000000U; + break; + /* used for initialize can_crc_struct */ + case CAN_CRC_STRUCT: + ((can_crc_struct *)p_struct)->classical_frm_mb_number = 0x00000000U; + ((can_crc_struct *)p_struct)->classical_frm_transmitted_crc = 0x00000000U; + ((can_crc_struct *)p_struct)->classical_fd_frm_mb_number = 0x00000000U; + ((can_crc_struct *)p_struct)->classical_fd_frm_transmitted_crc = 0x00000000U; + break; + /* used for initialize can_crc_struct */ + case CAN_ERRCNT_STRUCT: + ((can_error_counter_struct *)p_struct)->fd_data_phase_rx_errcnt = 0x00U; + ((can_error_counter_struct *)p_struct)->fd_data_phase_tx_errcnt = 0x00U; + ((can_error_counter_struct *)p_struct)->rx_errcnt = 0x00U; + ((can_error_counter_struct *)p_struct)->tx_errcnt = 0x00U; + break; + default: + break; + } +} + +/*! + \brief configure receive fifo/mailbox private filter + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index + \param[in] filter_data: filter data to configure + \param[out] none + \retval none +*/ +void can_private_filter_config(uint32_t can_periph, uint32_t index, uint32_t filter_data) +{ + CAN_RFIFOMPF(can_periph, index) = filter_data; +} + +/*! + \brief enter the corresponding mode + \param[in] can_periph: CANx(x=0,1,2) + \param[in] mode: the mode to enter + only one parameter can be selected which is shown as below: + \arg CAN_NORMAL_MODE: normal mode + \arg CAN_MONITOR_MODE: monitor mode + \arg CAN_LOOPBACK_SILENT_MODE: loopback mode + \arg CAN_INACTIVE_MODE: inactive mode + \arg CAN_DISABLE_MODE: disable mode + \arg CAN_PN_MODE: Pretended Networking mode + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum mode) +{ + uint32_t timeout; + ErrStatus ret = SUCCESS; + + /* enter INACTIVE mode */ + /* exit can_disable mode */ + CAN_CTL0(can_periph) &= ~CAN_CTL0_CANDIS; + /* enter inactive mode */ + CAN_CTL0(can_periph) |= CAN_CTL0_HALT | CAN_CTL0_INAMOD; + /* exit Pretended Networking mode */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_PNEN | CAN_CTL0_PNMOD); + timeout = CAN_DELAY; + /* wait for inactive mode state */ + while(((CAN_CTL0_NRDY | CAN_CTL0_INAS) != (CAN_CTL0(can_periph) & (CAN_CTL0_NRDY | CAN_CTL0_INAS))) && (timeout)) { + timeout--; + } + if((CAN_CTL0_NRDY | CAN_CTL0_INAS) != (CAN_CTL0(can_periph) & (CAN_CTL0_NRDY | CAN_CTL0_INAS))) { + return ERROR; + } + + /* configure the modes */ + switch(mode) { + case CAN_NORMAL_MODE: + CAN_CTL1(can_periph) &= ~(CAN_CTL1_LSCMOD | CAN_CTL1_MMOD); + break; + case CAN_MONITOR_MODE: + CAN_CTL1(can_periph) &= ~CAN_CTL1_LSCMOD; + CAN_CTL1(can_periph) |= CAN_CTL1_MMOD; + break; + case CAN_LOOPBACK_SILENT_MODE: + CAN_CTL1(can_periph) &= ~CAN_CTL1_MMOD; + CAN_CTL0(can_periph) &= ~CAN_CTL0_SRDIS; + CAN_FDCTL(can_periph) &= ~CAN_FDCTL_TDCEN; + CAN_CTL1(can_periph) |= CAN_CTL1_LSCMOD; + break; + case CAN_INACTIVE_MODE: + break; + case CAN_DISABLE_MODE: + CAN_CTL0(can_periph) |= CAN_CTL0_CANDIS; + break; + case CAN_PN_MODE: + CAN_CTL0(can_periph) |= (CAN_CTL0_PNEN | CAN_CTL0_PNMOD); + break; + default: + break; + } + + /* exit INACTIVE mode */ + if(CAN_INACTIVE_MODE != mode) { + /* exit inactive mode */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_HALT | CAN_CTL0_INAMOD); + timeout = CAN_DELAY; + while((CAN_CTL0(can_periph) & CAN_CTL0_INAS) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_INAS) { + return ERROR; + } + } + + if(CAN_PN_MODE == mode) { + timeout = CAN_DELAY; + while((0U == (CAN_CTL0(can_periph) & CAN_CTL0_PNS)) && (timeout)) { + timeout--; + } + if(0U == (CAN_CTL0(can_periph) & CAN_CTL0_PNS)) { + return ERROR; + } + } + return ret; +} + +/*! + \brief get operation mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval can_operation_modes_enum +*/ +can_operation_modes_enum can_operation_mode_get(uint32_t can_periph) +{ + uint32_t reg; + can_operation_modes_enum state = CAN_NORMAL_MODE; + + reg = CAN_CTL0(can_periph); + reg &= (CAN_CTL0_NRDY | CAN_CTL0_INAS | CAN_CTL0_PNS | CAN_CTL0_LPS); + + if((CAN_CTL0_NRDY | CAN_CTL0_LPS) == reg) { + state = CAN_DISABLE_MODE; + } else if((CAN_CTL0_NRDY | CAN_CTL0_INAS) == reg) { + state = CAN_INACTIVE_MODE; + } else if(0U == reg) { + if(CAN_CTL1(can_periph)&CAN_CTL1_MMOD) { + state = CAN_MONITOR_MODE; + } else if(CAN_CTL1(can_periph)&CAN_CTL1_LSCMOD) { + state = CAN_LOOPBACK_SILENT_MODE; + } else { + state = CAN_NORMAL_MODE; + } + } else if(CAN_CTL0_PNS == reg) { + state = CAN_PN_MODE; + } else { + /* should not get here */ + } + + return state; +} + +/*! + \brief exit inactive mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_inactive_mode_exit(uint32_t can_periph) +{ + uint32_t timeout; + + /* exit inactive mode */ + CAN_CTL0(can_periph) &= ~CAN_CTL0_HALT; + timeout = CAN_DELAY; + while((CAN_CTL0(can_periph) & CAN_CTL0_INAS) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_INAS) { + return ERROR; + } else { + return SUCCESS; + } +} + +/*! + \brief exit Pretended Networking mode + \param[in] can_periph: CANx(x=0,1,2) + \param[in] none + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_pn_mode_exit(uint32_t can_periph) +{ + uint32_t timeout; + + CAN_CTL0(can_periph) &= ~(CAN_CTL0_PNEN | CAN_CTL0_PNMOD); + timeout = CAN_DELAY; + while((CAN_CTL0(can_periph) & CAN_CTL0_PNS) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_PNS) { + return ERROR; + } else { + return SUCCESS; + } +} + +/*! + \brief can FD initialize + \param[in] can_periph: CANx(x=0,1,2) + \param[in] can_fd_para_init: can fd parameter struct + iso_can_fd_enable: ENABLE, DISABLE + bitrate_switch_enable: ENABLE, DISABLE + mailbox_data_size: CAN_MAILBOX_DATA_SIZE_8_BYTES, CAN_MAILBOX_DATA_SIZE_16_BYTES, + CAN_MAILBOX_DATA_SIZE_32_BYTES, CAN_MAILBOX_DATA_SIZE_64_BYTES + tdc_enable: ENABLE, DISABLE + tdc_offset: 0 ~ 31 + prescaler: 1~1024 + resync_jump_width: 1~8 + prop_time_segment: 0~31 + time_segment_1: 1~8 + time_segment_2: 2~8 + \param[out] none + \retval none +*/ +void can_fd_config(uint32_t can_periph, can_fd_parameter_struct *can_fd_para_init) +{ + /* clear register bits, then enable FD mode */ + CAN_CTL0(can_periph) &= ~CAN_CTL0_RFEN; + CAN_CTL1(can_periph) &= ~CAN_CTL1_BSPMOD; + CAN_CTL2(can_periph) &= ~CAN_CTL2_ISO; + CAN_FDCTL(can_periph) &= ~(CAN_FDCTL_BRSEN | CAN_FDCTL_MDSZ | CAN_FDCTL_TDCEN | CAN_FDCTL_TDCO); + CAN_FDBT(can_periph) &= ~(CAN_FDBT_DBAUDPSC | CAN_FDBT_DSJW | CAN_FDBT_DPTS | CAN_FDBT_DPBS1 | CAN_FDBT_DPBS2); + CAN_CTL0(can_periph) |= CAN_CTL0_FDEN; + + /* support ISO or non-ISO mode */ + if((uint32_t)ENABLE == can_fd_para_init->iso_can_fd_enable) { + CAN_CTL2(can_periph) |= CAN_CTL2_ISO; + } + /* set TDC parameter */ + if((uint32_t)ENABLE == can_fd_para_init->tdc_enable) { + CAN_FDCTL(can_periph) |= CAN_FDCTL_TDCEN; + } + /* set data bit rate */ + if((uint32_t)ENABLE == can_fd_para_init->bitrate_switch_enable) { + CAN_FDCTL(can_periph) |= CAN_FDCTL_BRSEN; + } + + /* set mailbox data size */ + CAN_FDCTL(can_periph) |= can_fd_para_init->mailbox_data_size; + /* configure FD bit timing */ + CAN_FDBT(can_periph) |= (uint32_t)(FDBT_DBAUDPSC(can_fd_para_init->prescaler - 1U) | + FDBT_DSJW((uint32_t)can_fd_para_init->resync_jump_width - 1U) | + FDBT_DPTS(can_fd_para_init->prop_time_segment) | + FDBT_DPBS1((uint32_t)can_fd_para_init->time_segment_1 - 1U) | + FDBT_DPBS2((uint32_t)can_fd_para_init->time_segment_2 - 1U)); + /* configure transmitter delay compensation offset */ + CAN_FDCTL(can_periph) |= FDCTL_TDCO(can_fd_para_init->tdc_offset); +} + +/*! + \brief enable bit rate switching + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_bitrate_switch_enable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) |= CAN_FDCTL_BRSEN; +} + +/*! + \brief disable bit rate switching + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_bitrate_switch_disable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) &= ~CAN_FDCTL_BRSEN; +} + +/*! + \brief get transmitter delay compensation value + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval 0 - 0x3F +*/ +uint32_t can_tdc_get(uint32_t can_periph) +{ + uint32_t reg = 0U; + + reg = CAN_FDCTL(can_periph); + + return GET_FDCTL_TDCV(reg); +} + +/*! + \brief enable transmitter delay compensation + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_tdc_enable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) |= CAN_FDCTL_TDCEN; +} + +/*! + \brief disable transmitter delay compensation + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_tdc_disable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) &= ~CAN_FDCTL_TDCEN; +} + +/*! + \brief configure rx FIFO + \param[in] can_periph: CANx(x=0,1,2) + \param[in] can_fifo_para_init: fifo parameter struct + dma_enable: ENABLE, DISABLE + filter_format_and_number: CAN_RXFIFO_FILTER_A_NUM_8, CAN_RXFIFO_FILTER_A_NUM_16, CAN_RXFIFO_FILTER_A_NUM_24, CAN_RXFIFO_FILTER_A_NUM_32, + CAN_RXFIFO_FILTER_A_NUM_40, CAN_RXFIFO_FILTER_A_NUM_48, CAN_RXFIFO_FILTER_A_NUM_56, CAN_RXFIFO_FILTER_A_NUM_64, + CAN_RXFIFO_FILTER_A_NUM_72, CAN_RXFIFO_FILTER_A_NUM_80, CAN_RXFIFO_FILTER_A_NUM_88, CAN_RXFIFO_FILTER_A_NUM_96, CAN_RXFIFO_FILTER_A_NUM_104, + CAN_RXFIFO_FILTER_B_NUM_16, CAN_RXFIFO_FILTER_B_NUM_32, CAN_RXFIFO_FILTER_B_NUM_48, CAN_RXFIFO_FILTER_B_NUM_64, + CAN_RXFIFO_FILTER_B_NUM_80, CAN_RXFIFO_FILTER_B_NUM_96, CAN_RXFIFO_FILTER_B_NUM_112, CAN_RXFIFO_FILTER_B_NUM_128, + CAN_RXFIFO_FILTER_B_NUM_144, CAN_RXFIFO_FILTER_B_NUM_160, CAN_RXFIFO_FILTER_B_NUM_176, CAN_RXFIFO_FILTER_B_NUM_192, CAN_RXFIFO_FILTER_B_NUM_208, + CAN_RXFIFO_FILTER_C_NUM_32, CAN_RXFIFO_FILTER_C_NUM_64, CAN_RXFIFO_FILTER_C_NUM_96, CAN_RXFIFO_FILTER_C_NUM_128, + CAN_RXFIFO_FILTER_C_NUM_160, CAN_RXFIFO_FILTER_C_NUM_192, CAN_RXFIFO_FILTER_C_NUM_224, CAN_RXFIFO_FILTER_C_NUM_256, + CAN_RXFIFO_FILTER_C_NUM_288, CAN_RXFIFO_FILTER_C_NUM_320, CAN_RXFIFO_FILTER_C_NUM_352, CAN_RXFIFO_FILTER_C_NUM_384, CAN_RXFIFO_FILTER_C_NUM_416, + CAN_RXFIFO_FILTER_D + fifo_public_filter: 0x00000000 ~ 0xFFFFFFFF + \param[out] none + \retval none +*/ +void can_rx_fifo_config(uint32_t can_periph, can_fifo_parameter_struct *can_fifo_para_init) +{ + uint32_t num; + + /* clear register bits, disable FD mode, then enable rx FIFO mode */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_FDEN | CAN_CTL0_DMAEN | CAN_CTL0_FS); + CAN_CTL2(can_periph) &= ~CAN_CTL2_RFFN; + CAN_CTL0(can_periph) |= CAN_CTL0_RFEN; + + /* clear FIFO status */ + CAN_STAT(can_periph) = (uint32_t)0xFFFFFFFFU; + while(CAN_STAT(can_periph) & CAN_STAT_MS5_RFNE) { + CAN_STAT(can_periph) = CAN_STAT_MS5_RFNE; + } + + /* set DMA mode */ + if((uint8_t)ENABLE == can_fifo_para_init->dma_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_DMAEN; + } + + /* configure filter format */ + CAN_CTL0(can_periph) |= (can_fifo_para_init->filter_format_and_number & CAN_CTL0_FS); + /* configure filter number */ + CAN_CTL2(can_periph) |= (can_fifo_para_init->filter_format_and_number & CAN_CTL2_RFFN); + /* configure fifo public fiter */ + CAN_RFIFOPUBF(can_periph) = can_fifo_para_init->fifo_public_filter; + /* configure fifo private fiter */ + if(!(CAN_CTL0(can_periph) & CAN_CTL0_RPFQEN)) { + for(num = 0U; num < CAN_MAX_MAILBOX_NUM; num++) { + CAN_RFIFOMPF(can_periph, num) = can_fifo_para_init->fifo_public_filter; + } + } +} + +/*! + \brief configure rx FIFO filter table + \param[in] can_periph: CANx(x=0,1,2) + \param[in] id_filter_table: id filter table struct + remote_frame: CAN_DATA_FRAME_ACCEPTED, CAN_REMOTE_FRAME_ACCEPTED + extended_frame: CAN_STANDARD_FRAME_ACCEPTED, CAN_EXTENDED_FRAME_ACCEPTED + id: 11 bits for standard frame, 29 bits for extended frame + \param[out] none + \retval none +*/ +void can_rx_fifo_filter_table_config(uint32_t can_periph, can_rx_fifo_id_filter_struct id_filter_table[]) +{ + /* set rx FIFO ID filter table elements */ + uint32_t i = 0U, j = 0U, num_of_filters = 0U; + uint32_t val = 0U; + uint32_t id_format = 0U; + uint32_t *filter_table = (uint32_t *)(uint32_t)(CAN_RAM(can_periph) + 0x00000060U); + + num_of_filters = (GET_CTL2_RFFN(CAN_CTL2(can_periph)) + 1U) * 8U; + id_format = CAN_CTL0(can_periph) & CAN_CTL0_FS; + + switch(id_format) { + case(CAN_FIFO_FILTER_FORMAT_A): + /* one full id (standard and extended) per id filter table element */ + for(i = 0U; i < num_of_filters; i++) { + val = 0U; + + if(CAN_REMOTE_FRAME_ACCEPTED == id_filter_table[i].remote_frame) { + val |= CAN_FDESX_RTR_A; + } + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[i].extended_frame) { + val |= CAN_FDESX_IDE_A; + val |= (uint32_t)FIFO_FILTER_ID_EXD_A(id_filter_table[i].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_A(id_filter_table[i].id); + } + filter_table[i] = val; + } + break; + case(CAN_FIFO_FILTER_FORMAT_B): + /* two full standard id or two partial 14-bit (standard and extended) id */ + j = 0U; + for(i = 0U; i < num_of_filters; i++) { + val = 0U; + + if(CAN_REMOTE_FRAME_ACCEPTED == id_filter_table[j].remote_frame) { + val |= CAN_FDESX_RTR_B0; + } + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= CAN_FDESX_IDE_B0; + val |= (uint32_t)FIFO_FILTER_ID_EXD_B0(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_B0(id_filter_table[j].id); + } + j++; + + if(CAN_REMOTE_FRAME_ACCEPTED == id_filter_table[j].remote_frame) { + val |= CAN_FDESX_RTR_B1; + } + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= CAN_FDESX_IDE_B1; + val |= (uint32_t)FIFO_FILTER_ID_EXD_B1(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_B1(id_filter_table[j].id); + } + j++; + + filter_table[i] = val; + } + break; + case(CAN_FIFO_FILTER_FORMAT_C): + /* four partial 8-bit standard id per id filter table element */ + j = 0U; + for(i = 0U; i < num_of_filters; i++) { + val = 0U; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C0(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C0(id_filter_table[j].id); + } + j++; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C1(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C1(id_filter_table[j].id); + } + j++; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C2(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C2(id_filter_table[j].id); + } + j++; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C3(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C3(id_filter_table[j].id); + } + j++; + + filter_table[i] = val; + } + break; + case(CAN_FIFO_FILTER_FORMAT_D): + /* all frames rejected */ + break; + default: + /* should not get here */ + break; + } +} + +/*! + \brief read rx FIFO data + \param[in] can_periph: CANx(x=0,1,2) + \param[out] rx_fifo: rx FIFO struct + \retval none +*/ +void can_rx_fifo_read(uint32_t can_periph, can_rx_fifo_struct *rx_fifo) +{ + uint32_t *rx_fifo_addr = (uint32_t *)rx_fifo; + uint32_t *can_mb = (uint32_t *)CAN_RAM(can_periph); + + /* read FIFO descriptor 0 */ + rx_fifo_addr[0] = can_mb[0]; + rx_fifo_addr[1] = can_mb[1]; + rx_fifo->data[0] = can_mb[2]; + rx_fifo->data[1] = can_mb[3]; + + /* clear FIFO status */ + CAN_STAT(can_periph) = CAN_STAT_MS5_RFNE; + + /* read FIFO id field */ + if(rx_fifo->ide) { + rx_fifo->id = GET_FDES1_ID_EXD(rx_fifo->id); + } else { + rx_fifo->id = GET_FDES1_ID_STD(rx_fifo->id); + } + + /* read FIFO data */ + can_data_to_little_endian_swap(rx_fifo->data, rx_fifo->data, rx_fifo->dlc); +} + +/*! + \brief get rx FIFO filter matching number + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval filter number +*/ +uint32_t can_rx_fifo_filter_matching_number_get(uint32_t can_periph) +{ + return GET_RFIFOIFMN_IDFMN(CAN_RFIFOIFMN(can_periph)); +} + +/*! + \brief clear rx FIFO + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_rx_fifo_clear(uint32_t can_periph) +{ + CAN_STAT(can_periph) = CAN_STAT_MS0_RFC; +} + +/*! + \brief get mailbox RAM address + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index, 0-31 + \param[out] none + \retval pointer to the mailbox address +*/ +uint32_t *can_ram_address_get(uint32_t can_periph, uint32_t index) +{ + uint32_t payload_size; + uint32_t *address; + + /* if CAN FD mode is enabled */ + if(CAN_CTL0(can_periph) & CAN_CTL0_FDEN) { + payload_size = (uint32_t)1U << (GET_FDCTL_MDSZ(CAN_FDCTL(can_periph)) + 3U); + } else { + payload_size = 8U; + } + address = (uint32_t *)(uint32_t)(CAN_RAM(can_periph) + (payload_size + 8U) * index); + + return address; +} + +/*! + \brief configure mailbox + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[in] mdpara: mailbox descriptor struct + rtr: 0, 1 + ide: 0, 1 + id: 0 - 0x1FFFFFFF + code: CAN_MB_RX_STATUS_INACTIVE, CAN_MB_RX_STATUS_FULL, CAN_MB_RX_STATUS_EMPTY, + CAN_MB_RX_STATUS_OVERRUN, CAN_MB_RX_STATUS_RANSWER, CAN_MB_RX_STATUS_BUSY, + CAN_MB_TX_STATUS_INACTIVE, CAN_MB_TX_STATUS_ABORT, CAN_MB_TX_STATUS_DATA + data_bytes: 0 - 64 + data: point to the data + esi: 0, 1 + fdf: 0, 1 + brs: 0, 1 + prio: 0 - 7 + \param[out] none + \retval none +*/ +void can_mailbox_config(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara) +{ + uint32_t dlc; + uint32_t mdes0 = 0U; + uint32_t length; + uint32_t *mdes; + + /* clear mailbox status */ + CAN_STAT(can_periph) = STAT_MS(index); + + /* get mailbox base address */ + mdes = can_ram_address_get(can_periph, index); + mdes[0] = 0U; + mdes[1] = 0U; + mdes[2] = 0U; + mdes[3] = 0U; + + /* set RTR bit */ + if(mdpara->rtr) { + mdes0 |= CAN_MDES0_RTR; + } + + /* set IDE bit and ID field */ + if(mdpara->ide) { + mdes0 |= CAN_MDES0_IDE; + mdes0 |= CAN_MDES0_SRR; + mdes[1] |= MDES1_ID_EXD(mdpara->id); + } else { + mdes[1] |= MDES1_ID_STD(mdpara->id); + } + + /* set CODE field */ + mdes0 |= MDES0_CODE(mdpara->code); + + if(mdpara->code != CAN_MB_RX_STATUS_EMPTY) { + /* copy user's buffer into the mailbox data area */ + if(mdpara->data_bytes) { + dlc = can_dlc_value_compute(mdpara->data_bytes); + mdes0 |= MDES0_DLC(dlc); + length = (uint32_t)1U << (GET_FDCTL_MDSZ(CAN_FDCTL(can_periph)) + 3U); + if(mdpara->data_bytes < length) { + length = mdpara->data_bytes; + } + can_data_to_big_endian_swap(&mdes[2], mdpara->data, length); + } + + /* prepare mailbox for transmission */ + if(CAN_MB_TX_STATUS_DATA == mdpara->code) { + /* set ESI bit */ + if(mdpara->esi) { + mdes0 |= CAN_MDES0_ESI; + } + /* set FDF and BRS bit */ + if(mdpara->fdf) { + mdes0 |= CAN_MDES0_FDF; + if(mdpara->brs) { + mdes0 |= CAN_MDES0_BRS; + } + mdes0 &= ~CAN_MDES0_RTR; + } + } + + /* set PRIO field */ + mdes[1] |= MDES1_PRIO(mdpara->prio); + } + + /* set mailbox descriptor 0 */ + mdes[0] = mdes0; +} + +/*! + \brief abort mailbox transmit + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_transmit_abort(uint32_t can_periph, uint32_t index) +{ + uint32_t mdes0; + uint32_t *mdes; + + /* abort transmit mailbox */ + mdes = can_ram_address_get(can_periph, index); + mdes0 = mdes[0]; + mdes0 &= ~CAN_MDES0_CODE; + mdes0 |= MDES0_CODE(CAN_MB_TX_STATUS_ABORT); + mdes[0] = mdes0; +} + +/*! + \brief inactive transmit mailbox + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_transmit_inactive(uint32_t can_periph, uint32_t index) +{ + uint32_t mdes0; + uint32_t *mdes; + + /* inactive transmit mailbox */ + mdes = can_ram_address_get(can_periph, index); + mdes0 = mdes[0]; + mdes0 &= ~CAN_MDES0_CODE; + mdes0 |= MDES0_CODE(CAN_MB_TX_STATUS_INACTIVE); + mdes[0] = mdes0; +} + +/*! + \brief read receive mailbox data + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] mdpara: mailbox descriptor struct + \retval ERROR or SUCCESS +*/ +ErrStatus can_mailbox_receive_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara) +{ + uint32_t i; + uint32_t cnt; + uint32_t timeout; + uint32_t *mdes = can_ram_address_get(can_periph, index); + uint32_t *mdaddr = (uint32_t *)mdpara; + + /* wait mailbox data ready */ + timeout = CAN_DELAY; + while((mdes[0] & MDES0_CODE(CAN_MB_RX_STATUS_BUSY)) && (timeout)) { + timeout--; + } + if(mdes[0] & MDES0_CODE(CAN_MB_RX_STATUS_BUSY)) { + return ERROR; + } + + /* get mailbox descriptor 0 */ + mdaddr[0] = mdes[0]; + mdaddr[1] = mdes[1]; + mdpara->data_bytes = can_payload_size_compute(mdaddr[0]); + cnt = (mdpara->data_bytes + 3U) / 4U; + mdaddr = mdpara->data; + mdes += 2U; + for(i = 0U; i < cnt; i++) { + mdaddr[i] = mdes[i]; + } + + /* clear mailbox status */ + CAN_STAT(can_periph) = STAT_MS(index); + /* unlock mailbox */ + CAN_TIMER(can_periph); + + /* get mailbox ID */ + if(mdpara->ide) { + mdpara->id = GET_MDES1_ID_EXD(mdpara->id); + } else { + mdpara->id = GET_MDES1_ID_STD(mdpara->id); + } + + /* get mailbox data */ + if(mdpara->data_bytes) { + can_data_to_little_endian_swap(mdpara->data, mdpara->data, mdpara->data_bytes); + } + + return SUCCESS; +} + +/*! + \brief lock the receive mailbox + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_receive_lock(uint32_t can_periph, uint32_t index) +{ + uint32_t *mdes; + + mdes = can_ram_address_get(can_periph, index); + REG32((uint32_t)mdes); +} + +/*! + \brief unlock the receive mailbox + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_mailbox_receive_unlock(uint32_t can_periph) +{ + CAN_TIMER(can_periph); +} + +/*! + \brief inactive the receive mailbox + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_receive_inactive(uint32_t can_periph, uint32_t index) +{ + uint32_t mdes0; + uint32_t *mdes; + + /* inactive receive mailbox */ + mdes = can_ram_address_get(can_periph, index); + mdes0 = mdes[0]; + mdes0 &= ~CAN_MDES0_CODE; + mdes0 |= MDES0_CODE(CAN_MB_RX_STATUS_INACTIVE); + mdes[0] = mdes0; +} + +/*! + \brief get mailbox code value + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: mailbox index(0~31) + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval mailbox code +*/ +uint32_t can_mailbox_code_get(uint32_t can_periph, uint32_t index) +{ + uint32_t code; + uint32_t *mdes; + + mdes = can_ram_address_get(can_periph, index); + code = GET_MDES0_CODE(mdes[0]); + + return code; +} + +/*! + \brief configure error counter + \param[in] can_periph: CANx(x=0,1,2) + \param[in] errcnt_struct + fd_data_phase_rx_errcnt: 0-255 + fd_data_phase_tx_errcnt: 0-255 + rx_errcnt: 0-255 + tx_errcnt: 0-255 + \retval none +*/ +void can_error_counter_config(uint32_t can_periph, can_error_counter_struct *errcnt_struct) +{ + CAN_ERR0(can_periph) = ERR0_REFCNT(errcnt_struct->fd_data_phase_rx_errcnt) | ERR0_TEFCNT(errcnt_struct->fd_data_phase_tx_errcnt) | \ + ERR0_RECNT(errcnt_struct->rx_errcnt) | ERR0_TECNT(errcnt_struct->tx_errcnt); +} + +/*! + \brief get error counter + \param[in] can_periph: CANx(x=0,1,2) + \param[out] errcnt_struct + fd_data_phase_rx_errcnt: 0-255 + fd_data_phase_tx_errcnt: 0-255 + rx_errcnt: 0-255 + tx_errcnt: 0-255 + \retval none +*/ +void can_error_counter_get(uint32_t can_periph, can_error_counter_struct *errcnt_struct) +{ + uint32_t reg = 0U; + + reg = CAN_ERR0(can_periph); + errcnt_struct->fd_data_phase_rx_errcnt = (uint8_t)GET_ERR0_REFCNT(reg); + errcnt_struct->fd_data_phase_tx_errcnt = (uint8_t)GET_ERR0_TEFCNT(reg); + errcnt_struct->rx_errcnt = (uint8_t)GET_ERR0_RECNT(reg); + errcnt_struct->tx_errcnt = (uint8_t)GET_ERR0_TECNT(reg); +} + +/*! + \brief get error state indicator + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval CAN_ERROR_STATE_ACTIVE, CAN_ERROR_STATE_PASSIVE or CAN_ERROR_STATE_BUS_OFF +*/ +can_error_state_enum can_error_state_get(uint32_t can_periph) +{ + uint32_t reg; + + reg = GET_ERR1_ERRSI(CAN_ERR1(can_periph)); + if(reg >= (uint32_t)CAN_ERROR_STATE_BUS_OFF) { + reg = (uint32_t)CAN_ERROR_STATE_BUS_OFF; + } + + return (can_error_state_enum)reg; +} + +/*! + \brief get mailbox CRC value + \param[in] can_periph: CANx(x=0,1,2) + \param[out] crc_struct: + classical_frm_mb_number: 0 - 0x1F + classical_frm_transmitted_crc: 0 - 0x7FFF + classical_fd_frm_mb_number: 0 - 0x1F + classical_fd_frm_transmitted_crc: 0 - 0x1FFFFF + \retval none +*/ +void can_crc_get(uint32_t can_periph, can_crc_struct *crc_struct) +{ + uint32_t reg1 = 0U, reg2 = 0U; + + reg1 = CAN_CRCC(can_periph); + reg2 = CAN_CRCCFD(can_periph); + crc_struct->classical_frm_mb_number = GET_CRCC_ANTM(reg1); + crc_struct->classical_frm_transmitted_crc = GET_CRCC_CRCTC(reg1); + crc_struct->classical_fd_frm_mb_number = GET_CRCCFD_ANTM(reg2); + crc_struct->classical_fd_frm_transmitted_crc = GET_CRCCFD_CRCTCI(reg2); +} + +/*! + \brief configure Pretended Networking mode parameter + \param[in] can_periph: CANx(x=0,1,2) + \param[in] pnmod_config: Pretended Networking mode config struct + timeout_int: ENABLE, DISABLE + match_int: ENABLE, DISABLE + num_matches: 1 ~ 255 + match_timeout: 0 ~ 0xFFFF + frame_filter: CAN_PN_FRAME_FILTERING_ID, CAN_PN_FRAME_FILTERING_ID_DATA + CAN_PN_FRAME_FILTERING_ID_NMM, CAN_PN_FRAME_FILTERING_ID_DATA_NMM + id_filter: CAN_PN_ID_FILTERING_EXACT, CAN_PN_ID_FILTERING_GREATER + CAN_PN_ID_FILTERING_SMALLER, CAN_PN_ID_FILTERING_RANGE + data_filter: CAN_PN_DATA_FILTERING_EXACT, CAN_PN_DATA_FILTERING_GREATER + CAN_PN_DATA_FILTERING_SMALLER, CAN_PN_DATA_FILTERING_RANGE + \param[out] none + \retval none +*/ +void can_pn_mode_config(uint32_t can_periph, can_pn_mode_config_struct *pnmod_config) +{ + uint32_t tmp; + + /* configure specific Pretended Networking mode settings */ + tmp = CAN_PN_CTL0(can_periph); + tmp &= ~(CAN_PN_CTL0_FFT | CAN_PN_CTL0_IDFT | CAN_PN_CTL0_DATAFT | + CAN_PN_CTL0_NMM | CAN_PN_CTL0_WMIE | CAN_PN_CTL0_WTOIE); + tmp |= (uint32_t)PN_CTL0_WTOIE(pnmod_config->timeout_int) | PN_CTL0_WMIE(pnmod_config->match_int) | \ + PN_CTL0_NMM(pnmod_config->num_matches) | pnmod_config->data_filter | \ + pnmod_config->id_filter | pnmod_config->frame_filter; + + CAN_PN_CTL0(can_periph) = tmp; + + /* set timeout value */ + CAN_PN_TO(can_periph) &= ~CAN_PN_TO_WTO; + CAN_PN_TO(can_periph) |= (uint32_t)PN_TO_WTO(pnmod_config->match_timeout); + + /* enable Pretended Networking mode */ + CAN_CTL0(can_periph) |= CAN_CTL0_PNMOD; +} + +/*! + \brief configure Pretended Networking mode filter + \param[in] can_periph: CANx(x=0,1,2) + \param[in] expect: Pretended Networking mode struct of expected wakeup frame + rtr: SET, RESET + ide: SET, RESET + id: 0~0x7FF | CAN_STANDARD, or 0~0x1FFFFFFF | CAN_EXTENDED + dlc_high_threshold: 0~8 + dlc_low_threshold: 0~8 + payload[0]: 0x00000000~0xFFFFFFFF + payload[1]: 0x00000000~0xFFFFFFFF + \param[in] filter: Pretended Networking mode struct of filter data + remote_frame: SET, RESET + extended_frame: SET, RESET + id: 0~0x7FF | CAN_STANDARD, or 0~0x1FFFFFFF | CAN_EXTENDED. Used as id filter data, or id expected high threshold. + payload[0]: 0x00000000~0xFFFFFFFF. Used as payload filter data, or payload expected high threshold. + payload[1]: 0x00000000~0xFFFFFFFF. Used as payload filter data, or payload expected high threshold. + \param[out] none + \retval none +*/ +void can_pn_mode_filter_config(uint32_t can_periph, can_pn_mode_filter_struct *expect, can_pn_mode_filter_struct *filter) +{ + uint32_t reg, temp; + + /* set filter identifier 0 */ + reg = 0U; + if((uint32_t)SET == expect->ide) { + reg |= CAN_PN_EID0_EIDE; + } + if((uint32_t)SET == expect->rtr) { + reg |= CAN_PN_EID0_ERTR; + } + if(CAN_STANDARD == (expect->id & BIT(31))){ + reg |= (uint32_t)PN_EID0_EIDF_ELT_STD(expect->id); + }else{ + reg |= (uint32_t)PN_EID0_EIDF_ELT_EXD(expect->id); + } + + CAN_PN_EID0(can_periph) = reg; + + temp = CAN_PN_CTL0(can_periph); + reg = 0U; + /* ID field 1 is used when ID filtering type is EXACT or RANGE */ + if(((temp & CAN_PN_CTL0_IDFT) == CAN_PN_ID_FILTERING_EXACT) || ((temp & CAN_PN_CTL0_IDFT) == CAN_PN_ID_FILTERING_RANGE)) { + if(CAN_STANDARD == (filter->id & BIT(31))){ + reg |= (uint32_t)PN_IFEID1_IDEFD_STD(filter->id); + }else{ + reg |= (uint32_t)PN_IFEID1_IDEFD_EXD(filter->id); + } + } + if((uint32_t)SET == filter->ide) { + reg |= CAN_PN_IFEID1_IDEFD; + } + if((uint32_t)SET == filter->rtr) { + reg |= CAN_PN_IFEID1_RTRFD; + } + /* set filter identifier 1 */ + CAN_PN_IFEID1(can_periph) = reg; + + /* data field is used when frame filtering type is not MATCH or MATCH NMM */ + if(((temp & CAN_PN_CTL0_FFT) == CAN_PN_FRAME_FILTERING_ID_DATA) || + ((temp & CAN_PN_CTL0_FFT) == CAN_PN_FRAME_FILTERING_ID_DATA_NMM)) { + /* set filter data payload 0 */ + CAN_PN_EDLC(can_periph) = PN_EDLC_DLCEHT(expect->dlc_high_threshold) | PN_EDLC_DLCELT(expect->dlc_low_threshold); + CAN_PN_EDL0(can_periph) = ((expect->payload[0] << 24U) & CAN_PN_EDL0_DB0ELT) | + ((expect->payload[0] << 8U) & CAN_PN_EDL0_DB1ELT) | + ((expect->payload[0] >> 8U) & CAN_PN_EDL0_DB2ELT) | + ((expect->payload[0] >> 24U) & CAN_PN_EDL0_DB3ELT); + CAN_PN_EDL1(can_periph) = ((expect->payload[1] << 24U) & CAN_PN_EDL1_DB4ELT) | + ((expect->payload[1] << 8U) & CAN_PN_EDL1_DB5ELT) | + ((expect->payload[1] >> 8U) & CAN_PN_EDL1_DB6ELT) | + ((expect->payload[1] >> 24U) & CAN_PN_EDL1_DB7ELT); + + /* data field 1 is used when data filtering type is EXACT or RANGE */ + if(((temp & CAN_PN_CTL0_DATAFT) == CAN_PN_DATA_FILTERING_EXACT) + || ((temp & CAN_PN_CTL0_DATAFT) == CAN_PN_DATA_FILTERING_RANGE)) { + /* set filter data payload 1 */ + CAN_PN_DF0EDH0(can_periph) = ((filter->payload[0] << 24U) & CAN_PN_DF0EDH0_DB0FD_EHT) | + ((filter->payload[0] << 8U) & CAN_PN_DF0EDH0_DB1FD_EHT) | + ((filter->payload[0] >> 8U) & CAN_PN_DF0EDH0_DB2FD_EHT) | + ((filter->payload[0] >> 24U) & CAN_PN_DF0EDH0_DB3FD_EHT); + CAN_PN_DF1EDH1(can_periph) = ((filter->payload[1] << 24U) & CAN_PN_DF1EDH1_DB4FD_EHT) | + ((filter->payload[1] << 8U) & CAN_PN_DF1EDH1_DB5FD_EHT) | + ((filter->payload[1] >> 8U) & CAN_PN_DF1EDH1_DB6FD_EHT) | + ((filter->payload[1] >> 24U) & CAN_PN_DF1EDH1_DB7FD_EHT); + } + } +} + + +/*! + \brief get matching message counter of Pretended Networking mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval 0~255 or -1 +*/ +int32_t can_pn_mode_num_of_match_get(uint32_t can_periph) +{ + int32_t ret = 0; + uint32_t reg = 0U; + + reg = CAN_PN_STAT(can_periph); + if(0U != (reg & CAN_PN_STAT_MMCNTS)) { + ret = (int32_t)(uint32_t)GET_PN_STAT_MMCNT(reg); + } else { + ret = -1; + } + return ret; +} + +/*! + \brief get matching message + \param[in] can_periph: CANx(x=0,1,2) + \param[in] index: Pretended Networking mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] mdpara: wakeup message information + \retval none +*/ +void can_pn_mode_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara) +{ + uint32_t *mdaddr = (uint32_t *)mdpara; + uint32_t *pnram = (uint32_t *)(uint32_t)(CAN_PN_RAM(can_periph) + index * 16U); + + mdaddr[0] = pnram[0]; + mdaddr[1] = pnram[1]; + /* get mailbox ID */ + if(0U != mdpara->ide) { + mdpara->id = GET_MDES1_ID_EXD(mdpara->id); + } else { + mdpara->id = GET_MDES1_ID_STD(mdpara->id); + } + mdpara->data_bytes = mdpara->dlc; + /* remote frame */ + if(0U != (mdaddr[0] & CAN_PN_RWMXCS_RRTR)){ + mdpara->data_bytes = 0U; + }else{ + /* classical frame */ + if(mdpara->dlc <= 8U) { + mdpara->data_bytes = mdpara->dlc; + }else{ + mdpara->data_bytes = 8U; + } + } + if(mdpara->data_bytes) { + can_data_to_little_endian_swap(mdpara->data, &pnram[2], mdpara->data_bytes); + } +} + +/*! + \brief enable self reception + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_self_reception_enable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) &= ~CAN_CTL0_SRDIS; +} + +/*! + \brief disable self reception + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_self_reception_disable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) |= CAN_CTL0_SRDIS; +} + +/*! + \brief enable transmit abort + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_transmit_abort_enable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) |= CAN_CTL0_MST; +} + +/*! + \brief disable transmit abort + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_transmit_abort_disable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) &= ~CAN_CTL0_MST; +} + +/*! + \brief enable auto bus off recovery mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_auto_busoff_recovery_enable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) &= ~CAN_CTL1_ABORDIS; +} + +/*! + \brief disable auto bus off recovery mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_auto_busoff_recovery_disable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) |= CAN_CTL1_ABORDIS; +} + +/*! + \brief enable time sync mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_time_sync_enable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) |= CAN_CTL1_TSYNC; +} + +/*! + \brief disable time sync mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_time_sync_disable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) &= ~CAN_CTL1_TSYNC; +} + +/*! + \brief enable edge filter mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_edge_filter_mode_enable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) &= ~CAN_CTL2_EFDIS; +} + +/*! + \brief disable edge filter mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_edge_filter_mode_disable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) |= CAN_CTL2_EFDIS; +} + +/*! + \brief enable protocol exception detection mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_ped_mode_enable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) |= CAN_CTL2_PREEN; +} + +/*! + \brief disable protocol exception detection mode + \param[in] can_periph: CANx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_ped_mode_disable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) &= ~CAN_CTL2_PREEN; +} + +/*! + \brief configure arbitration delay bits + \param[in] can_periph: CANx(x=0,1,2) + \param[in] delay_bits: delay bits + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_arbitration_delay_bits_config(uint32_t can_periph, uint32_t delay_bits) +{ + CAN_CTL2(can_periph) &= ~CAN_CTL2_ASD; + CAN_CTL2(can_periph) |= (uint32_t)CTL2_ASD(delay_bits); +} + +/*! + \brief configure bit sampling mode + \param[in] can_periph: CANx(x=0,1,2) + \param[in] sampling_mode: bit sampling mode + only one parameter can be selected which is shown as below: + \arg CAN_BSP_MODE_ONE_SAMPLE: one sample for received bit + \arg CAN_BSP_MODE_THREE_SAMPLES: three samples for received bit + \param[out] none + \retval none +*/ +void can_bsp_mode_config(uint32_t can_periph, uint32_t sampling_mode) +{ + if(CAN_BSP_MODE_ONE_SAMPLE == sampling_mode) { + CAN_CTL1(can_periph) &= ~CAN_CTL1_BSPMOD; + } else { + CAN_CTL1(can_periph) |= CAN_CTL1_BSPMOD; + } +} + +/*! + \brief get CAN flag + \param[in] can_periph: CANx(x=0,1,2) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_CAN_PN: Pretended Networking state flag + \arg CAN_FLAG_SOFT_RST: software reset flag + \arg CAN_FLAG_ERR_SUMMARY: error summary flag + \arg CAN_FLAG_BUSOFF: bus off flag + \arg CAN_FLAG_RECEIVING: receiving state flag + \arg CAN_FLAG_TRANSMITTING: transmitting state flag + \arg CAN_FLAG_IDLE: IDLE state flag + \arg CAN_FLAG_RX_WARNING: receive warning flag + \arg CAN_FLAG_TX_WARNING: transmit warning flag + \arg CAN_FLAG_STUFF_ERR: stuff error flag + \arg CAN_FLAG_FORM_ERR: form error flag + \arg CAN_FLAG_CRC_ERR: CRC error flag + \arg CAN_FLAG_ACK_ERR: ACK error flag + \arg CAN_FLAG_BIT_DOMINANT_ERR: bit dominant error flag + \arg CAN_FLAG_BIT_RECESSIVE_ERR: bit recessive error flag + \arg CAN_FLAG_SYNC_ERR: synchronization flag + \arg CAN_FLAG_BUSOFF_RECOVERY: bus off recovery flag + \arg CAN_FLAG_ERR_SUMMARY_FD: fd error summary flag + \arg CAN_FLAG_ERR_OVERRUN: error overrun flag + \arg CAN_FLAG_STUFF_ERR_FD: stuff error in FD data phase flag + \arg CAN_FLAG_FORM_ERR_FD: form error in FD data phase flag + \arg CAN_FLAG_CRC_ERR_FD: CRC error in FD data phase flag + \arg CAN_FLAG_BIT_DOMINANT_ERR_FD: bit dominant error in FD data phase flag + \arg CAN_FLAG_BIT_RECESSIVE_ERR_FD: bit recessive error in FD data phase flag + \arg CAN_FLAG_MBx(x=0~31): mailbox x flag + \arg CAN_FLAG_FIFO_AVAILABLE: fifo available flag + \arg CAN_FLAG_FIFO_WARNING: fifo warning flag + \arg CAN_FLAG_FIFO_OVERFLOW: fifo overflow flag + \arg CAN_FLAG_WAKEUP_MATCH: Pretended Networking match flag + \arg CAN_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup flag + \arg CAN_FLAG_TDC_OUT_OF_RANGE: transmitter delay is out of compensation range flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) +{ + if(CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear CAN flag + \param[in] can_periph: CANx(x=0,1,2) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_ERR_SUMMARY: error summary flag + \arg CAN_FLAG_BUSOFF: bus off flag + \arg CAN_FLAG_BUSOFF_RECOVERY: bus off recovery flag + \arg CAN_FLAG_ERR_SUMMARY_FD: fd error summary flag + \arg CAN_FLAG_ERR_OVERRUN: error overrun flag + \arg CAN_FLAG_MBx(x=0~31): mailbox x flag + \arg CAN_FLAG_FIFO_AVAILABLE: fifo available flag + \arg CAN_FLAG_FIFO_WARNING: fifo warning flag + \arg CAN_FLAG_FIFO_OVERFLOW: fifo overflow flag + \arg CAN_FLAG_WAKEUP_MATCH: Pretended Networking match flag + \arg CAN_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup flag + \arg CAN_FLAG_TDC_OUT_OF_RANGE: transmitter delay is out of compensation range flag + \param[out] none + \retval none +*/ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag) +{ + if(CAN_FLAG_TDC_OUT_OF_RANGE == flag) { + CAN_FDCTL(can_periph) |= CAN_FDCTL_TDCS; + } else { + CAN_REG_VAL(can_periph, flag) = BIT(CAN_BIT_POS(flag)); + } +} + +/*! + \brief enable CAN interrupt + \param[in] can_periph: CANx(x=0,1,2) + \param[in] interrupt: CAN interrupt, refer to can_interrupt_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_ERR_SUMMARY: error interrupt + \arg CAN_INT_RX_WARNING: receive warning interrupt + \arg CAN_INT_TX_WARNING: transmit warning interrupt + \arg CAN_INT_BUSOFF: bus off interrupt + \arg CAN_INT_BUSOFF_RECOVERY: bus off recovery interrupt + \arg CAN_INT_ERR_SUMMARY_FD: fd error interrupt + \arg CAN_INT_MBx(x=0~31): mailbox x interrupt + \arg CAN_INT_FIFO_AVAILABLE: fifo available interrupt + \arg CAN_INT_FIFO_WARNING: fifo warning interrupt + \arg CAN_INT_FIFO_OVERFLOW: fifo overflow interrupt + \arg CAN_INT_WAKEUP_MATCH: Pretended Networking match interrupt + \arg CAN_INT_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_interrupt_enable(uint32_t can_periph, can_interrupt_enum interrupt) +{ + can_operation_modes_enum mode = CAN_NORMAL_MODE; + ErrStatus ret = SUCCESS; + + /* enable receive or transmit warning error interrupt should enable error warning in CTL0 register */ + if((CAN_INT_RX_WARNING == interrupt) || (CAN_INT_TX_WARNING == interrupt)) { + mode = can_operation_mode_get(can_periph); + /* in INACTIVE mode */ + if(CAN_INACTIVE_MODE == mode){ + CAN_CTL0(can_periph) |= CAN_CTL0_WERREN; + }else{ + ret = can_operation_mode_enter(can_periph, CAN_INACTIVE_MODE); + if(SUCCESS == ret){ + CAN_CTL0(can_periph) |= CAN_CTL0_WERREN; + ret = can_operation_mode_enter(can_periph, mode); + } + } + } + + CAN_REG_VAL(can_periph, interrupt) |= BIT(CAN_BIT_POS(interrupt)); + return ret; +} + +/*! + \brief disable CAN interrupt + \param[in] can_periph: CANx(x=0,1,2) + \param[in] interrupt: CAN interrupt, refer to can_interrupt_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_ERR_SUMMARY: error interrupt + \arg CAN_INT_RX_WARNING: receive warning interrupt + \arg CAN_INT_TX_WARNING: transmit warning interrupt + \arg CAN_INT_BUSOFF: bus off interrupt + \arg CAN_INT_BUSOFF_RECOVERY: bus off recovery interrupt + \arg CAN_INT_ERR_SUMMARY_FD: fd error interrupt + \arg CAN_INT_MBx(x=0~31): mailbox x interrupt + \arg CAN_INT_FIFO_AVAILABLE: fifo available interrupt + \arg CAN_INT_FIFO_WARNING: fifo warning interrupt + \arg CAN_INT_FIFO_OVERFLOW: fifo overflow interrupt + \arg CAN_INT_WAKEUP_MATCH: Pretended Networking match interrupt + \arg CAN_INT_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_interrupt_disable(uint32_t can_periph, can_interrupt_enum interrupt) +{ + can_operation_modes_enum mode = CAN_NORMAL_MODE; + ErrStatus ret = SUCCESS; + + /* disable receive or transmit warning error interrupt should enable error warning in CTL0 register */ + if((0U == (CAN_CTL0(can_periph) & CAN_CTL0_WERREN)) && ((CAN_INT_RX_WARNING == interrupt) || (CAN_INT_TX_WARNING == interrupt))) { + mode = can_operation_mode_get(can_periph); + /* in INACTIVE mode */ + if(CAN_INACTIVE_MODE == mode){ + CAN_CTL0(can_periph) |= CAN_CTL0_WERREN; + }else{ + ret = can_operation_mode_enter(can_periph, CAN_INACTIVE_MODE); + if(SUCCESS == ret){ + CAN_CTL0(can_periph) |= CAN_CTL0_WERREN; + ret = can_operation_mode_enter(can_periph, mode); + } + } + } + + CAN_REG_VAL(can_periph, interrupt) &= ~BIT(CAN_BIT_POS(interrupt)); + return ret; +} + +/*! + \brief get CAN interrupt flag + \param[in] can_periph: CANx(x=0,1,2) + \param[in] int_flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_ERR_SUMMARY: error summary interrupt flag + \arg CAN_INT_FLAG_BUSOFF: bus off interrupt flag + \arg CAN_INT_FLAG_RX_WARNING: receive warning interrupt flag + \arg CAN_INT_FLAG_TX_WARNING: transmit warning interrupt flag + \arg CAN_INT_FLAG_BUSOFF_RECOVERY: bus off recovery interrupt flag + \arg CAN_INT_FLAG_ERR_SUMMARY_FD: fd error summary interrupt flag + \arg CAN_INT_FLAG_MBx(x=0~31): mailbox x interrupt flag + \arg CAN_INT_FLAG_FIFO_AVAILABLE: fifo available interrupt flag + \arg CAN_INT_FLAG_FIFO_WARNING: fifo warning interrupt flag + \arg CAN_INT_FLAG_FIFO_OVERFLOW: fifo overflow interrupt flag + \arg CAN_INT_FLAG_WAKEUP_MATCH: Pretended Networking match interrupt flag + \arg CAN_INT_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum int_flag) +{ + if(CAN_REG_VAL(can_periph, int_flag) & BIT(CAN_BIT_POS(int_flag))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear CAN interrupt flag + \param[in] can_periph: CANx(x=0,1,2) + \param[in] int_flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_ERR_SUMMARY: error summary interrupt flag + \arg CAN_INT_FLAG_BUSOFF: bus off interrupt flag + \arg CAN_INT_FLAG_RX_WARNING: receive warning interrupt flag + \arg CAN_INT_FLAG_TX_WARNING: transmit warning interrupt flag + \arg CAN_INT_FLAG_BUSOFF_RECOVERY: bus off recovery interrupt flag + \arg CAN_INT_FLAG_ERR_SUMMARY_FD: fd error summary interrupt flag + \arg CAN_INT_FLAG_MBx(x=0~31): mailbox x interrupt flag + \arg CAN_INT_FLAG_FIFO_AVAILABLE: fifo available interrupt flag + \arg CAN_INT_FLAG_FIFO_WARNING: fifo warning interrupt flag + \arg CAN_INT_FLAG_FIFO_OVERFLOW: fifo overflow interrupt flag + \arg CAN_INT_FLAG_WAKEUP_MATCH: Pretended Networking match interrupt flag + \arg CAN_INT_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt flag + \param[out] none + \retval none +*/ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum int_flag) +{ + CAN_REG_VAL(can_periph, int_flag) = BIT(CAN_BIT_POS(int_flag)); +} + +/*! + \brief computes the maximum payload size (in bytes), given a dlc + \param[in] mdes0: mailbox descriptor 0 data + \param[out] none + \retval payload_size +*/ +static uint32_t can_payload_size_compute(uint32_t mdes0) +{ + uint8_t ret = 0U; + uint32_t dlc_value = GET_MDES0_DLC(mdes0); + + /* remote frame */ + if(0U != (mdes0 & CAN_MDES0_RTR)){ + ret = 0U; + }else{ + /* FD frame */ + if(0U != (mdes0 & CAN_MDES0_FDF)){ + if(dlc_value <= 15U) { + ret = dlc_to_databytes[dlc_value]; + } + /* classical frame */ + }else{ + if(dlc_value <= 8U) { + ret = (uint8_t)dlc_value; + }else{ + ret = 8U; + } + } + } + + return (uint32_t)ret; +} + +/*! + \brief swap data to little endian + \param[in] src: data source address + \param[in] len: data length be byte + \param[out] dest: data destination address + \retval none +*/ +static void can_data_to_little_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len) +{ + volatile uint32_t i = 0U; + uint32_t cnt; + uint32_t temp_src = 0U; + + /* get the word length of the data */ + cnt = (len + 3U) / 4U; + /* change each word from big endian to little endian */ + for(i = 0U; i < cnt; i++) { + temp_src = src[i]; + dest[i] = ((uint32_t)(temp_src >> 24U) & 0x000000FFU) | + ((uint32_t)(temp_src >> 8U) & 0x0000FF00U) | + ((uint32_t)(temp_src << 8U) & 0x00FF0000U) | + ((uint32_t)(temp_src << 24U) & 0xFF000000U); + } + + cnt = len % 4U; + if(cnt) { + dest[i - 1U] &= ((uint32_t)1U << (cnt * 8U)) - 1U; + } +} + +/*! + \brief swap data to big endian + \param[in] src: data source address + \param[in] len: data length be byte + \param[out] dest: data destination address + \retval none +*/ +static void can_data_to_big_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len) +{ + volatile uint32_t i = 0U; + uint32_t cnt; + uint32_t temp_src = 0U; + + /* get the word length of the data */ + cnt = (len + 3U) / 4U; + for(i = 0U; i < cnt; i++) { + /* change each word from little endian to big endian */ + temp_src = src[i]; + dest[i] = ((uint32_t)(temp_src >> 24U) & 0x000000FFU) | + ((uint32_t)(temp_src >> 8U) & 0x0000FF00U) | + ((uint32_t)(temp_src << 8U) & 0x00FF0000U) | + ((uint32_t)(temp_src << 24U) & 0xFF000000U); + } + + cnt = len % 4U; + if(cnt) { + dest[i - 1U] &= ~(((uint32_t)1U << ((4U - cnt) * 8U)) - 1U); + } +} + +/*! + \brief computes the DLC field value, given a payload size (in bytes) + \param[in] payload_size: payload size + \param[out] none + \retval DLC value +*/ +static uint32_t can_dlc_value_compute(uint32_t payload_size) +{ + uint32_t ret = 8U; + + if(payload_size <= 8U) { + ret = payload_size; + } else if(payload_size <= 24U) { + ret = (payload_size - 9U) / 4U + 9U; + } else if(payload_size <= 64U) { + ret = (payload_size - 17U) / 16U + 13U; + } else { + ret = 8U; + } + + return ret; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau.c new file mode 100644 index 0000000000..2295d4489b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau.c @@ -0,0 +1,733 @@ +/*! + \file gd32h7xx_cau.c + \brief CAU driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_cau.h" +#include "gd32h7xx_rcu.h" + +#define FLAG_MASK ((uint32_t)0x00000020U) +#define STAT0_AESDES_MASK ((uint32_t)0x00000015U) +#define STAT0_TDES_MASK ((uint32_t)0x00000014U) + +/*! + \brief reset the CAU peripheral + \param[in] none + \param[out] none + \retval none +*/ +void cau_deinit(void) +{ + /* enable CAU reset state */ + rcu_periph_reset_enable(RCU_CAURST); + /* release CAU from reset state */ + rcu_periph_reset_disable(RCU_CAURST); +} + +/*! + \brief initialize the CAU encrypt and decrypt parameter struct with the default values + \param[in] none + \param[out] cau_parameter: + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bytes + iv: initialization vector + iv_size: iv size in bytes + input: input data + in_length: input data length in bytes + aad: additional authentication data + aad_size: header size + \retval none +*/ +void cau_struct_para_init(cau_parameter_struct *cau_parameter) +{ + /* set the CAU encrypt and decrypt parameters struct with the default values */ + cau_parameter->alg_dir = CAU_ENCRYPT; + cau_parameter->key = 0U; + cau_parameter->key_size = 0U; + cau_parameter->iv = 0U; + cau_parameter->iv_size = 0U; + cau_parameter->input = 0U; + cau_parameter->in_length = 0U; + cau_parameter->aad = 0U; + cau_parameter->aad_size = 0U; +} + +/*! + \brief initialize the key parameter structure with the default values + \param[in] none + \param[out] key_initpara: + key_0_high: key 0 high + key_0_low: key 0 low + key_1_high: key 1 high + key_1_low: key 1 low + key_2_high: key 2 high + key_2_low: key 2 low + key_3_high: key 3 high + key_3_low: key 3 low + \retval none +*/ +void cau_key_struct_para_init(cau_key_parameter_struct *key_initpara) +{ + /* set the key parameters struct with the default values */ + key_initpara->key_0_high = 0U; + key_initpara->key_0_low = 0U; + key_initpara->key_1_high = 0U; + key_initpara->key_1_low = 0U; + key_initpara->key_2_high = 0U; + key_initpara->key_2_low = 0U; + key_initpara->key_3_high = 0U; + key_initpara->key_3_low = 0U; +} + +/*! + \brief initialize the vectors parameter struct with the default values + \param[in] none + \param[out] iv_initpara: + iv_0_high: init vector 0 high + iv_0_low: init vector 0 low + iv_1_high: init vector 1 high + iv_1_low: init vector 1 low + \retval none +*/ +void cau_iv_struct_para_init(cau_iv_parameter_struct *iv_initpara) +{ + /* set the vectors parameters struct with the default values */ + iv_initpara->iv_0_high = 0U; + iv_initpara->iv_0_low = 0U; + iv_initpara->iv_1_high = 0U; + iv_initpara->iv_1_low = 0U; +} + +/*! + \brief initialize the context parameter struct with the default values + \param[in] none + \param[out] cau_context: + ctl_config: current configuration + iv_0_high: init vector 0 high + iv_0_low: init vector 0 low + iv_1_high: init vector 1 high + iv_1_low: init vector 1 low + key_0_high: key 0 high + key_0_low: key 0 low + key_1_high: key 1 high + key_1_low: key 1 low + key_2_high: key 2 high + key_2_low: key 2 low + key_3_high: key 3 high + key_3_low: key 3 low + gcmccmctxs[8]: GCM or CCM mode context switch + gcmctxs[8]: GCM mode context switch + \retval none +*/ +void cau_context_struct_para_init(cau_context_parameter_struct *cau_context) +{ + cau_context->ctl_config = 0U; + + /* set the vectors parameters with the default values */ + cau_context->iv_0_high = 0U; + cau_context->iv_0_low = 0U; + cau_context->iv_1_high = 0U; + cau_context->iv_1_low = 0U; + + /* set the key parameters with the default values */ + cau_context->key_0_high = 0U; + cau_context->key_0_low = 0U; + cau_context->key_1_high = 0U; + cau_context->key_1_low = 0U; + cau_context->key_2_high = 0U; + cau_context->key_2_low = 0U; + cau_context->key_3_high = 0U; + cau_context->key_3_low = 0U; + + /* set the context switch with the default values */ + cau_context->gcmccmctxs[0] = 0U; + cau_context->gcmccmctxs[1] = 0U; + cau_context->gcmccmctxs[2] = 0U; + cau_context->gcmccmctxs[3] = 0U; + cau_context->gcmccmctxs[4] = 0U; + cau_context->gcmccmctxs[5] = 0U; + cau_context->gcmccmctxs[6] = 0U; + cau_context->gcmccmctxs[7] = 0U; + + cau_context->gcmctxs[0] = 0U; + cau_context->gcmctxs[1] = 0U; + cau_context->gcmctxs[2] = 0U; + cau_context->gcmctxs[3] = 0U; + cau_context->gcmctxs[4] = 0U; + cau_context->gcmctxs[5] = 0U; + cau_context->gcmctxs[6] = 0U; + cau_context->gcmctxs[7] = 0U; +} + +/*! + \brief enable the CAU peripheral + \param[in] none + \param[out] none + \retval none +*/ +void cau_enable(void) +{ + /* enable the CAU processor */ + CAU_CTL |= CAU_CTL_CAUEN; +} + +/*! + \brief disable the CAU peripheral + \param[in] none + \param[out] none + \retval none +*/ +void cau_disable(void) +{ + /* disable the CAU processor */ + CAU_CTL &= ~CAU_CTL_CAUEN; +} + +/*! + \brief enable the CAU DMA interface + \param[in] dma_req: specify the CAU DMA transfer request to be enabled + one or more parameters can be selected which are shown as below: + \arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer + \arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer + \param[out] none + \retval none +*/ +void cau_dma_enable(uint32_t dma_req) +{ + /* enable the selected CAU DMA request */ + CAU_DMAEN |= dma_req; +} + +/*! + \brief disable the CAU DMA interface + \param[in] dma_req: specify the CAU DMA transfer request to be disabled + one or more parameters can be selected which are shown as below: + \arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer + \arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer + \param[out] none + \retval none +*/ +void cau_dma_disable(uint32_t dma_req) +{ + /* disable the selected CAU DMA request */ + CAU_DMAEN &= ~(dma_req); +} + +/*! + \brief initialize the CAU peripheral + \param[in] alg_dir: algorithm direction + only one parameter can be selected which is shown as below: + \arg CAU_ENCRYPT: encrypt + \arg CAU_DECRYPT: decrypt + \param[in] algo_mode: algorithm mode selection + only one parameter can be selected which is shown as below: + \arg CAU_MODE_TDES_ECB: TDES-ECB (3DES Electronic codebook) + \arg CAU_MODE_TDES_CBC: TDES-CBC (3DES Cipher block chaining) + \arg CAU_MODE_DES_ECB: DES-ECB (simple DES Electronic codebook) + \arg CAU_MODE_DES_CBC: DES-CBC (simple DES Cipher block chaining) + \arg CAU_MODE_AES_ECB: AES-ECB (AES Electronic codebook) + \arg CAU_MODE_AES_CBC: AES-CBC (AES Cipher block chaining) + \arg CAU_MODE_AES_CTR: AES-CTR (AES counter mode) + \arg CAU_MODE_AES_KEY: AES decryption key preparation mode + \arg CAU_MODE_AES_GCM: AES-GCM (AES Galois/counter mode) + \arg CAU_MODE_AES_CCM: AES-CCM (AES combined cipher machine mode) + \arg CAU_MODE_AES_CFB: AES-CFB (cipher feedback mode) + \arg CAU_MODE_AES_OFB: AES-OFB (output feedback mode) + \param[in] swapping: data swapping selection + only one parameter can be selected which is shown as below: + \arg CAU_SWAPPING_32BIT: no swapping + \arg CAU_SWAPPING_16BIT: half-word swapping + \arg CAU_SWAPPING_8BIT: bytes swapping + \arg CAU_SWAPPING_1BIT: bit swapping + \param[out] none + \retval none +*/ +void cau_init(uint32_t alg_dir, uint32_t algo_mode, uint32_t swapping) +{ + /* select algorithm mode */ + CAU_CTL &= ~CAU_CTL_ALGM; + CAU_CTL |= algo_mode; + + /* select data swapping */ + CAU_CTL &= ~CAU_CTL_DATAM; + CAU_CTL |= swapping; + + /* select algorithm direction */ + CAU_CTL &= ~CAU_CTL_CAUDIR; + CAU_CTL |= alg_dir; +} + +/*! + \brief configure key selection + \param[in] key_selection: key source selection when aes mode + only one parameter can be selected which is shown as below: + \arg CAU_KEY: use the key from CAU register + \arg CAU_EFUSE_KEY: use the key from EFUSE + \param[out] none + \retval none +*/ +void cau_aes_key_select(uint32_t key_selection) +{ + CAU_CTL &= ~CAU_CTL_KEY_SEL; + CAU_CTL |= key_selection; +} + +/*! + \brief configure key size if use AES algorithm + \param[in] key_size: key length selection when aes mode + only one parameter can be selected which is shown as below: + \arg CAU_KEYSIZE_128BIT: 128 bit key length + \arg CAU_KEYSIZE_192BIT: 192 bit key length + \arg CAU_KEYSIZE_256BIT: 256 bit key length + \param[out] none + \retval none +*/ +void cau_aes_keysize_config(uint32_t key_size) +{ + CAU_CTL &= ~CAU_CTL_KEYM; + CAU_CTL |= key_size; +} + +/*! + \brief initialize the key parameters + \param[in] key_initpara: key init parameter struct + key_0_high: key 0 high + key_0_low: key 0 low + key_1_high: key 1 high + key_1_low: key 1 low + key_2_high: key 2 high + key_2_low: key 2 low + key_3_high: key 3 high + key_3_low: key 3 low + \param[out] none + \retval none +*/ +void cau_key_init(cau_key_parameter_struct *key_initpara) +{ + CAU_KEY0H = key_initpara->key_0_high; + CAU_KEY0L = key_initpara->key_0_low; + CAU_KEY1H = key_initpara->key_1_high; + CAU_KEY1L = key_initpara->key_1_low; + CAU_KEY2H = key_initpara->key_2_high; + CAU_KEY2L = key_initpara->key_2_low; + CAU_KEY3H = key_initpara->key_3_high; + CAU_KEY3L = key_initpara->key_3_low; +} + +/*! + \brief initialize the vectors parameters + \param[in] iv_initpara: vectors init parameter struct + iv_0_high: init vector 0 high + iv_0_low: init vector 0 low + iv_1_high: init vector 1 high + iv_1_low: init vector 1 low + \param[out] none + \retval none +*/ +void cau_iv_init(cau_iv_parameter_struct *iv_initpara) +{ + CAU_IV0H = iv_initpara->iv_0_high; + CAU_IV0L = iv_initpara->iv_0_low; + CAU_IV1H = iv_initpara->iv_1_high; + CAU_IV1L = iv_initpara->iv_1_low; +} + +/*! + \brief configure phase + \param[in] phase: gcm or ccm phase + only one parameter can be selected which is shown as below: + \arg CAU_PREPARE_PHASE: prepare phase + \arg CAU_AAD_PHASE: AAD phase + \arg CAU_ENCRYPT_DECRYPT_PHASE: encryption/decryption phase + \arg CAU_TAG_PHASE: tag phase + \param[out] none + \retval none +*/ +void cau_phase_config(uint32_t phase) +{ + uint32_t temp; + /* Get the CTL register */ + temp = CAU_CTL; + /* Reset the phase configuration bits */ + temp &= ~CAU_CTL_GCM_CCMPH; + /* Set the selected phase */ + temp |= phase; + /* Set the CTL register */ + CAU_CTL = temp; +} + +/*! + \brief flush the IN and OUT FIFOs + \param[in] none + \param[out] none + \retval none +*/ +void cau_fifo_flush(void) +{ + /* reset the read and write pointers of the FIFOs */ + CAU_CTL |= CAU_CTL_FFLUSH; +} + +/*! + \brief return whether CAU peripheral is enabled or disabled + \param[in] none + \param[out] none + \retval ControlStatus: ENABLE or DISABLE +*/ +ControlStatus cau_enable_state_get(void) +{ + ControlStatus ret = DISABLE; + if(RESET != (CAU_CTL & CAU_CTL_CAUEN)) { + ret = ENABLE; + } + return ret; +} + +/*! + \brief write data to the IN FIFO + \param[in] data: data to write (0 - 0xFFFFFFFF) + \param[out] none + \retval none +*/ +void cau_data_write(uint32_t data) +{ + CAU_DI = data; +} + +/*! + \brief return the last data entered into the output FIFO + \param[in] none + \param[out] none + \retval last data entered into the output FIFO +*/ +uint32_t cau_data_read(void) +{ + return CAU_DO; +} + +/*! + \brief save context before context switching + \param[in] key_initpara: key init parameter struct + key_0_high: key 0 high + key_0_low: key 0 low + key_1_high: key 1 high + key_1_low: key 1 low + key_2_high: key 2 high + key_2_low: key 2 low + key_3_high: key 3 high + key_3_low: key 3 low + \param[out] cau_context: + ctl_config: current configuration + iv_0_high: init vector 0 high + iv_0_low: init vector 0 low + iv_1_high: init vector 1 high + iv_1_low: init vector 1 low + key_0_high: key 0 high + key_0_low: key 0 low + key_1_high: key 1 high + key_1_low: key 1 low + key_2_high: key 2 high + key_2_low: key 2 low + key_3_high: key 3 high + key_3_low: key 3 low + gcmccmctxs[8]: GCM or CCM mode context switch + gcmctxs[8]: GCM mode context switch + \retval none +*/ +void cau_context_save(cau_context_parameter_struct *cau_context, cau_key_parameter_struct *key_initpara) +{ + uint32_t checkmask = 0U; + uint32_t checkbits = 0U; + uint32_t algm_reg = 0U; + + /* stop DMA transfers on the IN FIFO by clearing the DMAIEN bit in the CAU_DMAEN */ + CAU_DMAEN &= ~CAU_DMA_INFIFO; + + algm_reg = CAU_CTL & CAU_CTL_ALGM; + /* AES or DES */ + if((uint32_t)0 != (algm_reg & (~CAU_MODE_TDES_CBC))) { + /* wait until both the IN and OUT FIFOs are empty (IEM=1 and ONE=0 in the CAU_STAT0 register) and BUSY=0 */ + checkbits = CAU_STAT0_IEM; + checkmask = STAT0_AESDES_MASK; + /* TDES */ + } else { + /* wait until OUT FIFO is empty (ONE=0 in the CAU_STAT0 register) and BUSY=0 */ + checkbits = 0U; + checkmask = STAT0_TDES_MASK; + } + + while((CAU_STAT0 & checkmask) != checkbits) { + } + + /* stop DMA transfers on the OUT FIFO by clear CAU_DMAEN_DMAOEN=0 */ + CAU_DMAEN &= ~CAU_DMAEN_DMAOEN; + /* disable CAU */ + CAU_CTL &= ~CAU_CTL_CAUEN; + + /* save the current configuration (bit 19, bit[17:16] and bit[9:2] in the CAU_CTL register) */ + cau_context->ctl_config = CAU_CTL & (CAU_CTL_GCM_CCMPH | + CAU_CTL_KEYM | + CAU_CTL_DATAM | + CAU_CTL_ALGM | + CAU_CTL_CAUDIR | + CAU_CTL_NBPILB); + + /* save the key value */ + cau_context->key_0_high = key_initpara->key_0_high; + cau_context->key_0_low = key_initpara->key_0_low; + cau_context->key_1_high = key_initpara->key_1_high; + cau_context->key_1_low = key_initpara->key_1_low; + cau_context->key_2_high = key_initpara->key_2_high; + cau_context->key_2_low = key_initpara->key_2_low; + cau_context->key_3_high = key_initpara->key_3_high; + cau_context->key_3_low = key_initpara->key_3_low; + + if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) { + /* if not in ECB mode, save the initialization vectors */ + cau_context->iv_0_high = CAU_IV0H; + cau_context->iv_0_low = CAU_IV0L; + cau_context->iv_1_high = CAU_IV1H; + cau_context->iv_1_low = CAU_IV1L; + } + + /* if in GCM/CCM mode, save the context switch registers */ + if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) { + cau_context->gcmccmctxs[0U] = CAU_GCMCCMCTXSx(0U); + cau_context->gcmccmctxs[1U] = CAU_GCMCCMCTXSx(1U); + cau_context->gcmccmctxs[2U] = CAU_GCMCCMCTXSx(2U); + cau_context->gcmccmctxs[3U] = CAU_GCMCCMCTXSx(3U); + cau_context->gcmccmctxs[4U] = CAU_GCMCCMCTXSx(4U); + cau_context->gcmccmctxs[5U] = CAU_GCMCCMCTXSx(5U); + cau_context->gcmccmctxs[6U] = CAU_GCMCCMCTXSx(6U); + cau_context->gcmccmctxs[7U] = CAU_GCMCCMCTXSx(7U); + } + + /* if in GCM mode, save the context switch registers */ + if(CAU_MODE_AES_GCM == algm_reg) { + cau_context->gcmctxs[0U] = CAU_GCMCTXSx(0U); + cau_context->gcmctxs[1U] = CAU_GCMCTXSx(1U); + cau_context->gcmctxs[2U] = CAU_GCMCTXSx(2U); + cau_context->gcmctxs[3U] = CAU_GCMCTXSx(3U); + cau_context->gcmctxs[4U] = CAU_GCMCTXSx(4U); + cau_context->gcmctxs[5U] = CAU_GCMCTXSx(5U); + cau_context->gcmctxs[6U] = CAU_GCMCTXSx(6U); + cau_context->gcmctxs[7U] = CAU_GCMCTXSx(7U); + } +} + +/*! + \brief restore context after context switching + \param[in] cau_context: + ctl_config: current configuration + iv_0_high: init vector 0 high + iv_0_low: init vector 0 low + iv_1_high: init vector 1 high + iv_1_low: init vector 1 low + key_0_high: key 0 high + key_0_low: key 0 low + key_1_high: key 1 high + key_1_low: key 1 low + key_2_high: key 2 high + key_2_low: key 2 low + key_3_high: key 3 high + key_3_low: key 3 low + gcmccmctxs[8]: GCM or CCM mode context switch + gcmctxs[8]: GCM mode context switch + \param[out] none + \retval none +*/ +void cau_context_restore(cau_context_parameter_struct *cau_context) +{ + uint32_t algm_reg, aes_decrypt; + + /* configure the processor with the saved configuration */ + CAU_CTL = cau_context->ctl_config; + + algm_reg = CAU_CTL & CAU_CTL_ALGM; + + /* restore the key value */ + CAU_KEY0H = cau_context->key_0_high; + CAU_KEY0L = cau_context->key_0_low; + CAU_KEY1H = cau_context->key_1_high; + CAU_KEY1L = cau_context->key_1_low; + CAU_KEY2H = cau_context->key_2_high; + CAU_KEY2L = cau_context->key_2_low; + CAU_KEY3H = cau_context->key_3_high; + CAU_KEY3L = cau_context->key_3_low; + + if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) { + /* restore the initialization vectors */ + CAU_IV0H = cau_context->iv_0_high; + CAU_IV0L = cau_context->iv_0_low; + CAU_IV1H = cau_context->iv_1_high; + CAU_IV1L = cau_context->iv_1_low; + } + + /* if in GCM/CCM mode, restore the context switch registers */ + if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) { + CAU_GCMCCMCTXSx(0U) = cau_context->gcmccmctxs[0U]; + CAU_GCMCCMCTXSx(1U) = cau_context->gcmccmctxs[1U]; + CAU_GCMCCMCTXSx(2U) = cau_context->gcmccmctxs[2U]; + CAU_GCMCCMCTXSx(3U) = cau_context->gcmccmctxs[3U]; + CAU_GCMCCMCTXSx(4U) = cau_context->gcmccmctxs[4U]; + CAU_GCMCCMCTXSx(5U) = cau_context->gcmccmctxs[5U]; + CAU_GCMCCMCTXSx(6U) = cau_context->gcmccmctxs[6U]; + CAU_GCMCCMCTXSx(7U) = cau_context->gcmccmctxs[7U]; + } + + /* if in GCM mode, restore the context switch registers */ + if(CAU_MODE_AES_GCM == algm_reg) { + CAU_GCMCTXSx(0U) = cau_context->gcmctxs[0U]; + CAU_GCMCTXSx(1U) = cau_context->gcmctxs[1U]; + CAU_GCMCTXSx(2U) = cau_context->gcmctxs[2U]; + CAU_GCMCTXSx(3U) = cau_context->gcmctxs[3U]; + CAU_GCMCTXSx(4U) = cau_context->gcmctxs[4U]; + CAU_GCMCTXSx(5U) = cau_context->gcmctxs[5U]; + CAU_GCMCTXSx(6U) = cau_context->gcmctxs[6U]; + CAU_GCMCTXSx(7U) = cau_context->gcmctxs[7U]; + } + + /* if it is AES ECB/CBC decryption, then first prepare key */ + aes_decrypt = CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR); + if(((CAU_MODE_AES_ECB | CAU_DECRYPT) == aes_decrypt) || ((CAU_MODE_AES_CBC | CAU_DECRYPT) == aes_decrypt)) { + uint32_t alg_dir, algo_mode, swapping; + + /* flush IN/OUT FIFOs */ + cau_fifo_flush(); + /* parameters for key preparation for AES decryption */ + alg_dir = CAU_DECRYPT; + algo_mode = CAU_MODE_AES_KEY; + swapping = CAU_SWAPPING_32BIT; + cau_init(alg_dir, algo_mode, swapping); + + /* enable CAU */ + cau_enable(); + + /* wait until BUSY=0 */ + while((uint32_t)0U != cau_flag_get(CAU_FLAG_BUSY)) { + } + + /* parameters for decryption */ + CAU_CTL = cau_context->ctl_config; + } + + /* enable CAU */ + cau_enable(); +} + +/*! + \brief get the CAU flag status + \param[in] flag: CAU flag status + only one parameter can be selected which is shown as below: + \arg CAU_FLAG_INFIFO_EMPTY: input FIFO empty + \arg CAU_FLAG_INFIFO_NO_FULL: input FIFO is not full + \arg CAU_FLAG_OUTFIFO_NO_EMPTY: output FIFO not empty + \arg CAU_FLAG_OUTFIFO_FULL: output FIFO is full + \arg CAU_FLAG_BUSY: the CAU core is busy + \arg CAU_FLAG_INFIFO: input FIFO flag status + \arg CAU_FLAG_OUTFIFO: output FIFO flag status + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cau_flag_get(uint32_t flag) +{ + uint32_t reg = 0U; + FlagStatus ret_flag = RESET; + + /* check if the flag is in CAU_STAT1 register */ + if(RESET != (flag & FLAG_MASK)) { + reg = CAU_STAT1; + } else { + /* the flag is in CAU_STAT0 register */ + reg = CAU_STAT0; + } + + /* check the status of the specified CAU flag */ + if(RESET != (reg & flag)) { + ret_flag = SET; + } + + return ret_flag; +} + +/*! + \brief enable the CAU interrupts + \param[in] interrupt: specify the CAU interrupt source to be enabled + one or more parameters can be selected which are shown as below: + \arg CAU_INT_INFIFO: input FIFO interrupt + \arg CAU_INT_OUTFIFO: output FIFO interrupt + \param[out] none + \retval none +*/ +void cau_interrupt_enable(uint32_t interrupt) +{ + /* enable the selected CAU interrupt */ + CAU_INTEN |= interrupt; +} + +/*! + \brief disable the CAU interrupts + \param[in] interrupt: specify the CAU interrupt source to be disabled + one or more parameters can be selected which are shown as below: + \arg CAU_INT_INFIFO: input FIFO interrupt + \arg CAU_INT_OUTFIFO: output FIFO interrupt + \param[out] none + \retval none +*/ +void cau_interrupt_disable(uint32_t interrupt) +{ + /* disable the selected CAU interrupt */ + CAU_INTEN &= ~(interrupt); +} + +/*! + \brief get the interrupt flag + \param[in] int_flag: CAU interrupt flag + only one parameter can be selected which is shown as below: + \arg CAU_INT_FLAG_INFIFO: input FIFO interrupt + \arg CAU_INT_FLAG_OUTFIFO: output FIFO interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cau_interrupt_flag_get(uint32_t int_flag) +{ + FlagStatus flag = RESET; + + /* check the status of the specified CAU interrupt */ + if(RESET != (CAU_INTF & int_flag)) { + flag = SET; + } + + return flag; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_aes.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_aes.c new file mode 100644 index 0000000000..1661f08a3e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_aes.c @@ -0,0 +1,917 @@ +/*! + \file gd32h7xx_cau_aes.c + \brief CAU AES driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_cau.h" +#include + +#define AESBSY_TIMEOUT ((uint32_t)0x00010000U) +#define BLOCK_B0_MASK ((uint8_t)0x07U) +#define BLOCK_DATA_SIZE ((uint32_t)0x00000010U) +#define MAX_CCM_IV_SIZE ((uint32_t)0x0000000FU) + +/* configure AES key structure parameter */ +static void cau_aes_key_config(uint8_t *key, uint32_t keysize, cau_key_parameter_struct *cau_key_initpara); +/* fill data into data input register */ +static ErrStatus cau_fill_data(uint8_t *input, uint32_t in_length); +/* AES calculate process */ +static ErrStatus cau_aes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output); + +/*! + \brief encrypt and decrypt using AES in ECB mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bits, must be either 128, 192 or 256 + input: input data + in_length: input data length in bytes, must be a multiple of 16 bytes + \param[out] output: pointer to the returned buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_aes_ecb(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* AES key structure parameter config */ + cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara); + /* key initialization */ + cau_key_init(&key_initpara); + + /* AES decryption */ + if(CAU_DECRYPT == cau_parameter->alg_dir) { + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* initialize the CAU peripheral */ + cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT); + + /* enable the CAU peripheral */ + cau_enable(); + + /* wait until the busy flag is RESET */ + do { + busystatus = cau_flag_get(CAU_FLAG_BUSY); + counter++; + } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus) { + return ERROR; + } + } + + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_AES_ECB, CAU_SWAPPING_8BIT); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + + /* enable the CAU peripheral */ + cau_enable(); + /* AES calculate process */ + ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using AES in CBC mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bits, must be either 128, 192 or 256 + iv: initialization vector, 16 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 16 bytes + \param[out] output: pointer to the returned buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_aes_cbc(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + + uint32_t ivaddr = (uint32_t)cau_parameter->iv; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* AES key structure parameter config */ + cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara); + /* key initialization */ + cau_key_init(&key_initpara); + + /* AES decryption */ + if(CAU_DECRYPT == cau_parameter->alg_dir) { + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* initialize the CAU peripheral */ + cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT); + + /* enable the CAU peripheral */ + cau_enable(); + + /* wait until the busy flag is RESET */ + do { + busystatus = cau_flag_get(CAU_FLAG_BUSY); + counter++; + } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus) { + return ERROR; + } + } + + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CBC, CAU_SWAPPING_8BIT); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr)); + cau_iv_init(&iv_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + + /* enable the CAU peripheral */ + cau_enable(); + /* AES calculate process */ + ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using AES in CTR mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bits, must be either 128, 192 or 256 + iv: initialization vector, 16 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 16 bytes + \param[out] output: pointer to the returned buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_aes_ctr(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + uint32_t ivaddr = (uint32_t)cau_parameter->iv; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CTR, CAU_SWAPPING_8BIT); + + /* AES key structure parameter config */ + cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara); + /* key initialization */ + cau_key_init(&key_initpara); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr)); + cau_iv_init(&iv_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + + /* enable the CAU peripheral */ + cau_enable(); + /* AES calculate process */ + ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using AES in CFB mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bits, must be either 128, 192 or 256 + iv: initialization vector, 16 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 16 bytes + \param[out] output: pointer to the returned buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_aes_cfb(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + uint32_t ivaddr = (uint32_t)cau_parameter->iv; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CFB, CAU_SWAPPING_8BIT); + + /* AES key structure parameter config */ + cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara); + /* key initialization */ + cau_key_init(&key_initpara); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr)); + cau_iv_init(&iv_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* enable the CAU peripheral */ + cau_enable(); + /* AES calculate process */ + ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using AES in OFB mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bits, must be either 128, 192 or 256 + iv: initialization vector, 16 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 16 bytes + \param[out] output: pointer to the returned buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_aes_ofb(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + uint32_t ivaddr = (uint32_t)cau_parameter->iv; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_AES_OFB, CAU_SWAPPING_8BIT); + + /* AES key structure parameter config */ + cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara); + /* key initialization */ + cau_key_init(&key_initpara); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr)); + cau_iv_init(&iv_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* enable the CAU peripheral */ + cau_enable(); + /* AES calculate process */ + ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using AES in GCM mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bits, must be either 128, 192 or 256 + iv: initialization vector, 16 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 16 bytes + aad: additional authentication data + aad_size: aad size in bytes, must be a multiple of 16 bytes + \param[out] output: pointer to the returned output data buffer + \param[out] tag: pointer to the returned tag buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_aes_gcm(cau_parameter_struct *cau_parameter, uint8_t *output, uint8_t *tag) +{ + ErrStatus ret = SUCCESS; + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + uint64_t aadlength = (uint64_t)cau_parameter->aad_size * 8U; + uint64_t inputlength = (uint64_t)cau_parameter->in_length * 8U; + uint32_t ivaddr = (uint32_t)cau_parameter->iv; + uint32_t tagaddr = (uint32_t)tag; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_AES_GCM, CAU_SWAPPING_8BIT); + + /* AES key structure parameter config */ + cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara); + /* key initialization */ + cau_key_init(&key_initpara); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr)); + cau_iv_init(&iv_initpara); + + /* prepare phase */ + /* select prepare phase */ + cau_phase_config(CAU_PREPARE_PHASE); + /* enable the CAU peripheral */ + cau_enable(); + /* wait for CAUEN bit to be 0 */ + while(ENABLE == cau_enable_state_get()) { + } + + /* aad phase */ + if((uint32_t)0U != cau_parameter->aad_size) { + /* select aad phase */ + cau_phase_config(CAU_AAD_PHASE); + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* enable the CAU peripheral */ + cau_enable(); + + ret = cau_fill_data(cau_parameter->aad, cau_parameter->aad_size); + + if(ERROR == ret) { + return ret; + } + } + + /* encrypt or decrypt phase */ + if((uint32_t)0U != cau_parameter->in_length) { + /* select encrypt or decrypt phase */ + cau_phase_config(CAU_ENCRYPT_DECRYPT_PHASE); + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* enable the CAU peripheral */ + cau_enable(); + + /* AES calculate process */ + ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output); + + if(ERROR == ret) { + return ret; + } + } + + /* tag phase */ + /* select tag phase */ + cau_phase_config(CAU_TAG_PHASE); + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* enable the CAU peripheral */ + cau_enable(); + + if(DISABLE == cau_enable_state_get()) { + return ERROR; + } + + cau_data_write(__REV((uint32_t)(aadlength >> 32U))); + cau_data_write(__REV((uint32_t)aadlength)); + cau_data_write(__REV((uint32_t)(inputlength >> 32U))); + cau_data_write(__REV((uint32_t)inputlength)); + + /* wait until the ONE flag is set */ + while(RESET == cau_flag_get(CAU_FLAG_OUTFIFO_NO_EMPTY)) { + } + + /* read the tag in the OUT FIFO */ + *(uint32_t *)(tagaddr) = cau_data_read(); + tagaddr += 4U; + *(uint32_t *)(tagaddr) = cau_data_read(); + tagaddr += 4U; + *(uint32_t *)(tagaddr) = cau_data_read(); + tagaddr += 4U; + *(uint32_t *)(tagaddr) = cau_data_read(); + tagaddr += 4U; + + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using AES in CCM mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key + key_size: key size in bytes + iv: initialization vector + iv_size: iv size in bytes + input: input data + in_length: input data length in bytes + aad: additional authentication data + aad_size: aad size + \param[in] mac_size: mac size (in bytes) + \param[out] output: pointer to the returned output data buffer + \param[out] tag: pointer to the returned tag buffer + \param[out] aad_buf: pointer to the user buffer used when formatting aad block + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_aes_ccm(cau_parameter_struct *cau_parameter, uint8_t *output, uint8_t tag[], uint32_t tag_size, uint8_t aad_buf[]) +{ + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + ErrStatus ret = ERROR; + uint32_t inputaddr = (uint32_t)cau_parameter->input; + uint32_t inputsize = cau_parameter->in_length; + uint32_t aadaddr = (uint32_t)cau_parameter->aad; + uint32_t aadsize = cau_parameter->aad_size; + uint32_t aad_block_size = 0U; + uint32_t ivaddr = (uint32_t)cau_parameter->iv; + uint32_t ivsize = cau_parameter->iv_size; + uint32_t outputaddr = (uint32_t)output; + uint32_t i = 0U, plen = 0U; + uint32_t head_index = 0U; + uint8_t blockb0[16U] = {0U}; + uint8_t counter[16U] = {0U}; + uint32_t ctraddr = (uint32_t)counter; + uint32_t b0addr = (uint32_t)blockb0; + uint32_t temp_tag[4U]; + + /* formatting the aad block */ + if((uint32_t)0U != aadsize) { + /* check that the aad length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ + if(aadsize < 65280U) { + aad_buf[head_index++] = (uint8_t)((aadsize >> 8U) & 0xFFU); + aad_buf[head_index++] = (uint8_t)((aadsize) & 0xFFU); + aad_block_size = aadsize + 2U; + } else { + /* aad is encoded as 0xFF || 0xFE || [aadsize]32, i.e., six octets */ + aad_buf[head_index++] = 0xFFU; + aad_buf[head_index++] = 0xFEU; + aad_buf[head_index++] = (uint8_t)((aadsize & 0xFF000000U) >> 24U); + aad_buf[head_index++] = (uint8_t)((aadsize & 0x00FF0000U) >> 16U); + aad_buf[head_index++] = (uint8_t)((aadsize & 0x0000FF00U) >> 8U); + aad_buf[head_index++] = (uint8_t)(aadsize & 0x000000FFU); + aad_block_size = aadsize + 6U; + } + /* copy the aad buffer in internal buffer "HBuffer" */ + for(i = 0U; i < aadsize; i++) { + aad_buf[head_index++] = *(uint8_t *)((uint32_t)(aadaddr + i)); + } + /* check if the aad block size is modulo 16 */ + if(0U != (aad_block_size % 16U)) { + /* Pad the aad buffer with 0s till the HBuffer length is modulo 16 */ + for(i = aad_block_size; i <= ((aad_block_size / 16U) + 1U) * 16U; i++) { + aad_buf[i] = 0U; + } + /* set the aad size to modulo 16 */ + aad_block_size = ((aad_block_size / 16U) + 1U) * 16U; + } + /* set the pointer aadaddr to HBuffer */ + aadaddr = (uint32_t)aad_buf; + } + + /* formatting the block B0 */ + if(0U != aadsize) { + blockb0[0] = 0x40U; + } + /* flags byte */ + blockb0[0] |= (0U | (((((uint8_t) tag_size - 2U) / 2U) & 0x07U) << 3U) | (((uint8_t)(15U - ivsize) - 1U) & 0x07U)); + + if(ivsize > MAX_CCM_IV_SIZE) { + return ERROR; + } + + for(i = 0U; i < ivsize; i++) { + blockb0[i + 1U] = *(uint8_t *)((uint32_t)(ivaddr + i)); + } + + /* the byte length for payload length expressing, which plus the ivsize must equal to 15 bytes */ + plen = 15U - ivsize; + /* if the byte length for payload length expressing is more than 4 bytes */ + if(plen > 4U) { + /* pad the blockb0 after vectors, and before the last 4 bytes */ + for(; i < 11U; i++) { + blockb0[i + 1U] = 0U; + } + blockb0[12U] = (uint8_t)((inputsize >> 24U) & 0xFFU); + blockb0[13U] = (uint8_t)((inputsize >> 16U) & 0xFFU); + blockb0[14U] = (uint8_t)((inputsize >> 8U) & 0xFFU); + blockb0[15U] = (uint8_t)(inputsize & 0xFFU); + } else { + /* the payload length is expressed in plen bytes */ + for(; i < 15U; i++) { + blockb0[i + 1U] = (uint8_t)((inputsize >> ((plen - 1U) * 8U)) & 0xFFU); + plen--; + } + } + + /* formatting the initial counter */ + /* byte 0: bits 0-2 contain the same encoding of q as in B0 */ + counter[0] = blockb0[0] & BLOCK_B0_MASK; + for(i = 1U; i < ivsize + 1U; i++) { + counter[i] = blockb0[i]; + } + /* set the LSB to 1 */ + counter[15] |= 0x01U; + + /* prepare phase */ + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* clear CAUEN bit to ensure CAU is disable */ + cau_disable(); + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CCM, CAU_SWAPPING_8BIT); + /* select init phase */ + cau_phase_config(CAU_PREPARE_PHASE); + + /* AES key structure parameter config */ + cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara); + /* key initialization */ + cau_key_init(&key_initpara); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ctraddr)); + ctraddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ctraddr)); + ctraddr += 4U; + iv_initpara.iv_1_high = __REV(*(uint32_t *)(ctraddr)); + ctraddr += 4U; + iv_initpara.iv_1_low = __REV(*(uint32_t *)(ctraddr)); + cau_iv_init(&iv_initpara); + + /* enable the CAU peripheral */ + cau_enable(); + + /* write block B0 in the In FIFO */ + cau_data_write(*(uint32_t *)(b0addr)); + b0addr += 4U; + cau_data_write(*(uint32_t *)(b0addr)); + b0addr += 4U; + cau_data_write(*(uint32_t *)(b0addr)); + b0addr += 4U; + cau_data_write(*(uint32_t *)(b0addr)); + + /* wait for CAUEN bit to be 0 */ + while(ENABLE == cau_enable_state_get()) { + } + + /* aad phase */ + if((uint32_t)0U != aadsize) { + /* select aad phase */ + cau_phase_config(CAU_AAD_PHASE); + /* enable the CAU peripheral */ + cau_enable(); + + ret = cau_fill_data((uint8_t *)aadaddr, aad_block_size); + + if(ERROR == ret) { + return ret; + } + } + + /* encrypt or decrypt phase */ + inputsize = cau_parameter->in_length; + + if((uint32_t)0U != inputsize) { + /* select encrypt or decrypt phase */ + cau_phase_config(CAU_ENCRYPT_DECRYPT_PHASE); + /* enable the CAU peripheral */ + cau_enable(); + + /* AES calculate process */ + ret = cau_aes_calculate((uint8_t *)inputaddr, inputsize, (uint8_t *)outputaddr); + + if(ERROR == ret) { + return ret; + } + } + + /* tag phase */ + /* select final phase */ + cau_phase_config(CAU_TAG_PHASE); + /* enable the CAU peripheral */ + cau_enable(); + + if(DISABLE == cau_enable_state_get()) { + return ERROR; + } + + ctraddr = (uint32_t)counter; + + cau_data_write(*(uint32_t *)(ctraddr)); + ctraddr += 4U; + cau_data_write(*(uint32_t *)(ctraddr)); + ctraddr += 4U; + cau_data_write(*(uint32_t *)(ctraddr)); + ctraddr += 4U; + /* reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */ + cau_data_write(*(uint32_t *)(ctraddr) & 0xFEFFFFFFU); + + /* wait until the ONE flag is set */ + while(RESET == cau_flag_get(CAU_FLAG_OUTFIFO_NO_EMPTY)) { + } + + /* read the tag in the OUT FIFO */ + temp_tag[0] = cau_data_read(); + temp_tag[1] = cau_data_read(); + temp_tag[2] = cau_data_read(); + temp_tag[3] = cau_data_read(); + + /* disable the CAU peripheral */ + cau_disable(); + + /* Copy temporary authentication TAG in user TAG buffer */ + for(i = 0U; i < tag_size; i++) { + tag[i] = (uint8_t)(temp_tag[i / 4U] >> (8U * (i % 4U))); + } + + return ret; +} +/*! + \brief AES key structure parameter config + \param[in] key: key used for AES algorithm + \param[in] keysize: length of the key in bits, must be either 128, 192 or 256 + \param[out] cau_key_initpara: key init parameter struct + key_0_high: key 0 high + key_0_low: key 0 low + key_1_high: key 1 high + key_1_low: key 1 low + key_2_high: key 2 high + key_2_low: key 2 low + key_3_high: key 3 high + key_3_low: key 3 low + \retval none +*/ +static void cau_aes_key_config(uint8_t *key, uint32_t keysize, cau_key_parameter_struct *cau_key_initpara) +{ + uint32_t keyaddr = (uint32_t)key; + + switch(keysize) { + /* 128-bit key initialization */ + case 128: + cau_aes_keysize_config(CAU_KEYSIZE_128BIT); + cau_key_initpara->key_2_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_2_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_3_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_3_low = __REV(*(uint32_t *)(keyaddr)); + break; + /* 192-bit key initialization */ + case 192: + cau_aes_keysize_config(CAU_KEYSIZE_192BIT); + cau_key_initpara->key_1_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_1_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_2_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_2_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_3_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_3_low = __REV(*(uint32_t *)(keyaddr)); + break; + /* 256-bit key initialization */ + case 256: + cau_aes_keysize_config(CAU_KEYSIZE_256BIT); + cau_key_initpara->key_0_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_0_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_1_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_1_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_2_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_2_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_3_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + cau_key_initpara->key_3_low = __REV(*(uint32_t *)(keyaddr)); + break; + default: + break; + } +} + +/*! + \brief fill data into data input register + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer in bytes, must be a multiple of 16 bytes + \retval ErrStatus: SUCCESS or ERROR +*/ +static ErrStatus cau_fill_data(uint8_t *input, uint32_t in_length) +{ + uint32_t inputaddr = (uint32_t)input; + uint32_t i = 0U; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + + if(DISABLE == cau_enable_state_get()) { + return ERROR; + } + + for(i = 0U; i < in_length; i += BLOCK_DATA_SIZE) { + /* wait until the IEM flag is set */ + while(RESET == cau_flag_get(CAU_FLAG_INFIFO_EMPTY)) { + } + + if(i + BLOCK_DATA_SIZE > in_length) { + /* the last block data number is less than 128bit */ + uint32_t block_data_temp[4] = {0U}; + + /* fill the remaining bits with zero */ + memcpy(block_data_temp, (uint32_t *)inputaddr, in_length - i); + inputaddr = (uint32_t)block_data_temp; + + /* if GCM encryption or CCM decryption, then configurate NBPILB bits in CTL register */ + if((CAU_CTL & CAU_CTL_GCM_CCMPH) == CAU_ENCRYPT_DECRYPT_PHASE) { + if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_GCM | CAU_ENCRYPT)) { + CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length); + } else if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_CCM | CAU_DECRYPT)) { + CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length); + } else { + } + } + } + + /* write data to the IN FIFO */ + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + } + /* wait until the complete message has been processed */ + counter = 0U; + do { + busystatus = cau_flag_get(CAU_FLAG_BUSY); + counter++; + } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus) { + return ERROR; + } + + return SUCCESS; +} + +/*! + \brief AES calculate process + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer in bytes, must be a multiple of 16 bytes + \param[out] output: pointer to the returned buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +static ErrStatus cau_aes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output) +{ + uint32_t inputaddr = (uint32_t)input; + uint32_t outputaddr = (uint32_t)output; + uint32_t i = 0U; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + + /* the clock is not enabled or there is no embedded CAU peripheral */ + if(DISABLE == cau_enable_state_get()) { + return ERROR; + } + + for(i = 0U; i < in_length; i += BLOCK_DATA_SIZE) { + /* wait until the IEM flag is set */ + while(RESET == cau_flag_get(CAU_FLAG_INFIFO_EMPTY)) { + } + + /* check if the last input data block */ + if(i + BLOCK_DATA_SIZE > in_length) { + /* the last block data number is less than 128bit */ + uint32_t block_data_temp[4] = {0}; + + /* fill the remaining bits with zero */ + memcpy(block_data_temp, (uint32_t *)inputaddr, in_length - i); + inputaddr = (uint32_t)block_data_temp; + + /* if GCM encryption or CCM decryption, then configurate NBPILB bits in CTL register */ + if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_GCM | CAU_ENCRYPT)) { + CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length); + } else if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_CCM | CAU_DECRYPT)) { + CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length); + } else { + } + } + + /* write data to the IN FIFO */ + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + + /* wait until the complete message has been processed */ + counter = 0U; + do { + busystatus = cau_flag_get(CAU_FLAG_BUSY); + counter++; + } while((AESBSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus) { + return ERROR; + } else { + /* read the output block from the output FIFO */ + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + } + } + + return SUCCESS; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_des.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_des.c new file mode 100644 index 0000000000..0de1da148b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_des.c @@ -0,0 +1,183 @@ +/*! + \file gd32h7xx_cau_des.c + \brief CAU DES driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_cau.h" + +#define DESBUSY_TIMEOUT ((uint32_t)0x00010000U) + +/* DES calculate process */ +static ErrStatus cau_des_calculate(uint8_t *input, uint32_t in_length, uint8_t *output); + +/*! + \brief encrypt and decrypt using DES in ECB mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key, 8 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 8 bytes + \param[out] output: pointer to the output buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_des_ecb(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + uint32_t keyaddr = (uint32_t)(cau_parameter->key); + uint32_t inputaddr = (uint32_t)(cau_parameter->input); + uint32_t outputaddr = (uint32_t)output; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_DES_ECB, CAU_SWAPPING_8BIT); + + /* key initialisation */ + key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr)); + cau_key_init(&key_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* enable the CAU peripheral */ + cau_enable(); + /* DES calculate process */ + ret = cau_des_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using DES in CBC mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key, 8 bytes + iv: initialization vector, 8 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 8 bytes + \param[out] output: pointer to the output structure + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_des_cbc(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + uint32_t keyaddr = (uint32_t)(cau_parameter->key); + uint32_t inputaddr = (uint32_t)(cau_parameter->input); + uint32_t outputaddr = (uint32_t)output; + uint32_t ivaddr = (uint32_t)(cau_parameter->iv); + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_DES_CBC, CAU_SWAPPING_8BIT); + + /* key initialisation */ + key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr)); + cau_key_init(&key_initpara); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr)); + cau_iv_init(&iv_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + + /* enable the CAU peripheral */ + cau_enable(); + /* DES calculate process */ + ret = cau_des_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief DES calculate process + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer in bytes, must be a multiple of 8 bytes + \param[in] output: pointer to the returned buffer + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +static ErrStatus cau_des_calculate(uint8_t *input, uint32_t in_length, uint8_t *output) +{ + uint32_t inputaddr = (uint32_t)input; + uint32_t outputaddr = (uint32_t)output; + uint32_t i = 0U; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + + /* the clock is not enabled or there is no embedded CAU peripheral */ + if(DISABLE == cau_enable_state_get()) { + return ERROR; + } + + for(i = 0U; i < in_length; i += 8U) { + /* write data to the IN FIFO */ + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + + /* wait until the complete message has been processed */ + counter = 0U; + do { + busystatus = cau_flag_get(CAU_FLAG_BUSY); + counter++; + } while((DESBUSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus) { + return ERROR; + } else { + /* read the output block from the output FIFO */ + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + } + } + + return SUCCESS; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_tdes.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_tdes.c new file mode 100644 index 0000000000..965b2c6386 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cau_tdes.c @@ -0,0 +1,198 @@ +/*! + \file gd32h7xx_cau_tdes.c + \brief CAU TDES driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_cau.h" + +#define TDESBSY_TIMEOUT ((uint32_t)0x00010000U) + +/* TDES calculate process */ +static ErrStatus cau_tdes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output); + +/*! + \brief encrypt and decrypt using TDES in ECB mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key, 24 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 8 bytes + \param[out] output: pointer to the output structure + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_tdes_ecb(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + uint32_t keyaddr = (uint32_t)(cau_parameter->key); + uint32_t inputaddr = (uint32_t)(cau_parameter->input); + uint32_t outputaddr = (uint32_t)output; + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_TDES_ECB, CAU_SWAPPING_8BIT); + + /* key initialization */ + key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_2_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_2_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_3_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_3_low = __REV(*(uint32_t *)(keyaddr)); + cau_key_init(&key_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + + /* enable the CAU peripheral */ + cau_enable(); + /* TDES calculate process */ + ret = cau_tdes_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief encrypt and decrypt using TDES in CBC mode + \param[in] cau_parameter: pointer to the input structure + alg_dir: algorithm directory + CAU_ENCRYPT, CAU_DECRYPT + key: key, 24 bytes + iv: initialization vector, 8 bytes + input: input data + in_length: input data length in bytes, must be a multiple of 8 bytes + \param[out] output: pointer to the output structure + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus cau_tdes_cbc(cau_parameter_struct *cau_parameter, uint8_t *output) +{ + ErrStatus ret = ERROR; + cau_key_parameter_struct key_initpara; + cau_iv_parameter_struct iv_initpara; + uint32_t keyaddr = (uint32_t)(cau_parameter->key); + uint32_t inputaddr = (uint32_t)(cau_parameter->input); + uint32_t outputaddr = (uint32_t)output; + uint32_t ivaddr = (uint32_t)(cau_parameter->iv); + + /* key structure initialization */ + cau_key_struct_para_init(&key_initpara); + /* initialize the CAU peripheral */ + cau_init(cau_parameter->alg_dir, CAU_MODE_TDES_CBC, CAU_SWAPPING_8BIT); + + /* key initialization */ + key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_2_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_2_low = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_3_high = __REV(*(uint32_t *)(keyaddr)); + keyaddr += 4U; + key_initpara.key_3_low = __REV(*(uint32_t *)(keyaddr)); + cau_key_init(&key_initpara); + + /* vectors initialization */ + iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr)); + ivaddr += 4U; + iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr)); + cau_iv_init(&iv_initpara); + + /* flush the IN and OUT FIFOs */ + cau_fifo_flush(); + /* enable the CAU peripheral */ + cau_enable(); + /* TDES calculate process */ + ret = cau_tdes_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr); + /* disable the CAU peripheral */ + cau_disable(); + + return ret; +} + +/*! + \brief TDES calculate process + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer in bytes, must be a multiple of 8 bytes + \param[out] output: pointer to the returned buffer + \retval ErrStatus: SUCCESS or ERROR +*/ +static ErrStatus cau_tdes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output) +{ + uint32_t inputaddr = (uint32_t)input; + uint32_t outputaddr = (uint32_t)output; + uint32_t i = 0U; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + + /* the clock is not enabled or there is no embedded CAU peripheral */ + if(DISABLE == cau_enable_state_get()) { + return ERROR; + } + + for(i = 0U; i < in_length; i += 8U) { + /* write data to the IN FIFO */ + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + cau_data_write(*(uint32_t *)(inputaddr)); + inputaddr += 4U; + + /* wait until the complete message has been processed */ + counter = 0U; + do { + busystatus = cau_flag_get(CAU_FLAG_BUSY); + counter++; + } while((TDESBSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus) { + return ERROR; + } else { + /* read the output block from the output FIFO */ + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + *(uint32_t *)(outputaddr) = cau_data_read(); + outputaddr += 4U; + } + } + + return SUCCESS; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cmp.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cmp.c new file mode 100644 index 0000000000..4dadf0c567 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cmp.c @@ -0,0 +1,577 @@ +/*! + \file gd32h7xx_cmp.c + \brief CMP driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_cmp.h" + +/*! + \brief CMP deinit + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_deinit(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ((uint32_t)0x00000000U); + CMP_IFC &= ((uint32_t)0xFFFEFFFFU); + CMP_STAT &= ((uint32_t)0xFFFEFFFEU); + CMP_SR &= ((uint32_t)0x00000000U); + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ((uint32_t)0x00000000U); + CMP_IFC &= ((uint32_t)0xFFFDFFFFU); + CMP_STAT &= ((uint32_t)0xFFFDFFFDU); + CMP_SR &= ((uint32_t)0x00000000U); + }else{ + } +} + +/*! + \brief CMP mode init + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] operating_mode + \arg CMP_MODE_HIGHSPEED: high speed mode + \arg CMP_MODE_MIDDLESPEED: medium speed mode + \arg CMP_MODE_VERYLOWSPEED: very-low speed mode + \param[in] inverting_input + \arg CMP_INVERTING_INPUT_1_4VREFINT: VREFINT *1/4 input + \arg CMP_INVERTING_INPUT_1_2VREFINT: VREFINT *1/2 input + \arg CMP_INVERTING_INPUT_3_4VREFINT: VREFINT *3/4 input + \arg CMP_INVERTING_INPUT_VREFINT: VREFINT input + \arg CMP_INVERTING_INPUT_DAC0_OUT0: PA4 (DAC) input + \arg CMP_INVERTING_INPUT_DAC0_OUT1: PA5 (DAC) input + \arg CMP_INVERTING_INPUT_PB1_PE10: PB1 for CMP0 or PE10 for CMP1 as inverting input + \arg CMP_INVERTING_INPUT_PC4_PE7: PC4 for CMP0 or PE7 for CMP1 as inverting input + \param[in] hysteresis + \arg CMP_HYSTERESIS_NO: output no hysteresis + \arg CMP_HYSTERESIS_LOW: output low hysteresis + \arg CMP_HYSTERESIS_MIDDLE: output middle hysteresis + \arg CMP_HYSTERESIS_HIGH: output high hysteresis + \param[out] none + \retval none +*/ +void cmp_mode_init(cmp_enum cmp_periph, uint32_t operating_mode, uint32_t inverting_input, uint32_t output_hysteresis) +{ + uint32_t temp = 0U; + + if(CMP0 == cmp_periph){ + /* initialize comparator 0 mode */ + temp = CMP0_CS; + temp &= ~(uint32_t)(CMP_CS_CMPXM | CMP_CS_CMPXMISEL | CMP_CS_CMPXHST); + temp |= (uint32_t)(operating_mode | inverting_input | output_hysteresis); + CMP0_CS = temp; + }else if(CMP1 == cmp_periph){ + /* initialize comparator 1 mode */ + temp = CMP1_CS; + temp &= ~(uint32_t)(CMP_CS_CMPXM | CMP_CS_CMPXMISEL | CMP_CS_CMPXHST); + temp |= (uint32_t)(operating_mode | inverting_input | output_hysteresis); + CMP1_CS = temp; + }else{ + } +} + +/*! + \brief CMP noninverting input select + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] noninverting_input + \arg CMP_NONINVERTING_INPUT_PB0_PE9: CMP noninverting input PB0 for CMP0 or PE9 for CMP1 + \arg CMP_NONINVERTING_INPUT_PB2_PE12: CMP noninverting input PB2 for CMP0 or PE12 for CMP1 + \param[out] none + \retval none +*/ +void cmp_noninverting_input_select(cmp_enum cmp_periph, uint32_t noninverting_input) +{ + uint32_t temp = 0U; + + if(CMP0 == cmp_periph){ + temp = CMP0_CS; + temp &= ~(uint32_t)CMP_CS_CMPXPSEL; + temp |= (uint32_t)noninverting_input; + CMP0_CS = temp; + }else if(CMP1 == cmp_periph){ + temp = CMP1_CS; + temp &= ~(uint32_t)CMP_CS_CMPXPSEL; + temp |= (uint32_t)noninverting_input; + CMP1_CS = temp; + }else{ + } +} + +/*! + \brief CMP output init + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] output_polarity + \arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted + \arg CMP_OUTPUT_POLARITY_NONINVERTED: output is not inverted + \param[out] none + \retval none +*/ +void cmp_output_init(cmp_enum cmp_periph, uint32_t output_polarity) +{ + uint32_t temp = 0U; + + if(CMP0 == cmp_periph){ + /* initialize comparator 0 output */ + temp = CMP0_CS; + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){ + temp |= (uint32_t)CMP_CS_CMPXPL; + }else{ + temp &= ~(uint32_t)CMP_CS_CMPXPL; + } + CMP0_CS = temp; + }else if(CMP1 == cmp_periph){ + /* initialize comparator 1 output */ + temp = CMP1_CS; + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){ + temp |= (uint32_t)CMP_CS_CMPXPL; + }else{ + temp &= ~(uint32_t)CMP_CS_CMPXPL; + } + CMP1_CS = temp; + }else{ + } +} + +/*! + \brief config comparator output port + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] cmp_output_sel + \arg CMP_AFSE_GPIO_PA6: CMP alternate GPIO PA6 + \arg CMP_AFSE_GPIO_PA8: CMP alternate GPIO PA8 + \arg CMP_AFSE_GPIO_PB12: CMP alternate GPIO PB12 + \arg CMP_AFSE_GPIO_PE6: CMP alternate GPIO PE6 + \arg CMP_AFSE_GPIO_PE15: CMP alternate GPIO PE15 + \arg CMP_AFSE_GPIO_PG2: CMP alternate GPIO PG2 + \arg CMP_AFSE_GPIO_PG3: CMP alternate GPIO PG3 + \arg CMP_AFSE_GPIO_PG4: CMP alternate GPIO PG4 + \arg CMP_AFSE_GPIO_PK0: CMP alternate GPIO PK0 + \arg CMP_AFSE_GPIO_PK1: CMP alternate GPIO PK1 + \arg CMP_AFSE_GPIO_PK2: CMP alternate GPIO PK2 + \param[out] none + \retval none +*/ +void cmp_output_mux_config(cmp_enum cmp_periph, uint32_t cmp_output_sel) +{ + if(CMP0 == cmp_periph){ + CMP_SR &= ~(uint32_t)cmp_output_sel; + }else if(CMP1 == cmp_periph){ + CMP_SR |= cmp_output_sel; + }else{ + } +} + +/*! + \brief CMP output blanking function init + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] blanking_source_selection + \arg CMP_BLANKING_NONE: CMP no blanking source + \arg CMP_BLANKING_TIMER0_OC0: CMP TIMER0_CH0 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER1_OC2: CMP TIMER1_CH2 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER2_OC2: CMP TIMER2_CH2 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER2_OC3: CMP TIMER2_CH3 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER7_OC0: CMP TIMER7_CH0 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER14_OC0: CMP TIMER14_CH0 output compare signal selected as blanking source + \param[out] none + \retval none +*/ +void cmp_blanking_init(cmp_enum cmp_periph, uint32_t blanking_source_selection) +{ + uint32_t temp = 0U; + + if(CMP0 == cmp_periph){ + temp = CMP0_CS; + temp &= ~(uint32_t)CMP_CS_CMPXBLK; + temp |= (uint32_t)blanking_source_selection; + CMP0_CS = temp; + }else if(CMP1 == cmp_periph){ + temp = CMP1_CS; + temp &= ~(uint32_t)CMP_CS_CMPXBLK; + temp |= (uint32_t)blanking_source_selection; + CMP1_CS = temp; + }else{ + } +} + +/*! + \brief enable CMP + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS |= (uint32_t)CMP_CS_CMPXEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS |= (uint32_t)CMP_CS_CMPXEN; + }else{ + } +} + +/*! + \brief disable CMP + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_disable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ~(uint32_t)CMP_CS_CMPXEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ~(uint32_t)CMP_CS_CMPXEN; + }else{ + } +} + +/*! + \brief enable the window mode + \param[in] none + \param[out] none + \retval none +*/ +void cmp_window_enable(void) +{ + CMP1_CS |= (uint32_t)CMP_CS_WNDEN; +} + +/*! + \brief disable the window mode + \param[in] none + \param[out] none + \retval none +*/ +void cmp_window_disable(void) +{ + CMP1_CS &= ~(uint32_t)CMP_CS_WNDEN; +} + +/*! + \brief lock the comparator + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_lock_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + /* lock CMP0 */ + CMP0_CS |= (uint32_t)CMP_CS_CMPXLK; + }else if(CMP1 == cmp_periph){ + /* lock CMP1 */ + CMP1_CS |= (uint32_t)CMP_CS_CMPXLK; + }else{ + } +} + +/*! + \brief enable the voltage scaler + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_voltage_scaler_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS |= (uint32_t)CMP_CS_CMPXSEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS |= (uint32_t)CMP_CS_CMPXSEN; + }else{ + } +} + +/*! + \brief disable the voltage scaler + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_voltage_scaler_disable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ~(uint32_t)CMP_CS_CMPXSEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ~(uint32_t)CMP_CS_CMPXSEN; + }else{ + } +} + +/*! + \brief enable the scaler bridge + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_scaler_bridge_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS |= (uint32_t)CMP_CS_CMPXBEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS |= (uint32_t)CMP_CS_CMPXBEN; + }else{ + } +} + +/*! + \brief disable the scaler bridge + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_scaler_bridge_disable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ~(uint32_t)CMP_CS_CMPXBEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ~(uint32_t)CMP_CS_CMPXBEN; + }else{ + } +} + +/*! + \brief get output level + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval the output level +*/ +uint32_t cmp_output_level_get(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + /* get output level of CMP0 */ + if((uint32_t)RESET != (CMP_STAT & CMP_STAT_CMP0O)) { + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + }else{ + /* get output level of CMP1 */ + if((uint32_t)RESET != (CMP_STAT & CMP_STAT_CMP1O)) { + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + } +} + +/*! + \brief get CMP flag + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] flag: CMP flags + \arg CMP_FLAG_COMPARE: CMP compare flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cmp_flag_get(cmp_enum cmp_periph, uint32_t flag) +{ + FlagStatus reval = RESET; + + if(CMP0 == cmp_periph){ + if(CMP_FLAG_COMPARE == flag){ + if(0U != (CMP_STAT & CMP_STAT_CMP0IF)){ + reval = SET; + } + } + }else if(CMP1 == cmp_periph){ + if(CMP_FLAG_COMPARE == flag){ + if(0U != (CMP_STAT & CMP_STAT_CMP1IF)){ + reval = SET; + } + } + } + return reval; +} + +/*! + \brief clear CMP flag + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] flag: CMP flags + \arg CMP_FLAG_COMPARE: CMP compare flag + \param[out] none + \retval none +*/ +void cmp_flag_clear(cmp_enum cmp_periph, uint32_t flag) +{ + if(CMP0 == cmp_periph){ + if(CMP_FLAG_COMPARE == flag){ + CMP_IFC |= (uint32_t)CMP_IFC_CMP0IC; + } + }else if(CMP1 == cmp_periph){ + if(CMP_FLAG_COMPARE == flag){ + CMP_IFC |= (uint32_t)CMP_IFC_CMP1IC; + } + }else{ + } +} + +/*! + \brief enable CMP interrupt + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] interrupt: CMP interrupt enable source + only one parameter can be selected which is shown as below: + \arg CMP_INT_COMPARE: CMP compare interrupt + \param[out] none + \retval none +*/ +void cmp_interrupt_enable(cmp_enum cmp_periph, uint32_t interrupt) +{ + if(CMP0 == cmp_periph){ + /* enable CMP0 interrupt */ + CMP0_CS |= (uint32_t)interrupt; + }else if(CMP1 == cmp_periph){ + /* enable CMP1 interrupt */ + CMP1_CS |= (uint32_t)interrupt; + }else{ + } +} + +/*! + \brief disable CMP interrupt + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] interrupt: CMP interrupt enable source + only one parameter can be selected which is shown as below: + \arg CMP_INT_COMPARE: CMP compare interrupt + \param[out] none + \retval none +*/ +void cmp_interrupt_disable(cmp_enum cmp_periph, uint32_t interrupt) +{ + if(CMP0 == cmp_periph){ + /* disable CMP0 interrupt */ + CMP0_CS &= ~(uint32_t)interrupt; + }else if(CMP1 == cmp_periph){ + /* disable CMP1 interrupt */ + CMP1_CS &= ~(uint32_t)interrupt; + }else{ + } +} + +/*! + \brief get CMP interrupt flag + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] flag: CMP interrupt flags + \arg CMP_INT_FLAG_COMPARE: CMP compare interrupt flag + \param[out] none + \retval none +*/ +FlagStatus cmp_interrupt_flag_get(cmp_enum cmp_periph, uint32_t flag) +{ + uint32_t intstatus = 0U, flagstatus = 0U; + + if(CMP0 == cmp_periph){ + if(CMP_INT_FLAG_COMPARE == flag){ + /* get the corresponding flag bit status */ + flagstatus = CMP_STAT & CMP_STAT_CMP0IF; + /* get the interrupt enable bit status */ + intstatus = CMP0_CS & CMP_CS_CMPXINTEN; + } + }else if(CMP1 == cmp_periph){ + if(CMP_INT_FLAG_COMPARE == flag){ + /* get the corresponding flag bit status */ + flagstatus = CMP_STAT & CMP_STAT_CMP1IF; + /* get the interrupt enable bit status */ + intstatus = CMP1_CS & CMP_CS_CMPXINTEN; + } + }else{ + } + + if((0U != flagstatus) && (0U != intstatus)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CMP interrupt flag + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] flag: CMP interrupt flags + \arg CMP_INT_FLAG_COMPARE: CMP compare interrupt flag + \param[out] none + \retval none +*/ +void cmp_interrupt_flag_clear(cmp_enum cmp_periph, uint32_t flag) +{ + /* clear CMP interrupt flag */ + if(CMP0 == cmp_periph){ + if(CMP_INT_FLAG_COMPARE == flag){ + CMP_IFC |= (uint32_t)CMP_IFC_CMP0IC; + } + }else if(CMP1 == cmp_periph){ + if(CMP_INT_FLAG_COMPARE == flag){ + CMP_IFC |= (uint32_t)CMP_IFC_CMP1IC; + } + }else{ + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cpdm.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cpdm.c new file mode 100644 index 0000000000..8c8e9c7b9e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_cpdm.c @@ -0,0 +1,246 @@ +/*! + \file gd32h7xx_cpdm.c + \brief CPDM driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_cpdm.h" + +#define CPDM_CPSEL_MASK ((uint32_t)0xFFFFFFF0U) /*!< CPDM output clock phase seclection mask */ +#define CPDM_DLSTCNT_MASK ((uint32_t)0xFFFF80FFU) /*!< CPDM delay step count for a uint delay UINT mask */ +#define CPDM_DLLENF_MASK ((uint32_t)0x80000000U) /*!< CPDM delay line length valid flag mask */ +#define CPDM_DLLEN_MASK ((uint32_t)0x0FFF0000U) /*!< CPDM delay line length mask */ + +#define CPDM_DLLEN_OFFSET ((uint32_t)16U) /*!< CPDM delay line length offset */ +#define CPDM_DLSTCNT_OFFSET ((uint32_t)8U) /*!< CPDM delay step count for a uint delay UINT offset */ +#define CPDM_DLLEN_11 ((uint32_t)0x04000000U) /*!< CPDM delay line length bit 11 */ +#define CPDM_DLLEN_10 ((uint32_t)0x08000000U) /*!< CPDM delay line length bit 10 */ +#define CPDM_DLLEN_10_0_MASK ((uint32_t)0x7FFU) /*!< CPDM delay line length bit 10 to bit 0 mask */ + +/*! + \brief enable CPDM + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[out] none + \retval none +*/ +void cpdm_enable(uint32_t cpdm_periph) +{ + /* enable CPDM */ + CPDM_CTL(cpdm_periph) |= (uint32_t)CPDM_CTL_CPDMEN; +} + +/*! + \brief disable CPDM + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[out] none + \retval none +*/ +void cpdm_disable(uint32_t cpdm_periph) +{ + /* disable CPDM */ + CPDM_CTL(cpdm_periph) &= ~(uint32_t)CPDM_CTL_CPDMEN; +} + +/*! + \brief enable CPDM delay line sample module + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[out] none + \retval none +*/ +void cpdm_delayline_sample_enable(uint32_t cpdm_periph) +{ + /* enable CPDM delay line sample module */ + CPDM_CTL(cpdm_periph) |= (uint32_t)CPDM_CTL_DLSEN; +} + +/*! + \brief disable CPDM delay line sample module + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[out] none + \retval none +*/ +void cpdm_delayline_sample_disable(uint32_t cpdm_periph) +{ + /* disable CPDM delay line sample module */ + CPDM_CTL(cpdm_periph) &= ~(uint32_t)CPDM_CTL_DLSEN; +} + +/*! + \brief select CPDM output clock phase + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[in] output_clock_phase: the output clock phase, refer to cpdm_output_phase_enum + only one parameter can be selected which is shown as below: + \arg CPDM_OUTPUT_PHASE_SELECTION_0: output clock phase = input clock + \arg CPDM_OUTPUT_PHASE_SELECTION_1: output clock phase = input clock + 1 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_2: output clock phase = input clock + 2 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_3: output clock phase = input clock + 3 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_4: output clock phase = input clock + 4 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_5: output clock phase = input clock + 5 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_6: output clock phase = input clock + 6 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_7: output clock phase = input clock + 7 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_8: output clock phase = input clock + 8 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_9: output clock phase = input clock + 9 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_10: output clock phase = input clock + 10 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_11: output clock phase = input clock + 11 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_12: output clock phase = input clock + 12 * UNIT delay + \param[out] none + \retval none +*/ +void cpdm_output_clock_phase_select(uint32_t cpdm_periph, cpdm_output_phase_enum output_clock_phase) +{ + uint32_t reg = 0U; + + reg = CPDM_CFG(cpdm_periph); + reg &= CPDM_CPSEL_MASK; + /* select CPDM output clock phase */ + reg |= output_clock_phase; + CPDM_CFG(cpdm_periph) = (uint32_t)reg; +} + +/*! + \brief get delay line length valid flag + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus cpdm_delayline_length_valid_flag_get(uint32_t cpdm_periph) +{ + uint32_t reg = 0U; + + reg = CPDM_CFG(cpdm_periph); + if(reg & CPDM_DLLENF_MASK) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief get delay line length + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[out] none + \retval the value of delay line length, 0x00~0xFFF +*/ +uint16_t cpdm_delayline_length_get(uint32_t cpdm_periph) +{ + return (uint16_t)((CPDM_CFG(cpdm_periph) & CPDM_DLLEN_MASK) >> CPDM_DLLEN_OFFSET); +} + +/*! + \brief configure CPDM clock output + \param[in] cpdm_periph: the clock phase delay module of SDIO + only one parameter can be selected which is shown as below: + \arg CPDM_SDIO0: clock phase delay module of SDIO0 + \arg CPDM_SDIO1: clock phase delay module of SDIO1 + \param[in] output_clock_phase: the output clock phase, refer to cpdm_output_phase_enum + only one parameter can be selected which is shown as below: + \arg CPDM_OUTPUT_PHASE_SELECTION_0: output clock phase = input clock + \arg CPDM_OUTPUT_PHASE_SELECTION_1: output clock phase = input clock + 1 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_2: output clock phase = input clock + 2 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_3: output clock phase = input clock + 3 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_4: output clock phase = input clock + 4 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_5: output clock phase = input clock + 5 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_6: output clock phase = input clock + 6 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_7: output clock phase = input clock + 7 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_8: output clock phase = input clock + 8 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_9: output clock phase = input clock + 9 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_10: output clock phase = input clock + 10 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_11: output clock phase = input clock + 11 * UNIT delay + \arg CPDM_OUTPUT_PHASE_SELECTION_12: output clock phase = input clock + 12 * UNIT delay + \param[out] none + \retval none +*/ +void cpdm_clock_output(uint32_t cpdm_periph, cpdm_output_phase_enum output_clock_phase) +{ + uint32_t reg = 0U; + uint32_t reg_cfg = 0U; + uint32_t delay_count = 0U; + + /* enable CPDM and delay line sample module */ + CPDM_CTL(cpdm_periph) = 0U; + CPDM_CTL(cpdm_periph) = CPDM_CTL_CPDMEN | CPDM_CTL_DLSEN; + /* configure CPDM output clock phase to the max value (12) */ + reg = CPDM_CFG(cpdm_periph); + reg &= CPDM_CPSEL_MASK; + reg |= CPDM_MAX_PHASE; + CPDM_CFG(cpdm_periph) = (uint32_t)reg; + + for(delay_count = 0U; delay_count <= CPDM_MAX_DELAY_STEP_COUNT; delay_count++) { + reg = CPDM_CFG(cpdm_periph); + reg &= CPDM_DLSTCNT_MASK; + /* configure delay line step count */ + reg |= delay_count << CPDM_DLSTCNT_OFFSET; + CPDM_CFG(cpdm_periph) = (uint32_t)reg; + + while(SET == (CPDM_CFG(cpdm_periph) & CPDM_CFG_DLLENF)) { + } + while(RESET == (CPDM_CFG(cpdm_periph) & CPDM_CFG_DLLENF)) { + } + + reg_cfg = CPDM_CFG(cpdm_periph); + if((((reg_cfg >> CPDM_DLLEN_OFFSET) & CPDM_DLLEN_10_0_MASK) > 0U) && + ((RESET == (reg_cfg & CPDM_DLLEN_11)) || (RESET == (reg_cfg & CPDM_DLLEN_10)))) { + break; + } + } + + /* enable CPDM and delay line sample module */ + CPDM_CTL(cpdm_periph) = 0U; + CPDM_CTL(cpdm_periph) = CPDM_CTL_CPDMEN | CPDM_CTL_DLSEN; + /* select the output clock phase */ + reg = CPDM_CFG(cpdm_periph); + reg &= CPDM_CPSEL_MASK; + reg |= output_clock_phase; + CPDM_CFG(cpdm_periph) = (uint32_t)reg; + /* disable delay line sample module */ + CPDM_CTL(cpdm_periph) = CPDM_CTL_CPDMEN; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_crc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_crc.c new file mode 100644 index 0000000000..13cb65c037 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_crc.c @@ -0,0 +1,247 @@ +/*! + \file gd32h7xx_crc.c + \brief CRC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_crc.h" + +#define CRC_IDATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU) +#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU) +#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U) +#define CRC_POLY_RESET_VALUE ((uint32_t)0x04C11DB7U) + +/*! + \brief deinit CRC calculation unit + \param[in] none + \param[out] none + \retval none +*/ +void crc_deinit(void) +{ + CRC_IDATA = CRC_IDATA_RESET_VALUE; + CRC_DATA = CRC_DATA_RESET_VALUE; + CRC_FDATA = CRC_FDATA_RESET_VALUE; + CRC_POLY = CRC_POLY_RESET_VALUE; + CRC_CTL = (uint32_t)CRC_CTL_RST; +} + +/*! + \brief enable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_enable(void) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O); + CRC_CTL |= (uint32_t)CRC_CTL_REV_O; +} + +/*! + \brief disable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_disable(void) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O); +} + +/*! + \brief reset data register to the value of initialization data register + \param[in] none + \param[out] none + \retval none +*/ +void crc_data_register_reset(void) +{ + CRC_CTL |= (uint32_t)CRC_CTL_RST; +} + +/*! + \brief read the data register + \param[in] none + \param[out] none + \retval 32-bit value of the data register +*/ +uint32_t crc_data_register_read(void) +{ + uint32_t data; + data = CRC_DATA; + return (data); +} + +/*! + \brief read the free data register + \param[in] none + \param[out] none + \retval 8-bit value of the free data register +*/ +uint8_t crc_free_data_register_read(void) +{ + uint8_t fdata; + fdata = (uint8_t)CRC_FDATA; + return (fdata); +} + +/*! + \brief write the free data register + \param[in] free_data: specify 8-bit data + \param[out] none + \retval none +*/ +void crc_free_data_register_write(uint8_t free_data) +{ + CRC_FDATA = (uint32_t)free_data; +} + +/*! + \brief write the initialization data register + \param[in] init_data:specify 32-bit data + \param[out] none + \retval none +*/ +void crc_init_data_register_write(uint32_t init_data) +{ + CRC_IDATA = init_data; +} + +/*! + \brief configure the CRC input data function + \param[in] data_reverse: specify input data reverse function + only one parameter can be selected which is shown as below: + \arg CRC_INPUT_DATA_NOT: input data is not reversed + \arg CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits + \arg CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits + \arg CRC_INPUT_DATA_WORD: input data is reversed on 32 bits + \param[out] none + \retval none +*/ +void crc_input_data_reverse_config(uint32_t data_reverse) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I); + CRC_CTL |= (uint32_t)data_reverse; +} + +/*! + \brief configure the CRC size of polynomial function + \param[in] poly_size: size of polynomial + only one parameter can be selected which is shown as below: + \arg CRC_CTL_PS_32: 32-bit polynomial for CRC calculation + \arg CRC_CTL_PS_16: 16-bit polynomial for CRC calculation + \arg CRC_CTL_PS_8: 8-bit polynomial for CRC calculation + \arg CRC_CTL_PS_7: 7-bit polynomial for CRC calculation + \param[out] none + \retval none +*/ +void crc_polynomial_size_set(uint32_t poly_size) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_PS); + CRC_CTL |= (uint32_t)poly_size; +} + +/*! + \brief configure the CRC polynomial value function + \param[in] poly: configurable polynomial value + \param[out] none + \retval none +*/ +void crc_polynomial_set(uint32_t poly) +{ + CRC_POLY &= (uint32_t)(~CRC_POLY_POLY); + CRC_POLY = poly; +} + +/*! + \brief CRC calculate single data + \param[in] sdata: specify input data + \param[in] data_format: input data format + only one parameter can be selected which is shown as below: + \arg INPUT_FORMAT_WORD: input data in word format + \arg INPUT_FORMAT_HALFWORD: input data in half-word format + \arg INPUT_FORMAT_BYTE: input data in byte format + \param[out] none + \retval CRC calculate value +*/ +uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format) +{ + if(INPUT_FORMAT_WORD == data_format) { + REG32(CRC) = sdata; + } else if(INPUT_FORMAT_HALFWORD == data_format) { + REG16(CRC) = (uint16_t)sdata; + } else if(INPUT_FORMAT_BYTE == data_format) { + REG8(CRC) = (uint8_t)sdata; + } else { + } + + return(CRC_DATA); +} + +/*! + \brief CRC calculate a data array + \param[in] array: pointer to the input data array + \param[in] size: size of the array + \param[in] data_format: input data format + only one parameter can be selected which is shown as below: + \arg INPUT_FORMAT_WORD: input data in word format + \arg INPUT_FORMAT_HALFWORD: input data in half-word format + \arg INPUT_FORMAT_BYTE: input data in byte format + \param[out] none + \retval CRC calculate value +*/ +uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format) +{ + uint8_t *data8; + uint16_t *data16; + uint32_t *data32; + uint32_t index; + + if(INPUT_FORMAT_WORD == data_format) { + data32 = (uint32_t *)array; + for(index = 0U; index < size; index++) { + REG32(CRC) = data32[index]; + } + } else if(INPUT_FORMAT_HALFWORD == data_format) { + data16 = (uint16_t *)array; + for(index = 0U; index < size; index++) { + REG16(CRC) = data16[index]; + } + } else { + data8 = (uint8_t *)array; + for(index = 0U; index < size; index++) { + REG8(CRC) = data8[index]; + } + } + + return (CRC_DATA); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ctc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ctc.c new file mode 100644 index 0000000000..95756a9de4 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ctc.c @@ -0,0 +1,390 @@ +/*! + \file gd32h7xx_ctc.c + \brief CTC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_ctc.h" + +#define CTC_FLAG_MASK ((uint32_t)0x00000700U) + +/* CTC register bit offset */ +#define CTC_TRIMVALUE_OFFSET ((uint32_t)8U) +#define CTC_TRIM_VALUE_OFFSET ((uint32_t)8U) +#define CTC_REFCAP_OFFSET ((uint32_t)16U) +#define CTC_LIMIT_VALUE_OFFSET ((uint32_t)16U) + +/*! + \brief reset CTC clock trim controller + \param[in] none + \param[out] none + \retval none +*/ +void ctc_deinit(void) +{ + /* reset CTC */ + rcu_periph_reset_enable(RCU_CTCRST); + rcu_periph_reset_disable(RCU_CTCRST); +} + +/*! + \brief enable CTC trim counter + \param[in] none + \param[out] none + \retval none +*/ +void ctc_counter_enable(void) +{ + CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN; +} + +/*! + \brief disable CTC trim counter + \param[in] none + \param[out] none + \retval none +*/ +void ctc_counter_disable(void) +{ + CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN); +} + +/*! + \brief configure the IRC48M trim value + \param[in] trim_value: 8-bit IRC48M trim value + \arg 0x00 - 0x3F + \param[out] none + \retval none +*/ +void ctc_irc48m_trim_value_config(uint8_t trim_value) +{ + /* clear TRIMVALUE bits */ + CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE); + /* set TRIMVALUE bits */ + CTC_CTL0 |= ((uint32_t)trim_value << CTC_TRIM_VALUE_OFFSET); +} + +/*! + \brief generate software reference source sync pulse + \param[in] none + \param[out] none + \retval none +*/ +void ctc_software_refsource_pulse_generate(void) +{ + CTC_CTL0 |= (uint32_t)CTC_CTL0_SWREFPUL; +} + +/*! + \brief configure hardware automatically trim mode + \param[in] hardmode: + only one parameter can be selected which is shown as below: + \arg CTC_HARDWARE_TRIM_MODE_ENABLE: hardware automatically trim mode enable + \arg CTC_HARDWARE_TRIM_MODE_DISABLE: hardware automatically trim mode disable + \param[out] none + \retval none +*/ +void ctc_hardware_trim_mode_config(uint32_t hardmode) +{ + CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM); + CTC_CTL0 |= (uint32_t)hardmode; +} + +/*! + \brief configure reference signal source polarity + \param[in] polarity: reference signal source edge + only one parameter can be selected which is shown as below: + \arg CTC_REFSOURCE_POLARITY_FALLING: reference signal source polarity is falling edge + \arg CTC_REFSOURCE_POLARITY_RISING: reference signal source polarity is rising edge + \param[out] none + \retval none +*/ +void ctc_refsource_polarity_config(uint32_t polarity) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL); + CTC_CTL1 |= (uint32_t)polarity; +} + +/*! + \brief select reference signal source + \param[in] refs: reference signal source + only one parameter can be selected which is shown as below: + \arg CTC_REFSOURCE_GPIO: GPIO is selected + \arg CTC_REFSOURCE_LXTAL: LXTAL is selected + \param[out] none + \retval none +*/ +void ctc_refsource_signal_select(uint32_t refs) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL); + CTC_CTL1 |= (uint32_t)refs; +} + +/*! + \brief configure reference signal source prescaler + \param[in] prescaler: reference signal source prescaler + only one parameter can be selected which is shown as below: + \arg CTC_REFSOURCE_PSC_OFF: reference signal not divided + \arg CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2 + \arg CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4 + \arg CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8 + \arg CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16 + \arg CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32 + \arg CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64 + \arg CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128 + \param[out] none + \retval none +*/ +void ctc_refsource_prescaler_config(uint32_t prescaler) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC); + CTC_CTL1 |= (uint32_t)prescaler; +} + +/*! + \brief configure clock trim base limit value + \param[in] limit_value: 8-bit clock trim base limit value + \arg 0x00 - 0xFF + \param[out] none + \retval none +*/ +void ctc_clock_limit_value_config(uint8_t limit_value) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM); + CTC_CTL1 |= (uint32_t)((uint32_t)limit_value << CTC_LIMIT_VALUE_OFFSET); +} + +/*! + \brief configure CTC counter reload value + \param[in] reload_value: 16-bit CTC counter reload value + \arg 0x0000 - 0xFFFF + \param[out] none + \retval none +*/ +void ctc_counter_reload_value_config(uint16_t reload_value) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE); + CTC_CTL1 |= (uint32_t)reload_value; +} + +/*! + \brief read CTC counter capture value when reference sync pulse occurred + \param[in] none + \param[out] none + \retval the 16-bit CTC counter capture value +*/ +uint16_t ctc_counter_capture_value_read(void) +{ + uint16_t capture_value = 0U; + capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> CTC_REFCAP_OFFSET); + return (capture_value); +} + +/*! + \brief read CTC trim counter direction when reference sync pulse occurred + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET + \arg SET: CTC trim counter direction is down-counting + \arg RESET: CTC trim counter direction is up-counting +*/ +FlagStatus ctc_counter_direction_read(void) +{ + if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief read CTC counter reload value + \param[in] none + \param[out] none + \retval the 16-bit CTC counter reload value +*/ +uint16_t ctc_counter_reload_value_read(void) +{ + uint16_t reload_value = 0U; + reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE); + return (reload_value); +} + +/*! + \brief read the IRC48M trim value + \param[in] none + \param[out] none + \retval the 8-bit IRC48M trim value +*/ +uint8_t ctc_irc48m_trim_value_read(void) +{ + uint8_t trim_value = 0U; + trim_value = (uint8_t)((CTC_CTL0 & CTC_CTL0_TRIMVALUE) >> CTC_TRIMVALUE_OFFSET); + return (trim_value); +} + +/*! + \brief get CTC flag + \param[in] flag: the CTC flag + only one parameter can be selected which is shown as below: + \arg CTC_FLAG_CKOK: clock trim OK flag + \arg CTC_FLAG_CKWARN: clock trim warning flag + \arg CTC_FLAG_ERR: error flag + \arg CTC_FLAG_EREF: expect reference flag + \arg CTC_FLAG_CKERR: clock trim error flag + \arg CTC_FLAG_REFMISS: reference sync pulse miss flag + \arg CTC_FLAG_TRIMERR: trim value error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ctc_flag_get(uint32_t flag) +{ + if(RESET != (CTC_STAT & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CTC flag + \param[in] flag: the CTC flag + only one parameter can be selected which is shown as below: + \arg CTC_FLAG_CKOK: clock trim OK flag + \arg CTC_FLAG_CKWARN: clock trim warning flag + \arg CTC_FLAG_ERR: error flag + \arg CTC_FLAG_EREF: expect reference flag + \arg CTC_FLAG_CKERR: clock trim error flag + \arg CTC_FLAG_REFMISS: reference sync pulse miss flag + \arg CTC_FLAG_TRIMERR: trim value error flag + \param[out] none + \retval none +*/ +void ctc_flag_clear(uint32_t flag) +{ + if(RESET != (flag & CTC_FLAG_MASK)){ + CTC_INTC |= CTC_INTC_ERRIC; + }else{ + CTC_INTC |= flag; + } +} + +/*! + \brief enable the CTC interrupt + \param[in] interrupt: CTC interrupt enable source + one or more parameters can be selected which are shown as below: + \arg CTC_INT_CKOK: clock trim OK interrupt + \arg CTC_INT_CKWARN: clock trim warning interrupt + \arg CTC_INT_ERR: error interrupt + \arg CTC_INT_EREF: expect reference interrupt + \param[out] none + \retval none +*/ +void ctc_interrupt_enable(uint32_t interrupt) +{ + CTC_CTL0 |= (uint32_t)interrupt; +} + +/*! + \brief disable the CTC interrupt + \param[in] interrupt: CTC interrupt disable source + one or more parameters can be selected which are shown as below: + \arg CTC_INT_CKOK: clock trim OK interrupt + \arg CTC_INT_CKWARN: clock trim warning interrupt + \arg CTC_INT_ERR: error interrupt + \arg CTC_INT_EREF: expect reference interrupt + \param[out] none + \retval none +*/ +void ctc_interrupt_disable(uint32_t interrupt) +{ + CTC_CTL0 &= (uint32_t)(~interrupt); +} + +/*! + \brief get CTC interrupt flag + \param[in] int_flag: the CTC interrupt flag + only one parameter can be selected which is shown as below: + \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt flag + \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt flag + \arg CTC_INT_FLAG_ERR: error interrupt flag + \arg CTC_INT_FLAG_EREF: expect reference interrupt flag + \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt flag + \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt flag + \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ctc_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t interrupt_flag = 0U, intenable = 0U; + + /* check whether the interrupt is enabled */ + if(RESET != (int_flag & CTC_FLAG_MASK)){ + intenable = CTC_CTL0 & CTC_CTL0_ERRIE; + }else{ + intenable = CTC_CTL0 & int_flag; + } + + /* get interrupt flag status */ + interrupt_flag = CTC_STAT & int_flag; + + if(interrupt_flag && intenable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear CTC interrupt flag + \param[in] int_flag: the CTC interrupt flag + only one parameter can be selected which is shown as below: + \arg CTC_INT_FLAG_CKOK: clock trim OK interrupt flag + \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt flag + \arg CTC_INT_FLAG_ERR: error interrupt flag + \arg CTC_INT_FLAG_EREF: expect reference interrupt flag + \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt flag + \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt flag + \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt flag + \param[out] none + \retval none +*/ +void ctc_interrupt_flag_clear(uint32_t int_flag) +{ + if(RESET != (int_flag & CTC_FLAG_MASK)){ + CTC_INTC |= CTC_INTC_ERRIC; + }else{ + CTC_INTC |= int_flag; + } +} + + diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dac.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dac.c new file mode 100644 index 0000000000..87cbfb8069 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dac.c @@ -0,0 +1,750 @@ +/*! + \file gd32h7xx_dac.c + \brief DAC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_dac.h" + +/* DAC register bit offset */ +#define OUT1_REG_OFFSET ((uint32_t)0x00000010U) +#define DH_12BIT_OFFSET ((uint32_t)0x00000010U) +#define DH_8BIT_OFFSET ((uint32_t)0x00000008U) + +#define DAC_STAT_FLAG_MASK0 (DAC_FLAG_DDUDR0 | DAC_FLAG_DDUDR1) +#define DAC_INT_EN_MASK0 (DAC_INT_DDUDR0 | DAC_INT_DDUDR1) +#define DAC_INT_FLAG_MASK0 (DAC_INT_FLAG_DDUDR0 | DAC_INT_FLAG_DDUDR1) + +/*! + \brief deinitialize DAC + \param[in] dac_periph: DACx(x=0) + \param[out] none + \retval none +*/ +void dac_deinit(uint32_t dac_periph) +{ + switch(dac_periph){ + case DAC0: + /* reset DAC0 */ + rcu_periph_reset_enable(RCU_DACRST); + rcu_periph_reset_disable(RCU_DACRST); + break; + default: + break; + } +} + +/*! + \brief enable DAC + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval none +*/ +void dac_enable(uint32_t dac_periph, uint8_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DEN0; + }else if(DAC_OUT1 == dac_out){ + DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DEN1; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable DAC + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval none +*/ +void dac_disable(uint32_t dac_periph, uint8_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DEN0); + }else if(DAC_OUT1 == dac_out){ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DEN1); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable DAC DMA function + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval none +*/ +void dac_dma_enable(uint32_t dac_periph, uint8_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DDMAEN0; + }else if(DAC_OUT1 == dac_out){ + DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DDMAEN1; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable DAC DMA function + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval none +*/ +void dac_dma_disable(uint32_t dac_periph, uint8_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DDMAEN0); + }else if(DAC_OUT1 == dac_out){ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DDMAEN1); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure DAC mode + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] mode: DAC working mode + only one parameter can be selected which is shown as below: + \arg NORMAL_PIN_BUFFON: DAC_OUT_x work in normal mode and connect to external pin with buffer enable + \arg NORMAL_PIN_PERIPHERAL_BUFFON: DAC_OUT_x work in normal mode and connect to external pin and on chip peripherals with buffer enable + \arg NORMAL_PIN_BUFFOFF: DAC_OUT_x work in normal mode and connect to external pin with buffer disable + \arg NORMAL_PIN_PERIPHERAL_BUFFOFF: DAC_OUT_x work in normal mode and connect to on chip peripherals with buffer disable + \arg SAMPLEKEEP_PIN_BUFFON: DAC_OUT_x work in sample and keep mode and connect to external pin with buffer enable + \arg SAMPLEKEEP_PIN_PERIPHERAL_BUFFON: DAC_OUT_x work in sample and keep mode and connect to external pin and on chip peripherals with buffer enable + \arg SAMPLEKEEP_PIN_BUFFOFF: DAC_OUT_x work in sample and keep mode and connect to external pin and on chip peripherals with buffer enable + \arg SAMPLEKEEP_PIN_PERIPHERAL_BUFFOFF: DAC_OUT_x work in sample and keep mode and connect to on chip peripherals with buffer disable + \param[out] none + \retval none +*/ +void dac_mode_config(uint32_t dac_periph, uint32_t dac_out, uint32_t mode) +{ + if(DAC_OUT0 == dac_out){ + /* configure DAC0 mode */ + DAC_MDCR(dac_periph) &= ~(uint32_t)DAC_MDCR_MODE0; + DAC_MDCR(dac_periph) |= mode; + }else if(DAC_OUT1 == dac_out){ + /* configure DAC1 mode */ + DAC_MDCR(dac_periph) &= ~(uint32_t)DAC_MDCR_MODE1; + DAC_MDCR(dac_periph) |= (mode << OUT1_REG_OFFSET); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief get the DACx trimming value + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval DACx trimming value +*/ +uint32_t dac_trimming_value_get(uint32_t dac_periph, uint32_t dac_out) +{ + uint32_t tmp = 0U; + if(DAC_OUT0 == dac_out) { + /* get the DAC_OUT_0 trimming value */ + tmp = DAC_CALR(dac_periph) & DAC_CALR_OTV0; + } else if(DAC_OUT1 == dac_out) { + /* get the DAC_OUT_1 trimming value */ + tmp = (DAC_CALR(dac_periph) & DAC_CALR_OTV1) >> OUT1_REG_OFFSET; + } else { + } + + return tmp; +} + +/*! + \brief set the DACx trimming value + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] trim_value: set new DAC trimming value + \param[out] none +*/ +void dac_trimming_value_set(uint32_t dac_periph, uint32_t dac_out, uint32_t trim_value) +{ + uint32_t tmp = 0U; + + /* get the trimming value */ + tmp = DAC_CALR(dac_periph); + + if(DAC_OUT0 == dac_out) { + /* set the DACx_OUT0 trimming value */ + tmp &= ~(uint32_t)DAC_CALR_OTV0; + tmp |= (trim_value & DAC_CALR_OTV0); + DAC_CALR(dac_periph) = tmp; + }else if(DAC_OUT1 == dac_out){ + /* set the DACx_OUT1 trimming value */ + tmp &= ~(uint32_t)DAC_CALR_OTV1; + tmp |= ((trim_value << OUT1_REG_OFFSET) & DAC_CALR_OTV1); + DAC_CALR(dac_periph) = tmp; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable the DACx trimming + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none +*/ +void dac_trimming_enable(uint32_t dac_periph, uint32_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + /* enable the DACx_OUT0 trimming */ + DAC_CTL0(dac_periph) |= DAC_CTL0_CALEN0; + }else if(DAC_OUT1 == dac_out){ + /* enable the DACx_OUT1 trimming */ + DAC_CTL0(dac_periph) |= DAC_CTL0_CALEN1; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief get DAC output value + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval DAC output data: 0~4095 +*/ +uint16_t dac_output_value_get(uint32_t dac_periph, uint8_t dac_out) +{ + uint16_t data = 0U; + + if(DAC_OUT0 == dac_out){ + /* store the DACx_OUT0 output value */ + data = (uint16_t)DAC_OUT0_DO(dac_periph); + }else if(DAC_OUT1 == dac_out){ + /* store the DACx_OUT1 output value */ + data = (uint16_t)DAC_OUT1_DO(dac_periph); + }else{ + /* illegal parameters */ + } + + return data; +} + +/*! + \brief set DAC data holding register value + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] dac_align: DAC data alignment mode + only one parameter can be selected which is shown as below: + \arg DAC_ALIGN_12B_R: 12-bit right-aligned data + \arg DAC_ALIGN_12B_L: 12-bit left-aligned data + \arg DAC_ALIGN_8B_R: 8-bit right-aligned data + \param[in] data: data to be loaded(0~4095) + \param[out] none + \retval none +*/ +void dac_data_set(uint32_t dac_periph, uint8_t dac_out, uint32_t dac_align, uint16_t data) +{ + /* DAC_OUT0 data alignment */ + if(DAC_OUT0 == dac_out){ + switch(dac_align){ + /* 12-bit right-aligned data */ + case DAC_ALIGN_12B_R: + DAC_OUT0_R12DH(dac_periph) = data; + break; + /* 12-bit left-aligned data */ + case DAC_ALIGN_12B_L: + DAC_OUT0_L12DH(dac_periph) = data; + break; + /* 8-bit right-aligned data */ + case DAC_ALIGN_8B_R: + DAC_OUT0_R8DH(dac_periph) = data; + break; + default: + break; + } + }else if(DAC_OUT1 == dac_out){ + /* DAC_OUT1 data alignment */ + switch(dac_align){ + /* 12-bit right-aligned data */ + case DAC_ALIGN_12B_R: + DAC_OUT1_R12DH(dac_periph) = data; + break; + /* 12-bit left-aligned data */ + case DAC_ALIGN_12B_L: + DAC_OUT1_L12DH(dac_periph) = data; + break; + /* 8-bit right-aligned data */ + case DAC_ALIGN_8B_R: + DAC_OUT1_R8DH(dac_periph) = data; + break; + default: + break; + } + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable DAC trigger + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval none +*/ +void dac_trigger_enable(uint32_t dac_periph, uint8_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DTEN0; + }else if(DAC_OUT1 == dac_out){ + DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DTEN1; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable DAC trigger + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[out] none + \retval none +*/ +void dac_trigger_disable(uint32_t dac_periph, uint8_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTEN0); + }else if(DAC_OUT1 == dac_out){ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTEN1); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure DAC trigger source + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] triggersource: external trigger of DAC + only one parameter can be selected which is shown as below: + \arg DAC_TRIGGER_EXTERNAL: external trigger selected by TRIGSEL + \arg DAC_TRIGGER_SOFTWARE: software trigger + \param[out] none + \retval none +*/ +void dac_trigger_source_config(uint32_t dac_periph, uint8_t dac_out, uint32_t triggersource) +{ + if(DAC_OUT0 == dac_out){ + /* configure DACx_OUT0 trigger source */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTSEL0); + DAC_CTL0(dac_periph) |= triggersource; + }else if(DAC_OUT1 == dac_out){ + /* configure DACx_OUT1 trigger source */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTSEL1); + DAC_CTL0(dac_periph) |= (triggersource << OUT1_REG_OFFSET); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable DAC software trigger + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \retval none +*/ +void dac_software_trigger_enable(uint32_t dac_periph, uint8_t dac_out) +{ + if(DAC_OUT0 == dac_out){ + DAC_SWT(dac_periph) |= (uint32_t)DAC_SWT_SWTR0; + }else if(DAC_OUT1 == dac_out){ + DAC_SWT(dac_periph) |= (uint32_t)DAC_SWT_SWTR1; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure DAC wave mode + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] wave_mode: DAC wave mode + only one parameter can be selected which is shown as below: + \arg DAC_WAVE_DISABLE: wave mode disable + \arg DAC_WAVE_MODE_LFSR: LFSR noise mode + \arg DAC_WAVE_MODE_TRIANGLE: triangle noise mode + \param[out] none + \retval none +*/ +void dac_wave_mode_config(uint32_t dac_periph, uint8_t dac_out, uint32_t wave_mode) +{ + if(DAC_OUT0 == dac_out){ + /* configure DACx_OUT0 wave mode */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWM0); + DAC_CTL0(dac_periph) |= wave_mode; + }else if(DAC_OUT1 == dac_out){ + /* configure DACx_OUT1 wave mode */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWM1); + DAC_CTL0(dac_periph) |= (wave_mode << OUT1_REG_OFFSET); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure DAC LFSR noise mode + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] unmask_bits: LFSR noise unmask bits + only one parameter can be selected which is shown as below: + \arg DAC_LFSR_BIT0: unmask the LFSR bit0 + \arg DAC_LFSR_BITS1_0: unmask the LFSR bits[1:0] + \arg DAC_LFSR_BITS2_0: unmask the LFSR bits[2:0] + \arg DAC_LFSR_BITS3_0: unmask the LFSR bits[3:0] + \arg DAC_LFSR_BITS4_0: unmask the LFSR bits[4:0] + \arg DAC_LFSR_BITS5_0: unmask the LFSR bits[5:0] + \arg DAC_LFSR_BITS6_0: unmask the LFSR bits[6:0] + \arg DAC_LFSR_BITS7_0: unmask the LFSR bits[7:0] + \arg DAC_LFSR_BITS8_0: unmask the LFSR bits[8:0] + \arg DAC_LFSR_BITS9_0: unmask the LFSR bits[9:0] + \arg DAC_LFSR_BITS10_0: unmask the LFSR bits[10:0] + \arg DAC_LFSR_BITS11_0: unmask the LFSR bits[11:0] + \param[out] none + \retval none +*/ +void dac_lfsr_noise_config(uint32_t dac_periph, uint8_t dac_out, uint32_t unmask_bits) +{ + if(DAC_OUT0 == dac_out){ + /* configure DACx_OUT0 LFSR noise mode */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW0); + DAC_CTL0(dac_periph) |= unmask_bits; + }else if(DAC_OUT1 == dac_out){ + /* configure DACx_OUT1 LFSR noise mode */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW1); + DAC_CTL0(dac_periph) |= (unmask_bits << OUT1_REG_OFFSET); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure DAC triangle noise mode + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] amplitude: the amplitude of the triangle + only one parameter can be selected which is shown as below: + \arg DAC_TRIANGLE_AMPLITUDE_1: triangle amplitude is 1 + \arg DAC_TRIANGLE_AMPLITUDE_3: triangle amplitude is 3 + \arg DAC_TRIANGLE_AMPLITUDE_7: triangle amplitude is 7 + \arg DAC_TRIANGLE_AMPLITUDE_15: triangle amplitude is 15 + \arg DAC_TRIANGLE_AMPLITUDE_31: triangle amplitude is 31 + \arg DAC_TRIANGLE_AMPLITUDE_63: triangle amplitude is 63 + \arg DAC_TRIANGLE_AMPLITUDE_127: triangle amplitude is 127 + \arg DAC_TRIANGLE_AMPLITUDE_255: triangle amplitude is 255 + \arg DAC_TRIANGLE_AMPLITUDE_511: triangle amplitude is 511 + \arg DAC_TRIANGLE_AMPLITUDE_1023: triangle amplitude is 1023 + \arg DAC_TRIANGLE_AMPLITUDE_2047: triangle amplitude is 2047 + \arg DAC_TRIANGLE_AMPLITUDE_4095: triangle amplitude is 4095 + \param[out] none + \retval none +*/ +void dac_triangle_noise_config(uint32_t dac_periph, uint8_t dac_out, uint32_t amplitude) +{ + if(DAC_OUT0 == dac_out){ + /* configure DACx_OUT0 triangle noise mode */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW0); + DAC_CTL0(dac_periph) |= amplitude; + }else if(DAC_OUT1 == dac_out){ + /* configure DACx_OUT1 triangle noise mode */ + DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW1); + DAC_CTL0(dac_periph) |= (amplitude << OUT1_REG_OFFSET); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable DAC concurrent mode + \param[in] dac_periph: DACx(x=0) + \param[out] none + \retval none +*/ +void dac_concurrent_enable(uint32_t dac_periph) +{ + uint32_t ctl = 0U; + + ctl = (uint32_t)(DAC_CTL0_DEN0 | DAC_CTL0_DEN1); + DAC_CTL0(dac_periph) |= (uint32_t)ctl; +} + +/*! + \brief disable DAC concurrent mode + \param[in] dac_periph: DACx(x=0) + \param[out] none + \retval none +*/ +void dac_concurrent_disable(uint32_t dac_periph) +{ + uint32_t ctl = 0U; + + ctl = (uint32_t)(DAC_CTL0_DEN0 | DAC_CTL0_DEN1); + DAC_CTL0(dac_periph) &= (uint32_t)(~ctl); +} + +/*! + \brief enable DAC concurrent software trigger + \param[in] dac_periph: DACx(x=0) + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_enable(uint32_t dac_periph) +{ + uint32_t swt = 0U; + + swt = (uint32_t)(DAC_SWT_SWTR0 | DAC_SWT_SWTR1); + DAC_SWT(dac_periph) |= (uint32_t)swt; +} + +/*! + \brief set DAC concurrent mode data holding register value + \param[in] dac_periph: DACx(x=0) + \param[in] dac_align: DAC data alignment mode + only one parameter can be selected which is shown as below: + \arg DAC_ALIGN_12B_R: 12-bit right-aligned data + \arg DAC_ALIGN_12B_L: 12-bit left-aligned data + \arg DAC_ALIGN_8B_R: 8-bit right-aligned data + \param[in] data0: data to be loaded(0~4095) + \param[in] data1: data to be loaded(0~4095) + \param[out] none + \retval none +*/ +void dac_concurrent_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data0, uint16_t data1) +{ + uint32_t data = 0U; + + switch(dac_align){ + /* 12-bit right-aligned data */ + case DAC_ALIGN_12B_R: + data = (uint32_t)(((uint32_t)data1 << DH_12BIT_OFFSET) | data0); + DACC_R12DH(dac_periph) = (uint32_t)data; + break; + /* 12-bit left-aligned data */ + case DAC_ALIGN_12B_L: + data = (uint32_t)(((uint32_t)data1 << DH_12BIT_OFFSET) | data0); + DACC_L12DH(dac_periph) = (uint32_t)data; + break; + /* 8-bit right-aligned data */ + case DAC_ALIGN_8B_R: + data = (uint32_t)(((uint32_t)data1 << DH_8BIT_OFFSET) | data0); + DACC_R8DH(dac_periph) = (uint32_t)data; + break; + default: + break; + } +} + +/*! + \brief set DAC sample and keep time value + \param[in] dac_periph: DACx(x=0) + \param[in] dac_out: DAC_OUTx(x=0,1) + \param[in] sample_time: DAC sample time + \param[in] keep_time: DAC keep time + \param[in] refresh_time: DAC refresh time + \param[out] none + \retval none +*/ +void dac_sample_keep_mode_config(uint32_t dac_periph, uint32_t dac_out, uint32_t sample_time, uint32_t keep_time, uint32_t refresh_time) +{ + uint32_t tmp = 0U; + + if(DAC_OUT0 == dac_out){ + /* configure DACx_OUT0 Sample & Keep mode */ + DAC_SKSTR0(dac_periph) |= (sample_time & DAC_SKSTR0_TSAMP0); + + tmp = (DAC_SKKTR(dac_periph) & ~(uint32_t)DAC_SKKTR_TKEEP0); + DAC_SKKTR(dac_periph) = tmp | (keep_time & DAC_SKKTR_TKEEP0); + + tmp = (DAC_SKRTR(dac_periph) & ~(uint32_t)DAC_SKRTR_TREF0); + DAC_SKRTR(dac_periph) = tmp | (refresh_time & DAC_SKRTR_TREF0); + }else if(DAC_OUT1 == dac_out){ + /* configure DACx_OUT1 Sample & Keep mode */ + DAC_SKSTR1(dac_periph) |= (sample_time & DAC_SKSTR1_TSAMP1); + + tmp = (DAC_SKKTR(dac_periph) & ~(uint32_t)DAC_SKKTR_TKEEP1); + DAC_SKKTR(dac_periph) = tmp | ((keep_time << 16) & DAC_SKKTR_TKEEP1); + + tmp = (DAC_SKRTR(dac_periph) & ~(uint32_t)DAC_SKRTR_TREF1); + DAC_SKRTR(dac_periph) = tmp | ((refresh_time << 16) & DAC_SKRTR_TREF1); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief get DAC flag + \param[in] dac_periph: DACx(x=0) + \param[in] flag: the DAC status flags, only one parameter can be selected which is shown + as below: + \arg DAC_FLAG_DDUDR0: DACx_OUT0 DMA underrun flag + \arg DAC_FLAG_CALF0: DACx_OUT0 calibration offset flag + \arg DAC_FLAG_BWT0: DACx_OUT0 sample and keep wtire enable flag + \arg DAC_FLAG_DDUDR1: DACx_OUT1 DMA underrun flag + \arg DAC_FLAG_CALF1: DACx_OUT1 calibration offset flag + \arg DAC_FLAG_BWT1: DACx_OUT1 sample and keep wtire enable flag + \param[out] none + \retval the state of DAC bit(SET or RESET) +*/ +FlagStatus dac_flag_get(uint32_t dac_periph, uint32_t flag) +{ + if(flag & DAC_STAT_FLAG_MASK0){ + /* check DAC_STAT0 flag */ + if(RESET != (DAC_STAT0(dac_periph) & flag)){ + return SET; + }else{ + return RESET; + } + }else{ + /* illegal parameters */ + return RESET; + } +} + +/*! + \brief clear DAC flag + \param[in] dac_periph: DACx(x=0) + \param[in] flag: DAC flag + only one parameter can be selected which is shown as below: + \arg DAC_FLAG_DDUDR0: DACx_OUT0 DMA underrun flag + \arg DAC_FLAG_DDUDR1: DACx_OUT1 DMA underrun flag + \param[out] none + \retval none +*/ +void dac_flag_clear(uint32_t dac_periph, uint32_t flag) +{ + if(flag & DAC_STAT_FLAG_MASK0){ + /* check DAC_STAT0 flag */ + DAC_STAT0(dac_periph) = (uint32_t)(flag & DAC_STAT_FLAG_MASK0); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable DAC interrupt + \param[in] dac_periph: DACx(x=0) + \param[in] interrupt: the DAC interrupt + only one parameter can be selected which is shown as below: + \arg DAC_INT_DDUDR0: DACx_OUT0 DMA underrun interrupt + \arg DAC_INT_DDUDR1: DACx_OUT1 DMA underrun interrupt + \param[out] none + \retval none +*/ +void dac_interrupt_enable(uint32_t dac_periph, uint32_t interrupt) +{ + if(interrupt & DAC_INT_EN_MASK0){ + /* enable underrun interrupt */ + DAC_CTL0(dac_periph) |= (uint32_t)(interrupt & DAC_INT_EN_MASK0); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable DAC interrupt + \param[in] dac_periph: DACx(x=0) + \param[in] interrupt: the DAC interrupt + only one parameter can be selected which is shown as below: + \arg DAC_INT_DDUDR0: DACx_OUT0 DMA underrun interrupt + \arg DAC_INT_DDUDR1: DACx_OUT1 DMA underrun interrupt + \param[out] none + \retval none +*/ +void dac_interrupt_disable(uint32_t dac_periph, uint32_t interrupt) +{ + if(interrupt & DAC_INT_EN_MASK0){ + /* disable underrun interrupt */ + DAC_CTL0(dac_periph) &= (uint32_t)(~(interrupt & DAC_INT_EN_MASK0)); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief get DAC interrupt flag + \param[in] dac_periph: DACx(x=0) + \param[in] int_flag: DAC interrupt flag + only one parameter can be selected which is shown as below: + \arg DAC_INT_FLAG_DDUDR0: DACx_OUT0 DMA underrun interrupt flag + \arg DAC_INT_FLAG_DDUDR1: DACx_OUT1 DMA underrun interrupt flag + \param[out] none + \retval the state of DAC interrupt flag(SET or RESET) +*/ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph, uint32_t int_flag) +{ + uint32_t reg1 = 0U, reg2 = 0U; + + if(int_flag & DAC_INT_FLAG_MASK0){ + /* check underrun interrupt int_flag */ + reg1 = DAC_STAT0(dac_periph) & int_flag; + reg2 = DAC_CTL0(dac_periph) & int_flag; + }else{ + /* illegal parameters */ + } + + /*get DAC interrupt flag status */ + if((RESET != reg1) && (RESET != reg2)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DAC interrupt flag + \param[in] dac_periph: DACx(x=0) + \param[in] int_flag: DAC interrupt flag + only one parameter can be selected which is shown as below: + \arg DAC_INT_FLAG_DDUDR0: DACx_OUT0 DMA underrun interrupt flag + \arg DAC_INT_FLAG_DDUDR1: DACx_OUT1 DMA underrun interrupt flag + \param[out] none + \retval none +*/ +void dac_interrupt_flag_clear(uint32_t dac_periph, uint32_t int_flag) +{ + /* clear underrun interrupt int_flag */ + if(int_flag & DAC_INT_FLAG_MASK0) + { + DAC_STAT0(dac_periph) = (uint32_t)int_flag; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dbg.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dbg.c new file mode 100644 index 0000000000..5a5c01a65f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dbg.c @@ -0,0 +1,168 @@ +/*! + \file gd32h7xx_dbg.c + \brief DBG driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_dbg.h" + +#define DBG_RESET_VAL ((uint32_t)0x00000000U) /*!< DBG reset value */ + +/*! + \brief deinitialize the DBG + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL0 = DBG_RESET_VAL; + DBG_CTL1 = DBG_RESET_VAL; + DBG_CTL2 = DBG_RESET_VAL; + DBG_CTL3 = DBG_RESET_VAL; + DBG_CTL4 = DBG_RESET_VAL; +} + +/*! + \brief read DBG_ID code register + \param[in] none + \param[out] none + \retval DBG_ID code +*/ +uint32_t dbg_id_get(void) +{ + return DBG_ID; +} + +/*! + \brief enable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + only one parameter can be selected which is shown as below: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_enable(uint32_t dbg_low_power) +{ + DBG_CTL0 |= dbg_low_power; +} + +/*! + \brief disable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + only one parameter can be selected which is shown as below: + \arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL0 &= ~dbg_low_power; +} + +/*! + \brief enable trace pin assignment + \param[in] none + \param[out] none + \retval none +*/ +void dbg_trace_pin_enable(void) +{ + DBG_CTL0 |= DBG_CTL0_TRACECLKEN; +} + +/*! + \brief disable trace pin assignment + \param[in] none + \param[out] none + \retval none +*/ +void dbg_trace_pin_disable(void) +{ + DBG_CTL0 &= ~DBG_CTL0_TRACECLKEN; +} + +/*! + \brief trace pin mode selection + \param[in] trace_mode: + \arg TRACE_MODE_ASYNC: trace pin used for async mode + \arg TRACE_MODE_SYNC_DATASIZE_1: trace pin used for sync mode and data size is 1 + \arg TRACE_MODE_SYNC_DATASIZE_2: trace pin used for sync mode and data size is 2 + \arg TRACE_MODE_SYNC_DATASIZE_4: trace pin used for sync mode and data size is 4 + \param[out] none + \retval none +*/ +void dbg_trace_pin_mode_set(uint32_t trace_mode) +{ + DBG_CTL0 &= ~DBG_CTL0_TRACE_MODE; + DBG_CTL0 |= trace_mode; +} + + +/*! + \brief enable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which are shown as below: + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): hold TIMERx counter when core is halted + \arg DBG_I2Cx_HOLD (x=0,1,2,3): hold I2Cx smbus when core is halted + \arg DBG_CANx_HOLD (x=0,1,2): hold CANx when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which are shown as below: + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): hold TIMERx counter when core is halted + \arg DBG_I2Cx_HOLD (x=0,1,2,3): hold I2Cx smbus when core is halted + \arg DBG_CANx_HOLD (x=0,1,2): hold CANx when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph)); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dci.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dci.c new file mode 100644 index 0000000000..b2055d3cdb --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dci.c @@ -0,0 +1,448 @@ +/*! + \file gd32h7xx_dci.c + \brief DCI driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + + +#include "gd32h7xx_dci.h" + +/*! + \brief DCI deinit + \param[in] none + \param[out] none + \retval none +*/ +void dci_deinit(void) +{ + rcu_periph_reset_enable(RCU_DCIRST); + rcu_periph_reset_disable(RCU_DCIRST); +} + +/*! + \brief initialize DCI registers + \param[in] dci_struct: DCI parameter initialization structure + members of the structure and the member values are shown as below: + capture_mode : DCI_CAPTURE_MODE_CONTINUOUS, DCI_CAPTURE_MODE_SNAPSHOT + colck_polarity : DCI_CK_POLARITY_FALLING, DCI_CK_POLARITY_RISING + hsync_polarity : DCI_HSYNC_POLARITY_LOW, DCI_HSYNC_POLARITY_HIGH + vsync_polarity : DCI_VSYNC_POLARITY_LOW, DCI_VSYNC_POLARITY_HIGH + frame_rate : DCI_FRAME_RATE_ALL, DCI_FRAME_RATE_1_2, DCI_FRAME_RATE_1_4 + interface_format: DCI_INTERFACE_FORMAT_8BITS, DCI_INTERFACE_FORMAT_10BITS, + DCI_INTERFACE_FORMAT_12BITS, DCI_INTERFACE_FORMAT_14BITS + \param[out] none + \retval none +*/ +void dci_init(dci_parameter_struct *dci_struct) +{ + uint32_t reg = 0U; + /* disable capture function and DCI */ + DCI_CTL &= ~(DCI_CTL_CAP | DCI_CTL_DCIEN); + /* configure DCI parameter */ + reg |= dci_struct->capture_mode; + reg |= dci_struct->clock_polarity; + reg |= dci_struct->hsync_polarity; + reg |= dci_struct->vsync_polarity; + reg |= dci_struct->frame_rate; + reg |= dci_struct->interface_format; + + DCI_CTL = reg; +} + +/*! + \brief enable DCI function + \param[in] none + \param[out] none + \retval none +*/ +void dci_enable(void) +{ + DCI_CTL |= DCI_CTL_DCIEN; +} + +/*! + \brief disable DCI function + \param[in] none + \param[out] none + \retval none +*/ +void dci_disable(void) +{ + DCI_CTL &= ~DCI_CTL_DCIEN; +} + +/*! + \brief enable DCI capture + \param[in] none + \param[out] none + \retval none +*/ +void dci_capture_enable(void) +{ + DCI_CTL |= DCI_CTL_CAP; +} + +/*! + \brief disable DCI capture + \param[in] none + \param[out] none + \retval none +*/ +void dci_capture_disable(void) +{ + DCI_CTL &= ~DCI_CTL_CAP; +} + +/*! + \brief enable DCI external vsync function in CCIR progressive mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_external_vsync_enable(void) +{ + DCI_CTL |= DCI_CTL_EVSEN; +} + +/*! + \brief disable DCI external vsync function in CCIR progressive mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_external_vsync_disable(void) +{ + DCI_CTL &= ~DCI_CTL_EVSEN; +} + +/*! + \brief enable DCI automatic error correction function in CCIR interlaced mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_automatic_error_correction_enable(void) +{ + DCI_CTL |= DCI_CTL_AECEN; +} + +/*! + \brief disable DCI automatic error correction function in CCIR interlaced mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_automatic_error_correction_disable(void) +{ + DCI_CTL &= ~DCI_CTL_AECEN; +} + +/*! + \brief enable DCI jpeg mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_jpeg_enable(void) +{ + DCI_CTL |= DCI_CTL_JM; +} + +/*! + \brief disable DCI jpeg mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_jpeg_disable(void) +{ + DCI_CTL &= ~DCI_CTL_JM; +} + +/*! + \brief enable cropping window function + \param[in] none + \param[out] none + \retval none +*/ +void dci_crop_window_enable(void) +{ + DCI_CTL |= DCI_CTL_WDEN; +} + +/*! + \brief disable cropping window function + \param[in] none + \param[out] none + \retval none +*/ +void dci_crop_window_disable(void) +{ + DCI_CTL &= ~DCI_CTL_WDEN; +} + +/*! + \brief configure DCI cropping window + \param[in] start_x: window horizontal start position + \param[in] start_y: window vertical start position + \param[in] size_width: window horizontal size + \param[in] size_height: window vertical size + \param[out] none + \retval none +*/ +void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height) +{ + DCI_CWSPOS = ((uint32_t)start_x | ((uint32_t)start_y << 16U)); + DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height << 16U)); +} + +/*! + \brief enable embedded synchronous mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_embedded_sync_enable(void) +{ + DCI_CTL |= DCI_CTL_ESM; +} + +/*! + \brief disble embedded synchronous mode + \param[in] none + \param[out] none + \retval none +*/ +void dci_embedded_sync_disable(void) +{ + DCI_CTL &= ~DCI_CTL_ESM; +} + +/*! + \brief CCIR mode enable + \param[in] none + \param[out] none + \retval none +*/ +void dci_ccir_enable(void) +{ + DCI_CTL |= DCI_CTL_CCEN; +} + +/*! + \brief CCIR mode disable + \param[in] none + \param[out] none + \retval none +*/ +void dci_ccir_disable(void) +{ + DCI_CTL &= ~DCI_CTL_CCEN; +} + +/*! + \brief CCIR mode select + \param[in] ccir_mode: specify which mode to select + only one parameter can be selected which is shown as below: + \arg CCIR_PROGRESSIVE_MODE: CCIR progressive mode + \arg CCIR_INTERLACE_MODE: CCIR interlace mode + \param[out] none + \retval none +*/ +void dci_ccir_mode_select(uint32_t ccir_mode) +{ + if(CCIR_INTERLACE_MODE == ccir_mode) { + DCI_CTL |= DCI_CTL_CCMOD; + } else { + DCI_CTL &= ~DCI_CTL_CCMOD; + } +} + +/*! + \brief config synchronous codes in embedded synchronous mode + \param[in] frame_start: frame start code in embedded synchronous mode + \param[in] line_start: line start code in embedded synchronous mode + \param[in] line_end: line end code in embedded synchronous mode + \param[in] frame_end: frame end code in embedded synchronous mode + \param[out] none + \retval none +*/ +void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end) +{ + DCI_SC = ((uint32_t)frame_start | ((uint32_t)line_start << 8U) | \ + ((uint32_t)line_end << 16U) | ((uint32_t)frame_end << 24U)); +} + +/*! + \brief config synchronous codes unmask in embedded synchronous mode + \param[in] frame_start: frame start code unmask bits in embedded synchronous mode + \param[in] line_start: line start code unmask bits in embedded synchronous mode + \param[in] line_end: line end code unmask bits in embedded synchronous mode + \param[in] frame_end: frame end code unmask bits in embedded synchronous mode + \param[out] none + \retval none +*/ +void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end) +{ + DCI_SCUMSK = ((uint32_t)frame_start | ((uint32_t)line_start << 8U) | \ + ((uint32_t)line_end << 16U) | ((uint32_t)frame_end << 24U)); +} + +/*! + \brief read DCI data register + \param[in] none + \param[out] none + \retval data +*/ +uint32_t dci_data_read(void) +{ + return DCI_DATA; +} + +/*! + \brief get specified flag + \param[in] flag: specify which flag to get + only one parameter can be selected which is shown as below: + \arg DCI_FLAG_HS: HS line status + \arg DCI_FLAG_VS: VS line status + \arg DCI_FLAG_FV: FIFO valid + \arg DCI_FLAG_EF: end of frame flag + \arg DCI_FLAG_OVR: FIFO overrun flag + \arg DCI_FLAG_ESE: embedded synchronous error flag + \arg DCI_FLAG_VSYNC: vsync flag + \arg DCI_FLAG_EL: end of line flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dci_flag_get(uint32_t flag) +{ + uint32_t stat = 0U; + + if(flag >> 31U) { + /* get flag status from DCI_STAT1 register */ + stat = DCI_STAT1; + } else { + /* get flag status from DCI_STAT0 register */ + stat = DCI_STAT0; + } + + if(flag & stat) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief enable specified DCI interrupt + \param[in] interrupt: specify which interrupt to enable + one or more parameter can be selected which is shown as below: + \arg DCI_INT_EF: end of frame interrupt + \arg DCI_INT_OVR: FIFO overrun interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_VSYNC: vsync interrupt + \arg DCI_INT_EL: end of line interrupt + \arg DCI_INT_F0: CCIR field 0 interrupt + \arg DCI_INT_F1: CCIR field 1 interrupt + \arg DCI_INT_COF: CCIR change of field interrupt + \arg DCI_INT_CCE: CCIR error interrupt + \param[out] none + \retval none +*/ +void dci_interrupt_enable(uint32_t interrupt) +{ + DCI_INTEN |= interrupt; +} + +/*! + \brief disable specified DCI interrupt + \param[in] interrupt: specify which interrupt to disable + one or more parameter can be selected which is shown as below: + \arg DCI_INT_EF: end of frame interrupt + \arg DCI_INT_OVR: FIFO overrun interrupt + \arg DCI_INT_ESE: embedded synchronous error interrupt + \arg DCI_INT_VSYNC: vsync interrupt + \arg DCI_INT_EL: end of line interrupt + \arg DCI_INT_F0: CCIR field 0 interrupt + \arg DCI_INT_F1: CCIR field 1 interrupt + \arg DCI_INT_COF: CCIR change of field interrupt + \arg DCI_INT_CCE: CCIR error interrupt + \param[out] none + \retval none +*/ +void dci_interrupt_disable(uint32_t interrupt) +{ + DCI_INTEN &= ~interrupt; +} + +/*! + \brief get specified interrupt flag + \param[in] int_flag: specify which flag to get + one or more parameter can be selected which is shown as below: + \arg DCI_INT_FLAG_EF: end of frame interrupt flag + \arg DCI_INT_FLAG_OVR: FIFO overrun interrupt flag + \arg DCI_INT_FLAG_ESE: embedded synchronous error interrupt flag + \arg DCI_INT_FLAG_VSYNC: vsync interrupt flag + \arg DCI_INT_FLAG_EL: end of line interrupt flag + \arg DCI_INT_FLAG_F0: CCIR field 0 interrupt flag + \arg DCI_INT_FLAG_F1: CCIR field 1 interrupt flag + \arg DCI_INT_FLAG_COF: CCIR change of field interrupt flag + \arg DCI_INT_FLAG_CCE: CCIR error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dci_interrupt_flag_get(uint32_t int_flag) +{ + if(RESET == (DCI_INTF & int_flag)) { + return RESET; + } else { + return SET; + } +} + +/*! + \brief clear specified interrupt flag + \param[in] int_flag: specify which flag to clear + one or more parameter can be selected which is shown as below: + \arg DCI_INT_FLAG_EF: end of frame interrupt flag + \arg DCI_INT_FLAG_OVR: FIFO overrun interrupt flag + \arg DCI_INT_FLAG_ESE: embedded synchronous error interrupt flag + \arg DCI_INT_FLAG_VSYNC: vsync interrupt flag + \arg DCI_INT_FLAG_EL: end of line interrupt flag + \arg DCI_INT_FLAG_COF: CCIR change of field interrupt flag + \arg DCI_INT_FLAG_CCE: CCIR error interrupt flag + \param[out] none + \retval none +*/ +void dci_interrupt_flag_clear(uint32_t int_flag) +{ + DCI_INTC |= int_flag; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dma.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dma.c new file mode 100644 index 0000000000..bb5567ed47 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_dma.c @@ -0,0 +1,1710 @@ +/*! + \file gd32h7xx_dma.c + \brief DMA driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_dma.h" +#include + +#define DMA_WRONG_HANDLE while(1){} + +/* DMA register bit offset */ +#define CHXFCTL_FCNT_OFFSET ((uint32_t)0x00000003U) /*!< bit offset of FCNT in DMA_CHxFCTL */ + +/* DMAMUX register bit offset */ +#define RM_CHXCFG_NBR_OFFSET ((uint32_t)0x00000013U) /*!< bit offset of NBR in DMAMUX_RM_CHXCFG */ +#define RG_CHXCFG_NBRG_OFFSET ((uint32_t)0x00000013U) /*!< bit offset of NBRG in DMAMUX_RG_CHXCFG */ + +/*! + \brief deinitialize DMA registers of a channel + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is deinitialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(dma_periph, channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHM0ADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_CHM1ADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_CHFCTL(dma_periph, channelx) = DMA_CHFCTL_RESET_VALUE; + if(channelx < DMA_CH4) { + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); + } else { + channelx -= (dma_channel_enum)4; + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); + } +} + +/*! + \brief initialize the DMA single data mode parameters structure with the default values + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMA channel + \retval none +*/ +void dma_single_data_para_struct_init(dma_single_data_parameter_struct *init_struct) +{ + /* set the DMA struct with the default values */ + init_struct->request = DMA_REQUEST_M2M; + init_struct->periph_addr = 0U; + init_struct->periph_inc = DMA_PERIPH_INCREASE_DISABLE; + init_struct->memory0_addr = 0U; + init_struct->memory_inc = DMA_MEMORY_INCREASE_DISABLE; + init_struct->periph_memory_width = 0U; + init_struct->circular_mode = DMA_CIRCULAR_MODE_DISABLE; + init_struct->direction = DMA_PERIPH_TO_MEMORY; + init_struct->number = 0U; + init_struct->priority = DMA_PRIORITY_LOW; +} + +/*! + \brief initialize the DMA multi data mode parameters structure with the default values + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMA channel + \retval none +*/ +void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct *init_struct) +{ + /* set the DMA structure with the default values */ + init_struct->request = DMA_REQUEST_M2M; + init_struct->periph_addr = 0U; + init_struct->periph_width = 0U; + init_struct->periph_inc = DMA_PERIPH_INCREASE_DISABLE; + init_struct->memory0_addr = 0U; + init_struct->memory_width = 0U; + init_struct->memory_inc = DMA_MEMORY_INCREASE_DISABLE; + init_struct->memory_burst_width = 0U; + init_struct->periph_burst_width = 0U; + init_struct->circular_mode = DMA_CIRCULAR_MODE_DISABLE; + init_struct->direction = DMA_PERIPH_TO_MEMORY; + init_struct->number = 0U; + init_struct->priority = DMA_PRIORITY_LOW; +} + +/*! + \brief initialize DMA single data mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] init_struct: the data needed to initialize DMA single data mode + request: DMA_REQUEST_x x is the type of request + periph_addr: peripheral base address + periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX + memory0_addr: memory base address + memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE + periph_memory_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT + circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE + direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY + number: the number of remaining data to be transferred by the DMA + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + \param[out] none + \retval none +*/ +void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_single_data_parameter_struct *init_struct) +{ + uint32_t ctl; + + /* select single data mode */ + DMA_CHFCTL(dma_periph, channelx) &= ~DMA_CHXFCTL_MDMEN; + + /* configure peripheral base address */ + DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr; + + /* configure memory base address */ + DMA_CHM0ADDR(dma_periph, channelx) = init_struct->memory0_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(dma_periph, channelx) = init_struct->number; + + /* configure peripheral and memory transfer width,channel priotity,transfer mode */ + ctl = DMA_CHCTL(dma_periph, channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM); + ctl |= (init_struct->periph_memory_width | (init_struct->periph_memory_width << 2U) | init_struct->priority | init_struct->direction); + DMA_CHCTL(dma_periph, channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + } else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure DMA circular mode */ + if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; + } + if(DMA0 == dma_periph) { + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG(channelx) |= init_struct->request; + } else { + DMAMUX_RM_CHXCFG((uint32_t)channelx + 8U) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG((uint32_t)channelx + 8U) |= init_struct->request; + } +} + +/*! + \brief initialize DMA multi data mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] dma_multi_data_parameter_struct: the data needed to initialize DMA multi data mode + request: DMA_REQUEST_x x is the type of request + periph_addr: peripheral base address + periph_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT + periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX + memory0_addr: memory0 base address + memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT + memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE + memory_burst_width: DMA_MEMORY_BURST_SINGLE,DMA_MEMORY_BURST_4_BEAT,DMA_MEMORY_BURST_8_BEAT,DMA_MEMORY_BURST_16_BEAT + periph_burst_width: DMA_PERIPH_BURST_SINGLE,DMA_PERIPH_BURST_4_BEAT,DMA_PERIPH_BURST_8_BEAT,DMA_PERIPH_BURST_16_BEAT + critical_value: DMA_FIFO_1_WORD,DMA_FIFO_2_WORD,DMA_FIFO_3_WORD,DMA_FIFO_4_WORD + circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE + direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY + number: the number of remaining data to be transferred by the DMA + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + \param[out] none + \retval none +*/ +void dma_multi_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_multi_data_parameter_struct *init_struct) +{ + uint32_t ctl; + + /* select multi data mode and configure FIFO critical value */ + DMA_CHFCTL(dma_periph, channelx) |= (DMA_CHXFCTL_MDMEN | init_struct->critical_value); + + /* configure peripheral base address */ + DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr; + + /* configure memory base address */ + DMA_CHM0ADDR(dma_periph, channelx) = init_struct->memory0_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(dma_periph, channelx) = init_struct->number; + + /* configure peripheral and memory transfer width,channel priotity,transfer mode,peripheral and memory burst transfer width */ + ctl = DMA_CHCTL(dma_periph, channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM | DMA_CHXCTL_PBURST | DMA_CHXCTL_MBURST); + ctl |= (init_struct->periph_width | (init_struct->memory_width) | init_struct->priority | init_struct->direction | init_struct->memory_burst_width | + init_struct->periph_burst_width); + DMA_CHCTL(dma_periph, channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + } else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure DMA circular mode */ + if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; + } + + if(DMA0 == dma_periph) { + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG(channelx) |= init_struct->request; + } else { + DMAMUX_RM_CHXCFG((uint32_t)channelx + 8U) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG((uint32_t)channelx + 8U) |= init_struct->request; + } +} + +/*! + \brief configure DMA peripheral base address + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set peripheral base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] address: peripheral base address, ranges from 0x00000000 to 0xFFFFFFFF + \param[out] none + \retval none +*/ +void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address) +{ + DMA_CHPADDR(dma_periph, channelx) = address; +} + +/*! + \brief configure DMA memory base address + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set memory base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] memory_flag: the selected memory + \arg DMA_MEMORY_0: DMA memory 0 + \arg DMA_MEMORY_1: DMA memory 1 + \param[in] address: memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t memory_flag, uint32_t address) +{ + if(memory_flag) { + DMA_CHM1ADDR(dma_periph, channelx) = address; + } else { + DMA_CHM0ADDR(dma_periph, channelx) = address; + } +} + +/*! + \brief configure the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] number: the number of remaining data to be transferred by the DMA, ranges from 0x00000000 to 0x0000FFFF + \param[out] none + \retval none +*/ +void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number) +{ + DMA_CHCNT(dma_periph, channelx) = number; +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval uint32_t: the number of remaining data to be transferred by the DMA, ranges from 0x00000000 to 0x0000FFFF +*/ +uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx) +{ + return (uint32_t)DMA_CHCNT(dma_periph, channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] priority: priority level of this channel + only one parameter can be selected which is shown as below: + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer burst beats of memory + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] mbeat: memory transfer burst beats + \arg DMA_MEMORY_BURST_SINGLE: memory transfer single burst + \arg DMA_MEMORY_BURST_4_BEAT: memory transfer 4-beat burst + \arg DMA_MEMORY_BURST_8_BEAT: memory transfer 8-beat burst + \arg DMA_MEMORY_BURST_16_BEAT: memory transfer 16-beat burst + \param[out] none + \retval none +*/ +void dma_memory_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mbeat) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MBURST; + ctl |= mbeat; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer burst beats of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] pbeat: peripheral transfer burst beats + only one parameter can be selected which is shown as below: + \arg DMA_PERIPH_BURST_SINGLE: peripheral transfer single burst + \arg DMA_PERIPH_BURST_4_BEAT: peripheral transfer 4-beat burst + \arg DMA_PERIPH_BURST_8_BEAT: peripheral transfer 8-beat burst + \arg DMA_PERIPH_BURST_16_BEAT: peripheral transfer 16-beat burst + \param[out] none + \retval none +*/ +void dma_periph_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pbeat) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PBURST; + ctl |= pbeat; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer data size of memory + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] msize: transfer data size of memory + only one parameter can be selected which is shown as below: + \arg DMA_MEMORY_WIDTH_8BIT: transfer data size of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data size of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data size of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t msize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= msize; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer data size of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] psize: transfer data size of peripheral + only one parameter can be selected which is shown as below: + \arg DMA_PERIPH_WIDTH_8BIT: transfer data size of peripheral is 8-bit + \arg DMA_PERIPH_WIDTH_16BIT: transfer data size of peripheral is 16-bit + \arg DMA_PERIPH_WIDTH_32BIT: transfer data size of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t psize) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= psize; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure memory address generation algorithm + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] generation_algorithm: the address generation algorithm + only one parameter can be selected which is shown as below: + \arg DMA_MEMORY_INCREASE_ENABLE: next address of memory is increasing address mode + \arg DMA_MEMORY_INCREASE_DISABLE: next address of memory is fixed address mode + \param[out] none + \retval none +*/ +void dma_memory_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm) +{ + if(DMA_MEMORY_INCREASE_ENABLE == generation_algorithm) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; + } +} + +/*! + \brief configure peripheral address generation algorithm + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] generation_algorithm: the address generation algorithm + only one parameter can be selected which is shown as below: + \arg DMA_PERIPH_INCREASE_ENABLE: next address of peripheral is increasing address mode + \arg DMA_PERIPH_INCREASE_DISABLE: next address of peripheral is fixed address mode + \arg DMA_PERIPH_INCREASE_FIX: increasing steps of peripheral address is fixed + \param[out] none + \retval none +*/ +void dma_peripheral_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm) +{ + if(DMA_PERIPH_INCREASE_ENABLE == generation_algorithm) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + } else if(DMA_PERIPH_INCREASE_DISABLE == generation_algorithm) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] direction: specify the direction of data transfer + only one parameter can be selected which is shown as below: + \arg DMA_PERIPH_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPH: read from memory and write to peripheral + \arg DMA_MEMORY_TO_MEMORY: read from memory and write to memory + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t direction) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_TM; + ctl |= direction; + + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure DMA switch buffer mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] memory1_addr: memory1 base address, ranges from 0x00000000 to 0xFFFFFFFF + \param[in] memory_select: the selected memory + \arg DMA_MEMORY_0: DMA memory 0 + \arg DMA_MEMORY_1: DMA memory 1 + \param[out] none + \retval none +*/ +void dma_switch_buffer_mode_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t memory1_addr, uint32_t memory_select) +{ + /* configure memory1 base address */ + DMA_CHM1ADDR(dma_periph, channelx) = memory1_addr; + + if(DMA_MEMORY_0 == memory_select) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MBS; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MBS; + } +} + +/*! + \brief get DMA using memory + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval the using memory, DMA_MEMORY_0 or DMA_MEMORY_1 +*/ +uint32_t dma_using_memory_get(uint32_t dma_periph, dma_channel_enum channelx) +{ + if((DMA_CHCTL(dma_periph, channelx)) & DMA_CHXCTL_MBS) { + return DMA_MEMORY_1; + } else { + return DMA_MEMORY_0; + } +} + +/*! + \brief enable DMA switch buffer mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_switch_buffer_mode_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + /* enable switch buffer mode */ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_SBMEN; +} + +/*! + \brief disable DMA switch buffer mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval none +*/ +void dma_switch_buffer_mode_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + /* disable switch buffer mode */ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_SBMEN; +} + +/*! + \brief get DMA FIFO status + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[out] none + \retval the number of words stored in FIFO + \arg DMA_FIFO_CNT_NO_DATA: no data + \arg DMA_FIFO_CNT_1_WORD: 1 word + \arg DMA_FIFO_CNT_2_WORD: 2 words + \arg DMA_FIFO_CNT_3_WORD: 3 words + \arg DMA_FIFO_CNT_EMPTY: empty + \arg DMA_FIFO_CNT_FULL: full +*/ +uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx) +{ + return ((DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FCNT)>>CHXFCTL_FCNT_OFFSET); +} + +/*! + \brief get DMA flag + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_FEE: FIFO error and exception flag + \arg DMA_FLAG_SDE: single data mode exception flag + \arg DMA_FLAG_TAE: transfer access error flag + \arg DMA_FLAG_HTF: half transfer finish flag + \arg DMA_FLAG_FTF: full transger finish flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + if(channelx < DMA_CH4) { + if(DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag, channelx)) { + return SET; + } else { + return RESET; + } + } else { + channelx -= (dma_channel_enum)4; + if(DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channelx)) { + return SET; + } else { + return RESET; + } + } +} + +/*! + \brief clear DMA flag + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_FEE: FIFO error and exception flag + \arg DMA_FLAG_SDE: single data mode exception flag + \arg DMA_FLAG_TAE: transfer access error flag + \arg DMA_FLAG_HTF: half transfer finish flag + \arg DMA_FLAG_FTF: full transger finish flag + \param[out] none + \retval none +*/ +void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + if(channelx < DMA_CH4) { + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(flag, channelx); + } else { + channelx -= (dma_channel_enum)4; + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(flag, channelx); + } +} + +/*! + \brief enable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] interrupt: specify which interrupt to enbale + one or more parameters can be selected which are shown as below: + \arg DMA_INT_SDE: single data mode exception interrupt + \arg DMA_INT_TAE: tranfer access error interrupt + \arg DMA_INT_HTF: half transfer finish interrupt + \arg DMA_INT_FTF: full transfer finish interrupt + \arg DMA_INT_FEE: FIFO exception interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt) +{ + if(DMA_CHXFCTL_FEEIE != (DMA_CHXFCTL_FEEIE & interrupt)) { + DMA_CHCTL(dma_periph, channelx) |= interrupt; + } else { + DMA_CHFCTL(dma_periph, channelx) |= DMA_CHXFCTL_FEEIE; + DMA_CHCTL(dma_periph, channelx) |= (interrupt & (~DMA_CHXFCTL_FEEIE)); + } +} + +/*! + \brief disable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] interrupt: specify which interrupt to disbale + one or more parameters can be selected which are shown as below: + \arg DMA_INT_SDE: single data mode exception interrupt + \arg DMA_INT_TAE: tranfer access error interrupt + \arg DMA_INT_HTF: half transfer finish interrupt + \arg DMA_INT_FTF: full transfer finish interrupt + \arg DMA_INT_FEE: FIFO exception interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt) +{ + if(DMA_CHXFCTL_FEEIE != (DMA_CHXFCTL_FEEIE & interrupt)) { + DMA_CHCTL(dma_periph, channelx) &= ~interrupt; + } else { + DMA_CHFCTL(dma_periph, channelx) &= ~DMA_CHXFCTL_FEEIE; + DMA_CHCTL(dma_periph, channelx) &= ~(interrupt & (~DMA_CHXFCTL_FEEIE)); + } +} + +/*! + \brief get DMA interrupt flag + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get interrupt flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] int_flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_FEE: FIFO error and exception flag + \arg DMA_INT_FLAG_SDE: single data mode exception flag + \arg DMA_INT_FLAG_TAE: transfer access error flag + \arg DMA_INT_FLAG_HTF: half transfer finish flag + \arg DMA_INT_FLAG_FTF: full transger finish flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + dma_channel_enum channel_flag_offset = channelx; + /* flags for channel0-3 */ + if(channelx < DMA_CH4) { + switch(int_flag) { + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE; + break; + case DMA_INTF_SDEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE; + break; + case DMA_INTF_TAEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE; + break; + case DMA_INTF_HTFIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INTF_FTFIF: + interrupt_flag = (DMA_INTF0(dma_periph) & DMA_FLAG_ADD(int_flag, channelx)); + interrupt_enable = (DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE); + break; + default: + break; + } + /* flags for channel4-7 */ + } else { + channel_flag_offset -= (dma_channel_enum)4U; + switch(int_flag) { + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(int_flag, channel_flag_offset); + interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE; + break; + case DMA_INTF_SDEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(int_flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE; + break; + case DMA_INTF_TAEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(int_flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE; + break; + case DMA_INTF_HTFIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(int_flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INTF_FTFIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(int_flag, channel_flag_offset); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE; + break; + default: + break; + } + } + + if(interrupt_flag && interrupt_enable) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear DMA interrupt flag + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear interrupt flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..7) + \param[in] int_flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_FEE: FIFO error and exception flag + \arg DMA_INT_FLAG_SDE: single data mode exception flag + \arg DMA_INT_FLAG_TAE: transfer access error flag + \arg DMA_INT_FLAG_HTF: half transfer finish flag + \arg DMA_INT_FLAG_FTF: full transger finish flag + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag) +{ + if(channelx < DMA_CH4) { + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(int_flag, channelx); + } else { + channelx -= (dma_channel_enum)4U; + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(int_flag, channelx); + } +} + +/*! + \brief initialize the parameters of DMAMUX synchronization mode structure with the default values + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMAMUX request multiplexer channel synchronization mode + \retval none +*/ +void dmamux_sync_struct_para_init(dmamux_sync_parameter_struct *init_struct) +{ + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* set the DMAMUX synchronization structure with the default values */ + init_struct->sync_id = DMAMUX_SYNC_EVT0_OUT; + init_struct->sync_polarity = DMAMUX_SYNC_RISING; + init_struct->request_number = 1U; +} + +/*! + \brief initialize DMAMUX request multiplexer channel synchronization mode + \param[in] channelx: specify which DMAMUX request multiplexer channel is initialized + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[in] init_struct: the data needed to initialize DMAMUX request multiplexer channel + sync_id: DMAMUX_SYNC_EXTI0, DMAMUX_SYNC_EXTI1, DMAMUX_SYNC_EXTI2, DMAMUX_SYNC_EXTI3, + DMAMUX_SYNC_EXTI4, DMAMUX_SYNC_EXTI5, DMAMUX_SYNC_EXTI6, DMAMUX_SYNC_EXTI7, + DMAMUX_SYNC_EXTI8, DMAMUX_SYNC_EXTI9, DMAMUX_SYNC_EXTI10, DMAMUX_SYNC_EXTI11, + DMAMUX_SYNC_EXTI12, DMAMUX_SYNC_EXTI13, DMAMUX_SYNC_EXTI14, DMAMUX_SYNC_EXTI15, + DMAMUX_SYNC_EVT0_OUT, DMAMUX_SYNC_EVT1_OUT, DMAMUX_SYNC_EVT2_OUT, DMAMUX_SYNC_EVT3_OUT, + DMAMUX_SYNC_EVT4_OUT, DMAMUX_SYNC_EVT5_OUT, DMAMUX_SYNC_EVT6_OUT, DMAMUX_SYNC_RTC_WAKEUP, + DMAMUX_SYNC_CMP0_OUTPUT, DMAMUX_SYNC_I2C0_WAKEUP, DMAMUX_SYNC_I2C1_WAKEUP, DMAMUX_SYNC_I2C2_WAKEUP, + DMAMUX_SYNC_I2C3_WAKEUP + sync_polarity: DMAMUX_SYNC_NO_EVENT, DMAMUX_SYNC_RISING, DMAMUX_SYNC_FALLING, DMAMUX_SYNC_RISING_FALLING + request_number: the number of DMA request that will be authorized after a sync event, from 1 to 32 + \param[out] none + \retval none +*/ +void dmamux_synchronization_init(dmamux_multiplexer_channel_enum channelx, dmamux_sync_parameter_struct *init_struct) +{ + uint32_t cfg; + + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* disable synchronization mode and event generation for DMA request forward number configuration */ + DMAMUX_RM_CHXCFG(channelx) &= ~(DMAMUX_RM_CHXCFG_SYNCEN | DMAMUX_RM_CHXCFG_EVGEN); + + /* configure synchronization input identification, synchronization input polarity, number of DMA requests to forward */ + cfg = DMAMUX_RM_CHXCFG(channelx); + cfg &= ~(DMAMUX_RM_CHXCFG_SYNCID | DMAMUX_RM_CHXCFG_NBR | DMAMUX_RM_CHXCFG_SYNCP); + cfg |= (init_struct->sync_polarity | (init_struct->sync_id) | RM_CHXCFG_NBR(init_struct->request_number - 1U)); + DMAMUX_RM_CHXCFG(channelx) = cfg; +} + +/*! + \brief enable synchronization mode + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[out] none + \retval none +*/ +void dmamux_synchronization_enable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) |= DMAMUX_RM_CHXCFG_SYNCEN; +} + +/*! + \brief disable synchronization mode + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[out] none + \retval none +*/ +void dmamux_synchronization_disable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) &= (~DMAMUX_RM_CHXCFG_SYNCEN); +} +/*! + \brief enable event generation + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[out] none + \retval none +*/ +void dmamux_event_generation_enable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) |= DMAMUX_RM_CHXCFG_EVGEN; +} + +/*! + \brief disable event generation + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[out] none + \retval none +*/ +void dmamux_event_generation_disable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) &= (~DMAMUX_RM_CHXCFG_EVGEN); +} + +/*! + \brief initialize the parameters of DMAMUX request generator structure with the default values + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMAMUX request generator channel + \retval none +*/ +void dmamux_gen_struct_para_init(dmamux_gen_parameter_struct *init_struct) +{ + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* set the DMAMUX request generator structure with the default values */ + init_struct->trigger_id = DMAMUX_SYNC_EVT0_OUT; + init_struct->trigger_polarity = DMAMUX_SYNC_RISING; + init_struct->request_number = 1U; +} + +/*! + \brief initialize DMAMUX request generator channel + \param[in] channelx: specify which DMAMUX request generator channel is initialized + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..7) + \param[in] init_struct: the data needed to initialize DMAMUX request generator channel + trigger_id: DMAMUX_TRIGGER_EXTI0, DMAMUX_TRIGGER_EXTI1, DMAMUX_TRIGGER_EXTI2, DMAMUX_TRIGGER_EXTI3, + DMAMUX_TRIGGER_EXTI4, DMAMUX_TRIGGER_EXTI5, DMAMUX_TRIGGER_EXTI6, DMAMUX_TRIGGER_EXTI7, + DMAMUX_TRIGGER_EXTI8, DMAMUX_TRIGGER_EXTI9, DMAMUX_TRIGGER_EXTI10, DMAMUX_TRIGGER_EXTI11, + DMAMUX_TRIGGER_EXTI12, DMAMUX_TRIGGER_EXTI13, DMAMUX_TRIGGER_EXTI14, DMAMUX_TRIGGER_EXTI15, + DMAMUX_TRIGGER_EVT0_OUT, DMAMUX_TRIGGER_EVT1_OUT, DMAMUX_TRIGGER_EVT2_OUT, DMAMUX_TRIGGER_EVT3_OUT, + DMAMUX_SYNC_EVT4_OUT, DMAMUX_SYNC_EVT5_OUT, DMAMUX_SYNC_EVT6_OUT, DMAMUX_SYNC_RTC_WAKEUP, + DMAMUX_SYNC_CMP0_OUTPUT, DMAMUX_SYNC_I2C0_WAKEUP, DMAMUX_SYNC_I2C1_WAKEUP, DMAMUX_SYNC_I2C2_WAKEUP, + DMAMUX_SYNC_I2C3_WAKEUP + trigger_polarity: DMAMUX_GEN_NO_EVENT, DMAMUX_GEN_RISING, DMAMUX_GEN_FALLING, DMAMUX_GEN_RISING_FALLING + request_number: the number of DMA request that will be generated after a signal event, from 1 to 32 + \param[out] none + \retval none +*/ +void dmamux_request_generator_init(dmamux_generator_channel_enum channelx, dmamux_gen_parameter_struct *init_struct) +{ + uint32_t cfg; + + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* disable DMAMUX request generator channel for DMA request generation number configuration */ + DMAMUX_RG_CHXCFG(channelx) &= ~(DMAMUX_RG_CHXCFG_RGEN); + + /* configure trigger input identification, trigger polarity, number of DMA requests to be generated */ + cfg = DMAMUX_RG_CHXCFG(channelx); + cfg &= ~(DMAMUX_RG_CHXCFG_TID | DMAMUX_RG_CHXCFG_NBRG | DMAMUX_RG_CHXCFG_RGTP); + cfg |= (RG_CHXCFG_NBRG(init_struct->request_number - 1U) | init_struct->trigger_id | init_struct->trigger_polarity); + DMAMUX_RG_CHXCFG(channelx) = cfg; +} + +/*! + \brief enable DMAMUX request generator channel + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..7) + \param[out] none + \retval none +*/ +void dmamux_request_generator_channel_enable(dmamux_generator_channel_enum channelx) +{ + DMAMUX_RG_CHXCFG(channelx) |= DMAMUX_RG_CHXCFG_RGEN; +} + +/*! + \brief disable DMAMUX request generator channel + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..7) + \param[out] none + \retval none +*/ +void dmamux_request_generator_channel_disable(dmamux_generator_channel_enum channelx) +{ + DMAMUX_RG_CHXCFG(channelx) &= (~DMAMUX_RG_CHXCFG_RGEN); +} + +/*! + \brief configure synchronization input polarity + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[in] polarity: synchronization input polarity + only one parameter can be selected which is shown as below: + \arg DMAMUX_SYNC_NO_EVENT: no event detection + \arg DMAMUX_SYNC_RISING: rising edge + \arg DMAMUX_SYNC_FALLING: falling edge + \arg DMAMUX_SYNC_RISING_FALLING: rising and falling edges + \param[out] none + \retval none +*/ +void dmamux_synchronization_polarity_config(dmamux_multiplexer_channel_enum channelx, uint32_t polarity) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_SYNCP; + DMAMUX_RM_CHXCFG(channelx) |= polarity; +} + +/*! + \brief configure number of DMA requests to forward + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[in] number: DMA requests number to forward + only one parameter can be selected which is shown as below: + \arg 1 - 32 + \param[out] none + \retval none +*/ +void dmamux_request_forward_number_config(dmamux_multiplexer_channel_enum channelx, uint32_t number) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_NBR; + DMAMUX_RM_CHXCFG(channelx) |= ((number - 1U) << RM_CHXCFG_NBR_OFFSET); +} + +/*! + \brief configure synchronization input identification + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[in] id: synchronization input identification + only one parameter can be selected which is shown as below: + \arg DMAMUX_SYNC_EXTI0: synchronization input is EXTI0 + \arg DMAMUX_SYNC_EXTI1: synchronization input is EXTI1 + \arg DMAMUX_SYNC_EXTI2: synchronization input is EXTI2 + \arg DMAMUX_SYNC_EXTI3: synchronization input is EXTI3 + \arg DMAMUX_SYNC_EXTI4: synchronization input is EXTI4 + \arg DMAMUX_SYNC_EXTI5: synchronization input is EXTI5 + \arg DMAMUX_SYNC_EXTI6: synchronization input is EXTI6 + \arg DMAMUX_SYNC_EXTI7: synchronization input is EXTI7 + \arg DMAMUX_SYNC_EXTI8: synchronization input is EXTI8 + \arg DMAMUX_SYNC_EXTI9: synchronization input is EXTI9 + \arg DMAMUX_SYNC_EXTI10: synchronization input is EXTI10 + \arg DMAMUX_SYNC_EXTI11: synchronization input is EXTI11 + \arg DMAMUX_SYNC_EXTI12: synchronization input is EXTI12 + \arg DMAMUX_SYNC_EXTI13: synchronization input is EXTI13 + \arg DMAMUX_SYNC_EXTI14: synchronization input is EXTI14 + \arg DMAMUX_SYNC_EXTI15: synchronization input is EXTI15 + \arg DMAMUX_SYNC_EVT0_OUT: synchronization input is Evt0_out + \arg DMAMUX_SYNC_EVT1_OUT: synchronization input is Evt1_out + \arg DMAMUX_SYNC_EVT2_OUT: synchronization input is Evt2_out + \arg DMAMUX_SYNC_EVT3_OUT: synchronization input is Evt3_out + \arg DMAMUX_SYNC_EVT4_OUT: synchronization input is Evt4_out + \arg DMAMUX_SYNC_EVT5_OUT: synchronization input is Evt5_out + \arg DMAMUX_SYNC_EVT6_OUT: synchronization input is Evt6_out + \arg DMAMUX_SYNC_RTC_WAKEUP: synchronization input is RTC wakeup + \arg DMAMUX_SYNC_CMP0_OUTPUT: synchronization input is CMP0 output + \arg DMAMUX_SYNC_I2C0_WAKEUP: synchronization input is I2C0 wakeup + \arg DMAMUX_SYNC_I2C1_WAKEUP: synchronization input is I2C1 wakeup + \arg DMAMUX_SYNC_I2C2_WAKEUP: synchronization input is I2C2 wakeup + \arg DMAMUX_SYNC_I2C3_WAKEUP: synchronization input is I2C3 wakeup + \param[out] none + \retval none +*/ +void dmamux_sync_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_SYNCID; + DMAMUX_RM_CHXCFG(channelx) |= id; +} + +/*! + \brief configure multiplexer input identification + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..15) + \param[in] id: input DMA request identification + only one parameter can be selected which is shown as below: + \arg DMA_REQUEST_M2M: memory to memory transfer + \arg DMA_REQUEST_GENERATOR0: DMAMUX request generator 0 + \arg DMA_REQUEST_GENERATOR1: DMAMUX request generator 1 + \arg DMA_REQUEST_GENERATOR2: DMAMUX request generator 2 + \arg DMA_REQUEST_GENERATOR3: DMAMUX request generator 3 + \arg DMA_REQUEST_GENERATOR4: DMAMUX request generator 4 + \arg DMA_REQUEST_GENERATOR5: DMAMUX request generator 5 + \arg DMA_REQUEST_GENERATOR6: DMAMUX request generator 6 + \arg DMA_REQUEST_GENERATOR7: DMAMUX request generator 7 + \arg DMA_REQUEST_ADC0: DMAMUX ADC0 request + \arg DMA_REQUEST_ADC1: DMAMUX ADC1 request + \arg DMA_REQUEST_TIMER0_CH0: DMAMUX TIMER0 CH0 request + \arg DMA_REQUEST_TIMER0_CH1: DMAMUX TIMER0 CH1 request + \arg DMA_REQUEST_TIMER0_CH2: DMAMUX TIMER0 CH2 request + \arg DMA_REQUEST_TIMER0_CH3: DMAMUX TIMER0 CH3 request + \arg DMA_REQUEST_TIMER0_MCH0: DMAMUX TIMER0 MCH0 request + \arg DMA_REQUEST_TIMER0_MCH1: DMAMUX TIMER0 MCH1 request + \arg DMA_REQUEST_TIMER0_MCH2: DMAMUX TIMER0 MCH2 request + \arg DMA_REQUEST_TIMER0_MCH3: DMAMUX TIMER0 MCH3 request + \arg DMA_REQUEST_TIMER0_UP: DMAMUX TIMER0 UP request + \arg DMA_REQUEST_TIMER0_TRG: DMAMUX TIMER0 TRG request + \arg DMA_REQUEST_TIMER0_CMT: DMAMUX TIMER0 CMT request + \arg DMA_REQUEST_TIMER1_CH0: DMAMUX TIMER1 CH0 request + \arg DMA_REQUEST_TIMER1_CH1: DMAMUX TIMER1 CH1 request + \arg DMA_REQUEST_TIMER1_CH2: DMAMUX TIMER1 CH2 request + \arg DMA_REQUEST_TIMER1_CH3: DMAMUX TIMER1 CH3 request + \arg DMA_REQUEST_TIMER1_UP: DMAMUX TIMER1 UP request + \arg DMA_REQUEST_TIMER1_TRG: DMAMUX TIMER1 TRG request + \arg DMA_REQUEST_TIMER2_CH0: DMAMUX TIMER2 CH0 request + \arg DMA_REQUEST_TIMER2_CH1: DMAMUX TIMER2 CH1 request + \arg DMA_REQUEST_TIMER2_CH2: DMAMUX TIMER2 CH2 request + \arg DMA_REQUEST_TIMER2_CH3: DMAMUX TIMER2 CH3 request + \arg DMA_REQUEST_TIMER2_UP: DMAMUX TIMER2 UP request + \arg DMA_REQUEST_TIMER2_TRG: DMAMUX TIMER2 TRG request + \arg DMA_REQUEST_TIMER3_CH0: DMAMUX TIMER3 CH0 request + \arg DMA_REQUEST_TIMER3_CH1: DMAMUX TIMER3 CH1 request + \arg DMA_REQUEST_TIMER3_CH2: DMAMUX TIMER3 CH2 request + \arg DMA_REQUEST_TIMER3_CH3: DMAMUX TIMER3 CH3 request + \arg DMA_REQUEST_TIMER3_TRG: DMAMUX TIMER3 TRG request + \arg DMA_REQUEST_TIMER3_UP: DMAMUX TIMER3 UP request + \arg DMA_REQUEST_I2C0_RX: DMAMUX I2C0 RX request + \arg DMA_REQUEST_I2C0_TX: DMAMUX I2C0 TX request + \arg DMA_REQUEST_I2C1_RX: DMAMUX I2C1 RX request + \arg DMA_REQUEST_I2C1_TX: DMAMUX I2C1 TX request + \arg DMA_REQUEST_SPI0_RX: DMAMUX SPI0 RX request + \arg DMA_REQUEST_SPI0_TX: DMAMUX SPI0 TX request + \arg DMA_REQUEST_SPI1_RX: DMAMUX SPI1 RX request + \arg DMA_REQUEST_SPI1_TX: DMAMUX SPI1 TX request + \arg DMA_REQUEST_USART0_RX: DMAMUX USART0 RX request + \arg DMA_REQUEST_USART0_TX: DMAMUX USART0 TX request + \arg DMA_REQUEST_USART1_RX: DMAMUX USART1 RX request + \arg DMA_REQUEST_USART1_TX: DMAMUX USART1 TX request + \arg DMA_REQUEST_USART2_RX: DMAMUX USART2 RX request + \arg DMA_REQUEST_USART2_TX: DMAMUX USART2 TX request + \arg DMA_REQUEST_TIMER7_CH0: DMAMUX TIMER7 CH0 request + \arg DMA_REQUEST_TIMER7_CH1: DMAMUX TIMER7 CH1 request + \arg DMA_REQUEST_TIMER7_CH2: DMAMUX TIMER7 CH2 request + \arg DMA_REQUEST_TIMER7_CH3: DMAMUX TIMER7 CH3 request + \arg DMA_REQUEST_TIMER7_MCH0: DMAMUX TIMER7 MCH0 request + \arg DMA_REQUEST_TIMER7_MCH1: DMAMUX TIMER7 MCH1 request + \arg DMA_REQUEST_TIMER7_MCH2: DMAMUX TIMER7 MCH2 request + \arg DMA_REQUEST_TIMER7_MCH3: DMAMUX TIMER7 MCH3 request + \arg DMA_REQUEST_TIMER7_UP: DMAMUX TIMER7 UP request + \arg DMA_REQUEST_TIMER7_TRG: DMAMUX TIMER7 TRG request + \arg DMA_REQUEST_TIMER7_CMT: DMAMUX TIMER7 CMT request + \arg DMA_REQUEST_TIMER4_CH0: DMAMUX TIMER4 CH0 request + \arg DMA_REQUEST_TIMER4_CH1: DMAMUX TIMER4 CH1 request + \arg DMA_REQUEST_TIMER4_CH2: DMAMUX TIMER4 CH2 request + \arg DMA_REQUEST_TIMER4_CH3: DMAMUX TIMER4 CH3 request + \arg DMA_REQUEST_TIMER4_UP: DMAMUX TIMER4 UP request + \arg DMA_REQUEST_TIMER4_CMT: DMAMUX TIMER4 CMT request + \arg DMA_REQUEST_TIMER4_TRG: DMAMUX TIMER4 TRG request + \arg DMA_REQUEST_SPI2_RX: DMAMUX SPI2 RX request + \arg DMA_REQUEST_SPI2_TX: DMAMUX SPI2 TX request + \arg DMA_REQUEST_UART3_RX: DMAMUX UART3 RX request + \arg DMA_REQUEST_UART3_TX: DMAMUX UART3 TX request + \arg DMA_REQUEST_UART4_RX: DMAMUX UART4 RX request + \arg DMA_REQUEST_UART4_TX: DMAMUX UART4 TX request + \arg DMA_REQUEST_DAC_CH0: DMAMUX DAC CH0 request + \arg DMA_REQUEST_DAC_CH1: DMAMUX DAC CH1 request + \arg DMA_REQUEST_TIMER5_UP: DMAMUX TIMER5 UP request + \arg DMA_REQUEST_TIMER6_UP: DMAMUX TIMER6 UP request + \arg DMA_REQUEST_USART5_RX: DMAMUX USART5 RX request + \arg DMA_REQUEST_USART5_TX: DMAMUX USART5 TX request + \arg DMA_REQUEST_I2C2_RX: DMAMUX I2C2 RX request + \arg DMA_REQUEST_I2C2_TX: DMAMUX I2C2 TX request + \arg DMA_REQUEST_DCI: DMAMUX DCI request + \arg DMA_REQUEST_CAU_IN: DMAMUX CAU IN request + \arg DMA_REQUEST_CAU_OUT: DMAMUX CAU OUT request + \arg DMA_REQUEST_HAU_IN: DMAMUX HAU IN request + \arg DMA_REQUEST_UART6_RX: DMAMUX UART6 RX request + \arg DMA_REQUEST_UART6_TX: DMAMUX UART6 TX request + \arg DMA_REQUEST_UART7_RX: DMAMUX UART7 RX request + \arg DMA_REQUEST_UART7_TX: DMAMUX UART7 TX request + \arg DMA_REQUEST_SPI3_RX: DMAMUX SPI3 RX request + \arg DMA_REQUEST_SPI3_TX: DMAMUX SPI3 TX request + \arg DMA_REQUEST_SPI4_RX: DMAMUX SPI4 RX request + \arg DMA_REQUEST_SPI4_TX: DMAMUX SPI4 TX request + \arg DMA_REQUEST_SAI0_B0: DMAMUX SAI0 B0 request + \arg DMA_REQUEST_SAI0_B1: DMAMUX SAI0 B1 request + \arg DMA_REQUEST_RSPDIF_DATA: DMAMUX RSPDIF DATA request + \arg DMA_REQUEST_RSPDIF_CS: DMAMUX RSPDIF CS request + \arg DMA_REQUEST_HPDF_FLT0: DMAMUX HPDF FLT0 request + \arg DMA_REQUEST_HPDF_FLT1: DMAMUX HPDF FLT1 request + \arg DMA_REQUEST_HPDF_FLT2: DMAMUX HPDF FLT2 request + \arg DMA_REQUEST_HPDF_FLT3: DMAMUX HPDF FLT3 request + \arg DMA_REQUEST_TIMER14_CH0: DMAMUX TIMER14 CH0 request + \arg DMA_REQUEST_TIMER14_CH1: DMAMUX TIMER14 CH1 request + \arg DMA_REQUEST_TIMER14_MCH0: DMAMUX TIMER14 MCH0 request + \arg DMA_REQUEST_TIMER14_UP: DMAMUX TIMER14 UP request + \arg DMA_REQUEST_TIMER14_TRG: DMAMUX TIMER14 TRG request + \arg DMA_REQUEST_TIMER14_CMT: DMAMUX TIMER14 CMT request + \arg DMA_REQUEST_TIMER15_CH0: DMAMUX TIMER15 CH0 request + \arg DMA_REQUEST_TIMER15_MCH0: DMAMUX TIMER15 MCH0 request + \arg DMA_REQUEST_TIMER15_UP: DMAMUX TIMER15 UP request + \arg DMA_REQUEST_TIMER16_CH0: DMAMUX TIMER16 CH0 request + \arg DMA_REQUEST_TIMER16_MCH0: DMAMUX TIMER16 MCH0 request + \arg DMA_REQUEST_TIMER16_UP: DMAMUX TIMER16 TRG request + \arg DMA_REQUEST_ADC2: DMAMUX ADC2 request + \arg DMA_REQUEST_FAC_READ: DMAMUX FAC READ request + \arg DMA_REQUEST_FAC_WRITE: DMAMUX FAC WRITE request + \arg DMA_REQUEST_TMU_INPUT: DMAMUX TMU INPUT request + \arg DMA_REQUEST_TMU_OUTPUT: DMAMUX TMU OUTPUT request + \arg DMA_REQUEST_TIMER22_CH0: DMAMUX TIMER22 CH0 request + \arg DMA_REQUEST_TIMER22_CH1: DMAMUX TIMER22 CH1 request + \arg DMA_REQUEST_TIMER22_CH2: DMAMUX TIMER22 CH2 request + \arg DMA_REQUEST_TIMER22_CH3: DMAMUX TIMER22 CH3 request + \arg DMA_REQUEST_TIMER22_UP: DMAMUX TIMER22 UP request + \arg DMA_REQUEST_TIMER22_TRG: DMAMUX TIMER22 TRG request + \arg DMA_REQUEST_TIMER23_CH0: DMAMUX TIMER23 CH0 request + \arg DMA_REQUEST_TIMER23_CH1: DMAMUX TIMER23 CH1 request + \arg DMA_REQUEST_TIMER23_CH2: DMAMUX TIMER23 CH2 request + \arg DMA_REQUEST_TIMER23_CH3: DMAMUX TIMER23 CH3 request + \arg DMA_REQUEST_TIMER23_UP: DMAMUX TIMER23 UP request + \arg DMA_REQUEST_TIMER23_TRG: DMAMUX TIMER23 TRG request + \arg DMA_REQUEST_TIMER30_CH0: DMAMUX TIMER30 CH0 request + \arg DMA_REQUEST_TIMER30_CH1: DMAMUX TIMER30 CH1 request + \arg DMA_REQUEST_TIMER30_CH2: DMAMUX TIMER30 CH2 request + \arg DMA_REQUEST_TIMER30_CH3: DMAMUX TIMER30 CH3 request + \arg DMA_REQUEST_TIMER30_UP: DMAMUX TIMER30 UP request + \arg DMA_REQUEST_TIMER30_TRG: DMAMUX TIMER30 TRG request + \arg DMA_REQUEST_TIMER31_CH0: DMAMUX TIMER31 CH0 request + \arg DMA_REQUEST_TIMER31_CH1: DMAMUX TIMER31 CH1 request + \arg DMA_REQUEST_TIMER31_CH2: DMAMUX TIMER31 CH2 request + \arg DMA_REQUEST_TIMER31_CH3: DMAMUX TIMER31 CH3 request + \arg DMA_REQUEST_TIMER31_UP: DMAMUX TIMER31 UP request + \arg DMA_REQUEST_TIMER31_TRG: DMAMUX TIMER31 TRG request + \arg DMA_REQUEST_TIMER40_CH0: DMAMUX TIMER40 CH0 request + \arg DMA_REQUEST_TIMER40_MCH0: DMAMUX TIMER40 MCH0 request + \arg DMA_REQUEST_TIMER40_CMT: DMAMUX TIMER40 CMT request + \arg DMA_REQUEST_TIMER40_UP: DMAMUX TIMER40 UP request + \arg DMA_REQUEST_TIMER41_CH0: DMAMUX TIMER41 CH0 request + \arg DMA_REQUEST_TIMER41_MCH0: DMAMUX TIMER41 MCH0 request + \arg DMA_REQUEST_TIMER41_CMT: DMAMUX TIMER41 CMT request + \arg DMA_REQUEST_TIMER41_UP: DMAMUX TIMER41 UP request + \arg DMA_REQUEST_TIMER42_CH0: DMAMUX TIMER42 CH0 request + \arg DMA_REQUEST_TIMER42_MCH0: DMAMUX TIMER42 MCH0 request + \arg DMA_REQUEST_TIMER42_CMT: DMAMUX TIMER42 CMT request + \arg DMA_REQUEST_TIMER42_UP: DMAMUX TIMER42 UP request + \arg DMA_REQUEST_TIMER43_CH0: DMAMUX TIMER43 CH0 request + \arg DMA_REQUEST_TIMER43_MCH0: DMAMUX TIMER43 MCH0 request + \arg DMA_REQUEST_TIMER43_CMT: DMAMUX TIMER43 CMT request + \arg DMA_REQUEST_TIMER43_UP: DMAMUX TIMER43 UP request + \arg DMA_REQUEST_TIMER44_CH0: DMAMUX TIMER44 CH0 request + \arg DMA_REQUEST_TIMER44_MCH0: DMAMUX TIMER44 MCH0 request + \arg DMA_REQUEST_TIMER44_CMT: DMAMUX TIMER44 CMT request + \arg DMA_REQUEST_TIMER44_UP: DMAMUX TIMER44 UP request + \arg DMA_REQUEST_TIMER50_UP: DMAMUX TIMER50 UP request + \arg DMA_REQUEST_TIMER51_UP: DMAMUX TIMER51 UP request + \arg DMA_REQUEST_SAI1_B0: DMAMUX SAI1 B0 request + \arg DMA_REQUEST_SAI1_B1: DMAMUX SAI1 B1 request + \arg DMA_REQUEST_SAI2_B0: DMAMUX SAI2 B0 request + \arg DMA_REQUEST_SAI2_B1: DMAMUX SAI2 B1 request + \arg DMA_REQUEST_SPI5_RX: DMAMUX SPI5 RX request + \arg DMA_REQUEST_SPI5_TX: DMAMUX SPI5 TX request + \arg DMA_REQUEST_I2C3_RX: DMAMUX I2C3 RX request + \arg DMA_REQUEST_I2C3_TX: DMAMUX I2C3 TX request + \arg DMA_REQUEST_CAN0: DMAMUX CAN0 request + \arg DMA_REQUEST_CAN1: DMAMUX CAN1 request + \arg DMA_REQUEST_CAN2: DMAMUX CAN2 request + \arg DMA_REQUEST_TIMER40_CH1: DMAMUX TIMER40 CH1 request + \arg DMA_REQUEST_TIMER40_TRG: DMAMUX TIMER40 TRG request + \arg DMA_REQUEST_TIMER41_CH1: DMAMUX TIMER41 CH1 request + \arg DMA_REQUEST_TIMER41_TRG: DMAMUX TIMER41 TRG request + \arg DMA_REQUEST_TIMER42_CH1: DMAMUX TIMER42 CH1 request + \arg DMA_REQUEST_TIMER42_TRG: DMAMUX TIMER42 TRG request + \arg DMA_REQUEST_TIMER43_CH1: DMAMUX TIMER43 CH1 request + \arg DMA_REQUEST_TIMER43_TRG: DMAMUX TIMER43 TRG request + \arg DMA_REQUEST_TIMER44_CH1: DMAMUX TIMER44 CH1 request + \arg DMA_REQUEST_TIMER44_TRG: DMAMUX TIMER44 TRG request + \param[out] none + \retval none +*/ +void dmamux_request_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG(channelx) |= id; +} + +/*! + \brief configure trigger input polarity + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..7) + \param[in] polarity: trigger input polarity + only one parameter can be selected which is shown as below: + \arg DMAMUX_GEN_NO_EVENT: no event detection + \arg DMAMUX_GEN_RISING: rising edge + \arg DMAMUX_GEN_FALLING: falling edge + \arg DMAMUX_GEN_RISING_FALLING: rising and falling edges + \param[out] none + \retval none +*/ +void dmamux_trigger_polarity_config(dmamux_generator_channel_enum channelx, uint32_t polarity) +{ + DMAMUX_RG_CHXCFG(channelx) &= ~DMAMUX_RG_CHXCFG_RGTP; + DMAMUX_RG_CHXCFG(channelx) |= polarity; +} + +/*! + \brief configure number of DMA requests to be generated + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..7) + \param[in] number: DMA requests number to be generated + only one parameter can be selected which is shown as below: + \arg 1 - 32 + \param[out] none + \retval none +*/ +void dmamux_request_generate_number_config(dmamux_generator_channel_enum channelx, uint32_t number) +{ + DMAMUX_RG_CHXCFG(channelx) &= ~DMAMUX_RG_CHXCFG_NBRG; + DMAMUX_RG_CHXCFG(channelx) |= ((number - 1U) << RG_CHXCFG_NBRG_OFFSET); +} + +/*! + \brief configure trigger input identification + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..7) + \param[in] id: trigger input identification + only one parameter can be selected which is shown as below: + \arg DMAMUX_TRIGGER_EXTI0: trigger input is EXTI0 + \arg DMAMUX_TRIGGER_EXTI1: trigger input is EXTI1 + \arg DMAMUX_TRIGGER_EXTI2: trigger input is EXTI2 + \arg DMAMUX_TRIGGER_EXTI3: trigger input is EXTI3 + \arg DMAMUX_TRIGGER_EXTI4: trigger input is EXTI4 + \arg DMAMUX_TRIGGER_EXTI5: trigger input is EXTI5 + \arg DMAMUX_TRIGGER_EXTI6: trigger input is EXTI6 + \arg DMAMUX_TRIGGER_EXTI7: trigger input is EXTI7 + \arg DMAMUX_TRIGGER_EXTI8: trigger input is EXTI8 + \arg DMAMUX_TRIGGER_EXTI9: trigger input is EXTI9 + \arg DMAMUX_TRIGGER_EXTI10: trigger input is EXTI10 + \arg DMAMUX_TRIGGER_EXTI11: trigger input is EXTI11 + \arg DMAMUX_TRIGGER_EXTI12: trigger input is EXTI12 + \arg DMAMUX_TRIGGER_EXTI13: trigger input is EXTI13 + \arg DMAMUX_TRIGGER_EXTI14: trigger input is EXTI14 + \arg DMAMUX_TRIGGER_EXTI15: trigger input is EXTI15 + \arg DMAMUX_TRIGGER_EVT0_OUT: trigger input is Evt0_out + \arg DMAMUX_TRIGGER_EVT1_OUT: trigger input is Evt1_out + \arg DMAMUX_TRIGGER_EVT2_OUT: trigger input is Evt2_out + \arg DMAMUX_TRIGGER_EVT3_OUT: trigger input is Evt3_out + \arg DMAMUX_TRIGGER_EVT4_OUT: trigger input is Evt4_out + \arg DMAMUX_TRIGGER_EVT5_OUT: trigger input is Evt5_out + \arg DMAMUX_TRIGGER_EVT6_OUT: trigger input is Evt6_out + \arg DMAMUX_TRIGGER_RTC_WAKEUP: trigger input is wakeup + \arg DMAMUX_TRIGGER_CMP0_OUTPUT: trigger input is CMP0 output + \arg DMAMUX_TRIGGER_CMP1_OUTPUT: trigger input is CMP1 output + \arg DMAMUX_TRIGGER_I2C0_WAKEUP: trigger input is I2C0 wakeup + \arg DMAMUX_TRIGGER_I2C1_WAKEUP: trigger input is I2C1 wakeup + \arg DMAMUX_TRIGGER_I2C2_WAKEUP: trigger input is I2C2 wakeup + \arg DMAMUX_TRIGGER_I2C3_WAKEUP: trigger input is I2C3 wakeup + \arg DMAMUX_TRIGGER_I2C0_INT_EVENT: trigger input is I2C0 interrupt event + \arg DMAMUX_TRIGGER_I2C1_INT_EVENT: trigger input is I2C1 interrupt event + \arg DMAMUX_TRIGGER_I2C2_INT_EVENT: trigger input is I2C2 interrupt event + \arg DMAMUX_TRIGGER_I2C3_INT_EVENT: trigger input is I2C3 interrupt event + \arg DMAMUX_TRIGGER_ADC2_INT: ADC2 interrupt + \param[out] none + \retval none +*/ +void dmamux_trigger_id_config(dmamux_generator_channel_enum channelx, uint32_t id) +{ + DMAMUX_RG_CHXCFG(channelx) &= ~DMAMUX_RG_CHXCFG_TID; + DMAMUX_RG_CHXCFG(channelx) |= id; +} + +/*! + \brief get DMAMUX flag + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH12_SO: DMAMUX request multiplexer channel 12 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH13_SO: DMAMUX request multiplexer channel 13 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH14_SO: DMAMUX request multiplexer channel 14 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH15_SO: DMAMUX request multiplexer channel 15 synchronization overrun flag + \arg DMAMUX_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun flag + \arg DMAMUX_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun flag + \arg DMAMUX_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun flag + \arg DMAMUX_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun flag + \arg DMAMUX_FLAG_GENCH4_TO: DMAMUX request generator channel 4 trigger overrun flag + \arg DMAMUX_FLAG_GENCH5_TO: DMAMUX request generator channel 5 trigger overrun flag + \arg DMAMUX_FLAG_GENCH6_TO: DMAMUX request generator channel 6 trigger overrun flag + \arg DMAMUX_FLAG_GENCH7_TO: DMAMUX request generator channel 7 trigger overrun flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dmamux_flag_get(dmamux_flag_enum flag) +{ + FlagStatus reval; + + if(RESET != (DMAMUX_REG_VAL(flag) & BIT(DMAMUX_BIT_POS(flag)))) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMAMUX flag + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH12_SO: DMAMUX request multiplexer channel 12 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH13_SO: DMAMUX request multiplexer channel 13 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH14_SO: DMAMUX request multiplexer channel 14 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH15_SO: DMAMUX request multiplexer channel 15 synchronization overrun flag + \arg DMAMUX_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun flag + \arg DMAMUX_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun flag + \arg DMAMUX_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun flag + \arg DMAMUX_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun flag + \arg DMAMUX_FLAG_GENCH4_TO: DMAMUX request generator channel 4 trigger overrun flag + \arg DMAMUX_FLAG_GENCH5_TO: DMAMUX request generator channel 5 trigger overrun flag + \arg DMAMUX_FLAG_GENCH6_TO: DMAMUX request generator channel 6 trigger overrun flag + \arg DMAMUX_FLAG_GENCH7_TO: DMAMUX request generator channel 7 trigger overrun flag + \param[out] none + \retval none +*/ +void dmamux_flag_clear(dmamux_flag_enum flag) +{ + DMAMUX_REG_VAL3(flag) = BIT(DMAMUX_BIT_POS(flag)); +} + +/*! + \brief enable DMAMUX interrupt + \param[in] interrupt: specify which interrupt to enable + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH12_SO: DMAMUX request multiplexer channel 12 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH13_SO: DMAMUX request multiplexer channel 13 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH14_SO: DMAMUX request multiplexer channel 14 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH15_SO: DMAMUX request multiplexer channel 15 synchronization overrun interrupt + \arg DMAMUX_INT_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt + \arg DMAMUX_INT_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt + \arg DMAMUX_INT_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt + \arg DMAMUX_INT_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt + \arg DMAMUX_INT_GENCH4_TO: DMAMUX request generator channel 4 trigger overrun interrupt + \arg DMAMUX_INT_GENCH5_TO: DMAMUX request generator channel 5 trigger overrun interrupt + \arg DMAMUX_INT_GENCH6_TO: DMAMUX request generator channel 6 trigger overrun interrupt + \arg DMAMUX_INT_GENCH7_TO: DMAMUX request generator channel 7 trigger overrun interrupt + \param[out] none + \retval none +*/ +void dmamux_interrupt_enable(dmamux_interrupt_enum interrupt) +{ + DMAMUX_REG_VAL(interrupt) |= BIT(DMAMUX_BIT_POS(interrupt)); +} + +/*! + \brief disable DMAMUX interrupt + \param[in] interrupt: specify which interrupt to disable + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH12_SO: DMAMUX request multiplexer channel 12 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH13_SO: DMAMUX request multiplexer channel 13 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH14_SO: DMAMUX request multiplexer channel 14 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH15_SO: DMAMUX request multiplexer channel 15 synchronization overrun interrupt + \arg DMAMUX_INT_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt + \arg DMAMUX_INT_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt + \arg DMAMUX_INT_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt + \arg DMAMUX_INT_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt + \arg DMAMUX_INT_GENCH4_TO: DMAMUX request generator channel 4 trigger overrun interrupt + \arg DMAMUX_INT_GENCH5_TO: DMAMUX request generator channel 5 trigger overrun interrupt + \arg DMAMUX_INT_GENCH6_TO: DMAMUX request generator channel 6 trigger overrun interrupt + \arg DMAMUX_INT_GENCH7_TO: DMAMUX request generator channel 7 trigger overrun interrupt + \param[out] none + \retval none +*/ +void dmamux_interrupt_disable(dmamux_interrupt_enum interrupt) +{ + DMAMUX_REG_VAL(interrupt) &= ~BIT(DMAMUX_BIT_POS(interrupt)); +} + +/*! + \brief get DMAMUX interrupt flag + \param[in] int_flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH12_SO: DMAMUX request multiplexer channel 12 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH13_SO: DMAMUX request multiplexer channel 13 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH14_SO: DMAMUX request multiplexer channel 14 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH15_SO: DMAMUX request multiplexer channel 15 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH4_TO: DMAMUX request generator channel 4 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH5_TO: DMAMUX request generator channel 5 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH6_TO: DMAMUX request generator channel 6 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH7_TO: DMAMUX request generator channel 7 trigger overrun interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dmamux_interrupt_flag_get(dmamux_interrupt_flag_enum int_flag) +{ + FlagStatus reval; + uint32_t intenable = 0U, flagstatus = 0U; + + /* get the interrupt enable bit status */ + intenable = (DMAMUX_REG_VAL2(int_flag) & BIT(DMAMUX_BIT_POS2(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (DMAMUX_REG_VAL(int_flag) & BIT(DMAMUX_BIT_POS(int_flag))); + + if(flagstatus && intenable) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMAMUX interrupt flag + \param[in] int_flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH12_SO: DMAMUX request multiplexer channel 12 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH13_SO: DMAMUX request multiplexer channel 13 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH14_SO: DMAMUX request multiplexer channel 14 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH15_SO: DMAMUX request multiplexer channel 15 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH4_TO: DMAMUX request generator channel 4 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH5_TO: DMAMUX request generator channel 5 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH6_TO: DMAMUX request generator channel 6 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH7_TO: DMAMUX request generator channel 7 trigger overrun interrupt flag + \param[out] none + \retval none +*/ +void dmamux_interrupt_flag_clear(dmamux_interrupt_flag_enum int_flag) +{ + DMAMUX_REG_VAL3(int_flag) = BIT(DMAMUX_BIT_POS(int_flag)); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_edout.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_edout.c new file mode 100644 index 0000000000..1a0f630433 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_edout.c @@ -0,0 +1,207 @@ +/*! + \file gd32h7xx_edout.c + \brief EDOUT driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_edout.h" + +/* EDOUT register bit offset */ +#define LOC_LOCMAX_MIN ((uint32_t)0x0000000FU) /*!< LOCMAX fields minimum value */ +#define LOC_LOCMAX_STEP ((uint32_t)0x00000004U) /*!< LOCMAX fields step value */ +#define OCNT_PDC_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of PDC in EDOUT_OCNT */ +#define ZCR_ZOWH_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of ZOWH in EDOUT_ZCR */ + +/*! + \brief deinitialize EDOUT + \param[in] none + \param[out] none + \retval none +*/ +void edout_deinit(void) +{ + /* reset EDOUT */ + rcu_periph_reset_enable(RCU_EDOUTRST); + rcu_periph_reset_disable(RCU_EDOUTRST); +} + +/*! + \brief initialize EDOUT + \param[in] pol: the active polarity of the B-phase output signal selection + only one parameter can be selected which is shown as below: + \arg EDOUT_POL_POSITIVE: active polarity is positive + \arg EDOUT_POL_NEGATIVE: active polarity is negative + \param[in] max_loc: (max_loc+1) must be a multiple of four between 16~65536 (e.g. 0x000F: The maximum location value is 16 (16=4*4)) + \param[in] cur_loc: current location value, 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register) + \param[out] none + \retval none +*/ +void edout_init(uint32_t pol, uint32_t max_loc, uint32_t cur_loc) +{ + /* reset polarity of the B-phase */ + EDOUT_CTL &= ~EDOUT_CTL_POL; + /* set polarity of the B-phase */ + EDOUT_CTL = pol; + + /* reset the maximum location value */ + EDOUT_LOC &= ~EDOUT_LOC_LOCMAX; + /* check the maximum location value */ + if(LOC_LOCMAX_MIN > max_loc) { + max_loc = LOC_LOCMAX_MIN; + } + while(0U != ((max_loc + 1U) % LOC_LOCMAX_STEP)) { + max_loc++; + } + /* set the maximum location value */ + EDOUT_LOC = max_loc & EDOUT_LOC_LOCMAX; + + /* reset the current location value */ + EDOUT_LCNT &= ~EDOUT_LCNT_LOCCNT; + /* set the current location value */ + EDOUT_LCNT = cur_loc & EDOUT_LCNT_LOCCNT; +} + +/*! + \brief enable EDOUT + \param[in] none + \param[out] none + \retval none +*/ +void edout_enable(void) +{ + EDOUT_ENABLE |= EDOUT_ENABLE_EDOUTEN; +} + +/*! + \brief disable EDOUT + \param[in] none + \param[out] none + \retval none +*/ +void edout_disable(void) +{ + EDOUT_ENABLE &= ~EDOUT_ENABLE_EDOUTEN; +} + +/*! + \brief set B-phase active polarity + \param[in] pol: the active polarity of the B-phase output signal selection + only one parameter can be selected which is shown as below: + \arg EDOUT_POL_POSITIVE: active polarity is positive + \arg EDOUT_POL_NEGATIVE: active polarity is negative + \param[out] none + \retval none +*/ +void edout_polarity_config(uint32_t pol) +{ + EDOUT_CTL = pol; +} + +/*! + \brief set the maximum location value for one rotation + \param[in] max_loc: (max_loc+1) must be a multiple of four between 16~65536, e.g. 0x000F: The maximum location value is 16 + \param[out] none + \retval none +*/ +void edout_max_location_value_config(uint32_t max_loc) +{ + EDOUT_LOC = max_loc & EDOUT_LOC_LOCMAX; +} + +/*! + \brief update the output counter, used to set the phase difference and the number of edges for the next update period + \param[in] num_edges: edge count, value range is -32768~32767, positive means clockwise rotation, negative means counter-clockwise rotation + \param[in] phase_diff: phase difference, value range is 2~65535, in units of PCLK + \param[out] none + \retval none +*/ +void edout_output_counter_update(int16_t num_edges, uint16_t phase_diff) +{ + EDOUT_OCNT = ((uint32_t)num_edges & EDOUT_OCNT_EDGC) | ((uint32_t)phase_diff << OCNT_PDC_OFFSET); +} + +/*! + \brief set the current location value + \param[in] cur_loc: current location value, 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register) + \param[out] none + \retval none +*/ +void edout_current_location_config(uint32_t cur_loc) +{ + EDOUT_LCNT = cur_loc & EDOUT_LCNT_LOCCNT; +} + +/*! + \brief get the current location value + \param[in] none + \param[out] none + \retval current location value, 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register) +*/ +uint16_t edout_current_location_get(void) +{ + return (uint16_t)EDOUT_LCNT; +} + +/*! + \brief configure Z-phase output mode + \param[in] mode: Z-phase output mode + only one parameter can be selected which is shown as below: + \arg EDOUT_Z_OUTPUT_MODE0: output according to the current location + \arg EDOUT_Z_OUTPUT_MODE1: output according to the number of edges + \param[out] none + \retval none +*/ +void edout_z_output_mode_config(uint32_t mode) +{ + /* reset the Z-phase output mode */ + EDOUT_ZCR &= ~EDOUT_ZCR_ZOMD; + /* set the Z-phase output mode */ + EDOUT_ZCR |= mode; +} + +/*! + \brief configure Z-phase output start location and width + \param[in] start_loc: Z-phase output start location, + when Z-phase output mode select EDOUT_Z_OUTPUT_MODE0: 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register) + when Z-phase output mode select EDOUT_Z_OUTPUT_MODE1: 0~edges (edges is the EDGC bit fields value of EDOUT_OCNT register) + \param[in] width: Z-phase output width + when Z-phase output mode select EDOUT_Z_OUTPUT_MODE0: 0~(locmax - start_loc) (locmax is the LOCMAX bit fields value of EDOUT_LOC register) + when Z-phase output mode select EDOUT_Z_OUTPUT_MODE1: 0~(edges - start_loc) (edges is the EDGC bit fields value of EDOUT_OCNT register) + \param[out] none + \retval none +*/ +void edout_z_output_start_loc_and_width_config(uint32_t start_loc, uint32_t width) +{ + /* reset the Z-phase output start location and output width */ + EDOUT_ZCR &= ~(EDOUT_ZCR_ZOSP | EDOUT_ZCR_ZOWH); + /* set the Z-phase output start location and output width */ + EDOUT_ZCR |= (start_loc & EDOUT_ZCR_ZOSP) | ((width << ZCR_ZOWH_OFFSET) & EDOUT_ZCR_ZOWH); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_efuse.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_efuse.c new file mode 100644 index 0000000000..056b51ec2d --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_efuse.c @@ -0,0 +1,514 @@ +/*! + \file gd32h7xx_efuse.c + \brief EFUSE driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_efuse.h" + +/* FMC register bit offset */ +#define EFUSE_CTL_AES_KEY_CRC_OFFSET ((uint32_t)0x00000018U) /*!< bit offset of AES_KEY_CRC in EFUSE_CTL register*/ +#define EFUSE_CTL_MPVEN_OFFSET ((uint32_t)0x0000000FU) /*!< bit offset of MPVEN in EFUSE_CTL register*/ +#define EFUSE_STAT_LDO_RDY_OFFSET ((uint32_t)0x00000004U) /*!< bit offset of LDO_RDY in EFUSE_STAT register*/ +#define EFUSE_ADDR_EFSIZE_OFFSET ((uint32_t)0x0000000AU) /*!< EFSIZE OFFSET in register EFUSE_ADDR */ + +#define EFUSE_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< EFUSE operation timeout value */ +#define USER_CTL_NDBG0 BIT(8) /*!< debug mode setting bit0 in register EFUSE_USER_CTL */ + +static uint32_t para_start_efaddr[EFUSE_PARA_CNT] = {USER_CTL_EFADDR, MCU_RESERVED_EFADDR, DP_EFADDR, AES_KEY_EFADDR, USER_DATA_EFADDR}; +static uint32_t para_reg_start_addr[EFUSE_PARA_CNT] = {EFUSE_USER_CTL_REG_ADDR, EFUSE_MCU_RSV_REG_ADDR, EFUSE_DP_REG_ADDR, EFUSE_AES_KEY_REG_ADDR, EFUSE_USER_DATA_REG_ADDR}; +static efuse_state_enum efuse_ready_wait(uint32_t efuse_flag, uint32_t timeout); + +/*! + \brief read system parameters from EFUSE macro to registers + \param[in] ef_addr: start address of the system parameters to be read + only one parameter can be selected which is shown as below: + \arg USER_CTL_EFADDR: user control parameter start address + \arg MCU_RESERVED_EFADDR: MCU reserved parameter start address + \arg DP_EFADDR: debug password parameter start address + \arg USER_DATA_EFADDR: user data parameter start address + \param[in] size: size of the system parameters to be read + only one parameter can be selected which is shown as below: + \arg USER_CTL_SIZE: user control parameter size + \arg MCU_RESERVED_SIZE: MCU reserved parameter size + \arg DP_SIZE: debug password parameter size + \arg USER_DATA_SIZE: user data parameter size + \param[out] buf: the buffer for data read from EFUSE macro + \retval ErrStatus: ERROR or SUCCESS +*/ + +ErrStatus efuse_read(uint32_t ef_addr, uint32_t size, uint32_t buf[]) +{ + ErrStatus status = SUCCESS; + uint32_t timeout = EFUSE_TIMEOUT; + efuse_state_enum efuse_state; + uint32_t reg_addr = 0U; + uint32_t i = 0U; + uint32_t number = 0U; + switch(ef_addr) { + case USER_CTL_EFADDR: + /* read user control */ + reg_addr = EFUSE_USER_CTL_REG_ADDR; + number = 1U; + break; + case MCU_RESERVED_EFADDR: + /* read MCU reserved data */ + reg_addr = EFUSE_MCU_RSV_REG_ADDR; + number = 1U; + break; + case DP_EFADDR: + /* read debug password */ + if(RESET != (EFUSE_USER_CTL & EFUSE_USER_CTL_DPLK)) { + if(RESET != (EFUSE_USER_CTL & EFUSE_USER_CTL_JTAGNSW)) { + if((RESET != (EFUSE_USER_CTL & USER_CTL_NDBG0))) { + status = ERROR; + } + } + } + if(SUCCESS == status) { + reg_addr = EFUSE_DP_REG_ADDR; + number = 2U; + } + break; + case USER_DATA_EFADDR: + /* read user data */ + reg_addr = EFUSE_USER_DATA_REG_ADDR; + number = 4U; + break; + default: + status = ERROR; + break; + } + if(ERROR == status) { + return status; + } + /* clear the RDIF bit if it is SET */ + efuse_flag_clear(EFUSE_FLAG_READ_COMPLETE_CLR); + /* reset the EFRW bit in EFUSE_CTL */ + EFUSE_CTL &= ~EFUSE_CTL_EFRW; + /* write the desired efuse address and size to the EFUSE_ADDR register */ + EFUSE_ADDR = (uint32_t)((size << EFUSE_ADDR_EFSIZE_OFFSET) | ef_addr); + /* start array read EFUSE operation */ + EFUSE_CTL |= EFUSE_CTL_EFSTR; + /* wait for the operation to complete */ + efuse_state = efuse_ready_wait(EFUSE_FLAG_READ_COMPLETE, timeout); + if(EFUSE_READY != efuse_state) { + status = ERROR; + } + /* read EFUSE register */ + for(i = 0U; i < number; i++) { + buf[i] = REG32(reg_addr + (4U * i)); + } + return status; +} + +/*! + \brief program register values to EFUSE macro system parameters + \param[in] ef_addr: the EFUSE address to be programmed, pgm_addr cannot exceed 384, and must be an integral multiple of 8 + \param[in] size: byte count to program, (1~16) + \param[in] buf: the buffer for data written to EFUSE macro + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus efuse_write(uint32_t ef_addr, uint32_t size, uint8_t *buf) +{ + uint32_t i; + uint32_t reg_addr; + uint32_t byte_offset_in_reg; + uint32_t cnt; + ErrStatus status = SUCCESS; + uint32_t para_index; + uint32_t tmp_buf_8; + uint32_t buf_addr; + uint32_t timeout = EFUSE_TIMEOUT; + efuse_state_enum efuse_state; + if(0U == size) { + return ERROR; + } + /* the address should be on byte address boundary */ + if(ef_addr % 8U) { + return ERROR; + } + if(MAX_EFADDR < ef_addr) { + return ERROR; + } + for(i = EFUSE_PARA_CNT; i > 0U; i--) { + if(ef_addr >= para_start_efaddr[i - 1U]) { + break; + } + } + /* get the index of parameter to be programmed */ + para_index = i - 1U; + /* program range should not over parameter boundary */ + if(para_index == (EFUSE_PARA_CNT - 1U)) { + if((ef_addr + size * 8U - 1U) > MAX_EFADDR) { + return ERROR; + } + } else { + if((ef_addr + size * 8U - 1U) > para_start_efaddr[para_index + 1U]) { + return ERROR; + } + } + if((AES_KEY_IDX == para_index) && (AES_KEY_SIZE != size)) { + /* AES key should be programmed in one time */ + return ERROR; + } + reg_addr = (unsigned int)para_reg_start_addr[para_index] + (ef_addr - para_start_efaddr[para_index]) / 32U * 4U; + byte_offset_in_reg = ((ef_addr - para_start_efaddr[para_index]) / 8U) % 4U; + /* clear the PGIF bit if it is SET */ + efuse_flag_clear(EFUSE_FLAG_PROGRAM_COMPLETE_CLR); + /* set the EFRW bit in EFUSE_CTL */ + EFUSE_CTL |= EFUSE_CTL_EFRW; + /* write the desired efuse address and size to the EFUSE_ADDR register */ + EFUSE_ADDR = (uint32_t)((size << EFUSE_ADDR_EFSIZE_OFFSET) | ef_addr); + buf_addr = (uint32_t)buf; + + while(size) { + if((0U != byte_offset_in_reg) || ((0U == byte_offset_in_reg) && (size < 4U))) { + cnt = size < (4U - byte_offset_in_reg) ? size : 4U - byte_offset_in_reg; + for(i = 0U; i < cnt; i++) { + tmp_buf_8 = buf_addr; + /* write the data to the corresponding register */ + tmp_buf_8 += i; + REG32(reg_addr) |= (((uint32_t)(*(uint8_t *)(tmp_buf_8))) << ((byte_offset_in_reg + i) * 8U)); + } + size -= cnt; + reg_addr += 4U; + byte_offset_in_reg = 0U; + buf_addr += cnt; + } else { + cnt = size / 4U; + for(i = 0U; i < cnt; i++) { + tmp_buf_8 = buf_addr; + /* write the data to the corresponding register */ + tmp_buf_8 += (i * 4U); + REG32(reg_addr) = (uint32_t)(*(uint32_t *)(tmp_buf_8)); + reg_addr += 4U; + } + size -= cnt * 4U; + buf_addr += cnt * 4U; + } + } + /* start EFUSE program operation */ + EFUSE_CTL |= EFUSE_CTL_EFSTR; + /* wait for the operation to complete */ + efuse_state = efuse_ready_wait(EFUSE_FLAG_PROGRAM_COMPLETE, timeout); + if(EFUSE_READY != efuse_state) { + status = ERROR; + } + return status; +} + +/*! + \brief program all user control parameters + \param[in] buf: the buffer of data written to efuse + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus efuse_user_control_write(uint8_t *buf) +{ + return efuse_write(USER_CTL_EFADDR, USER_CTL_SIZE, buf); +} + +/*! + \brief program all MCU reserved parameters + \param[in] buf: the buffer of data written to efuse + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus efuse_mcu_reserved_write(uint8_t *buf) +{ + return efuse_write(MCU_RESERVED_EFADDR, MCU_RESERVED_SIZE, buf); +} + +/*! + \brief program all debug password parameters + \param[in] buf: the buffer of data written to efuse + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus efuse_dp_write(uint8_t *buf) +{ + return efuse_write(DP_EFADDR, DP_SIZE, buf); +} + +/*! + \brief program all AES key parameters + \param[in] buf: the buffer of data written to efuse + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus efuse_aes_key_write(uint8_t *buf) +{ + return efuse_write(AES_KEY_EFADDR, AES_KEY_SIZE, buf); +} + +/*! + \brief program all user data parameters + \param[in] buf: the buffer of data written to efuse + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus efuse_user_data_write(uint8_t *buf) +{ + return efuse_write(USER_DATA_EFADDR, USER_DATA_SIZE, buf); +} + +/*! + \brief get 8-bits CRC calculation result value of AES key + \param[in] none + \param[out] none + \retval 8-bits CRC calculation result value of AES key +*/ +uint8_t efuse_aes_key_crc_get(void) +{ + return (uint8_t)((EFUSE_CTL & EFUSE_CTL_AES_KEY_CRC) >> EFUSE_CTL_AES_KEY_CRC_OFFSET); +} + +/*! + \brief enable monitor program voltage function + \param[in] none + \param[out] none + \retval none +*/ +void efuse_monitor_program_voltage_enable(void) +{ + uint32_t ctl_reg; + ctl_reg = EFUSE_CTL; + /* enable monitor program voltage function */ + ctl_reg |= EFUSE_CTL_MPVEN; + EFUSE_CTL = ctl_reg; +} + +/*! + \brief disable monitor program voltage function + \param[in] none + \param[out] none + \retval none +*/ +void efuse_monitor_program_voltage_disable(void) +{ + uint32_t ctl_reg; + ctl_reg = EFUSE_CTL; + /* disable monitor program voltage function */ + ctl_reg &= ~EFUSE_CTL_MPVEN; + EFUSE_CTL = ctl_reg; +} + +/*! + \brief get monitor program voltage function + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus efuse_monitor_program_voltage_get(void) +{ + FlagStatus mpven_state = RESET; + + if(EFUSE_CTL_MPVEN == (uint32_t)(EFUSE_CTL & EFUSE_CTL_MPVEN)) { + mpven_state = SET; + } else { + mpven_state = RESET; + } + return mpven_state; +} + +/*! + \brief get ldo ready signal + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus efuse_ldo_ready_get(void) +{ + FlagStatus ldo_ready_state = RESET; + + if(EFUSE_STAT_LDO_RDY == (uint32_t)(EFUSE_STAT & EFUSE_STAT_LDO_RDY)) { + ldo_ready_state = SET; + } else { + ldo_ready_state = RESET; + } + return ldo_ready_state; +} + +/*! + \brief check EFUSE flag is set or not + \param[in] flag: specifies to get a flag + only one parameter can be selected which is shown as below: + \arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR: illegal access error flag + \arg EFUSE_FLAG_PROGRAM_COMPLETE: programming operation completion flag + \arg EFUSE_FLAG_READ_COMPLETE: read operation completion flag + \arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus efuse_flag_get(uint32_t flag) +{ + if(EFUSE_STAT & (uint32_t)flag) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear EFUSE pending flag + \param[in] flag: specifies to clear a flag + only one parameter can be selected which is shown as below: + \arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR_CLR: clear illegal access error flag + \arg EFUSE_FLAG_PROGRAM_COMPLETE_CLR: clear programming operation completion flag + \arg EFUSE_FLAG_READ_COMPLETE_CLR: clear read operation completion flag + \arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR_CLR: clear program voltage setting error interrupt flag + \param[out] none + \retval none +*/ +void efuse_flag_clear(uint32_t flag) +{ + EFUSE_STATC |= (uint32_t)flag; +} + +/*! + \brief enable EFUSE interrupt + \param[in] interrupt: specifies an interrupt to enbale + only one parameter can be selected which is shown as below: + \arg EFUSE_INT_ILLEGAL_ACCESS_ERR: illegal access error interrupt + \arg EFUSE_INT_PROGRAM_COMPLETE: programming operation completion interrupt + \arg EFUSE_INT_READ_COMPLETE: read operation completion interrupt + \arg EFUSE_INT_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt + \param[out] none + \retval none +*/ +void efuse_interrupt_enable(uint32_t interrupt) +{ + EFUSE_CTL = (uint32_t)interrupt; +} + +/*! + \brief disable EFUSE interrupt + \param[in] interrupt: specifies an interrupt to disbale + only one parameter can be selected which is shown as below: + \arg EFUSE_INT_ILLEGAL_ACCESS_ERR: illegal access error interrupt + \arg EFUSE_INT_PROGRAM_COMPLETE: programming operation completion interrupt + \arg EFUSE_INT_READ_COMPLETE: read operation completion interrupt + \arg EFUSE_INT_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt + \param[out] none + \retval none +*/ +void efuse_interrupt_disable(uint32_t interrupt) +{ + EFUSE_CTL &= ~(uint32_t)interrupt; +} + +/*! + \brief check EFUSE interrupt flag is set or not + \param[in] int_flag: specifies to get a flag + only one parameter can be selected which is shown as below: + \arg EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR: illegal access error interrupt + \arg EFUSE_INT_FLAG_PROGRAM_COMPLETE: programming operation completion interrupt + \arg EFUSE_INT_FLAG_READ_COMPLETE: read operation completion interrupt + \arg EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus efuse_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (EFUSE_REG_VAL(int_flag) & BIT(EFUSE_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (EFUSE_REG_VAL2(int_flag) & BIT(EFUSE_BIT_POS2(int_flag))); + + if(flagstatus && intenable) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear EFUSE pending interrupt flag + \param[in] int_flag: specifies to clear a flag + only one parameter can be selected which is shown as below: + \arg EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR_CLR: clear illegal access error interrupt flag + \arg EFUSE_INT_FLAG_PROGRAM_COMPLETE_CLR: clear programming operation completion interrupt flag + \arg EFUSE_INT_FLAG_READ_COMPLETE_CLR: clear operation completion interrupt flag + \arg EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR_CLR: clear program voltage setting error interrupt flag + \param[out] none + \retval none +*/ +void efuse_interrupt_flag_clear(uint32_t int_flag) +{ + EFUSE_STATC |= (uint32_t)int_flag; +} + +/*! + \brief check whether EFUSE is ready or not + \param[in] flag: + only one parameter can be selected which is shown as below: + \arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR: illegal access error flag + \arg EFUSE_FLAG_PROGRAM_COMPLETE: programming operation completion flag + \arg EFUSE_FLAG_READ_COMPLETE: read operation completion flag + \arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error flag + \param[out] none + \retval state of EFUSE + \arg EFUSE_READY: EFUSE operation has been completed + \arg EFUSE_BUSY: EFUSE operation is in progress + \arg EFUSE_IAERR: illegal access error + \arg EFUSE_PVERR: program voltage setting error + \arg EFUSE_TOERR: EFUSE timeout error +*/ +static efuse_state_enum efuse_ready_wait(uint32_t efuse_flag, uint32_t timeout) +{ + efuse_state_enum efuse_state = EFUSE_BUSY; + + /* wait for EFUSE ready */ + do { + /* get EFUSE flag set or not */ + if(EFUSE_STAT & (uint32_t)efuse_flag) { + efuse_state = EFUSE_READY; + } else if(EFUSE_STAT & EFUSE_STAT_IAERRIF) { + efuse_state = EFUSE_IAERR; + } else if(EFUSE_STAT & EFUSE_STAT_PVIF) { + efuse_state = EFUSE_PVERR; + } else { + /* illegal parameters */ + } + timeout--; + } while((EFUSE_BUSY == efuse_state) && (0U != timeout)); + + if(EFUSE_BUSY == efuse_state) { + efuse_state = EFUSE_TOERR; + } + + /* return the EFUSE state */ + return efuse_state; +} + diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_enet.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_enet.c new file mode 100644 index 0000000000..99774f30b2 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_enet.c @@ -0,0 +1,3773 @@ +/*! + \file gd32h7xx_enet.c + \brief ENET driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_enet.h" +#include +#include + +#if defined(GD32H7XX) + +#if defined (__CC_ARM) /*!< ARM compiler */ +__attribute__((section(".ARM.__at_0x30000000"))) enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM]; /*!< ENET RxDMA descriptor */ +__attribute__((section(".ARM.__at_0x30000160"))) enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */ +__attribute__((section(".ARM.__at_0x30000300"))) uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive buffer */ +__attribute__((section(".ARM.__at_0x30002100"))) uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */ + +#elif defined ( __ICCARM__ ) /*!< IAR compiler */ +#pragma location=0x30000000 +enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM]; /*!< ENET RxDMA descriptor */ +#pragma location=0x30000160 +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */ +#pragma location=0x30000300 +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive buffer */ +#pragma location=0x30002100 +uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */ + +#elif defined (__GNUC__) /* GNU Compiler */ +enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM] __attribute__((section(".ARM.__at_0x30000000"))); /*!< ENET RxDMA descriptor */ +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM] __attribute__((section(".ARM.__at_0x30000160"))); /*!< ENET TxDMA descriptor */ +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE] __attribute__((section(".ARM.__at_0x30000300"))); /*!< ENET receive buffer */ +uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE] __attribute__((section(".ARM.__at_0x30002100"))); /*!< ENET transmit buffer */ + +#endif /* __CC_ARM */ + +/* global transmit and receive descriptors pointers */ +enet_descriptors_struct *dma_current_txdesc; +enet_descriptors_struct *dma_current_rxdesc; + +/* structure pointer of ptp descriptor for normal mode */ +enet_descriptors_struct *dma_current_ptp_txdesc = NULL; +enet_descriptors_struct *dma_current_ptp_rxdesc = NULL; + +/* init structure parameters for ENET initialization */ +static enet_initpara_struct enet_initpara = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U}; + +static uint32_t enet_unknow_err = 0U; +/* array of register offset for debug information get */ +static const uint16_t enet_reg_tab[] = { + 0x0000U, 0x0004U, 0x0008U, 0x000CU, 0x0010U, 0x0014U, 0x0018U, 0x001CU, 0x0028U, 0x002CU, 0x0034U, + + 0x0038U, 0x003CU, 0x0040U, 0x0044U, 0x0048U, 0x004CU, 0x0050U, 0x0054U, 0x0058U, 0x005CU, 0x1080U, + + 0x0100U, 0x0104U, 0x0108U, 0x010CU, 0x0110U, 0x014CU, 0x0150U, 0x0168U, 0x0194U, 0x0198U, 0x01C4U, + + 0x0700U, 0x0704U, 0x0708U, 0x070CU, 0x0710U, 0x0714U, 0x0718U, 0x071CU, 0x0720U, 0x0728U, 0x072CU, + + 0x1000U, 0x1004U, 0x1008U, 0x100CU, 0x1010U, 0x1014U, 0x1018U, 0x101CU, 0x1020U, 0x1024U, 0x1048U, + + 0x104CU, 0x1050U, 0x1054U +}; + +/* initialize ENET peripheral with generally concerned parameters, call it by enet_init() */ +static void enet_default_init(uint32_t enet_periph); +#ifndef USE_DELAY +/* insert a delay time */ +static void enet_delay(uint32_t ncount); +#endif /* USE_DELAY */ + +/*! + \brief deinitialize the ENET, and reset structure parameters for ENET initialization + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_deinit(uint32_t enet_periph) +{ + switch(enet_periph) { + case ENET0: + /* reset ENET0 */ + rcu_periph_reset_enable(RCU_ENET0RST); + rcu_periph_reset_disable(RCU_ENET0RST); + enet_initpara_reset(); + break; + case ENET1: + /* reset ENET1 */ + rcu_periph_reset_enable(RCU_ENET1RST); + rcu_periph_reset_disable(RCU_ENET1RST); + enet_initpara_reset(); + break; + default: + break; + } +} + +/*! + \brief configure the parameters which are usually less cared for initialization + note -- this function must be called before enet_init(), otherwise + configuration will be no effect + \param[in] option: different function option, which is related to several parameters, + only one parameter can be selected which is shown as below, refer to enet_option_enum + \arg FORWARD_OPTION: choose to configure the frame forward related parameters + \arg DMABUS_OPTION: choose to configure the DMA bus mode related parameters + \arg DMA_MAXBURST_OPTION: choose to configure the DMA max burst related parameters + \arg DMA_ARBITRATION_OPTION: choose to configure the DMA arbitration related parameters + \arg STORE_OPTION: choose to configure the store forward mode related parameters + \arg DMA_OPTION: choose to configure the DMA descriptor related parameters + \arg VLAN_OPTION: choose to configure vlan related parameters + \arg FLOWCTL_OPTION: choose to configure flow control related parameters + \arg HASHH_OPTION: choose to configure hash high + \arg HASHL_OPTION: choose to configure hash low + \arg FILTER_OPTION: choose to configure frame filter related parameters + \arg HALFDUPLEX_OPTION: choose to configure halfduplex mode related parameters + \arg TIMER_OPTION: choose to configure time counter related parameters + \arg INTERFRAMEGAP_OPTION: choose to configure the inter frame gap related parameters + \param[in] para: the related parameters according to the option + all the related parameters should be configured which are shown as below + FORWARD_OPTION related parameters: + - ENET_AUTO_PADCRC_DROP_ENABLE/ ENET_AUTO_PADCRC_DROP_DISABLE ; + - ENET_TYPEFRAME_CRC_DROP_ENABLE/ ENET_TYPEFRAME_CRC_DROP_DISABLE ; + - ENET_FORWARD_ERRFRAMES_ENABLE/ ENET_FORWARD_ERRFRAMES_DISABLE ; + - ENET_FORWARD_UNDERSZ_GOODFRAMES_ENABLE/ ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE . + DMABUS_OPTION related parameters: + - ENET_ADDRESS_ALIGN_ENABLE/ ENET_ADDRESS_ALIGN_DISABLE ; + - ENET_FIXED_BURST_ENABLE/ ENET_FIXED_BURST_DISABLE ; + - ENET_MIXED_BURST_ENABLE/ ENET_MIXED_BURST_DISABLE ; + DMA_MAXBURST_OPTION related parameters: + - ENET_RXDP_1BEAT/ ENET_RXDP_2BEAT/ ENET_RXDP_4BEAT/ + ENET_RXDP_8BEAT/ ENET_RXDP_16BEAT/ ENET_RXDP_32BEAT/ + ENET_RXDP_4xPGBL_4BEAT/ ENET_RXDP_4xPGBL_8BEAT/ + ENET_RXDP_4xPGBL_16BEAT/ ENET_RXDP_4xPGBL_32BEAT/ + ENET_RXDP_4xPGBL_64BEAT/ ENET_RXDP_4xPGBL_128BEAT ; + - ENET_PGBL_1BEAT/ ENET_PGBL_2BEAT/ ENET_PGBL_4BEAT/ + ENET_PGBL_8BEAT/ ENET_PGBL_16BEAT/ ENET_PGBL_32BEAT/ + ENET_PGBL_4xPGBL_4BEAT/ ENET_PGBL_4xPGBL_8BEAT/ + ENET_PGBL_4xPGBL_16BEAT/ ENET_PGBL_4xPGBL_32BEAT/ + ENET_PGBL_4xPGBL_64BEAT/ ENET_PGBL_4xPGBL_128BEAT ; + - ENET_RXTX_DIFFERENT_PGBL/ ENET_RXTX_SAME_PGBL ; + DMA_ARBITRATION_OPTION related parameters: + - ENET_ARBITRATION_RXPRIORTX + - ENET_ARBITRATION_RXTX_1_1/ ENET_ARBITRATION_RXTX_2_1/ + ENET_ARBITRATION_RXTX_3_1/ ENET_ARBITRATION_RXTX_4_1/. + STORE_OPTION related parameters: + - ENET_RX_MODE_STOREFORWARD/ ENET_RX_MODE_CUTTHROUGH ; + - ENET_TX_MODE_STOREFORWARD/ ENET_TX_MODE_CUTTHROUGH ; + - ENET_RX_THRESHOLD_64BYTES/ ENET_RX_THRESHOLD_32BYTES/ + ENET_RX_THRESHOLD_96BYTES/ ENET_RX_THRESHOLD_128BYTES ; + - ENET_TX_THRESHOLD_64BYTES/ ENET_TX_THRESHOLD_128BYTES/ + ENET_TX_THRESHOLD_192BYTES/ ENET_TX_THRESHOLD_256BYTES/ + ENET_TX_THRESHOLD_40BYTES/ ENET_TX_THRESHOLD_32BYTES/ + ENET_TX_THRESHOLD_24BYTES/ ENET_TX_THRESHOLD_16BYTES . + DMA_OPTION related parameters: + - ENET_FLUSH_RXFRAME_ENABLE/ ENET_FLUSH_RXFRAME_DISABLE ; + - ENET_SECONDFRAME_OPT_ENABLE/ ENET_SECONDFRAME_OPT_DISABLE ; + - ENET_ENHANCED_DESCRIPTOR/ ENET_NORMAL_DESCRIPTOR . + VLAN_OPTION related parameters: + - ENET_VLANTAGCOMPARISON_12BIT/ ENET_VLANTAGCOMPARISON_16BIT ; + - MAC_VLT_VLTI(regval) . + FLOWCTL_OPTION related parameters: + - MAC_FCTL_PTM(regval) ; + - ENET_ZERO_QUANTA_PAUSE_ENABLE/ ENET_ZERO_QUANTA_PAUSE_DISABLE ; + - ENET_PAUSETIME_MINUS4/ ENET_PAUSETIME_MINUS28/ + ENET_PAUSETIME_MINUS144/ENET_PAUSETIME_MINUS256 ; + - ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT/ ENET_UNIQUE_PAUSEDETECT ; + - ENET_RX_FLOWCONTROL_ENABLE/ ENET_RX_FLOWCONTROL_DISABLE ; + - ENET_TX_FLOWCONTROL_ENABLE/ ENET_TX_FLOWCONTROL_DISABLE ; + - ENET_ACTIVE_THRESHOLD_256BYTES/ ENET_ACTIVE_THRESHOLD_512BYTES ; + - ENET_ACTIVE_THRESHOLD_768BYTES/ ENET_ACTIVE_THRESHOLD_1024BYTES ; + - ENET_ACTIVE_THRESHOLD_1280BYTES/ ENET_ACTIVE_THRESHOLD_1536BYTES ; + - ENET_ACTIVE_THRESHOLD_1792BYTES ; + - ENET_DEACTIVE_THRESHOLD_256BYTES/ ENET_DEACTIVE_THRESHOLD_512BYTES ; + - ENET_DEACTIVE_THRESHOLD_768BYTES/ ENET_DEACTIVE_THRESHOLD_1024BYTES ; + - ENET_DEACTIVE_THRESHOLD_1280BYTES/ ENET_DEACTIVE_THRESHOLD_1536BYTES ; + - ENET_DEACTIVE_THRESHOLD_1792BYTES . + HASHH_OPTION related parameters: + - 0x0~0xFFFF FFFFU + HASHL_OPTION related parameters: + - 0x0~0xFFFF FFFFU + FILTER_OPTION related parameters: + - ENET_SRC_FILTER_NORMAL_ENABLE/ ENET_SRC_FILTER_INVERSE_ENABLE/ + ENET_SRC_FILTER_DISABLE ; + - ENET_DEST_FILTER_INVERSE_ENABLE/ ENET_DEST_FILTER_INVERSE_DISABLE ; + - ENET_MULTICAST_FILTER_HASH_OR_PERFECT/ ENET_MULTICAST_FILTER_HASH/ + ENET_MULTICAST_FILTER_PERFECT/ ENET_MULTICAST_FILTER_NONE ; + - ENET_UNICAST_FILTER_EITHER/ ENET_UNICAST_FILTER_HASH/ + ENET_UNICAST_FILTER_PERFECT ; + - ENET_PCFRM_PREVENT_ALL/ ENET_PCFRM_PREVENT_PAUSEFRAME/ + ENET_PCFRM_FORWARD_ALL/ ENET_PCFRM_FORWARD_FILTERED . + HALFDUPLEX_OPTION related parameters: + - ENET_CARRIERSENSE_ENABLE/ ENET_CARRIERSENSE_DISABLE ; + - ENET_RECEIVEOWN_ENABLE/ ENET_RECEIVEOWN_DISABLE ; + - ENET_RETRYTRANSMISSION_ENABLE/ ENET_RETRYTRANSMISSION_DISABLE ; + - ENET_BACKOFFLIMIT_10/ ENET_BACKOFFLIMIT_8/ + ENET_BACKOFFLIMIT_4/ ENET_BACKOFFLIMIT_1 ; + - ENET_DEFERRALCHECK_ENABLE/ ENET_DEFERRALCHECK_DISABLE . + TIMER_OPTION related parameters: + - ENET_WATCHDOG_ENABLE/ ENET_WATCHDOG_DISABLE ; + - ENET_JABBER_ENABLE/ ENET_JABBER_DISABLE ; + INTERFRAMEGAP_OPTION related parameters: + - ENET_INTERFRAMEGAP_96BIT/ ENET_INTERFRAMEGAP_88BIT/ + ENET_INTERFRAMEGAP_80BIT/ ENET_INTERFRAMEGAP_72BIT/ + ENET_INTERFRAMEGAP_64BIT/ ENET_INTERFRAMEGAP_56BIT/ + ENET_INTERFRAMEGAP_48BIT/ ENET_INTERFRAMEGAP_40BIT . + \param[out] none + \retval none +*/ +void enet_initpara_config(enet_option_enum option, uint32_t para) +{ + switch(option) { + case FORWARD_OPTION: + /* choose to configure forward_frame, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)FORWARD_OPTION; + enet_initpara.forward_frame = para; + break; + case DMABUS_OPTION: + /* choose to configure dmabus_mode, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMABUS_OPTION; + enet_initpara.dmabus_mode = para; + break; + case DMA_MAXBURST_OPTION: + /* choose to configure dma_maxburst, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMA_MAXBURST_OPTION; + enet_initpara.dma_maxburst = para; + break; + case DMA_ARBITRATION_OPTION: + /* choose to configure dma_arbitration, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMA_ARBITRATION_OPTION; + enet_initpara.dma_arbitration = para; + break; + case STORE_OPTION: + /* choose to configure store_forward_mode, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)STORE_OPTION; + enet_initpara.store_forward_mode = para; + break; + case DMA_OPTION: + /* choose to configure dma_function, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)DMA_OPTION; + +#ifndef SELECT_DESCRIPTORS_ENHANCED_MODE + para &= ~ENET_ENHANCED_DESCRIPTOR; +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + + enet_initpara.dma_function = para; + break; + case VLAN_OPTION: + /* choose to configure vlan_config, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)VLAN_OPTION; + enet_initpara.vlan_config = para; + break; + case FLOWCTL_OPTION: + /* choose to configure flow_control, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)FLOWCTL_OPTION; + enet_initpara.flow_control = para; + break; + case HASHH_OPTION: + /* choose to configure hashtable_high, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)HASHH_OPTION; + enet_initpara.hashtable_high = para; + break; + case HASHL_OPTION: + /* choose to configure hashtable_low, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)HASHL_OPTION; + enet_initpara.hashtable_low = para; + break; + case FILTER_OPTION: + /* choose to configure framesfilter_mode, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)FILTER_OPTION; + enet_initpara.framesfilter_mode = para; + break; + case HALFDUPLEX_OPTION: + /* choose to configure halfduplex_param, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)HALFDUPLEX_OPTION; + enet_initpara.halfduplex_param = para; + break; + case TIMER_OPTION: + /* choose to configure timer_config, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)TIMER_OPTION; + enet_initpara.timer_config = para; + break; + case INTERFRAMEGAP_OPTION: + /* choose to configure interframegap, and save the configuration parameters */ + enet_initpara.option_enable |= (uint32_t)INTERFRAMEGAP_OPTION; + enet_initpara.interframegap = para; + break; + default: + break; + } +} + +/*! + \brief initialize ENET peripheral with generally concerned parameters and the less cared + parameters + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mediamode: PHY mode and mac loopback configurations, only one parameter can be selected + which is shown as below, refer to enet_mediamode_enum + \arg ENET_AUTO_NEGOTIATION: PHY auto negotiation + \arg ENET_100M_FULLDUPLEX: 100Mbit/s, full-duplex + \arg ENET_100M_HALFDUPLEX: 100Mbit/s, half-duplex + \arg ENET_10M_FULLDUPLEX: 10Mbit/s, full-duplex + \arg ENET_10M_HALFDUPLEX: 10Mbit/s, half-duplex + \arg ENET_LOOPBACKMODE: MAC in loopback mode at the MII + \param[in] checksum: IP frame checksum offload function, only one parameter can be selected + which is shown as below, refer to enet_mediamode_enum + \arg ENET_NO_AUTOCHECKSUM: disable IP frame checksum function + \arg ENET_AUTOCHECKSUM_DROP_FAILFRAMES: enable IP frame checksum function + \arg ENET_AUTOCHECKSUM_ACCEPT_FAILFRAMES: enable IP frame checksum function, and the received frame + with only payload error but no other errors will not be dropped + \param[in] recept: frame filter function, only one parameter can be selected + which is shown as below, refer to enet_frmrecept_enum + \arg ENET_PROMISCUOUS_MODE: promiscuous mode enabled + \arg ENET_RECEIVEALL: all received frame are forwarded to application + \arg ENET_BROADCAST_FRAMES_PASS: the address filters pass all received broadcast frames + \arg ENET_BROADCAST_FRAMES_DROP: the address filters filter all incoming broadcast frames + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_init(uint32_t enet_periph, enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept) +{ + uint32_t reg_value = 0U, reg_temp = 0U, temp = 0U; + uint32_t media_temp = 0U; + uint32_t timeout = 0U; + uint16_t phy_value = 0U; + ErrStatus phy_state = ERROR, enet_state = ERROR; + + /* PHY interface configuration, configure SMI clock and reset PHY chip */ + if(ERROR == enet_phy_config(enet_periph)) { + _ENET_DELAY_(PHY_RESETDELAY); + if(ERROR == enet_phy_config(enet_periph)) { + return enet_state; + } + } + /* initialize ENET peripheral with generally concerned parameters */ + enet_default_init(enet_periph); + + /* 1st, configure mediamode */ + media_temp = (uint32_t)mediamode; + /* if is PHY auto negotiation */ + if((uint32_t)ENET_AUTO_NEGOTIATION == media_temp) { + /* wait for PHY_LINKED_STATUS bit be set */ + do { + enet_phy_write_read(enet_periph, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); + phy_value &= PHY_LINKED_STATUS; + timeout++; + } while((RESET == phy_value) && (timeout < PHY_READ_TO)); + /* return ERROR due to timeout */ + if(PHY_READ_TO == timeout) { + return enet_state; + } + /* reset timeout counter */ + timeout = 0U; + + /* enable auto-negotiation */ + phy_value = PHY_AUTONEGOTIATION; + phy_state = enet_phy_write_read(enet_periph, ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); + if(!phy_state) { + /* return ERROR due to write timeout */ + return enet_state; + } + + /* wait for the PHY_AUTONEGO_COMPLETE bit be set */ + do { + enet_phy_write_read(enet_periph, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); + phy_value &= PHY_AUTONEGO_COMPLETE; + timeout++; + } while((RESET == phy_value) && (timeout < (uint32_t)PHY_READ_TO)); + /* return ERROR due to timeout */ + if(PHY_READ_TO == timeout) { + return enet_state; + } + /* reset timeout counter */ + timeout = 0U; + + /* read the result of the auto-negotiation */ + enet_phy_write_read(enet_periph, ENET_PHY_READ, PHY_ADDRESS, PHY_SR, &phy_value); + /* configure the duplex mode of MAC following the auto-negotiation result */ + if((uint16_t)RESET != (phy_value & PHY_DUPLEX_STATUS)) { + media_temp = ENET_MODE_FULLDUPLEX; + } else { + media_temp = ENET_MODE_HALFDUPLEX; + } + /* configure the communication speed of MAC following the auto-negotiation result */ + if((uint16_t)RESET != (phy_value & PHY_SPEED_STATUS)) { + media_temp |= ENET_SPEEDMODE_10M; + } else { + media_temp |= ENET_SPEEDMODE_100M; + } + } else { + phy_value = (uint16_t)((media_temp & ENET_MAC_CFG_DPM) >> 3U); + phy_value |= (uint16_t)((media_temp & ENET_MAC_CFG_SPD) >> 1U); + phy_state = enet_phy_write_read(enet_periph, ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); + if(!phy_state) { + /* return ERROR due to write timeout */ + return enet_state; + } + /* PHY configuration need some time */ + _ENET_DELAY_(PHY_CONFIGDELAY); + } + /* after configuring the PHY, use mediamode to configure registers */ + reg_value = ENET_MAC_CFG(enet_periph); + /* configure ENET_MAC_CFG register */ + reg_value &= (~(ENET_MAC_CFG_SPD | ENET_MAC_CFG_DPM | ENET_MAC_CFG_LBM)); + reg_value |= media_temp; + ENET_MAC_CFG(enet_periph) = reg_value; + + /* 2st, configure checksum */ + if(RESET != ((uint32_t)checksum & ENET_CHECKSUMOFFLOAD_ENABLE)) { + ENET_MAC_CFG(enet_periph) |= ENET_CHECKSUMOFFLOAD_ENABLE; + + reg_value = ENET_DMA_CTL(enet_periph); + /* configure ENET_DMA_CTL register */ + reg_value &= ~ENET_DMA_CTL_DTCERFD; + reg_value |= ((uint32_t)checksum & ENET_DMA_CTL_DTCERFD); + ENET_DMA_CTL(enet_periph) = reg_value; + } + + /* 3rd, configure recept */ + ENET_MAC_FRMF(enet_periph) |= (uint32_t)recept; + + /* 4th, configure different function options */ + /* configure forward_frame related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)FORWARD_OPTION)) { + reg_temp = enet_initpara.forward_frame; + + reg_value = ENET_MAC_CFG(enet_periph); + temp = reg_temp; + /* configure ENET_MAC_CFG register */ + reg_value &= (~(ENET_MAC_CFG_TFCD | ENET_MAC_CFG_APCD)); + temp &= (ENET_MAC_CFG_TFCD | ENET_MAC_CFG_APCD); + reg_value |= temp; + ENET_MAC_CFG(enet_periph) = reg_value; + + reg_value = ENET_DMA_CTL(enet_periph); + temp = reg_temp; + /* configure ENET_DMA_CTL register */ + reg_value &= (~(ENET_DMA_CTL_FERF | ENET_DMA_CTL_FUF)); + temp &= ((ENET_DMA_CTL_FERF | ENET_DMA_CTL_FUF) << 2U); + reg_value |= (temp >> 2U); + ENET_DMA_CTL(enet_periph) = reg_value; + } + + /* configure dmabus_mode related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMABUS_OPTION)) { + temp = enet_initpara.dmabus_mode; + + reg_value = ENET_DMA_BCTL(enet_periph); + /* configure ENET_DMA_BCTL register */ + reg_value &= ~(ENET_DMA_BCTL_AA | ENET_DMA_BCTL_FB \ + | ENET_DMA_BCTL_FPBL | ENET_DMA_BCTL_MB); + reg_value |= temp; + ENET_DMA_BCTL(enet_periph) = reg_value; + } + + /* configure dma_maxburst related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_MAXBURST_OPTION)) { + temp = enet_initpara.dma_maxburst; + + reg_value = ENET_DMA_BCTL(enet_periph); + /* configure ENET_DMA_BCTL register */ + reg_value &= ~(ENET_DMA_BCTL_RXDP | ENET_DMA_BCTL_PGBL | ENET_DMA_BCTL_UIP); + reg_value |= temp; + ENET_DMA_BCTL(enet_periph) = reg_value; + } + + /* configure dma_arbitration related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_ARBITRATION_OPTION)) { + temp = enet_initpara.dma_arbitration; + + reg_value = ENET_DMA_BCTL(enet_periph); + /* configure ENET_DMA_BCTL register */ + reg_value &= ~(ENET_DMA_BCTL_RTPR | ENET_DMA_BCTL_DAB); + reg_value |= temp; + ENET_DMA_BCTL(enet_periph) = reg_value; + } + + /* configure store_forward_mode related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)STORE_OPTION)) { + temp = enet_initpara.store_forward_mode; + + reg_value = ENET_DMA_CTL(enet_periph); + /* configure ENET_DMA_CTL register */ + reg_value &= ~(ENET_DMA_CTL_RSFD | ENET_DMA_CTL_TSFD | ENET_DMA_CTL_RTHC | ENET_DMA_CTL_TTHC); + reg_value |= temp; + ENET_DMA_CTL(enet_periph) = reg_value; + } + + /* configure dma_function related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_OPTION)) { + reg_temp = enet_initpara.dma_function; + + reg_value = ENET_DMA_CTL(enet_periph); + temp = reg_temp; + /* configure ENET_DMA_CTL register */ + reg_value &= (~(ENET_DMA_CTL_DAFRF | ENET_DMA_CTL_OSF)); + temp &= (ENET_DMA_CTL_DAFRF | ENET_DMA_CTL_OSF); + reg_value |= temp; + ENET_DMA_CTL(enet_periph) = reg_value; + + reg_value = ENET_DMA_BCTL(enet_periph); + temp = reg_temp; + /* configure ENET_DMA_BCTL register */ + reg_value &= (~ENET_DMA_BCTL_DFM); + temp &= ENET_DMA_BCTL_DFM; + reg_value |= temp; + ENET_DMA_BCTL(enet_periph) = reg_value; + } + + /* configure vlan_config related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)VLAN_OPTION)) { + reg_temp = enet_initpara.vlan_config; + + reg_value = ENET_MAC_VLT(enet_periph); + /* configure ENET_MAC_VLT register */ + reg_value &= ~(ENET_MAC_VLT_VLTI | ENET_MAC_VLT_VLTC); + reg_value |= reg_temp; + ENET_MAC_VLT(enet_periph) = reg_value; + } + + /* configure flow_control related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)FLOWCTL_OPTION)) { + reg_temp = enet_initpara.flow_control; + + reg_value = ENET_MAC_FCTL(enet_periph); + temp = reg_temp; + /* configure ENET_MAC_FCTL register */ + reg_value &= ~(ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_DZQP | ENET_MAC_FCTL_PLTS \ + | ENET_MAC_FCTL_UPFDT | ENET_MAC_FCTL_RFCEN | ENET_MAC_FCTL_TFCEN); + temp &= (ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_DZQP | ENET_MAC_FCTL_PLTS \ + | ENET_MAC_FCTL_UPFDT | ENET_MAC_FCTL_RFCEN | ENET_MAC_FCTL_TFCEN); + reg_value |= temp; + ENET_MAC_FCTL(enet_periph) = reg_value; + + reg_value = ENET_MAC_FCTH(enet_periph); + temp = reg_temp; + /* configure ENET_MAC_FCTH register */ + reg_value &= ~(ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD); + temp &= ((ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD) << 8U); + reg_value |= (temp >> 8U); + ENET_MAC_FCTH(enet_periph) = reg_value; + } + + /* configure hashtable_high related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHH_OPTION)) { + ENET_MAC_HLH(enet_periph) = enet_initpara.hashtable_high; + } + + /* configure hashtable_low related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHL_OPTION)) { + ENET_MAC_HLL(enet_periph) = enet_initpara.hashtable_low; + } + + /* configure framesfilter_mode related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)FILTER_OPTION)) { + reg_temp = enet_initpara.framesfilter_mode; + + reg_value = ENET_MAC_FRMF(enet_periph); + /* configure ENET_MAC_FRMF register */ + reg_value &= ~(ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT | ENET_MAC_FRMF_DAIFLT \ + | ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT | ENET_MAC_FRMF_MFD \ + | ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_PCFRM); + reg_value |= reg_temp; + ENET_MAC_FRMF(enet_periph) = reg_value; + } + + /* configure halfduplex_param related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HALFDUPLEX_OPTION)) { + reg_temp = enet_initpara.halfduplex_param; + + reg_value = ENET_MAC_CFG(enet_periph); + /* configure ENET_MAC_CFG register */ + reg_value &= ~(ENET_MAC_CFG_CSD | ENET_MAC_CFG_ROD | ENET_MAC_CFG_RTD \ + | ENET_MAC_CFG_BOL | ENET_MAC_CFG_DFC); + reg_value |= reg_temp; + ENET_MAC_CFG(enet_periph) = reg_value; + } + + /* configure timer_config related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)TIMER_OPTION)) { + reg_temp = enet_initpara.timer_config; + + reg_value = ENET_MAC_CFG(enet_periph); + /* configure ENET_MAC_CFG register */ + reg_value &= ~(ENET_MAC_CFG_WDD | ENET_MAC_CFG_JBD); + reg_value |= reg_temp; + ENET_MAC_CFG(enet_periph) = reg_value; + } + + /* configure interframegap related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)INTERFRAMEGAP_OPTION)) { + reg_temp = enet_initpara.interframegap; + + reg_value = ENET_MAC_CFG(enet_periph); + /* configure ENET_MAC_CFG register */ + reg_value &= ~ENET_MAC_CFG_IGBS; + reg_value |= reg_temp; + ENET_MAC_CFG(enet_periph) = reg_value; + } + + enet_state = SUCCESS; + return enet_state; +} + +/*! + \brief reset all core internal registers located in CLK_TX and CLK_RX + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_software_reset(uint32_t enet_periph) +{ + uint32_t timeout = 0U; + ErrStatus enet_state = ERROR; + uint32_t dma_flag; + + /* reset all core internal registers located in CLK_TX and CLK_RX */ + ENET_DMA_BCTL(enet_periph) |= ENET_DMA_BCTL_SWR; + + /* wait for reset operation complete */ + do { + dma_flag = (ENET_DMA_BCTL(enet_periph) & ENET_DMA_BCTL_SWR); + timeout++; + } while((RESET != dma_flag) && (ENET_DELAY_TO != timeout)); + + /* reset operation complete */ + if(RESET == (ENET_DMA_BCTL(enet_periph) & ENET_DMA_BCTL_SWR)) { + enet_state = SUCCESS; + } + + return enet_state; +} + +/*! + \brief check receive frame valid and return frame size + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval size of received frame: 0x0 - 0x3FFF +*/ +uint32_t enet_rxframe_size_get(uint32_t enet_periph) +{ + uint32_t size = 0U; + uint32_t status; + + /* get rdes0 information of current RxDMA descriptor */ + status = dma_current_rxdesc->status; + + /* if the desciptor is owned by DMA */ + if((uint32_t)RESET != (status & ENET_RDES0_DAV)) { + return 0U; + } + + /* if has any error, or the frame uses two or more descriptors */ + if((((uint32_t)RESET) != (status & ENET_RDES0_ERRS)) || + (((uint32_t)RESET) == (status & ENET_RDES0_LDES)) || + (((uint32_t)RESET) == (status & ENET_RDES0_FDES))) { + /* drop current receive frame */ + enet_rxframe_drop(enet_periph); + + return 1U; + } +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE + /* if is an ethernet-type frame, and IP frame payload error occurred */ + if(((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FRMT) && + ((uint32_t)RESET) != (dma_current_rxdesc->extended_status & ENET_RDES4_IPPLDERR)) { + /* drop current receive frame */ + enet_rxframe_drop(enet_periph); + + return 1U; + } +#else + /* if is an ethernet-type frame, and IP frame payload error occurred */ + if((((uint32_t)RESET) != (status & ENET_RDES0_FRMT)) && + (((uint32_t)RESET) != (status & ENET_RDES0_PCERR))) { + /* drop current receive frame */ + enet_rxframe_drop(enet_periph); + + return 1U; + } +#endif + /* if CPU owns current descriptor, no error occured, the frame uses only one descriptor */ + if((((uint32_t)RESET) == (status & ENET_RDES0_DAV)) && + (((uint32_t)RESET) == (status & ENET_RDES0_ERRS)) && + (((uint32_t)RESET) != (status & ENET_RDES0_LDES)) && + (((uint32_t)RESET) != (status & ENET_RDES0_FDES))) { + /* get the size of the received data including CRC */ + size = GET_RDES0_FRML(status); + /* substract the CRC size */ + size = size - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG(enet_periph) & ENET_MAC_CFG_TFCD)) && (RESET != (status & ENET_RDES0_FRMT))) { + size = size + 4U; + } + } else { + enet_unknow_err++; + enet_rxframe_drop(enet_periph); + + return 1U; + } + + /* return packet size */ + return size; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in chain mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_descriptors_chain_init(uint32_t enet_periph, enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* if want to initialize DMA Tx descriptors */ + if(ENET_DMA_TX == direction) { + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select chain mode */ + desc_status = ENET_TDES0_TCHM; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + } else { + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive chained mode and set buffer1 size */ + desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + dma_current_ptp_rxdesc = NULL; + dma_current_ptp_txdesc = NULL; + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* if is not the last descriptor */ + if(num < (count - 1U)) { + /* configure the next descriptor address */ + desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); + } else { + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t) desc_tab; + } + } +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in ring mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_descriptors_ring_init(uint32_t enet_periph, enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc; + enet_descriptors_struct *desc_tab; + uint8_t *buf; + + /* configure descriptor skip length */ + ENET_DMA_BCTL(enet_periph) &= ~ENET_DMA_BCTL_DPSL; + ENET_DMA_BCTL(enet_periph) |= DMA_BCTL_DPSL(0); + + /* if want to initialize DMA Tx descriptors */ + if(ENET_DMA_TX == direction) { + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + } else { + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* set buffer1 size */ + desc_bufsize = ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + dma_current_ptp_rxdesc = NULL; + dma_current_ptp_txdesc = NULL; + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* when it is the last descriptor */ + if(num == (count - 1U)) { + if(ENET_DMA_TX == direction) { + /* configure transmit end of ring mode */ + desc->status |= ENET_TDES0_TERM; + } else { + /* configure receive end of ring mode */ + desc->control_buffer_size |= ENET_RDES1_RERM; + } + } + } +} + +/*! + \brief handle current received frame data to application buffer + \param[in] enet_periph: ENETx(x=0,1) + \param[in] bufsize: the size of buffer which is the parameter in function + \param[out] buffer: pointer to the received frame data + note -- if the input is NULL, user should copy data in application by himself + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_frame_receive(uint32_t enet_periph, uint8_t buffer[], uint32_t bufsize) +{ + uint32_t offset = 0U, size = 0U; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)) { + return ERROR; + } + + /* if buffer pointer is null, indicates that users has copied data in application */ + if(NULL != buffer) { + /* if no error occurs, and the frame uses only one descriptor */ + if((((uint32_t)RESET) == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FDES))) { + /* get the frame length except CRC */ + size = GET_RDES0_FRML(dma_current_rxdesc->status); + size = size - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG(enet_periph) & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))) { + size = size + 4U; + } + + /* to avoid situation that the frame size exceeds the buffer length */ + if(size > bufsize) { + return ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0U; offset < size; offset++) { + (*(buffer + offset)) = (*(__IO uint8_t *)(uint32_t)((dma_current_rxdesc->buffer1_addr) + offset)); + } + + } else { + /* return ERROR */ + return ERROR; + } + } + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if((uint32_t)RESET != (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_RBU)) { + /* clear RBU flag */ + ENET_DMA_STAT(enet_periph) = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN(enet_periph) = 0U; + } + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_rxdesc->buffer2_next_desc_addr); + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR(enet_periph)); + } else { + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL( + enet_periph)))); + } + } + + return SUCCESS; +} + +/*! + \brief handle application buffer data to transmit it + \param[in] enet_periph: ENETx(x=0,1) + \param[in] buffer: pointer to the frame data to be transmitted, + note -- if the input is NULL, user should handle the data in application by himself + \param[in] length: the length of frame data to be transmitted + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_frame_transmit(uint32_t enet_periph, uint8_t buffer[], uint32_t length) +{ + uint32_t offset = 0U; + uint32_t dma_tbu_flag, dma_tu_flag; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)) { + return ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE) { + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer) { + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0U; offset < length; offset++) { + (*(__IO uint8_t *)(uint32_t)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + + /* set the frame length */ + dma_current_txdesc->control_buffer_size = length; + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + dma_tbu_flag = (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_TU); + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { + /* clear TBU and TU flag */ + ENET_DMA_STAT(enet_periph) = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN(enet_periph) = 0U; + } + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)) { + dma_current_txdesc = (enet_descriptors_struct *)(dma_current_txdesc->buffer2_next_desc_addr); + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)) { + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct *)(ENET_DMA_TDTADDR(enet_periph)); + } else { + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_txdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL( + enet_periph)))); + } + } + + return SUCCESS; +} + +/*! + \brief configure the transmit IP frame checksum offload calculation and insertion + \param[in] desc: the descriptor pointer which users want to configure + \param[in] checksum: IP frame checksum configuration + only one parameter can be selected which is shown as below + \arg ENET_CHECKSUM_DISABLE: checksum insertion disabled + \arg ENET_CHECKSUM_IPV4HEADER: only IP header checksum calculation and insertion are enabled + \arg ENET_CHECKSUM_TCPUDPICMP_SEGMENT: TCP/UDP/ICMP checksum insertion calculated but pseudo-header + \arg ENET_CHECKSUM_TCPUDPICMP_FULL: TCP/UDP/ICMP checksum insertion fully calculated + \param[out] none + \retval ErrStatus: ERROR, SUCCESS +*/ +ErrStatus enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum) +{ + if(NULL != desc) { + desc->status &= ~ENET_TDES0_CM; + desc->status |= checksum; + return SUCCESS; + } else { + return ERROR; + } +} + +/*! + \brief ENET Tx and Rx function enable (include MAC and DMA module) + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_enable(uint32_t enet_periph) +{ + enet_tx_enable(enet_periph); + enet_rx_enable(enet_periph); +} + +/*! + \brief ENET Tx and Rx function disable (include MAC and DMA module) + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_disable(uint32_t enet_periph) +{ + enet_tx_disable(enet_periph); + enet_rx_disable(enet_periph); +} + +/*! + \brief configure MAC address + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mac_addr: select which MAC address will be set, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS0: set MAC address 0 filter + \arg ENET_MAC_ADDRESS1: set MAC address 1 filter + \arg ENET_MAC_ADDRESS2: set MAC address 2 filter + \arg ENET_MAC_ADDRESS3: set MAC address 3 filter + \param[in] paddr: the buffer pointer which stores the MAC address + (little-ending store, such as MAC address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) + \param[out] none + \retval none +*/ +void enet_mac_address_set(uint32_t enet_periph, enet_macaddress_enum mac_addr, uint8_t paddr[]) +{ + REG32(ENET_ADDRH_BASE(enet_periph) + (uint32_t)mac_addr) = ENET_SET_MACADDRH(paddr); + REG32(ENET_ADDRL_BASE(enet_periph) + (uint32_t)mac_addr) = ENET_SET_MACADDRL(paddr); +} + +/*! + \brief get MAC address + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mac_addr: select which MAC address will be get, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS0: get MAC address 0 filter + \arg ENET_MAC_ADDRESS1: get MAC address 1 filter + \arg ENET_MAC_ADDRESS2: get MAC address 2 filter + \arg ENET_MAC_ADDRESS3: get MAC address 3 filter + \param[out] paddr: the buffer pointer which is stored the MAC address + (little-ending store, such as mac address is aa:bb:cc:dd:ee:22, the buffer is {22, ee, dd, cc, bb, aa}) + \param[in] bufsize: refer to the size of the buffer which stores the MAC address + \arg 6 - 255 + \retval ErrStatus: ERROR, SUCCESS +*/ +ErrStatus enet_mac_address_get(uint32_t enet_periph, enet_macaddress_enum mac_addr, uint8_t paddr[], uint8_t bufsize) +{ + if(bufsize < 6U) { + return ERROR; + } + paddr[0] = ENET_GET_MACADDR(enet_periph, mac_addr, 0U); + paddr[1] = ENET_GET_MACADDR(enet_periph, mac_addr, 1U); + paddr[2] = ENET_GET_MACADDR(enet_periph, mac_addr, 2U); + paddr[3] = ENET_GET_MACADDR(enet_periph, mac_addr, 3U); + paddr[4] = ENET_GET_MACADDR(enet_periph, mac_addr, 4U); + paddr[5] = ENET_GET_MACADDR(enet_periph, mac_addr, 5U); + return SUCCESS; +} + +/*! + \brief ENET Tx function enable (include MAC and DMA module) + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_tx_enable(uint32_t enet_periph) +{ + ENET_MAC_CFG(enet_periph) |= ENET_MAC_CFG_TEN; + enet_txfifo_flush(enet_periph); + ENET_DMA_CTL(enet_periph) |= ENET_DMA_CTL_STE; +} + +/*! + \brief ENET Tx function disable (include MAC and DMA module) + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_tx_disable(uint32_t enet_periph) +{ + ENET_DMA_CTL(enet_periph) &= ~ENET_DMA_CTL_STE; + enet_txfifo_flush(enet_periph); + ENET_MAC_CFG(enet_periph) &= ~ENET_MAC_CFG_TEN; +} + +/*! + \brief ENET Rx function enable (include MAC and DMA module) + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_rx_enable(uint32_t enet_periph) +{ + ENET_MAC_CFG(enet_periph) |= ENET_MAC_CFG_REN; + ENET_DMA_CTL(enet_periph) |= ENET_DMA_CTL_SRE; +} + +/*! + \brief ENET Rx function disable (include MAC and DMA module) + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_rx_disable(uint32_t enet_periph) +{ + ENET_DMA_CTL(enet_periph) &= ~ENET_DMA_CTL_SRE; + ENET_MAC_CFG(enet_periph) &= ~ENET_MAC_CFG_REN; +} + +/*! + \brief put registers value into the application buffer + \param[in] enet_periph: ENETx(x=0,1) + \param[in] type: register type which will be get, refer to enet_registers_type_enum, + only one parameter can be selected which is shown as below + \arg ALL_MAC_REG: get the registers within the offset scope between ENET_MAC_CFG and ENET_MAC_FCTH + \arg ALL_MSC_REG: get the registers within the offset scope between ENET_MSC_CTL and ENET_MSC_RGUFCNT + \arg ALL_PTP_REG: get the registers within the offset scope between ENET_PTP_TSCTL and ENET_PTP_PPSCTL + \arg ALL_DMA_REG: get the registers within the offset scope between ENET_DMA_BCTL and ENET_DMA_CRBADDR + \param[in] num: the number of registers that the user want to get + \param[out] preg: the application buffer pointer for storing the register value + \retval none +*/ +void enet_registers_get(uint32_t enet_periph, enet_registers_type_enum type, uint32_t *preg, uint32_t num) +{ + uint32_t offset = 0U, max = 0U, limit = 0U; + + offset = (uint32_t)type; + max = (uint32_t)type + num; + limit = sizeof(enet_reg_tab) / sizeof(uint16_t); + + /* prevent element in this array is out of range */ + if(max > limit) { + max = limit; + } + + for(; offset < max; offset++) { + /* get value of the corresponding register */ + *preg = REG32((enet_periph) + enet_reg_tab[offset]); + preg++; + } +} + +/*! + \brief get the enet debug status from the debug register + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mac_debug: enet debug status, + only one parameter can be selected which is shown as below + \arg ENET_MAC_RECEIVER_NOT_IDLE: MAC receiver is not in idle state + \arg ENET_RX_ASYNCHRONOUS_FIFO_STATE: Rx asynchronous FIFO status + \arg ENET_RXFIFO_WRITING: RxFIFO is doing write operation + \arg ENET_RXFIFO_READ_STATUS: RxFIFO read operation status + \arg ENET_RXFIFO_STATE: RxFIFO state + \arg ENET_MAC_TRANSMITTER_NOT_IDLE: MAC transmitter is not in idle state + \arg ENET_MAC_TRANSMITTER_STATUS: status of MAC transmitter + \arg ENET_PAUSE_CONDITION_STATUS: pause condition status + \arg ENET_TXFIFO_READ_STATUS: TxFIFO read operation status + \arg ENET_TXFIFO_WRITING: TxFIFO is doing write operation + \arg ENET_TXFIFO_NOT_EMPTY: TxFIFO is not empty + \arg ENET_TXFIFO_FULL: TxFIFO is full + \param[out] none + \retval value of the status users want to get +*/ +uint32_t enet_debug_status_get(uint32_t enet_periph, uint32_t mac_debug) +{ + uint32_t temp_state = 0U; + + switch(mac_debug) { + case ENET_RX_ASYNCHRONOUS_FIFO_STATE: + temp_state = GET_MAC_DBG_RXAFS(ENET_MAC_DBG(enet_periph)); + break; + case ENET_RXFIFO_READ_STATUS: + temp_state = GET_MAC_DBG_RXFRS(ENET_MAC_DBG(enet_periph)); + break; + case ENET_RXFIFO_STATE: + temp_state = GET_MAC_DBG_RXFS(ENET_MAC_DBG(enet_periph)); + break; + case ENET_MAC_TRANSMITTER_STATUS: + temp_state = GET_MAC_DBG_SOMT(ENET_MAC_DBG(enet_periph)); + break; + case ENET_TXFIFO_READ_STATUS: + temp_state = GET_MAC_DBG_TXFRS(ENET_MAC_DBG(enet_periph)); + break; + default: + if(RESET != (ENET_MAC_DBG(enet_periph) & mac_debug)) { + temp_state = 0x00000001U; + } + break; + } + return temp_state; +} + +/*! + \brief enable the MAC address filter + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mac_addr: select which MAC address will be enable + \arg ENET_MAC_ADDRESS1: enable MAC address 1 filter + \arg ENET_MAC_ADDRESS2: enable MAC address 2 filter + \arg ENET_MAC_ADDRESS3: enable MAC address 3 filter + \param[out] none + \retval none +*/ +void enet_address_filter_enable(uint32_t enet_periph, enet_macaddress_enum mac_addr) +{ + REG32(ENET_ADDRH_BASE(enet_periph) + mac_addr) |= ENET_MAC_ADDR1H_AFE; +} + +/*! + \brief disable the MAC address filter + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mac_addr: select which MAC address will be disable, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS1: disable MAC address 1 filter + \arg ENET_MAC_ADDRESS2: disable MAC address 2 filter + \arg ENET_MAC_ADDRESS3: disable MAC address 3 filter + \param[out] none + \retval none +*/ +void enet_address_filter_disable(uint32_t enet_periph, enet_macaddress_enum mac_addr) +{ + REG32(ENET_ADDRH_BASE(enet_periph) + mac_addr) &= ~ENET_MAC_ADDR1H_AFE; +} + +/*! + \brief configure the MAC address filter + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mac_addr: select which MAC address will be configured, + only one parameter can be selected which is shown as below + \arg ENET_MAC_ADDRESS1: configure MAC address 1 filter + \arg ENET_MAC_ADDRESS2: configure MAC address 2 filter + \arg ENET_MAC_ADDRESS3: configure MAC address 3 filter + \param[in] addr_mask: select which MAC address bytes will be mask, + one or more parameters can be selected which are shown as below + \arg ENET_ADDRESS_MASK_BYTE0: mask ENET_MAC_ADDR1L[7:0] bits + \arg ENET_ADDRESS_MASK_BYTE1: mask ENET_MAC_ADDR1L[15:8] bits + \arg ENET_ADDRESS_MASK_BYTE2: mask ENET_MAC_ADDR1L[23:16] bits + \arg ENET_ADDRESS_MASK_BYTE3: mask ENET_MAC_ADDR1L [31:24] bits + \arg ENET_ADDRESS_MASK_BYTE4: mask ENET_MAC_ADDR1H [7:0] bits + \arg ENET_ADDRESS_MASK_BYTE5: mask ENET_MAC_ADDR1H [15:8] bits + \param[in] filter_type: select which MAC address filter type will be selected, + only one parameter can be selected which is shown as below + \arg ENET_ADDRESS_FILTER_SA: The MAC address is used to compared with the SA field of the received frame + \arg ENET_ADDRESS_FILTER_DA: The MAC address is used to compared with the DA field of the received frame + \param[out] none + \retval none +*/ +void enet_address_filter_config(uint32_t enet_periph, enet_macaddress_enum mac_addr, uint32_t addr_mask, uint32_t filter_type) +{ + uint32_t reg; + + /* get the address filter register value which is to be configured */ + reg = REG32(ENET_ADDRH_BASE(enet_periph) + mac_addr); + + /* clear and configure the address filter register */ + reg &= ~(ENET_MAC_ADDR1H_MB | ENET_MAC_ADDR1H_SAF); + reg |= (addr_mask | filter_type); + REG32(ENET_ADDRH_BASE(enet_periph) + mac_addr) = reg; +} + +/*! + \brief PHY interface configuration (configure SMI clock and reset PHY chip) + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_phy_config(uint32_t enet_periph) +{ + uint32_t ahbclk; + uint32_t reg; + uint16_t phy_value; + ErrStatus enet_state = ERROR; + + /* clear the previous MDC clock */ + reg = ENET_MAC_PHY_CTL(enet_periph); + reg &= ~ENET_MAC_PHY_CTL_CLR; + + /* get the HCLK frequency */ + ahbclk = rcu_clock_freq_get(CK_AHB); + + /* configure MDC clock according to HCLK frequency range */ + if(ENET_RANGE(ahbclk, 20000000U, 35000000U)) { + reg |= ENET_MDC_HCLK_DIV16; + } else if(ENET_RANGE(ahbclk, 35000000U, 60000000U)) { + reg |= ENET_MDC_HCLK_DIV26; + } else if(ENET_RANGE(ahbclk, 60000000U, 100000000U)) { + reg |= ENET_MDC_HCLK_DIV42; + } else if(ENET_RANGE(ahbclk, 100000000U, 150000000U)) { + reg |= ENET_MDC_HCLK_DIV62; + } else if(ENET_RANGE(ahbclk, 150000000U, 250000000U)) { + reg |= ENET_MDC_HCLK_DIV102; + } else if(ENET_RANGE(ahbclk, 250000000U, 300000000U)) { + reg |= ENET_MDC_HCLK_DIV124; + } else if(ENET_RANGE(ahbclk, 300000000U, 350000000U)) { + reg |= ENET_MDC_HCLK_DIV142; + } else if((ENET_RANGE(ahbclk, 350000000U, 400000000U)) || (400000000U == ahbclk)) { + reg |= ENET_MDC_HCLK_DIV162; + } else { + return enet_state; + } + + ENET_MAC_PHY_CTL(enet_periph) = reg; + + /* reset PHY */ + phy_value = PHY_RESET; + if(ERROR == (enet_phy_write_read(enet_periph, ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value))){ + return enet_state; + } + /* PHY reset need some time */ + _ENET_DELAY_(ENET_DELAY_TO); + + /* check whether PHY reset is complete */ + if(ERROR == (enet_phy_write_read(enet_periph, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value))) { + return enet_state; + } + + /* PHY reset complete */ + if(RESET == (phy_value & PHY_RESET)) { + enet_state = SUCCESS; + } + + return enet_state; +} + +/*! + \brief write to / read from a PHY register + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: only one parameter can be selected which is shown as below + \arg ENET_PHY_WRITE: write data to phy register + \arg ENET_PHY_READ: read data from phy register + \param[in] phy_address: 0x0 - 0x1F + \param[in] phy_reg: 0x0 - 0x1F + \param[in] pvalue: the value will be written to the PHY register in ENET_PHY_WRITE direction + \param[out] pvalue: the value will be read from the PHY register in ENET_PHY_READ direction + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_phy_write_read(uint32_t enet_periph, enet_phydirection_enum direction, uint16_t phy_address, uint16_t phy_reg, uint16_t *pvalue) +{ + uint32_t reg, phy_flag; + uint32_t timeout = 0U; + ErrStatus enet_state = ERROR; + + /* configure ENET_MAC_PHY_CTL with write/read operation */ + reg = ENET_MAC_PHY_CTL(enet_periph); + reg &= ~(ENET_MAC_PHY_CTL_PB | ENET_MAC_PHY_CTL_PW | ENET_MAC_PHY_CTL_PR | ENET_MAC_PHY_CTL_PA); + reg |= (direction | MAC_PHY_CTL_PR(phy_reg) | MAC_PHY_CTL_PA(phy_address) | ENET_MAC_PHY_CTL_PB); + + /* if do the write operation, write value to the register */ + if(ENET_PHY_WRITE == direction) { + ENET_MAC_PHY_DATA(enet_periph) = *pvalue; + } + + /* do PHY write/read operation, and wait the operation complete */ + ENET_MAC_PHY_CTL(enet_periph) = reg; + do { + phy_flag = (ENET_MAC_PHY_CTL(enet_periph) & ENET_MAC_PHY_CTL_PB); + timeout++; + } while((RESET != phy_flag) && (ENET_DELAY_TO != timeout)); + + /* write/read operation complete */ + if(RESET == (ENET_MAC_PHY_CTL(enet_periph) & ENET_MAC_PHY_CTL_PB)) { + enet_state = SUCCESS; + } + + /* if do the read operation, get value from the register */ + if(ENET_PHY_READ == direction) { + *pvalue = (uint16_t)ENET_MAC_PHY_DATA(enet_periph); + } + + return enet_state; +} + +/*! + \brief enable the loopback function of PHY chip + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_phyloopback_enable(uint32_t enet_periph) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = ERROR; + + /* get the PHY configuration to update it */ + enet_phy_write_read(enet_periph, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + /* enable the PHY loopback mode */ + temp_phy |= PHY_LOOPBACK; + + /* update the PHY control register with the new configuration */ + phy_state = enet_phy_write_read(enet_periph, ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + return phy_state; +} + +/*! + \brief disable the loopback function of PHY chip + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_phyloopback_disable(uint32_t enet_periph) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = ERROR; + + /* get the PHY configuration to update it */ + enet_phy_write_read(enet_periph, ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + /* disable the PHY loopback mode */ + temp_phy &= (uint16_t)~PHY_LOOPBACK; + + /* update the PHY control register with the new configuration */ + phy_state = enet_phy_write_read(enet_periph, ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + return phy_state; +} + +/*! + \brief enable ENET forward feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET forward mode, + one or more parameters can be selected which are shown as below + \arg ENET_AUTO_PADCRC_DROP: the function of the MAC strips the Pad/FCS field on received frames + \arg ENET_TYPEFRAME_CRC_DROP: the function that FCS field(last 4 bytes) of frame will be dropped before forwarding + \arg ENET_FORWARD_ERRFRAMES: the function that all frame received with error except runt error are forwarded to memory + \arg ENET_FORWARD_UNDERSZ_GOODFRAMES: the function that forwarding undersized good frames + \param[out] none + \retval none +*/ +void enet_forward_feature_enable(uint32_t enet_periph, uint32_t feature) +{ + uint32_t mask; + + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); + ENET_MAC_CFG(enet_periph) |= mask; + + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); + ENET_DMA_CTL(enet_periph) |= (mask >> 2U); +} + +/*! + \brief disable ENET forward feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET forward mode, + one or more parameters can be selected which are shown as below + \arg ENET_AUTO_PADCRC_DROP: the function of the MAC strips the Pad/FCS field on received frames + \arg ENET_TYPEFRAME_CRC_DROP: the function that FCS field(last 4 bytes) of frame will be dropped before forwarding + \arg ENET_FORWARD_ERRFRAMES: the function that all frame received with error except runt error are forwarded to memory + \arg ENET_FORWARD_UNDERSZ_GOODFRAMES: the function that forwarding undersized good frames + \param[out] none + \retval none +*/ +void enet_forward_feature_disable(uint32_t enet_periph, uint32_t feature) +{ + uint32_t mask; + + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); + ENET_MAC_CFG(enet_periph) &= ~mask; + + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); + ENET_DMA_CTL(enet_periph) &= ~(mask >> 2U); +} + +/*! + \brief enable ENET fliter feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET fliter mode, + one or more parameters can be selected which are shown as below + \arg ENET_SRC_FILTER: filter source address function + \arg ENET_SRC_FILTER_INVERSE: inverse source address filtering result function + \arg ENET_DEST_FILTER_INVERSE: inverse DA filtering result function + \arg ENET_MULTICAST_FILTER_PASS: pass all multicast frames function + \arg ENET_MULTICAST_FILTER_HASH_MODE: HASH multicast filter function + \arg ENET_UNICAST_FILTER_HASH_MODE: HASH unicast filter function + \arg ENET_FILTER_MODE_EITHER: HASH or perfect filter function + \param[out] none + \retval none +*/ +void enet_fliter_feature_enable(uint32_t enet_periph, uint32_t feature) +{ + ENET_MAC_FRMF(enet_periph) |= feature; +} + +/*! + \brief disable ENET fliter feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET fliter mode, + one or more parameters can be selected which are shown as below + \arg ENET_SRC_FILTER: filter source address function + \arg ENET_SRC_FILTER_INVERSE: inverse source address filtering result function + \arg ENET_DEST_FILTER_INVERSE: inverse DA filtering result function + \arg ENET_MULTICAST_FILTER_PASS: pass all multicast frames function + \arg ENET_MULTICAST_FILTER_HASH_MODE: HASH multicast filter function + \arg ENET_UNICAST_FILTER_HASH_MODE: HASH unicast filter function + \arg ENET_FILTER_MODE_EITHER: HASH or perfect filter function + \param[out] none + \retval none +*/ +void enet_fliter_feature_disable(uint32_t enet_periph, uint32_t feature) +{ + ENET_MAC_FRMF(enet_periph) &= ~feature; +} + +/*! + \brief generate the pause frame, ENET will send pause frame after enable transmit flow control + this function only use in full-dulex mode + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_pauseframe_generate(uint32_t enet_periph) +{ + ErrStatus enet_state = ERROR; + uint32_t temp = 0U; + + /* in full-duplex mode, must make sure this bit is 0 before writing register */ + temp = ENET_MAC_FCTL(enet_periph) & ENET_MAC_FCTL_FLCBBKPA; + if(RESET == temp) { + ENET_MAC_FCTL(enet_periph) |= ENET_MAC_FCTL_FLCBBKPA; + enet_state = SUCCESS; + } + return enet_state; +} + +/*! + \brief configure the pause frame detect type + \param[in] enet_periph: ENETx(x=0,1) + \param[in] detect: pause frame detect type, + only one parameter can be selected which is shown as below + \arg ENET_MAC0_AND_UNIQUE_ADDRESS_PAUSEDETECT: besides the unique multicast address, MAC can also + use the MAC0 address to detecting pause frame + \arg ENET_UNIQUE_PAUSEDETECT: only the unique multicast address for pause frame which is specified + in IEEE802.3 can be detected + \param[out] none + \retval none +*/ +void enet_pauseframe_detect_config(uint32_t enet_periph, uint32_t detect) +{ + ENET_MAC_FCTL(enet_periph) &= ~ENET_MAC_FCTL_UPFDT; + ENET_MAC_FCTL(enet_periph) |= detect; +} + +/*! + \brief configure the pause frame parameters + \param[in] enet_periph: ENETx(x=0,1) + \param[in] pausetime: pause time in transmit pause control frame + \param[in] pause_threshold: the threshold of the pause timer for retransmitting frames automatically, + this value must make sure to be less than configured pause time, only one parameter can be + selected which is shown as below + \arg ENET_PAUSETIME_MINUS4: pause time minus 4 slot times + \arg ENET_PAUSETIME_MINUS28: pause time minus 28 slot times + \arg ENET_PAUSETIME_MINUS144: pause time minus 144 slot times + \arg ENET_PAUSETIME_MINUS256: pause time minus 256 slot times + \param[out] none + \retval none +*/ +void enet_pauseframe_config(uint32_t enet_periph, uint32_t pausetime, uint32_t pause_threshold) +{ + ENET_MAC_FCTL(enet_periph) &= ~(ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_PLTS); + ENET_MAC_FCTL(enet_periph) |= (MAC_FCTL_PTM(pausetime) | pause_threshold); +} + +/*! + \brief configure the threshold of the flow control(deactive and active threshold) + \param[in] enet_periph: ENETx(x=0,1) + \param[in] deactive: the threshold of the deactive flow control, this value + should always be less than active flow control value, only one + parameter can be selected which is shown as below + \arg ENET_DEACTIVE_THRESHOLD_256BYTES: threshold level is 256 bytes + \arg ENET_DEACTIVE_THRESHOLD_512BYTES: threshold level is 512 bytes + \arg ENET_DEACTIVE_THRESHOLD_768BYTES: threshold level is 768 bytes + \arg ENET_DEACTIVE_THRESHOLD_1024BYTES: threshold level is 1024 bytes + \arg ENET_DEACTIVE_THRESHOLD_1280BYTES: threshold level is 1280 bytes + \arg ENET_DEACTIVE_THRESHOLD_1536BYTES: threshold level is 1536 bytes + \arg ENET_DEACTIVE_THRESHOLD_1792BYTES: threshold level is 1792 bytes + \param[in] active: the threshold of the active flow control, only one parameter + can be selected which is shown as below + \arg ENET_ACTIVE_THRESHOLD_256BYTES: threshold level is 256 bytes + \arg ENET_ACTIVE_THRESHOLD_512BYTES: threshold level is 512 bytes + \arg ENET_ACTIVE_THRESHOLD_768BYTES: threshold level is 768 bytes + \arg ENET_ACTIVE_THRESHOLD_1024BYTES: threshold level is 1024 bytes + \arg ENET_ACTIVE_THRESHOLD_1280BYTES: threshold level is 1280 bytes + \arg ENET_ACTIVE_THRESHOLD_1536BYTES: threshold level is 1536 bytes + \arg ENET_ACTIVE_THRESHOLD_1792BYTES: threshold level is 1792 bytes + \param[out] none + \retval none +*/ +void enet_flowcontrol_threshold_config(uint32_t enet_periph, uint32_t deactive, uint32_t active) +{ + ENET_MAC_FCTH(enet_periph) = ((deactive | active) >> 8U); +} + +/*! + \brief enable ENET flow control feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET flow control mode + one or more parameters can be selected which are shown as below + \arg ENET_ZERO_QUANTA_PAUSE: the automatic zero-quanta generation function + \arg ENET_TX_FLOWCONTROL: the flow control operation in the MAC + \arg ENET_RX_FLOWCONTROL: decoding function for the received pause frame and process it + \arg ENET_BACK_PRESSURE: back pressure operation in the MAC(only use in half-dulex mode) + \param[out] none + \retval none +*/ +void enet_flowcontrol_feature_enable(uint32_t enet_periph, uint32_t feature) +{ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)) { + ENET_MAC_FCTL(enet_periph) &= ~ENET_ZERO_QUANTA_PAUSE; + } + feature &= ~ENET_ZERO_QUANTA_PAUSE; + ENET_MAC_FCTL(enet_periph) |= feature; +} + +/*! + \brief disable ENET flow control feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET flow control mode + one or more parameters can be selected which are shown as below + \arg ENET_ZERO_QUANTA_PAUSE: the automatic zero-quanta generation function + \arg ENET_TX_FLOWCONTROL: the flow control operation in the MAC + \arg ENET_RX_FLOWCONTROL: decoding function for the received pause frame and process it + \arg ENET_BACK_PRESSURE: back pressure operation in the MAC(only use in half-dulex mode) + \param[out] none + \retval none +*/ +void enet_flowcontrol_feature_disable(uint32_t enet_periph, uint32_t feature) +{ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)) { + ENET_MAC_FCTL(enet_periph) |= ENET_ZERO_QUANTA_PAUSE; + } + feature &= ~ENET_ZERO_QUANTA_PAUSE; + ENET_MAC_FCTL(enet_periph) &= ~feature; +} + +/*! + \brief get the dma transmit/receive process state + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: choose the direction of dma process which users want to check, + refer to enet_dmadirection_enum, only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: dma transmit process + \arg ENET_DMA_RX: dma receive process + \param[out] none + \retval state of dma process, the value range shows below: + ENET_RX_STATE_STOPPED, ENET_RX_STATE_FETCHING, ENET_RX_STATE_WAITING, + ENET_RX_STATE_SUSPENDED, ENET_RX_STATE_CLOSING, ENET_RX_STATE_QUEUING, + ENET_TX_STATE_STOPPED, ENET_TX_STATE_FETCHING, ENET_TX_STATE_WAITING, + ENET_TX_STATE_READING, ENET_TX_STATE_SUSPENDED, ENET_TX_STATE_CLOSING +*/ +uint32_t enet_dmaprocess_state_get(uint32_t enet_periph, enet_dmadirection_enum direction) +{ + uint32_t reval; + reval = (uint32_t)(ENET_DMA_STAT(enet_periph) & (uint32_t)direction); + return reval; +} + +/*! + \brief poll the DMA transmission/reception enable by writing any value to the + ENET_DMA_TPEN/ENET_DMA_RPEN register, this will make the DMA to resume transmission/reception + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: choose the direction of DMA process which users want to resume, + refer to enet_dmadirection_enum, only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA transmit process + \arg ENET_DMA_RX: DMA receive process + \param[out] none + \retval none +*/ +void enet_dmaprocess_resume(uint32_t enet_periph, enet_dmadirection_enum direction) +{ + if(ENET_DMA_TX == direction) { + ENET_DMA_TPEN(enet_periph) = 0U; + } else { + ENET_DMA_RPEN(enet_periph) = 0U; + } +} + +/*! + \brief check and recover the Rx process + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_rxprocess_check_recovery(uint32_t enet_periph) +{ + uint32_t status; + + /* get DAV information of current RxDMA descriptor */ + status = dma_current_rxdesc->status; + status &= ENET_RDES0_DAV; + + /* if current descriptor is owned by DMA, but the descriptor address mismatches with + receive descriptor address pointer updated by RxDMA controller */ + if((ENET_DMA_CRDADDR(enet_periph) != ((uint32_t)dma_current_rxdesc)) && + (ENET_RDES0_DAV == status)) { + dma_current_rxdesc = (enet_descriptors_struct *)ENET_DMA_CRDADDR(enet_periph); + } +} + +/*! + \brief flush the ENET transmit FIFO, and wait until the flush operation completes + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus enet_txfifo_flush(uint32_t enet_periph) +{ + uint32_t flush_state; + uint32_t timeout = 0U; + ErrStatus enet_state = ERROR; + + /* set the FTF bit for flushing transmit FIFO */ + ENET_DMA_CTL(enet_periph) |= ENET_DMA_CTL_FTF; + /* wait until the flush operation completes */ + do { + flush_state = ENET_DMA_CTL(enet_periph) & ENET_DMA_CTL_FTF; + timeout++; + } while((RESET != flush_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(RESET == flush_state) { + enet_state = SUCCESS; + } + + return enet_state; +} + +/*! + \brief get the transmit/receive address of current descriptor, or current buffer, or descriptor table + \param[in] enet_periph: ENETx(x=0,1) + \param[in] addr_get: choose the address which users want to get, refer to enet_desc_reg_enum, + only one parameter can be selected which is shown as below + \arg ENET_RX_DESC_TABLE: the start address of the receive descriptor table + \arg ENET_RX_CURRENT_DESC: the start descriptor address of the current receive descriptor read by + the RxDMA controller + \arg ENET_RX_CURRENT_BUFFER: the current receive buffer address being read by the RxDMA controller + \arg ENET_TX_DESC_TABLE: the start address of the transmit descriptor table + \arg ENET_TX_CURRENT_DESC: the start descriptor address of the current transmit descriptor read by + the TxDMA controller + \arg ENET_TX_CURRENT_BUFFER: the current transmit buffer address being read by the TxDMA controller + \param[out] none + \retval address value +*/ +uint32_t enet_current_desc_address_get(uint32_t enet_periph, enet_desc_reg_enum addr_get) +{ + uint32_t reval = 0U; + + reval = REG32((enet_periph) + (uint32_t)addr_get); + return reval; +} + +/*! + \brief get the Tx or Rx descriptor information + \param[in] enet_periph: ENETx(x=0,1) + \param[in] desc: the descriptor pointer which users want to get information + \param[in] info_get: the descriptor information type which is selected, + only one parameter can be selected which is shown as below + \arg RXDESC_BUFFER_1_SIZE: receive buffer 1 size + \arg RXDESC_BUFFER_2_SIZE: receive buffer 2 size + \arg RXDESC_FRAME_LENGTH: the byte length of the received frame that was transferred to the buffer + \arg TXDESC_COLLISION_COUNT: the number of collisions occurred before the frame was transmitted + \arg RXDESC_BUFFER_1_ADDR: the buffer1 address of the Rx frame + \arg TXDESC_BUFFER_1_ADDR: the buffer1 address of the Tx frame + \param[out] none + \retval descriptor information, if value is 0xFFFFFFFFU, means the false input parameter +*/ +uint32_t enet_desc_information_get(uint32_t enet_periph, enet_descriptors_struct *desc, enet_descstate_enum info_get) +{ + uint32_t reval = 0xFFFFFFFFU; + + switch(info_get) { + case RXDESC_BUFFER_1_SIZE: + reval = GET_RDES1_RB1S(desc->control_buffer_size); + break; + case RXDESC_BUFFER_2_SIZE: + reval = GET_RDES1_RB2S(desc->control_buffer_size); + break; + case RXDESC_FRAME_LENGTH: + reval = GET_RDES0_FRML(desc->status); + if(reval > 4U) { + reval = reval - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG(enet_periph) & ENET_MAC_CFG_TFCD)) && (RESET != (desc->status & ENET_RDES0_FRMT))) { + reval = reval + 4U; + } + } else { + reval = 0U; + } + + break; + case RXDESC_BUFFER_1_ADDR: + reval = desc->buffer1_addr; + break; + case TXDESC_BUFFER_1_ADDR: + reval = desc->buffer1_addr; + break; + case TXDESC_COLLISION_COUNT: + reval = GET_TDES0_COCNT(desc->status); + break; + default: + break; + } + return reval; +} + +/*! + \brief get the number of missed frames during receiving + \param[in] enet_periph: ENETx(x=0,1) + \param[out] rxfifo_drop: pointer to the number of frames dropped by RxFIFO + \param[out] rxdma_drop: pointer to the number of frames missed by the RxDMA controller + \retval none +*/ +void enet_missed_frame_counter_get(uint32_t enet_periph, uint32_t *rxfifo_drop, uint32_t *rxdma_drop) +{ + uint32_t temp_counter = 0U; + + temp_counter = ENET_DMA_MFBOCNT(enet_periph); + *rxfifo_drop = GET_DMA_MFBOCNT_MSFA(temp_counter); + *rxdma_drop = GET_DMA_MFBOCNT_MSFC(temp_counter); +} + +/*! + \brief get the bit flag of ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to get flag + \param[in] desc_flag: the bit flag of ENET DMA descriptor, + only one parameter can be selected which is shown as below + \arg ENET_TDES0_DB: deferred + \arg ENET_TDES0_UFE: underflow error + \arg ENET_TDES0_EXD: excessive deferral + \arg ENET_TDES0_VFRM: VLAN frame + \arg ENET_TDES0_ECO: excessive collision + \arg ENET_TDES0_LCO: late collision + \arg ENET_TDES0_NCA: no carrier + \arg ENET_TDES0_LCA: loss of carrier + \arg ENET_TDES0_IPPE: IP payload error + \arg ENET_TDES0_FRMF: frame flushed + \arg ENET_TDES0_JT: jabber timeout + \arg ENET_TDES0_ES: error summary + \arg ENET_TDES0_IPHE: IP header error + \arg ENET_TDES0_TTMSS: transmit timestamp status + \arg ENET_TDES0_TCHM: the second address chained mode + \arg ENET_TDES0_TERM: transmit end of ring mode + \arg ENET_TDES0_TTSEN: transmit timestamp function enable + \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DCRC: disable CRC + \arg ENET_TDES0_FSG: first segment + \arg ENET_TDES0_LSG: last segment + \arg ENET_TDES0_INTC: interrupt on completion + \arg ENET_TDES0_DAV: DAV bit + \arg ENET_RDES0_PCERR: payload checksum error + \arg ENET_RDES0_EXSV: extended status valid + \arg ENET_RDES0_CERR: CRC error + \arg ENET_RDES0_DBERR: dribble bit error + \arg ENET_RDES0_RERR: receive error + \arg ENET_RDES0_RWDT: receive watchdog timeout + \arg ENET_RDES0_FRMT: frame type + \arg ENET_RDES0_LCO: late collision + \arg ENET_RDES0_IPHERR: IP frame header error + \arg ENET_RDES0_TSV: timestamp valid + \arg ENET_RDES0_LDES: last descriptor + \arg ENET_RDES0_FDES: first descriptor + \arg ENET_RDES0_VTAG: VLAN tag + \arg ENET_RDES0_OERR: overflow error + \arg ENET_RDES0_LERR: length error + \arg ENET_RDES0_SAFF: SA filter fail + \arg ENET_RDES0_DERR: descriptor error + \arg ENET_RDES0_ERRS: error summary + \arg ENET_RDES0_DAFF: destination address filter fail + \arg ENET_RDES0_DAV: descriptor available + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus enet_desc_flag_get(enet_descriptors_struct *desc, uint32_t desc_flag) +{ + FlagStatus enet_flag = RESET; + + if((uint32_t)RESET != (desc->status & desc_flag)) { + enet_flag = SET; + } + + return enet_flag; +} + +/*! + \brief set the bit flag of ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to set flag + \param[in] desc_flag: the bit flag of ENET DMA descriptor, + only one parameter can be selected which is shown as below + \arg ENET_TDES0_VFRM: VLAN frame + \arg ENET_TDES0_FRMF: frame flushed + \arg ENET_TDES0_TCHM: the second address chained mode + \arg ENET_TDES0_TERM: transmit end of ring mode + \arg ENET_TDES0_TTSEN: transmit timestamp function enable + \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DCRC: disable CRC + \arg ENET_TDES0_FSG: first segment + \arg ENET_TDES0_LSG: last segment + \arg ENET_TDES0_INTC: interrupt on completion + \arg ENET_TDES0_DAV: DAV bit + \arg ENET_RDES0_DAV: descriptor available + \param[out] none + \retval none +*/ +void enet_desc_flag_set(enet_descriptors_struct *desc, uint32_t desc_flag) +{ + desc->status |= desc_flag; +} + +/*! + \brief clear the bit flag of ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to clear flag + \param[in] desc_flag: the bit flag of ENET DMA descriptor, + only one parameter can be selected which is shown as below + \arg ENET_TDES0_VFRM: VLAN frame + \arg ENET_TDES0_FRMF: frame flushed + \arg ENET_TDES0_TCHM: the second address chained mode + \arg ENET_TDES0_TERM: transmit end of ring mode + \arg ENET_TDES0_TTSEN: transmit timestamp function enable + \arg ENET_TDES0_DPAD: disable adding pad + \arg ENET_TDES0_DCRC: disable CRC + \arg ENET_TDES0_FSG: first segment + \arg ENET_TDES0_LSG: last segment + \arg ENET_TDES0_INTC: interrupt on completion + \arg ENET_TDES0_DAV: DAV bit + \arg ENET_RDES0_DAV: descriptor available + \param[out] none + \retval none +*/ +void enet_desc_flag_clear(enet_descriptors_struct *desc, uint32_t desc_flag) +{ + desc->status &= ~desc_flag; +} + +/*! + \brief when receiving completed, set RS bit in ENET_DMA_STAT register will immediately set + \param[in] desc: the descriptor pointer which users want to configure + \param[out] none + \retval none +*/ +void enet_rx_desc_immediate_receive_complete_interrupt(enet_descriptors_struct *desc) +{ + desc->control_buffer_size &= ~ENET_RDES1_DINTC; +} + +/*! + \brief when receiving completed, set RS bit in ENET_DMA_STAT register will is set after a configurable delay time + \param[in] enet_periph: ENETx(x=0,1) + \param[in] desc: the descriptor pointer which users want to configure + \param[in] delay_time: delay a time of 256*delay_time HCLK, this value must be between 0 and 0xFF + \param[out] none + \retval none +*/ +void enet_rx_desc_delay_receive_complete_interrupt(uint32_t enet_periph, enet_descriptors_struct *desc, uint32_t delay_time) +{ + desc->control_buffer_size |= ENET_RDES1_DINTC; + ENET_DMA_RSWDC(enet_periph) = DMA_RSWDC_WDCFRS(delay_time); +} + +/*! + \brief drop current receive frame + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_rxframe_drop(uint32_t enet_periph) +{ + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + if(NULL != dma_current_ptp_rxdesc) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0U != dma_current_ptp_rxdesc->status) { + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); + } else { + /* ponter to the next ptp descriptor */ + dma_current_ptp_rxdesc++; + } + } else { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_rxdesc->buffer2_next_desc_addr); + } + + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR(enet_periph)); + if(NULL != dma_current_ptp_rxdesc) { + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); + } + } else { + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL( + enet_periph))); + if(NULL != dma_current_ptp_rxdesc) { + dma_current_ptp_rxdesc++; + } + } + } +} + +/*! + \brief enable DMA feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of DMA mode, + one or more parameters can be selected which are shown as below + \arg ENET_NO_FLUSH_RXFRAME: RxDMA does not flushes frames function + \arg ENET_SECONDFRAME_OPT: TxDMA controller operate on second frame function + \param[out] none + \retval none +*/ +void enet_dma_feature_enable(uint32_t enet_periph, uint32_t feature) +{ + ENET_DMA_CTL(enet_periph) |= feature; +} + +/*! + \brief disable DMA feature + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of DMA mode, + one or more parameters can be selected which are shown as below + \arg ENET_NO_FLUSH_RXFRAME: RxDMA does not flushes frames function + \arg ENET_SECONDFRAME_OPT: TxDMA controller operate on second frame function + \param[out] none + \retval none +*/ +void enet_dma_feature_disable(uint32_t enet_periph, uint32_t feature) +{ + ENET_DMA_CTL(enet_periph) &= ~feature; +} + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE +/*! + \brief get the bit of extended status flag in ENET DMA descriptor + \param[in] desc: the descriptor pointer which users want to get the extended status flag + \param[in] desc_status: the extended status want to get, + only one parameter can be selected which is shown as below + \arg ENET_RDES4_IPPLDT: IP frame payload type + \arg ENET_RDES4_IPHERR: IP frame header error + \arg ENET_RDES4_IPPLDERR: IP frame payload error + \arg ENET_RDES4_IPCKSB: IP frame checksum bypassed + \arg ENET_RDES4_IPF4: IP frame in version 4 + \arg ENET_RDES4_IPF6: IP frame in version 6 + \arg ENET_RDES4_PTPMT: PTP message type + \arg ENET_RDES4_PTPOEF: PTP on ethernet frame + \arg ENET_RDES4_PTPVF: PTP version format + \param[out] none + \retval value of extended status +*/ +uint32_t enet_rx_desc_enhanced_status_get(enet_descriptors_struct *desc, uint32_t desc_status) +{ + uint32_t reval = 0xFFFFFFFFU; + + switch(desc_status) { + case ENET_RDES4_IPPLDT: + reval = GET_RDES4_IPPLDT(desc->extended_status); + break; + case ENET_RDES4_PTPMT: + reval = GET_RDES4_PTPMT(desc->extended_status); + break; + default: + if((uint32_t)RESET != (desc->extended_status & desc_status)) { + reval = 1U; + } else { + reval = 0U; + } + } + + return reval; +} + +/*! + \brief configure descriptor to work in enhanced mode + \param[in] none + \param[out] none + \retval none +*/ +void enet_desc_select_enhanced_mode(uint32_t enet_periph) +{ + ENET_DMA_BCTL(enet_periph) |= ENET_DMA_BCTL_DFM; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in enhanced chain mode with ptp function + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_ptp_enhanced_descriptors_chain_init(uint32_t enet_periph, enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* if want to initialize DMA Tx descriptors */ + if(ENET_DMA_TX == direction) { + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select chain mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + } else { + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive chained mode and set buffer1 size */ + desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + + /* configuration each descriptor */ + for(num = 0U; num < count; num++) { + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* if is not the last descriptor */ + if(num < (count - 1U)) { + /* configure the next descriptor address */ + desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); + } else { + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t)desc_tab; + } + } +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in enhanced ring mode with ptp function + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[out] none + \retval none +*/ +void enet_ptp_enhanced_descriptors_ring_init(uint32_t enet_periph, enet_dmadirection_enum direction) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc; + enet_descriptors_struct *desc_tab; + uint8_t *buf; + + /* configure descriptor skip length */ + ENET_DMA_BCTL(enet_periph) &= ~ENET_DMA_BCTL_DPSL; + ENET_DMA_BCTL(enet_periph) |= DMA_BCTL_DPSL(0); + + /* if want to initialize DMA Tx descriptors */ + if(ENET_DMA_TX == direction) { + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select ring mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + } else { + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* set buffer1 size */ + desc_bufsize = ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + } + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* when it is the last descriptor */ + if(num == (count - 1U)) { + if(ENET_DMA_TX == direction) { + /* configure transmit end of ring mode */ + desc->status |= ENET_TDES0_TERM; + } else { + /* configure receive end of ring mode */ + desc->control_buffer_size |= ENET_RDES1_RERM; + } + } + } +} + +/*! + \brief receive a packet data with timestamp values to application buffer, when the DMA is in enhanced mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] bufsize: the size of buffer which is the parameter in function + \param[out] buffer: pointer to the application buffer + note -- if the input is NULL, user should copy data in application by himself + \param[out] timestamp: pointer to the table which stores the timestamp high and low + note -- if the input is NULL, timestamp is ignored + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_receive_enhanced_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t bufsize, uint32_t timestamp[]) +{ + uint32_t offset = 0U, size = 0U; + uint32_t timeout = 0U; + uint32_t rdes0_tsv_flag; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)) { + return ERROR; + } + + /* if buffer pointer is null, indicates that users has copied data in application */ + if(NULL != buffer) { + /* if no error occurs, and the frame uses only one descriptor */ + if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))) { + /* get the frame length except CRC */ + size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U; + + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG(enet_periph) & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))) { + size = size + 4U; + } + + /* to avoid situation that the frame size exceeds the buffer length */ + if(size > bufsize) { + return ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0U; offset < size; offset++) { + (*(buffer + offset)) = (*(__IO uint8_t *)((dma_current_rxdesc->buffer1_addr) + offset)); + } + } else { + return ERROR; + } + } + + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ + if(NULL != timestamp) { + /* wait for ENET_RDES0_TSV flag to be set, the timestamp value is taken and + write to the RDES6 and RDES7 */ + do { + rdes0_tsv_flag = (dma_current_rxdesc->status & ENET_RDES0_TSV); + timeout++; + } while((RESET == rdes0_tsv_flag) && (timeout < ENET_DELAY_TO)); + + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + return ERROR; + } + + /* clear the ENET_RDES0_TSV flag */ + dma_current_rxdesc->status &= ~ENET_RDES0_TSV; + /* get the timestamp value of the received frame */ + timestamp[0] = dma_current_rxdesc->timestamp_low; + timestamp[1] = dma_current_rxdesc->timestamp_high; + } + + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if((uint32_t)RESET != (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_RBU)) { + /* Clear RBU flag */ + ENET_DMA_STAT(enet_periph) = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN(enet_periph) = 0U; + } + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_rxdesc->buffer2_next_desc_addr); + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR(enet_periph)); + } else { + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct *)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL(enet_periph))); + } + } + + return SUCCESS; +} + +/*! + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] buffer: pointer on the application buffer + note -- if the input is NULL, user should copy data in application by himself + \param[in] length: the length of frame data to be transmitted + \param[out] timestamp: pointer to the table which stores the timestamp high and low + note -- if the input is NULL, timestamp is ignored + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_transmit_enhanced_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t length, uint32_t timestamp[]) +{ + uint32_t offset = 0U; + uint32_t dma_tbu_flag, dma_tu_flag; + uint32_t tdes0_ttmss_flag; + uint32_t timeout = 0U; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)) { + return ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE) { + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer) { + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0U; offset < length; offset++) { + (*(__IO uint8_t *)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + /* set the frame length */ + dma_current_txdesc->control_buffer_size = length; + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + dma_tbu_flag = (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_TU); + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { + /* Clear TBU and TU flag */ + ENET_DMA_STAT(enet_periph) = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN(enet_periph) = 0U; + } + + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ + if(NULL != timestamp) { + /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */ + do { + tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS); + timeout++; + } while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); + + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + return ERROR; + } + + /* clear the ENET_TDES0_TTMSS flag */ + dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; + /* get the timestamp value of the transmit frame */ + timestamp[0] = dma_current_txdesc->timestamp_low; + timestamp[1] = dma_current_txdesc->timestamp_high; + } + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)) { + dma_current_txdesc = (enet_descriptors_struct *)(dma_current_txdesc->buffer2_next_desc_addr); + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)) { + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct *)(ENET_DMA_TDTADDR(enet_periph)); + } else { + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_txdesc = (enet_descriptors_struct *)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL(enet_periph))); + } + } + + return SUCCESS; +} + +#else + +/*! + \brief configure descriptor to work in normal mode + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_desc_select_normal_mode(uint32_t enet_periph) +{ + ENET_DMA_BCTL(enet_periph) &= ~ENET_DMA_BCTL_DFM; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in normal chain mode with PTP function + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[in] desc_ptptab: pointer to the first descriptor address of PTP Rx descriptor table + \param[out] none + \retval none +*/ +void enet_ptp_normal_descriptors_chain_init(uint32_t enet_periph, enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* if want to initialize DMA Tx descriptors */ + if(ENET_DMA_TX == direction) { + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select chain mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TCHM | ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + dma_current_ptp_txdesc = desc_ptptab; + } else { + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive chained mode and set buffer1 size */ + desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + dma_current_ptp_rxdesc = desc_ptptab; + } + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* if is not the last descriptor */ + if(num < (count - 1U)) { + /* configure the next descriptor address */ + desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U); + } else { + /* when it is the last descriptor, the next descriptor address + equals to first descriptor address in descriptor table */ + desc->buffer2_next_desc_addr = (uint32_t)desc_tab; + } + /* set desc_ptptab equal to desc_tab */ + (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr; + (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr; + } + /* when it is the last ptp descriptor, preserve the first descriptor + address of desc_ptptab in ptp descriptor status */ + (&desc_ptptab[num - 1U])->status = (uint32_t)desc_ptptab; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in normal ring mode with PTP function + \param[in] enet_periph: ENETx(x=0,1) + \param[in] direction: the descriptors which users want to init, refer to enet_dmadirection_enum, + only one parameter can be selected which is shown as below + \arg ENET_DMA_TX: DMA Tx descriptors + \arg ENET_DMA_RX: DMA Rx descriptors + \param[in] desc_ptptab: pointer to the first descriptor address of PTP Rx descriptor table + \param[out] none + \retval none +*/ +void enet_ptp_normal_descriptors_ring_init(uint32_t enet_periph, enet_dmadirection_enum direction, enet_descriptors_struct *desc_ptptab) +{ + uint32_t num = 0U, count = 0U, maxsize = 0U; + uint32_t desc_status = 0U, desc_bufsize = 0U; + enet_descriptors_struct *desc, *desc_tab; + uint8_t *buf; + + /* configure descriptor skip length */ + ENET_DMA_BCTL(enet_periph) &= ~ENET_DMA_BCTL_DPSL; + ENET_DMA_BCTL(enet_periph) |= DMA_BCTL_DPSL(0); + + /* if want to initialize DMA Tx descriptors */ + if(ENET_DMA_TX == direction) { + /* save a copy of the DMA Tx descriptors */ + desc_tab = txdesc_tab; + buf = &tx_buff[0][0]; + count = ENET_TXBUF_NUM; + maxsize = ENET_TXBUF_SIZE; + + /* select ring mode, and enable transmit timestamp function */ + desc_status = ENET_TDES0_TTSEN; + + /* configure DMA Tx descriptor table address register */ + ENET_DMA_TDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_txdesc = desc_tab; + dma_current_ptp_txdesc = desc_ptptab; + } else { + /* if want to initialize DMA Rx descriptors */ + /* save a copy of the DMA Rx descriptors */ + desc_tab = rxdesc_tab; + buf = &rx_buff[0][0]; + count = ENET_RXBUF_NUM; + maxsize = ENET_RXBUF_SIZE; + + /* enable receiving */ + desc_status = ENET_RDES0_DAV; + /* select receive ring mode and set buffer1 size */ + desc_bufsize = (uint32_t)ENET_RXBUF_SIZE; + + /* configure DMA Rx descriptor table address register */ + ENET_DMA_RDTADDR(enet_periph) = (uint32_t)desc_tab; + dma_current_rxdesc = desc_tab; + dma_current_ptp_rxdesc = desc_ptptab; + } + + /* configure each descriptor */ + for(num = 0U; num < count; num++) { + /* get the pointer to the next descriptor of the descriptor table */ + desc = desc_tab + num; + + /* configure descriptors */ + desc->status = desc_status; + desc->control_buffer_size = desc_bufsize; + desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]); + + /* when it is the last descriptor */ + if(num == (count - 1U)) { + if(ENET_DMA_TX == direction) { + /* configure transmit end of ring mode */ + desc->status |= ENET_TDES0_TERM; + } else { + /* configure receive end of ring mode */ + desc->control_buffer_size |= ENET_RDES1_RERM; + } + } + /* set desc_ptptab equal to desc_tab */ + (&desc_ptptab[num])->buffer1_addr = desc->buffer1_addr; + (&desc_ptptab[num])->buffer2_next_desc_addr = desc->buffer2_next_desc_addr; + } + /* when it is the last ptp descriptor, preserve the first descriptor + address of desc_ptptab in ptp descriptor status */ + (&desc_ptptab[num - 1U])->status = (uint32_t)desc_ptptab; +} + +/*! + \brief receive a packet data with timestamp values to application buffer, when the DMA is in normal mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] bufsize: the size of buffer which is the parameter in function + \param[out] timestamp: pointer to the table which stores the timestamp high and low + \param[out] buffer: pointer to the application buffer + note -- if the input is NULL, user should copy data in application by himself + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_receive_normal_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t bufsize, uint32_t timestamp[]) +{ + uint32_t offset = 0U, size = 0U; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)) { + return ERROR; + } + + /* if buffer pointer is null, indicates that users has copied data in application */ + if(NULL != buffer) { + /* if no error occurs, and the frame uses only one descriptor */ + if(((uint32_t)RESET == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_LDES)) && + ((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_FDES))) { + + /* get the frame length except CRC */ + size = GET_RDES0_FRML(dma_current_rxdesc->status) - 4U; + /* if is a type frame, and CRC is not included in forwarding frame */ + if((RESET != (ENET_MAC_CFG(enet_periph) & ENET_MAC_CFG_TFCD)) && (RESET != (dma_current_rxdesc->status & ENET_RDES0_FRMT))) { + size = size + 4U; + } + + /* to avoid situation that the frame size exceeds the buffer length */ + if(size > bufsize) { + return ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0U; offset < size; offset++) { + (*(buffer + offset)) = (*(__IO uint8_t *)(uint32_t)((dma_current_ptp_rxdesc->buffer1_addr) + offset)); + } + + } else { + return ERROR; + } + } + /* copy timestamp value from Rx descriptor to application array */ + timestamp[0] = dma_current_rxdesc->buffer1_addr; + timestamp[1] = dma_current_rxdesc->buffer2_next_desc_addr; + + dma_current_rxdesc->buffer1_addr = dma_current_ptp_rxdesc ->buffer1_addr ; + dma_current_rxdesc->buffer2_next_desc_addr = dma_current_ptp_rxdesc ->buffer2_next_desc_addr; + + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if((uint32_t)RESET != (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_RBU)) { + /* clear RBU flag */ + ENET_DMA_STAT(enet_periph) = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN(enet_periph) = 0U; + } + + /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)) { + dma_current_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0U != dma_current_ptp_rxdesc->status) { + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); + } else { + /* ponter to the next ptp descriptor */ + dma_current_ptp_rxdesc++; + } + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)) { + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_rxdesc = (enet_descriptors_struct *)(ENET_DMA_RDTADDR(enet_periph)); + /* RDES2 and RDES3 will not be covered by buffer address, so do not need to preserve a new table, + use the same table with RxDMA descriptor */ + dma_current_ptp_rxdesc = (enet_descriptors_struct *)(dma_current_ptp_rxdesc->status); + } else { + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_rxdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL( + enet_periph))); + dma_current_ptp_rxdesc ++; + } + } + + return SUCCESS; +} + +/*! + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] buffer: pointer on the application buffer + note -- if the input is NULL, user should copy data in application by himself + \param[in] length: the length of frame data to be transmitted + \param[out] timestamp: pointer to the table which stores the timestamp high and low + note -- if the input is NULL, timestamp is ignored + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptpframe_transmit_normal_mode(uint32_t enet_periph, uint8_t buffer[], uint32_t length, uint32_t timestamp[]) +{ + uint32_t offset = 0U, timeout = 0U; + uint32_t dma_tbu_flag, dma_tu_flag, tdes0_ttmss_flag; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)) { + return ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE) { + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer) { + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0U; offset < length; offset++) { + (*(__IO uint8_t *)(uint32_t)((dma_current_ptp_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + /* set the frame length */ + dma_current_txdesc->control_buffer_size = (length & (uint32_t)0x00001FFFU); + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + dma_tbu_flag = (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT(enet_periph) & ENET_DMA_STAT_TU); + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { + /* clear TBU and TU flag */ + ENET_DMA_STAT(enet_periph) = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN(enet_periph) = 0U; + } + + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ + if(NULL != timestamp) { + /* wait for ENET_TDES0_TTMSS flag to be set, a timestamp was captured */ + do { + tdes0_ttmss_flag = (dma_current_txdesc->status & ENET_TDES0_TTMSS); + timeout++; + } while((RESET == tdes0_ttmss_flag) && (timeout < ENET_DELAY_TO)); + + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + return ERROR; + } + + /* clear the ENET_TDES0_TTMSS flag */ + dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; + /* get the timestamp value of the transmit frame */ + timestamp[0] = dma_current_txdesc->buffer1_addr; + timestamp[1] = dma_current_txdesc->buffer2_next_desc_addr; + } + dma_current_txdesc->buffer1_addr = dma_current_ptp_txdesc ->buffer1_addr ; + dma_current_txdesc->buffer2_next_desc_addr = dma_current_ptp_txdesc ->buffer2_next_desc_addr; + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)) { + dma_current_txdesc = (enet_descriptors_struct *)(dma_current_ptp_txdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0U != dma_current_ptp_txdesc->status) { + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_txdesc = (enet_descriptors_struct *)(dma_current_ptp_txdesc->status); + } else { + /* ponter to the next ptp descriptor */ + dma_current_ptp_txdesc++; + } + } else { + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)) { + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct *)(ENET_DMA_TDTADDR(enet_periph)); + /* TDES2 and TDES3 will not be covered by buffer address, so do not need to preserve a new table, + use the same table with TxDMA descriptor */ + dma_current_ptp_txdesc = (enet_descriptors_struct *)(dma_current_ptp_txdesc->status); + } else { + /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */ + dma_current_txdesc = (enet_descriptors_struct *)(uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + GET_DMA_BCTL_DPSL(ENET_DMA_BCTL( + enet_periph))); + dma_current_ptp_txdesc ++; + } + } + return SUCCESS; +} + +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/*! + \brief wakeup frame filter register pointer reset + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_wum_filter_register_pointer_reset(uint32_t enet_periph) +{ + ENET_MAC_WUM(enet_periph) |= ENET_MAC_WUM_WUFFRPR; +} + +/*! + \brief set the remote wakeup frame registers + \param[in] enet_periph: ENETx(x=0,1) + \param[in] pdata: pointer to buffer data which is written to remote wakeup frame registers (8 words total) + \param[out] none + \retval none +*/ +void enet_wum_filter_config(uint32_t enet_periph, uint32_t pdata[]) +{ + uint32_t num = 0U; + + /* configure ENET_MAC_RWFF register */ + for(num = 0U; num < ETH_WAKEUP_REGISTER_LENGTH; num++) { + ENET_MAC_RWFF(enet_periph) = pdata[num]; + } +} + +/*! + \brief enable wakeup management features + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_WUM_POWER_DOWN: power down mode + \arg ENET_WUM_MAGIC_PACKET_FRAME: enable a wakeup event due to magic packet reception + \arg ENET_WUM_WAKE_UP_FRAME: enable a wakeup event due to wakeup frame reception + \arg ENET_WUM_GLOBAL_UNICAST: any received unicast frame passed filter is considered to be a wakeup frame + \param[out] none + \retval none +*/ +void enet_wum_feature_enable(uint32_t enet_periph, uint32_t feature) +{ + ENET_MAC_WUM(enet_periph) |= feature; +} + +/*! + \brief disable wakeup management features + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_WUM_MAGIC_PACKET_FRAME: enable a wakeup event due to magic packet reception + \arg ENET_WUM_WAKE_UP_FRAME: enable a wakeup event due to wakeup frame reception + \arg ENET_WUM_GLOBAL_UNICAST: any received unicast frame passed filter is considered to be a wakeup frame + \param[out] none + \retval none +*/ +void enet_wum_feature_disable(uint32_t enet_periph, uint32_t feature) +{ + ENET_MAC_WUM(enet_periph) &= (~feature); +} + +/*! + \brief reset the MAC statistics counters + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +void enet_msc_counters_reset(uint32_t enet_periph) +{ + /* reset all counters */ + ENET_MSC_CTL(enet_periph) |= ENET_MSC_CTL_CTR; +} + +/*! + \brief enable the MAC statistics counter features + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_MSC_COUNTER_STOP_ROLLOVER: counter stop rollover + \arg ENET_MSC_RESET_ON_READ: reset on read + \arg ENET_MSC_COUNTERS_FREEZE: MSC counter freeze + \param[out] none + \retval none +*/ +void enet_msc_feature_enable(uint32_t enet_periph, uint32_t feature) +{ + ENET_MSC_CTL(enet_periph) |= feature; +} + +/*! + \brief disable the MAC statistics counter features + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: one or more parameters can be selected which are shown as below + \arg ENET_MSC_COUNTER_STOP_ROLLOVER: counter stop rollover + \arg ENET_MSC_RESET_ON_READ: reset on read + \arg ENET_MSC_COUNTERS_FREEZE: MSC counter freeze + \param[out] none + \retval none +*/ +void enet_msc_feature_disable(uint32_t enet_periph, uint32_t feature) +{ + ENET_MSC_CTL(enet_periph) &= (~feature); +} + +/*! + \brief configure MAC statistics counters preset mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] mode: MSC counters preset mode, refer to enet_msc_preset_enum, + only one parameter can be selected which is shown as below + \arg ENET_MSC_PRESET_NONE: do not preset MSC counter + \arg ENET_MSC_PRESET_HALF: preset all MSC counters to almost-half(0x7FFF FFF0) value + \arg ENET_MSC_PRESET_FULL: preset all MSC counters to almost-full(0xFFFF FFF0) value + \param[out] none + \retval none +*/ +void enet_msc_counters_preset_config(uint32_t enet_periph, enet_msc_preset_enum mode) +{ + ENET_MSC_CTL(enet_periph) &= ENET_MSC_PRESET_MASK; + ENET_MSC_CTL(enet_periph) |= (uint32_t)mode; +} + +/*! + \brief get MAC statistics counter + \param[in] enet_periph: ENETx(x=0,1) + \param[in] counter: MSC counters which is selected, refer to enet_msc_counter_enum, + only one parameter can be selected which is shown as below + \arg ENET_MSC_TX_SCCNT: MSC transmitted good frames after a single collision counter + \arg ENET_MSC_TX_MSCCNT: MSC transmitted good frames after more than a single collision counter + \arg ENET_MSC_TX_TGFCNT: MSC transmitted good frames counter + \arg ENET_MSC_RX_RFCECNT: MSC received frames with CRC error counter + \arg ENET_MSC_RX_RFAECNT: MSC received frames with alignment error counter + \arg ENET_MSC_RX_RGUFCNT: MSC received good unicast frames counter + \param[out] none + \retval the MSC counter value +*/ +uint32_t enet_msc_counters_get(uint32_t enet_periph, enet_msc_counter_enum counter) +{ + uint32_t reval; + reval = REG32((enet_periph + (uint32_t)counter)); + return reval; +} + +/*! + \brief change subsecond to nanosecond + \param[in] subsecond: subsecond value + \param[out] none + \retval the nanosecond value +*/ +uint32_t enet_ptp_subsecond_2_nanosecond(uint32_t subsecond) +{ + uint64_t val = subsecond * 1000000000Ull; + val >>= 31U; + return (uint32_t)val; +} + +/*! + \brief change nanosecond to subsecond + \param[in] nanosecond: nanosecond value + \param[out] none + \retval the subsecond value +*/ +uint32_t enet_ptp_nanosecond_2_subsecond(uint32_t nanosecond) +{ + uint64_t val = nanosecond * 0x80000000Ull; + val /= 1000000000U; + return (uint32_t)val; +} + +/*! + \brief enable the PTP features + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET PTP mode + one or more parameters can be selected which are shown as below + \arg ENET_RXTX_TIMESTAMP: timestamp function for transmit and receive frames + \arg ENET_PTP_TIMESTAMP_INT: timestamp interrupt trigger + \arg ENET_ALL_RX_TIMESTAMP: all received frames are taken snapshot + \arg ENET_NONTYPE_FRAME_SNAPSHOT: take snapshot when received non type frame + \arg ENET_IPV6_FRAME_SNAPSHOT: take snapshot for IPv6 frame + \arg ENET_IPV4_FRAME_SNAPSHOT: take snapshot for IPv4 frame + \arg ENET_PTP_FRAME_USE_MACADDRESS_FILTER: use MAC address1-3 to filter the PTP frame + \param[out] none + \retval none +*/ +void enet_ptp_feature_enable(uint32_t enet_periph, uint32_t feature) +{ + ENET_PTP_TSCTL(enet_periph) |= feature; +} + +/*! + \brief disable the PTP features + \param[in] enet_periph: ENETx(x=0,1) + \param[in] feature: the feature of ENET PTP mode + one or more parameters can be selected which are shown as below + \arg ENET_RXTX_TIMESTAMP: timestamp function for transmit and receive frames + \arg ENET_PTP_TIMESTAMP_INT: timestamp interrupt trigger + \arg ENET_ALL_RX_TIMESTAMP: all received frames are taken snapshot + \arg ENET_NONTYPE_FRAME_SNAPSHOT: take snapshot when received non type frame + \arg ENET_IPV6_FRAME_SNAPSHOT: take snapshot for IPv6 frame + \arg ENET_IPV4_FRAME_SNAPSHOT: take snapshot for IPv4 frame + \arg ENET_PTP_FRAME_USE_MACADDRESS_FILTER: use MAC address1-3 to filter the PTP frame + \param[out] none + \retval none +*/ +void enet_ptp_feature_disable(uint32_t enet_periph, uint32_t feature) +{ + ENET_PTP_TSCTL(enet_periph) &= ~feature; +} + +/*! + \brief configure the PTP timestamp function + \param[in] enet_periph: ENETx(x=0,1) + \param[in] func: only one parameter can be selected which is shown as below + \arg ENET_CKNT_ORDINARY: type of ordinary clock node type for timestamp + \arg ENET_CKNT_BOUNDARY: type of boundary clock node type for timestamp + \arg ENET_CKNT_END_TO_END: type of end-to-end transparent clock node type for timestamp + \arg ENET_CKNT_PEER_TO_PEER: type of peer-to-peer transparent clock node type for timestamp + \arg ENET_PTP_ADDEND_UPDATE: addend register update + \arg ENET_PTP_SYSTIME_UPDATE: timestamp update + \arg ENET_PTP_SYSTIME_INIT: timestamp initialize + \arg ENET_PTP_FINEMODE: the system timestamp uses the fine method for updating + \arg ENET_PTP_COARSEMODE: the system timestamp uses the coarse method for updating + \arg ENET_SUBSECOND_DIGITAL_ROLLOVER: digital rollover mode + \arg ENET_SUBSECOND_BINARY_ROLLOVER: binary rollover mode + \arg ENET_SNOOPING_PTP_VERSION_2: version 2 + \arg ENET_SNOOPING_PTP_VERSION_1: version 1 + \arg ENET_EVENT_TYPE_MESSAGES_SNAPSHOT: only event type messages are taken snapshot + \arg ENET_ALL_TYPE_MESSAGES_SNAPSHOT: all type messages are taken snapshot except announce, + management and signaling message + \arg ENET_MASTER_NODE_MESSAGE_SNAPSHOT: snapshot is only take for master node message + \arg ENET_SLAVE_NODE_MESSAGE_SNAPSHOT: snapshot is only taken for slave node message + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus enet_ptp_timestamp_function_config(uint32_t enet_periph, enet_ptp_function_enum func) +{ + uint32_t temp_config = 0U, temp_state = 0U; + uint32_t timeout = 0U; + ErrStatus enet_state = SUCCESS; + + switch(func) { + case ENET_CKNT_ORDINARY: + case ENET_CKNT_BOUNDARY: + case ENET_CKNT_END_TO_END: + case ENET_CKNT_PEER_TO_PEER: + ENET_PTP_TSCTL(enet_periph) &= ~ENET_PTP_TSCTL_CKNT; + ENET_PTP_TSCTL(enet_periph) |= (uint32_t)func; + break; + case ENET_PTP_ADDEND_UPDATE: + /* this bit must be read as zero before application set it */ + do { + temp_state = ENET_PTP_TSCTL(enet_periph) & ENET_PTP_TSCTL_TMSARU; + timeout++; + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + enet_state = ERROR; + } else { + ENET_PTP_TSCTL(enet_periph) |= ENET_PTP_TSCTL_TMSARU; + } + break; + case ENET_PTP_SYSTIME_UPDATE: + /* both the TMSSTU and TMSSTI bits must be read as zero before application set this bit */ + do { + temp_state = ENET_PTP_TSCTL(enet_periph) & (ENET_PTP_TSCTL_TMSSTU | ENET_PTP_TSCTL_TMSSTI); + timeout++; + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + enet_state = ERROR; + } else { + ENET_PTP_TSCTL(enet_periph) |= ENET_PTP_TSCTL_TMSSTU; + } + break; + case ENET_PTP_SYSTIME_INIT: + /* this bit must be read as zero before application set it */ + do { + temp_state = ENET_PTP_TSCTL(enet_periph) & ENET_PTP_TSCTL_TMSSTI; + timeout++; + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + enet_state = ERROR; + } else { + ENET_PTP_TSCTL(enet_periph) |= ENET_PTP_TSCTL_TMSSTI; + } + break; + default: + temp_config = (uint32_t)func & (~BIT(31)); + if(RESET != ((uint32_t)func & BIT(31))) { + ENET_PTP_TSCTL(enet_periph) |= temp_config; + } else { + ENET_PTP_TSCTL(enet_periph) &= ~temp_config; + } + break; + } + + return enet_state; +} + +/*! + \brief configure system time subsecond increment value + \param[in] enet_periph: ENETx(x=0,1) + \param[in] subsecond: the value will be added to the subsecond value of system time, + this value must be between 0 and 0xFF + \param[out] none + \retval none +*/ +void enet_ptp_subsecond_increment_config(uint32_t enet_periph, uint32_t subsecond) +{ + ENET_PTP_SSINC(enet_periph) = PTP_SSINC_STMSSI(subsecond); +} + +/*! + \brief adjusting the clock frequency only in fine update mode + \param[in] enet_periph: ENETx(x=0,1) + \param[in] add: the value will be added to the accumulator register to achieve time synchronization + \param[out] none + \retval none +*/ +void enet_ptp_timestamp_addend_config(uint32_t enet_periph, uint32_t add) +{ + ENET_PTP_TSADDEND(enet_periph) = add; +} + +/*! + \brief initialize or add/subtract to second of the system time + \param[in] enet_periph: ENETx(x=0,1) + \param[in] sign: timestamp update positive or negative sign, + only one parameter can be selected which is shown as below + \arg ENET_PTP_ADD_TO_TIME: timestamp update value is added to system time + \arg ENET_PTP_SUBSTRACT_FROM_TIME: timestamp update value is subtracted from system time + \param[in] second: initializing or adding/subtracting to second of the system time + \param[in] subsecond: the current subsecond of the system time + with 0.46 ns accuracy if required accuracy is 20 ns + \param[out] none + \retval none +*/ +void enet_ptp_timestamp_update_config(uint32_t enet_periph, uint32_t sign, uint32_t second, uint32_t subsecond) +{ + ENET_PTP_TSUH(enet_periph) = second; + ENET_PTP_TSUL(enet_periph) = sign | PTP_TSUL_TMSUSS(subsecond); +} + +/*! + \brief configure the expected target time + \param[in] enet_periph: ENETx(x=0,1) + \param[in] second: the expected target second time + \param[in] nanosecond: the expected target nanosecond time (signed) + \param[out] none + \retval none +*/ +void enet_ptp_expected_time_config(uint32_t enet_periph, uint32_t second, uint32_t nanosecond) +{ + ENET_PTP_ETH(enet_periph) = second; + ENET_PTP_ETL(enet_periph) = nanosecond; +} + +/*! + \brief get the current system time + \param[in] enet_periph: ENETx(x=0,1) + \param[out] systime_struct: pointer to a enet_ptp_systime_struct structure which contains + parameters of PTP system time + members of the structure and the member values are shown as below: + second: 0x0 - 0xFFFF FFFF + nanosecond: 0x0 - 0x7FFF FFFF * 10^9 / 2^31 + sign: ENET_PTP_TIME_POSITIVE, ENET_PTP_TIME_NEGATIVE + \retval none +*/ +void enet_ptp_system_time_get(uint32_t enet_periph, enet_ptp_systime_struct *systime_struct) +{ + uint32_t temp_sec = 0U, temp_subs = 0U; + + /* get the value of sysytem time registers */ + temp_sec = (uint32_t)ENET_PTP_TSH(enet_periph); + temp_subs = (uint32_t)ENET_PTP_TSL(enet_periph); + + /* get sysytem time and construct the enet_ptp_systime_struct structure */ + systime_struct->second = temp_sec; + systime_struct->nanosecond = GET_PTP_TSL_STMSS(temp_subs); + systime_struct->nanosecond = enet_ptp_subsecond_2_nanosecond(systime_struct->nanosecond); + systime_struct->sign = GET_PTP_TSL_STS(temp_subs); +} + +/*! + \brief configure the PPS output frequency + \param[in] enet_periph: ENETx(x=0,1) + \param[in] freq: PPS output frequency, + only one parameter can be selected which is shown as below + \arg ENET_PPSOFC_1HZ: PPS output 1Hz frequency + \arg ENET_PPSOFC_2HZ: PPS output 2Hz frequency + \arg ENET_PPSOFC_4HZ: PPS output 4Hz frequency + \arg ENET_PPSOFC_8HZ: PPS output 8Hz frequency + \arg ENET_PPSOFC_16HZ: PPS output 16Hz frequency + \arg ENET_PPSOFC_32HZ: PPS output 32Hz frequency + \arg ENET_PPSOFC_64HZ: PPS output 64Hz frequency + \arg ENET_PPSOFC_128HZ: PPS output 128Hz frequency + \arg ENET_PPSOFC_256HZ: PPS output 256Hz frequency + \arg ENET_PPSOFC_512HZ: PPS output 512Hz frequency + \arg ENET_PPSOFC_1024HZ: PPS output 1024Hz frequency + \arg ENET_PPSOFC_2048HZ: PPS output 2048Hz frequency + \arg ENET_PPSOFC_4096HZ: PPS output 4096Hz frequency + \arg ENET_PPSOFC_8192HZ: PPS output 8192Hz frequency + \arg ENET_PPSOFC_16384HZ: PPS output 16384Hz frequency + \arg ENET_PPSOFC_32768HZ: PPS output 32768Hz frequency + \param[out] none + \retval none +*/ +void enet_ptp_pps_output_frequency_config(uint32_t enet_periph, uint32_t freq) +{ + ENET_PTP_PPSCTL(enet_periph) = freq; +} + +/*! + \brief configure and start PTP timestamp counter + \param[in] enet_periph: ENETx(x=0,1) + \param[in] updatemethod: method for updating + \arg ENET_PTP_FINEMODE: fine correction method + \arg ENET_PTP_COARSEMODE: coarse correction method + \param[in] init_sec: second value for initializing system time + \param[in] init_subsec: subsecond value for initializing system time + \param[in] carry_cfg: the value to be added to the accumulator register (in fine method is used) + \param[in] accuracy_cfg: the value to be added to the subsecond value of system time + \param[out] none + \retval none +*/ +void enet_ptp_start(uint32_t enet_periph, int32_t updatemethod, uint32_t init_sec, uint32_t init_subsec, uint32_t carry_cfg, uint32_t accuracy_cfg) +{ + /* mask the timestamp trigger interrupt */ + enet_interrupt_disable(enet_periph, ENET_MAC_INT_TMSTIM); + + /* enable timestamp */ + enet_ptp_feature_enable(enet_periph, ENET_ALL_RX_TIMESTAMP | ENET_RXTX_TIMESTAMP); + + /* configure system time subsecond increment based on the PTP clock frequency */ + enet_ptp_subsecond_increment_config(enet_periph, accuracy_cfg); + + if(ENET_PTP_FINEMODE == updatemethod) { + /* fine correction method: configure the timestamp addend, then update */ + enet_ptp_timestamp_addend_config(enet_periph, carry_cfg); + enet_ptp_timestamp_function_config(enet_periph, ENET_PTP_ADDEND_UPDATE); + /* wait until update is completed */ + while(SET == enet_ptp_flag_get(enet_periph, (uint32_t)ENET_PTP_ADDEND_UPDATE)) { + } + } + + /* choose the fine correction method */ + enet_ptp_timestamp_function_config(enet_periph, (enet_ptp_function_enum)updatemethod); + + /* initialize the system time */ + enet_ptp_timestamp_update_config(enet_periph, ENET_PTP_ADD_TO_TIME, init_sec, init_subsec); + enet_ptp_timestamp_function_config(enet_periph, ENET_PTP_SYSTIME_INIT); + +#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE + enet_desc_select_enhanced_mode(enet_periph); +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ +} + +/*! + \brief adjust frequency in fine method by configure addend register + \param[in] enet_periph: ENETx(x=0,1) + \param[in] carry_cfg: the value to be added to the accumulator register + \param[out] none + \retval none +*/ +void enet_ptp_finecorrection_adjfreq(uint32_t enet_periph, int32_t carry_cfg) +{ + /* re-configure the timestamp addend, then update */ + enet_ptp_timestamp_addend_config(enet_periph, (uint32_t)carry_cfg); + enet_ptp_timestamp_function_config(enet_periph, ENET_PTP_ADDEND_UPDATE); +} + +/*! + \brief update system time in coarse method + \param[in] enet_periph: ENETx(x=0,1) + \param[in] systime_struct: : pointer to a enet_ptp_systime_struct structure which contains + parameters of PTP system time + members of the structure and the member values are shown as below: + second: 0x0 - 0xFFFF FFFF + nanosecond: 0x0 - 0x7FFF FFFF * 10^9 / 2^31 + sign: ENET_PTP_TIME_POSITIVE, ENET_PTP_TIME_NEGATIVE + \param[out] none + \retval none +*/ +void enet_ptp_coarsecorrection_systime_update(uint32_t enet_periph, enet_ptp_systime_struct *systime_struct) +{ + uint32_t subsecond_val; + uint32_t carry_cfg; + + subsecond_val = enet_ptp_nanosecond_2_subsecond(systime_struct->nanosecond); + + /* save the carry_cfg value */ + carry_cfg = ENET_PTP_TSADDEND_TMSA; + + /* update the system time */ + enet_ptp_timestamp_update_config(enet_periph, systime_struct->sign, systime_struct->second, subsecond_val); + enet_ptp_timestamp_function_config(enet_periph, ENET_PTP_SYSTIME_UPDATE); + + /* wait until the update is completed */ + while(SET == enet_ptp_flag_get(enet_periph, (uint32_t)ENET_PTP_SYSTIME_UPDATE)) { + } + + /* write back the carry_cfg value, then update */ + enet_ptp_timestamp_addend_config(enet_periph, carry_cfg); + enet_ptp_timestamp_function_config(enet_periph, ENET_PTP_ADDEND_UPDATE); +} + +/*! + \brief set system time in fine method + \param[in] enet_periph: ENETx(x=0,1) + \param[in] systime_struct: : pointer to a enet_ptp_systime_struct structure which contains + parameters of PTP system time + members of the structure and the member values are shown as below: + second: 0x0 - 0xFFFF FFFF + nanosecond: 0x0 - 0x7FFF FFFF * 10^9 / 2^31 + sign: ENET_PTP_TIME_POSITIVE, ENET_PTP_TIME_NEGATIVE + \param[out] none + \retval none +*/ +void enet_ptp_finecorrection_settime(uint32_t enet_periph, enet_ptp_systime_struct *systime_struct) +{ + uint32_t subsecond_val; + + subsecond_val = enet_ptp_nanosecond_2_subsecond(systime_struct->nanosecond); + + /* initialize the system time */ + enet_ptp_timestamp_update_config(enet_periph, systime_struct->sign, systime_struct->second, subsecond_val); + enet_ptp_timestamp_function_config(enet_periph, ENET_PTP_SYSTIME_INIT); + + /* wait until the system time initialzation finished */ + while(SET == enet_ptp_flag_get(enet_periph, (uint32_t)ENET_PTP_SYSTIME_INIT)) { + } +} + +/*! + \brief get the ptp flag status + \param[in] enet_periph: ENETx(x=0,1) + \param[in] flag: ptp flag status to be checked + \arg ENET_PTP_ADDEND_UPDATE: addend register update + \arg ENET_PTP_SYSTIME_UPDATE: timestamp update + \arg ENET_PTP_SYSTIME_INIT: timestamp initialize + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus enet_ptp_flag_get(uint32_t enet_periph, uint32_t flag) +{ + FlagStatus bitstatus = RESET; + + if((uint32_t)RESET != (ENET_PTP_TSCTL(enet_periph) & flag)) { + bitstatus = SET; + } + + return bitstatus; +} + +/*! + \brief reset the ENET initpara struct, call it before using enet_initpara_config() + \param[in] none + \param[out] none + \retval none +*/ +void enet_initpara_reset(void) +{ + enet_initpara.option_enable = 0U; + enet_initpara.forward_frame = 0U; + enet_initpara.dmabus_mode = 0U; + enet_initpara.dma_maxburst = 0U; + enet_initpara.dma_arbitration = 0U; + enet_initpara.store_forward_mode = 0U; + enet_initpara.dma_function = 0U; + enet_initpara.vlan_config = 0U; + enet_initpara.flow_control = 0U; + enet_initpara.hashtable_high = 0U; + enet_initpara.hashtable_low = 0U; + enet_initpara.framesfilter_mode = 0U; + enet_initpara.halfduplex_param = 0U; + enet_initpara.timer_config = 0U; + enet_initpara.interframegap = 0U; +} + +/*! + \brief initialize ENET peripheral with generally concerned parameters, call it by enet_init() + \param[in] enet_periph: ENETx(x=0,1) + \param[out] none + \retval none +*/ +static void enet_default_init(uint32_t enet_periph) +{ + uint32_t reg_value = 0U; + + /* MAC */ + /* configure ENET_MAC_CFG register */ + reg_value = ENET_MAC_CFG(enet_periph); + reg_value &= MAC_CFG_MASK; + reg_value |= ENET_WATCHDOG_ENABLE | ENET_JABBER_ENABLE | ENET_INTERFRAMEGAP_96BIT \ + | ENET_SPEEDMODE_10M | ENET_MODE_HALFDUPLEX | ENET_LOOPBACKMODE_DISABLE \ + | ENET_CARRIERSENSE_ENABLE | ENET_RECEIVEOWN_ENABLE \ + | ENET_RETRYTRANSMISSION_ENABLE | ENET_BACKOFFLIMIT_10 \ + | ENET_DEFERRALCHECK_DISABLE \ + | ENET_TYPEFRAME_CRC_DROP_DISABLE \ + | ENET_AUTO_PADCRC_DROP_DISABLE \ + | ENET_CHECKSUMOFFLOAD_DISABLE; + ENET_MAC_CFG(enet_periph) = reg_value; + + /* configure ENET_MAC_FRMF register */ + ENET_MAC_FRMF(enet_periph) = ENET_SRC_FILTER_DISABLE | ENET_DEST_FILTER_INVERSE_DISABLE \ + | ENET_MULTICAST_FILTER_PERFECT | ENET_UNICAST_FILTER_PERFECT \ + | ENET_PCFRM_PREVENT_ALL | ENET_BROADCASTFRAMES_ENABLE \ + | ENET_PROMISCUOUS_DISABLE | ENET_RX_FILTER_ENABLE; + + /* configure ENET_MAC_HLH, ENET_MAC_HLL register */ + ENET_MAC_HLH(enet_periph) = 0x00000000U; + + ENET_MAC_HLL(enet_periph) = 0x00000000U; + + /* configure ENET_MAC_FCTL, ENET_MAC_FCTH register */ + reg_value = ENET_MAC_FCTL(enet_periph); + reg_value &= MAC_FCTL_MASK; + reg_value |= MAC_FCTL_PTM(0) | ENET_ZERO_QUANTA_PAUSE_DISABLE \ + | ENET_PAUSETIME_MINUS4 | ENET_UNIQUE_PAUSEDETECT \ + | ENET_RX_FLOWCONTROL_DISABLE | ENET_TX_FLOWCONTROL_DISABLE; + ENET_MAC_FCTL(enet_periph) = reg_value; + + /* configure ENET_MAC_VLT register */ + ENET_MAC_VLT(enet_periph) = ENET_VLANTAGCOMPARISON_16BIT | MAC_VLT_VLTI(0); + + /* disable MAC interrupt */ + ENET_MAC_INTMSK(enet_periph) |= ENET_MAC_INTMSK_TMSTIM | ENET_MAC_INTMSK_WUMIM; + + /* MSC */ + /* disable MSC Rx interrupt */ + ENET_MSC_RINTMSK(enet_periph) |= ENET_MSC_RINTMSK_RFAEIM | ENET_MSC_RINTMSK_RFCEIM \ + | ENET_MSC_RINTMSK_RGUFIM; + + /* disable MSC Tx interrupt */ + ENET_MSC_TINTMSK(enet_periph) |= ENET_MSC_TINTMSK_TGFIM | ENET_MSC_TINTMSK_TGFMSCIM \ + | ENET_MSC_TINTMSK_TGFSCIM; + + /* DMA */ + /* configure ENET_DMA_CTL register */ + reg_value = ENET_DMA_CTL(enet_periph); + reg_value &= DMA_CTL_MASK; + reg_value |= ENET_TCPIP_CKSUMERROR_DROP | ENET_RX_MODE_STOREFORWARD \ + | ENET_FLUSH_RXFRAME_ENABLE | ENET_TX_MODE_STOREFORWARD \ + | ENET_TX_THRESHOLD_64BYTES | ENET_RX_THRESHOLD_64BYTES \ + | ENET_SECONDFRAME_OPT_DISABLE; + ENET_DMA_CTL(enet_periph) = reg_value; + + /* configure ENET_DMA_BCTL register */ + reg_value = ENET_DMA_BCTL(enet_periph); + reg_value &= DMA_BCTL_MASK; + reg_value = ENET_ADDRESS_ALIGN_ENABLE | ENET_ARBITRATION_RXTX_2_1 \ + | ENET_RXDP_32BEAT | ENET_PGBL_32BEAT | ENET_RXTX_DIFFERENT_PGBL \ + | ENET_FIXED_BURST_ENABLE | ENET_MIXED_BURST_DISABLE \ + | ENET_NORMAL_DESCRIPTOR; + ENET_DMA_BCTL(enet_periph) = reg_value; +} + +#ifndef USE_DELAY +/*! + \brief insert a delay time + \param[in] ncount: specifies the delay time length + \param[out] none + \param[out] none +*/ +static void enet_delay(uint32_t ncount) +{ + __IO uint32_t delay_time = 0U; + + for(delay_time = ncount; delay_time != 0U; delay_time--) { + } +} +#endif /* USE_DELAY */ + +/*! + \brief get the ENET MAC/MSC/PTP/DMA status flag + \param[in] enet_periph: ENETx(x=0,1) + \param[in] enet_flag: ENET status flag, refer to enet_flag_enum, + only one parameter can be selected which is shown as below + \arg ENET_MAC_FLAG_MPKR: magic packet received flag + \arg ENET_MAC_FLAG_WUFR: wakeup frame received flag + \arg ENET_MAC_FLAG_FLOWCONTROL: flow control status flag + \arg ENET_MAC_FLAG_WUM: WUM status flag + \arg ENET_MAC_FLAG_MSC: MSC status flag + \arg ENET_MAC_FLAG_MSCR: MSC receive status flag + \arg ENET_MAC_FLAG_MSCT: MSC transmit status flag + \arg ENET_MAC_FLAG_TMST: time stamp trigger status flag + \arg ENET_PTP_FLAG_TSSCO: timestamp second counter overflow flag + \arg ENET_PTP_FLAG_TTM: target time match flag + \arg ENET_MSC_FLAG_RFCE: received frames CRC error flag + \arg ENET_MSC_FLAG_RFAE: received frames alignment error flag + \arg ENET_MSC_FLAG_RGUF: received good unicast frames flag + \arg ENET_MSC_FLAG_TGFSC: transmitted good frames single collision flag + \arg ENET_MSC_FLAG_TGFMSC: transmitted good frames more single collision flag + \arg ENET_MSC_FLAG_TGF: transmitted good frames flag + \arg ENET_DMA_FLAG_TS: transmit status flag + \arg ENET_DMA_FLAG_TPS: transmit process stopped status flag + \arg ENET_DMA_FLAG_TBU: transmit buffer unavailable status flag + \arg ENET_DMA_FLAG_TJT: transmit jabber timeout status flag + \arg ENET_DMA_FLAG_RO: receive overflow status flag + \arg ENET_DMA_FLAG_TU: transmit underflow status flag + \arg ENET_DMA_FLAG_RS: receive status flag + \arg ENET_DMA_FLAG_RBU: receive buffer unavailable status flag + \arg ENET_DMA_FLAG_RPS: receive process stopped status flag + \arg ENET_DMA_FLAG_RWT: receive watchdog timeout status flag + \arg ENET_DMA_FLAG_ET: early transmit status flag + \arg ENET_DMA_FLAG_FBE: fatal bus error status flag + \arg ENET_DMA_FLAG_ER: early receive status flag + \arg ENET_DMA_FLAG_AI: abnormal interrupt summary flag + \arg ENET_DMA_FLAG_NI: normal interrupt summary flag + \arg ENET_DMA_FLAG_EB_DMA_ERROR: DMA error flag + \arg ENET_DMA_FLAG_EB_TRANSFER_ERROR: transfer error flag + \arg ENET_DMA_FLAG_EB_ACCESS_ERROR: access error flag + \arg ENET_DMA_FLAG_MSC: MSC status flag + \arg ENET_DMA_FLAG_WUM: WUM status flag + \arg ENET_DMA_FLAG_TST: timestamp trigger status flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus enet_flag_get(uint32_t enet_periph, enet_flag_enum enet_flag) +{ + if(RESET != (ENET_REG_VAL(enet_periph, enet_flag) & BIT(ENET_BIT_POS(enet_flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the ENET DMA status flag + \param[in] enet_periph: ENETx(x=0,1) + \param[in] enet_flag: ENET DMA flag clear, refer to enet_flag_clear_enum + only one parameter can be selected which is shown as below + \arg ENET_DMA_FLAG_TS_CLR: transmit status flag clear + \arg ENET_DMA_FLAG_TPS_CLR: transmit process stopped status flag clear + \arg ENET_DMA_FLAG_TBU_CLR: transmit buffer unavailable status flag clear + \arg ENET_DMA_FLAG_TJT_CLR: transmit jabber timeout status flag clear + \arg ENET_DMA_FLAG_RO_CLR: receive overflow status flag clear + \arg ENET_DMA_FLAG_TU_CLR: transmit underflow status flag clear + \arg ENET_DMA_FLAG_RS_CLR: receive status flag clear + \arg ENET_DMA_FLAG_RBU_CLR: receive buffer unavailable status flag clear + \arg ENET_DMA_FLAG_RPS_CLR: receive process stopped status flag clear + \arg ENET_DMA_FLAG_RWT_CLR: receive watchdog timeout status flag clear + \arg ENET_DMA_FLAG_ET_CLR: early transmit status flag clear + \arg ENET_DMA_FLAG_FBE_CLR: fatal bus error status flag clear + \arg ENET_DMA_FLAG_ER_CLR: early receive status flag clear + \arg ENET_DMA_FLAG_AI_CLR: abnormal interrupt summary flag clear + \arg ENET_DMA_FLAG_NI_CLR: normal interrupt summary flag clear + \param[out] none + \retval none +*/ +void enet_flag_clear(uint32_t enet_periph, enet_flag_clear_enum enet_flag) +{ + /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */ + ENET_REG_VAL(enet_periph, enet_flag) = BIT(ENET_BIT_POS(enet_flag)); +} + +/*! + \brief enable ENET MAC/MSC/DMA interrupt + \param[in] enet_periph: ENETx(x=0,1) + \param[in] enet_int: ENET interrupt, + only one parameter can be selected which is shown as below + \arg ENET_MAC_INT_WUMIM: WUM interrupt mask + \arg ENET_MAC_INT_TMSTIM: timestamp trigger interrupt mask + \arg ENET_MSC_INT_RFCEIM: received frame CRC error interrupt mask + \arg ENET_MSC_INT_RFAEIM: received frames alignment error interrupt mask + \arg ENET_MSC_INT_RGUFIM: received good unicast frames interrupt mask + \arg ENET_MSC_INT_TGFSCIM: transmitted good frames single collision interrupt mask + \arg ENET_MSC_INT_TGFMSCIM: transmitted good frames more single collision interrupt mask + \arg ENET_MSC_INT_TGFIM: transmitted good frames interrupt mask + \arg ENET_DMA_INT_TIE: transmit interrupt enable + \arg ENET_DMA_INT_TPSIE: transmit process stopped interrupt enable + \arg ENET_DMA_INT_TBUIE: transmit buffer unavailable interrupt enable + \arg ENET_DMA_INT_TJTIE: transmit jabber timeout interrupt enable + \arg ENET_DMA_INT_ROIE: receive overflow interrupt enable + \arg ENET_DMA_INT_TUIE: transmit underflow interrupt enable + \arg ENET_DMA_INT_RIE: receive interrupt enable + \arg ENET_DMA_INT_RBUIE: receive buffer unavailable interrupt enable + \arg ENET_DMA_INT_RPSIE: receive process stopped interrupt enable + \arg ENET_DMA_INT_RWTIE: receive watchdog timeout interrupt enable + \arg ENET_DMA_INT_ETIE: early transmit interrupt enable + \arg ENET_DMA_INT_FBEIE: fatal bus error interrupt enable + \arg ENET_DMA_INT_ERIE: early receive interrupt enable + \arg ENET_DMA_INT_AIE: abnormal interrupt summary enable + \arg ENET_DMA_INT_NIE: normal interrupt summary enable + \param[out] none + \retval none +*/ +void enet_interrupt_enable(uint32_t enet_periph, enet_int_enum enet_int) +{ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6U)) { + /* ENET_DMA_INTEN register interrupt */ + ENET_REG_VAL(enet_periph, enet_int) |= BIT(ENET_BIT_POS(enet_int)); + } else { + /* other INTMSK register interrupt */ + ENET_REG_VAL(enet_periph, enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); + } +} + +/*! + \brief disable ENET MAC/MSC/DMA interrupt + \param[in] enet_periph: ENETx(x=0,1) + \param[in] enet_int: ENET interrupt, + only one parameter can be selected which is shown as below + \arg ENET_MAC_INT_WUMIM: WUM interrupt mask + \arg ENET_MAC_INT_TMSTIM: timestamp trigger interrupt mask + \arg ENET_MSC_INT_RFCEIM: received frame CRC error interrupt mask + \arg ENET_MSC_INT_RFAEIM: received frames alignment error interrupt mask + \arg ENET_MSC_INT_RGUFIM: received good unicast frames interrupt mask + \arg ENET_MSC_INT_TGFSCIM: transmitted good frames single collision interrupt mask + \arg ENET_MSC_INT_TGFMSCIM: transmitted good frames more single collision interrupt mask + \arg ENET_MSC_INT_TGFIM: transmitted good frames interrupt mask + \arg ENET_DMA_INT_TIE: transmit interrupt enable + \arg ENET_DMA_INT_TPSIE: transmit process stopped interrupt enable + \arg ENET_DMA_INT_TBUIE: transmit buffer unavailable interrupt enable + \arg ENET_DMA_INT_TJTIE: transmit jabber timeout interrupt enable + \arg ENET_DMA_INT_ROIE: receive overflow interrupt enable + \arg ENET_DMA_INT_TUIE: transmit underflow interrupt enable + \arg ENET_DMA_INT_RIE: receive interrupt enable + \arg ENET_DMA_INT_RBUIE: receive buffer unavailable interrupt enable + \arg ENET_DMA_INT_RPSIE: receive process stopped interrupt enable + \arg ENET_DMA_INT_RWTIE: receive watchdog timeout interrupt enable + \arg ENET_DMA_INT_ETIE: early transmit interrupt enable + \arg ENET_DMA_INT_FBEIE: fatal bus error interrupt enable + \arg ENET_DMA_INT_ERIE: early receive interrupt enable + \arg ENET_DMA_INT_AIE: abnormal interrupt summary enable + \arg ENET_DMA_INT_NIE: normal interrupt summary enable + \param[out] none + \retval none +*/ +void enet_interrupt_disable(uint32_t enet_periph, enet_int_enum enet_int) +{ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6U)) { + /* ENET_DMA_INTEN register interrupt */ + ENET_REG_VAL(enet_periph, enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); + } else { + /* other INTMSK register interrupt */ + ENET_REG_VAL(enet_periph, enet_int) |= BIT(ENET_BIT_POS(enet_int)); + } +} + +/*! + \brief get ENET MAC/MSC/DMA interrupt flag + \param[in] enet_periph: ENETx(x=0,1) + \param[in] int_flag: ENET interrupt flag, + only one parameter can be selected which is shown as below + \arg ENET_MAC_INT_FLAG_WUM: WUM status flag + \arg ENET_MAC_INT_FLAG_MSC: MSC status flag + \arg ENET_MAC_INT_FLAG_MSCR: MSC receive status flag + \arg ENET_MAC_INT_FLAG_MSCT: MSC transmit status flag + \arg ENET_MAC_INT_FLAG_TMST: time stamp trigger status flag + \arg ENET_MSC_INT_FLAG_RFCE: received frames CRC error flag + \arg ENET_MSC_INT_FLAG_RFAE: received frames alignment error flag + \arg ENET_MSC_INT_FLAG_RGUF: received good unicast frames flag + \arg ENET_MSC_INT_FLAG_TGFSC: transmitted good frames single collision flag + \arg ENET_MSC_INT_FLAG_TGFMSC: transmitted good frames more single collision flag + \arg ENET_MSC_INT_FLAG_TGF: transmitted good frames flag + \arg ENET_DMA_INT_FLAG_TS: transmit status flag + \arg ENET_DMA_INT_FLAG_TPS: transmit process stopped status flag + \arg ENET_DMA_INT_FLAG_TBU: transmit buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_TJT: transmit jabber timeout status flag + \arg ENET_DMA_INT_FLAG_RO: receive overflow status flag + \arg ENET_DMA_INT_FLAG_TU: transmit underflow status flag + \arg ENET_DMA_INT_FLAG_RS: receive status flag + \arg ENET_DMA_INT_FLAG_RBU: receive buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_RPS: receive process stopped status flag + \arg ENET_DMA_INT_FLAG_RWT: receive watchdog timeout status flag + \arg ENET_DMA_INT_FLAG_ET: early transmit status flag + \arg ENET_DMA_INT_FLAG_FBE: fatal bus error status flag + \arg ENET_DMA_INT_FLAG_ER: early receive status flag + \arg ENET_DMA_INT_FLAG_AI: abnormal interrupt summary flag + \arg ENET_DMA_INT_FLAG_NI: normal interrupt summary flag + \arg ENET_DMA_INT_FLAG_MSC: MSC status flag + \arg ENET_DMA_INT_FLAG_WUM: WUM status flag + \arg ENET_DMA_INT_FLAG_TST: timestamp trigger status flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus enet_interrupt_flag_get(uint32_t enet_periph, enet_int_flag_enum int_flag) +{ + if(RESET != (ENET_REG_VAL(enet_periph, int_flag) & BIT(ENET_BIT_POS(int_flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear ENET DMA interrupt flag + \param[in] enet_periph: ENETx(x=0,1) + \param[in] int_flag_clear: clear ENET interrupt flag, + only one parameter can be selected which is shown as below + \arg ENET_DMA_INT_FLAG_TS_CLR: transmit status flag + \arg ENET_DMA_INT_FLAG_TPS_CLR: transmit process stopped status flag + \arg ENET_DMA_INT_FLAG_TBU_CLR: transmit buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_TJT_CLR: transmit jabber timeout status flag + \arg ENET_DMA_INT_FLAG_RO_CLR: receive overflow status flag + \arg ENET_DMA_INT_FLAG_TU_CLR: transmit underflow status flag + \arg ENET_DMA_INT_FLAG_RS_CLR: receive status flag + \arg ENET_DMA_INT_FLAG_RBU_CLR: receive buffer unavailable status flag + \arg ENET_DMA_INT_FLAG_RPS_CLR: receive process stopped status flag + \arg ENET_DMA_INT_FLAG_RWT_CLR: receive watchdog timeout status flag + \arg ENET_DMA_INT_FLAG_ET_CLR: early transmit status flag + \arg ENET_DMA_INT_FLAG_FBE_CLR: fatal bus error status flag + \arg ENET_DMA_INT_FLAG_ER_CLR: early receive status flag + \arg ENET_DMA_INT_FLAG_AI_CLR: abnormal interrupt summary flag + \arg ENET_DMA_INT_FLAG_NI_CLR: normal interrupt summary flag + \param[out] none + \retval none +*/ +void enet_interrupt_flag_clear(uint32_t enet_periph, enet_int_flag_clear_enum int_flag_clear) +{ + /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */ + ENET_REG_VAL(enet_periph, int_flag_clear) = BIT(ENET_BIT_POS(int_flag_clear)); +} + +#endif /* GD32H7XX */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exmc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exmc.c new file mode 100644 index 0000000000..34cd9b5537 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exmc.c @@ -0,0 +1,942 @@ +/*! + \file gd32h7xx_exmc.c + \brief EXMC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include +#include "gd32h7xx_exmc.h" + +/* EXMC bank0 register reset value */ +#define BANK0_SNCTL_RESET ((uint32_t)0x000030DAU) /* SNCTL register reset value */ +#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU) /* SNTCFG register reset value */ +#define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU) /* SNWTCFG register reset value */ + +/* EXMC bank2 register reset value */ +#define BANK2_NCTL_RESET ((uint32_t)0x00000008U) /* NCTL register reset value */ +#define BANK2_NINTEN_RESET ((uint32_t)0x00000042U) /* NINTEN register reset value */ +#define BANK2_NCTCFG_RESET ((uint32_t)0xFFFFFFFFU) /* NCTCFG register reset value */ +#define BANK2_NATCFG_RESET ((uint32_t)0xFFFFFFFFU) /* NATCFG register reset value */ + +/* EXMC SDRAM device register reset value */ +#define SDRAM_DEVICE_SDCTL_RESET ((uint32_t)0x000002D0U) /* SDCTL register reset value */ +#define SDRAM_DEVICE_SDTCFG_RESET ((uint32_t)0x0FFFFFFFU) /* SDTCFG register reset value */ +#define SDRAM_DEVICE_SDCMD_RESET ((uint32_t)0x00000000U) /* SDCMD register reset value */ +#define SDRAM_DEVICE_SDARI_RESET ((uint32_t)0x00000000U) /* SDARI register reset value */ +#define SDRAM_DEVICE_SDSTAT_RESET ((uint32_t)0x00000000U) /* SDSTAT register reset value */ +#define SDRAM_DEVICE_SDRSCTL_RESET ((uint32_t)0x00000000U) /* SDRSCTL register reset value */ + +/* EXMC register bit offset */ +/* EXMC_SNCTL register bit offset */ +#define SNCTL_NRMUX_OFFSET ((uint32_t)0x00000001U) /* bit offset of NRMUX */ +#define SNCTL_NREN_OFFSET ((uint32_t)0x00000006U) /* bit offset of NREN */ +#define SNCTL_SBRSTEN_OFFSET ((uint32_t)0x00000008U) /* bit offset of SBRSTEN */ +#define SNCTL_WREN_OFFSET ((uint32_t)0x0000000CU) /* bit offset of WREN */ +#define SNCTL_NRWTEN_OFFSET ((uint32_t)0x0000000DU) /* bit offset of NRWTEN */ +#define SNCTL_EXMODEN_OFFSET ((uint32_t)0x0000000EU) /* bit offset of EXMODEN */ +#define SNCTL_ASYNCWAITEN_OFFSET ((uint32_t)0x0000000FU) /* bit offset of ASYNCWAITEN */ +#define SNCTL_BKREMAP_OFFSET ((uint32_t)0x00000018U) /* bit offset of BKREMAP */ + +/* EXMC_SNTCFG register bit offset */ +#define SNTCFG_AHLD_OFFSET ((uint32_t)0x00000004U) /* bit offset of AHLD */ +#define SNTCFG_DSET_OFFSET ((uint32_t)0x00000008U) /* bit offset of DSET */ +#define SNTCFG_BUSLAT_OFFSET ((uint32_t)0x00000010U) /* bit offset of BUSLAT */ + +/* EXMC_NCTL register bit offset */ +#define NCTL_NDWTEN_OFFSET ((uint32_t)0x00000001U) /* bit offset of NDWTEN */ +#define NCTL_ECCEN_OFFSET ((uint32_t)0x00000006U) /* bit offset of ECCEN */ + +/* EXMC_NCTCFG register bit offset */ +#define NCTCFG_COMWAIT_OFFSET ((uint32_t)0x00000008U) /* bit offset of COMWAIT */ +#define NCTCFG_COMHLD_OFFSET ((uint32_t)0x00000010U) /* bit offset of COMHLD */ +#define NCTCFG_COMHIZ_OFFSET ((uint32_t)0x00000018U) /* bit offset of COMHIZ */ + +/* EXMC_NATCFG register bit offset */ +#define NATCFG_ATTWAIT_OFFSET ((uint32_t)0x00000008U) /* bit offset of ATTWAIT */ +#define NATCFG_ATTHLD_OFFSET ((uint32_t)0x00000010U) /* bit offset of ATTHLD */ +#define NATCFG_ATTHIZ_OFFSET ((uint32_t)0x00000018U) /* bit offset of ATTHIZ */ + +/* EXMC_SDCTL register bit offset */ +#define SDCTL_WPEN_OFFSET ((uint32_t)0x00000009U) /* bit offset of WPEN */ +#define SDCTL_BRSTRD_OFFSET ((uint32_t)0x0000000CU) /* bit offset of BRSTRD */ + +/* EXMC_SDTCFG register bit offset */ +#define SDTCFG_XSRD_OFFSET ((uint32_t)0x00000004U) /* bit offset of XSRD */ +#define SDTCFG_RASD_OFFSET ((uint32_t)0x00000008U) /* bit offset of RASD */ +#define SDTCFG_ARFD_OFFSET ((uint32_t)0x0000000CU) /* bit offset of ARFD */ +#define SDTCFG_WRD_OFFSET ((uint32_t)0x00000010U) /* bit offset of WRD */ +#define SDTCFG_RPD_OFFSET ((uint32_t)0x00000014U) /* bit offset of RPD */ +#define SDTCFG_RCD_OFFSET ((uint32_t)0x00000018U) /* bit offset of RCD */ + +/* EXMC_SDCMD register bit offset */ +#define SDCMD_NARF_OFFSET ((uint32_t)0x00000005U) /* bit offset of NARF */ +#define SDCMD_MRC_OFFSET ((uint32_t)0x00000009U) /* bit offset of MRC */ + +/* EXMC_SDCMD register bit offset */ +#define SDARI_ARINTV_OFFSET ((uint32_t)0x00000001U) /* bit offset of ARINTV */ + +/* EXMC_SDRSCTL register bit offset */ +#define SDRSCTL_SSCR_OFFSET ((uint32_t)0x00000001U) /* bit offset of SSCR */ +#define SDRSCTL_SDSC_OFFSET ((uint32_t)0x00000004U) /* bit offset of SDSC */ + +/* EXMC_SDSTAT register bit offset */ +#define SDSTAT_STA0_OFFSET ((uint32_t)0x00000001U) /* bit offset of STA0 */ +#define SDSTAT_STA1_OFFSET ((uint32_t)0x00000003U) /* bit offset of STA1 */ + +/* EXMC_NINTEN register interrupt enable bit and interrupt status bit interval */ +#define NINTEN_INTEN_INTS_INTERVAL ((uint32_t)0x00000003U) /* bit offset of INTEN_INTS */ + +/*! + \brief deinitialize EXMC NOR/SRAM region + \param[in] exmc_norsram_region: select the region of bank0 + only one parameter can be selected which is shown as below: + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3): EXMC BANK0 REGIONx + \param[out] none + \retval none +*/ +void exmc_norsram_deinit(uint32_t exmc_norsram_region) +{ + /* reset the registers */ + EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_RESET; + EXMC_SNTCFG(exmc_norsram_region) = BANK0_SNTCFG_RESET; + EXMC_SNWTCFG(exmc_norsram_region) = BANK0_SNWTCFG_RESET; +} + +/*! + \brief initialize exmc_norsram_parameter_struct with the default values + \param[in] none + \param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer + \retval none +*/ +void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct) +{ + /* configure control variables with default values */ + exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0; + exmc_norsram_init_struct->address_data_mux = ENABLE; + exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM; + exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_8B; + exmc_norsram_init_struct->burst_mode = DISABLE; + exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW; + exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE; + exmc_norsram_init_struct->memory_write = ENABLE; + exmc_norsram_init_struct->nwait_signal = ENABLE; + exmc_norsram_init_struct->extended_mode = DISABLE; + exmc_norsram_init_struct->asyn_wait = DISABLE; + exmc_norsram_init_struct->cram_page_size = EXMC_CRAM_AUTO_SPLIT; + exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE; + + /* configure read/write timing */ + exmc_norsram_init_struct->read_write_timing = NULL; + + /* configure write timing when extended mode is used */ + exmc_norsram_init_struct->write_timing = NULL; +} + +/*! + \brief initialize EXMC NOR/SRAM region + \param[in] exmc_norsram_init_struct: configure the EXMC NOR/SRAM parameter + norsram_region: EXMC_BANK0_NORSRAM_REGIONx, x=0~3 + write_mode: EXMC_ASYN_WRITE, EXMC_SYN_WRITE + extended_mode: ENABLE or DISABLE + asyn_wait: ENABLE or DISABLE + nwait_signal: ENABLE or DISABLE + memory_write: ENABLE or DISABLE + nwait_config: EXMC_NWAIT_CONFIG_BEFORE, EXMC_NWAIT_CONFIG_DURING + nwait_polarity: EXMC_NWAIT_POLARITY_LOW, EXMC_NWAIT_POLARITY_HIGH + burst_mode: ENABLE or DISABLE + databus_width: EXMC_NOR_DATABUS_WIDTH_8B, EXMC_NOR_DATABUS_WIDTH_16B + memory_type: EXMC_MEMORY_TYPE_SRAM, EXMC_MEMORY_TYPE_PSRAM, EXMC_MEMORY_TYPE_NOR + address_data_mux: ENABLE or DISABLE + cram_page_size: EXMC_CRAM_AUTO_SPLIT, EXMC_CRAM_PAGE_SIZE_128_BYTES, EXMC_CRAM_PAGE_SIZE_256_BYTES, + EXMC_CRAM_PAGE_SIZE_512_BYTES, EXMC_CRAM_PAGE_SIZE_1024_BYTES + read_write_timing: struct exmc_norsram_timing_parameter_struct set the time + asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D + syn_data_latency: EXMC_DATALAT_x_CLK, x=2~17 + syn_clk_division: EXMC_SYN_CLOCK_RATIO_x_CLK, x=2~16 + bus_latency: 0x0U~0xFU + asyn_data_setuptime: 1~255 + asyn_address_holdtime: 1~15 + asyn_address_setuptime: 0~15 + write_timing: struct exmc_norsram_timing_parameter_struct set the time + asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D + syn_data_latency: EXMC_DATALAT_x_CLK, x=2~17 + syn_clk_division: EXMC_SYN_CLOCK_RATIO_x_CLK, x=2~16 + bus_latency: 0~15 + asyn_data_setuptime: 1~255 + asyn_address_holdtime: 1~15 + asyn_address_setuptime: 0~15 + \param[out] none + \retval none +*/ +void exmc_norsram_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct) +{ + uint32_t snctl = 0x00000000U, sntcfg = 0x00000000U, snwtcfg = 0x00000000U; + + /* get value of register EXMC_SNCTL */ + snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region); + + /* clear control bits */ + snctl &= (uint32_t)(~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN | + EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WEN | + EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWTEN | EXMC_SNCTL_SYNCWR | + EXMC_SNCTL_NRMUX | EXMC_SNCTL_BKREMAP | EXMC_SNCTL_CCK | EXMC_SNCTL_CPS)); + + /* configure control bits */ + snctl |= (uint32_t)((exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | + exmc_norsram_init_struct->memory_type | + exmc_norsram_init_struct->databus_width | + (exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) | + exmc_norsram_init_struct->nwait_polarity | + exmc_norsram_init_struct->nwait_config | + (exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) | + (exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | + (exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) | + (exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAITEN_OFFSET) | + exmc_norsram_init_struct->write_mode | + exmc_norsram_init_struct->cram_page_size); + + /* nor flash access enable */ + if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type) { + snctl |= (uint32_t)EXMC_SNCTL_NREN; + } + + /* configure timing */ + sntcfg = (uint32_t)(exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime | + (exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) | + (exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | + (exmc_norsram_init_struct->read_write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | + exmc_norsram_init_struct->read_write_timing->syn_clk_division | + exmc_norsram_init_struct->read_write_timing->syn_data_latency | + exmc_norsram_init_struct->read_write_timing->asyn_access_mode); + + if(ENABLE == exmc_norsram_init_struct->extended_mode) { + /* for extended mode, configure write timing */ + snwtcfg = (uint32_t)(exmc_norsram_init_struct->write_timing->asyn_address_setuptime | + (exmc_norsram_init_struct->write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) | + (exmc_norsram_init_struct->write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) | + (exmc_norsram_init_struct->write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) | + exmc_norsram_init_struct->write_timing->asyn_access_mode); + } else { + snwtcfg = BANK0_SNWTCFG_RESET; + } + + /* configure the registers */ + EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl; + EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg; + EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg; +} + +/*! + \brief enable EXMC NOR/PSRAM bank region + \param[in] exmc_norsram_region: specify the region of NOR/PSRAM bank + only one parameter can be selected which is shown as below: + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3): EXMC BANK0 REGIONx + \param[out] none + \retval none +*/ +void exmc_norsram_enable(uint32_t exmc_norsram_region) +{ + EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN; +} + +/*! + \brief disable EXMC NOR/PSRAM bank region + \param[in] exmc_norsram_region: specify the region of NOR/PSRAM Bank + only one parameter can be selected which is shown as below: + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3): EXMC BANK0 REGIONx + \param[out] none + \retval none +*/ +void exmc_norsram_disable(uint32_t exmc_norsram_region) +{ + EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN; +} + +/*! + \brief deinitialize EXMC NAND bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_nand_deinit(void) +{ + /* deinitialize EXMC_BANK2_NAND */ + EXMC_NCTL = BANK2_NCTL_RESET; + EXMC_NINTEN = BANK2_NINTEN_RESET; + EXMC_NCTCFG = BANK2_NCTCFG_RESET; + EXMC_NATCFG = BANK2_NATCFG_RESET; +} + +/*! + \brief initialize exmc_nand_parameter_struct with the default values + \param[in] none + \param[out] the initialized struct exmc_nand_parameter_struct pointer + \retval none +*/ +void exmc_nand_struct_para_init(exmc_nand_parameter_struct *exmc_nand_init_struct) +{ + /* configure the structure with default values */ + exmc_nand_init_struct->wait_feature = DISABLE; + exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B; + exmc_nand_init_struct->ecc_logic = DISABLE; + exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES; + exmc_nand_init_struct->ctr_latency = 0x00U; + exmc_nand_init_struct->atr_latency = 0x00U; + exmc_nand_init_struct->common_space_timing = NULL; + exmc_nand_init_struct->attribute_space_timing = NULL; +} + +/*! + \brief initialize EXMC NAND bank + \param[in] exmc_nand_init_struct: configure the EXMC NAND parameter + ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096 + atr_latency: EXMC_ALE_RE_DELAY_x_CK_EXMC,x=1~16 + ctr_latency: EXMC_CLE_RE_DELAY_x_CK_EXMC,x=1~16 + ecc_logic: ENABLE or DISABLE + databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B + wait_function: ENABLE or DISABLE + common_space_timing: struct exmc_nand_timing_parameter_struct set the time + databus_hiztime: 1~255 + holdtime: 1~254 + waittime: 2~255 + setuptime: 1~255 + attribute_space_timing: struct exmc_nand_timing_parameter_struct set the time + databus_hiztime: 0~254 + holdtime: 1~254 + waittime: 2~255 + setuptime: 1~255 + \param[out] none + \retval none +*/ +void exmc_nand_init(exmc_nand_parameter_struct *exmc_nand_init_struct) +{ + uint32_t nctl = 0x00000000U, nctcfg = 0x00000000U, natcfg = 0x00000000U; + + /* configure nctl for EXMC_NCTL */ + nctl = (uint32_t)((exmc_nand_init_struct->wait_feature << NCTL_NDWTEN_OFFSET) | + exmc_nand_init_struct->databus_width | + (exmc_nand_init_struct->ecc_logic << NCTL_ECCEN_OFFSET) | + exmc_nand_init_struct->ecc_size | + exmc_nand_init_struct->ctr_latency | + exmc_nand_init_struct->atr_latency); + + /* configure nctcfg for EXMC_NCTCFG */ + nctcfg = (uint32_t)(((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NCTCFG_COMSET) | + (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NCTCFG_COMWAIT_OFFSET) & EXMC_NCTCFG_COMWAIT) | + ((exmc_nand_init_struct->common_space_timing->holdtime << NCTCFG_COMHLD_OFFSET) & EXMC_NCTCFG_COMHLD) | + (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NCTCFG_COMHIZ_OFFSET) & EXMC_NCTCFG_COMHIZ)); + + /* configure natcfg for EXMC_NATCFG */ + natcfg = (uint32_t)(((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NATCFG_ATTSET) | + (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NATCFG_ATTWAIT_OFFSET) & EXMC_NATCFG_ATTWAIT) | + ((exmc_nand_init_struct->attribute_space_timing->holdtime << NATCFG_ATTHLD_OFFSET) & EXMC_NATCFG_ATTHLD) | + ((exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NATCFG_ATTHIZ_OFFSET) & EXMC_NATCFG_ATTHIZ)); + + /* initialize EXMC_BANK2_NAND */ + EXMC_NCTL = nctl; + EXMC_NCTCFG = nctcfg; + EXMC_NATCFG = natcfg; +} + +/*! + \brief enable NAND bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_nand_enable(void) +{ + EXMC_NCTL |= EXMC_NCTL_NDBKEN; +} + +/*! + \brief disable NAND bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_nand_disable(void) +{ + EXMC_NCTL &= ~EXMC_NCTL_NDBKEN; +} + +/*! + \brief deinitialize EXMC SDRAM device + \param[in] exmc_sdram_device: select the SRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_SDRAM_DEVICEx(x=0, 1) + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sdram_deinit(uint32_t exmc_sdram_device) +{ + /* reset SDRAM registers */ + EXMC_SDCTL(exmc_sdram_device) = SDRAM_DEVICE_SDCTL_RESET; + EXMC_SDTCFG(exmc_sdram_device) = SDRAM_DEVICE_SDTCFG_RESET; + EXMC_SDCMD = SDRAM_DEVICE_SDCMD_RESET; + EXMC_SDARI = SDRAM_DEVICE_SDARI_RESET; + EXMC_SDRSCTL = SDRAM_DEVICE_SDRSCTL_RESET; +} + +/*! + \brief initialize exmc_sdram_parameter_struct with the default values + \param[in] none + \param[out] the initialized struct exmc_parameter_struct pointer + \retval none +*/ +void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct) +{ + /* configure the structure with default values */ + exmc_sdram_init_struct->sdram_device = EXMC_SDRAM_DEVICE0; + exmc_sdram_init_struct->column_address_width = EXMC_SDRAM_COW_ADDRESS_8; + exmc_sdram_init_struct->row_address_width = EXMC_SDRAM_ROW_ADDRESS_11; + exmc_sdram_init_struct->data_width = EXMC_SDRAM_DATABUS_WIDTH_16B; + exmc_sdram_init_struct->internal_bank_number = EXMC_SDRAM_4_INTER_BANK; + exmc_sdram_init_struct->cas_latency = EXMC_CAS_LATENCY_1_SDCLK; + exmc_sdram_init_struct->write_protection = ENABLE; + exmc_sdram_init_struct->sdclock_config = EXMC_SDCLK_DISABLE; + exmc_sdram_init_struct->burst_read_switch = DISABLE; + exmc_sdram_init_struct->pipeline_read_delay = EXMC_PIPELINE_DELAY_0_CK_EXMC; + + exmc_sdram_init_struct->timing = NULL; +} + +/*! + \brief initialize EXMC SDRAM device + \param[in] exmc_sdram_init_struct: configure the EXMC SDRAM parameter + sdram_device: EXMC_SDRAM_DEVICE0,EXMC_SDRAM_DEVICE1 + pipeline_read_delay: EXMC_PIPELINE_DELAY_x_CK_EXMC,x=0~2 + burst_read_switch: ENABLE or DISABLE + sdclock_config: EXMC_SDCLK_DISABLE,EXMC_SDCLK_PERIODS_2_CK_EXMC,EXMC_SDCLK_PERIODS_3_CK_EXMC,EXMC_SDCLK_PERIODS_4_CK_EXMC,EXMC_SDCLK_PERIODS_5_CK_EXMC + write_protection: ENABLE or DISABLE + cas_latency: EXMC_CAS_LATENCY_x_SDCLK,x=1~3 + internal_bank_number: EXMC_SDRAM_2_INTER_BANK,EXMC_SDRAM_4_INTER_BANK + data_width: EXMC_SDRAM_DATABUS_WIDTH_8B,EXMC_SDRAM_DATABUS_WIDTH_16B,EXMC_SDRAM_DATABUS_WIDTH_32B + row_address_width: EXMC_SDRAM_ROW_ADDRESS_x,x=11~13 + column_address_width: EXMC_SDRAM_COW_ADDRESS_x,x=8~11 + timing: exmc_sdram_timing_parameter_struct set the time + row_to_column_delay: 1~16 + row_precharge_delay: 1~16 + write_recovery_delay: 1~16 + auto_refresh_delay: 1~16 + row_address_select_delay: 1~16 + exit_selfrefresh_delay: 1~16 + load_mode_register_delay: 1~16 + \param[out] none + \retval none +*/ +void exmc_sdram_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct) +{ + uint32_t sdctl0, sdctl1, sdtcfg0, sdtcfg1; + + /* configure EXMC_SDCTL0 or EXMC_SDCTL1 */ + if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device) { + /* configure EXMC_SDCTL0 */ + EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = (uint32_t)(exmc_sdram_init_struct->column_address_width | + exmc_sdram_init_struct->row_address_width | + exmc_sdram_init_struct->data_width | + exmc_sdram_init_struct->internal_bank_number | + exmc_sdram_init_struct->cas_latency | + (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET) | + exmc_sdram_init_struct->sdclock_config | + (exmc_sdram_init_struct->burst_read_switch << SDCTL_BRSTRD_OFFSET) | + exmc_sdram_init_struct->pipeline_read_delay); + + /* configure EXMC_SDTCFG0 */ + EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) | + (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) | + (((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) | + (((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET); + } else { + /* configure EXMC_SDCTL0 and EXMC_SDCTL1 */ + /* some bits in the EXMC_SDCTL1 register are reserved */ + sdctl0 = EXMC_SDCTL(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDCTL_PIPED | EXMC_SDCTL_BRSTRD | EXMC_SDCTL_SDCLK | EXMC_SDCTL_SDCLK_2)); + + sdctl0 |= (uint32_t)(exmc_sdram_init_struct->sdclock_config | + (exmc_sdram_init_struct->burst_read_switch << SDCTL_BRSTRD_OFFSET) | + exmc_sdram_init_struct->pipeline_read_delay); + + sdctl1 = (uint32_t)(exmc_sdram_init_struct->column_address_width | + exmc_sdram_init_struct->row_address_width | + exmc_sdram_init_struct->data_width | + exmc_sdram_init_struct->internal_bank_number | + exmc_sdram_init_struct->cas_latency | + (exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET)); + + EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = sdctl0; + EXMC_SDCTL(EXMC_SDRAM_DEVICE1) = sdctl1; + + /* configure EXMC_SDTCFG0 and EXMC_SDTCFG1 */ + /* some bits in the EXMC_SDTCFG1 register are reserved */ + sdtcfg0 = EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDTCFG_RPD | EXMC_SDTCFG_WRD | EXMC_SDTCFG_ARFD)); + + sdtcfg0 |= (uint32_t)((((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) | + (((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET)); + + sdtcfg1 = (uint32_t)(((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) | + (((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) | + (((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET)); + + EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = sdtcfg0; + EXMC_SDTCFG(EXMC_SDRAM_DEVICE1) = sdtcfg1; + } +} + +/*! + \brief configure NOR/PSRAM and SDRAM remap + \param[in] bank_remap: NOR/PSRAM and SDRAM map address + only one parameter can be selected which is shown as below: + \arg EXMC_BANK_REMAP_DEFAULT: default mapping + \arg EXMC_BANK_NORPSRAM_SDRAM_SWAP: NOR/PSRAM bank and SDRAM device 0 swapped + \param[out] none + \retval none +*/ +void exmc_norsram_sdram_remap_config(uint32_t bank_remap) +{ + /* reset BKREMAP bits */ + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= (uint32_t)(~EXMC_SNCTL_BKREMAP); + + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= bank_remap; +} + +/*! + \brief get NOR/PSRAM and SDRAM remap configuration + \param[in] none + \param[out] none + \retval bank remap value + \arg EXMC_BANK_REMAP_DEFAULT: default mapping + \arg EXMC_BANK_NORPSRAM_SDRAM_SWAP: NOR/PSRAM bank and SDRAM device 0 swapped +*/ +uint32_t exmc_norsram_sdram_remap_get(void) +{ + uint32_t bank_remap; + + bank_remap = EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) & EXMC_SNCTL_BKREMAP; + + return bank_remap; +} + +/*! + \brief configure consecutive clock mode (consecutive clock is only supported in EXMC BANK0 REGION0) + \param[in] clock_mode: specify when the clock is generated + only one parameter can be selected which is shown as below: + \arg EXMC_CLOCK_SYN_MODE: the clock is generated only during synchronous access + \arg EXMC_CLOCK_UNCONDITIONALLY: the clock is generated unconditionally + \param[out] none + \retval none +*/ +void exmc_norsram_consecutive_clock_config(uint32_t clock_mode) +{ + if(EXMC_CLOCK_UNCONDITIONALLY == clock_mode) { + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_CLOCK_UNCONDITIONALLY; + } else { + EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_CLOCK_UNCONDITIONALLY; + } +} + +/*! + \brief configure CRAM page size + \param[in] exmc_norsram_region: select the region of bank0 + only one parameter can be selected which is shown as below: + \arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3) + \param[in] page_size: CRAM page size + only one parameter can be selected which is shown as below: + \arg EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access + \arg EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes + \arg EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes + \arg EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes + \arg EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes + \param[out] none + \retval none +*/ +void exmc_norsram_page_size_config(uint32_t exmc_norsram_region, uint32_t page_size) +{ + /* reset the bits */ + EXMC_SNCTL(exmc_norsram_region) &= ~EXMC_SNCTL_CPS; + + EXMC_SNCTL(exmc_norsram_region) |= page_size; +} + +/*! + \brief enable or disable the EXMC NAND ECC function + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void exmc_nand_ecc_config(ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + /* enable NAND bank ECC function */ + EXMC_NCTL |= EXMC_NCTL_ECCEN; + } else { + /* disable NAND bank ECC function */ + EXMC_NCTL &= ~EXMC_NCTL_ECCEN; + } +} + +/*! + \brief get the EXMC ECC value + \param[in] none + \param[out] none + \retval the error correction code(ECC) value +*/ +uint32_t exmc_ecc_get(void) +{ + return(EXMC_NECC); +} + +/*! + \brief enable read sample function + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sdram_readsample_enable(void) +{ + EXMC_SDRSCTL |= EXMC_SDRSCTL_RSEN; +} + +/*! + \brief disable read sample function + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sdram_readsample_disable(void) +{ + EXMC_SDRSCTL &= (uint32_t)(~EXMC_SDRSCTL_RSEN); +} + +/*! + \brief configure the delayed sample clock of read data + \param[in] delay_cell: SDRAM the delayed sample clock of read data + only one parameter can be selected which is shown as below: + \arg EXMC_SDRAM_x_DELAY_CELL(x=0..15) + \param[in] extra_clk: sample cycle of read data + only one parameter can be selected which is shown as below: + \arg EXMC_SDRAM_READSAMPLE_0_EXTRACK: add 0 extra CK_EXMC cycle to the read data sample clock besides the delay chain + \arg EXMC_SDRAM_READSAMPLE_1_EXTRACK: add 1 extra CK_EXMC cycle to the read data sample clock besides the delay chain + \param[out] none + \retval none +*/ +void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_clk) +{ + uint32_t sdrsctl = 0U; + + /* reset the bits */ + sdrsctl = EXMC_SDRSCTL & (~(EXMC_SDRSCTL_SDSC | EXMC_SDRSCTL_SSCR)); + /* set the bits */ + sdrsctl |= (uint32_t)(delay_cell | extra_clk); + EXMC_SDRSCTL = sdrsctl; +} + +/*! + \brief configure the SDRAM memory command + \param[in] exmc_sdram_command_init_struct: initialize EXMC SDRAM command + mode_register_content: + auto_refresh_number: EXMC_SDRAM_AUTO_REFLESH_x_SDCLK, x=1~15 + bank_select: EXMC_SDRAM_DEVICE0_SELECT, EXMC_SDRAM_DEVICE1_SELECT, EXMC_SDRAM_DEVICE0_1_SELECT + command: EXMC_SDRAM_NORMAL_OPERATION, EXMC_SDRAM_CLOCK_ENABLE, EXMC_SDRAM_PRECHARGE_ALL, + EXMC_SDRAM_AUTO_REFRESH, EXMC_SDRAM_LOAD_MODE_REGISTER, EXMC_SDRAM_SELF_REFRESH, + EXMC_SDRAM_POWERDOWN_ENTRY + \param[out] none + \retval none +*/ +void exmc_sdram_command_config(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct) +{ + /* configure command register */ + EXMC_SDCMD = (uint32_t)((exmc_sdram_command_init_struct->command) | + (exmc_sdram_command_init_struct->bank_select) | + ((exmc_sdram_command_init_struct->auto_refresh_number)) | + ((exmc_sdram_command_init_struct->mode_register_content) << SDCMD_MRC_OFFSET)); +} + +/*! + \brief set auto-refresh interval + \param[in] exmc_count: the number SDRAM clock cycles unit between two successive auto-refresh commands, 0x00000000~0x00001FFF + \param[out] none + \retval none +*/ +void exmc_sdram_refresh_count_set(uint32_t exmc_count) +{ + uint32_t sdari; + sdari = EXMC_SDARI & (~EXMC_SDARI_ARINTV); + EXMC_SDARI = sdari | (uint32_t)((exmc_count << SDARI_ARINTV_OFFSET) & EXMC_SDARI_ARINTV); +} + +/*! + \brief set the number of successive auto-refresh command + \param[in] exmc_number: the number of successive Auto-refresh cycles will be send, 1~15 + \param[out] none + \retval none +*/ +void exmc_sdram_autorefresh_number_set(uint32_t exmc_number) +{ + uint32_t sdcmd; + sdcmd = EXMC_SDCMD & (~EXMC_SDCMD_NARF); + EXMC_SDCMD = sdcmd | (uint32_t)((exmc_number << SDCMD_NARF_OFFSET) & EXMC_SDCMD_NARF); +} + +/*! + \brief configure the write protection function + \param[in] exmc_sdram_device: specify the SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_SDRAM_DEVICEx(x=0,1) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + EXMC_SDCTL(exmc_sdram_device) |= (uint32_t)EXMC_SDCTL_WPEN; + } else { + EXMC_SDCTL(exmc_sdram_device) &= ~((uint32_t)EXMC_SDCTL_WPEN); + } +} + +/*! + \brief get the status of SDRAM device0 or device1 + \param[in] exmc_sdram_device: specify the SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_SDRAM_DEVICEx(x=0,1) + \param[out] none + \retval the status of SDRAM device +*/ +uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device) +{ + uint32_t sdstat = 0U; + + if(EXMC_SDRAM_DEVICE0 == exmc_sdram_device) { + sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA0) >> SDSTAT_STA0_OFFSET); + } else { + sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA1) >> SDSTAT_STA1_OFFSET); + } + + return sdstat; +} + +/*! + \brief get EXMC flag status + \param[in] exmc_bank: specify the NAND bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] flag: EXMC status and flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_FLAG_LEVEL: interrupt high-level status + \arg EXMC_NAND_FLAG_RISE: interrupt rising edge status + \arg EXMC_NAND_FLAG_FALL: interrupt falling edge status + \arg EXMC_NAND_FLAG_FIFOE: FIFO empty flag + \arg EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag + \arg EXMC_SDRAM_FLAG_NREADY: not ready status + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus exmc_flag_get(uint32_t exmc_bank, uint32_t flag) +{ + uint32_t status = 0x00000000U; + + if(EXMC_BANK2_NAND == exmc_bank) { + /* NAND bank2 */ + status = EXMC_NINTEN; + } else { + /* SDRAM device0 or device1 */ + status = EXMC_SDSTAT; + } + + if((status & flag) != (uint32_t)flag) { + /* flag is reset */ + return RESET; + } else { + /* flag is set */ + return SET; + } +} + +/*! + \brief clear EXMC flag status + \param[in] exmc_bank: specify the NAND bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] flag: EXMC status and flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_FLAG_LEVEL: interrupt high-level status + \arg EXMC_NAND_FLAG_RISE: interrupt rising edge status + \arg EXMC_NAND_FLAG_FALL: interrupt falling edge status + \arg EXMC_NAND_FLAG_FIFOE: FIFO empty flag + \arg EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag + \param[out] none + \retval none +*/ +void exmc_flag_clear(uint32_t exmc_bank, uint32_t flag) +{ + if(EXMC_BANK2_NAND == exmc_bank) { + /* NAND bank2 */ + EXMC_NINTEN &= ~flag; + } else { + /* SDRAM device0 or device1 */ + EXMC_SDARI |= EXMC_SDARI_REC; + } +} + +/*! + \brief enable EXMC interrupt + \param[in] exmc_bank: specify the NAND bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt: specify get which interrupt flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_INT_FLAG_LEVEL: high-level interrupt flag + \arg EXMC_NAND_INT_FLAG_RISE: rising edge interrupt flag + \arg EXMC_NAND_INT_FLAG_FALL: falling edge interrupt flag + \arg EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt flag + \param[out] none + \retval none +*/ +void exmc_interrupt_enable(uint32_t exmc_bank, uint32_t interrupt) +{ + if(EXMC_BANK2_NAND == exmc_bank) { + /* NAND bank2 */ + EXMC_NINTEN |= interrupt; + } else { + /* SDRAM device0 or device1 */ + EXMC_SDARI |= EXMC_SDARI_REIE; + } +} + +/*! + \brief disable EXMC interrupt + \param[in] exmc_bank: specify the NAND bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt: specify get which interrupt flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_INT_LEVEL: high-level interrupt + \arg EXMC_NAND_INT_RISE: rising edge interrupt + \arg EXMC_NAND_INT_FALL: falling edge interrupt + \arg EXMC_SDRAM_INT_REFRESH: refresh error interrupt + \param[out] none + \retval none +*/ +void exmc_interrupt_disable(uint32_t exmc_bank, uint32_t interrupt) +{ + if(EXMC_BANK2_NAND == exmc_bank) { + /* NAND bank2 */ + EXMC_NINTEN &= ~interrupt; + } else { + /* SDRAM device0 or device1 */ + EXMC_SDARI &= ~EXMC_SDARI_REIE; + } +} + +/*! + \brief get EXMC interrupt flag + \param[in] exmc_bank: specify the NAND bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt: EXMC interrupt flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_INT_FLAG_LEVEL: high-level interrupt flag + \arg EXMC_NAND_INT_FLAG_RISE: rising edge interrupt flag + \arg EXMC_NAND_INT_FLAG_FALL: falling edge interrupt flag + \arg EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank, uint32_t interrupt) +{ + uint32_t reg_value = 0x00000000U; + uint32_t interrupt_enable = 0x00000000U; + uint32_t interrupt_status = 0x00000000U; + + if(EXMC_BANK2_NAND == exmc_bank) { + /* NAND bank2 */ + reg_value = EXMC_NINTEN; + interrupt_status = (reg_value & (interrupt >> NINTEN_INTEN_INTS_INTERVAL)); + } else { + /* SDRAM device0 or device1 */ + reg_value = EXMC_SDARI; + interrupt_status = (EXMC_SDSTAT & EXMC_SDSDAT_REIF); + } + + interrupt_enable = (reg_value & interrupt); + + if((interrupt_enable) && (interrupt_status)) { + /* interrupt flag is set */ + return SET; + } else { + /* interrupt flag is reset */ + return RESET; + } +} + +/*! + \brief clear EXMC interrupt flag + \param[in] exmc_bank: specify the NAND bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt: EXMC interrupt flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_INT_FLAG_LEVEL: high-level interrupt and flag + \arg EXMC_NAND_INT_FLAG_RISE: rising edge interrupt and flag + \arg EXMC_NAND_INT_FLAG_FALL: falling edge interrupt and flag + \arg EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag + \param[out] none + \retval none +*/ +void exmc_interrupt_flag_clear(uint32_t exmc_bank, uint32_t interrupt) +{ + if(EXMC_BANK2_NAND == exmc_bank) { + /* NAND bank2 */ + EXMC_NINTEN &= ~(interrupt >> NINTEN_INTEN_INTS_INTERVAL); + } else { + /* SDRAM device0 or device1 */ + EXMC_SDARI |= EXMC_SDARI_REC; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exti.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exti.c new file mode 100644 index 0000000000..8bbf40edf3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_exti.c @@ -0,0 +1,254 @@ +/*! + \file gd32h7xx_exti.c + \brief EXTI driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_exti.h" + +#define EXTI_REG_RESET_VALUE ((uint32_t)0x00000000U) + +/*! + \brief deinitialize the EXTI + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of all the EXTI registers */ + EXTI_INTEN0 = EXTI_REG_RESET_VALUE; + EXTI_EVEN0 = EXTI_REG_RESET_VALUE; + EXTI_RTEN0 = EXTI_REG_RESET_VALUE; + EXTI_FTEN0 = EXTI_REG_RESET_VALUE; + EXTI_SWIEV0 = EXTI_REG_RESET_VALUE; + EXTI_INTEN1 = EXTI_REG_RESET_VALUE; + EXTI_EVEN1 = EXTI_REG_RESET_VALUE; + EXTI_RTEN1 = EXTI_REG_RESET_VALUE; + EXTI_FTEN1 = EXTI_REG_RESET_VALUE; + EXTI_SWIEV1 = EXTI_REG_RESET_VALUE; +} + +/*! + \brief initialize the EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[in] mode: interrupt or event mode, refer to exti_mode_enum + only one parameter can be selected which is shown as below: + \arg EXTI_INTERRUPT: interrupt mode + \arg EXTI_EVENT: event mode + \param[in] trig_type: interrupt and event trigger type, refer to exti_trig_type_enum + only one parameter can be selected which is shown as below: + \arg EXTI_TRIG_RISING: rising edge trigger + \arg EXTI_TRIG_FALLING: falling trigger + \arg EXTI_TRIG_BOTH: rising and falling trigger + \arg EXTI_TRIG_NONE: without rising edge or falling edge trigger + \param[out] none + \retval none +*/ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type) +{ + /* reset the EXTI line x */ + EXTI_INTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); + EXTI_EVEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); + EXTI_RTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); + EXTI_FTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); + + /* set the EXTI mode and enable the interrupts or events from EXTI line x */ + switch(mode) { + case EXTI_INTERRUPT: + EXTI_INTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); + break; + case EXTI_EVENT: + EXTI_EVEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); + break; + default: + break; + } + + /* set the EXTI trigger type */ + switch(trig_type) { + case EXTI_TRIG_RISING: + EXTI_RTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); + EXTI_FTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); + break; + case EXTI_TRIG_FALLING: + EXTI_RTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); + EXTI_FTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); + break; + case EXTI_TRIG_BOTH: + EXTI_RTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); + EXTI_FTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); + break; + case EXTI_TRIG_NONE: + default: + break; + } +} + +/*! + \brief enable the interrupts from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_enable(exti_line_enum linex) +{ + EXTI_INTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); +} + +/*! + \brief disable the interrupts from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); +} + +/*! + \brief enable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); +} + +/*! + \brief disable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); +} + +/*! + \brief enable the software interrupt event from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_enable(exti_line_enum linex) +{ + EXTI_SWIEV(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex); +} + +/*! + \brief disable the software interrupt event from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex); +} + +/*! + \brief get EXTI line x interrupt pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if(RESET != (EXTI_PD(EXTI_REG_VAL(linex)) & EXTI_BIT_POS(linex))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear EXTI line x interrupt pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD(EXTI_REG_VAL(linex)) = EXTI_BIT_POS(linex); +} + +/*! + \brief get EXTI line x interrupt pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + if(RESET != (EXTI_PD(EXTI_REG_VAL(linex)) & EXTI_BIT_POS(linex))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear EXTI line x interrupt pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..37): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD(EXTI_REG_VAL(linex)) = EXTI_BIT_POS(linex); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fac.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fac.c new file mode 100644 index 0000000000..958c1f1293 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fac.c @@ -0,0 +1,659 @@ +/*! + \file gd32h7xx_fac.c + \brief FAC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_fac.h" +#include + +/*! + \brief reset FAC peripheral + \param[in] none + \param[out] none + \retval none +*/ +void fac_deinit(void) +{ + rcu_periph_reset_enable(RCU_FACRST); + rcu_periph_reset_disable(RCU_FACRST); +} + +/*! + \brief initialize the FAC filter parameter struct with the default values + \param[in] fac_parameter: fac parameter struct + \param[out] none + \retval none +*/ +void fac_struct_para_init(fac_parameter_struct *fac_parameter) +{ + fac_parameter->input_addr = 0U; + fac_parameter->input_size = 0U; + fac_parameter->input_threshold = 0U; + fac_parameter->coeff_addr = 0U; + fac_parameter->coeff_size = 0U; + fac_parameter->output_addr = 0U; + fac_parameter->output_size = 0U; + fac_parameter->output_threshold = 0U; + fac_parameter->clip = 0U; + fac_parameter->func = 0U; + fac_parameter->ipp = 0U; + fac_parameter->ipq = 0U; + fac_parameter->ipr = 0U; +} + +/*! + \brief initialize the FAC fixed data preload parameter struct with the default values + \param[in] fac_parameter: fac parameter struct + \param[out] none + \retval none +*/ +void fac_fixed_data_preload_init(fac_fixed_data_preload_struct *init_struct) +{ + init_struct->coeffa_size = 0U; + init_struct->coeffa_ctx = 0U; + init_struct->coeffb_size = 0U; + init_struct->coeffb_ctx = 0U; + init_struct->input_size = 0U; + init_struct->input_ctx = 0U; + init_struct->output_size = 0U; + init_struct->output_ctx = 0U; +} + +/*! + \brief initialize the FAC float data preload parameter struct with the default values + \param[in] fac_parameter: fac parameter struct + \param[out] none + \retval none +*/ +void fac_float_data_preload_init(fac_float_data_preload_struct *init_struct) +{ + init_struct->coeffa_size = 0U; + init_struct->coeffa_ctx = 0U; + init_struct->coeffb_size = 0U; + init_struct->coeffb_ctx = 0U; + init_struct->input_size = 0U; + init_struct->input_ctx = 0U; + init_struct->output_size = 0U; + init_struct->output_ctx = 0U; +} + +/*! + \brief initialize the FAC peripheral + \param[in] init_struct: the data needed to initialize FAC + input_addr: x0 buffer base address, 0..255 + input_size: x0 buffer size, 0..255 + input_threshold: FAC_THRESHOLD_1, FAC_THRESHOLD_2, + FAC_THRESHOLD_4, FAC_THRESHOLD_8 + coeff_addr: x1 buffer base address, 0..255 + coeff_size: x1 buffer size, 0..255 + output_addr: Y buffer base address, 0..255 + output_size: Y buffer size, 0..255 + output_threshold: FAC_THRESHOLD_1, FAC_THRESHOLD_2, + FAC_THRESHOLD_4, FAC_THRESHOLD_8 + clip: enable or disable the clipping feature + ipp: value IPP (vector length, number of filter taps, etc.) + ipq: value IPQ (vector length, etc.) + ipr: value IPR (gain, etc.) + \param[out] none + \retval none +*/ +void fac_init(fac_parameter_struct *fac_parameter) +{ + /* FAC_X0BCFG: configure the input X0 buffer */ + FAC_X0BCFG = ((((uint32_t)fac_parameter->input_addr) & FAC_X0BCFG_X0B_ADDR) | \ + ((((uint32_t)fac_parameter->input_size) << 8U) & FAC_X0BCFG_X0B_SIZE)); + + /* FAC_X0BCFG: configure the input X0 threshold */ + FAC_X0BCFG |= (((uint32_t)fac_parameter->input_threshold) & FAC_X0BCFG_X0_WBFF); + + /* FAC_X1BCFG: configure the coefficient X1 buffer */ + FAC_X1BCFG = ((((uint32_t)fac_parameter->coeff_addr) & FAC_X1BCFG_X1B_ADDR) | \ + ((((uint32_t)fac_parameter->coeff_size) << 8U) & FAC_X1BCFG_X1B_SIZE)); + + /* FAC_YBCFG: configure the output Y buffer */ + FAC_YBCFG = ((((uint32_t)fac_parameter->output_addr) & FAC_YBCFG_YB_ADDR) | \ + ((((uint32_t)fac_parameter->output_size) << 8U) & FAC_YBCFG_YB_SIZE)); + + /* FAC_YBCFG: configure the output Y threshold */ + FAC_YBCFG |= (((uint32_t)fac_parameter->output_threshold) & FAC_YBCFG_Y_WBEF); + + /* FAC_CTL: configure the state of clip */ + FAC_CTL |= ((((uint32_t)fac_parameter->clip) << 15U) & FAC_CTL_CPEN); +} + +/*! + \brief FAC preload X0 X1 Y fixed buffer + \param[in] init_struct: FAC preload init struct + coeffa_size: size of the coefficient vector A,0~255 + coeffa_ctx: [IIR only] content of the coefficient vector A + coeffb_size: size of the coefficient vector B + coeffb_ctx: size of the coefficient vector B + input_size: size of the input data,0~255 + input_ctx: content of the input data + output_size: size of the output data,0~255 + output_ctx: content of the output data + only one parameter can be selected which is shown as below: + \arg PRELOAD_DMA_MODE: preload access buffer mode with dma + \arg PRELOAD_POLLING_MODE: preload access buffer mode with polling + \param[out] none + \retval none +*/ +void fac_fixed_buffer_preload(fac_fixed_data_preload_struct *init_struct) +{ + /* FAC_PARACFG: configure parameter of filter preload */ + FAC_PARACFG = ((uint32_t)init_struct->input_size & FAC_PARACFG_IPP) | \ + FUNC_LOAD_X0 | FAC_PARACFG_EXE; + + /* load the X0 buffer for input data */ + fac_fixed_data_preload(init_struct->input_size, init_struct->input_ctx); + /* configure dma for X0 preload */ + + /* FAC_PARACFG: configure parameter of filter preload */ + FAC_PARACFG = (((uint32_t)init_struct->coeffb_size) & FAC_PARACFG_IPP) | \ + ((((uint32_t)init_struct->coeffa_size) << 8) & FAC_PARACFG_IPQ) | \ + FUNC_LOAD_X1 | FAC_PARACFG_EXE; + + /* load the x1 buffer for cofficientB */ + fac_fixed_data_preload(init_struct->coeffb_size, (init_struct->coeffb_ctx)); + + /* load the x1 buffer for cofficientA */ + if((NULL != init_struct->coeffa_ctx) && (0U != init_struct->coeffa_size)) { + /* Load the buffer into the internal memory */ + fac_fixed_data_preload(init_struct->coeffa_size, (init_struct->coeffa_ctx)); + } + /* if need configure to preload output buffer */ + if((NULL != init_struct->output_ctx) && (0U != init_struct->output_size)) { + FAC_PARACFG = ((uint32_t)init_struct->output_size & FAC_PARACFG_IPP) | \ + FUNC_LOAD_Y | FAC_PARACFG_EXE; + + /* load the Y buffer for input data */ + fac_fixed_data_preload(init_struct->output_size, init_struct->output_ctx); + } +} + +/*! + \brief FAC preload X0 X1 Y float buffer + \param[in] init_struct: FAC preload init struct + coeffa_size: size of the coefficient vector A,0~255 + coeffa_ctx: [IIR only] content of the coefficient vector A + coeffb_size: size of the coefficient vector B + coeffb_ctx: size of the coefficient vector B + input_size: size of the input data,0~255 + input_ctx: content of the input data + output_size: size of the output data,0~255 + output_ctx: content of the output data + only one parameter can be selected which is shown as below: + \arg PRELOAD_DMA_MODE: preload access buffer mode with dma + \arg PRELOAD_POLLING_MODE: preload access buffer mode with polling + \param[out] none + \retval none +*/ +void fac_float_buffer_preload(fac_float_data_preload_struct *init_struct) +{ + /* FAC_PARACFG: Config parameter of filter preload */ + FAC_PARACFG = ((uint32_t)init_struct->input_size & FAC_PARACFG_IPP) | \ + FUNC_LOAD_X0 | FAC_PARACFG_EXE; + + /* load the x0 buffer for input data */ + fac_float_data_preload(init_struct->input_size, init_struct->input_ctx); + /* configure dma for x0 preload */ + /* FAC_PARACFG: Config parameter of filter preload */ + FAC_PARACFG = (((uint32_t)init_struct->coeffb_size) & FAC_PARACFG_IPP) | \ + ((((uint32_t)init_struct->coeffa_size) << 8) & FAC_PARACFG_IPQ) | \ + FUNC_LOAD_X1 | FAC_PARACFG_EXE; + + /* load the x1 buffer for cofficientB */ + fac_float_data_preload(init_struct->coeffb_size, (init_struct->coeffb_ctx)); + + /* load the x1 buffer for cofficientA */ + if((NULL != init_struct->coeffa_ctx) && (0U != init_struct->coeffa_size)) { + /* load the buffer into the internal memory */ + fac_float_data_preload(init_struct->coeffa_size, (init_struct->coeffa_ctx)); + } + /* if need configure to preload output buffer */ + if((NULL != init_struct->output_ctx) && (0U != init_struct->output_size)) { + FAC_PARACFG = ((uint32_t)init_struct->output_size & FAC_PARACFG_IPP) | \ + FUNC_LOAD_Y | FAC_PARACFG_EXE; + + /* load the Y buffer for input data */ + fac_float_data_preload(init_struct->output_size, init_struct->output_ctx); + } +} +/*! + \brief FAC preload fixed data pointer + \param[in] array: 16-bit data + \param[in] size: size of data + \param[out] none + \retval none +*/ +void fac_fixed_data_preload(uint8_t size, int16_t array[]) +{ + uint8_t i; + for(i = 0U; i < size; i++) { + FAC_WDATA = ((*((uint16_t*)&array[i])) & FAC_WDATA_WDATA); + } +} + +/*! + \brief FAC preload float data pointer + \param[in] data: 32-bit data + \param[in] size: size of data + \param[out] none + \retval none +*/ +void fac_float_data_preload(uint8_t size, float array[]) +{ + uint8_t i; + for(i = 0U; i < size; i++) { + FAC_WDATA = ((*((uint32_t*) & array[i]))); + } +} + +/*! + \brief FAC reset write and read pointers. the internal control logic,FAC_STAT register and the FAC_PARACFG register is reset + \param[in] none + \param[out] none + \retval none +*/ +void fac_reset(void) +{ + FAC_CTL |= FAC_CTL_RST; +} + +/*! + \brief configure the FAC clip feature + \param[in] cpmod: the state of clip + only one parameter can be selected which is shown as below: + \arg FAC_CP_ENABLE: ENABLE CLIP + \arg FAC_CP_DISABLE: DISABLE CLIP + \param[out] none + \retval none +*/ +void fac_clip_config(uint8_t cpmod) +{ + if(FAC_CP_ENABLE == cpmod) { + FAC_CTL |= FAC_CTL_CPEN; + } else { + FAC_CTL &= ~(FAC_CTL_CPEN); + } +} + +/*! + \brief enable FAC float point format + \param[in] none + \param[out] none + \retval none +*/ +void fac_float_enable(void) +{ + FAC_CTL |= FAC_CTL_FLTEN; +} + +/*! + \brief disable FAC float point format + \param[in] none + \param[out] none + \retval none +*/ +void fac_float_disable(void) +{ + FAC_CTL &= ~FAC_CTL_FLTEN; +} + +/*! + \brief enable the FAC DMA + \param[in] dma_req: dma transfer type + only one parameter can be selected which is shown as below: + \arg FAC_DMA_READ: read buffer dma + \arg FAC_DMA_WRITE: write buffer dma + \param[out] none + \retval none +*/ +void fac_dma_enable(uint32_t dma_req) +{ + FAC_CTL |= dma_req; +} + +/*! + \brief disable the FAC DMA + \param[in] dma_req: dma transfer type + only one parameter can be selected which is shown as below: + \arg FAC_DMA_READ: read buffer dma + \arg FAC_DMA_WRITE: write buffer dma + \param[out] none + \retval none +*/ +void fac_dma_disable(uint32_t dma_req) +{ + FAC_CTL &= ~dma_req; +} + +/*! + \brief FAC configure input buffer + \param[in] watermark: threshold of input buffer + FAC_THRESHOLD_1, FAC_THRESHOLD_2, + FAC_THRESHOLD_4, FAC_THRESHOLD_8 + \param[in] baseaddr: base address of input buffer, 0..255 + \param[in] bufsize: buffer size of input buffer, 0..255 + \param[out] none + \retval none +*/ +void fac_x0_config(uint32_t watermark, uint8_t baseaddr, uint8_t bufsize) +{ + /* set base address */ + FAC_X0BCFG &= ~FAC_X0BCFG_X0B_ADDR; + FAC_X0BCFG |= ((uint32_t)baseaddr); + + /* set buffer size */ + FAC_X0BCFG &= ~FAC_X0BCFG_X0B_SIZE; + FAC_X0BCFG |= (((uint32_t)bufsize) << 8U); + + /* set watermark */ + FAC_X0BCFG &= ~FAC_X0BCFG_X0_WBFF; + FAC_X0BCFG |= watermark; +} + +/*! + \brief FAC configure coefficient buffer + \param[in] baseaddr: base address of coefficient buffer, 0..255 + \param[in] bufsize: buffer size of coefficient buffer, 0..255 + \param[out] none + \retval none +*/ +void fac_x1_config(uint8_t baseaddr, uint8_t bufsize) +{ + /* set base address */ + FAC_X1BCFG &= ~FAC_X1BCFG_X1B_ADDR; + FAC_X1BCFG |= ((uint32_t)baseaddr); + + /* set buffer size */ + FAC_X1BCFG &= ~FAC_X1BCFG_X1B_SIZE; + FAC_X1BCFG |= (((uint32_t)bufsize) << 8U); +} + +/*! + \brief FAC configure output buffer + \param[in] watermark: threshold of output buffer + FAC_THRESHOLD_1, FAC_THRESHOLD_2, + FAC_THRESHOLD_4, FAC_THRESHOLD_8 + \param[in] baseaddr: base address of output buffer, 0..255 + \param[in] bufsize: buffer size of output buffer, 0..255 + \param[out] none + \retval none +*/ +void fac_y_config(uint32_t watermark, uint8_t baseaddr, uint8_t bufsize) +{ + /* set base address */ + FAC_YBCFG &= ~FAC_YBCFG_YB_ADDR; + FAC_YBCFG |= ((uint32_t)baseaddr); + + /* set buffer size */ + FAC_YBCFG &= ~FAC_YBCFG_YB_SIZE; + FAC_YBCFG |= (((uint32_t)bufsize) << 8U); + + /* set watermark */ + FAC_YBCFG &= ~FAC_YBCFG_Y_WBEF; + FAC_YBCFG |= watermark; +} + +/*! + \brief FAC configure execute function + \param[in] func: select function to excute + FUNC_CONVO_FIR, FUNC_IIR_DIRECT_FORM_1 + \param[in] ipp: parameter of forward coefficient, 2..64 + \param[in] ipq: parameter of backward coefficient, 1..63 + \param[in] ipr: parameter of gain, 0..7 + \param[out] none + \retval none +*/ +void fac_function_config(fac_parameter_struct *fac_parameter) +{ + /* set function */ + FAC_PARACFG &= ~FAC_PARACFG_FUN; + FAC_PARACFG |= fac_parameter->func; + + /* set filter parameter */ + FAC_PARACFG &= ~(FAC_PARACFG_IPP | FAC_PARACFG_IPQ | FAC_PARACFG_IPR); + FAC_PARACFG |= ((uint32_t)fac_parameter->ipp) | (((uint32_t)fac_parameter->ipq) << 8U) | (((uint32_t)fac_parameter->ipr) << 16U); +} + +/*! + \brief start the fac + \param[in] none + \param[out] none + \retval none +*/ +void fac_start(void) +{ + /* set start */ + FAC_PARACFG |= FAC_PARACFG_EXE; +} + +/*! + \brief stop the fac + \param[in] none + \param[out] none + \retval none +*/ +void fac_stop(void) +{ + /* set start */ + FAC_PARACFG &= ~FAC_PARACFG_EXE; +} + +/*! + \brief finish the filter calculate + \param[in] none + \param[out] none + \retval none +*/ +void fac_finish_calculate(void) +{ + /* clear execute */ + FAC_PARACFG &= ~FAC_PARACFG_EXE; + + /* disable read and write interrupt */ + fac_interrupt_disable(FAC_CTL_RIE | FAC_CTL_WIE); + + /* disable read and write dma */ + fac_dma_disable(FAC_DMA_READ); + fac_dma_disable(FAC_DMA_WRITE); + + /* reset register and pointer */ + FAC_CTL |= FAC_CTL_RST; +} + +/*! + \brief FAC write data with fixed ponit format + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void fac_fixed_data_write(int16_t data) +{ + FAC_WDATA_INT = (int16_t)data; +} + +/*! + \brief FAC read data with fixed point format + \param[in] none + \param[out] none + \retval 16-bit data +*/ +int16_t fac_fixed_data_read(void) +{ int16_t value; + value = (int16_t)FAC_RDATA_INT; + return value; +} + +/*! + \brief FAC write data with float ponit format + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void fac_float_data_write(float data) +{ + FAC_WDATA_FLOAT = (float)data; +} + +/*! + \brief FAC read data with fixed point format + \param[in] none + \param[out] none + \retval 16-bit data +*/ +float fac_float_data_read(void) +{ + float value; + value = (float)FAC_RDATA_FLOAT; + return value; +} + +/*! + \brief enable the FAC Interrupt + \param[in] interrupt: FAC Interrupt + only one parameter can be selected which is shown as below: + \arg FAC_CTL_RIE: Read buffer interrupt + \arg FAC_CTL_WIE: Write buffer interrupt + \arg FAC_CTL_OFEIE: Overflow error interrupt + \arg FAC_CTL_UFEIE: Underflow error interrupt + \arg FAC_CTL_STEIE: Saturation error interrupt + \arg FAC_CTL_GSTEIE: gain saturation error interrupt + \param[out] none + \retval none +*/ +void fac_interrupt_enable(uint32_t interrupt) +{ + FAC_CTL |= interrupt; +} + +/*! + \brief disable the FAC Interrupt + \param[in] interrupt: FAC Interrupt + only one parameter can be selected which is shown as below: + \arg FAC_CTL_RIE: Read buffer interrupt + \arg FAC_CTL_WIE: Write buffer interrupt + \arg FAC_CTL_OFEIE: Overflow error interrupt + \arg FAC_CTL_UFEIE: Underflow error interrupt + \arg FAC_CTL_STEIE: Saturation error interrupt + \arg FAC_CTL_GSTEIE: gain saturation error interrupt + \param[out] none + \retval none +*/ +void fac_interrupt_disable(uint32_t interrupt) +{ + FAC_CTL &= ~interrupt; +} + +/*! + \brief get FAC interrupt flag status + \param[in] interrupt: FAC interrupt flag status + only one parameter can be selected which is shown as below: + \arg FAC_INT_FLAG_YBEF: Y buffer read interrupt flag + \arg FAC_INT_FLAG_X0BFF: X0 buffer write interrupt flag + \arg FAC_INT_FLAG_OFEF: overflow error interrupt flag + \arg FAC_INT_FLAG_UFEF: underflow error interrupt flag + \arg FAC_INT_FLAG_STEF: saturation error interrupt flag + \arg FAC_INT_FLAG_GSTEF: gain saturation error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fac_interrupt_flag_get(uint8_t interrupt) +{ + uint32_t reg1 = FAC_CTL; + uint32_t reg2 = FAC_STAT; + + switch(interrupt) { + /* Y buffer read interrupt */ + case FAC_INT_FLAG_YBEF: + reg1 = reg1 & FAC_CTL_RIE; + reg2 = (((reg2 & FAC_STAT_YBEF) == 0U)?FAC_STAT_YBEF:0U); + break; + /* X0 buffer write interrupt */ + case FAC_INT_FLAG_X0BFF: + reg1 = reg1 & FAC_CTL_WIE; + reg2 = (((reg2 & FAC_STAT_X0BFF) == 0U)?FAC_STAT_X0BFF:0U); + break; + /* overflow error interrupt */ + case FAC_INT_FLAG_OFEF: + reg1 = reg1 & FAC_CTL_OFEIE; + reg2 = reg2 & FAC_STAT_OFEF; + break; + /* underflow error interrupt */ + case FAC_INT_FLAG_UFEF: + reg1 = reg1 & FAC_CTL_UFEIE; + reg2 = reg2 & FAC_STAT_UFEF; + break; + /* saturation error interrupt */ + case FAC_INT_FLAG_STEF: + reg1 = reg1 & FAC_CTL_STEIE; + reg2 = reg2 & FAC_STAT_STEF; + break; + /* saturation error interrupt */ + case FAC_INT_FLAG_GSTEF: + reg1 = reg1 & FAC_CTL_GSTEIE; + reg2 = reg2 & FAC_STAT_GSTEF; + break; + default : + break; + } + /*get FAC interrupt flag status */ + if(reg1 && reg2) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief get FAC flag status + \param[in] flag: FAC flag status + only one parameter can be selected which is shown as below: + \arg FAC_FLAG_YBEF: Y buffer empty flag + \arg FAC_FLAG_X0BFF: X0 buffer full flag + \arg FAC_FLAG_OFEF: overflow error flag + \arg FAC_FLAG_UFEF: underflow error flag + \arg FAC_FLAG_STEF: saturation error flag + \arg FAC_FLAG_GSTEF: gain saturation error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fac_flag_get(uint32_t flag) +{ + if(FAC_STAT & flag) { + return SET; + } else { + return RESET; + } +} + diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fmc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fmc.c new file mode 100644 index 0000000000..3b5e573e52 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fmc.c @@ -0,0 +1,1755 @@ +/*! + \file gd32h7xx_fmc.c + \brief FMC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_fmc.h" + +#define FLASH_DENSITY_ADDRESS ((uint32_t)0x1FF0F7E0U) /*!< memory density information address */ +#define FLASH_DENSITY_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of FLASH_DENSITY in memory density information */ + +/* FMC register bit offset */ +#define BTADDR_BOOT_ADDR0_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of BOOT_ADDR0 in FMC_BTADDR_EFT/FMC_BTADDR_MDF register*/ +#define BTADDR_BOOT_ADDR1_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BOOT_ADDR1 in FMC_BTADDR_EFT/FMC_BTADDR_MDF register */ +#define SCRADDR_SCR_AREA_START_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of SCR_AREA_START in FMC_SCRADDR_EFT/FMC_SCRADDR_MDF register */ +#define SCRADDR_SCR_AREA_END_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SCR_AREA_END in FMC_SCRADDR_EFT/FMC_SCRADDR_MDF register */ +#define DCRPADDR_DCRP_AREA_START_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of DCRP_AREA_START in FMC_DCRPADDR_EFT/FMC_DCRPADDR_MDF register */ +#define DCRPADDR_DCRP_AREA_END_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of DCRP_AREA_END in FMC_DCRPADDR_EFT/FMC_DCRPADDR_MDF register */ +#define OBSTAT0_SPC_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of SPC in FMC_OBSTAT0_EFT/FMC_OBSTAT0_MDF register */ +#define OBSTAT1_DATA_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of DATA in FMC_OBSTAT1_EFT/FMC_OBSTAT1_MDF register */ +#define NODEC_NODEC_AREA_START_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of SCR_AREA_START in FMC_SCRADDR_EFT/FMC_SCRADDR_MDF register */ +#define NODEC_NODEC_AREA_END_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SCR_AREA_END in FMC_SCRADDR_EFT/FMC_SCRADDR_MDF register */ + +/* option byte factory value */ +#define OB_OBSTAT0_FACTORY_VALUE ((uint32_t)0x01C6AAD0U) /*!< the factory value of option byte in FMC_OBSTAT0_EFT/FMC_OBSTAT0_MDF */ +#define OB_OBSTAT1_FACTORY_VALUE ((uint32_t)0x00000087U) /*!< the factory value of option byte in FMC_OBSTAT1_EFT/FMC_OBSTAT1_MDF */ +#define OB_BTADDR_FACTORY_VALUE ((uint32_t)0x1FF00800U) /*!< the factory value of option byte in FMC_BTADDR_EFT/FMC_BTADDR_MDF */ +#define OB_DCRPADDR_FACTORY_VALUE ((uint32_t)0x000000FFU) /*!< the factory value of option byte in FMC_DCRPADDR_EFT/FMC_DCRPADDR_MDF */ +#define OB_SCRADDR_FACTORY_VALUE ((uint32_t)0x000000FFU) /*!< the factory value of option byte in FMC_SCRADDR_EFT/FMC_SCRADDR_MDF */ +#define OB_WP_FACTORY_VALUE ((uint32_t)0x3FFFFFFFU) /*!< the factory value of option byte in FMC_WP_EFT/FMC_WP_MDF */ + +/* invalid DCRP area value */ +#define INVALID_DCRP_START_ADDR ((uint32_t)0x000000FFU) /*!< the start address to make DCRP area invalid */ +#define INVALID_DCRP_END_ADDR ((uint32_t)0x00000000U) /*!< the end address to make DCRP area invalid */ + +/* invalid SCR area value */ +#define INVALID_SCR_START_ADDR ((uint32_t)0x000000FFU) /*!< the start address to make SCR area invalid */ +#define INVALID_SCR_END_ADDR ((uint32_t)0x00000000U) /*!< the end address to make SCR area invalid */ + +/* get FMC state */ +static fmc_state_enum fmc_state_get(void); +/* check whether FMC is ready or not */ +static fmc_state_enum fmc_ready_wait(uint32_t timeout); + +/*! + \brief unlock FMC_CTL register + \param[in] none + \param[out] none + \retval none +*/ +void fmc_unlock(void) +{ + if((RESET != (FMC_CTL & FMC_CTL_LK))) { + /* write the FMC key */ + FMC_KEY = UNLOCK_KEY0; + FMC_KEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock FMC_CTL register + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit*/ + FMC_CTL |= FMC_CTL_LK; +} + +/*! + \brief FMC erase sector + \param[in] address: address to erase + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_sector_erase(uint32_t address) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + FMC_CTL |= FMC_CTL_SER; + /* write the sector address */ + FMC_ADDR = address; + /* start sector erase */ + FMC_CTL |= FMC_CTL_START; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the SER bit */ + FMC_CTL &= (~FMC_CTL_SER); + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief FMC typical mass erase + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_typical_mass_erase(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* enable mass erase operation */ + FMC_CTL |= FMC_CTL_MER; + /* start whole chip erase */ + FMC_CTL |= FMC_CTL_START; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the MER bit */ + FMC_CTL &= ~FMC_CTL_MER; + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief FMC protection-removed mass erase + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_protection_removed_mass_erase(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* remove DCRP area */ + ob_dcrp_area_config(OB_DCRP_AREA_ERASE_ENABLE, INVALID_DCRP_START_ADDR, INVALID_DCRP_END_ADDR); + /* remove secure-access area */ + ob_secure_area_config(OB_SCR_AREA_ERASE_ENABLE, INVALID_SCR_START_ADDR, INVALID_SCR_END_ADDR); + /* disable all sectors' erase/program protection */ + ob_write_protection_disable(OB_WP_ALL); + /* enable mass erase operation */ + FMC_CTL |= FMC_CTL_MER; + /* start chip erase */ + FMC_CTL |= FMC_CTL_START; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the MER bit */ + FMC_CTL &= ~FMC_CTL_MER; + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief FMC program a word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + __ISB(); + __DSB(); + REG32(address) = data; + __ISB(); + __DSB(); + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief FMC program a double-word at the corresponding address + \param[in] address: address to program + \param[in] data: double word to program + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data) +{ + uint32_t data0, data1; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + data0 = (uint32_t)(data & 0xFFFFFFFFU); + data1 = (uint32_t)((data >> 32U) & 0xFFFFFFFFU); + if(FMC_READY == fmc_state) { + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + __ISB(); + __DSB(); + REG32(address) = data0; + REG32(address + 4U) = data1; + __ISB(); + __DSB(); + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable check programming area + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_check_programming_area_enable(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + fmc_unlock(); + FMC_CTL |= FMC_CTL_PGCHEN; + fmc_lock(); + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief disable check programming area + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_check_programming_area_disable(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + fmc_unlock(); + FMC_CTL &= ~FMC_CTL_PGCHEN; + fmc_lock(); + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief unlock the option byte operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(RESET != (FMC_OBCTL & FMC_OBCTL_OBLK)) { + /* write the FMC key */ + FMC_OBKEY = OB_UNLOCK_KEY0; + FMC_OBKEY = OB_UNLOCK_KEY1; + } +} + +/*! + \brief lock the option byte operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_lock(void) +{ + /* set the OB_LK bit */ + FMC_OBCTL |= FMC_OBCTL_OBLK; +} + +/*! + \brief send option bytes modification start command + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_start(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + /* set the OB_START bit in OBCTL register */ + FMC_OBCTL |= FMC_OBCTL_OBSTART; + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + return fmc_state; +} + +/*! + \brief modify option byte to factory value + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_factory_value_config(void) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* get the option byte security protection value */ + obstat0_reg = (FMC_OBSTAT0_EFT & FMC_OBSTAT0_EFT_SPC); + /* write factory value to FMC_OBSTAT0_MDF */ + FMC_OBSTAT0_MDF = obstat0_reg | OB_OBSTAT0_FACTORY_VALUE; + /* write factory value to FMC_OBSTAT1_MDF */ + FMC_OBSTAT1_MDF = OB_OBSTAT1_FACTORY_VALUE; + /* write factory value to FMC_BTADDR_MDF */ + FMC_BTADDR_MDF = OB_BTADDR_FACTORY_VALUE; + /* write factory value to FMC_DCRPADDR_MDF */ + FMC_DCRPADDR_MDF = OB_DCRPADDR_FACTORY_VALUE; + /* write factory value to FMC_SCRADDR_MDF */ + FMC_SCRADDR_MDF = OB_SCRADDR_FACTORY_VALUE; + /* write factory value to FMC_WP_MDF */ + FMC_WP_MDF = OB_WP_FACTORY_VALUE; + } + + fmc_state = ob_start(); + + return fmc_state; +} + +/*! + \brief enable secure access mode + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_secure_access_mode_enable(void) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat0_reg = FMC_OBSTAT0_EFT; + /* enable secure access mode */ + obstat0_reg |= FMC_OBSTAT0_MDF_SCR; + FMC_OBSTAT0_MDF = obstat0_reg; + } + + return fmc_state; +} + +/*! + \brief disable secure access mode + \param[in] none + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_secure_access_mode_disable(void) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat0_reg = FMC_OBSTAT0_EFT; + /* disable secure access mode */ + obstat0_reg &= ~FMC_OBSTAT0_MDF_SCR; + FMC_OBSTAT0_MDF = obstat0_reg; + } + + return fmc_state; +} + +/*! + \brief configure the option byte security protection level + \param[in] ob_spc: specify security protection level + only one parameter can be selected which is shown as below: + \arg FMC_NSPC: no protection + \arg FMC_LSPC: protection level low + \arg FMC_HSPC: protection level high + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_security_protection_config(uint8_t ob_spc) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat0_reg = FMC_OBSTAT0_EFT; + /* reset the OBSTAT0_SPC, set according to ob_spc */ + obstat0_reg &= ~FMC_OBSTAT0_MDF_SPC; + obstat0_reg |= ((uint32_t)ob_spc << OBSTAT0_SPC_OFFSET); + FMC_OBSTAT0_MDF = obstat0_reg; + } + + return fmc_state; +} + +/*! + \brief configure the option byte BOR threshold value + \param[in] ob_bor_th: option byte BOR threshold value + only one parameter can be selected which is shown as below: + \arg OB_BOR_TH_VALUE3: BOR threshold value 3 + \arg OB_BOR_TH_VALUE2: BOR threshold value 2 + \arg OB_BOR_TH_VALUE1: BOR threshold value 1 + \arg OB_BOR_TH_OFF: no BOR function + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_bor_threshold_config(uint32_t ob_bor_th) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat0_reg = FMC_OBSTAT0_EFT; + /* set BOR threshold level */ + obstat0_reg &= ~FMC_OBSTAT0_MDF_BOR_TH; + FMC_OBSTAT0_MDF = (uint32_t)(obstat0_reg | ob_bor_th); + } + + return fmc_state; +} + +/*! + \brief configure low power related option byte + \param[in] ob_fwdgt: option byte watchdog value + only one parameter can be selected which is shown as below: + \arg OB_FWDGT_SW: software free watchdog + \arg OB_FWDGT_HW: hardware free watchdog + \param[in] ob_deepsleep: option byte deepsleep reset value + only one parameter can be selected which is shown as below: + \arg OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode + \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode + \param[in] ob_stdby:option byte standby reset value + only one parameter can be selected which is shown as below: + \arg OB_STDBY_NRST: no reset when entering standby mode + \arg OB_STDBY_RST: generate a reset instead of entering standby mode + \param[in] ob_fwdg_suspend_deepsleep: option byte FWDG suspend status in deep-sleep mode + only one parameter can be selected which is shown as below: + \arg OB_DPSLP_FWDGT_SUSPEND: free watchdog is suspended in deep-sleep mode + \arg OB_DPSLP_FWDGT_RUN: free watchdog is running in deep-sleep mode + \param[in] ob_fwdg_suspend_standby: option byte FWDG suspend status in standby mode + only one parameter can be selected which is shown as below: + \arg OB_STDBY_FWDGT_SUSPEND: free watchdog is suspended in standby mode + \arg OB_STDBY_FWDGT_RUN: free watchdog is running in standby mode + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_low_power_config(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby, uint32_t ob_fwdg_suspend_deepsleep, + uint32_t ob_fwdg_suspend_standby) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat0_reg = FMC_OBSTAT0_EFT; + /* set according to ob_fwdgt, ob_deepsleep, ob_stdby, ob_fwdg_suspend_deepsleep, ob_fwdg_suspend_standby */ + obstat0_reg &= ~(FMC_OBSTAT0_MDF_NWDG_HW | FMC_OBSTAT0_MDF_NRST_DPSLP | FMC_OBSTAT0_MDF_NRST_STDBY + | FMC_OBSTAT0_MDF_FWDGSPD_DPSLP | FMC_OBSTAT0_MDF_FWDGSPD_STDBY); + FMC_OBSTAT0_MDF = (uint32_t)(obstat0_reg | ob_fwdgt | ob_deepsleep | ob_stdby | ob_fwdg_suspend_deepsleep | ob_fwdg_suspend_standby); + } + + return fmc_state; +} + +/*! + \brief configure TCM ECC option byte + \param[in] ob_itcmecc: ITCM ECC function enable bit + only one parameter can be selected which is shown as below: + \arg OB_ITCMECCEN_DISABLE: disabled ITCM ECC function + \arg OB_ITCMECCEN_ENABLE: enabled ITCM ECC function + \param[in] ob_dtcm0ecc: DTCM0 ECC function enable bit + only one parameter can be selected which is shown as below: + \arg OB_DTCM0ECCEN_DISABLE: disabled DTCM0 ECC function + \arg OB_DTCME0CCEN_ENABLE: enabled DTCM0 ECC function + \param[in] ob_dtcm1ecc: DTCM1 ECC function enable bit + only one parameter can be selected which is shown as below: + \arg OB_DTCM1ECCEN_DISABLE: disabled DTCM1 ECC function + \arg OB_DTCM1ECCEN_ENABLE: enabled DTCM1 ECC function + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_tcm_ecc_config(uint32_t ob_itcmecc, uint32_t ob_dtcm0ecc, uint32_t ob_dtcm1ecc) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat0_reg = FMC_OBSTAT0_EFT; + /* set according to ob_itcmecc, ob_dtcm0ecc, ob_stdby, ob_dtcm1ecc */ + obstat0_reg &= ~(FMC_OBSTAT0_MDF_ITCMECCEN | FMC_OBSTAT0_MDF_DTCM0ECCEN | FMC_OBSTAT0_MDF_DTCM1ECCEN); + FMC_OBSTAT0_MDF = (uint32_t)(obstat0_reg | ob_itcmecc | ob_dtcm0ecc | ob_dtcm1ecc); + } + + return fmc_state; +} + +/*! + \brief configure I/O speed optimization option byte + \param[in] ob_iospeed_op: configure I/O speed optimization, high-speed at low-voltage enable bit + only one parameter can be selected which is shown as below: + \arg OB_IOSPDOPEN_DISABLE: disabled I/O speed optimization + \arg OB_IOSPDOPEN_ENABLE: enabled I/O speed optimization + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_iospeed_optimize_config(uint32_t ob_iospeed_op) +{ + uint32_t obstat0_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat0_reg = FMC_OBSTAT0_EFT; + /* set according to ob_iospeed_op */ + obstat0_reg &= ~(FMC_OBSTAT0_MDF_IOSPDOPEN); + FMC_OBSTAT0_MDF = (uint32_t)(obstat0_reg | ob_iospeed_op); + } + + return fmc_state; +} + + +/*! + \brief configure option byte TCM shared RAM size + ITCM RAM + DTCM RAM size should not exceed 512KB + \param[in] itcm_shared_ram_size: ITCM shared RAM size + only one parameter can be selected which is shown as below: + \arg OB_ITCM_SHARED_RAM_0KB: ITCM shared RAM size is 0KB + \arg OB_ITCM_SHARED_RAM_64KB: ITCM shared RAM size is 64KB + \arg OB_ITCM_SHARED_RAM_128KB: ITCM shared RAM size is 128KB + \arg OB_ITCM_SHARED_RAM_256KB: ITCM shared RAM size is 256KB + \arg OB_ITCM_SHARED_RAM_512KB: ITCM shared RAM size is 512KB + \param[in] dtcm_shared_ram_size: DTCM shared RAM size + only one parameter can be selected which is shown as below: + \arg OB_DTCM_SHARED_RAM_0KB: DTCM shared RAM size is 0KB + \arg OB_DTCM_SHARED_RAM_64KB: DTCM shared RAM size is 64KB + \arg OB_DTCM_SHARED_RAM_128KB: DTCM shared RAM size is 128KB + \arg OB_DTCM_SHARED_RAM_256KB: DTCM shared RAM size is 256KB + \arg OB_DTCM_SHARED_RAM_512KB: DTCM shared RAM size is 512KB + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_tcm_shared_ram_config(uint32_t itcm_shared_ram_size, uint32_t dtcm_shared_ram_size) +{ + uint32_t obstat1_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat1_reg = FMC_OBSTAT1_EFT; + + /* set ITCM shared ram size according to itcm_shared_ram_size */ + obstat1_reg &= ~FMC_OBSTAT1_MDF_ITCM_SZ_SHRRAM; + obstat1_reg |= itcm_shared_ram_size; + + /* set DTCM shared ram size according to dtcm_shared_ram_size */ + obstat1_reg &= ~FMC_OBSTAT1_MDF_DTCM_SZ_SHRRAM; + obstat1_reg |= dtcm_shared_ram_size; + + FMC_OBSTAT1_MDF = obstat1_reg; + } + + return fmc_state; +} + +/*! + \brief modify option byte DATA + \param[in] ob_data: option bytes user data + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_data_program(uint16_t ob_data) +{ + uint32_t obstat1_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obstat1_reg = FMC_OBSTAT1_EFT; + + /* modify user data according to ob_data */ + obstat1_reg &= ~FMC_OBSTAT1_MDF_DATA; + obstat1_reg |= ((uint32_t)ob_data << OBSTAT1_DATA_OFFSET); + FMC_OBSTAT1_MDF = obstat1_reg; + } + + return fmc_state; +} + +/*! + \brief configure boot address + \param[in] boot_pin: boot pin configuration + only one parameter can be selected which is shown as below: + \arg BOOT_PIN_0: boot pin value is 0 + \arg BOOT_PIN_1: boot pin value is 1 + \param[in] boot_address: specify the MSB of boot address + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_boot_address_config(uint8_t boot_pin, uint16_t boot_address) +{ + uint32_t btaddr_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + btaddr_reg = FMC_BTADDR_EFT; + + if(BOOT_PIN_0 == boot_pin) { + /* set to boot address 0 */ + btaddr_reg &= ~FMC_BTADDR_MDF_BOOT_ADDR0; + btaddr_reg |= (uint32_t)((uint32_t)boot_address << BTADDR_BOOT_ADDR0_OFFSET); + } else { + /* set to boot address 1 */ + btaddr_reg &= ~FMC_BTADDR_MDF_BOOT_ADDR1; + btaddr_reg |= (uint32_t)((uint32_t)boot_address << BTADDR_BOOT_ADDR1_OFFSET); + } + FMC_BTADDR_MDF = btaddr_reg; + } + + return fmc_state; +} + +/*! + \brief configure DCRP area + \param[in] dcrp_eren: DCRP area erase enable bit + \arg OB_DCRP_AREA_ERASE_DISABLE: DCRP area erase disable + \arg OB_DCRP_AREA_ERASE_ENABLE: DCRP area erase enable + \param[in] dcrp_start: DCRP area start address, contain the first 4K-byte block of the DCRP area.(0 - 0x3BF) + \param[in] dcrp_end: DCRP area end address, contain the last 4K-byte block of the DCRP area.(0 - 0x3BF) + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_dcrp_area_config(uint32_t dcrp_eren, uint32_t dcrp_start, uint32_t dcrp_end) +{ + uint32_t dcrpaddr_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + dcrpaddr_reg = 0U; + dcrpaddr_reg |= dcrp_eren; + dcrpaddr_reg |= dcrp_start; + dcrpaddr_reg |= (uint32_t)(dcrp_end << DCRPADDR_DCRP_AREA_END_OFFSET); + FMC_DCRPADDR_MDF = dcrpaddr_reg; + } + + return fmc_state; +} + +/*! + \brief configure secure-access area + \param[in] scr_eren: secure-access area erase enable bit + \arg OB_SCR_AREA_ERASE_DISABLE: secure-access area erase disable + \arg OB_SCR_AREA_ERASE_ENABLE: secure-access area erase enable + \param[in] scr_start: secure-access area start address, contain the first 4K-byte block of the secure-access area.(0 - 0x3BF) + \param[in] scr_end: secure-access area end address, contain the last 4K-byte block of the secure-access area.(0 - 0x3BF) + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_secure_area_config(uint32_t scr_eren, uint32_t scr_start, uint32_t scr_end) +{ + uint32_t scraddr_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + scraddr_reg = 0U; + scraddr_reg |= scr_eren; + scraddr_reg |= scr_start; + scraddr_reg |= (uint32_t)(scr_end << SCRADDR_SCR_AREA_END_OFFSET); + FMC_SCRADDR_MDF = scraddr_reg; + } + + return fmc_state; +} + +/*! + \brief enable erase/program protection + \param[in] ob_wp: specify sector to be erase/program protected + one or more parameters can be selected which are shown as below: + \arg OB_WP_0 erase/program protect sector 0 ~ sector 15 + \arg OB_WP_1: erase/program protect sector 16 ~ sector 31 + \arg OB_WP_2: erase/program protect sector 32 ~ sector 47 + \arg OB_WP_3: erase/program protect sector 48 ~ sector 63 + \arg OB_WP_4: erase/program protect sector 64 ~ sector 79 + \arg OB_WP_5: erase/program protect sector 80 ~ sector 95 + \arg OB_WP_6: erase/program protect sector 96 ~ sector 111 + \arg OB_WP_7: erase/program protect sector 112 ~ sector 127 + \arg OB_WP_8: erase/program protect sector 128 ~ sector 143 + \arg OB_WP_9: erase/program protect sector 144 ~ sector 159 + \arg OB_WP_10: erase/program protect sector 160 ~ sector 175 + \arg OB_WP_11: erase/program protect sector 176 ~ sector 191 + \arg OB_WP_12: erase/program protect sector 192 ~ sector 207 + \arg OB_WP_13: erase/program protect sector 208 ~ sector 223 + \arg OB_WP_14: erase/program protect sector 224 ~ sector 239 + \arg OB_WP_15: erase/program protect sector 240 ~ sector 255 + \arg OB_WP_16: erase/program protect sector 256 ~ sector 383 + \arg OB_WP_17: erase/program protect sector 384 ~ sector 511 + \arg OB_WP_18: erase/program protect sector 512 ~ sector 639 + \arg OB_WP_19: erase/program protect sector 640 ~ sector 767 + \arg OB_WP_20: erase/program protect sector 768 ~ sector 895 + \arg OB_WP_21: erase/program protect sector 896 ~ sector 959 + \arg OB_WP_ALL: all sectors + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_write_protection_enable(uint32_t ob_wp) +{ + uint32_t wp_reg = FMC_WP_EFT; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + wp_reg &= ~ob_wp; + FMC_WP_MDF = wp_reg; + } + + return fmc_state; +} + +/*! + \brief disable erase/program protection + \param[in] ob_wp: specify sector to be erase/program protected + one or more parameters can be selected which are shown as below: + \arg OB_WP_0 ee/program protect sector 0 ~ sector 15 + \arg OB_WP_1: erase/program protect sector 16 ~ sector 31 + \arg OB_WP_2: erase/program protect sector 32 ~ sector 47 + \arg OB_WP_3: erase/program protect sector 48 ~ sector 63 + \arg OB_WP_4: erase/program protect sector 64 ~ sector 79 + \arg OB_WP_5: erase/program protect sector 80 ~ sector 95 + \arg OB_WP_6: erase/program protect sector 96 ~ sector 111 + \arg OB_WP_7: erase/program protect sector 112 ~ sector 127 + \arg OB_WP_8: erase/program protect sector 128 ~ sector 143 + \arg OB_WP_9: erase/program protect sector 144 ~ sector 159 + \arg OB_WP_10: erase/program protect sector 160 ~ sector 175 + \arg OB_WP_11: erase/program protect sector 176 ~ sector 191 + \arg OB_WP_12: erase/program protect sector 192 ~ sector 207 + \arg OB_WP_13: erase/program protect sector 208 ~ sector 223 + \arg OB_WP_14: erase/program protect sector 224 ~ sector 239 + \arg OB_WP_15: erase/program protect sector 240 ~ sector 255 + \arg OB_WP_16: erase/program protect sector 256 ~ sector 383 + \arg OB_WP_17: erase/program protect sector 384 ~ sector 511 + \arg OB_WP_18: erase/program protect sector 512 ~ sector 639 + \arg OB_WP_19: erase/program protect sector 640 ~ sector 767 + \arg OB_WP_20: erase/program protect sector 768 ~ sector 895 + \arg OB_WP_21: erase/program protect sector 896 ~ sector 959 + \arg OB_WP_ALL: all sectors + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum ob_write_protection_disable(uint32_t ob_wp) +{ + uint32_t wp_reg = FMC_WP_EFT; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + wp_reg |= ob_wp; + FMC_WP_MDF = wp_reg; + } + + return fmc_state; +} + +/*! + \brief get the option byte secure access mode + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ob_secure_mode_get(void) +{ + FlagStatus secure_mode_state = RESET; + + if(OB_SECURE_MODE_ENABLE == (uint32_t)(FMC_OBSTAT0_EFT & FMC_OBSTAT0_EFT_SCR)) { + secure_mode_state = SET; + } else { + secure_mode_state = RESET; + } + return secure_mode_state; +} + +/*! + \brief get the option byte security protection level + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ob_security_protection_flag_get(void) +{ + FlagStatus spc_state = RESET; + + if(((uint8_t)(FMC_OBSTAT0_EFT >> OBSTAT0_SPC_OFFSET)) != (uint8_t)FMC_NSPC) { + spc_state = SET; + } else { + spc_state = RESET; + } + return spc_state; +} + +/*! + \brief get the option byte BOR threshold value + \param[in] none + \param[out] none + \retval the BOR threshold value: + \arg OB_BOR_TH_VALUE3: BOR threshold value 3 + \arg OB_BOR_TH_VALUE2: BOR threshold value 2 + \arg OB_BOR_TH_VALUE1: BOR threshold value 1 + \arg OB_BOR_TH_OFF: no BOR function +*/ +uint32_t ob_bor_threshold_get(void) +{ + return (uint32_t)((uint32_t)FMC_OBSTAT0_EFT & FMC_OBSTAT0_EFT_BOR_TH); +} + +/*! + \brief get low power related option byte + \param[in] none + \param[out] fwdgt: watchdog option + \arg OB_FWDGT_HW: hardware free watchdog + \arg OB_FWDGT_SW: software free watchdog + \param[out] deepsleep: deepsleep reset option + \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode + \arg OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode + \param[out] standby: standby reset option + \arg OB_STDBY_RST: generate a reset instead of entering standby mode + \arg OB_STDBY_NRST: no reset when entering standby mode + \param[out] fwdg_suspend_deepsleep: FWDG suspend status in deepsleep mode option + \arg OB_DPSLP_FWDGT_SUSPEND: free watchdog is suspended in deepsleep mode + \arg OB_DPSLP_FWDGT_RUN: free watchdog is running in deepsleep mode + \param[out] fwdg_suspend_standby: FWDG suspend status in standby mode option + \arg OB_STDBY_FWDGT_SUSPEND: free watchdog is suspended in standby mode + \arg OB_STDBY_FWDGT_RUN: free watchdog is running in standby mode + \retval none +*/ +void ob_low_power_get(uint32_t *fwdgt, uint32_t *deepsleep, uint32_t *standby, uint32_t *fwdg_suspend_deepsleep, uint32_t *fwdg_suspend_standby) +{ + uint32_t obstat0_reg; + + obstat0_reg = FMC_OBSTAT0_EFT; + *fwdgt = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_NWDG_HW); + *deepsleep = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_NRST_DPSLP); + *standby = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_NRST_STDBY); + *fwdg_suspend_deepsleep = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_FWDGSPD_DPSLP); + *fwdg_suspend_standby = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_FWDGSPD_STDBY); +} + +/*! + \brief get TCM ECC configuration + \param[in] none + \param[out] itcmecc_option: CPU ITCM ECC function enable option + \arg OB_ITCMECCEN_DISABLE: ITCM ECC function disable + \arg OB_ITCMECCEN_ENABLE: ITCM ECC function enable + \param[out] dtcm0ecc_option: CPU DTCM0 ECC function enable option + \arg OB_DTCM0ECCEN_DISABLE: DTCM0 ECC function disable + \arg OB_DTCM0ECCEN_ENABLE: DTCM0 ECC function enable + \param[out] dtcm1ecc_option: CPU DTCM1 ECC function enable option + \arg OB_DTCM1ECCEN_DISABLE: DTCM1 ECC function disable + \arg OB_DTCM1ECCEN_ENABLE: DTCM1 ECC function enable + \retval none +*/ +void ob_tcm_ecc_get(uint32_t *itcmecc_option, uint32_t *dtcm0ecc_option, uint32_t *dtcm1ecc_option) +{ + uint32_t obstat0_reg; + + obstat0_reg = FMC_OBSTAT0_EFT; + *itcmecc_option = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_ITCMECCEN); + *dtcm0ecc_option = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_DTCM0ECCEN); + *dtcm1ecc_option = (uint32_t)(obstat0_reg & FMC_OBSTAT0_EFT_DTCM1ECCEN); +} + +/*! + \brief get IO speed optimize configuration + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ob_iospeed_optimize_get(void) +{ + FlagStatus iospeed_opt_state = RESET; + + if(OB_IOSPDOPEN_ENABLE == (uint32_t)(FMC_OBSTAT0_EFT & FMC_OBSTAT0_EFT_IOSPDOPEN)) { + iospeed_opt_state = SET; + } else { + iospeed_opt_state = RESET; + } + return iospeed_opt_state; +} + +/*! + \brief get the option byte TCM shared RAM size + \param[in] none + \param[out] itcm_shared_ram_kb_size: ITCM shared RAM size in KB unit + \arg OB_ITCM_SHARED_RAM_0KB: ITCM shared RAM size is 0KB + \arg OB_ITCM_SHARED_RAM_64KB: ITCM shared RAM size is 64KB + \arg OB_ITCM_SHARED_RAM_128KB: ITCM shared RAM size is 128KB + \arg OB_ITCM_SHARED_RAM_256KB: ITCM shared RAM size is 256KB + \arg OB_ITCM_SHARED_RAM_512KB: ITCM shared RAM size is 512KB + \param[out] dtcm_shared_ram_kb_size: DTCM shared RAM size in KB unit + \arg OB_DTCM_SHARED_RAM_0KB: DTCM shared RAM size is 0KB + \arg OB_DTCM_SHARED_RAM_64KB: DTCM shared RAM size is 64KB + \arg OB_DTCM_SHARED_RAM_128KB: DTCM shared RAM size is 128KB + \arg OB_DTCM_SHARED_RAM_256KB: DTCM shared RAM size is 256KB + \arg OB_DTCM_SHARED_RAM_512KB: DTCM shared RAM size is 512KB + \retval none +*/ +void ob_tcm_shared_ram_size_get(uint32_t *itcm_shared_ram_kb_size, uint32_t *dtcm_shared_ram_kb_size) +{ + uint32_t itcm_size_value, dtcm_size_value; + + itcm_size_value = (uint32_t)((uint32_t)FMC_OBSTAT1_EFT & FMC_OBSTAT1_EFT_ITCM_SZ_SHRRAM); + dtcm_size_value = (uint32_t)((uint32_t)FMC_OBSTAT1_EFT & FMC_OBSTAT1_EFT_DTCM_SZ_SHRRAM); + + switch(itcm_size_value) { + case OB_ITCM_SHARED_RAM_0KB: + /* ITCM shared RAM size is 0KB */ + *itcm_shared_ram_kb_size = 0U; + break; + case OB_ITCM_SHARED_RAM_64KB: + /* ITCM shared RAM size is 64KB */ + *itcm_shared_ram_kb_size = 64U; + break; + case OB_ITCM_SHARED_RAM_128KB: + /* ITCM shared RAM size is 128KB */ + *itcm_shared_ram_kb_size = 128U; + break; + case OB_ITCM_SHARED_RAM_256KB: + /* ITCM shared RAM size is 256KB */ + *itcm_shared_ram_kb_size = 256U; + break; + case OB_ITCM_SHARED_RAM_512KB: + /* ITCM shared RAM size is 512KB */ + *itcm_shared_ram_kb_size = 512U; + break; + default: + break; + } + + switch(dtcm_size_value) { + case OB_DTCM_SHARED_RAM_0KB: + /* DTCM shared RAM size is 0KB */ + *dtcm_shared_ram_kb_size = 0U; + break; + case OB_DTCM_SHARED_RAM_64KB: + /* DTCM shared RAM size is 64KB */ + *dtcm_shared_ram_kb_size = 64U; + break; + case OB_DTCM_SHARED_RAM_128KB: + /* DTCM shared RAM size is 128KB */ + *dtcm_shared_ram_kb_size = 128U; + break; + case OB_DTCM_SHARED_RAM_256KB: + /* DTCM shared RAM size is 256KB */ + *dtcm_shared_ram_kb_size = 256U; + break; + case OB_DTCM_SHARED_RAM_512KB: + /* DTCM shared RAM size is 512KB */ + *dtcm_shared_ram_kb_size = 512U; + break; + default: + break; + } +} + +/*! + \brief get user data value + \param[in] none + \param[out] none + \retval option bytes user data +*/ +uint16_t ob_data_get(void) +{ + return (uint16_t)(FMC_OBSTAT1_EFT >> OBSTAT1_DATA_OFFSET); +} + +/*! + \brief get boot address + \param[in] boot_pin: boot pin configuration + only one parameter can be selected which is shown as below: + \arg BOOT_PIN_0: boot pin value is 0 + \arg BOOT_PIN_1: boot pin value is 1 + \param[out] none + \retval boot_address: boot address +*/ +uint32_t ob_boot_address_get(uint8_t boot_pin) +{ + uint32_t boot_address; + uint32_t btaddr_reg = FMC_BTADDR_EFT; + + if(BOOT_PIN_0 == boot_pin) { + /* get boot address 0 */ + boot_address = (uint32_t)((btaddr_reg & FMC_BTADDR_EFT_BOOT_ADDR0) << 16u); + } else { + /* get boot address 1 */ + boot_address = (uint32_t)((btaddr_reg & FMC_BTADDR_EFT_BOOT_ADDR1)); + } + return boot_address; +} + +/*! + \brief get DCRP area configuration + \param[in] none + \param[out] dcrp_erase_option: DCRP area erase option + \arg OB_DCRP_AREA_ERASE_DISABLE: DCRP area erase disable + \arg OB_DCRP_AREA_ERASE_ENABLE: DCRP area erase enable + \param[out] dcrp_start_addr: DCRP area start address, contain the first 4K-byte block of the DCRP area.(0 - 0x3BF) + \param[out] dcrp_end_addr: DCRP area end address, contain the last 4K-byte block of the DCRP area.(0 - 0x3BF) + \retval state of DCRP area address + \arg INVLD_AREA_ADDRESS: the area address is invalid + \arg VLD_AREA_ADDRESS: the area address is valid +*/ +uint8_t ob_dcrp_area_get(uint32_t *dcrp_erase_option, uint32_t *dcrp_area_start_addr, uint32_t *dcrp_area_end_addr) +{ + uint32_t dcrpaddr_reg; + uint32_t main_flash_size; + dcrpaddr_reg = FMC_DCRPADDR_EFT; + main_flash_size = REG32(FLASH_DENSITY_ADDRESS) >> FLASH_DENSITY_OFFSET; + + /* get DCRP area erase option */ + *dcrp_erase_option = (uint32_t)(dcrpaddr_reg & FMC_DCRPADDR_EFT_DCRP_EREN); + *dcrp_area_start_addr = ((uint32_t)(dcrpaddr_reg & FMC_DCRPADDR_EFT_DCRP_AREA_START)) >> DCRPADDR_DCRP_AREA_START_OFFSET; + *dcrp_area_end_addr = ((uint32_t)(dcrpaddr_reg & FMC_DCRPADDR_EFT_DCRP_AREA_END)) >> DCRPADDR_DCRP_AREA_END_OFFSET; + if((*dcrp_area_start_addr) == (*dcrp_area_end_addr)) { + /* the whole main flash memory is DCRP area */ + *dcrp_area_start_addr = MAIN_FLASH_BASE_ADDRESS; + *dcrp_area_end_addr = MAIN_FLASH_BASE_ADDRESS + main_flash_size - 1U; + return VLD_AREA_ADDRESS; + } else if((*dcrp_area_start_addr) < (*dcrp_area_end_addr)) { + /* get DCRP area start address */ + *dcrp_area_start_addr = (*dcrp_area_start_addr) * DCRP_SIZE_UNIT; + *dcrp_area_start_addr += MAIN_FLASH_BASE_ADDRESS; + /* get DCRP area end address */ + *dcrp_area_end_addr = ((*dcrp_area_end_addr) + 1U) * DCRP_SIZE_UNIT - 1U; + *dcrp_area_end_addr += MAIN_FLASH_BASE_ADDRESS; + return VLD_AREA_ADDRESS; + } else { + /* no valid DCRP area */ + return INVLD_AREA_ADDRESS; + } +} + +/*! + \brief get secure-access area configuration + \param[in] none + \param[out] secure_erase_option: secure-access area erase option + \arg OB_SCR_AREA_ERASE_DISABLE: secure-access area erase disable + \arg OB_SCR_AREA_ERASE_ENABLE: secure-access area erase enable + \param[out] scr_area_start_addr: secure-access area start address, contain the first 4K-byte block of the secure-access area.(0 - 0x3BF) + \param[out] scr_area_end_addr: secure-access area end address, contain the last 4K-byte block of the secure-access area.(0 - 0x3BF) + \retval state of secure-access area address + \arg INVLD_AREA_ADDRESS: the area address is invalid + \arg VLD_AREA_ADDRESS: the area address is valid +*/ +uint8_t ob_secure_area_get(uint32_t *secure_area_option, uint32_t *scr_area_start_addr, uint32_t *scr_area_end_addr) +{ + uint32_t scraddr_reg; + uint32_t main_flash_size; + scraddr_reg = FMC_SCRADDR_EFT; + main_flash_size = REG32(FLASH_DENSITY_ADDRESS) >> FLASH_DENSITY_OFFSET; + + /* get secure-access area erase option */ + *secure_area_option = (uint32_t)(scraddr_reg & FMC_SCRADDR_EFT_SCR_EREN); + *scr_area_start_addr = ((uint32_t)(scraddr_reg & FMC_SCRADDR_EFT_SCR_AREA_START)) >> SCRADDR_SCR_AREA_START_OFFSET; + *scr_area_end_addr = ((uint32_t)(scraddr_reg & FMC_SCRADDR_EFT_SCR_AREA_END)) >> SCRADDR_SCR_AREA_END_OFFSET; + if((*scr_area_start_addr) == (*scr_area_end_addr)) { + /* the whole main flash memory is secure-access area */ + *scr_area_start_addr = MAIN_FLASH_BASE_ADDRESS; + *scr_area_end_addr = MAIN_FLASH_BASE_ADDRESS + main_flash_size - 1U; + return VLD_AREA_ADDRESS; + } else if((*scr_area_start_addr) < (*scr_area_end_addr)) { + /* get secure-access area start address */ + *scr_area_start_addr = (*scr_area_start_addr) * SCR_SIZE_UNIT; + *scr_area_start_addr += MAIN_FLASH_BASE_ADDRESS; + /* get secure-access area end address */ + *scr_area_end_addr = ((*scr_area_end_addr) + 1U) * SCR_SIZE_UNIT - 1U; + *scr_area_end_addr += MAIN_FLASH_BASE_ADDRESS; + return VLD_AREA_ADDRESS; + } else { + /* no valid area */ + return INVLD_AREA_ADDRESS; + } +} + +/*! + \brief get the option byte erase/program protection + \param[in] none + \param[out] none + \retval the FMC erase/program protection option byte value(0 - 0x3FFFFFFF) +*/ +uint32_t ob_write_protection_get(void) +{ + /* return the FMC erase/program protection option byte value */ + return (uint32_t)(FMC_WP_EFT); +} + +/*! + \brief configure NO-RTDEC area + \param[in] nodec_area_start: no rtdec area start address, contain the last 4K-byte block that reading main flash block without decryption. + \param[in] nodec_area_end: no rtdec area end address, contain the first 4K-byte block that reading main flash block without decryption. + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_no_rtdec_config(uint32_t nodec_area_start, uint32_t nodec_area_end) +{ + uint32_t nodec_reg; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + fmc_unlock(); + nodec_reg = 0U; + nodec_reg |= nodec_area_start; + nodec_reg |= (uint32_t)(nodec_area_end << NODEC_NODEC_AREA_END_OFFSET); + FMC_NODEC = nodec_reg; + fmc_lock(); + } + + return fmc_state; +} + +/*! + \brief configure AES initialization vector + \param[in] aes_iv: high 96 bits of AES initialization vector + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_aes_iv_config(uint32_t *aes_iv) +{ + uint32_t aes_iv_addr = (uint32_t)aes_iv; + fmc_state_enum fmc_state = FMC_READY; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + fmc_unlock(); + FMC_AESIV0_MDF = *(uint32_t *)(aes_iv_addr); + aes_iv_addr += 4U; + FMC_AESIV1_MDF = *(uint32_t *)(aes_iv_addr); + aes_iv_addr += 4U; + FMC_AESIV2_MDF = *(uint32_t *)(aes_iv_addr); + fmc_lock(); + } + + return fmc_state; +} + +/*! + \brief get Flash ECC function enable flag + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flash_ecc_get(void) +{ + return fmc_flag_get((fmc_flag_enum)FMC_FLAG_FECC); +} + +/*! + \brief get NO-RTDEC area + \param[in] none + \param[out] nodec_area_start: no rtdec area start address, contain the last 4K-byte block that reading main flash block without decryption. + \param[out] nodec_area_end: no rtdec area end address, contain the first 4K-byte block that reading main flash block without decryption. + \retval none +*/ +void fmc_no_rtdec_get(uint32_t *nodec_area_start, uint32_t *nodec_area_end) +{ + uint32_t nodec_reg; + + nodec_reg = FMC_NODEC; + *nodec_area_start = (uint32_t)(nodec_reg & FMC_NODEC_NODEC_AREA_START); + *nodec_area_end = (uint32_t)(nodec_reg & FMC_NODEC_NODEC_AREA_END); +} + +/*! + \brief get AES initialization vector + \param[in] none + \param[out] aes_iv: high 96 bits of AES initialization vector + \retval none +*/ +void fmc_aes_iv_get(uint32_t *aes_iv) +{ + uint32_t aes_iv_addr = (uint32_t)aes_iv; + *(uint32_t *)aes_iv_addr = (uint32_t)(FMC_AESIV0_EFT); + aes_iv_addr += 4U; + *(uint32_t *)aes_iv_addr = (uint32_t)(FMC_AESIV1_EFT); + aes_iv_addr += 4U; + *(uint32_t *)aes_iv_addr = (uint32_t)(FMC_AESIV2_EFT); +} + +/*! + \brief get product ID + \param[in] none + \param[out] pid: product ID + \retval none +*/ +void fmc_pid_get(uint32_t *pid) +{ + uint32_t pid_addr = (uint32_t)pid; + *(uint32_t *)pid_addr = (uint32_t)(FMC_PID0); + pid_addr += 4U; + *(uint32_t *)pid_addr = (uint32_t)(FMC_PID1); +} + +/*! + \brief get FMC flag status + \param[in] flag: FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_BUSY: flash busy flag bit + \arg FMC_FLAG_END: flash end of operation flag bit + \arg FMC_FLAG_WPERR: flash erase/program protection error flag bit + \arg FMC_FLAG_PGSERR: flash program sequence error flag bit + \arg FMC_FLAG_RPERR: flash read protection error flag bit + \arg FMC_FLAG_RSERR: flash read secure error flag bit + \arg FMC_FLAG_ECCCOR: flash one bit correct error flag bit + \arg FMC_FLAG_ECCDET: flash two bits detect error flag bit + \arg FMC_FLAG_OBMERR: flash option byte modify error flag bit + \arg FMC_FLAG_FECC: flash ECC function flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(fmc_flag_enum flag) +{ + if(RESET != (FMC_REG_VAL(flag) & BIT(FMC_BIT_POS(flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear FMC flag status + \param[in] flag: FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_END: flash end of operation flag bit + \arg FMC_FLAG_WPERR: flash erase/program protection error flag bit + \arg FMC_FLAG_PGSERR: flash program sequence error flag bit + \arg FMC_FLAG_RPERR: flash read protection error flag bit + \arg FMC_FLAG_RSERR: flash read secure error flag bit + \arg FMC_FLAG_ECCCOR: flash one bit correct error flag bit + \arg FMC_FLAG_ECCDET: flash two bits detect error flag bit + \arg FMC_FLAG_OBMERR: flash option byte modify error flag bit + \param[out] none + \retval none +*/ +void fmc_flag_clear(fmc_flag_enum flag) +{ + /* clear the flags */ + FMC_REG_VAL(flag) = BIT(FMC_BIT_POS(flag)); +} + +/*! + \brief enable FMC interrupt + \param[in] interrupt: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_INT_END : FMC end of program interrupt + \arg FMC_INT_WPERR: FMC erase/program protection error interrupt + \arg FMC_INT_PGSERR: FMC program sequence error interrupt + \arg FMC_INT_RPERR: FMC read protection error interrupt + \arg FMC_INT_RSERR: FMC read secure error interrupt + \arg FMC_INT_ECCCOR: FMC one bit correct error interrupt + \arg FMC_INT_ECCDET: FMC two bits detect error interrupt + \arg FMC_INT_OBMERR: FMC option byte modify error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(fmc_interrupt_enum interrupt) +{ + FMC_REG_VAL(interrupt) |= BIT(FMC_BIT_POS(interrupt)); +} + +/*! + \brief disable FMC interrupt + \param[in] interrupt: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_INT_END : FMC end of program interrupt + \arg FMC_INT_WPERR: FMC erase/program protection error interrupt + \arg FMC_INT_PGSERR: FMC program sequence error interrupt + \arg FMC_INT_RPERR: FMC read protection error interrupt + \arg FMC_INT_RSERR: FMC read secure error interrupt + \arg FMC_INT_ECCCOR: FMC one bit correct error interrupt + \arg FMC_INT_ECCDET: FMC two bits detect error interrupt + \arg FMC_INT_OBMERR: FMC option byte modify error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(fmc_interrupt_enum interrupt) +{ + FMC_REG_VAL(interrupt) &= ~BIT(FMC_BIT_POS(interrupt)); +} + +/*! + \brief get FMC interrupt flag status + \param[in] flag: FMC interrupt flag + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_END: flash end of operation interrupt flag + \arg FMC_INT_FLAG_WPERR: flash erase/program protection error interrupt flag + \arg FMC_INT_FLAG_PGSERR: flash program sequence error interrupt flag + \arg FMC_INT_FLAG_RPERR: flash read protection error interrupt flag + \arg FMC_INT_FLAG_RSERR: flash read secure error interrupt flag + \arg FMC_INT_FLAG_ECCCOR: flash one bit error detected and correct interrupt flag + \arg FMC_INT_FLAG_ECCDET: flash two bit errors detect interrupt flag + \arg FMC_INT_FLAG_OBMERR: option byte modify error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (FMC_REG_VAL(int_flag) & BIT(FMC_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (FMC_REG_VAL2(int_flag) & BIT(FMC_BIT_POS2(int_flag))); + + if(flagstatus && intenable) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear FMC interrupt flag status + \param[in] flag: FMC interrupt flag + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_END: flash end of operation interrupt flag + \arg FMC_INT_FLAG_WPERR: flash erase/program protection error interrupt flag + \arg FMC_INT_FLAG_PGSERR: flash program sequence error interrupt flag + \arg FMC_INT_FLAG_RPERR: flash read protection error interrupt flag + \arg FMC_INT_FLAG_RSERR: flash read secure error interrupt flag + \arg FMC_INT_FLAG_ECCCOR: flash one bit error detected and correct interrupt flag + \arg FMC_INT_FLAG_ECCDET: flash two bit errors detect interrupt flag + \arg FMC_INT_FLAG_OBMERR: option byte modify error flag + \param[out] none + \retval none +*/ +void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum int_flag) +{ + /* clear the intrrupt flag */ + FMC_REG_VAL2(int_flag) = BIT(FMC_BIT_POS2(int_flag)); +} + +/*! + \brief get FMC state + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: operation has been completed + \arg FMC_BUSY: operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error +*/ +static fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)) { + fmc_state = FMC_BUSY; + } else { + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)) { + fmc_state = FMC_WPERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGSERR)) { + fmc_state = FMC_PGSERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_RPERR)) { + fmc_state = FMC_RPERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_RSERR)) { + fmc_state = FMC_RSERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_ECCCOR)) { + fmc_state = FMC_ECCCOR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_ECCDET)) { + fmc_state = FMC_ECCDET; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_OBMERR)) { + fmc_state = FMC_OBMERR; + } else { + /* illegal parameters */ + } + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \param[in] timeout: timeout count + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: operation has been completed + \arg FMC_BUSY: operation is in progress + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_RPERR: read protection error + \arg FMC_RSERR: read secure error + \arg FMC_ECCCOR: one bit correct error + \arg FMC_ECCDET: two bits detect error + \arg FMC_OBMERR: option byte modify error + \arg FMC_TOERR: timeout error +*/ +static fmc_state_enum fmc_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do { + /* get FMC state */ + fmc_state = fmc_state_get(); + timeout--; + } while((FMC_BUSY == fmc_state) && (0U != timeout)); + + if(FMC_BUSY == fmc_state) { + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fwdgt.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fwdgt.c new file mode 100644 index 0000000000..886c7efcd5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_fwdgt.c @@ -0,0 +1,250 @@ +/*! + \file gd32h7xx_fwdgt.c + \brief FWDGT driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_fwdgt.h" + +/* write value to FWDGT_CTL_CMD bit field */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) +/* write value to FWDGT_WND_WND bit field */ +#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) + +/*! + \brief enable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_enable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; +} + +/*! + \brief disable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_disable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE; +} + +/*! + \brief start the FWDGT counter + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the FWDGT counter prescaler value + \param[in] prescaler_value: specify prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + } while((--timeout > (uint32_t)0x00000000U) && (RESET != flag_status)); + + if(RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_value; + + return SUCCESS; +} + +/*! + \brief configure the FWDGT counter reload value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value) +{ + uint32_t timeout = FWDGT_RLD_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + return SUCCESS; +} + +/*! + \brief configure the FWDGT counter window value + \param[in] window_value: specify window value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_window_value_config(uint16_t window_value) +{ + uint32_t time_index = FWDGT_WND_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_WND */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the WUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_WUD; + }while((--time_index > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_WND = WND_WND(window_value); + + return SUCCESS; +} + +/*! + \brief reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief configure counter reload value, and prescaler divider value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[in] prescaler_div: FWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC,and FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + only one parameter can be selected which is shown as below: + \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going + \arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fwdgt_flag_get(uint16_t flag) +{ + if (RESET != (FWDGT_STAT & flag)){ + return SET; + } + return RESET; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_gpio.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_gpio.c new file mode 100644 index 0000000000..f61e9a65a2 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_gpio.c @@ -0,0 +1,492 @@ +/*! + \file gd32h7xx_gpio.c + \brief GPIO driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[out] none + \retval none +*/ +void gpio_deinit(uint32_t gpio_periph) +{ + switch(gpio_periph){ + case GPIOA: + /* reset GPIOA */ + rcu_periph_reset_enable(RCU_GPIOARST); + rcu_periph_reset_disable(RCU_GPIOARST); + break; + case GPIOB: + /* reset GPIOB */ + rcu_periph_reset_enable(RCU_GPIOBRST); + rcu_periph_reset_disable(RCU_GPIOBRST); + break; + case GPIOC: + /* reset GPIOC */ + rcu_periph_reset_enable(RCU_GPIOCRST); + rcu_periph_reset_disable(RCU_GPIOCRST); + break; + case GPIOD: + /* reset GPIOD */ + rcu_periph_reset_enable(RCU_GPIODRST); + rcu_periph_reset_disable(RCU_GPIODRST); + break; + case GPIOE: + /* reset GPIOE */ + rcu_periph_reset_enable(RCU_GPIOERST); + rcu_periph_reset_disable(RCU_GPIOERST); + break; + case GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + case GPIOG: + /* reset GPIOG */ + rcu_periph_reset_enable(RCU_GPIOGRST); + rcu_periph_reset_disable(RCU_GPIOGRST); + break; + case GPIOH: + /* reset GPIOH */ + rcu_periph_reset_enable(RCU_GPIOHRST); + rcu_periph_reset_disable(RCU_GPIOHRST); + break; + case GPIOJ: + /* reset GPIOJ */ + rcu_periph_reset_enable(RCU_GPIOJRST); + rcu_periph_reset_disable(RCU_GPIOJRST); + break; + case GPIOK: + /* reset GPIOK */ + rcu_periph_reset_enable(RCU_GPIOKRST); + rcu_periph_reset_disable(RCU_GPIOKRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO mode + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] mode: gpio pin mode + only one parameter can be selected which is shown as below: + \arg GPIO_MODE_INPUT: input mode + \arg GPIO_MODE_OUTPUT: output mode + \arg GPIO_MODE_AF: alternate function mode + \arg GPIO_MODE_ANALOG: analog mode + \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor + only one parameter can be selected which is shown as below: + \arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors + \arg GPIO_PUPD_PULLUP: with pull-up resistor + \arg GPIO_PUPD_PULLDOWN:with pull-down resistor + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin) +{ + uint16_t i; + uint32_t ctl, pupd; + + ctl = GPIO_CTL(gpio_periph); + pupd = GPIO_PUD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode); + + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, pull_up_down); + } + } + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +/*! + \brief set GPIO output type and speed + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] otype: gpio pin output mode + only one parameter can be selected which is shown as below: + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed: gpio pin output max speed + only one parameter can be selected which is shown as below: + \arg GPIO_OSPEED_12MHZ: output max speed 12MHz + \arg GPIO_OSPEED_60MHZ: output max speed 60MHz + \arg GPIO_OSPEED_85MHZ: output max speed 85MHz + \arg GPIO_OSPEED_100_220MHZ: output max speed 100/220MHz + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin) +{ + uint16_t i; + uint32_t ospeed; + + if(GPIO_OTYPE_OD == otype){ + GPIO_OMODE(gpio_periph) |= (uint32_t)pin; + }else{ + GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin); + } + + /* get the specified pin output speed bits value */ + ospeed = GPIO_OSPD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin output speed bits */ + ospeed &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeed |= GPIO_OSPEED_SET(i,speed); + } + } + GPIO_OSPD(gpio_periph) = ospeed; +} + +/*! + \brief set GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_set(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BOP(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief reset GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BC(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief write data to the specified GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[in] bit_value: SET or RESET + only one parameter can be selected which is shown as below: + \arg RESET: clear the port pin + \arg SET: set the port pin + \param[out] none + \retval none +*/ +void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value) +{ + if(RESET != bit_value){ + GPIO_BOP(gpio_periph) = (uint32_t)pin; + }else{ + GPIO_BC(gpio_periph) = (uint32_t)pin; + } +} + +/*! + \brief write data to the specified GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] data: specify the value to be written to the port output control register + \param[out] none + \retval none +*/ +void gpio_port_write(uint32_t gpio_periph, uint16_t data) +{ + GPIO_OCTL(gpio_periph) = (uint32_t)data; +} + +/*! + \brief set GPIO input filter + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] speriod: gpio pin input sample period + only one parameter can be selected which is shown as below: + \arg GPIO_ISPERIOD(x): x = 0 ~ 255 + \param[in] iftype: gpio pin input filtering type + only one parameter can be selected which is shown as below: + \arg GPIO_IFTYPE_SYNC: input filter type synchronization + \arg GPIO_IFTYPE_3_SAMPLE: input filter type filter 3 samples + \arg GPIO_IFTYPE_6_SAMPLE: input filter type filter 6 samples + \arg GPIO_IFTYPE_ASYNC: input filter type asynchronous + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_input_filter_set(uint32_t gpio_periph, uint8_t speriod, uint32_t iftype, uint32_t pin) +{ + uint16_t i; + uint32_t isperiod; + uint32_t iftp; + + isperiod = GPIO_IFL(gpio_periph); + if(pin & 0x000000FFU){ + isperiod &= ~GPIO_IFL_FLPRD0; + isperiod |= (uint32_t)speriod; + } + if(pin & 0x0000FF00U){ + isperiod &= ~GPIO_IFL_FLPRD1; + isperiod |= ((uint32_t)speriod << 8U); + } + GPIO_IFL(gpio_periph) = isperiod; + + /* get the specified pin output speed bits value */ + iftp = GPIO_IFTP(gpio_periph); + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin output speed bits */ + iftp &= ~GPIO_IFTYPE_MASK(i); + /* set the specified pin output speed bits */ + iftp |= GPIO_IFTYPE_SET(i,iftype); + } + } + GPIO_IFTP(gpio_periph) = iftp; +} + +/*! + \brief get GPIO pin input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO port input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_input_port_get(uint32_t gpio_periph) +{ + return ((uint16_t)GPIO_ISTAT(gpio_periph)); +} + +/*! + \brief get GPIO pin output status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO port output status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_output_port_get(uint32_t gpio_periph) +{ + return ((uint16_t)GPIO_OCTL(gpio_periph)); +} + +/*! + \brief set GPIO alternate function + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] alt_func_num: GPIO pin af function, please refer to specific device datasheet + only one parameter can be selected which is shown as below: + \arg GPIO_AF_0: SYSTEM, TIMER40, TIMER41, TIMER42, TIMER43, TIMER44 + \arg GPIO_AF_1: TIMER0, TIMER1, TIMER15, TIMER16, EXMC, SAI1, SAI2 + \arg GPIO_AF_2: TIMER2, TIMER3, TIMER4, TIMER7, TIMER14, TLI, CAN2, SAI0, EXMC + \arg GPIO_AF_3: TIMER7, TIMER9, EDOUT, EXMC, TLI, HPDF, OSPIM + \arg GPIO_AF_4: TIMER14, TIMER30, TIMER31, I2C0, I2C1, I2C2, I2C3, USART0, HPDF, OSPIM, TLI + \arg GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5, CAN2 + \arg GPIO_AF_6: UART3, SPI2, I2C3, HPDF, SAI0, ETH1, EDOUT, OSPIM + \arg GPIO_AF_7: USART0, USART1, USART2, USART5, UART6, TIMER40, TIMER41, TIMER42, TIMER43, + SPI1, SPI2, SPI5, SDIO0, USBHS1 + \arg GPIO_AF_8: UART3, UART4, UART7, SPI5, SDIO0, RSPDIF, TIMER44, USBHS1, SAI1, SAI2 + \arg GPIO_AF_9: SDIO1, TRGSEL, CAN0, CAN1, TLI, OPSIM, EXMC, RSPDIF, SAI2 + \arg GPIO_AF_10: SAI1, SAI2, OTG0, SDIO1, CMP, USBHS0, OPSIM, EXMC + \arg GPIO_AF_11: ETH0, MDIO, CMP, UART6, EXMC, HPDF, I2C3, TLI, SDIO1, OPSIM + \arg GPIO_AF_12: TIMER0, MDIOS, SDIO0, EXMC, OPSIM, CMP, TLI, USBHS1 + \arg GPIO_AF_13: TRGSEL, DCI, COMP0, CMP, TIMER22 + \arg GPIO_AF_14: TLI, UART4, TIMER23 + \arg GPIO_AF_15: EVENTOUT + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin) +{ + uint16_t i; + uint32_t afrl, afrh; + + afrl = GPIO_AFSEL0(gpio_periph); + afrh = GPIO_AFSEL1(gpio_periph); + + for(i = 0U;i < 8U;i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i,alt_func_num); + } + } + + for(i = 8U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U,alt_func_num); + } + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} + +/*! + \brief lock GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin) +{ + uint32_t lock = 0x00010000U; + lock |= pin; + + /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */ + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + GPIO_LOCK(gpio_periph) = (uint32_t)pin; + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + lock = GPIO_LOCK(gpio_periph); + lock = GPIO_LOCK(gpio_periph); +} + +/*! + \brief toggle GPIO pin status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_TG(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief toggle GPIO port status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,J,K) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau.c new file mode 100644 index 0000000000..ffeb7847d8 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau.c @@ -0,0 +1,398 @@ +/*! + \file gd32h7xx_hau.c + \brief HAU driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_hau.h" +#include "gd32h7xx_rcu.h" + +#define HASH_CONTEXT_INTERNAL_REG 37U +#define HMAC_CONTEXT_INTERNAL_REG 53U + +/*! + \brief reset the HAU peripheral + \param[in] none + \param[out] none + \retval none +*/ +void hau_deinit(void) +{ + /* enable HAU reset state */ + rcu_periph_reset_enable(RCU_HAURST); + /* release HAU from reset state */ + rcu_periph_reset_disable(RCU_HAURST); +} + +/*! + \brief initialize the HAU peripheral parameters + \param[in] initpara: HAU init parameter struct + members of the structure and the member values are shown as below: + algo: HAU_ALGO_SHA1, HAU_ALGO_SHA224, HAU_ALGO_SHA256, HAU_ALGO_MD5 + mode: HAU_MODE_HASH, HAU_MODE_HMAC + datatype: HAU_SWAPPING_32BIT, HAU_SWAPPING_16BIT, HAU_SWAPPING_8BIT, HAU_SWAPPING_1BIT + keytype: HAU_KEY_SHORTER_64, HAU_KEY_LONGGER_64 + \param[out] none + \retval none +*/ +void hau_init(hau_init_parameter_struct* initpara) +{ + /* configure the algorithm, mode and the data type */ + HAU_CTL &= (~(uint32_t)(HAU_CTL_ALGM_0 | HAU_CTL_ALGM_1 | HAU_CTL_DATAM | HAU_CTL_HMS)); + HAU_CTL |= (initpara->algo | initpara->datatype | initpara->mode); + + /* when mode is HMAC, set the key */ + if(HAU_MODE_HMAC == initpara->mode){ + HAU_CTL &= (~(uint32_t)HAU_CTL_KLM); + HAU_CTL |= initpara->keytype; + } + + /* start the digest of a new message */ + HAU_CTL |= HAU_CTL_START; +} + +/*! + \brief initialize the structure hau_initpara with default value + \param[in] none + \param[out] initpara: HAU init parameter struct + \retval none +*/ +void hau_init_struct_para_init(hau_init_parameter_struct* initpara) +{ + initpara->algo = HAU_ALGO_SHA1; + initpara->mode = HAU_MODE_HASH; + initpara->datatype = HAU_SWAPPING_32BIT; + initpara->keytype = HAU_KEY_SHORTER_64; +} + +/*! + \brief reset the HAU processor core + \param[in] none + \param[out] none + \retval none +*/ +void hau_reset(void) +{ + /* set to 1 to reset the HAU processor core, then it is ready to start the digest calculation */ + HAU_CTL |= HAU_CTL_START; +} + +/*! + \brief configure the number of valid bits in last word of the message + \param[in] valid_num: number of valid bits in last word of the message + only one parameter can be selected which is shown as below: + \arg 0x00: all 32 bits of the last data written are valid + \arg 0x01: only bit [31] of the last data written to HAU_DI after data swapping are valid + \arg 0x02: only bits [31:30] of the last data written to HAU_DI after data swapping are valid + \arg 0x03: only bits [31:29] of the last data written to HAU_DI after data swapping are valid + ... + \arg 0x1F: only bits [31:1] of the last data written to HAU_DI after data swapping are valid + \param[out] none + \retval none +*/ +void hau_last_word_validbits_num_config(uint32_t valid_num) +{ + HAU_CFG &= (~(uint32_t)HAU_CFG_VBL); + HAU_CFG |= CFG_VBL(valid_num); +} + +/*! + \brief write data to the IN FIFO + \param[in] data: data to write + \param[out] none + \retval none +*/ +void hau_data_write(uint32_t data) +{ + HAU_DI = data; +} + +/*! + \brief return the number of words already written into the IN FIFO + \param[in] none + \param[out] none + \retval number of words in the input FIFO +*/ +uint32_t hau_infifo_words_num_get(void) +{ + uint32_t ret = 0U; + ret = GET_CTL_NWIF(HAU_CTL); + return ret; +} + +/*! + \brief read the message digest result + \param[in] none + \param[out] digestpara: HAU digest parameter struct + out[x](x = 0...7): message digest result 0-7 + \retval none +*/ +void hau_digest_read(hau_digest_parameter_struct* digestpara) +{ + digestpara->out[0] = HAU_DO0; + digestpara->out[1] = HAU_DO1; + digestpara->out[2] = HAU_DO2; + digestpara->out[3] = HAU_DO3; + digestpara->out[4] = HAU_DO4; + digestpara->out[5] = HAU_DO5; + digestpara->out[6] = HAU_DO6; + digestpara->out[7] = HAU_DO7; +} + +/*! + \brief enable digest calculation + \param[in] none + \param[out] none + \retval none +*/ +void hau_digest_calculation_enable(void) +{ + HAU_CFG |= HAU_CFG_CALEN; +} + +/*! + \brief configure single or multiple DMA is used, and digest calculation at the end of a DMA transfer or not + \param[in] multi_single + only one parameter can be selected which is shown as below: + \arg SINGLE_DMA_AUTO_DIGEST: message padding and message digest calculation at the end of a DMA transfer + \arg MULTIPLE_DMA_NO_DIGEST: multiple DMA transfers needed and CALEN bit is not automatically set at the end of a DMA transfer + \param[out] none + \retval none +*/ +void hau_multiple_single_dma_config(uint32_t multi_single) +{ + HAU_CTL &= (~(uint32_t)HAU_CTL_MDS); + HAU_CTL |= multi_single; +} + +/*! + \brief enable the HAU DMA interface + \param[in] none + \param[out] none + \retval none +*/ +void hau_dma_enable(void) +{ + HAU_CTL |= HAU_CTL_DMAE; +} + +/*! + \brief disable the HAU DMA interface + \param[in] none + \param[out] none + \retval none +*/ +void hau_dma_disable(void) +{ + HAU_CTL &= (~(uint32_t)HAU_CTL_DMAE); +} + +/*! + \brief initialize the struct context + \param[in] none + \param[out] context: HAU context parameter struct + \retval none +*/ +void hau_context_struct_para_init(hau_context_parameter_struct* context) +{ + uint8_t i = 0U; + + /* initialize context parameter struct */ + context->hau_inten_bak = 0U; + context->hau_cfg_bak = 0U; + context->hau_ctl_bak = 0U; + for(i = 0U; i <= HMAC_CONTEXT_INTERNAL_REG; i++){ + context->hau_ctxs_bak[i] = 0U; + } +} + +/*! + \brief save the HAU peripheral context + \param[in] none + \param[out] context_save: pointer to a hau_context structure that contains the repository for current context + \retval none +*/ +void hau_context_save(hau_context_parameter_struct* context_save) +{ + uint8_t i = 0U; + uint8_t i_max = HASH_CONTEXT_INTERNAL_REG; + + hau_context_struct_para_init(context_save); + /* save context registers */ + context_save->hau_inten_bak = HAU_INTEN; + context_save->hau_cfg_bak = HAU_CFG; + context_save->hau_ctl_bak = HAU_CTL; + + if(0U != (HAU_CTL & HAU_CTL_HMS)){ + i_max = HMAC_CONTEXT_INTERNAL_REG; + } + for(i = 0U; i <= i_max; i++){ + context_save->hau_ctxs_bak[i] = HAU_CTXS(i); + } +} + +/*! + \brief restore the HAU peripheral context + \param[in] context_restore: pointer to a hau_context_parameter_struct structure that contains the repository for saved context + \param[out] none + \retval none +*/ +void hau_context_restore(hau_context_parameter_struct* context_restore) +{ + uint8_t i = 0U; + uint8_t i_max = HASH_CONTEXT_INTERNAL_REG; + + /* restore context registers */ + HAU_INTEN = context_restore->hau_inten_bak; + HAU_CFG = context_restore->hau_cfg_bak; + HAU_CTL = context_restore->hau_ctl_bak; + /* Initialize the hash processor */ + HAU_CTL |= HAU_CTL_START; + + /* continue restoring context registers */ + if(0U != (HAU_CTL & HAU_CTL_HMS)){ + i_max = HMAC_CONTEXT_INTERNAL_REG; + } + for(i = 0U; i <= i_max; i++){ + HAU_CTXS(i) = context_restore->hau_ctxs_bak[i]; + } +} + +/*! + \brief get the HAU flag status + \param[in] flag: HAU flag status + only one parameter can be selected which is shown as below: + \arg HAU_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO + \arg HAU_FLAG_CALCULATION_COMPLETE: digest calculation is completed + \arg HAU_FLAG_DMA: DMA is enabled (DMAE =1) or a transfer is processing + \arg HAU_FLAG_BUSY: data block is in process + \arg HAU_FLAG_INFIFO_NO_EMPTY: the input FIFO is not empty + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus hau_flag_get(uint32_t flag) +{ + uint32_t ret = 0U; + FlagStatus ret_flag = RESET; + + /* check if the flag is in HAU_CTL register */ + if(RESET != (flag & HAU_FLAG_INFIFO_NO_EMPTY)){ + ret = HAU_CTL; + }else{ + ret = HAU_STAT; + } + + if (RESET != (ret & flag)){ + ret_flag = SET; + } + + return ret_flag; +} + +/*! + \brief clear the HAU flag status + \param[in] flag: HAU flag status + one or more parameters can be selected which are shown as below: + \arg HAU_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO + \arg HAU_FLAG_CALCULATION_COMPLETE: digest calculation is completed + \param[out] none + \retval none +*/ +void hau_flag_clear(uint32_t flag) +{ + HAU_STAT = ~(uint32_t)(flag); +} + +/*! + \brief enable the HAU interrupts + \param[in] interrupt: specify the HAU interrupt source to be enabled + one or more parameters can be selected which are shown as below: + \arg HAU_INT_DATA_INPUT: a new block can be entered into the IN buffer + \arg HAU_INT_CALCULATION_COMPLETE: calculation complete + \param[out] none + \retval none +*/ +void hau_interrupt_enable(uint32_t interrupt) +{ + HAU_INTEN |= interrupt; +} + +/*! + \brief disable the HAU interrupts + \param[in] interrupt: specify the HAU interrupt source to be disabled + one or more parameters can be selected which are shown as below: + \arg HAU_INT_DATA_INPUT: a new block can be entered into the IN buffer + \arg HAU_INT_CALCULATION_COMPLETE: calculation complete + \param[out] none + \retval none +*/ +void hau_interrupt_disable(uint32_t interrupt) +{ + HAU_INTEN &= ~(uint32_t)(interrupt); +} + +/*! + \brief get the HAU interrupt flag status + \param[in] int_flag: HAU interrupt flag status + only one parameter can be selected which is shown as below: + \arg HAU_INT_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO + \arg HAU_INT_FLAG_CALCULATION_COMPLETE: digest calculation is completed + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus hau_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t ret = 0U; + FlagStatus flag = RESET; + + /* return the status of the interrupt */ + ret = HAU_STAT; + + if(RESET != ((HAU_INTEN & ret) & int_flag)){ + flag = SET; + } + + return flag; +} + +/*! + \brief clear the HAU interrupt flag status + \param[in] int_flag: HAU interrupt flag status + one or more parameters can be selected which are shown as below: + \arg HAU_INT_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO + \arg HAU_INT_FLAG_CALCULATION_COMPLETE: digest calculation is completed + \param[out] none + \retval none +*/ +void hau_interrupt_flag_clear(uint32_t int_flag) +{ + HAU_STAT = ~(uint32_t)(int_flag); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau_sha_md5.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau_sha_md5.c new file mode 100644 index 0000000000..0d28d22bd1 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hau_sha_md5.c @@ -0,0 +1,422 @@ +/*! + \file gd32h7xx_hau_sha_md5.c + \brief HAU_SHA_MD5 driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_hau.h" + +#define SHAMD5_BSY_TIMEOUT ((uint32_t)0x00010000U) + +/* HAU SHA/MD5 digest read in HASH mode */ +static void hau_sha_md5_digest_read(uint32_t algo, uint8_t output[]); +/* HAU digest calculate process in HASH mode */ +static ErrStatus hau_hash_calculate(uint32_t algo, uint8_t input[], uint32_t in_length, uint8_t output[]); +/* HAU digest calculate process in HMAC mode */ +static ErrStatus hau_hmac_calculate(uint32_t algo, uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]); + +/*! + \brief calculate digest using SHA1 in HASH mode + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hash_sha_1(uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hash_calculate(HAU_ALGO_SHA1, input, in_length, output); + return ret; +} + +/*! + \brief calculate digest using SHA1 in HMAC mode + \param[in] key: pointer to the key used for HMAC + \param[in] keysize: length of the key used for HMAC + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hmac_sha_1(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hmac_calculate(HAU_ALGO_SHA1, key, keysize, input, in_length, output); + return ret; +} + +/*! + \brief calculate digest using SHA224 in HASH mode + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hash_sha_224(uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hash_calculate(HAU_ALGO_SHA224, input, in_length, output); + return ret; +} + +/*! + \brief calculate digest using SHA224 in HMAC mode + \param[in] key: pointer to the key used for HMAC + \param[in] keysize: length of the key used for HMAC + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hmac_sha_224(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hmac_calculate(HAU_ALGO_SHA224, key, keysize, input, in_length, output); + return ret; +} + +/*! + \brief calculate digest using SHA256 in HASH mode + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hash_sha_256(uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hash_calculate(HAU_ALGO_SHA256, input, in_length, output); + return ret; +} + +/*! + \brief calculate digest using SHA256 in HMAC mode + \param[in] key: pointer to the key used for HMAC + \param[in] keysize: length of the key used for HMAC + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hmac_sha_256(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hmac_calculate(HAU_ALGO_SHA256, key, keysize, input, in_length, output); + return ret; +} + +/*! + \brief calculate digest using MD5 in HASH mode + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hash_md5(uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hash_calculate(HAU_ALGO_MD5, input, in_length, output); + return ret; +} + +/*! + \brief calculate digest using MD5 in HMAC mode + \param[in] key: pointer to the key used for HMAC + \param[in] keysize: length of the key used for HMAC + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hau_hmac_md5(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + ErrStatus ret = ERROR; + ret = hau_hmac_calculate(HAU_ALGO_MD5, key, keysize, input, in_length, output); + return ret; +} + +/*! + \brief HAU SHA/MD5 digest read + \param[in] algo: algorithm selection + only one parameter can be selected which is shown as below + \arg HAU_ALGO_SHA1: SHA1 algorithm + \arg HAU_ALGO_SHA224: SHA224 algorithm + \arg HAU_ALGO_SHA256: SHA256 algorithm + \arg HAU_ALGO_MD5: MD5 algorithm + \param[out] output: the result digest + \retval none +*/ +static void hau_sha_md5_digest_read(uint32_t algo, uint8_t output[]) +{ + hau_digest_parameter_struct digest_para; + uint32_t outputaddr = (uint32_t)output; + + switch(algo){ + case HAU_ALGO_SHA1: + /* read the message digest result */ + hau_digest_read(&digest_para); + /* reverse byte order, copy result to outputaddr */ + *(uint32_t*)(outputaddr) = __REV(digest_para.out[0]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[1]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[2]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[3]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[4]); + break; + case HAU_ALGO_SHA224: + /* read the message digest result */ + hau_digest_read(&digest_para); + /* reverse byte order, copy result to outputaddr */ + *(uint32_t*)(outputaddr) = __REV(digest_para.out[0]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[1]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[2]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[3]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[4]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[5]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[6]); + break; + case HAU_ALGO_SHA256: + /* read the message digest result */ + hau_digest_read(&digest_para); + /* reverse byte order, copy result to outputaddr */ + *(uint32_t*)(outputaddr) = __REV(digest_para.out[0]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[1]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[2]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[3]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[4]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[5]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[6]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[7]); + break; + case HAU_ALGO_MD5: + /* read the message digest result */ + hau_digest_read(&digest_para); + /* reverse byte order, copy result to outputaddr */ + *(uint32_t*)(outputaddr) = __REV(digest_para.out[0]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[1]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[2]); + outputaddr += 4U; + *(uint32_t*)(outputaddr) = __REV(digest_para.out[3]); + break; + default: + break; + } +} + +/*! + \brief HAU digest calculate process in HASH mode + \param[in] algo: algorithm selection + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +static ErrStatus hau_hash_calculate(uint32_t algo, uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + hau_init_parameter_struct init_para; + + __IO uint32_t num_last_valid = 0U; + uint32_t i = 0U; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + uint32_t inputaddr = (uint32_t)input; + + /* number of valid bits in last word */ + num_last_valid = 8U * (in_length % 4U); + + /* HAU peripheral initialization */ + hau_deinit(); + + /* HAU configuration */ + init_para.algo = algo; + init_para.mode = HAU_MODE_HASH; + init_para.datatype = HAU_SWAPPING_8BIT; + hau_init(&init_para); + + /* configure the number of valid bits in last word of the message */ + hau_last_word_validbits_num_config(num_last_valid); + + /* write data to the IN FIFO */ + for(i = 0U; i < in_length; i += 4U){ + hau_data_write(*(uint32_t*)inputaddr); + inputaddr += 4U; + } + + /* enable digest calculation */ + hau_digest_calculation_enable(); + + /* wait until the busy flag is reset */ + do{ + busystatus = hau_flag_get(HAU_FLAG_BUSY); + counter++; + }while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus){ + return ERROR; + }else{ + /* read the message digest */ + hau_sha_md5_digest_read(algo, output); + } + return SUCCESS; +} + +/*! + \brief HAU digest calculate process in HMAC mode + \param[in] algo: algorithm selection + \param[in] key: pointer to the key used for HMAC + \param[in] keysize: length of the key used for HMAC + \param[in] input: pointer to the input buffer + \param[in] in_length: length of the input buffer + \param[out] output: the result digest + \retval ErrStatus: SUCCESS or ERROR +*/ +static ErrStatus hau_hmac_calculate(uint32_t algo, uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]) +{ + hau_init_parameter_struct init_para; + + __IO uint16_t num_last_valid = 0U; + __IO uint16_t num_key_valid = 0U; + uint32_t i = 0U; + __IO uint32_t counter = 0U; + uint32_t busystatus = 0U; + uint32_t keyaddr = (uint32_t)key; + uint32_t inputaddr = (uint32_t)input; + + /* number of valid bits in last word of the message */ + num_last_valid = 8U * (uint16_t)(in_length % 4U); + /* number of valid bits in last word of the key */ + num_key_valid = 8U * (uint16_t)(keysize % 4U); + + /* HAU peripheral initialization */ + hau_deinit(); + + /* HAU configuration */ + init_para.algo = algo; + init_para.mode = HAU_MODE_HMAC; + init_para.datatype = HAU_SWAPPING_8BIT; + if(keysize > 64U){ + init_para.keytype = HAU_KEY_LONGGER_64; + }else{ + init_para.keytype = HAU_KEY_SHORTER_64; + } + hau_init(&init_para); + + /* configure the number of valid bits in last word of the key */ + hau_last_word_validbits_num_config((uint32_t)num_key_valid); + + /* write the key */ + for(i = 0U; i < keysize; i += 4U){ + hau_data_write(*(uint32_t*)keyaddr); + keyaddr += 4U; + } + + /* enable digest calculation */ + hau_digest_calculation_enable(); + + /* wait until the busy flag is reset */ + do{ + busystatus = hau_flag_get(HAU_FLAG_BUSY); + counter++; + }while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus){ + return ERROR; + }else{ + /* configure the number of valid bits in last word of the message */ + hau_last_word_validbits_num_config((uint32_t)num_last_valid); + + /* write data to the IN FIFO */ + for(i = 0U; i < in_length; i += 4U){ + hau_data_write(*(uint32_t*)inputaddr); + inputaddr += 4U; + } + + /* enable digest calculation */ + hau_digest_calculation_enable(); + + /* wait until the busy flag is reset */ + counter = 0U; + do{ + busystatus = hau_flag_get(HAU_FLAG_BUSY); + counter++; + }while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus){ + return ERROR; + }else{ + /* configure the number of valid bits in last word of the key */ + hau_last_word_validbits_num_config((uint32_t)num_key_valid); + + /* write the key */ + keyaddr = (uint32_t)key; + for(i = 0U; i < keysize; i += 4U){ + hau_data_write(*(uint32_t*)keyaddr); + keyaddr += 4U; + } + + /* enable digest calculation */ + hau_digest_calculation_enable(); + + /* wait until the busy flag is reset */ + counter = 0U; + do{ + busystatus = hau_flag_get(HAU_FLAG_BUSY); + counter++; + }while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus)); + + if(RESET != busystatus){ + return ERROR; + }else{ + /* read the message digest */ + hau_sha_md5_digest_read(algo, output); + } + } + } + return SUCCESS; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hpdf.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hpdf.c new file mode 100644 index 0000000000..187145c11a --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hpdf.c @@ -0,0 +1,1722 @@ +/*! + \file gd32h7xx_hpdf.c + \brief HPDF driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_hpdf.h" +#include + +/* HPDF register bit offset */ +#define CH0CTL_CKOUTDIV_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of CKOUTDIV in HPDf_CH0CTL */ +#define CHXCFG_DTRS_OFFSET ((uint32_t)0x00000003U) /*!< bit offset of DTRS in HPDF_CH0CFG */ +#define CHXCFG0_CALOFF_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of CALOFF in HPDF_CH0CFG */ +#define CHXCFG1_TMFOR_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of TMFOR in CHXCFG1 */ +#define FLTYSFCFG_SFOR_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SFOR in FLTYSFCFG */ +#define FLTYIDATAT_IDATA_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of IDATA in FLTYIDATA */ +#define FLTYRDATAT_RDATA_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of RDATA in FLTYRDATA */ +#define FLTYTMHT_HTVAL_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of HTVAL in FLTYTMHT */ +#define FLTYTMLT_LTVAL_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of LTVAL in FLTYTMLT */ +#define FLTYEMMAX_MAXVAL_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of MAXVAL in FLTYEMMAX */ +#define FLTYEMMIN_MINVAL_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of MINVAL in FLTYEMMIN */ +#define FLTYCT_CTCNT_OFFSET ((uint32_t)0x00000004U) /*!< bit offset of CTCNT in FLTYCT */ +#define SIGN_BIT_OFFSET ((uint32_t)0x00800000U) /*!< bit offset of signed value */ + +#define HPDF_WRONG_HANDLE while(1){} + +/*! + \brief reset HPDF + \param[in] none + \param[out] none + \retval none +*/ +void hpdf_deinit(void) +{ + /* reset HPDF */ + rcu_periph_reset_enable(RCU_HPDFRST); + rcu_periph_reset_disable(RCU_HPDFRST); +} + +/*! + \brief initialize the parameters of HPDF channel struct with the default values + \param[in] init_struct: the initialization data needed to initialize HPDF + serial_interface: EXTERNAL_CKIN, INTERNAL_CKOUT, HALF_CKOUT_FALLING_EDGE, HALF_CKOUT_RISING_EDGE + spi_ck_source: SPI_RISING_EDGE, SPI_FALLING_EDGE, MANCHESTER_CODE0, MANCHESTER_CODE1 + malfunction_monitor: MM_DISABLE, MM_ENABLE + calibration_offset: calibration offset(-8388608 ~ 8388607) + right_bit_shift: data right bit-shift(0 ~ 31) + channel_multiplexer: SERIAL_INPUT, INTERNAL_INPUT + channel_pin_select: CHPINSEL_CURRENT, CHPINSEL_NEXT + ck_loss_detector: CLK_LOSS_DISABLE, CLK_LOSS_ENABLE + data_packing_mode: DPM_STANDARD_MODE, DPM_INTERLEAVED_MODE, DPM_DUAL_MODE + tm_filter: TM_FASTSINC, TM_SINC1, TM_SINC2, TM_SINC3 + tm_filter_oversample: threshold monitor filter oversampling rate(0 ~ 31), AW_FLT_BYPASS=0 + mm_break_signal: DISABLE, ENABLE + mm_counter_threshold: malfunction monitor counter threshold(0 ~ 255) + plsk_value: the number of serial input samples that will be skipped(0 ~ 63) + \param[out] none + \retval none +*/ +void hpdf_channel_struct_para_init(hpdf_channel_parameter_struct *init_struct) +{ + /* check whether the struct is empty */ + if(NULL == init_struct) { + HPDF_WRONG_HANDLE + } + /* set the struct with the default values */ + init_struct->serial_interface = SPI_RISING_EDGE; + init_struct->spi_ck_source = EXTERNAL_CKIN; + init_struct->malfunction_monitor = MM_DISABLE; + init_struct->calibration_offset = 0; + init_struct->right_bit_shift = 0U; + init_struct->channel_multiplexer = SERIAL_INPUT; + init_struct->channel_pin_select = CHPINSEL_CURRENT; + init_struct->ck_loss_detector = CLK_LOSS_DISABLE; + init_struct->data_packing_mode = DPM_STANDARD_MODE; + init_struct->tm_filter = TM_FASTSINC; + init_struct->tm_filter_oversample = TM_FLT_BYPASS; + init_struct->mm_break_signal = DISABLE; + init_struct->mm_counter_threshold = 0U; + init_struct->plsk_value = 0U; +} + +/*! + \brief initialize the parameters of HPDF filter struct with the default values + \param[in] init_struct: the initialization data needed to initialize HPDF + sinc_filter: FLT_FASTSINC, FLT_SINC1, FLT_SINC2, FLT_SINC3, FLT_SINC4, FLT_SINC5 + sinc_oversample: sinc filter oversampling rate(0 ~ 1023), FLT_SINC_BYPASS=0 + integrator_oversample: integrator oversampling rate(0 ~ 255), INTEGRATOR_BYPASS=0 + tm_fast_mode: TMFM_DISABLE, TMFM_ENABLE + tm_channel: TMCHEN_DISABLE, TMCHEN_CHANNEL0, TMCHEN_CHANNEL1, TMCHEN_CHANNEL0_1 + tm_high_threshold: threshold monitor high threshold(-8388608 ~ 8388607) + tm_low_threshold: threshold monitor low threshold value(-8388608 ~ 8388607) + extreme_monitor_channel: EM_CHANNEL_DISABLE, EM_CHANNEL0, EM_CHANNEL1, EM_CHANNEL0_1 + ht_break_signal: NO_TM_HT_BREAK, TM_HT_BREAK0, TM_HT_BREAK1, TM_HT_BREAK0_1 + lt_break_signal: NO_TM_LT_BREAK, TM_LT_BREAK0, TM_LT_BREAK1, TM_LT_BREAK0_1 + \param[out] none + \retval none +*/ +void hpdf_filter_struct_para_init(hpdf_filter_parameter_struct *init_struct) +{ + /* check whether the struct is empty */ + if(NULL == init_struct) { + HPDF_WRONG_HANDLE + } + /* set the struct with the default values */ + init_struct->sinc_filter = FLT_FASTSINC; + init_struct->sinc_oversample = FLT_SINC_BYPASS; + init_struct->integrator_oversample = INTEGRATOR_BYPASS; + init_struct->tm_fast_mode = TMFM_DISABLE; + init_struct->tm_channel = TMCHEN_DISABLE; + init_struct->tm_high_threshold = 0; + init_struct->tm_low_threshold = 0; + init_struct->extreme_monitor_channel = EM_CHANNEL_DISABLE; + init_struct->ht_break_signal = NO_TM_HT_BREAK; + init_struct->lt_break_signal = NO_TM_LT_BREAK; +} + +/*! + \brief initialize the parameters of regular conversion struct with the default values + \param[in] init_struct: the initialization data needed to initialize HPDF + \param[out] none + \retval none +*/ +void hpdf_rc_struct_para_init(hpdf_rc_parameter_struct *init_struct) +{ + /* check whether the struct is empty */ + if(NULL == init_struct) { + HPDF_WRONG_HANDLE + } + /* set the struct with the default values */ + init_struct->continuous_mode = RCCM_DISABLE; + init_struct->fast_mode = FAST_DISABLE; + init_struct->rcdmaen = RCDMAEN_DISABLE; + init_struct->rcsyn = RCSYN_DISABLE; + init_struct->rcs_channel = RCS_CHANNEL0; +} + +/*! + \brief initialize the parameters of inserted conversion struct with the default values + \param[in] init_struct: the initialization data needed to initialize HPDF + \param[out] none + \retval none +*/ +void hpdf_ic_struct_para_init(hpdf_ic_parameter_struct *init_struct) +{ + /* check whether the struct is empty */ + if(NULL == init_struct) { + HPDF_WRONG_HANDLE + } + /* set the struct with the default values */ + init_struct->scmod = SCMOD_DISABLE; + init_struct->icdmaen = ICDMAEN_DISABLE; + init_struct->ic_channel_group = ICGSEL_CHANNEL0; + init_struct->icsyn = ICSYN_DISABLE; + init_struct->trigger_edge = TRG_DISABLE; + init_struct->trigger_signal = HPDF_ITRG0; +} + +/*! + \brief enable the HPDF module globally + \param[in] none + \param[out] none + \retval none +*/ +void hpdf_enable(void) +{ + /* enable the HPDF module globally */ + HPDF_CHXCTL(CHANNEL0) |= HPDF_CH0CTL_HPDFEN; +} + +/*! + \brief disable the HPDF module globally + \param[in] none + \param[out] none + \retval none +*/ +void hpdf_disable(void) +{ + /* disable the HPDF module globally */ + HPDF_CHXCTL(CHANNEL0) &= ~HPDF_CH0CTL_HPDFEN; +} + +/*! + \brief initialize the HPDF channel + \param[in] channelx: CHANNELx(x=0..7) + \param[in] init_struct: the initialization data needed to initialize HPDF channel + serial_interface: EXTERNAL_CKIN, INTERNAL_CKOUT, HALF_CKOUT_FALLING_EDGE, HALF_CKOUT_RISING_EDGE + spi_ck_source: SPI_RISING_EDGE, SPI_FALLING_EDGE, MANCHESTER_CODE0, MANCHESTER_CODE1 + malfunction_monitor: MM_DISABLE, MM_ENABLE + calibration_offset: calibration offset(-8388608 ~ 8388607) + right_bit_shift: data right bit-shift(0 ~ 31) + channel_multiplexer: SERIAL_INPUT, INTERNAL_INPUT + channel_pin_select: CHPINSEL_CURRENT, CHPINSEL_NEXT + ck_loss_detector: CLK_LOSS_DISABLE, CLK_LOSS_ENABLE + data_packing_mode: DPM_STANDARD_MODE, DPM_INTERLEAVED_MODE, DPM_DUAL_MODE + tm_filter: TM_FASTSINC, TM_SINC1, TM_SINC2, TM_SINC3 + tm_filter_oversample: threshold monitor filter oversampling rate(1 ~ 32), TM_FLT_BYPASS=0 + mm_break_signal: DISABLE, ENABLE + mm_counter_threshold: malfunction monitor counter threshold(0 ~ 255) + plsk_value: the number of serial input samples that will be skipped(0 ~ 63) + \param[out] none + \retval none +*/ +void hpdf_channel_init(hpdf_channel_enum channelx, hpdf_channel_parameter_struct *init_struct) +{ + uint32_t reg; + /* configure the HPDF_CHXCTL */ + reg = HPDF_CHXCTL(channelx); + reg &= ~(HPDF_CHXCTL_SPICKSS | HPDF_CHXCTL_SITYP | HPDF_CHXCTL_MMEN | HPDF_CHXCTL_CKLEN | HPDF_CHXCTL_CHPINSEL | \ + HPDF_CHXCTL_CMSD | HPDF_CHXCTL_DPM); + reg |= (init_struct->spi_ck_source | init_struct->serial_interface | init_struct->malfunction_monitor | \ + init_struct->channel_multiplexer | init_struct->channel_pin_select | init_struct->ck_loss_detector | \ + init_struct->data_packing_mode); + HPDF_CHXCTL(channelx) = reg; + /* configure the HPDF_CHXCFG0 */ + reg = HPDF_CHXCFG0(channelx); + reg &= ~(HPDF_CHXCFG0_CALOFF | HPDF_CHXCFG0_DTRS); + reg |= (((uint32_t)init_struct-> calibration_offset << CHXCFG0_CALOFF_OFFSET) | (init_struct->right_bit_shift << CHXCFG_DTRS_OFFSET)); + HPDF_CHXCFG0(channelx) = reg; + /* configure the HPDF_CHXCFG1 */ + reg = HPDF_CHXCFG1(channelx); + reg &= ~(HPDF_CHXCFG1_TMSFO | HPDF_CHXCFG1_TMFOR | HPDF_CHXCFG1_MMBSD | HPDF_CHXCFG1_MMCT); + reg |= (init_struct->tm_filter | ((init_struct->tm_filter_oversample - 1U) << CHXCFG1_TMFOR_OFFSET) | init_struct->mm_break_signal | \ + init_struct->mm_counter_threshold); + HPDF_CHXCFG1(channelx) = reg; + /* configure the HPDF_CHXPS */ + reg = HPDF_CHXPS(channelx); + reg &= ~(HPDF_CHXPS_PLSK); + reg |= init_struct->plsk_value; + HPDF_CHXPS(channelx) = reg; +} + +/*! + \brief initialize the HPDF filter + \param[in] filtery: FLTY(y=0..3) + \param[in] init_struct: the initialization data needed to initialize HPDF filter + sinc_filter: FLT_FASTSINC, FLT_SINC1, FLT_SINC2, FLT_SINC3, FLT_SINC4, FLT_SINC5 + sinc_oversample: sinc filter oversampling rate(1 ~ 1024), FLT_SINC_BYPASS=0 + integrator_oversample: integrator oversampling rate(1 ~ 256), INTEGRATOR_BYPASS=0 + tm_fast_mode: TMFM_DISABLE, TMFM_ENABLE + tm_channel: TMCHEN_DISABLE, TMCHEN_CHANNELx(x=0..7) + tm_high_threshold: threshold monitor high threshold(-8388608 ~ 8388607) + tm_low_threshold: threshold monitor low threshold value(-8388608 ~ 8388607) + extreme_monitor_channel: EM_CHANNEL_DISABLE, EM_CHANNELx(x=0..7) + ht_break_signal: NO_TM_HT_BREAK, TM_HT_BREAKx(x=0..3) + lt_break_signal: NO_TM_LT_BREAK, TM_LT_BREAKx(x=0..3) + \param[out] none + \retval none +*/ +void hpdf_filter_init(hpdf_filter_enum filtery, hpdf_filter_parameter_struct *init_struct) +{ + uint32_t reg; + /* configure the HPDF_FLTYCTL0 */ + HPDF_FLTYCTL0(filtery) |= init_struct->tm_fast_mode; + /* configure the HPDF_FLTYCTL1 */ + reg = HPDF_FLTYCTL1(filtery); + reg &= ~(HPDF_FLTYCTL1_TMCHEN | HPDF_FLTYCTL1_EMCS); + reg |= (init_struct->tm_channel | init_struct->extreme_monitor_channel); + HPDF_FLTYCTL1(filtery) = reg; + /* configure the HPDF_FLTYSFCTL*/ + reg = HPDF_FLTYSFCFG(filtery); + reg &= ~(HPDF_FLTYSFCFG_SFO | HPDF_FLTYSFCFG_SFOR | HPDF_FLTYSFCFG_IOR); + reg |= (init_struct->sinc_filter | ((init_struct->sinc_oversample - 1U) << FLTYSFCFG_SFOR_OFFSET) | (init_struct->integrator_oversample - 1U)); + HPDF_FLTYSFCFG(filtery) = reg; + /* configure the HPDF_FLTYTMHT */ + reg = HPDF_FLTYTMHT(filtery); + reg &= ~(HPDF_FLTYTMHT_HTVAL | HPDF_FLTYTMHT_HTBSD); + reg |= (((uint32_t)init_struct->tm_high_threshold << FLTYTMHT_HTVAL_OFFSET) | init_struct->ht_break_signal); + HPDF_FLTYTMHT(filtery) = reg; + /* configure the HPDF_FLTYTMLT */ + reg = HPDF_FLTYTMLT(filtery); + reg &= ~(HPDF_FLTYTMLT_LTVAL | HPDF_FLTYTMLT_LTBSD); + reg |= (((uint32_t)init_struct->tm_low_threshold << FLTYTMLT_LTVAL_OFFSET) | init_struct->lt_break_signal); + HPDF_FLTYTMLT(filtery) = reg; +} + +/*! + \brief initialize the regular conversion + \param[in] filtery: FLTY(y=0..3) + \param[in] init_struct: the initialization data needed to initialize regular conversion + continuous_mode: RCCM_DISABLE, RCCM_ENABLE + fast_mode: FAST_DISABLE, FAST_ENABLE + rcdmaen: RCDMAEN_DISABLE, RCDMAEN_ENABLE + rcsyn: RCSYN_DISABLE, RCSYN_ENABLE + rcs_channel: RCS_CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_rc_init(hpdf_filter_enum filtery, hpdf_rc_parameter_struct *init_struct) +{ + uint32_t reg; + /* configure the HPDF_FLTYCTL0 */ + reg = HPDF_FLTYCTL0(filtery); + reg &= ~(HPDF_FLTYCTL0_FAST | HPDF_FLTYCTL0_RCS | HPDF_FLTYCTL0_RCDMAEN | HPDF_FLTYCTL0_RCSYN | HPDF_FLTYCTL0_RCCM); + reg |= (init_struct->continuous_mode | init_struct->fast_mode | init_struct->rcdmaen | init_struct->rcsyn | \ + init_struct->rcs_channel); + HPDF_FLTYCTL0(filtery) = reg; +} + +/*! + \brief initialize the inserted conversion + \param[in] filtery: FLTY(y=0..3) + \param[in] init_struct: the initialization data needed to initialize inserted conversion + scmod: SCMOD_DISABLE, SCMOD_ENABLE + icdmaen: ICDMAEN_DISABLE, ICDMAEN_ENABLE + ic_channel_group: ICGSEL_CHANNELx(x=0..7) + icsyn: ICSYN_DISABLE, ICSYN_ENABLE + trigger_dege: TRG_DISABLE, RISING_EDGE_TRG, FALLING_EDGE_TRG, EDGE_TRG + trigger_signal: HPDF_ITRGx(x=0..8), HPDF_ITRG11, HPDF_ITRG12, HPDF_ITRG24, HPDF_ITRG25, HPDF_ITRG31 + \param[out] none + \retval none +*/ +void hpdf_ic_init(hpdf_filter_enum filtery, hpdf_ic_parameter_struct *init_struct) +{ + uint32_t reg; + /* configure the HPDF_FLTYCTL0 */ + reg = HPDF_FLTYCTL0(filtery); + reg &= ~(HPDF_FLTYCTL0_ICTEEN | HPDF_FLTYCTL0_ICTSSEL | HPDF_FLTYCTL0_ICDMAEN | HPDF_FLTYCTL0_SCMOD | \ + HPDF_FLTYCTL0_ICSYN); + reg |= (init_struct->trigger_edge | init_struct->trigger_signal | init_struct->icdmaen | init_struct->scmod | \ + init_struct->icsyn); + HPDF_FLTYCTL0(filtery) = reg; + /* configure the HPDF_FLTYICGS */ + reg = HPDF_FLTYICGS(filtery); + reg &= ~HPDF_FLTYICGS_ICGSEL; + reg |= init_struct->ic_channel_group; + HPDF_FLTYICGS(filtery) = reg; +} + +/*! + \brief configure serial output clock + \param[in] source: the HPDF serial clock output source + only one parameter can be selected which is shown as below: + \arg SERIAL_SYSTEM_CLK: serial clock output source is from system clock + \arg SERIAL_AUDIO_CLK: serial clock output source is from audio clock + \param[in] divider: serial clock output divider 0-255 + \param[in] mode: serial clock output duty mode + only one parameter can be selected which is shown as below: + \arg CKOUTDM_DISABLE: disable serial clock output duty mode + \arg CKOUTDM_ENABLE: enable serial clock output duty mode + \param[out] none + \retval none +*/ +void hpdf_clock_output_config(uint32_t source, uint8_t divider, uint32_t mode) +{ + uint32_t reg; + reg = HPDF_CHXCTL(CHANNEL0); + reg &= ~(HPDF_CH0CTL_CKOUTSEL | HPDF_CH0CTL_CKOUTSEL | HPDF_CH0CTL_CKOUTDM); + /* configure serial output clock */ + reg |= (source | ((uint32_t)divider << CH0CTL_CKOUTDIV_OFFSET) | mode); + HPDF_CHXCTL(CHANNEL0) = reg; +} + +/*! + \brief configure serial clock output source + \param[in] source: the HPDF serial clock output source + \arg SERIAL_SYSTEM_CLK: serial clock output source is from system clock + \arg SERIAL_AUDIO_CLK: serial clock output source is from audio clock + \param[out] none + \retval none +*/ +void hpdf_clock_output_source_config(uint32_t source) +{ + uint32_t reg; + reg = HPDF_CHXCTL(CHANNEL0); + reg &= ~HPDF_CH0CTL_CKOUTSEL; + reg |= source; + HPDF_CHXCTL(CHANNEL0) = reg; +} + +/*! + \brief disable serial clock output duty mode + \param[in] none + \param[out] none + \retval none +*/ +void hpdf_clock_output_duty_mode_disable(void) +{ + /* make sure the HPDF_CH0CTL_HPDFEN=0 */ + if(RESET == (HPDF_CHXCTL(CHANNEL0) & HPDF_CH0CTL_HPDFEN)) { + HPDF_CHXCTL(CHANNEL0) &= ~CKOUTDM_ENABLE; + } +} + +/*! + \brief enable serial clock output duty mode + \param[in] none + \param[out] none + \retval none +*/ +void hpdf_clock_output_duty_mode_enable(void) +{ + /* make sure the HPDF_CH0CTL_HPDFEN=0 */ + if(RESET == (HPDF_CHXCTL(CHANNEL0) & HPDF_CH0CTL_HPDFEN)) { + HPDF_CHXCTL(CHANNEL0) |= CKOUTDM_ENABLE; + } +} + +/*! + \brief configure serial clock output divider + \param[in] divider: serial clock output divider 0-255 + \param[out] none + \retval none +*/ +void hpdf_clock_output_divider_config(uint8_t divider) +{ + uint32_t reg; + /* make sure the HPDF_CH0CTL_HPDFEN=0 */ + if(RESET == (HPDF_CHXCTL(CHANNEL0) & HPDF_CH0CTL_HPDFEN)) { + reg = HPDF_CHXCTL(CHANNEL0); + reg &= ~HPDF_CH0CTL_CKOUTDIV; + reg |= ((uint32_t)divider << CH0CTL_CKOUTDIV_OFFSET); + HPDF_CHXCTL(CHANNEL0) = reg; + } +} + +/*! + \brief enable the HPDF channel + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_channel_enable(hpdf_channel_enum channelx) +{ + HPDF_CHXCTL(channelx) |= HPDF_CHXCTL_CHEN; +} + +/*! + \brief disable the HPDF channel + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_channel_disable(hpdf_channel_enum channelx) +{ + HPDF_CHXCTL(channelx) &= ~HPDF_CHXCTL_CHEN; +} + +/*! + \brief configure SPI clock source + \param[in] channelx: CHANNELx(x=0..7) + \param[in] clock_source: SPI clock source + only one parameter can be selected which is shown as below: + \arg EXTERNAL_CKIN: external input clock + \arg INTERNAL_CKOUT: internal CKOUT clock + \arg HALF_CKOUT_FALLING_EDGE: internal CKOUT clock, sampling point on each second CKOUT falling edge + \arg HALF_CKOUT_RISING_EDGE: internal CKOUT clock, sampling point on each second CKOUT rising edge + \param[out] none + \retval none +*/ +void hpdf_spi_clock_source_config(hpdf_channel_enum channelx, uint32_t clock_source) +{ + uint32_t reg; + reg = HPDF_CHXCTL(channelx); + /* make sure the CHEN=0 */ + if(RESET == (reg & HPDF_CHXCTL_CHEN)) { + reg &= ~HPDF_CHXCTL_SPICKSS; + reg |= clock_source; + HPDF_CHXCTL(channelx) = reg; + } +} + +/*! + \brief configure serial interface type + \param[in] channelx: CHANNELx(x=0..7) + \param[in] type: serial interface type + only one parameter can be selected which is shown as below: + \arg SPI_RISING_EDGE: SPI interface, sample data on rising edge + \arg SPI_FALLING_EDGE: SPI interface, sample data on rising edge + \arg MANCHESTER_CODE0: Manchester coded input: rising edge = logic 0, falling edge = logic 1 + \arg MANCHESTER_CODE1: Manchester coded input: rising edge = logic 1, falling edge = logic 0 + \param[out] none + \retval none +*/ +void hpdf_serial_interface_type_config(hpdf_channel_enum channelx, uint32_t type) +{ + uint32_t reg; + reg = HPDF_CHXCTL(channelx); + /* make sure the CHEN=0 */ + if(RESET == (reg & HPDF_CHXCTL_CHEN)) { + reg &= ~HPDF_CHXCTL_SITYP; + reg |= type; + HPDF_CHXCTL(channelx) = reg; + } +} + +/*! + \brief disable malfunction monitor + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_malfunction_monitor_disable(hpdf_channel_enum channelx) +{ + HPDF_CHXCTL(channelx) &= ~HPDF_CHXCTL_MMEN; +} + +/*! + \brief enable malfunction monitor + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_malfunction_monitor_enable(hpdf_channel_enum channelx) +{ + HPDF_CHXCTL(channelx) |= HPDF_CHXCTL_MMEN; +} + +/*! + \brief disable clock loss detector + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_clock_loss_disable(hpdf_channel_enum channelx) +{ + HPDF_CHXCTL(channelx) &= ~HPDF_CHXCTL_CKLEN; +} + +/*! + \brief enable clock loss detector + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_clock_loss_enable(hpdf_channel_enum channelx) +{ + HPDF_CHXCTL(channelx) |= HPDF_CHXCTL_CKLEN; +} + +/*! + \brief disable channel inputs pins redirection + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_channel_pin_redirection_disable(hpdf_channel_enum channelx) +{ + /* make sure the CHEN=0 */ + if(RESET == (HPDF_CHXCTL(channelx) & HPDF_CHXCTL_CHEN)) { + HPDF_CHXCTL(channelx) &= ~HPDF_CHXCTL_CHPINSEL; + } +} + +/*! + \brief enable channel inputs pins redirection + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval none +*/ +void hpdf_channel_pin_redirection_enable(hpdf_channel_enum channelx) +{ + /* make sure the CHEN=0 */ + if(RESET == (HPDF_CHXCTL(channelx) & HPDF_CHXCTL_CHEN)) { + HPDF_CHXCTL(channelx) |= HPDF_CHXCTL_CHPINSEL; + } +} + +/*! + \brief configure channel multiplexer select input data source + \param[in] channelx: CHANNELx(x=0..7) + \param[in] data_source: input data source + only one parameter can be selected which is shown as below: + \arg SERIAL_INPUT: input data source is taken from serial inputs + \arg ADC_INPUT: input data source is taken from ADC output register + \arg INTERNAL_INPUT: input data source is taken from internal HPDF_CHXPDI register + \param[out] none + \retval none +*/ +void hpdf_channel_multiplexer_config(hpdf_channel_enum channelx, uint32_t data_source) +{ + uint32_t reg; + reg = HPDF_CHXCTL(channelx); + /* make sure the CHEN=0 */ + if(RESET == (reg & HPDF_CHXCTL_CHEN)) { + reg &= ~HPDF_CHXCTL_CMSD; + /* configure the input data source */ + reg |= data_source; + HPDF_CHXCTL(channelx) = reg; + } +} + +/*! + \brief configure data packing mode + \param[in] channelx: CHANNELx(x=0..7) + \param[in] mode: parallel data packing mode + only one parameter can be selected which is shown as below: + \arg DPM_STANDARD_MODE : standard mode + \arg DPM_INTERLEAVED_MODE: interleaved mode + \arg DPM_DUAL_MODE: dual mode + \param[out] none + \retval none +*/ +void hpdf_data_pack_mode_config(hpdf_channel_enum channelx, uint32_t mode) +{ + uint32_t reg; + reg = HPDF_CHXCTL(channelx); + /* make sure the CHEN=0 */ + if(RESET == (reg & HPDF_CHXCTL_CHEN)) { + reg &= ~HPDF_CHXCTL_DPM; + /* configure the data packing mode */ + reg |= mode; + HPDF_CHXCTL(channelx) = reg; + } +} + +/*! + \brief configure data right bit-shift + \param[in] channelx: CHANNELx(x=0..7) + \param[in] right_shift: the number of bits that determine the right shift(0-31) + \param[out] none + \retval none +*/ +void hpdf_data_right_bit_shift_config(hpdf_channel_enum channelx, uint8_t right_shift) +{ + uint32_t reg; + /* make sure the CHEN=0 */ + if(RESET == (HPDF_CHXCTL(channelx) & HPDF_CHXCTL_CHEN)) { + reg = HPDF_CHXCFG0(channelx); + reg &= ~HPDF_CHXCFG0_DTRS; + /* configure the right shift */ + reg |= ((uint32_t)right_shift << CHXCFG_DTRS_OFFSET); + HPDF_CHXCFG0(channelx) = reg; + } +} + +/*! + \brief configure calibration offset + \param[in] channelx: CHANNELx(x=0..7) + \param[in] offset: 24-bit calibration offset, must be in (-8388608~8388607) + \param[out] none + \retval none +*/ +void hpdf_calibration_offset_config(hpdf_channel_enum channelx, int32_t offset) +{ + uint32_t reg; + reg = HPDF_CHXCFG0(channelx); + reg &= ~HPDF_CHXCFG0_CALOFF; + /* configure the calibration offset */ + reg |= ((uint32_t)offset << CHXCFG0_CALOFF_OFFSET); + HPDF_CHXCFG0(channelx) = reg; +} + +/*! + \brief configure malfunction monitor break signal + \param[in] channelx: CHANNELx(x=0..7) + \param[in] break_signal: malfunction monitor break signal distribution + one or more parameters can be selected which is shown as below: + \arg NO_MM_BREAK: break signal is not distributed to malfunction monitor on channel + \arg MM_BREAK0: break signal 0 is distributed to malfunction monitor on channel + \arg MM_BREAK1: break signal 1 is distributed to malfunction monitor on channel + \arg MM_BREAK2: break signal 2 is distributed to malfunction monitor on channel + \arg MM_BREAK3: break signal 3 is distributed to malfunction monitor on channel + \param[out] none + \retval none +*/ +void hpdf_malfunction_break_signal_config(hpdf_channel_enum channelx, uint32_t break_signal) +{ + uint32_t reg; + reg = HPDF_CHXCFG1(channelx); + reg &= ~HPDF_CHXCFG1_MMBSD; + /* configure the break signal */ + reg |= break_signal; + HPDF_CHXCFG1(channelx) = reg; +} + +/*! + \brief configure malfunction monitor counter threshold + \param[in] channelx: CHANNELx(x=0..7) + \param[in] threshold: malfunction monitor counter threshold(0-255) + \param[out] none + \retval none +*/ +void hpdf_malfunction_counter_config(hpdf_channel_enum channelx, uint8_t threshold) +{ + uint32_t reg; + reg = HPDF_CHXCFG1(channelx); + reg &= ~HPDF_CHXCFG1_MMCT; + /* configure the malfunction monitor counter threshold */ + reg |= threshold; + HPDF_CHXCFG1(channelx) = reg; +} + +/*! + \brief write the parallel data on standard mode of data packing + \param[in] channelx: CHANNELx(x=0..7) + \param[in] data: the parallel data + \param[out] none + \retval none +*/ +void hpdf_write_parallel_data_standard_mode(hpdf_channel_enum channelx, int16_t data) +{ + /* make sure HPDF channel is used receive parallel data */ + if(INTERNAL_INPUT == (HPDF_CHXCTL(channelx) & INTERNAL_INPUT)) { + /* make sure the data pack of HPDF_CHXPDI register is standard mode */ + if(DPM_STANDARD_MODE == (HPDF_CHXCTL(channelx) & DPM_STANDARD_MODE)) { + HPDF_CHXPDI(channelx) = (uint16_t)data; + } + } +} + +/*! + \brief write the parallel data on interleaved mode of data packing + \param[in] channelx: CHANNELx(x=0..7) + \param[in] data: the parallel data + \param[out] none + \retval none +*/ +void hpdf_write_parallel_data_interleaved_mode(hpdf_channel_enum channelx, int32_t data) +{ + /* make sure HPDF channel is used receive parallel data */ + if(INTERNAL_INPUT == (HPDF_CHXCTL(channelx) & INTERNAL_INPUT)) { + /* make sure the data pack of HPDF_CH0PDI register is interleaved mode */ + if(DPM_INTERLEAVED_MODE == (HPDF_CHXCTL(channelx) & DPM_INTERLEAVED_MODE)) { + HPDF_CHXPDI(channelx) = (uint32_t)data; + } + } +} + +/*! + \brief write the parallel data on dual mode of data packing + \param[in] channelx: CHANNELx(x=0..7) + \param[in] data: the parallel data + \param[out] none + \retval none +*/ +void hpdf_write_parallel_data_dual_mode(hpdf_channel_enum channelx, int32_t data) +{ + /* make sure HPDF channel is used receive parallel data */ + if(INTERNAL_INPUT == (HPDF_CHXCTL(channelx) & INTERNAL_INPUT)) { + /* make sure the data pack of HPDF_CH0PDI register is dual mode */ + if(DPM_DUAL_MODE == (HPDF_CHXCTL(channelx) & DPM_DUAL_MODE)) { + HPDF_CHXPDI(channelx) = (uint32_t)data; + } + } +} + +/*! + \brief update the number of pulses to skip + \param[in] channelx: CHANNELx(x=0..7) + \param[in] number: the number of serial input samples that will be skipped + \param[out] none + \retval none +*/ +void hpdf_pulse_skip_update(hpdf_channel_enum channelx, uint8_t number) +{ + /* update the number of pulses to skip */ + HPDF_CHXPS(channelx) = (uint32_t)number; +} + +/*! + \brief read the number of pulses to skip + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval the number of pulses to skip +*/ +uint8_t hpdf_pulse_skip_read(hpdf_channel_enum channelx) +{ + uint8_t val; + /* read the number of pulses to skip */ + val = (uint8_t)HPDF_CHXPS(channelx); + return val; +} + +/*! + \brief enable filter + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_filter_enable(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_FLTEN; +} + +/*! + \brief disable filter + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_filter_disable(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_FLTEN; +} + +/*! + \brief configure sinc filter order and oversample + \param[in] filtery: FLTY(y=0..3) + \param[in] order: sinc filter order + only one parameter can be selected which is shown as below: + \arg FLT_FASTSINC: FastSinc filter type + \arg FLT_SINC1: Sinc1 filter type + \arg FLT_SINC2: Sinc2 filter type + \arg FLT_SINC3: Sinc3 filter type + \arg FLT_SINC4: Sinc4 filter type + \arg FLT_SINC5: Sinc5 filter type + \param[in] oversample: Sinc filter oversampling rate(1-1024) + \param[out] none + \retval none +*/ +void hpdf_filter_config(hpdf_filter_enum filtery, uint32_t order, uint16_t oversample) +{ + uint32_t reg; + /* make sure the FLTEN=0 */ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + reg = HPDF_FLTYSFCFG(filtery); + reg &= ~(HPDF_FLTYSFCFG_SFO | HPDF_FLTYSFCFG_SFOR); + /* configure the sinc filter order and oversample */ + reg |= (order | (((uint32_t)oversample - 1U) << FLTYSFCFG_SFOR_OFFSET)); + HPDF_FLTYSFCFG(filtery) = reg; + } +} + +/*! + \brief configure integrator oversampling rate + \param[in] filtery: FLTY(y=0..3) + \param[in] oversample: integrator oversampling rate(1-256) + \param[out] none + \retval none +*/ +void hpdf_integrator_oversample(hpdf_filter_enum filtery, uint16_t oversample) +{ + uint32_t reg; + /* make sure the FLTEN=0 */ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + reg = HPDF_FLTYSFCFG(filtery); + reg &= ~HPDF_FLTYSFCFG_IOR; + /* configure the integrator oversampling rate */ + reg |= (uint32_t)oversample - 1U; + HPDF_FLTYSFCFG(filtery) = reg; + } +} + +/*! + \brief configure threshold monitor filter order and oversample + \param[in] channelx: CHANNELx(x=0..7) + \param[in] order: threshold monitor Sinc filter order + only one parameter can be selected which is shown as below: + \arg TM_FASTSINC: FastSinc filter type + \arg TM_SINC1: Sinc1 filter type + \arg TM_SINC2: Sinc2 filter type + \arg TM_SINC3: Sinc3 filter type + \param[in] oversample: Sinc filter oversampling rate(1-32) + \param[out] none + \retval none +*/ +void hpdf_threshold_monitor_filter_config(hpdf_channel_enum channelx, uint32_t order, uint8_t oversample) +{ + uint32_t reg; + /* make sure the CHEN=0 */ + if(RESET == (HPDF_CHXCTL(channelx) & HPDF_CHXCTL_CHEN)) { + reg = HPDF_CHXCFG1(channelx); + reg &= ~(HPDF_CHXCFG1_TMSFO | HPDF_CHXCFG1_TMFOR); + /* configure the threshold monitor filter order and oversample rate */ + reg |= (order | (((uint32_t)oversample - 1U) << CHXCFG1_TMFOR_OFFSET)); + HPDF_CHXCFG1(channelx) = reg; + } +} + +/*! + \brief read the threshold monitor filter data + \param[in] channelx: CHANNELx(x=0..7) + \param[out] none + \retval the threshold monitor filter data +*/ +int16_t hpdf_threshold_monitor_filter_read_data(hpdf_channel_enum channelx) +{ + int16_t val; + val = (int16_t)HPDF_CHXTMFDT(channelx); + return val; +} + +/*! + \brief disable threshold monitor fast mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_threshold_monitor_fast_mode_disable(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_TMFM; +} + +/*! + \brief enable threshold monitor fast mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_threshold_monitor_fast_mode_enable(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_TMFM; +} + +/*! + \brief configure threshold monitor channel + \param[in] filtery: FLTY(y=0..3) + \param[in] channel: which channel use threshold monitor y(x=0,3) + one or more parameters can be selected which is shown as below: + \arg TMCHEN_DISABLE: threshold monitor y is disabled on all channel + \arg TMCHEN_CHANNELx(x=0..7) threshold monitor is enabled on channel x + \param[out] none + \retval none +*/ +void hpdf_threshold_monitor_channel(hpdf_filter_enum filtery, uint32_t channel) +{ + uint32_t reg; + reg = HPDF_FLTYCTL1(filtery); + reg &= ~HPDF_FLTYCTL1_TMCHEN; + /* configure the channel which threshold monitor watch on */ + reg |= channel; + HPDF_FLTYCTL1(filtery) = reg; +} + +/*! + \brief configure threshold monitor high threshold value + \param[in] filtery: FLTY(y=0..3) + \param[in] value: high threshold value(-8388608~8388607) + \param[out] none + \retval none +*/ +void hpdf_threshold_monitor_high_threshold(hpdf_filter_enum filtery, int32_t value) +{ + uint32_t reg; + reg = HPDF_FLTYTMHT(filtery); + reg &= ~HPDF_FLTYTMHT_HTVAL; + /* write the signed value */ + reg |= (uint32_t)value << FLTYTMHT_HTVAL_OFFSET; + HPDF_FLTYTMHT(filtery) = reg; +} + +/*! + \brief configure threshold monitor low threshold value + \param[in] filtery: FLTY(y=0..3) + \param[in] value: low threshold value(-8388608~8388607) + \param[out] none + \retval none +*/ +void hpdf_threshold_monitor_low_threshold(hpdf_filter_enum filtery, int32_t value) +{ + uint32_t reg; + reg = HPDF_FLTYTMLT(filtery); + reg &= ~HPDF_FLTYTMLT_LTVAL; + /* write the signed value */ + reg |= (uint32_t)value << FLTYTMLT_LTVAL_OFFSET; + HPDF_FLTYTMLT(filtery) = reg; +} + +/*! + \brief configure threshold monitor high threshold event break signal + \param[in] filtery: FLTY(y=0..3) + \param[in] break_signal: HPDF break signal + one or more parameters can be selected which is shown as below: + \arg NO_TM_HT_BREAK: break signal is not distributed to an threshold monitor high threshold event + \arg TM_HT_BREAKx(x=0..3): break signal x is distributed to an threshold monitor high threshold event + \param[out] none + \retval none +*/ +void hpdf_high_threshold_break_signal(hpdf_filter_enum filtery, uint32_t break_signal) +{ + uint32_t reg; + reg = HPDF_FLTYTMHT(filtery); + reg &= ~HPDF_FLTYTMHT_HTBSD; + /* configure the break signal */ + reg |= break_signal; + HPDF_FLTYTMHT(filtery) = reg; +} + +/*! + \brief configure threshold monitor low threshold event break signal + \param[in] filtery: FLTY(y=0..3) + \param[in] break_signal: the HPDF break signal + one or more parameters can be selected which is shown as below: + \arg NO_TM_LT_BREAK: break signal is not distributed to an threshold monitor low threshold event + \arg TM_LT_BREAKx(x=0..3): break signal x is distributed to an threshold monitor low threshold event + \param[out] none + \retval none +*/ +void hpdf_low_threshold_break_signal(hpdf_filter_enum filtery, uint32_t break_signal) +{ + uint32_t reg; + reg = HPDF_FLTYTMLT(filtery); + reg &= ~HPDF_FLTYTMLT_LTBSD; + /* configure the break signal */ + reg |= break_signal; + HPDF_FLTYTMLT(filtery) = reg; +} + +/*! + \brief configure extremes monitor channel + \param[in] filtery: FLTY(y=0..3) + \param[in] channel: which channel use extremes monitor + one or more parameters can be selected which is shown as below: + \arg EM_CHANNEL_DISABLE: extremes monitor y does not accept data from any channel + \arg EM_CHANNELx(x=0..7): extremes monitor accepts data from channel x + \param[out] none + \retval none +*/ +void hpdf_extremes_monitor_channel(hpdf_filter_enum filtery, uint32_t channel) +{ + uint32_t reg; + reg = HPDF_FLTYCTL1(filtery); + reg &= ~HPDF_FLTYCTL1_EMCS; + /* configure the channel which channel use extremes monitor */ + reg |= channel; + HPDF_FLTYCTL1(filtery) = reg; +} + +/*! + \brief get the extremes monitor maximum value + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval the maximum value +*/ +int32_t hpdf_extremes_monitor_maximum_get(hpdf_filter_enum filtery) +{ + uint32_t val; + /* get the maximum value */ + val = HPDF_FLTYEMMAX(filtery) >> FLTYEMMAX_MAXVAL_OFFSET; + /* get the sign of value */ + if(val & SIGN_BIT_OFFSET) { + val |= 0xFF000000U; + } + return (int32_t)val; +} + +/*! + \brief get the extremes monitor minimum value + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval the minimum value +*/ +int32_t hpdf_extremes_monitor_minimum_get(hpdf_filter_enum filtery) +{ + uint32_t val; + /* get the channel of maximum value */ + val = HPDF_FLTYEMMIN(filtery) >> FLTYEMMIN_MINVAL_OFFSET; + /* get the sign of vlaue */ + if(val & SIGN_BIT_OFFSET) { + val |= 0xFF000000U; + } + return (int32_t)val; +} + +/*! + \brief get the conversion timer value + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval count value of conversion time +*/ +uint32_t hpdf_conversion_time_get(hpdf_filter_enum filtery) +{ + uint32_t val; + /* get the channel of maximum value */ + val = HPDF_FLTYCT(filtery) >> FLTYCT_CTCNT_OFFSET; + return val; +} + +/*! + \brief disable regular conversions continuous mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_continuous_disable(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_RCCM; +} + +/*! + \brief enable regular conversions continuous mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_continuous_enable(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_RCCM; +} + +/*! + \brief start regular channel conversion by software + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_start_by_software(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_SRCS; +} + +/*! + \brief disable regular conversion synchronously + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_syn_disable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_RCSYN; + } +} + +/*! + \brief enable regular conversion synchronously + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_syn_enable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_RCSYN; + } +} + +/*! + \brief disable regular conversion DMA channel + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_dma_disable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_RCDMAEN; + } +} + +/*! + \brief enable regular conversion DMA channel + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_dma_enable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_RCDMAEN; + } +} + +/*! + \brief configure regular conversion channel + \param[in] filtery: FLTY(y=0..3) + \param[in] channel: the regular conversion channel selection + only one parameter can be selected which is shown as below: + \arg RCS_CHANNELx(x=0..7): regular conversion channel + \param[out] none + \retval none +*/ +void hpdf_rc_channel_config(hpdf_filter_enum filtery, uint32_t channel) +{ + uint32_t reg; + reg = HPDF_FLTYCTL0(filtery); + reg &= ~HPDF_FLTYCTL0_RCS; + reg |= channel; + HPDF_FLTYCTL0(filtery) = reg; +} + +/*! + \brief disable regular conversion fast conversion mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_fast_mode_disable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_FAST; + } +} + +/*! + \brief enable regular conversion fast conversion mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_rc_fast_mode_enable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_FAST; + } +} + +/*! + \brief get the regular conversions data + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval regular conversions data +*/ +int32_t hpdf_rc_data_get(hpdf_filter_enum filtery) +{ + uint32_t val; + /* get the signed data */ + val = HPDF_FLTYRDATA(filtery) >> FLTYRDATAT_RDATA_OFFSET; + /* get the sign of vlaue */ + if(val & SIGN_BIT_OFFSET) { + val |= 0xFF000000U; + } + return (int32_t)val; +} + +/*! + \brief get the channel of regular group channel most recently converted + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval the channel +*/ +uint8_t hpdf_rc_channel_get(hpdf_filter_enum filtery) +{ + uint8_t val; + val = (uint8_t)HPDF_FLTYRDATA(filtery); + val &= (uint8_t)HPDF_FLTYRDATA_RCCH; + return val; +} + +/*! + \brief start inserted channel conversion by software + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_start_by_software(hpdf_filter_enum filtery) +{ + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_SICC; +} + +/*! + \brief disable inserted conversion synchronously + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_syn_disable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_ICSYN; + } +} + +/*! + \brief enable inserted conversion synchronously + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_syn_enable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_ICSYN; + } +} + +/*! + \brief disable inserted conversion DMA channel + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_dma_disable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_ICDMAEN; + } +} + +/*! + \brief enable inserted conversion DMA channel + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_dma_enable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_ICDMAEN; + } +} + +/*! + \brief disable scan conversion mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_scan_mode_disable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_SCMOD; + } +} + +/*! + \brief enable scan conversion mode + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_scan_mode_enable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) |= HPDF_FLTYCTL0_SCMOD; + } +} + +/*! + \brief disable inserted conversions trigger siganl + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval none +*/ +void hpdf_ic_trigger_signal_disable(hpdf_filter_enum filtery) +{ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + HPDF_FLTYCTL0(filtery) &= ~HPDF_FLTYCTL0_ICTEEN; + } +} + +/*! + \brief configure inserted conversions trigger siganl and trigger edge + \param[in] filtery: FLTY(y=0..3) + \param[in] trigger: inserted conversions trigger signal + only one parameter can be selected which is shown as below: + \arg HPDF_ITRG0: TIMER0_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG1: TIMER0_TRGO1 is selected to start inserted conversion + \arg HPDF_ITRG2: TIMER7_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG3: TIMER7_TRGO1 is selected to start inserted conversion + \arg HPDF_ITRG4: TIMER2_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG5: TIMER3_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG6: TIMER15_CH1 is selected to start inserted conversion + \arg HPDF_ITRG7: TIMER5_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG8: TIMER6_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG11: TIMER22_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG12: TIMER23_TRGO0 is selected to start inserted conversion + \arg HPDF_ITRG24: EXTI11 is selected to start inserted conversion + \arg HPDF_ITRG25: EXTI15 is selected to start inserted conversion + \arg HPDF_ITRG31: HPDF_ITRG is selected to start inserted conversion + \param[in] trigger_edge: inserted conversions trigger edge + only one parameter can be selected which is shown as below: + \arg TRG_DISABLE: disable trigger siganl + \arg RISING_EDGE_TRG: rising edge on the trigger signal + \arg FALLING_EDGE_TRG: falling edge on the trigger signal + \arg EDGE_TRG: edge (rising edges and falling edges) on the trigger signal + \param[out] none + \retval none +*/ +void hpdf_ic_trigger_signal_config(hpdf_filter_enum filtery, uint32_t trigger, uint32_t trigger_edge) +{ + uint32_t reg; + /* make sure the FLTEN=0 */ + if(RESET == (HPDF_FLTYCTL0(filtery) & HPDF_FLTYCTL0_FLTEN)) { + reg = HPDF_FLTYCTL0(filtery); + reg &= ~(HPDF_FLTYCTL0_ICTEEN | HPDF_FLTYCTL0_ICTSSEL); + /* configure inserted conversions trigger siganl and trigger edge */ + reg |= (trigger | trigger_edge); + HPDF_FLTYCTL0(filtery) = reg; + } +} + +/*! + \brief configure inserted group conversions channel + \param[in] filtery: FLTY(y=0..3) + \param[in] channel: the HPDF channel belongs to inserted group + one or more parameters can be selected which is shown as below: + \arg ICGSEL_CHANNELx(x=0..7): channelx belongs to the inserted group + \param[out] none + \retval none +*/ +void hpdf_ic_channel_config(hpdf_filter_enum filtery, uint32_t channel) +{ + uint32_t reg; + reg = HPDF_FLTYICGS(filtery); + reg &= ~HPDF_FLTYICGS_ICGSEL; + reg |= channel; + HPDF_FLTYICGS(filtery) = reg; +} + +/*! + \brief get the inserted conversions data + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval inserted conversions data +*/ +int32_t hpdf_ic_data_get(hpdf_filter_enum filtery) +{ + uint32_t val; + /* get the unsigned data */ + val = HPDF_FLTYIDATA(filtery) >> FLTYIDATAT_IDATA_OFFSET; + /* get the sign of value */ + if(val & SIGN_BIT_OFFSET) { + val |= 0xFF000000U; + } + /* get the signed data */ + return (int32_t)val; +} + +/*! + \brief get the channel of inserted group channel most recently converted + \param[in] filtery: FLTY(y=0..3) + \param[out] none + \retval the channel +*/ +uint8_t hpdf_ic_channel_get(hpdf_filter_enum filtery) +{ + uint8_t val; + val = (uint8_t)HPDF_FLTYIDATA(filtery); + val &= (uint8_t)HPDF_FLTYIDATA_ICCH; + return val; +} + +/*! + \brief get the HPDF flags + \param[in] filtery: FLTY(y=0..3) + \param[in] flag: HPDF flags, refer to hpdf_flag_enum + only one parameter can be selected which is shown as below: + \arg HPDF_FLAG_FLTY_ICEF: FLTY inserted conversion end flag + \arg HPDF_FLAG_FLTY_RCEF: FLTY regular conversion end flag + \arg HPDF_FLAG_FLTY_ICDOF: FLTY inserted conversion data overflow flag + \arg HPDF_FLAG_FLTY_RCDOF: FLTY regular conversion data overflow flag + \arg HPDF_FLAG_FLTY_TMEOF: FLTY threshold monitor event occurred flag + \arg HPDF_FLAG_FLTY_ICPF: FLTY inserted conversion in progress flag + \arg HPDF_FLAG_FLTY_RCPF: FLTY regular conversion in progress flag + \arg HPDF_FLAG_FLT0_CKLFx(x=0..7): clock signal is lost on channel x flag + \arg HPDF_FLAG_FLT0_MMFx(x=0..7): malfunction event occurred on channel x flag + \arg HPDF_FLAG_FLTY_RCHPDT: FLTY inserted channel most recently converted + \arg HPDF_FLAG_FLTY_LTFx(x=0..7): threshold monitor low threshold flag on channel x flag + \arg HPDF_FLAG_FLTY_HTFx(x=0..7): threshold monitor high threshold flag on channel x flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus hpdf_flag_get(hpdf_filter_enum filtery, hpdf_flag_enum flag) +{ + FlagStatus flag_state = RESET; + switch(filtery) { + case FLT0: + /* get the flag in FLT0 register */ + if(RESET != (HPDF_REG_VAL(HPDF_FLT0, flag) & BIT(HPDF_BIT_POS(flag)))) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + case FLT1: + /* get the flag in FLT1 register */ + if(RESET != (HPDF_REG_VAL(HPDF_FLT1, flag) & BIT(HPDF_BIT_POS(flag)))) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + case FLT2: + /* get the flag in FLT2 register */ + if(RESET != (HPDF_REG_VAL(HPDF_FLT2, flag) & BIT(HPDF_BIT_POS(flag)))) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + case FLT3: + /* get the flag in FLT3 register */ + if(RESET != (HPDF_REG_VAL(HPDF_FLT3, flag) & BIT(HPDF_BIT_POS(flag)))) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + default : + break; + } + return flag_state; +} + +/*! + \brief clear the HPDF flags + \param[in] filtery: FLTY(y=0..3) + \param[in] flag: HPDF flags, refer to hpdf_flag_enum + only one parameter can be selected which is shown as below: + \arg HPDF_FLAG_FLTY_ICEF: FLTY inserted conversion end flag + \arg HPDF_FLAG_FLTY_RCEF: FLTY regular conversion end flag + \arg HPDF_FLAG_FLTY_ICDOF: FLTY inserted conversion data overflow flag + \arg HPDF_FLAG_FLTY_RCDOF: FLTY regular conversion data overflow flag + \arg HPDF_FLAG_FLTY_TMEOF: FLTY threshold monitor event occurred flag + \arg HPDF_FLAG_FLT0_CKLFx(x=0..7): clock signal is lost on channel x flag + \arg HPDF_FLAG_FLT0_MMFx(x=0..7): malfunction event occurred on channel x flag + \arg HPDF_FLAG_FLTY_LTFx(x=0..7): threshold monitor low threshold flag on channel x flag + \arg HPDF_FLAG_FLTY_HTFx(x=0..7): threshold monitor high threshold flag on channel x flag + \param[out] none + \retval none +*/ +void hpdf_flag_clear(hpdf_filter_enum filtery, hpdf_flag_enum flag) +{ + if(FLTYTMSTAT_REG_OFFSET == ((uint32_t)flag >> 6)) { + /* clear threshold monitor high threshold flag */ + HPDF_FLTYTMFC(filtery) |= BIT(HPDF_BIT_POS(flag)); + } else { + switch(flag) { + case HPDF_FLAG_FLTY_ICEF: + /* read the inserted conversion data */ + HPDF_FLTYIDATA(filtery); + break; + case HPDF_FLAG_FLTY_RCEF: + /* read the regular conversion data */ + HPDF_FLTYRDATA(filtery); + break; + case HPDF_FLAG_FLTY_TMEOF: + /* clear the threshold monitor flag */ + HPDF_FLTYTMFC(filtery) |= (HPDF_FLTYTMFC_HTFC | HPDF_FLTYTMFC_LTFC); + break; + default : + HPDF_FLTYINTC(filtery) |= BIT(HPDF_BIT_POS(flag)); + break; + } + } +} + +/*! + \brief enable HPDF interrupt + \param[in] filtery: FLTY(y=0..3) + \param[in] interrupt: HPDF interrupts, refer to hpdf_interrput_enum + only one parameter can be selected which is shown as below: + \arg HPDF_INT_FLTY_ICEIE: FLTY inserted conversion end interrupt enable + \arg HPDF_INT_FLTY_RCEIE: FLTY regular conversion end interrupt enable + \arg HPDF_INT_FLTY_ICDOIE: FLTY inserted conversion data overflow interrupt enable + \arg HPDF_INT_FLTY_RCDOIE: FLTY regular conversion data overflow interrupt enable + \arg HPDF_INT_FLTY_TMIE: FLTY threshold monitor interrupt enable + \arg HPDF_INT_FLT0_MMIE: malfunction monitor interrupt enable + \arg HPDF_INT_FLT0_CKLIE: clock loss interrupt enable + \param[out] none + \retval none +*/ +void hpdf_interrupt_enable(hpdf_filter_enum filtery, hpdf_interrput_enum interrupt) +{ + switch(filtery) { + case FLT0: + HPDF_REG_VAL(HPDF_FLT0, interrupt) |= BIT(HPDF_BIT_POS(interrupt)); + break; + case FLT1: + HPDF_REG_VAL(HPDF_FLT1, interrupt) |= BIT(HPDF_BIT_POS(interrupt)); + break; + case FLT2: + HPDF_REG_VAL(HPDF_FLT2, interrupt) |= BIT(HPDF_BIT_POS(interrupt)); + break; + case FLT3: + HPDF_REG_VAL(HPDF_FLT3, interrupt) |= BIT(HPDF_BIT_POS(interrupt)); + break; + default : + break; + } +} + +/*! + \brief disable HPDF interrupt + \param[in] filtery: FLTY(y=0..3) + \param[in] interrupt: HPDF interrupts, refer to hpdf_interrput_enum + only one parameter can be selected which is shown as below: + \arg HPDF_INT_FLTY_ICEIE: FLTY inserted conversion interrupt enable + \arg HPDF_INT_FLTY_RCEIE: FLTY regular conversion interrupt enable + \arg HPDF_INT_FLTY_ICDOIE: FLTY inserted conversion data overflow interrupt enable + \arg HPDF_INT_FLTY_RCDOIE: FLTY regular conversion data overflow interrupt enable + \arg HPDF_INT_FLTY_TMIE: FLTY threshold monitor interrupt enable + \arg HPDF_INT_FLT0_MMIE: malfunction monitor interrupt enable + \arg HPDF_INT_FLT0_CKLIE: clock loss interrupt enable + \param[out] none + \retval none +*/ +void hpdf_interrupt_disable(hpdf_filter_enum filtery, hpdf_interrput_enum interrupt) +{ + switch(filtery) { + case FLT0: + HPDF_REG_VAL(HPDF_FLT0, interrupt) &= ~BIT(HPDF_BIT_POS(interrupt)); + break; + case FLT1: + HPDF_REG_VAL(HPDF_FLT1, interrupt) &= ~BIT(HPDF_BIT_POS(interrupt)); + break; + case FLT2: + HPDF_REG_VAL(HPDF_FLT2, interrupt) &= ~BIT(HPDF_BIT_POS(interrupt)); + break; + case FLT3: + HPDF_REG_VAL(HPDF_FLT3, interrupt) &= ~BIT(HPDF_BIT_POS(interrupt)); + break; + default : + break; + } +} + +/*! + \brief get the HPDF interrupt flags + \param[in] filtery: FLTY(y=0..3) + \param[in] int_flag: HPDF flags, refer to hpdf_interrput_enum + only one parameter can be selected which is shown as below: + \arg HPDF_INT_FLAG_FLTY_ICEF: FLTY inserted conversion end interrupt flag + \arg HPDF_INT_FLAG_FLTY_RCEF: FLTY regular conversion end interrupt flag + \arg HPDF_INT_FLAG_FLTY_ICDOF: FLTY inserted conversion data overflow interrupt flag + \arg HPDF_INT_FLAG_FLTY_RCDOF: FLTY regular conversion data overflow interrupt flag + \arg HPDF_INT_FLAG_FLTY_TMEOF: FLTY threshold monitor event occurred interrupt flag + \arg HPDF_INT_FLAG_FLT0_CKLFx(x=0..7): clock signal is lost on channel x interrupt flag + \arg HPDF_INT_FLAG_FLT0_MMFx(x=0..7): malfunction event occurred on channel x interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus hpdf_interrupt_flag_get(hpdf_filter_enum filtery, hpdf_interrput_flag_enum int_flag) +{ + FlagStatus flag_state = RESET; + uint32_t int_enable = 0U, flags = 0U; + switch(filtery) { + case FLT0: + /* get the interrupt enable bit status */ + int_enable = (HPDF_REG_VAL(HPDF_FLT0, int_flag) & BIT(HPDF_BIT_POS(int_flag))); + /* get the interrupt enable bit status */ + flags = (HPDF_REG_VAL2(HPDF_FLT0, int_flag) & BIT(HPDF_BIT_POS2(int_flag))); + if(flags && int_enable) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + case FLT1: + /* get the interrupt enable bit status */ + int_enable = (HPDF_REG_VAL(HPDF_FLT1, int_flag) & BIT(HPDF_BIT_POS(int_flag))); + /* get the interrupt enable bit status */ + flags = (HPDF_REG_VAL2(HPDF_FLT1, int_flag) & BIT(HPDF_BIT_POS2(int_flag))); + if(flags && int_enable) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + case FLT2: + /* get the interrupt enable bit status */ + int_enable = (HPDF_REG_VAL(HPDF_FLT2, int_flag) & BIT(HPDF_BIT_POS(int_flag))); + /* get the interrupt enable bit status */ + flags = (HPDF_REG_VAL2(HPDF_FLT2, int_flag) & BIT(HPDF_BIT_POS2(int_flag))); + if(flags && int_enable) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + case FLT3: + /* get the interrupt enable bit status */ + int_enable = (HPDF_REG_VAL(HPDF_FLT3, int_flag) & BIT(HPDF_BIT_POS(int_flag))); + /* get the interrupt enable bit status */ + flags = (HPDF_REG_VAL2(HPDF_FLT3, int_flag) & BIT(HPDF_BIT_POS2(int_flag))); + if(flags && int_enable) { + flag_state = SET; + } else { + flag_state = RESET; + } + break; + default : + break; + } + return flag_state; +} + +/*! + \brief clear the HPDF interrupt flags + \param[in] filtery: FLTY(y=0..3) + \param[in] int_flag: HPDF flags, refer to hpdf_interrput_flag_enum + only one parameter can be selected which is shown as below: + \arg HPDF_INT_FLAG_FLTY_ICEF: FLTY inserted conversion end interrupt flag + \arg HPDF_INT_FLAG_FLTY_RCEF: FLTY regular conversion end interrupt flag + \arg HPDF_INT_FLAG_FLTY_ICDOF: FLTY inserted conversion data overflow interrupt flag + \arg HPDF_INT_FLAG_FLTY_RCDOF: FLTY regular conversion data overflow interrupt flag + \arg HPDF_INT_FLAG_FLTY_TMEOF: FLTY threshold monitor event occurred interrupt flag + \arg HPDF_INT_FLAG_FLT0_CKLFx(x=0..7): clock signal is lost on channelx interrupt flag + \arg HPDF_INT_FLAG_FLT0_MMFx(x=0..7): malfunction event occurred on channelx interrupt flag + \param[out] none + \retval none +*/ +void hpdf_interrupt_flag_clear(hpdf_filter_enum filtery, hpdf_interrput_flag_enum int_flag) +{ + switch(int_flag) { + case HPDF_INT_FLAG_FLTY_ICEF: + /* read the inserted conversion data */ + HPDF_FLTYIDATA(filtery); + break; + case HPDF_INT_FLAG_FLTY_RCEF: + /* read the regular conversion data */ + HPDF_FLTYRDATA(filtery); + break; + case HPDF_INT_FLAG_FLTY_TMEOF: + /* clear the threshold monitor flag */ + HPDF_FLTYTMFC(filtery) |= (HPDF_FLTYTMFC_HTFC | HPDF_FLTYTMFC_LTFC); + break; + default : + HPDF_FLTYINTC(filtery) |= BIT(HPDF_BIT_POS2(int_flag)); + break; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hwsem.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hwsem.c new file mode 100644 index 0000000000..646ffa46c4 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_hwsem.c @@ -0,0 +1,286 @@ +/*! + \file gd32h7xx_hwsem.c + \brief HWSEM driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_hwsem.h" + +/*! + \brief try to lock the specific semaphore by writing process ID + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[in] process: the process to lock the semaphore + only one parameter can be selected which is shown as below: + \arg 0 - 0xFF + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hwsem_lock_set(hwsem_semaphore_enum semaphore, uint8_t process) +{ + uint32_t temp_mid = 0U, temp_pid = 0U; + ErrStatus ret = ERROR; + + /* try to lock the semaphore */ + HWSEM_CTL(semaphore) = (uint32_t)(HWSEM_LOCK | CTL_MID(HWSEM_MASTER_ID) | CTL_PID(process)); + + /* read the control register to confirm the semaphore is locked by target process or not */ + temp_mid = hwsem_master_id_get(semaphore); + temp_pid = hwsem_process_id_get(semaphore); + if((HWSEM_MASTER_ID == temp_mid) && (process == temp_pid)) { + ret = SUCCESS; + } + + return ret; +} + +/*! + \brief try to release the lock of the semaphore by writing process ID + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[in] process: the process to unlock the semaphore + only one parameter can be selected which is shown as below: + \arg 0 - 0xFF + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hwsem_lock_release(hwsem_semaphore_enum semaphore, uint8_t process) +{ + uint32_t lock_state = 0U; + ErrStatus ret = ERROR; + + HWSEM_CTL(semaphore) = (uint32_t)(CTL_MID(HWSEM_MASTER_ID) | CTL_PID(process)); + + lock_state = HWSEM_CTL(semaphore) & HWSEM_CTL_LK; + if(0U == lock_state) { + ret = SUCCESS; + } + + return ret; +} + +/*! + \brief try to lock the semaphore by reading + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus hwsem_lock_by_reading(hwsem_semaphore_enum semaphore) +{ + ErrStatus ret = ERROR; + + if((uint32_t)(HWSEM_LOCK | CTL_MID(HWSEM_MASTER_ID)) == HWSEM_RLK(semaphore)) { + ret = SUCCESS; + } + + return ret; +} + +/*! + \brief unlock all semaphores of the master ID + \param[in] key: key value + \arg 0 - 0xFFFF + \param[out] none + \retval none +*/ +ErrStatus hwsem_unlock_all(uint16_t key) +{ + ErrStatus ret = ERROR; + + HWSEM_UNLK = UNLK_KEY(key) | UNLK_MID(HWSEM_MASTER_ID); + + if(key == hwsem_key_get()) { + ret = SUCCESS; + } + return ret; +} + +/*! + \brief get process ID of the specific semaphore + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval uint32_t: process ID of semaphore +*/ +uint32_t hwsem_process_id_get(hwsem_semaphore_enum semaphore) +{ + return (uint32_t)(GET_CTL_PID(HWSEM_CTL(semaphore))); +} + +/*! + \brief get master ID of the specific semaphore + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval uint32_t: master ID of semaphore +*/ +uint32_t hwsem_master_id_get(hwsem_semaphore_enum semaphore) +{ + return (uint32_t)(GET_CTL_MID(HWSEM_CTL(semaphore))); +} + +/*! + \brief get the lock status of the semaphore + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus hwsem_lock_status_get(hwsem_semaphore_enum semaphore) +{ + FlagStatus ret = RESET; + + if(0U != (HWSEM_CTL(semaphore) & HWSEM_LOCK)) { + ret = SET; + } + + return ret; +} + +/*! + \brief set the key + \param[in] key: key value + \arg 0 - 0xFFFF + \param[out] none + \retval none +*/ +void hwsem_key_set(uint16_t key) +{ + HWSEM_KEY = KEY_KEY(key); +} + +/*! + \brief get the key + \param[in] none + \param[out] none + \retval uint16_t: key to unlock all semaphores +*/ +uint16_t hwsem_key_get(void) +{ + return ((uint16_t)GET_KEY_KEY(HWSEM_KEY)); +} + +/*! + \brief get the HWSEM flag status + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus hwsem_flag_get(hwsem_semaphore_enum semaphore) +{ + FlagStatus ret = RESET; + + if(RESET != ((HWSEM_STAT >> semaphore) & 0x1U)) { + return SET; + } + + return ret; +} + +/*! + \brief clear HWSEM flag status + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval none +*/ +void hwsem_flag_clear(hwsem_semaphore_enum semaphore) +{ + HWSEM_INTC = (1U << semaphore); +} + +/*! + \brief get HWSEM interrupt flag status + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus hwsem_interrupt_flag_get(hwsem_semaphore_enum semaphore) +{ + FlagStatus ret = RESET; + + if(RESET != ((HWSEM_INTF >> semaphore) & 0x1U)) { + ret = SET; + } + + return ret; +} + +/*! + \brief clear HWSEM interrupt flag + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval none +*/ +void hwsem_interrupt_flag_clear(hwsem_semaphore_enum semaphore) +{ + HWSEM_INTC = (1U << semaphore); +} + +/*! + \brief enable HWSEM interrupt + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval none +*/ +void hwsem_interrupt_enable(hwsem_semaphore_enum semaphore) +{ + HWSEM_INTEN |= (1U << semaphore); +} + +/*! + \brief disable HWSEM interrupt + \param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum + only one parameter can be selected which is shown as below: + \arg SEMx (x=0..31): semaphore x + \param[out] none + \retval none +*/ +void hwsem_interrupt_disable(hwsem_semaphore_enum semaphore) +{ + HWSEM_INTEN &= (uint32_t)(~((uint32_t)1U << semaphore)); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_i2c.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_i2c.c new file mode 100644 index 0000000000..5522a00751 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_i2c.c @@ -0,0 +1,968 @@ +/*! + \file gd32h7xx_i2c.c + \brief I2C driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ +#include "gd32h7xx_i2c.h" + +/* I2C register bit mask */ +#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */ +#define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */ + +/* I2C register bit offset */ +#define CTL0_DNF_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of DNF in I2C_CTL0 */ +#define CTL1_BYTENUM_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BYTENUM in I2C_CTL1 */ +#define STAT_READDR_OFFSET ((uint32_t)0x00000011U) /*!< bit offset of READDR in I2C_STAT */ +#define TIMING_SCLL_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of SCLL in I2C_TIMING */ +#define TIMING_SCLH_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of SCLH in I2C_TIMING */ +#define TIMING_SDADELY_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SDADELY in I2C_TIMING */ +#define TIMING_SCLDELY_OFFSET ((uint32_t)0x00000014U) /*!< bit offset of SCLDELY in I2C_TIMING */ +#define TIMING_PSC_OFFSET ((uint32_t)0x0000001CU) /*!< bit offset of PSC in I2C_TIMING */ +#define SADDR1_ADDMSK_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of ADDMSK in I2C_SADDR1 */ +#define TIMEOUT_BUSTOB_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BUSTOB in I2C_TIMEOUT */ + +/*! + \brief reset I2C + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph) { + /* reset I2C0 */ + case I2C0: + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + /* reset I2C1 */ + case I2C1: + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; + /* reset I2C2 */ + case I2C2: + rcu_periph_reset_enable(RCU_I2C2RST); + rcu_periph_reset_disable(RCU_I2C2RST); + break; + /* reset I2C3 */ + case I2C3: + rcu_periph_reset_enable(RCU_I2C3RST); + rcu_periph_reset_disable(RCU_I2C3RST); + break; + default: + break; + } +} + +/*! + \brief configure the timing parameters + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] psc: 0-0x0000000F, timing prescaler + \param[in] scl_dely: 0-0x0000000F, data setup time + \param[in] sda_dely: 0-0x0000000F, data hold time + \param[out] none + \retval none +*/ +void i2c_timing_config(uint32_t i2c_periph, uint32_t psc, uint32_t scl_dely, uint32_t sda_dely) +{ + /* clear PSC, SCLDELY, SDADELY bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_PSC; + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLDELY; + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SDADELY; + /* mask PSC, SCLDELY, SDADELY bits in I2C_TIMING register */ + psc = (uint32_t)(psc << TIMING_PSC_OFFSET) & I2C_TIMING_PSC; + scl_dely = (uint32_t)(scl_dely << TIMING_SCLDELY_OFFSET) & I2C_TIMING_SCLDELY; + sda_dely = (uint32_t)(sda_dely << TIMING_SDADELY_OFFSET) & I2C_TIMING_SDADELY; + /* write PSC, SCLDELY, SDADELY bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) |= (psc | scl_dely | sda_dely); +} + +/*! + \brief configure digital noise filter + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] filter_length: the length of filter spikes + only one parameter can be selected which is shown as below: + \arg FILTER_DISABLE: digital filter is disabled + \arg FILTER_LENGTH_1: digital filter is enabled and filter spikes with a length of up to 1 tI2CCLK + \arg FILTER_LENGTH_2: digital filter is enabled and filter spikes with a length of up to 2 tI2CCLK + \arg FILTER_LENGTH_3: digital filter is enabled and filter spikes with a length of up to 3 tI2CCLK + \arg FILTER_LENGTH_4: digital filter is enabled and filter spikes with a length of up to 4 tI2CCLK + \arg FILTER_LENGTH_5: digital filter is enabled and filter spikes with a length of up to 5 tI2CCLK + \arg FILTER_LENGTH_6: digital filter is enabled and filter spikes with a length of up to 6 tI2CCLK + \arg FILTER_LENGTH_7: digital filter is enabled and filter spikes with a length of up to 7 tI2CCLK + \arg FILTER_LENGTH_8: digital filter is enabled and filter spikes with a length of up to 8 tI2CCLK + \arg FILTER_LENGTH_9: digital filter is enabled and filter spikes with a length of up to 9 tI2CCLK + \arg FILTER_LENGTH_10: digital filter is enabled and filter spikes with a length of up to 10 tI2CCLK + \arg FILTER_LENGTH_11: digital filter is enabled and filter spikes with a length of up to 11 tI2CCLK + \arg FILTER_LENGTH_12: digital filter is enabled and filter spikes with a length of up to 12 tI2CCLK + \arg FILTER_LENGTH_13: digital filter is enabled and filter spikes with a length of up to 13 tI2CCLK + \arg FILTER_LENGTH_14: digital filter is enabled and filter spikes with a length of up to 14 tI2CCLK + \arg FILTER_LENGTH_15: digital filter is enabled and filter spikes with a length of up to 15 tI2CCLK + \param[out] none + \retval none +*/ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, uint32_t filter_length) +{ + I2C_CTL0(i2c_periph) &= (uint32_t)(~I2C_CTL0_DNF); + I2C_CTL0(i2c_periph) |= (uint32_t)(filter_length << CTL0_DNF_OFFSET); +} + +/*! + \brief enable analog noise filter + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_ANOFF; +} + +/*! + \brief disable analog noise filter + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ANOFF; +} + +/*! + \brief configure the SCL high and low period of clock in master mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] sclh: 0-0x000000FF, SCL high period + \param[in] scll: 0-0x000000FF, SCL low period + \param[out] none + \retval none +*/ +void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll) +{ + /* clear SCLH, SCLL bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLH; + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLL; + /* mask SCLH, SCLL bits in I2C_TIMING register */ + sclh = (uint32_t)(sclh << TIMING_SCLH_OFFSET) & I2C_TIMING_SCLH; + scll = (uint32_t)(scll << TIMING_SCLL_OFFSET) & I2C_TIMING_SCLL; + /* write SCLH, SCLL bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) |= (sclh | scll); +} + +/*! + \brief configure I2C slave address and transfer direction in master mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] address: 0-0x3FF except reserved address, I2C slave address to be sent + \param[in] trans_direction: I2C transfer direction in master mode + only one parameter can be selected which is shown as below: + \arg I2C_MASTER_TRANSMIT: master transmit + \arg I2C_MASTER_RECEIVE: master receive + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction) +{ + /* configure slave address */ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_SADDRESS; + I2C_CTL1(i2c_periph) |= address; + /* configure transfer direction */ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_TRDIR; + I2C_CTL1(i2c_periph) |= trans_direction; +} + +/*! + \brief 10-bit address header executes read direction only in master receive mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_address10_header_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_HEAD10R; +} + +/*! + \brief 10-bit address header executes complete sequence in master receive mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_address10_header_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_HEAD10R; +} + +/*! + \brief enable 10-bit addressing mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_address10_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_ADD10EN; +} + +/*! + \brief disable 10-bit addressing mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_address10_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_ADD10EN; +} + +/*! + \brief enable I2C automatic end mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_automatic_end_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_AUTOEND; +} + +/*! + \brief disable I2C automatic end mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_automatic_end_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_AUTOEND; +} + +/*! + \brief enable the response to a general call + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_GCEN; +} + +/*! + \brief disable the response to a general call + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_GCEN; +} + +/*! + \brief enable to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SS; +} + +/*! + \brief disable to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SS; +} + +/*! + \brief configure I2C slave address + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] address: I2C address + \param[in] addr_format: 7 bits or 10 bits + only one parameter can be selected which is shown as below: + \arg I2C_ADDFORMAT_7BITS: address format is 7 bits + \arg I2C_ADDFORMAT_10BITS: address format is 10 bits + \param[out] none + \retval none +*/ +void i2c_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_format) +{ + /* configure ADDRESS[7:1] and address format */ + address = address & I2C_ADDRESS_MASK; + I2C_SADDR0(i2c_periph) = (addr_format | address); + /* enable I2C address in slave mode */ + I2C_SADDR0(i2c_periph) |= I2C_SADDR0_ADDRESSEN; +} + +/*! + \brief define which bits of ADDRESS[7:1] need to compare with the incoming address byte + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] compare_bits: the bits need to compare + only one parameter can be selected which is shown as below: + \arg ADDRESS_BIT1_COMPARE: address bit1 needs compare + \arg ADDRESS_BIT2_COMPARE: address bit2 needs compare + \arg ADDRESS_BIT3_COMPARE: address bit3 needs compare + \arg ADDRESS_BIT4_COMPARE: address bit4 needs compare + \arg ADDRESS_BIT5_COMPARE: address bit5 needs compare + \arg ADDRESS_BIT6_COMPARE: address bit6 needs compare + \arg ADDRESS_BIT7_COMPARE: address bit7 needs compare + \param[out] none + \retval none +*/ +void i2c_address_bit_compare_config(uint32_t i2c_periph, uint32_t compare_bits) +{ + I2C_CTL2(i2c_periph) &= ~I2C_CTL2_ADDM; + I2C_CTL2(i2c_periph) |= compare_bits; +} + +/*! + \brief disable I2C address in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_address_disable(uint32_t i2c_periph) +{ + I2C_SADDR0(i2c_periph) &= ~I2C_SADDR0_ADDRESSEN; +} + +/*! + \brief configure I2C second slave address + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] address: I2C address + \param[in] addr_mask: the bits not need to compare + only one parameter can be selected which is shown as below: + \arg ADDRESS2_NO_MASK: no mask, all the bits must be compared + \arg ADDRESS2_MASK_BIT1: ADDRESS2[1] is masked, only ADDRESS2[7:2] are compared + \arg ADDRESS2_MASK_BIT1_2: ADDRESS2[2:1] is masked, only ADDRESS2[7:3] are compared + \arg ADDRESS2_MASK_BIT1_3: ADDRESS2[3:1] is masked, only ADDRESS2[7:4] are compared + \arg ADDRESS2_MASK_BIT1_4: ADDRESS2[4:1] is masked, only ADDRESS2[7:5] are compared + \arg ADDRESS2_MASK_BIT1_5: ADDRESS2[5:1] is masked, only ADDRESS2[7:6] are compared + \arg ADDRESS2_MASK_BIT1_6: ADDRESS2[6:1] is masked, only ADDRESS2[7] are compared + \arg ADDRESS2_MASK_ALL: all the ADDRESS2[7:1] bits are masked + \param[out] none + \retval none +*/ +void i2c_second_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_mask) +{ + /* configure ADDRESS2[7:1] */ + address = address & I2C_ADDRESS2_MASK; + I2C_SADDR1(i2c_periph) |= address; + /* configure ADDRESS2[7:1] mask */ + I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDMSK2; + I2C_SADDR1(i2c_periph) |= (uint32_t)(addr_mask << SADDR1_ADDMSK_OFFSET); + /* enable i2c second address in slave mode */ + I2C_SADDR1(i2c_periph) |= I2C_SADDR1_ADDRESS2EN; +} + +/*! + \brief disable I2C second address in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_second_address_disable(uint32_t i2c_periph) +{ + I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDRESS2EN; +} + +/*! + \brief get received match address in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval uint32_t: received match address +*/ +uint32_t i2c_recevied_address_get(uint32_t i2c_periph) +{ + return (uint32_t)((I2C_STAT(i2c_periph) & I2C_STAT_READDR) >> STAT_READDR_OFFSET); +} + +/*! + \brief enable slave byte control + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_slave_byte_control_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SBCTL; +} + +/*! + \brief disable slave byte control + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_slave_byte_control_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SBCTL; +} + +/*! + \brief generate a NACK in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_nack_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_NACKEN; +} + +/*! + \brief generate an ACK in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_nack_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_NACKEN; +} + +/*! + \brief enable wakeup from deep-sleep mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_wakeup_from_deepsleep_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_WUEN; +} + +/*! + \brief disable wakeup from deep-sleep mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_wakeup_from_deepsleep_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_WUEN; +} + +/*! + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN; +} + +/*! + \brief disable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_I2CEN; +} + +/*! + \brief generate a START condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_START; +} + +/*! + \brief generate a STOP condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_STOP; +} + +/*! + \brief I2C transmit data + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] data: data to be transmitted + \param[out] none + \retval none +*/ +void i2c_data_transmit(uint32_t i2c_periph, uint32_t data) +{ + I2C_TDATA(i2c_periph) = (I2C_TDATA_TDATA & data); +} + +/*! + \brief I2C receive data + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval uint32_t: 0x0-0xFF +*/ +uint32_t i2c_data_receive(uint32_t i2c_periph) +{ + return (I2C_RDATA(i2c_periph) & I2C_RDATA_RDATA); +} + +/*! + \brief enable I2C reload mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_reload_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_RELOAD; +} + +/*! + \brief disable I2C reload mode + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_reload_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_RELOAD; +} + +/*! + \brief configure number of bytes to be transferred + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] byte_number: 0x0-0xFF, number of bytes to be transferred + \param[out] none + \retval none +*/ +void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint32_t byte_number) +{ + I2C_CTL1(i2c_periph) &= (uint32_t)(~I2C_CTL1_BYTENUM); + I2C_CTL1(i2c_periph) |= (uint32_t)(byte_number << CTL1_BYTENUM_OFFSET); +} + +/*! + \brief enable I2C DMA for transmission or reception + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] dma: I2C DMA + only one parameter can be selected which is shown as below: + \arg I2C_DMA_TRANSMIT: transmit data using DMA + \arg I2C_DMA_RECEIVE: receive data using DMA + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma) +{ + if(I2C_DMA_TRANSMIT == dma) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_DENT; + } else { + I2C_CTL0(i2c_periph) |= I2C_CTL0_DENR; + } +} + +/*! + \brief disable I2C DMA for transmission or reception + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] dma: I2C DMA + only one parameter can be selected which is shown as below: + \arg I2C_DMA_TRANSMIT: transmit data using DMA + \arg I2C_DMA_RECEIVE: receive data using DMA + \param[out] none + \retval none +*/ +void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma) +{ + if(I2C_DMA_TRANSMIT == dma) { + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENT; + } else { + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENR; + } +} + +/*! + \brief I2C transfers PEC value + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_pec_transfer(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_PECTRANS; +} + +/*! + \brief enable I2C PEC calculation + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_pec_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_PECEN; +} + +/*! + \brief disable I2C PEC calculation + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_pec_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_PECEN; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval uint32_t: 0x0-0xFF +*/ +uint32_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (I2C_PEC(i2c_periph) & I2C_PEC_PECV); +} + +/*! + \brief enable SMBus alert + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_smbus_alert_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBALTEN; +} + +/*! + \brief disable SMBus alert + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_smbus_alert_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBALTEN; +} + +/*! + \brief enable SMBus device default address + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_smbus_default_addr_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBDAEN; +} + +/*! + \brief disable SMBus device default address + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_smbus_default_addr_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBDAEN; +} + +/*! + \brief enable SMBus host address + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_smbus_host_addr_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBHAEN; +} + +/*! + \brief disable SMBus host address + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_smbus_host_addr_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBHAEN; +} + +/*! + \brief enable extended clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_extented_clock_timeout_enable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_EXTOEN; +} + +/*! + \brief disable extended clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_extented_clock_timeout_disable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_EXTOEN; +} + +/*! + \brief enable clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_clock_timeout_enable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_TOEN; +} + +/*! + \brief disable clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[out] none + \retval none +*/ +void i2c_clock_timeout_disable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOEN; +} + +/*! + \brief configure bus timeout B + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] timeout: bus timeout B + \param[out] none + \retval none +*/ +void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOB; + I2C_TIMEOUT(i2c_periph) |= (uint32_t)(timeout << TIMEOUT_BUSTOB_OFFSET); +} + +/*! + \brief configure bus timeout A + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] timeout: bus timeout A + \param[out] none + \retval none +*/ +void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOA; + I2C_TIMEOUT(i2c_periph) |= timeout; +} + +/*! + \brief configure idle clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] timeout: bus timeout A + \arg BUSTOA_DETECT_SCL_LOW: BUSTOA is used to detect SCL low timeout + \arg BUSTOA_DETECT_IDLE: BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle + \param[out] none + \retval none +*/ +void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOIDLE; + I2C_TIMEOUT(i2c_periph) |= timeout; +} + +/*! + \brief get I2C flag status + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] flag: I2C flags + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_TBE: I2C_TDATA is empty during transmitting + \arg I2C_FLAG_TI: transmit interrupt + \arg I2C_FLAG_RBNE: I2C_RDATA is not empty during receiving + \arg I2C_FLAG_ADDSEND: address received matches in slave mode + \arg I2C_FLAG_NACK: not acknowledge flag + \arg I2C_FLAG_STPDET: STOP condition detected in slave mode + \arg I2C_FLAG_TC: transfer complete in master mode + \arg I2C_FLAG_TCR: transfer complete reload + \arg I2C_FLAG_BERR: bus error + \arg I2C_FLAG_LOSTARB: arbitration Lost + \arg I2C_FLAG_OUERR: overrun/underrun error in slave mode + \arg I2C_FLAG_PECERR: PEC error + \arg I2C_FLAG_TIMEOUT: timeout flag + \arg I2C_FLAG_SMBALT: SMBus alert + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver in slave mode + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag) +{ + if(RESET != (I2C_STAT(i2c_periph) & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear I2C flag status + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] flag: I2C flags + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_ADDSEND: address received matches in slave mode + \arg I2C_FLAG_NACK: not acknowledge flag + \arg I2C_FLAG_STPDET: STOP condition detected in slave mode + \arg I2C_FLAG_BERR: bus error + \arg I2C_FLAG_LOSTARB: arbitration Lost + \arg I2C_FLAG_OUERR: overrun/underrun error in slave mode + \arg I2C_FLAG_PECERR: PEC error + \arg I2C_FLAG_TIMEOUT: timeout flag + \arg I2C_FLAG_SMBALT: SMBus Alert + \param[out] none + \retval none +*/ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag) +{ + I2C_STATC(i2c_periph) |= flag; +} + +/*! + \brief enable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] interrupt: I2C interrupts + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_TC: transfer complete interrupt + \arg I2C_INT_STPDET: stop detection interrupt + \arg I2C_INT_NACK: not acknowledge received interrupt + \arg I2C_INT_ADDM: address match interrupt + \arg I2C_INT_RBNE: receive interrupt + \arg I2C_INT_TI: transmit interrupt + \param[out] none + \retval none +*/ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t interrupt) +{ + I2C_CTL0(i2c_periph) |= interrupt; +} + +/*! + \brief disable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] interrupt: I2C interrupts + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_TC: transfer complete interrupt + \arg I2C_INT_STPDET: stop detection interrupt + \arg I2C_INT_NACK: not acknowledge received interrupt + \arg I2C_INT_ADDM: address match interrupt + \arg I2C_INT_RBNE: receive interrupt + \arg I2C_INT_TI: transmit interrupt + \param[out] none + \retval none +*/ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t interrupt) +{ + I2C_CTL0(i2c_periph) &= ~interrupt; +} + +/*! + \brief get I2C interrupt flag status + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] int_flag: I2C interrupt flags + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_TI: transmit interrupt flag + \arg I2C_INT_FLAG_RBNE: I2C_RDATA is not empty during receiving interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address received matches in slave mode interrupt flag + \arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag + \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_TC: transfer complete in master mode interrupt flag + \arg I2C_INT_FLAG_TCR: transfer complete reload interrupt flag + \arg I2C_INT_FLAG_BERR: bus error interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag + \arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error interrupt flag + \arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + uint32_t ret1 = RESET; + uint32_t ret2 = RESET; + + /* get the status of interrupt enable bit */ + ret1 = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag))); + /* get the status of interrupt flag */ + ret2 = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag))); + if(ret1 && ret2) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear I2C interrupt flag status + \param[in] i2c_periph: I2Cx(x=0,1,2,3) + \param[in] int_flag: I2C interrupt flags + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_ADDSEND: address received matches in slave mode interrupt flag + \arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag + \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_BERR: bus error interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag + \arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error interrupt flag + \arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag + \param[out] none + \retval none +*/ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + I2C_STATC(i2c_periph) |= BIT(I2C_BIT_POS2(int_flag)); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ipa.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ipa.c new file mode 100644 index 0000000000..9fbe1ac1f7 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ipa.c @@ -0,0 +1,823 @@ +/*! + \file gd32h7xx_ipa.c + \brief IPA driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_ipa.h" + +#define IPA_DEFAULT_VALUE 0x00000000U +#define IPA_DEFAULT_SCALE 0x00001000U + +#define IPA_DEFAULT_YUV_CONV_YOFFSET 0x00000000U +#define IPA_DEFAULT_YUV_CONV_UVOFFSET 0x00000000U +#define IPA_DEFAULT_YUV_CONV_C0OFFSET 0x00000100U +#define IPA_DEFAULT_YUV_CONV_C1OFFSET 0x00000123U +#define IPA_DEFAULT_YUV_CONV_C2OFFSET 0x0000076BU +#define IPA_DEFAULT_YUV_CONV_C3OFFSET 0x0000079CU +#define IPA_DEFAULT_YUV_CONV_C4OFFSET 0x00000208U + +#define IPA_DEFAULT_YCBCR_CONV_YOFFSET 0x000001F0U +#define IPA_DEFAULT_YCBCR_CONV_UVOFFSET 0x00000180U +#define IPA_DEFAULT_YCBCR_CONV_C0OFFSET 0x0000012AU +#define IPA_DEFAULT_YCBCR_CONV_C1OFFSET 0x00000198U +#define IPA_DEFAULT_YCBCR_CONV_C2OFFSET 0x00000730U +#define IPA_DEFAULT_YCBCR_CONV_C3OFFSET 0x0000079CU +#define IPA_DEFAULT_YCBCR_CONV_C4OFFSET 0x00000204U + +/*! + \brief deinitialize IPA registers + \param[in] none + \param[out] none + \retval none +*/ +void ipa_deinit(void) +{ + rcu_periph_reset_enable(RCU_IPARST); + rcu_periph_reset_disable(RCU_IPARST); +} + +/*! + \brief enable IPA transfer + \param[in] none + \param[out] none + \retval none +*/ +void ipa_transfer_enable(void) +{ + IPA_CTL |= IPA_CTL_TEN; +} + +/*! + \brief enable IPA transfer hang up + \param[in] none + \param[out] none + \retval none +*/ +void ipa_transfer_hangup_enable(void) +{ + IPA_CTL |= IPA_CTL_THU; +} + +/*! + \brief disable IPA transfer hang up + \param[in] none + \param[out] none + \retval none +*/ +void ipa_transfer_hangup_disable(void) +{ + IPA_CTL &= ~(IPA_CTL_THU); +} + +/*! + \brief enable IPA transfer stop + \param[in] none + \param[out] none + \retval none +*/ +void ipa_transfer_stop_enable(void) +{ + IPA_CTL |= IPA_CTL_TST; +} + +/*! + \brief disable IPA transfer stop + \param[in] none + \param[out] none + \retval none +*/ +void ipa_transfer_stop_disable(void) +{ + IPA_CTL &= ~(IPA_CTL_TST); +} + +/*! + \brief enable IPA foreground LUT loading + \param[in] none + \param[out] none + \retval none +*/ +void ipa_foreground_lut_loading_enable(void) +{ + IPA_FPCTL |= IPA_FPCTL_FLLEN; +} + +/*! + \brief enable IPA background LUT loading + \param[in] none + \param[out] none + \retval none +*/ +void ipa_background_lut_loading_enable(void) +{ + IPA_BPCTL |= IPA_BPCTL_BLLEN; +} + +/*! + \brief set pixel format convert mode, the function is invalid when the IPA transfer is enabled + \param[in] pfcm: pixel format convert mode + only one parameter can be selected which is shown as below: + \arg IPA_FGTODE: foreground memory to destination memory without pixel format convert + \arg IPA_FGTODE_PF_CONVERT: foreground memory to destination memory with pixel format convert + \arg IPA_FGBGTODE: blending foreground and background memory to destination memory + \arg IPA_FILL_UP_DE: fill up destination memory with specific color + \param[out] none + \retval none +*/ +void ipa_pixel_format_convert_mode_set(uint32_t pfcm) +{ + IPA_CTL &= ~(IPA_CTL_PFCM); + IPA_CTL |= pfcm; +} + +/*! + \brief enable foreground interlace mode + \param[in] none + \param[out] none + \retval none +*/ +void ipa_foreground_interlace_mode_enable(void) +{ + IPA_FPCTL |= IPA_FPCTL_FIIMEN; +} + +/*! + \brief disable foreground interlace mode + \param[in] none + \param[out] none + \retval none +*/ +void ipa_foreground_interlace_mode_disable(void) +{ + IPA_FPCTL &= ~(IPA_FPCTL_FIIMEN); +} + +/*! + \brief initialize the structure of IPA foreground parameter struct with the default values, it is + suggested that call this function after an ipa_foreground_parameter_struct structure is defined + \param[in] none + \param[out] foreground_struct: the data needed to initialize foreground + \retval none +*/ +void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct* foreground_struct) +{ + /* initialize the struct parameters with default values */ + foreground_struct->foreground_memaddr = IPA_DEFAULT_VALUE; + foreground_struct->foreground_lineoff = IPA_DEFAULT_VALUE; + foreground_struct->foreground_prealpha = IPA_DEFAULT_VALUE; + foreground_struct->foreground_alpha_algorithm = IPA_FG_ALPHA_MODE_0; + foreground_struct->foreground_pf = FOREGROUND_PPF_ARGB8888; + foreground_struct->foreground_prered = IPA_DEFAULT_VALUE; + foreground_struct->foreground_pregreen = IPA_DEFAULT_VALUE; + foreground_struct->foreground_preblue = IPA_DEFAULT_VALUE; + foreground_struct->foreground_interlace_mode = DISABLE; + foreground_struct->foreground_efuv_memaddr = IPA_DEFAULT_VALUE; +} + +/*! + \brief initialize foreground parameters + \param[in] foreground_struct: the data needed to initialize foreground + foreground_memaddr: foreground memory base address + foreground_lineoff: foreground line offset + foreground_prealpha: foreground pre-defined alpha value + foreground_alpha_algorithm: IPA_FG_ALPHA_MODE_0,IPA_FG_ALPHA_MODE_1,IPA_FG_ALPHA_MODE_2 + foreground_pf: foreground pixel format(FOREGROUND_PPF_ARGB8888, FOREGROUND_PPF_RGB888, FOREGROUND_PPF_RGB565, + FOREGROUND_PPF_ARGB1555, FOREGROUND_PPF_ARGB4444, FOREGROUND_PPF_L8, FOREGROUND_PPF_AL44, + FOREGROUND_PPF_AL88, FOREGROUND_PPF_L4, FOREGROUND_PPF_A8, FOREGROUND_PPF_A4, + FOREGROUND_PPF_YUV444_1P, FOREGROUND_PPF_UYVY422_1P, FOREGROUND_PPF_VYUY422_1P, + FOREGROUND_PPF_YUV420_2P, FOREGROUND_PPF_YVU420_2P) + foreground_prered: foreground pre-defined red value + foreground_pregreen: foreground pre-defined green value + foreground_preblue: foreground pre-defined blue value + foreground_interlace_mode: ENABLE, DISABLE + foreground_efuv_memaddr: foreground even frame / UV memory base address + \param[out] none + \retval none +*/ +void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct) +{ + FlagStatus tempflag = RESET; + if(RESET != (IPA_CTL & IPA_CTL_TEN)){ + tempflag = SET; + /* reset the TEN in order to configure the following bits */ + IPA_CTL &= ~IPA_CTL_TEN; + } + + /* foreground memory base address configuration */ + IPA_FMADDR &= ~(IPA_FMADDR_FMADDR); + IPA_FMADDR = foreground_struct->foreground_memaddr; + /* foreground line offset configuration */ + IPA_FLOFF &= ~(IPA_FLOFF_FLOFF); + IPA_FLOFF = foreground_struct->foreground_lineoff; + /* foreground pixel format pre-defined alpha, alpha calculation algorithm configuration */ + IPA_FPCTL &= ~(IPA_FPCTL_FPDAV | IPA_FPCTL_FAVCA | IPA_FPCTL_FPF | IPA_FPCTL_FIIMEN); + IPA_FPCTL |= (foreground_struct->foreground_prealpha << 24U); + IPA_FPCTL |= foreground_struct->foreground_alpha_algorithm; + IPA_FPCTL |= foreground_struct->foreground_pf; + if(ENABLE == foreground_struct->foreground_interlace_mode){ + IPA_FPCTL |= IPA_FPCTL_FIIMEN; + } + /* foreground pre-defined red green blue configuration */ + IPA_FPV &= ~(IPA_FPV_FPDRV | IPA_FPV_FPDGV| IPA_FPV_FPDBV); + IPA_FPV |= ((foreground_struct->foreground_prered << 16U) | (foreground_struct->foreground_pregreen << 8U) + | (foreground_struct->foreground_preblue)); + /* foreground even frame / UV memory base address configuration */ + IPA_EF_UV_MADDR &= ~(IPA_EF_UV_MADDR_EFUVMADDR); + IPA_EF_UV_MADDR = foreground_struct->foreground_efuv_memaddr; + + if(SET == tempflag){ + /* restore the state of TEN */ + IPA_CTL |= IPA_CTL_TEN; + } +} + +/*! + \brief initialize the structure of IPA background parameter struct with the default values, it is + suggested that call this function after an ipa_background_parameter_struct structure is defined + \param[in] none + \param[out] background_struct: the data needed to initialize background + \retval none +*/ +void ipa_background_struct_para_init(ipa_background_parameter_struct* background_struct) +{ + /* initialize the struct parameters with default values */ + background_struct->background_memaddr = IPA_DEFAULT_VALUE; + background_struct->background_lineoff = IPA_DEFAULT_VALUE; + background_struct->background_prealpha = IPA_DEFAULT_VALUE; + background_struct->background_alpha_algorithm = IPA_BG_ALPHA_MODE_0; + background_struct->background_pf = BACKGROUND_PPF_ARGB8888; + background_struct->background_prered = IPA_DEFAULT_VALUE; + background_struct->background_pregreen = IPA_DEFAULT_VALUE; + background_struct->background_preblue = IPA_DEFAULT_VALUE; +} + +/*! + \brief initialize background parameters + \param[in] background_struct: the data needed to initialize background + background_memaddr: background memory base address + background_lineoff: background line offset + background_prealpha: background pre-defined alpha value + background_alpha_algorithm: IPA_BG_ALPHA_MODE_0, IPA_FG_ALPHA_MODE_1, IPA_FG_ALPHA_MODE_2 + background_pf: background pixel format(BACKGROUND_PPF_ARGB8888, BACKGROUND_PPF_RGB888, BACKGROUND_PPF_RGB565, + BACKGROUND_PPF_ARGB1555, BACKGROUND_PPF_ARGB4444, BACKGROUND_PPF_L8, BACKGROUND_PPF_AL44, + BACKGROUND_PPF_AL88, BACKGROUND_PPF_L4, BACKGROUND_PPF_A8, BACKGROUND_PPF_A4) + background_prered: background pre-defined red value + background_pregreen: background pre-defined green value + background_preblue: background pre-defined blue value + \param[out] none + \retval none +*/ +void ipa_background_init(ipa_background_parameter_struct* background_struct) +{ + FlagStatus tempflag = RESET; + if(RESET != (IPA_CTL & IPA_CTL_TEN)){ + tempflag = SET; + /* reset the TEN in order to configure the following bits */ + IPA_CTL &= ~IPA_CTL_TEN; + } + + /* background memory base address configuration */ + IPA_BMADDR &= ~(IPA_BMADDR_BMADDR); + IPA_BMADDR = background_struct->background_memaddr; + /* background line offset configuration */ + IPA_BLOFF &= ~(IPA_BLOFF_BLOFF); + IPA_BLOFF = background_struct->background_lineoff; + /* background pixel format pre-defined alpha, alpha calculation algorithm configuration */ + IPA_BPCTL &= ~(IPA_BPCTL_BPDAV | IPA_BPCTL_BAVCA | IPA_BPCTL_BPF); + IPA_BPCTL |= (background_struct->background_prealpha << 24U); + IPA_BPCTL |= background_struct->background_alpha_algorithm; + IPA_BPCTL |= background_struct->background_pf; + /* background pre-defined red green blue configuration */ + IPA_BPV &= ~(IPA_BPV_BPDRV|IPA_BPV_BPDGV | IPA_BPV_BPDBV); + IPA_BPV |= ((background_struct->background_prered << 16U) | (background_struct->background_pregreen << 8U) + | (background_struct->background_preblue)); + + if(SET == tempflag){ + /* restore the state of TEN */ + IPA_CTL |= IPA_CTL_TEN; + } +} + +/*! + \brief initialize the structure of IPA destination parameter struct with the default values, it is + suggested that call this function after an ipa_destination_parameter_struct structure is defined + \param[in] none + \param[out] destination_struct: the data needed to initialize destination parameter + \retval none +*/ +void ipa_destination_struct_para_init(ipa_destination_parameter_struct* destination_struct) +{ + /* initialize the struct parameters with default values */ + destination_struct->destination_pf = IPA_DPF_ARGB8888; + destination_struct->destination_lineoff = IPA_DEFAULT_VALUE; + destination_struct->destination_prealpha = IPA_DEFAULT_VALUE; + destination_struct->destination_prered = IPA_DEFAULT_VALUE; + destination_struct->destination_pregreen = IPA_DEFAULT_VALUE; + destination_struct->destination_preblue = IPA_DEFAULT_VALUE; + destination_struct->destination_memaddr = IPA_DEFAULT_VALUE; + destination_struct->image_width = IPA_DEFAULT_VALUE; + destination_struct->image_height = IPA_DEFAULT_VALUE; + destination_struct->image_rotate = DESTINATION_ROTATE_0; + destination_struct->image_hor_decimation = DESTINATION_HORDECIMATE_DISABLE; + destination_struct->image_ver_decimation = DESTINATION_VERDECIMATE_DISABLE; + destination_struct->image_bilinear_xscale = IPA_DEFAULT_SCALE; + destination_struct->image_bilinear_yscale = IPA_DEFAULT_SCALE; + destination_struct->image_scaling_width = IPA_DEFAULT_VALUE; + destination_struct->image_scaling_height = IPA_DEFAULT_VALUE; +} + +/*! + \brief initialize destination parameters + \param[in] destination_struct: the data needed to initialize destination parameters + destination_pf: IPA_DPF_ARGB8888, IPA_DPF_RGB888, IPA_DPF_RGB565, IPA_DPF_ARGB1555, + IPA_DPF_ARGB4444, refer to ipa_dpf_enum + destination_lineoff: destination line offset + destination_prealpha: destination pre-defined alpha value + destination_prered: destination pre-defined red value + destination_pregreen: destination pre-defined green value + destination_preblue: destination pre-defined blue value + destination_memaddr: destination memory base address + image_width: width of the image to be processed + image_height: height of the image to be processed + image_rotate: DESTINATION_ROTATE_0, DESTINATION_ROTATE_90, + DESTINATION_ROTATE_180, DESTINATION_ROTATE_270 + image_hor_decimation: DESTINATION_HORDECIMATE_DISABLE, DESTINATION_HORDECIMATE_2, + DESTINATION_HORDECIMATE_4, DESTINATION_HORDECIMATE_8 + image_ver_decimation: DESTINATION_VERDECIMATE_DISABLE, DESTINATION_VERDECIMATE_2, + DESTINATION_VERDECIMATE_4, DESTINATION_VERDECIMATE_8 + image_bilinear_xscale: x scaling factor + image_bilinear_yscale: y scaling factor + image_scaling_width: width of the image after scaling + image_scaling_height: height of the image after scaling + \param[out] none + \retval none +*/ +void ipa_destination_init(ipa_destination_parameter_struct* destination_struct) +{ + uint32_t destination_pixelformat; + FlagStatus tempflag = RESET; + if(RESET != (IPA_CTL & IPA_CTL_TEN)){ + tempflag = SET; + /* reset the TEN in order to configure the following bits */ + IPA_CTL &= ~IPA_CTL_TEN; + } + + /* destination pixel format, interlace sampling method and rotation configuration */ + IPA_DPCTL &= ~(IPA_DPCTL_DPF | IPA_DPCTL_ROT | IPA_DPCTL_HORDEC | IPA_DPCTL_VERDEC); + IPA_DPCTL = (destination_struct->destination_pf | + destination_struct->image_rotate | + destination_struct->image_hor_decimation | + destination_struct->image_ver_decimation); + destination_pixelformat = destination_struct->destination_pf; + /* destination pixel format ARGB8888 */ + switch(destination_pixelformat){ + case IPA_DPF_ARGB8888: + IPA_DPV &= ~(IPA_DPV_DPDBV_0 | (IPA_DPV_DPDGV_0) | (IPA_DPV_DPDRV_0) | (IPA_DPV_DPDAV_0)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 8U) + | (destination_struct->destination_prered << 16U) + | (destination_struct->destination_prealpha << 24U)); + break; + /* destination pixel format RGB888 */ + case IPA_DPF_RGB888: + IPA_DPV &= ~(IPA_DPV_DPDBV_1 | (IPA_DPV_DPDGV_1) | (IPA_DPV_DPDRV_1)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 8U) + | (destination_struct->destination_prered << 16U)); + break; + /* destination pixel format RGB565 */ + case IPA_DPF_RGB565: + IPA_DPV &= ~(IPA_DPV_DPDBV_2 | (IPA_DPV_DPDGV_2) | (IPA_DPV_DPDRV_2)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 5U) + | (destination_struct->destination_prered << 11U)); + break; + /* destination pixel format ARGB1555 */ + case IPA_DPF_ARGB1555: + IPA_DPV &= ~(IPA_DPV_DPDBV_3 | (IPA_DPV_DPDGV_3) | (IPA_DPV_DPDRV_3)|(IPA_DPV_DPDAV_3)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 5U) + | (destination_struct->destination_prered << 10U) + | (destination_struct->destination_prealpha << 15U)); + break; + /* destination pixel format ARGB4444 */ + case IPA_DPF_ARGB4444: + IPA_DPV &= ~(IPA_DPV_DPDBV_4 | (IPA_DPV_DPDGV_4) | (IPA_DPV_DPDRV_4)|(IPA_DPV_DPDAV_4)); + IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 4U) + | (destination_struct->destination_prered << 8U) + | (destination_struct->destination_prealpha << 12U)); + break; + default: + break; + } + /* destination memory base address configuration */ + IPA_DMADDR &= ~(IPA_DMADDR_DMADDR); + IPA_DMADDR = destination_struct->destination_memaddr; + /* destination line offset configuration */ + IPA_DLOFF &= ~(IPA_DLOFF_DLOFF); + IPA_DLOFF = destination_struct->destination_lineoff; + /* image size configuration */ + IPA_IMS &= ~(IPA_IMS_HEIGHT | IPA_IMS_WIDTH); + IPA_IMS |= ((destination_struct->image_width << 16U) | (destination_struct->image_height)); + /* xscale and yscale configuration */ + IPA_BSCTL &= ~(IPA_BSCTL_XSCALE | IPA_BSCTL_YSCALE); + IPA_BSCTL = ((destination_struct->image_bilinear_xscale & IPA_BSCTL_XSCALE) | + ((uint32_t)(destination_struct->image_bilinear_yscale << 16U) & IPA_BSCTL_YSCALE)); + /* image size after scaling configuration */ + IPA_DIMS &= ~(IPA_DIMS_DWIDTH | IPA_DIMS_DHEIGHT); + IPA_DIMS = (destination_struct->image_scaling_height & IPA_DIMS_DHEIGHT) | + ((uint32_t)((destination_struct->image_scaling_width << 16U) & IPA_DIMS_DWIDTH)); + + if(SET == tempflag){ + /* restore the state of TEN */ + IPA_CTL |= IPA_CTL_TEN; + } +} + +/*! + \brief initialize IPA foreground LUT parameters + \param[in] fg_lut_num: foreground LUT number of pixel + \param[in] fg_lut_pf: foreground LUT pixel format(IPA_LUT_PF_ARGB8888, IPA_LUT_PF_RGB888) + \param[in] fg_lut_addr: foreground LUT memory base address + \param[out] none + \retval none +*/ +void ipa_foreground_lut_init(uint8_t fg_lut_num, uint8_t fg_lut_pf, uint32_t fg_lut_addr) +{ + FlagStatus tempflag = RESET; + if(RESET != (IPA_FPCTL & IPA_FPCTL_FLLEN)){ + tempflag = SET; + /* reset the FLLEN in order to configure the following bits */ + IPA_FPCTL &= ~IPA_FPCTL_FLLEN; + } + + /* foreground LUT number of pixel configuration */ + IPA_FPCTL |= ((uint32_t)fg_lut_num << 8U); + /* foreground LUT pixel format configuration */ + if(IPA_LUT_PF_RGB888 == fg_lut_pf){ + IPA_FPCTL |= IPA_FPCTL_FLPF; + }else if(IPA_LUT_PF_ARGB8888 == fg_lut_pf){ + IPA_FPCTL &= ~(IPA_FPCTL_FLPF); + }else{ + } + /* foreground LUT memory base address configuration */ + IPA_FLMADDR &= ~(IPA_FLMADDR_FLMADDR); + IPA_FLMADDR = fg_lut_addr; + + if(SET == tempflag){ + /* restore the state of FLLEN */ + IPA_FPCTL |= IPA_FPCTL_FLLEN; + } +} + +/*! + \brief initialize IPA background LUT parameters + \param[in] bg_lut_num: background LUT number of pixel + \param[in] bg_lut_pf: background LUT pixel format(IPA_LUT_PF_ARGB8888, IPA_LUT_PF_RGB888) + \param[in] bg_lut_addr: background LUT memory base address + \param[out] none + \retval none +*/ +void ipa_background_lut_init(uint8_t bg_lut_num, uint8_t bg_lut_pf, uint32_t bg_lut_addr) +{ + FlagStatus tempflag = RESET; + if(RESET != (IPA_BPCTL & IPA_BPCTL_BLLEN)){ + tempflag = SET; + /* reset the BLLEN in order to configure the following bits */ + IPA_BPCTL &= ~IPA_BPCTL_BLLEN; + } + + /* background LUT number of pixel configuration */ + IPA_BPCTL |= ((uint32_t)bg_lut_num << 8U); + /* background LUT pixel format configuration */ + if(IPA_LUT_PF_RGB888 == bg_lut_pf){ + IPA_BPCTL |= IPA_BPCTL_BLPF; + }else if(IPA_LUT_PF_ARGB8888 == bg_lut_pf){ + IPA_BPCTL &= ~(IPA_BPCTL_BLPF); + }else{ + } + /* background LUT memory base address configuration */ + IPA_BLMADDR &= ~(IPA_BLMADDR_BLMADDR); + IPA_BLMADDR = bg_lut_addr; + + if(SET == tempflag){ + /* restore the state of BLLEN */ + IPA_BPCTL |= IPA_BPCTL_BLLEN; + } +} + +/*! + \brief configure IPA line mark + \param[in] line_num: line number + \param[out] none + \retval none +*/ +void ipa_line_mark_config(uint16_t line_num) +{ + IPA_LM &= ~(IPA_LM_LM); + IPA_LM = line_num; +} + +/*! + \brief inter-timer enable or disable + \param[in] timer_cfg: IPA_INTER_TIMER_ENABLE,IPA_INTER_TIMER_DISABLE + \param[out] none + \retval none +*/ +void ipa_inter_timer_config(uint8_t timer_cfg) +{ + if(IPA_INTER_TIMER_ENABLE == timer_cfg){ + /* inter-timer enable */ + IPA_ITCTL |= IPA_ITCTL_ITEN; + }else if(IPA_INTER_TIMER_DISABLE == timer_cfg){ + /* inter-timer disable */ + IPA_ITCTL &= ~(IPA_ITCTL_ITEN); + }else{ + /* do nothing */ + } +} + +/*! + \brief configure the number of clock cycles interval + \param[in] clk_num: the number of clock cycles + \param[out] none + \retval none +*/ +void ipa_interval_clock_num_config(uint8_t clk_num) +{ + /* NCCI[7:0] bits have no meaning if ITEN is '0' */ + IPA_ITCTL &= ~(IPA_ITCTL_NCCI); + IPA_ITCTL |= ((uint32_t)clk_num << 8U); +} + +/*! + \brief configure the color space conversion parameter + \param[out] conversion_struct: the data needed to configure color conversion parameters + \param[in] ipa_colorspace_enum: the color space + IPA_COLORSPACE_YUV: using default YUV parameter to initialization struct + IPA_COLORSPACE_YCBCR: using default YCbCr parameter to initialization struct + \retval none +*/ +void ipa_color_conversion_struct_para_init(ipa_conversion_parameter_struct* conversion_struct, ipa_colorspace_enum colorspace) +{ + if(IPA_COLORSPACE_YUV == colorspace){ + /* initialize the struct parameters with default YUV conversion values */ + conversion_struct->color_space = IPA_COLORSPACE_YUV; + conversion_struct->y_offset = IPA_DEFAULT_YUV_CONV_YOFFSET; + conversion_struct->uv_offset = IPA_DEFAULT_YUV_CONV_UVOFFSET; + conversion_struct->coef_c0 = IPA_DEFAULT_YUV_CONV_C0OFFSET; + conversion_struct->coef_c1 = IPA_DEFAULT_YUV_CONV_C1OFFSET; + conversion_struct->coef_c2 = IPA_DEFAULT_YUV_CONV_C2OFFSET; + conversion_struct->coef_c3 = IPA_DEFAULT_YUV_CONV_C3OFFSET; + conversion_struct->coef_c4 = IPA_DEFAULT_YUV_CONV_C4OFFSET; + }else if(IPA_COLORSPACE_YCBCR == colorspace){ + /* initialize the struct parameters with default YCbCr conversion values */ + conversion_struct->color_space = IPA_COLORSPACE_YCBCR; + conversion_struct->y_offset = IPA_DEFAULT_YCBCR_CONV_YOFFSET; + conversion_struct->uv_offset = IPA_DEFAULT_YCBCR_CONV_UVOFFSET; + conversion_struct->coef_c0 = IPA_DEFAULT_YCBCR_CONV_C0OFFSET; + conversion_struct->coef_c1 = IPA_DEFAULT_YCBCR_CONV_C1OFFSET; + conversion_struct->coef_c2 = IPA_DEFAULT_YCBCR_CONV_C2OFFSET; + conversion_struct->coef_c3 = IPA_DEFAULT_YCBCR_CONV_C3OFFSET; + conversion_struct->coef_c4 = IPA_DEFAULT_YCBCR_CONV_C4OFFSET; + }else{ + /* do nothing */ + } +} + +/*! + \brief configure the color space conversion parameter + \param[in] conversion_struct: the data needed to configure color conversion parameters + color_space: IPA_COLORSPACE_YUV, IPA_COLORSPACE_YCBCR + y_offset: offset implicit in the Y data + uv_offset: offset implicit in the UV data + coef_c0: Y multiplier coefficient + coef_c1: V/Cr red multiplier coefficient + coef_c2: V/Cr green multiplier coefficient + coef_c3: U/Cb green multiplier coefficient + coef_c4: U/Cb blue multiplier coefficient + \param[out] none + \retval none +*/ +void ipa_color_conversion_config(ipa_conversion_parameter_struct* conversion_struct) +{ + FlagStatus tempflag = RESET; + if(RESET != (IPA_CTL & IPA_CTL_TEN)){ + tempflag = SET; + /* reset the TEN in order to configure the following bits */ + IPA_CTL &= ~IPA_CTL_TEN; + } + + /* Y offset, UV offset, compliment Y multiplier configuration */ + IPA_CSCC_CFG0 &= ~(IPA_CSCC_CFG0_YOFF | IPA_CSCC_CFG0_UVOFF | IPA_CSCC_CFG0_C0); + IPA_CSCC_CFG0 |= (((conversion_struct->y_offset) & IPA_CSCC_CFG0_YOFF) | + ((uint32_t)(conversion_struct->uv_offset << 9U) & IPA_CSCC_CFG0_UVOFF) | + ((uint32_t)(conversion_struct->coef_c0 << 18U) & IPA_CSCC_CFG0_C0)); + /* red V/Cr multiplier, blue U/Cb multiplier configuration */ + IPA_CSCC_CFG1 &= ~(IPA_CSCC_CFG1_C1 | IPA_CSCC_CFG1_C4); + IPA_CSCC_CFG1 |= ((conversion_struct->coef_c4 & IPA_CSCC_CFG1_C4) | + ((uint32_t)(conversion_struct->coef_c1 << 16U) & IPA_CSCC_CFG1_C1)); + /* green V/Cr multiplier coefficient, green U/Cb multiplier configuration */ + IPA_CSCC_CFG2 &= ~(IPA_CSCC_CFG2_C2 | IPA_CSCC_CFG2_C3); + IPA_CSCC_CFG2 |= ((conversion_struct->coef_c3 & IPA_CSCC_CFG2_C3) | + ((uint32_t)(conversion_struct->coef_c2 << 16U) & IPA_CSCC_CFG2_C2)); + + if(IPA_COLORSPACE_YUV == conversion_struct->color_space){ + /* convert YUV to RGB */ + IPA_CSCC_CFG0 &= ~(IPA_CSCC_CFG0_CONVMOD); + }else{ + /* convert YCbCr to RGB */ + IPA_CSCC_CFG0 |= IPA_CSCC_CFG0_CONVMOD; + } + + if(SET == tempflag){ + /* restore the state of TEN */ + IPA_CTL |= IPA_CTL_TEN; + } +} + +/*! + \brief configure IPA foreground scaling, including horizontal/vertical pre-decimation factors and X/Y scaling factors + \param[in] horizontal_decimation: horizontal scaling value + only one parameter can be selected which is shown as below: + \arg DESTINATION_HORDECIMATE_DISABLE: disable horizontal decimate + \arg DESTINATION_HORDECIMATE_2: horizontal decimated by 2 + \arg DESTINATION_HORDECIMATE_4: horizontal decimated by 4 + \arg DESTINATION_HORDECIMATE_8: horizontal decimated by 8 + \param[in] vertical_decimation: vertical scaling value + only one parameter can be selected which is shown as below: + \arg DESTINATION_VERDECIMATE_DISABLE: disable vertical decimate + \arg DESTINATION_VERDECIMATE_2: vertical decimated by 2 + \arg DESTINATION_VERDECIMATE_4: vertical decimated by 4 + \arg DESTINATION_VERDECIMATE_8: vertical decimated by 8 + \param[in] image_scaling_width: image scaling factor of width + \param[in] image_scaling_height: image scaling factor of height + \param[out] none + \retval none +*/ +void ipa_foreground_scaling_config(uint32_t horizontal_decimation, uint32_t vertical_decimation, uint32_t image_scaling_width, uint32_t image_scaling_height) +{ + /* configure decimation filter */ + IPA_DPCTL &= ~(uint32_t)(IPA_DPCTL_VERDEC | IPA_DPCTL_HORDEC); + IPA_DPCTL |= (horizontal_decimation | vertical_decimation); + + /* XScaling and YScaling configuration */ + IPA_BSCTL &= ~(IPA_BSCTL_XSCALE | IPA_BSCTL_YSCALE); + IPA_BSCTL = ((image_scaling_width & IPA_BSCTL_XSCALE) | + ((uint32_t)(image_scaling_height << 16U) & IPA_BSCTL_YSCALE)); +} + +/*! + \brief configure IPA destination scaling, including width/height of image to be processed + \param[in] dest_scaling_width: width of destination image after scaling + \param[in] dest_scaling_height: height of destination image after scaling + \param[out] none + \retval none +*/ +void ipa_destination_scaling_config(uint32_t dest_scaling_width, uint32_t dest_scaling_height) +{ + IPA_DIMS &= ~(IPA_DIMS_DWIDTH | IPA_DIMS_DHEIGHT); + IPA_DIMS = (dest_scaling_height & IPA_DIMS_DHEIGHT) | + ((uint32_t)((dest_scaling_width << 16U) & IPA_DIMS_DWIDTH)); +} + +/*! + \brief get IPA flag status in IPA_INTF register + \param[in] flag: IPA flags + one or more parameters can be selected which are shown as below: + \arg IPA_FLAG_TAE: transfer access error interrupt flag + \arg IPA_FLAG_FTF: full transfer finish interrupt flag + \arg IPA_FLAG_TLM: transfer line mark interrupt flag + \arg IPA_FLAG_LAC: LUT access conflict interrupt flag + \arg IPA_FLAG_LLF: LUT loading finish interrupt flag + \arg IPA_FLAG_WCF: wrong configuration interrupt flag + \param[out] none + \retval none +*/ +FlagStatus ipa_flag_get(uint32_t flag) +{ + if(RESET != (IPA_INTF & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear IPA flag in IPA_INTF register + \param[in] flag: IPA flags + one or more parameters can be selected which are shown as below: + \arg IPA_FLAG_TAE: transfer access error interrupt flag + \arg IPA_FLAG_FTF: full transfer finish interrupt flag + \arg IPA_FLAG_TLM: transfer line mark interrupt flag + \arg IPA_FLAG_LAC: LUT access conflict interrupt flag + \arg IPA_FLAG_LLF: LUT loading finish interrupt flag + \arg IPA_FLAG_WCF: wrong configuration interrupt flag + \param[out] none + \retval none +*/ +void ipa_flag_clear(uint32_t flag) +{ + IPA_INTC |= (flag); +} + +/*! + \brief enable IPA interrupt + \param[in] int_flag: IPA interrupt flags + one or more parameters can be selected which are shown as below: + \arg IPA_INT_TAE: transfer access error interrupt + \arg IPA_INT_FTF: full transfer finish interrupt + \arg IPA_INT_TLM: transfer line mark interrupt + \arg IPA_INT_LAC: LUT access conflict interrupt + \arg IPA_INT_LLF: LUT loading finish interrupt + \arg IPA_INT_WCF: wrong configuration interrupt + \param[out] none + \retval none +*/ +void ipa_interrupt_enable(uint32_t int_flag) +{ + IPA_CTL |= (int_flag); +} + +/*! + \brief disable IPA interrupt + \param[in] int_flag: IPA interrupt flags + one or more parameters can be selected which are shown as below: + \arg IPA_INT_TAE: transfer access error interrupt + \arg IPA_INT_FTF: full transfer finish interrupt + \arg IPA_INT_TLM: transfer line mark interrupt + \arg IPA_INT_LAC: LUT access conflict interrupt + \arg IPA_INT_LLF: LUT loading finish interrupt + \arg IPA_INT_WCF: wrong configuration interrupt + \param[out] none + \retval none +*/ +void ipa_interrupt_disable(uint32_t int_flag) +{ + IPA_CTL &= ~(int_flag); +} + +/*! + \brief get IPA interrupt flag + \param[in] int_flag: IPA interrupt flag flags + one or more parameters can be selected which are shown as below: + \arg IPA_INT_FLAG_TAE: transfer access error interrupt flag + \arg IPA_INT_FLAG_FTF: full transfer finish interrupt flag + \arg IPA_INT_FLAG_TLM: transfer line mark interrupt flag + \arg IPA_INT_FLAG_LAC: LUT access conflict interrupt flag + \arg IPA_INT_FLAG_LLF: LUT loading finish interrupt flag + \arg IPA_INT_FLAG_WCF: wrong configuration interrupt flag + \param[out] none + \retval none +*/ +FlagStatus ipa_interrupt_flag_get(uint32_t int_flag) +{ + if(RESET != (IPA_INTF & int_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear IPA interrupt flag + \param[in] int_flag: IPA interrupt flag flags + one or more parameters can be selected which are shown as below: + \arg IPA_INT_FLAG_TAE: transfer access error interrupt flag + \arg IPA_INT_FLAG_FTF: full transfer finish interrupt flag + \arg IPA_INT_FLAG_TLM: transfer line mark interrupt flag + \arg IPA_INT_FLAG_LAC: LUT access conflict interrupt flag + \arg IPA_INT_FLAG_LLF: LUT loading finish interrupt flag + \arg IPA_INT_FLAG_WCF: wrong configuration interrupt flag + \param[out] none + \retval none +*/ +void ipa_interrupt_flag_clear(uint32_t int_flag) +{ + IPA_INTC |= (int_flag); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_lpdts.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_lpdts.c new file mode 100644 index 0000000000..9cb350527e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_lpdts.c @@ -0,0 +1,332 @@ +/*! + \file gd32h7xx_lpdts.c + \brief LPDTS driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_lpdts.h" + +/* LPDTS high threshold value offset macro */ +#define LPDTS_IT_INTHT_OFFSET ((uint32_t)16U) +/* sampling time offset macro */ +#define LPDTS_CFG_SPT_OFFSET ((uint32_t)16U) +/* engineering value offset macro */ +#define LPDTS_SDATA_VAL_OFFSET ((uint32_t)16U) +/* the T0 temperature macro */ +#define LPDTS_T0_TMP_VAL ((uint32_t)25U) + +/*! + \brief reset the LPDTS registers + \param[in] none + \param[out] none + \retval none +*/ +void lpdts_deinit(void) +{ + rcu_periph_reset_enable(RCU_LPDTSRST); + rcu_periph_reset_disable(RCU_LPDTSRST); +} + +/*! + \brief initialize the parameters of LPDTS struct with the default values + \param[in] none + \param[out] init_struct: the initialization data needed to initialize LPDTS + \retval none +*/ +void lpdts_struct_para_init(lpdts_parameter_struct *init_struct) +{ + /* set the struct with the default values */ + init_struct->ref_clock = REF_PCLK; + init_struct->trigger_input = NO_HARDWARE_TRIGGER; + init_struct->sampling_time = SPT_CLOCK_15; +} + +/*! + \brief initialize the LPDTS + \param[in] init_struct: the initialization data needed to initialize LPDTS_CFG + ref_clock: REF_PCLK, REF_LXTAL + trigger_input: NO_HARDWARE_TRIGGER, LPDTS_TRG + sampling_time: SPT_CLOCK_x(x=1..15) + \param[out] none + \retval none +*/ +void lpdts_init(lpdts_parameter_struct *init_struct) +{ + uint32_t reg; + /* configure the LPDTS_CFG */ + reg = LPDTS_CFG; + reg &= ~(LPDTS_CFG_REFSEL | LPDTS_CFG_ITSEL | LPDTS_CFG_SPT); + reg |= (init_struct->ref_clock | init_struct->trigger_input | init_struct->sampling_time); + LPDTS_CFG = reg; +} + +/*! + \brief enable LPDTS temperature sensor + \param[in] none + \param[out] none + \retval none +*/ +void lpdts_enable(void) +{ + LPDTS_CFG |= LPDTS_CFG_TSEN; +} + +/*! + \brief disable LPDTS temperature sensor + \param[in] none + \param[out] none + \retval none +*/ +void lpdts_disable(void) +{ + LPDTS_CFG &= ~LPDTS_CFG_TSEN; +} + +/*! + \brief enable LPDTS software trigger + \param[in] none + \param[out] none + \retval none +*/ +void lpdts_soft_trigger_enable(void) +{ + LPDTS_CFG |= LPDTS_CFG_TRGS; +} + +/*! + \brief disable LPDTS software trigger + \param[in] none + \param[out] none + \retval none +*/ +void lpdts_soft_trigger_disable(void) +{ + LPDTS_CFG &= ~LPDTS_CFG_TRGS; +} + +/*! + \brief configure LPDTS high threshold value + \param[in] value: high threshold value(0~65535) + \param[out] none + \retval none +*/ +void lpdts_high_threshold_set(uint16_t value) +{ + uint32_t reg; + /* configure the LPDTS_IT */ + reg = LPDTS_IT; + reg &= ~LPDTS_IT_INTHT; + reg |= (uint32_t)value << LPDTS_IT_INTHT_OFFSET; + LPDTS_IT = reg; +} + +/*! + \brief configure LPDTS low threshold value + \param[in] value: low threshold value(0~65535) + \param[out] none + \retval none +*/ +void lpdts_low_threshold_set(uint16_t value) +{ + uint32_t reg; + /* configure the LPDTS_IT */ + reg = LPDTS_IT; + reg &= ~LPDTS_IT_INTLT; + reg |= (uint32_t)value; + LPDTS_IT = reg; +} + +/*! + \brief configure LPDTS reference clock selection + \param[in] source: reference clock source + only one parameter can be selected which is shown as below: + \arg REF_PCLK: high speed reference clock (PCLK) + \arg REF_LXTAL: low speed reference clock (LXTAL) + \param[out] none + \retval none +*/ +void lpdts_ref_clock_source_config(uint32_t source) +{ + uint32_t reg; + /* configure the LPDTS_CFG */ + reg = LPDTS_CFG; + reg &= ~LPDTS_CFG_REFSEL; + reg |= source; + LPDTS_CFG = reg; +} + +/*! + \brief get temperature from LPDTS + \param[in] none + \param[out] none + \retval temperature: temperature in deg C +*/ +int32_t lpdts_temperature_get(void) +{ + uint32_t freq; + uint32_t count; + uint32_t t0; + uint32_t t0_freq; + uint32_t ramp_coeff; + uint32_t reg_cfg; + int32_t temperature; + + /* get the total number of samples */ + count = (LPDTS_DATA & LPDTS_DATA_COVAL); + /* get LPDTS_CFG configuration */ + reg_cfg = LPDTS_CFG; + + /* get the module frequency on Hz */ + if((reg_cfg & LPDTS_CFG_REFSEL) == LPDTS_CFG_REFSEL) { + freq = (LXTAL_VALUE * count) / (2U * ((reg_cfg & LPDTS_CFG_SPT) >> LPDTS_CFG_SPT_OFFSET)); + } else { + freq = (2U * rcu_clock_freq_get(CK_APB1) / count) * ((reg_cfg & LPDTS_CFG_SPT) >> LPDTS_CFG_SPT_OFFSET); + } + + /* read factory settings */ + t0 = (LPDTS_SDATA & LPDTS_SDATA_VAL) >> LPDTS_SDATA_VAL_OFFSET; + if(t0 == 0U) { + t0 = LPDTS_T0_TMP_VAL; + } + + /* get the T0 frequency on Hz */ + t0_freq = (LPDTS_SDATA & LPDTS_SDATA_FREQ) * 100U; + /* get the ramp coefficient for the temperature sensor on deg C/Hz */ + ramp_coeff = LPDTS_RDATA & LPDTS_RDATA_RCVAL; + + /* figure out the temperature deg C */ + temperature = (int32_t)t0 + (((int32_t)freq - (int32_t)t0_freq) / (int32_t)ramp_coeff); + + return temperature; +} + +/*! + \brief get LPDTS flag + \param[in] flag: LPDTS ready flag + only one parameter can be selected which is shown as below: + \arg LPDTS_FLAG_TSR + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus lpdts_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + + if(LPDTS_STAT & flag) { + status = SET; + } + /* return the state of corresponding LPDTS flag */ + return status; +} + +/*! + \brief enable LPDTS interrupt + \param[in] interrupt: the LPDTS interrupt + one or more parameters can be selected which is shown as below: + \arg LPDTS_INT_EM + \arg LPDTS_INT_LT + \arg LPDTS_INT_HT + \arg LPDTS_INT_EMA + \arg LPDTS_INT_LTA + \arg LPDTS_INT_HTA + \param[out] none + \retval none +*/ +void lpdts_interrupt_enable(uint32_t interrupt) +{ + LPDTS_INTEN |= interrupt; +} + +/*! + \brief disable LPDTS interrupt + \param[in] interrupt: the LPDTS interrupt + one or more parameters can be selected which is shown as below: + \arg LPDTS_INT_EM + \arg LPDTS_INT_LT + \arg LPDTS_INT_HT + \arg LPDTS_INT_EMA + \arg LPDTS_INT_LTA + \arg LPDTS_INT_HTA + \param[out] none + \retval none +*/ +void lpdts_interrupt_disable(uint32_t interrupt) +{ + LPDTS_INTEN &= ~interrupt; +} + +/*! + \brief get LPDTS interrupt flag + \param[in] flag: LPDTS interrupt flag + only one parameter can be selected which is shown as below: + \arg LPDTS_INT_FLAG_EM + \arg LPDTS_INT_FLAG_LT + \arg LPDTS_INT_FLAG_HT + \arg LPDTS_INT_FLAG_EMA + \arg LPDTS_INT_FLAG_LTA + \arg LPDTS_INT_FLAG_HTA + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus lpdts_interrupt_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + uint32_t state; + + state = LPDTS_STAT; + if(state & flag) { + state = LPDTS_INTEN; + if(state & flag) { + status = SET; + } + } + /* return the state of corresponding LPDTS flag */ + return status; +} + +/*! + \brief clear the LPDTS interrupt flag + \param[in] flag: LPDTS flag + one or more parameter can be selected which is shown as below: + \arg LPDTS_INT_FLAG_EM + \arg LPDTS_INT_FLAG_LT + \arg LPDTS_INT_FLAG_HT + \arg LPDTS_INT_FLAG_EMA + \arg LPDTS_INT_FLAG_LTA + \arg LPDTS_INT_FLAG_HTA + \param[out] none + \retval none +*/ +void lpdts_interrupt_flag_clear(uint32_t flag) +{ + /* clear the flags */ + LPDTS_INTC = flag; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdio.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdio.c new file mode 100644 index 0000000000..bf1f56ef58 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdio.c @@ -0,0 +1,404 @@ +/*! + \file gd32h7xx_mdio.c + \brief MDIO driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_mdio.h" + +/*! + \brief reset MDIO + \param[in] none + \param[out] none + \retval none +*/ +void mdio_deinit(void) +{ + /* reset MDIO */ + rcu_periph_reset_enable(RCU_MDIORST); + rcu_periph_reset_disable(RCU_MDIORST); +} + +/*! + \brief reset MDIO block + \param[in] none + \param[out] none + \retval none +*/ +void mdio_software_reset(void) +{ + MDIO_CTL |= MDIO_CTL_SWRST; +} + +/*! + \brief initialize MDIO for communication + \param[in] phy_size: PHY bit length + only one parameter can be selected which is shown as below: + \arg MDIO_PHY_BITS_3: PHY use 3 bits + \arg MDIO_PHY_BITS_5: PHY use 5 bits + \param[in] phy_softaddr: software provided PHYADR (0 - 31) + \param[in] phy_sel: PHYADR select + only one parameter can be selected which is shown as below: + \arg MDIO_PHYADR_HARDWARE: sets expected PHYADR = PHYPIN[4:0] + \arg MDIO_PHYADR_HW_SW_MIX(regval): sets Software address valid bits + \arg MDIO_PHYADR_SOFTWARE: sets expected PHYADR = PHYSW[4:0] + \arg other user defined value: 1 - 30 + \param[in] devadd: device type + only one parameter can be selected which is shown as below: + \arg DEVADD_PMA_PMD: device type PMA/PMD + \arg DEVADD_WIS: device type WIS + \arg DEVADD_PCS: device type PCS + \arg DEVADD_PHY_XS: device type PHY XS + \arg DEVADD_DTE_XS: device type DTE XS + \param[out] none + \retval uint32_t: the PHYADR that the device will respond to 0 - 31 +*/ +uint32_t mdio_init(uint32_t phy_size, uint32_t phy_softaddr, uint32_t phy_sel, uint16_t devadd) +{ + uint32_t phy_addr = 0U, phy_hard = 0U; + + /* configure MDIO phy bit length */ + MDIO_CTL &= ~MDIO_CTL_PHYB; + MDIO_CTL |= phy_size; + + /* configure the PHYADR and DEVADD */ + MDIO_CFG &= ~(MDIO_CFG_PHYSW | MDIO_CFG_EPHYSEL | MDIO_CFG_EDEVADD); + MDIO_CFG |= CFG_PHYSW(phy_softaddr) | CFG_EPHYSEL(phy_sel) | CFG_EDEVADD(devadd); + + /* calculate the PHYADR that the device will respond to */ + phy_hard = mdio_phy_pin_read(); + phy_addr = (phy_hard & (~phy_sel)) | (phy_softaddr & phy_sel); + + return phy_addr; +} + +/*! + \brief configure MDIO phy bit length + \param[in] phy_bit: PHY bit length + only one parameter can be selected which is shown as below: + \arg MDIO_PHY_BITS_3: PHY use 3 bits + \arg MDIO_PHY_BITS_5: PHY use 5 bits + \param[out] none + \retval none +*/ +void mdio_phy_length_config(uint32_t phy_bit) +{ + MDIO_CTL &= ~MDIO_CTL_PHYB; + MDIO_CTL |= phy_bit; +} + +/*! + \brief set the software PHYADR value + \param[in] phy_soft: software provided PHYADR (0 - 31) + \param[out] none + \retval none +*/ +void mdio_soft_phyadr_set(uint32_t phy_soft) +{ + MDIO_CFG &= ~MDIO_CFG_PHYSW; + MDIO_CFG |= CFG_PHYSW(phy_soft); +} + +/*! + \brief select the expected frame field PHYADR + \param[in] phy_sel: PHYADR select + only one parameter can be selected which is shown as below: + \arg MDIO_PHYADR_HARDWARE: sets expected PHYADR = PHYPIN[4:0] + \arg MDIO_PHYADR_SOFTWARE: sets expected PHYADR = PHYSW[4:0] + \arg other user defined value: 1 - 30 + \param[out] none + \retval none +*/ +void mdio_framefield_phyadr_config(uint32_t phy_sel) +{ + MDIO_CFG &= ~MDIO_CFG_EPHYSEL; + MDIO_CFG |= CFG_EPHYSEL(phy_sel); +} + +/*! + \brief configure the expected frame field DEVADD + \param[in] type: device type + only one parameter can be selected which is shown as below: + \arg DEVADD_PMA_PMD: device type PMA/PMD + \arg DEVADD_WIS: device type WIS + \arg DEVADD_PCS: device type PCS + \arg DEVADD_PHY_XS: device type PHY XS + \arg DEVADD_DTE_XS: device type DTE XS + \param[out] none + \retval none +*/ +void mdio_framefield_devadd_config(uint16_t type) +{ + MDIO_CFG &= ~MDIO_CFG_EDEVADD; + MDIO_CFG |= CFG_EDEVADD(type); +} + +/*! + \brief read the hardware PRTADR[4:0] value + \param[in] none + \param[out] none + \retval uint32_t: 0x0-0x1F +*/ +uint32_t mdio_phy_pin_read(void) +{ + return GET_PIN_PHYPIN(MDIO_PIN); +} + +/*! + \brief configure the expected frame bit timeout + \param[in] timeout: timeout counter among frame bits (0 - 0xFFFF) + \param[out] none + \retval none +*/ +void mdio_timeout_config(uint16_t timeout) +{ + MDIO_TO &= ~MDIO_TO_TOCNT; + MDIO_TO |= TO_TOCNT(timeout); +} + +/*! + \brief enable MDIO frame bit timeout + \param[in] none + \param[out] none + \retval none +*/ +void mdio_timeout_enable(void) +{ + MDIO_TO |= MDIO_TO_TOEN; +} + +/*! + \brief disable MDIO frame bit timeout + \param[in] none + \param[out] none + \retval none +*/ +void mdio_timeout_disable(void) +{ + MDIO_TO &= ~MDIO_TO_TOEN; +} + +/*! + \brief read the received frame field OP + \param[in] none + \param[out] none + \retval uint16_t: 0x0-0x11 +*/ +uint16_t mdio_op_receive(void) +{ + return (uint16_t)(GET_RFRM_ROP(MDIO_RFRM)); +} + +/*! + \brief read the received frame field PHYADR + \param[in] none + \param[out] none + \retval uint16_t: 0x0-0x1F +*/ +uint16_t mdio_phyadr_receive(void) +{ + return (uint16_t)(GET_RFRM_RPHY(MDIO_RFRM)); +} + +/*! + \brief read the received frame field DEVADD + \param[in] none + \param[out] none + \retval uint16_t: 0x0-0x1F +*/ +uint16_t mdio_devadd_receive(void) +{ + return (uint16_t)(GET_RFRM_RDEV(MDIO_RFRM)); +} + +/*! + \brief read the received frame field TA + \param[in] none + \param[out] none + \retval uint16_t: 0x0-0x11 +*/ +uint16_t mdio_ta_receive(void) +{ + return (uint16_t)(GET_RFRM_RTA(MDIO_RFRM)); +} + +/*! + \brief read the received frame field DATA + \param[in] none + \param[out] none + \retval uint16_t: 0x0-0xFFFF +*/ +uint16_t mdio_data_receive(void) +{ + return (uint16_t)(GET_RDATA_RDATA(MDIO_RDATA)); +} + +/*! + \brief read the received frame field ADDRESS + \param[in] none + \param[out] none + \retval uint16_t: 0x0-0xFFFF +*/ +uint16_t mdio_address_receive(void) +{ + return (uint16_t)(GET_RADDR_RADDR(MDIO_RADDR)); +} + +/*! + \brief transmit the frame field DATA + \param[in] data: data to put in a read or post read increment address frame for transmission (0x0-0xFFFF) + \param[out] none + \retval none +*/ +void mdio_data_transmit(uint16_t data) +{ + MDIO_TDATA = (uint32_t)data; +} + +/*! + \brief get the flag status of the frame + \param[in] flag: MDIO flag + only one parameter can be selected which is shown as below: + \arg MDIO_FLAG_WRFRM: a write data frame flag status + \arg MDIO_FLAG_ADDRFRM: an address frame flag status + \arg MDIO_FLAG_RDINCFRM: a post read increment address frame flag status + \arg MDIO_FLAG_RDFRM: a read data frame flag status + \arg MDIO_FLAG_DEVM: a DEVADD match frame flag status + \arg MDIO_FLAG_DEVNM: a DEVADD nonmatch frame flag status + \arg MDIO_FLAG_PHYM: a PHYADR match frame flag status + \arg MDIO_FLAG_PHYNM: a PHYADR nonmatch frame flag status + \arg MDIO_FLAG_TANM: a TA nonmatch frame flag status + \arg MDIO_FLAG_TIMEOUT: timeout flag + \arg MDIO_FLAG_TX_UNDERRUN: transmit underrun flag + \arg MDIO_FLAG_RX_OVERRUN: receive overrun flag + \arg MDIO_FLAG_RBNE: read data buffer not empty flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mdio_flag_get(uint32_t flag) +{ + __IO uint32_t reg = 0U; + + reg = MDIO_STAT; + if(RESET != (reg & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the flag status + \param[in] flag: MDIO flag + one or more parameters can be selected which are shown as below: + \arg MDIO_FLAG_WRFRM: a write data frame flag status + \arg MDIO_FLAG_ADDRFRM: an address frame flag status + \arg MDIO_FLAG_RDINCFRM: a post read increment address frame flag status + \arg MDIO_FLAG_RDFRM: a read data frame flag status + \arg MDIO_FLAG_DEVM: a DEVADD match frame flag status + \arg MDIO_FLAG_DEVNM: a DEVADD nonmatch frame flag status + \arg MDIO_FLAG_PHYM: a PHYADR match frame flag status + \arg MDIO_FLAG_PHYNM: a PHYADR nonmatch frame flag status + \arg MDIO_FLAG_TANM: a TA nonmatch frame flag status + \arg MDIO_FLAG_TIMEOUT: timeout flag + \arg MDIO_FLAG_TX_UNDERRUN: transmit underrun flag + \arg MDIO_FLAG_RX_OVERRUN: receive overrun flag + \arg MDIO_FLAG_RBNE: read data buffer not empty flag + \param[out] none + \retval none +*/ +void mdio_flag_clear(uint32_t flag) +{ + __IO uint32_t reg = 0U; + + reg = MDIO_TDATA; + + if((MDIO_FLAG_RX_OVERRUN | MDIO_FLAG_RBNE) & flag){ + (void)(MDIO_RDATA); + }else if(MDIO_FLAG_TX_UNDERRUN & flag){ + MDIO_TDATA = reg; + }else if((MDIO_FLAG_WRFRM | MDIO_FLAG_ADDRFRM | MDIO_FLAG_RDINCFRM | MDIO_FLAG_RDFRM + | MDIO_FLAG_DEVM | MDIO_FLAG_DEVNM | MDIO_FLAG_PHYM | MDIO_FLAG_PHYNM | MDIO_FLAG_TIMEOUT) & flag){ + (void)(MDIO_STAT); + } else { + /* illegal parameters */ + } +} + +/*! + \brief enable MDIO interrupt + \param[in] interrupt: MDIO interrupt + one or more parameters can be selected which are shown as below: + \arg MDIO_INT_WRFRM: a write data frame interrupt + \arg MDIO_INT_ADDRFRM: an address frame interrupt + \arg MDIO_INT_RDINCFRM: a post read increment address frame interrupt + \arg MDIO_INT_RDFRM: a read data frame interrupt + \arg MDIO_INT_DEVM: a DEVADD match frame interrupt + \arg MDIO_INT_DEVNM: a DEVADD nonmatch frame interrupt + \arg MDIO_INT_PHYM: a PHYADR match frame interrupt + \arg MDIO_INT_PHYNM: a PHYADR nonmatch frame interrupt + \arg MDIO_INT_TANM: a TA nonmatch frame flag interrupt + \arg MDIO_INT_TIMEOUT: a timeout interrupt + \arg MDIO_INT_TX_UNDERRUN: a transmit underrun interrupt + \arg MDIO_INT_RX_OVERRUN: a receive overrun interrupt + \arg MDIO_INT_RBNE: a read data buffer not empty interrupt + \param[out] none + \retval none +*/ +void mdio_interrupt_enable(uint32_t interrupt) +{ + MDIO_INTEN |= interrupt; +} + +/*! + \brief disable MDIO interrupt + \param[in] interrupt: MDIO interrupt + one or more parameters can be selected which are shown as below: + \arg MDIO_INT_WRFRM: a write data frame interrupt + \arg MDIO_INT_ADDRFRM: an address frame interrupt + \arg MDIO_INT_RDINCFRM: a post read increment address frame interrupt + \arg MDIO_INT_RDFRM: a read data frame interrupt + \arg MDIO_INT_DEVM: a DEVADD match frame interrupt + \arg MDIO_INT_DEVNM: a DEVADD nonmatch frame interrupt + \arg MDIO_INT_PHYM: a PHYADR match frame interrupt + \arg MDIO_INT_PHYNM: a PHYADR nonmatch frame interrupt + \arg MDIO_INT_TANM: a TA nonmatch frame flag interrupt + \arg MDIO_INT_TIMEOUT: a timeout interrupt + \arg MDIO_INT_TX_UNDERRUN: a transmit underrun interrupt + \arg MDIO_INT_RX_OVERRUN: a receive overrun interrupt + \arg MDIO_INT_RBNE: a read data buffer not empty interrupt + \param[out] none + \retval none +*/ +void mdio_interrupt_disable(uint32_t interrupt) +{ + MDIO_INTEN &= ~(interrupt); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdma.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdma.c new file mode 100644 index 0000000000..b8ade9909c --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_mdma.c @@ -0,0 +1,1018 @@ +/*! + \file gd32h7xx_mdma.c + \brief MDMA driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_mdma.h" +#include + +#define MDMA_ADDRESS_MASK ((uint32_t)0x0000FFFFU) /*!< MDMA multi-block update address mask */ +#define STAT1_FLAG_MASK ((uint32_t)0x0000F000U) /*!< MDMA_STAT1 flag mask */ +#define CHXMBADDRU_DADDRUV_OFFSET (16U) /*!< destination update address offset */ +#define CHXCFG_BTLEN_OFFSET (18U) /*!< bit offset of BTLEN in MDMA_CHxCFG */ +#define CHXBTCFG_BRNUM_OFFSET (20U) /*!< bit offset of BRNUM in MDMA_CHxBTCFG */ + +/*! + \brief deinitialize MDMA + \param[in] none + \param[out] none + \retval none +*/ +void mdma_deinit(void) +{ + /* reset MDMA */ + rcu_periph_reset_enable(RCU_MDMARST); + rcu_periph_reset_disable(RCU_MDMARST); +} + +/*! + \brief deinitialize MDMA registers of a channel + \param[in] channelx: specify which MDMA channel is deinitialized + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval none +*/ +void mdma_channel_deinit(mdma_channel_enum channelx) +{ + MDMA_CHXSTATC(channelx) = 0x0000001FU; + MDMA_CHXCTL0(channelx) = 0U; + MDMA_CHXCFG(channelx) = 0U; + MDMA_CHXBTCFG(channelx) = 0U; + MDMA_CHXSADDR(channelx) = 0U; + MDMA_CHXDADDR(channelx) = 0U; + MDMA_CHXMBADDRU(channelx) = 0U; + MDMA_CHXLADDR(channelx) = 0U; + MDMA_CHXCTL1(channelx) = 0U; + MDMA_CHXMADDR(channelx) = 0U; + MDMA_CHXMDATA(channelx) = 0U; +} + +/*! + \brief initialize the MDMA single data mode parameters structure with the default values + \param[in] none + \param[out] init_struct: the initialization data needed to initialize MDMA channel + \retval none +*/ +void mdma_para_struct_init(mdma_parameter_struct *init_struct) +{ + /* set the MDMA struct with the default values */ + init_struct->request = 0U; + init_struct->trans_trig_mode = MDMA_BUFFER_TRANSFER; + init_struct->priority = MDMA_PRIORITY_LOW; + init_struct->endianness = MDMA_LITTLE_ENDIANNESS; + init_struct->source_inc = MDMA_SOURCE_INCREASE_DISABLE; + init_struct->dest_inc = MDMA_DESTINATION_INCREASE_DISABLE; + init_struct->source_data_size = MDMA_SOURCE_DATASIZE_8BIT; + init_struct->dest_data_dize = MDMA_DESTINATION_DATASIZE_8BIT; + init_struct->data_alignment = MDMA_DATAALIGN_RIGHT; + init_struct->buff_trans_len = 0U; + init_struct->source_burst = MDMA_SOURCE_BURST_SINGLE; + init_struct->dest_burst = MDMA_DESTINATION_BURST_SINGLE; + init_struct->mask_addr = 0x00000000U; + init_struct->mask_data = 0x00000000U; + init_struct->source_addr = 0x00000000U; + init_struct->destination_addr = 0x00000000U; + init_struct->tbytes_num_in_block = 0U; + init_struct->source_bus = MDMA_SOURCE_AXI; + init_struct->destination_bus = MDMA_DESTINATION_AXI; + init_struct->bufferable_write_mode = MDMA_BUFFERABLE_WRITE_DISABLE; +} + +/*! + \brief initialize the MDMA multi block transfer mode parameters structure with the default values + \param[in] none + \param[out] block_init_struct: the initialization data needed to initialize MDMA multi block transfer + \retval none +*/ +void mdma_multi_block_para_struct_init(mdma_multi_block_parameter_struct *block_init_struct) +{ + block_init_struct->block_num = 0U; + block_init_struct->saddr_update_val = 0U; + block_init_struct->dstaddr_update_val = 0U; + block_init_struct->saddr_update_dir = UPDATE_DIR_INCREASE; + block_init_struct->dstaddr_update_dir = UPDATE_DIR_INCREASE; +} + +/*! + \brief initialize the MDMA link node configuration structure with the default values + \param[in] none + \param[out] node: the initialization data needed to initialize link node + \retval none +*/ +void mdma_link_node_para_struct_init(mdma_link_node_parameter_struct *node) +{ + node->chxcfg_reg = 0U; + node->chxbtcfg_reg = 0U; + node->chxsaddr_reg = 0U; + node->chxdaddr_reg = 0U; + node->chxmbaddru_reg = 0U; + node->chxladdr_reg = 0U; + node->chxctl1_reg = 0U; + node->reserved = 0U; + node->chxmaddr_reg = 0U; + node->chxmdata_reg = 0U; +} + +/*! + \brief initialize MDMA channel with MDMA parameter structure + \param[in] channelx: specify which MDMA channel is initialized + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] init_struct: the data needed to initialize MDMA single data mode + and the member values are shown as below: + request: MDMA_REQUEST_DMA0_CH0_FTFIF, MDMA_REQUEST_DMA0_CH1_FTFIF, MDMA_REQUEST_DMA0_CH2_FTFIF, MDMA_REQUEST_DMA0_CH3_FTFIF, MDMA_REQUEST_DMA0_CH4_FTFIF, + MDMA_REQUEST_DMA0_CH5_FTFIF, MDMA_REQUEST_DMA0_CH6_FTFIF, MDMA_REQUEST_DMA0_CH7_FTFIF, MDMA_REQUEST_DMA1_CH0_FTFIF, MDMA_REQUEST_DMA1_CH1_FTFIF, + MDMA_REQUEST_DMA1_CH2_FTFIF, MDMA_REQUEST_DMA1_CH3_FTFIF, MDMA_REQUEST_DMA1_CH4_FTFIF, MDMA_REQUEST_DMA1_CH5_FTFIF, MDMA_REQUEST_DMA1_CH6_FTFIF, + MDMA_REQUEST_DMA1_CH7_FTFIF, MDMA_REQUEST_TLI_INT, MDMA_REQUEST_OSPI0_FT, MDMA_REQUEST_OSPI0_TC, MDMA_REQUEST_IPA_CLUT_TRIG, MDMA_REQUEST_IPA_TC_TRIG, + MDMA_REQUEST_IPA_TWM_TRIG, MDMA_REQUEST_SDIO0_DATA_END, MDMA_REQUEST_SDIO0_BUF_END, MDMA_REQUEST_SDIO0_CMD_END, MDMA_REQUEST_OSPI1_FT, + MDMA_REQUEST_OSPI1_TC, MDMA_REQUEST_SW + trans_trig_mode: MDMA_BUFFER_TRANSFER, MDMA_BLOCK_TRANSFER, MDMA_MULTI_BLOCK_TRANSFER, MDMA_COMPLETE_TRANSFER + priority: MDMA_PRIORITY_LOW, MDMA_PRIORITY_MEDIUM, MDMA_PRIORITY_HIGH, MDMA_PRIORITY_ULTRA_HIGH + endianness: MDMA_LITTLE_ENDIANNESS, MDMA_BYTE_ENDIANNESS_EXCHANGE, MDMA_HALFWORD_ENDIANNESS_EXCHANGE, MDMA_WORD_ENDIANNESS_EXCHANGE + source_inc: MDMA_SOURCE_INCREASE_DISABLE, MDMA_SOURCE_INCREASE_8BIT, MDMA_SOURCE_INCREASE_16BIT, MDMA_SOURCE_INCREASE_32BIT, MDMA_SOURCE_INCREASE_64BIT, + MDMA_SOURCE_DECREASE_8BIT, MDMA_SOURCE_DECREASE_16BIT, MDMA_SOURCE_DECREASE_32BIT, MDMA_SOURCE_DECREASE_64BIT + dest_inc: MDMA_DESTINATION_INCREASE_DISABLE, MDMA_DESTINATION_INCREASE_8BIT, MDMA_DESTINATION_INCREASE__16BIT, MDMA_DESTINATION_INCREASE_32BIT, MDMA_DESTINATION_INCREASE_64BIT, + MDMA_DESTINATION_DECREASE_8BIT, MDMA_DESTINATION_DECREASE_16BIT, MDMA_DESTINATION_DECREASE_32BIT, MDMA_DESTINATION_DECREASE_64BIT + source_data_size: MDMA_SOURCE_DATASIZE_8BIT, MDMA_SOURCE_DATASIZE_16BIT, MDMA_SOURCE_DATASIZE_32BIT, MDMA_SOURCE_DATASIZE_64BIT + dest_data_dize: MDMA_DESTINATION_DATASIZE_8BIT, MDMA_DESTINATION_DATASIZE_16BIT, MDMA_DESTINATION_DATASIZE_32BIT, MDMA_DESTINATION_DATASIZE_64BIT + data_alignment: MDMA_DATAALIGN_PKEN, MDMA_DATAALIGN_RIGHT, MDMA_DATAALIGN_RIGHT_SIGNED, MDMA_DATAALIGN_LEFT + buff_trans_len: the number of bytes to be transferred is (buff_trans_len+1), buff_trans_len ranges from 0 to 127 + source_burst: MDMA_SOURCE_BURST_SINGLE, MDMA_SOURCE_BURST_2BEATS, MDMA_SOURCE_BURST_4BEATS, MDMA_SOURCE_BURST_8BEATS, MDMA_SOURCE_BURST_16BEATS, + MDMA_SOURCE_BURST_32BEATS, MDMA_SOURCE_BURST_64BEATS, MDMA_SOURCE_BURST_128BEATS + dest_burst: MDMA_DESTINATION_BURST_SINGLE, MDMA_DESTINATION_BURST_2BEATS, MDMA_DESTINATION_BURST_4BEATS, MDMA_DESTINATION_BURST_8BEATS, MDMA_DESTINATION_BURST_16BEATS, + MDMA_DESTINATION_BURST_32BEATS, MDMA_DESTINATION_BURST_64BEATS, MDMA_DESTINATION_BURST_128BEATS + mask_addr: mask address, ranges from 0x00000000 to 0xFFFFFFFF + mask_data: mask data, ranges from 0x00000000 to 0xFFFFFFFF + source_addr: source address, ranges from 0x00000000 to 0xFFFFFFFF + destination_addr: destination address, ranges from 0x00000000 to 0xFFFFFFFF + tbytes_num_in_block: transfer byte number of a block transfer, ranges from 0x00000000 to 0x0001FFFF + source_bus: MDMA_SOURCE_AXI, MDMA_SOURCE_AHB_TCM + destination_bus: MDMA_DESTINATION_AXI, MDMA_DESTINATION_AHB_TCM + bufferable_write_mode: MDMA_BUFFERABLE_WRITE_ENABLE, MDMA_BUFFERABLE_WRITE_DISABLE + \param[out] none + \retval none +*/ +void mdma_init(mdma_channel_enum channelx, mdma_parameter_struct *init_struct) +{ + mdma_channel_disable(channelx); + + /* configure endianness and priority */ + MDMA_CHXCTL0(channelx) &= ~(MDMA_CHXCTL0_BES | MDMA_CHXCTL0_HWES | MDMA_CHXCTL0_WES | MDMA_CHXCTL0_PRIO); + MDMA_CHXCTL0(channelx) |= (init_struct->endianness | init_struct->priority); + + /* configure MDMA transfer width, memory transfer width, channel priority */ + MDMA_CHXCFG(channelx) = (init_struct->data_alignment | init_struct->dest_burst | init_struct->dest_data_dize | init_struct->dest_inc | \ + init_struct->source_burst | init_struct->source_data_size | init_struct->source_inc | init_struct->trans_trig_mode | \ + ((init_struct->buff_trans_len << CHXCFG_BTLEN_OFFSET) & MDMA_CHXCFG_BTLEN) | init_struct->bufferable_write_mode); + /* configure mask address, mask data */ + MDMA_CHXMADDR(channelx) = init_struct->mask_addr; + MDMA_CHXMDATA(channelx) = init_struct->mask_data; + + /* configure source address */ + MDMA_CHXSADDR(channelx) = init_struct->source_addr; + /* configure destination address */ + MDMA_CHXDADDR(channelx) = init_struct->destination_addr; + + /* configure block transfer byte number */ + if(MDMA_BUFFER_TRANSFER == init_struct->trans_trig_mode) { + MDMA_CHXBTCFG(channelx) = (init_struct->tbytes_num_in_block & MDMA_CHXBTCFG_TBNUM); + } else if(MDMA_BLOCK_TRANSFER == init_struct->trans_trig_mode) { + MDMA_CHXBTCFG(channelx) = (init_struct->tbytes_num_in_block & MDMA_CHXBTCFG_TBNUM); + } else if(MDMA_MULTI_BLOCK_TRANSFER == init_struct->trans_trig_mode) { + MDMA_CHXBTCFG(channelx) &= ~MDMA_CHXBTCFG_TBNUM; + MDMA_CHXBTCFG(channelx) |= (init_struct->tbytes_num_in_block & MDMA_CHXBTCFG_TBNUM); + } else if(MDMA_COMPLETE_TRANSFER == init_struct->trans_trig_mode) { + MDMA_CHXBTCFG(channelx) &= ~MDMA_CHXBTCFG_TBNUM; + MDMA_CHXBTCFG(channelx) |= (init_struct->tbytes_num_in_block & MDMA_CHXBTCFG_TBNUM); + } else { + /* illegal parameters */ + } + + /* configure request source */ + MDMA_CHXCFG(channelx) &= ~MDMA_CHXCFG_SWREQMOD; + if(MDMA_REQUEST_SW == init_struct->request) { + MDMA_CHXCFG(channelx) |= MDMA_CHXCFG_SWREQMOD; + } else { + MDMA_CHXCTL1(channelx) &= ~MDMA_CHXCTL1_TRIGSEL; + MDMA_CHXCTL1(channelx) |= init_struct->request; + } + /* configure bus type for source and destination */ + MDMA_CHXCTL1(channelx) &= ~(MDMA_CHXCTL1_SBSEL | MDMA_CHXCTL1_DBSEL); + MDMA_CHXCTL1(channelx) |= (init_struct->source_bus | init_struct->destination_bus); +} + +/*! + \brief configure MDMA buffer/block transfer mode + \param[in] channelx: specify which MDMA channel is initialized + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] saddr: source address, ranges from 0x00000000 to 0xFFFFFFFF + \param[in] daddr: destination address, ranges from 0x00000000 to 0xFFFFFFFF + \param[in] tbnum: number of bytes to transfer, ranges from 0x00000000 to 0x00010000 + \param[out] none + \retval none +*/ +void mdma_buffer_block_mode_config(mdma_channel_enum channelx, uint32_t saddr, uint32_t daddr, uint32_t tbnum) +{ + MDMA_CHXSADDR(channelx) = saddr; + MDMA_CHXDADDR(channelx) = daddr; + MDMA_CHXBTCFG(channelx) &= ~MDMA_CHXBTCFG_TBNUM; + MDMA_CHXBTCFG(channelx) |= (tbnum & MDMA_CHXBTCFG_TBNUM); +} + +/*! + \brief configure MDMA multi block transfer mode + \param[in] channelx: specify which MDMA channel is initialized + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] tbnum: number of bytes to transfer in block, range from 0x00000000 to 0x00000FFF + \param[in] block_init_struct: the data needed to initialize MDMA multi block mode, + the member values are shown as below: + block_num: multi block number, ranges from 0x00000000 to 0x00000FFF + saddr_update_val: source address update value, ranges from 0x0000 to 0xFFFF + dstaddr_update_val: destination address update value, ranges from 0x0000 to 0xFFFF + saddr_update_dir: source address update direction, UPDATE_DIR_INCREASE, UPDATE_DIR_DECREASE + dstaddr_update_dir: destination address update direction, UPDATE_DIR_INCREASE, UPDATE_DIR_DECREASE + \param[out] none + \retval none +*/ +void mdma_multi_block_mode_config(mdma_channel_enum channelx, uint32_t tbnum, mdma_multi_block_parameter_struct *block_init_struct) +{ + uint32_t blockoffset; + + MDMA_CHXBTCFG(channelx) = (((block_init_struct->block_num << CHXBTCFG_BRNUM_OFFSET) & MDMA_CHXBTCFG_BRNUM) | (tbnum & MDMA_CHXBTCFG_TBNUM)); + + MDMA_CHXMBADDRU(channelx) &= ~(MDMA_CHXMBADDRU_SADDRUV | MDMA_CHXMBADDRU_DADDRUV); + /* if block source address offset is negative, set the block repeat source address update mode to decrement */ + if(UPDATE_DIR_DECREASE == block_init_struct->saddr_update_dir) { + MDMA_CHXBTCFG(channelx) |= MDMA_CHXBTCFG_SADDRUM; + /* write new chxmbaddru register value: source repeat block offset */ + blockoffset = (uint32_t)block_init_struct->saddr_update_val; + MDMA_CHXMBADDRU(channelx) |= (blockoffset & MDMA_ADDRESS_MASK); + } else { + MDMA_CHXBTCFG(channelx) &= ~MDMA_CHXBTCFG_SADDRUM; + /* write new chxmbaddru register value: source repeat block offset */ + MDMA_CHXMBADDRU(channelx) |= (((uint32_t)block_init_struct->saddr_update_val) & MDMA_ADDRESS_MASK); + } + + if(UPDATE_DIR_DECREASE == block_init_struct->dstaddr_update_dir) { + MDMA_CHXBTCFG(channelx) |= MDMA_CHXBTCFG_DADDRUM; + /* write new chxmbaddru register value: destination repeat block offset */ + blockoffset = (uint32_t)block_init_struct->dstaddr_update_val; + MDMA_CHXMBADDRU(channelx) |= ((uint32_t)(blockoffset & MDMA_ADDRESS_MASK) << CHXMBADDRU_DADDRUV_OFFSET); + } else { + MDMA_CHXBTCFG(channelx) &= ~MDMA_CHXBTCFG_DADDRUM; + /* write new chxmbaddru register value: destination repeat block offset */ + MDMA_CHXMBADDRU(channelx) |= ((((uint32_t)block_init_struct->dstaddr_update_val) & MDMA_ADDRESS_MASK) << CHXMBADDRU_DADDRUV_OFFSET); + } +} + +/*! + \brief create MDMA link list node + \param[in] channelx: specify which MDMA channel is initialized + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] node: link node structure to create, members of the structure are shown as below: + chxcfg_reg: channel configure register + chxbtcfg_reg: channel block transfer configure register + chxsaddr_reg: channel source address register + chxdaddr_reg: channel destination address register + chxmbaddru_reg: channel multi-block address update register + chxladdr_reg: channel link address register + chxctl1_reg: channel control register 1 + chxmaddr_reg: channel mask address register + chxmdata_reg: channel mask data register + \param[in] block_init_struct: mdma muti block structure, members of the structure and the member values are shown as below: + block_num: multi-block number, ranges from 0x00000000 to 0x00000FFF + saddr_update_val: source address update value, ranges from 0x0000 to 0xFFFF + dstaddr_update_val: destination address update value, ranges from 0x0000 to 0xFFFF + saddr_update_dir: source address update direction, UPDATE_DIR_INCREASE, UPDATE_DIR_DECREASE + dstaddr_update_dir: destination address update direction, UPDATE_DIR_INCREASE, UPDATE_DIR_DECREASE + \param[in] init_struct: the data needed to initialize MDMA single data mode, + members of the structure and the member values are shown as below: + request: MDMA_REQUEST_x, x is the type of request + trans_trig_mode: MDMA_BUFFER_TRANSFER, MDMA_BLOCK_TRANSFER, MDMA_MULTI_BLOCK_TRANSFER, MDMA_COMPLETE_TRANSFER + priority: MDMA_PRIORITY_LOW, MDMA_PRIORITY_MEDIUM, MDMA_PRIORITY_HIGH, MDMA_PRIORITY_ULTRA_HIGH + endianness: MDMA_LITTLE_ENDIANNESS, MDMA_BYTE_ENDIANNESS_EXCHANGE, MDMA_HALFWORD_ENDIANNESS_EXCHANGE, MDMA_WORD_ENDIANNESS_EXCHANGE + source_inc: MDMA_SOURCE_INCREASE_DISABLE, MDMA_SOURCE_INCREASE_8BIT, MDMA_SOURCE_INCREASE_16BIT, MDMA_SOURCE_INCREASE_32BIT, MDMA_SOURCE_INCREASE_64BIT, + MDMA_SOURCE_DECREASE_8BIT, MDMA_SOURCE_DECREASE_16BIT, MDMA_SOURCE_DECREASE_32BIT, MDMA_SOURCE_DECREASE_64BIT + dest_inc: MDMA_DESTINATION_INCREASE_DISABLE, MDMA_DESTINATION_INCREASE_8BIT, MDMA_DESTINATION_INCREASE__16BIT, MDMA_DESTINATION_INCREASE_32BIT, MDMA_DESTINATION_INCREASE_64BIT, + MDMA_DESTINATION_DECREASE_8BIT, MDMA_DESTINATION_DECREASE_16BIT, MDMA_DESTINATION_DECREASE_32BIT, MDMA_DESTINATION_DECREASE_64BIT + source_data_size: MDMA_SOURCE_DATASIZE_8BIT, MDMA_SOURCE_DATASIZE_16BIT, MDMA_SOURCE_DATASIZE_32BIT, MDMA_SOURCE_DATASIZE_64BIT + dest_data_dize: MDMA_DESTINATION_DATASIZE_8BIT, MDMA_DESTINATION_DATASIZE_16BIT, MDMA_DESTINATION_DATASIZE_32BIT, MDMA_DESTINATION_DATASIZE_64BIT + data_alignment: MDMA_DATAALIGN_PKEN, MDMA_DATAALIGN_RIGHT, MDMA_DATAALIGN_RIGHT_SIGNED, MDMA_DATAALIGN_LEFT + buff_trans_len: the number of bytes to be transferred is (buff_trans_len+1), buff_trans_len ranges from 0 to 127 + source_burst: MDMA_SOURCE_BURST_SINGLE, MDMA_SOURCE_BURST_2BEATS, MDMA_SOURCE_BURST_4BEATS, MDMA_SOURCE_BURST_8BEATS, MDMA_SOURCE_BURST_16BEATS, + MDMA_SOURCE_BURST_32BEATS, MDMA_SOURCE_BURST_64BEATS, MDMA_SOURCE_BURST_128BEATS + dest_burst: MDMA_DESTINATION_BURST_SINGLE, MDMA_DESTINATION_BURST_2BEATS, MDMA_DESTINATION_BURST_4BEATS, MDMA_DESTINATION_BURST_8BEATS, MDMA_DESTINATION_BURST_16BEATS, + MDMA_DESTINATION_BURST_32BEATS, MDMA_DESTINATION_BURST_64BEATS, MDMA_DESTINATION_BURST_128BEATS + mask_addr: mask address, ranges from 0x00000000 to 0xFFFFFFFF + mask_data: mask data, ranges from 0x00000000 to 0xFFFFFFFF + source_addr: source address, ranges from 0x00000000 to 0xFFFFFFFF + destination_addr: destination address, ranges from 0x00000000 to 0xFFFFFFFF + tbytes_num_in_block: transfer byte number of a block transfer, ranges from 0x00000000 to 0x0001FFFF + source_bus: MDMA_SOURCE_AXI, MDMA_SOURCE_AHB_TCM + destination_bus: MDMA_DESTINATION_AXI, MDMA_DESTINATION_AHB_TCM + bufferable_write_mode: MDMA_BUFFERABLE_WRITE_ENABLE, MDMA_BUFFERABLE_WRITE_DISABLE + \retval none +*/ +void mdma_node_create(mdma_link_node_parameter_struct *node, mdma_multi_block_parameter_struct *block_init_struct, mdma_parameter_struct *init_struct) +{ + uint32_t cfg, blockoffset; + + /* configure channel configure register */ + cfg = (init_struct->data_alignment | init_struct->dest_burst | init_struct->dest_data_dize | init_struct->dest_inc | \ + init_struct->source_burst | init_struct->source_data_size | init_struct->source_inc | init_struct->trans_trig_mode | \ + ((init_struct->buff_trans_len << CHXCFG_BTLEN_OFFSET) & MDMA_CHXCFG_BTLEN) | init_struct->bufferable_write_mode); + node->chxcfg_reg = cfg; + + /* configure channel request source */ + if(MDMA_REQUEST_SW == init_struct->request) { + node->chxcfg_reg |= MDMA_CHXCFG_SWREQMOD; + } else { + node->chxctl1_reg &= ~MDMA_CHXCTL1_TRIGSEL; + node->chxctl1_reg |= init_struct->request; + } + /* configure bus type for source and destination */ + node->chxctl1_reg &= ~(MDMA_CHXCTL1_SBSEL | MDMA_CHXCTL1_DBSEL); + node->chxctl1_reg |= (init_struct->source_bus | init_struct->destination_bus); + + /* configure channel block transfer configure register */ + cfg = (((block_init_struct->block_num << CHXBTCFG_BRNUM_OFFSET) & MDMA_CHXBTCFG_BRNUM)| (init_struct->tbytes_num_in_block & MDMA_CHXBTCFG_TBNUM)); + node->chxbtcfg_reg = cfg; + + /* configure source address, destination adress, mask address and mask data */ + node->chxsaddr_reg = init_struct->source_addr; + node->chxdaddr_reg = init_struct->destination_addr; + node->chxmaddr_reg = init_struct->mask_addr; + node->chxmdata_reg = init_struct->mask_data; + + node->chxmbaddru_reg &= ~(MDMA_CHXMBADDRU_SADDRUV | MDMA_CHXMBADDRU_DADDRUV); + /* if block source address offset is negative, set the block repeat source address update mode to decrement */ + if(UPDATE_DIR_DECREASE == block_init_struct->saddr_update_val) { + node->chxbtcfg_reg |= MDMA_CHXBTCFG_SADDRUM; + /* write new chxmbaddru register value: source repeat block offset */ + blockoffset = (uint32_t)block_init_struct->saddr_update_val; + node->chxmbaddru_reg |= (blockoffset & MDMA_ADDRESS_MASK); + } else { + node->chxbtcfg_reg &= ~MDMA_CHXBTCFG_SADDRUM; + /* write new chxmbaddru register value: source repeat block offset */ + node->chxmbaddru_reg |= (((uint32_t)block_init_struct->saddr_update_val) & MDMA_ADDRESS_MASK); + } + + if(UPDATE_DIR_DECREASE == block_init_struct->dstaddr_update_dir) { + node->chxbtcfg_reg |= MDMA_CHXBTCFG_DADDRUM; + /* write new chxmbaddru register value: destination repeat block offset */ + blockoffset = (uint32_t)block_init_struct->dstaddr_update_val; + node->chxmbaddru_reg |= ((uint32_t)(blockoffset & MDMA_ADDRESS_MASK) << CHXMBADDRU_DADDRUV_OFFSET); + } else { + node->chxbtcfg_reg &= ~MDMA_CHXBTCFG_DADDRUM; + /* write new chxmbaddru register value: destination repeat block offset */ + node->chxmbaddru_reg |= ((((uint32_t)block_init_struct->dstaddr_update_val) & MDMA_ADDRESS_MASK) << CHXMBADDRU_DADDRUV_OFFSET); + } + + node->chxladdr_reg = 0U; + node->reserved = 0U; +} + +/*! + \brief MDMA add node to link list + \param[in] pre_node: previous structure node pointer, members of the structure and the member values are shown as below: + chxcfg_reg: channel configure register + chxbtcfg_reg: channel block transfer configure register + chxsaddr_reg: channel source address register + chxdaddr_reg: channel destination address register + chxmbaddru_reg: channel multi-block address update register + chxladdr_reg: channel link address register + chxctl1_reg: channel control register 1 + chxmaddr_reg: channel mask address register + chxmdata_reg: channel mask data register + \param[in] new_node: new node pointer, members of the structure and the member values are shown as below: + chxcfg_reg: channel configure register + chxbtcfg_reg: channel block transfer configure register + chxsaddr_reg: channel source address register + chxdaddr_reg: channel destination address register + chxmbaddru_reg: channel multi-block address update register + chxladdr_reg: channel link address register + chxctl1_reg: channel control register 1 + chxmaddr_reg: channel mask address register + chxmdata_reg: channel mask data register + \param[out] none + \retval none +*/ +void mdma_node_add(mdma_link_node_parameter_struct *pre_node, mdma_link_node_parameter_struct *new_node) +{ + pre_node->chxladdr_reg = (uint32_t)new_node; +} + +/*! + \brief MDMA disconnect link list node + \param[in] pre_node: previous structure node pointer, members of the structure and the member values are shown as below: + chxcfg_reg: channel configure register + chxbtcfg_reg: channel block transfer configure register + chxsaddr_reg: channel source address register + chxdaddr_reg: channel destination address register + chxmbaddru_reg: channel multi-block address update register + chxladdr_reg: channel link address register + chxctl1_reg: channel control register 1 + chxmaddr_reg: channel mask address register + chxmdata_reg: channel mask data register + \param[in] unused_node: unused link list node pointer, members of the structure and the member values are shown as below: + chxcfg_reg: channel configure register + chxbtcfg_reg: channel block transfer configure register + chxsaddr_reg: channel source address register + chxdaddr_reg: channel destination address register + chxmbaddru_reg: channel multi-block address update register + chxladdr_reg: channel link address register + chxctl1_reg: channel control register 1 + chxmaddr_reg: channel mask address register + chxmdata_reg: channel mask data register + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus mdma_node_delete(mdma_link_node_parameter_struct *pre_node, mdma_link_node_parameter_struct *unused_node) +{ + if(pre_node->chxladdr_reg != (uint32_t)unused_node) { + /* link address unmatched */ + return ERROR; + } else { + /* link address matched, disconnect the unused node from link list */ + pre_node->chxladdr_reg = 0U; + return SUCCESS; + } +} + +/*! + \brief configure MDMA destination base address + \param[in] channelx: specify which MDMA channel to set peripheral base address + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] address: destination base address, ranges from 0x00000000 to 0xFFFFFFFF + \param[out] none + \retval none +*/ +void mdma_destination_address_config(mdma_channel_enum channelx, uint32_t address) +{ + MDMA_CHXDADDR(channelx) = address; +} + +/*! + \brief configure MDMA source base address + \param[in] channelx: specify which MDMA channel to set Memory base address + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] address: source base address, ranges from 0x00000000 to 0xFFFFFFFF + \param[out] none + \retval none +*/ +void mdma_source_address_config(mdma_channel_enum channelx, uint32_t address) +{ + MDMA_CHXSADDR(channelx) = address; +} + +/*! + \brief configure MDMA destination bus + \param[in] channelx: specify which MDMA channel to set bus + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] bus: destination bus + \arg MDMA_DESTINATION_AXI: destination bus is the system bus or AXI bus + \arg MDMA_DESTINATION_AHB_TCM: destination bus is AHB bus or TCM + \param[out] none + \retval none +*/ +void mdma_destination_bus_config(mdma_channel_enum channelx, uint32_t bus) +{ + MDMA_CHXCTL1(channelx) &= ~MDMA_CHXCTL1_DBSEL; + MDMA_CHXCTL1(channelx) |= bus; +} + +/*! + \brief configure MDMA source bus + \param[in] channelx: specify which MDMA channel to set bus + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] bus: source bus + \arg MDMA_SOURCE_AXI: source bus is the system bus or AXI bus + \arg MDMA_SOURCE_AHB_TCM: source bus is AHB bus or TCM + \param[out] none + \retval none +*/ +void mdma_source_bus_config(mdma_channel_enum channelx, uint32_t bus) +{ + MDMA_CHXCTL1(channelx) &= ~MDMA_CHXCTL1_SBSEL; + MDMA_CHXCTL1(channelx) |= bus; +} + +/*! + \brief configure priority level of MDMA channel + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] priority: priority level of this channel + only one parameter can be selected which is shown as below: + \arg MDMA_PRIORITY_LOW: low priority + \arg MDMA_PRIORITY_MEDIUM: medium priority + \arg MDMA_PRIORITY_HIGH: high priority + \arg MDMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void mdma_priority_config(mdma_channel_enum channelx, uint32_t priority) +{ + /* configure priority level */ + MDMA_CHXCTL0(channelx) &= ~MDMA_CHXCTL0_PRIO; + MDMA_CHXCTL0(channelx) |= priority; +} + +/*! + \brief configure endianness of MDMA channel + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] endianness: MDMA endianness + only one parameter can be selected which is shown as below: + \arg MDMA_LITTLE_ENDIANNESS: little endianness preserve + \arg MDMA_BYTE_ENDIANNESS_EXCHANGE: exchange the order of the bytes in a half-word + \arg MDMA_HALFWORD_ENDIANNESS_EXCHANGE: exchange the order of the half-words in a word + \arg MDMA_WORD_ENDIANNESS_EXCHANGE: exchange the order of the words in a double word + \param[out] none + \retval none +*/ +void mdma_endianness_config(mdma_channel_enum channelx, uint32_t endianness) +{ + /* configure MDMA endianness */ + MDMA_CHXCTL0(channelx) &= ~(MDMA_CHXCTL0_BES | MDMA_CHXCTL0_HWES | MDMA_CHXCTL0_WES); + MDMA_CHXCTL0(channelx) |= endianness; +} + +/*! + \brief configure data alignment of MDMA channel + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] alignment: MDMA data alignment + only one parameter can be selected which is shown as below: + \arg MDMA_DATAALIGN_PKEN: pack/unpack the source data to match the destination data size + \arg MDMA_DATAALIGN_RIGHT: right aligned, padded with 0s (default) + \arg MDMA_DATAALIGN_RIGHT_SIGNED: right aligned with sign extended, note: this mode is allowed only if the source data size is smaller than destination data size + \arg MDMA_DATAALIGN_LEFT: left aligned, padded with 0s in low bytes position when source data size smaller than destination data size, and only high byte of source is written when source data size larger than destination data size + \param[out] none + \retval none +*/ +void mdma_alignment_config(mdma_channel_enum channelx, uint32_t alignment) +{ + /* configure MDMA endianness */ + MDMA_CHXCFG(channelx) &= ~(MDMA_CHXCFG_PKEN | MDMA_CHXCFG_PAMOD); + MDMA_CHXCFG(channelx) |= alignment; +} + +/*! + \brief configure transfer burst beats of source + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] sbeat: source transfer burst beats + \arg MDMA_SOURCE_BURST_SINGLE: source transfer single burst + \arg MDMA_SOURCE_BURST_2BEATS: source transfer 2-beat burst + \arg MDMA_SOURCE_BURST_4BEATS: source transfer 4-beat burst + \arg MDMA_SOURCE_BURST_8BEATS: source transfer 8-beat burst + \arg MDMA_SOURCE_BURST_16BEATS: source transfer 16-beat burst + \arg MDMA_SOURCE_BURST_32BEATS: source transfer 32-beat burst + \arg MDMA_SOURCE_BURST_64BEATS: source transfer 64-beat burst + \arg MDMA_SOURCE_BURST_128BEATS: source transfer 128-beat burst + \param[out] none + \retval none +*/ +void mdma_source_burst_beats_config(mdma_channel_enum channelx, uint32_t sbeat) +{ + /* configure transfer burst beats of source */ + MDMA_CHXCFG(channelx) &= ~MDMA_CHXCFG_SBURST; + MDMA_CHXCFG(channelx) |= sbeat; +} + +/*! + \brief configure transfer burst beats of destination + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] dbeat: destination transfer burst beats + only one parameter can be selected which is shown as below: + \arg MDMA_DESTINATION_BURST_SINGLE: destination transfer single burst + \arg MDMA_DESTINATION_BURST_2BEATS: destination transfer 2-beat burst + \arg MDMA_DESTINATION_BURST_4BEATS: destination transfer 4-beat burst + \arg MDMA_DESTINATION_BURST_8BEATS: destination transfer 8-beat burst + \arg MDMA_DESTINATION_BURST_16BEATS: destination transfer 16-beat burst + \arg MDMA_DESTINATION_BURST_32BEATS: destination transfer 32-beat burst + \arg MDMA_DESTINATION_BURST_64BEATS: destination transfer 64-beat burst + \arg MDMA_DESTINATION_BURST_128BEATS: destination transfer 128-beat burst + \param[out] none + \retval none +*/ +void mdma_destination_burst_beats_config(mdma_channel_enum channelx, uint32_t dbeat) +{ + /* configure transfer burst beats of destination */ + MDMA_CHXCFG(channelx) &= ~MDMA_CHXCFG_DBURST; + MDMA_CHXCFG(channelx) |= dbeat; +} + +/*! + \brief configure data size of source + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] swidth: source data size + only one parameter can be selected which is shown as below: + \arg MDMA_SOURCE_DATASIZE_8BIT: source data size is byte + \arg MDMA_SOURCE_DATASIZE_16BIT: source data size is half word + \arg MDMA_SOURCE_DATASIZE_32BIT: source data size is word + \arg MDMA_SOURCE_DATASIZE_64BIT: source data size is double word + \param[out] none + \retval none +*/ +void mdma_source_width_config(mdma_channel_enum channelx, uint32_t swidth) +{ + /* configure data size of source */ + MDMA_CHXCFG(channelx) &= ~MDMA_CHXCFG_SWIDTH; + MDMA_CHXCFG(channelx) |= swidth; +} + +/*! + \brief configure data size of destination + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] dwidth: destination data size + only one parameter can be selected which is shown as below: + \arg MDMA_DESTINATION_DATASIZE_8BIT: destination data size is byte + \arg MDMA_DESTINATION_DATASIZE_16BIT: destination data size is half word + \arg MDMA_DESTINATION_DATASIZE_32BIT: destination data size is word + \arg MDMA_DESTINATION_DATASIZE_64BIT: destination data size is double word + \param[out] none + \retval none +*/ +void mdma_destination_width_config(mdma_channel_enum channelx, uint32_t dwidth) +{ + /* configure data size of source */ + MDMA_CHXCFG(channelx) &= ~MDMA_CHXCFG_DWIDTH; + MDMA_CHXCFG(channelx) |= dwidth; +} + +/*! + \brief configure source adress increment mode + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] sinc: source adress increment mode + only one parameter can be selected which is shown as below: + \arg MDMA_SOURCE_INCREASE_DISABLE: no increment + \arg MDMA_SOURCE_INCREASE_8BIT: source address pointer is incremented by a byte (8 bits) + \arg MDMA_SOURCE_INCREASE_16BIT: source address pointer is incremented by a half word (16 bits) + \arg MDMA_SOURCE_INCREASE_32BIT: source address pointer is incremented by a word (32 bits) + \arg MDMA_SOURCE_INCREASE_64BIT: source address pointer is incremented by a double word (64 bits) + \arg MDMA_SOURCE_DECREASE_8BIT: source address pointer is decremented by a byte (8 bits) + \arg MDMA_SOURCE_DECREASE_16BIT: source address pointer is decremented by a half word (16 bits) + \arg MDMA_SOURCE_DECREASE_32BIT: source address pointer is decremented by a word (32 bits) + \arg MDMA_SOURCE_DECREASE_64BIT: source address pointer is decremented by a double word (64 bits) + \param[out] none + \retval none +*/ +void mdma_source_increment_config(mdma_channel_enum channelx, uint32_t sinc) +{ + /* configure adress increment mode of source */ + MDMA_CHXCFG(channelx) &= ~(MDMA_CHXCFG_SIMOD | MDMA_CHXCFG_SIOS); + MDMA_CHXCFG(channelx) |= sinc; +} + +/*! + \brief configure destination adress increment mode + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] dinc: destination adress increment mode + only one parameter can be selected which is shown as below: + \arg MDMA_DESTINATION_INCREASE_DISABLE: no increment + \arg MDMA_DESTINATION_INCREASE_8BIT: destination address pointer is incremented by a byte (8 bits) + \arg MDMA_DESTINATION_INCREASE_16BIT: destination address pointer is incremented by a half word (16 bits) + \arg MDMA_DESTINATION_INCREASE_32BIT: destination address pointer is incremented by a word (32 bits) + \arg MDMA_DESTINATION_INCREASE_64BIT: destination address pointer is incremented by a double word (64 bits)) + \arg MDMA_DESTINATION_DECREASE_8BIT: destination address pointer is decremented by a byte (8 bits) + \arg MDMA_DESTINATION_DECREASE_16BIT: destination address pointer is decremented by a half word (16 bits) + \arg MDMA_DESTINATION_DECREASE_32BIT: destination address pointer is decremented by a word (32 bits) + \arg MDMA_DESTINATION_DECREASE_64BIT: destination address pointer is decremented by a double word (64 bits) + \param[out] none + \retval none +*/ +void mdma_destination_increment_config(mdma_channel_enum channelx, uint32_t dinc) +{ + /* configure adress increment mode of destination */ + MDMA_CHXCFG(channelx) &= ~(MDMA_CHXCFG_DIMOD | MDMA_CHXCFG_DIOS); + MDMA_CHXCFG(channelx) |= dinc; +} + +/*! + \brief enable MDMA channel bufferable write mode + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval none +*/ +void mdma_channel_bufferable_write_enable(mdma_channel_enum channelx) +{ + MDMA_CHXCFG(channelx) |= MDMA_CHXCFG_BWMOD; +} + +/*! + \brief disable MDMA channel bufferable write mode + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval none +*/ +void mdma_channel_bufferable_write_disable(mdma_channel_enum channelx) +{ + MDMA_CHXCFG(channelx) &= ~MDMA_CHXCFG_BWMOD; +} + +/*! + \brief enable MDMA channel software request + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval none +*/ +void mdma_channel_software_request_enable(mdma_channel_enum channelx) +{ + MDMA_CHXCTL0(channelx) |= MDMA_CHXCTL0_SWREQ; +} + +/*! + \brief enable MDMA channel + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval none +*/ +void mdma_channel_enable(mdma_channel_enum channelx) +{ + MDMA_CHXCTL0(channelx) |= MDMA_CHXCTL0_CHEN; +} + +/*! + \brief disable MDMA channel + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval none +*/ +void mdma_channel_disable(mdma_channel_enum channelx) +{ + MDMA_CHXCTL0(channelx) &= ~MDMA_CHXCTL0_CHEN; +} + +/*! + \brief get MDMA transfer error direction + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval transfer error direction: MDMA_READ_ERROR or MDMA_WRITE_ERROR +*/ +uint32_t mdma_transfer_error_direction_get(mdma_channel_enum channelx) +{ + return (MDMA_CHXSTAT1(channelx) & MDMA_CHXSTAT1_TERRD); +} + +/*! + \brief get MDMA transfer error address + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[out] none + \retval the low 7 bits of the transfer error address +*/ +uint32_t mdma_transfer_error_address_get(mdma_channel_enum channelx) +{ + return (uint32_t)(MDMA_CHXSTAT1(channelx) & MDMA_CHXSTAT1_ERRADDR); +} + +/*! + \brief get MDMA flag + \param[in] channelx: specify which MDMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg MDMA_FLAG_ERR: transfer error flag + \arg MDMA_FLAG_CHTCF: channel transfer complete flag + \arg MDMA_FLAG_MBTCF: multi-block transfer complete flag + \arg MDMA_FLAG_BTCF: block transfer complete flag + \arg MDMA_FLAG_TCF: buffer transfer complete flag + \arg MDMA_FLAG_REQAF: request active flag + \arg MDMA_FLAG_LDTERR: link data transfer error flag in the last transfer of the channel + \arg MDMA_FLAG_MDTERR: mask data error flag + \arg MDMA_FLAG_ASERR: address and size error flag + \arg MDMA_FLAG_BZERR: block size error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mdma_flag_get(mdma_channel_enum channelx, uint32_t flag) +{ + uint32_t flag_pos = 0U; + + if(STAT1_FLAG & flag) { + /* get the flag in CHXSTAT1 */ + flag_pos = (flag & STAT1_FLAG_MASK); + if(MDMA_CHXSTAT1(channelx) & flag_pos) { + return SET; + } else { + return RESET; + } + } else { + /* get the flag in CHXSTAT0 */ + if(MDMA_CHXSTAT0(channelx) & flag) { + return SET; + } else { + return RESET; + } + } +} + +/*! + \brief clear MDMA flag + \param[in] channelx: specify which MDMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] flag: specify clear which flag + only one parameter can be selected which is shown as below: + \arg MDMA_FLAG_ERR: transfer error flag + \arg MDMA_FLAG_CHTCF: channel transfer complete flag + \arg MDMA_FLAG_MBTCF: multi-block transfer complete flag + \arg MDMA_FLAG_BTCF: block transfer complete flag + \arg MDMA_FLAG_TCF: buffer transfer complete flag + \arg MDMA_FLAG_LDTERR: link data transfer error flag in the last transfer of the channel + \arg MDMA_FLAG_MDTERR: mask data error flag + \arg MDMA_FLAG_ASERR: address and size error flag + \arg MDMA_FLAG_BZERR: block size error flag + \param[out] none + \retval none +*/ +void mdma_flag_clear(mdma_channel_enum channelx, uint32_t flag) +{ + if(STAT1_FLAG & flag) { + MDMA_CHXSTATC(channelx) |= MDMA_CHXSTATC_ERRC; + } else { + MDMA_CHXSTATC(channelx) |= flag; + } +} + +/*! + \brief enable MDMA interrupt + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] interrupt: specify which interrupt to enbale + one or more parameters can be selected which are shown as below: + \arg MDMA_INT_ERR: transfer error interrupt + \arg MDMA_INT_CHTC: channel transfer complete interrupt + \arg MDMA_INT_MBTC: multi-block transfer complete interrupt + \arg MDMA_INT_BTC: block transfer complete interrupt + \arg MDMA_INT_TC: buffer transfer complete interrupt + \param[out] none + \retval none +*/ +void mdma_interrupt_enable(mdma_channel_enum channelx, uint32_t interrupt) +{ + MDMA_CHXCTL0(channelx) |= interrupt; +} + +/*! + \brief disable MDMA interrupt + \param[in] channelx: specify which MDMA channel + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] interrupt: specify which interrupt to disbale + one or more parameters can be selected which are shown as below: + \arg MDMA_INT_ERR: transfer error interrupt + \arg MDMA_INT_CHTC: channel transfer complete interrupt + \arg MDMA_INT_MBTC: multi-block transfer complete interrupt + \arg MDMA_INT_BTC: block transfer complete interrupt + \arg MDMA_INT_TC: buffer transfer complete interrupt + \param[out] none + \retval none +*/ +void mdma_interrupt_disable(mdma_channel_enum channelx, uint32_t interrupt) +{ + MDMA_CHXCTL0(channelx) &= ~interrupt; +} + +/*! + \brief get MDMA interrupt flag + \param[in] channelx: specify which MDMA channel to get flag + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] int_flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg MDMA_INT_FLAG_ERR: transfer error interrupt flag + \arg MDMA_INT_FLAG_CHTCF: channel transfer complete interrupt flag + \arg MDMA_INT_FLAG_MBTCF: multi-block transfer complete interrupt flag + \arg MDMA_INT_FLAG_BTCF: block transfer complete interrupt flag + \arg MDMA_INT_FLAG_TCF: buffer transfer complete interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mdma_interrupt_flag_get(mdma_channel_enum channelx, uint32_t int_flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + switch(int_flag) { + case MDMA_INT_FLAG_ERR: + /* get error interrupt enable bit and flag bit */ + interrupt_enable = (MDMA_CHXCTL0(channelx) & MDMA_CHXCTL0_ERRIE); + interrupt_flag = (MDMA_CHXSTAT0(channelx) & int_flag); + break; + case MDMA_INT_FLAG_CHTCF: + /* get channel transfer complete interrupt enable bit and flag bit */ + interrupt_enable = (MDMA_CHXCTL0(channelx) & MDMA_CHXCTL0_CHTCIE); + interrupt_flag = (MDMA_CHXSTAT0(channelx) & int_flag); + break; + case MDMA_INT_FLAG_MBTCF: + /* get multi-block transfer complete interrupt enable bit and flag bit */ + interrupt_enable = (MDMA_CHXCTL0(channelx) & MDMA_CHXCTL0_MBTCIE); + interrupt_flag = (MDMA_CHXSTAT0(channelx) & int_flag); + break; + case MDMA_INT_FLAG_BTCF: + /* get block transfer complete interrupt enable bit and flag bit */ + interrupt_enable = (MDMA_CHXCTL0(channelx) & MDMA_CHXCTL0_BTCIE); + interrupt_flag = (MDMA_CHXSTAT0(channelx) & int_flag); + break; + case MDMA_INT_FLAG_TCF: + /* get buffer transfer complete interrupt enable bit and flag bit */ + interrupt_enable = (MDMA_CHXCTL0(channelx) & MDMA_CHXCTL0_TCIE); + interrupt_flag = (MDMA_CHXSTAT0(channelx) & int_flag); + break; + default: + break; + } + + if(interrupt_flag && interrupt_enable) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear MDMA interrupt flag + \param[in] channelx: specify which MDMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg MDMA_CHx(x=0..15) + \param[in] int_flag: specify clear which flag + only one parameter can be selected which is shown as below: + \arg MDMA_INT_FLAG_ERR: transfer error interrupt flag + \arg MDMA_INT_FLAG_CHTCF: channel transfer complete interrupt flag + \arg MDMA_INT_FLAG_MBTCF: multi-block transfer complete interrupt flag + \arg MDMA_INT_FLAG_BTCF: block transfer complete interrupt flag + \arg MDMA_INT_FLAG_TCF: buffer transfer complete interrupt flag + \param[out] none + \retval none +*/ +void mdma_interrupt_flag_clear(mdma_channel_enum channelx, uint32_t int_flag) +{ + MDMA_CHXSTATC(channelx) |= int_flag; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_misc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_misc.c new file mode 100644 index 0000000000..5075ef1da2 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_misc.c @@ -0,0 +1,257 @@ +/*! + \file gd32h7xx_misc.c + \brief MISC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_misc.h" + +/*! + \brief set the priority group + \param[in] nvic_prigroup: the NVIC priority group + \arg NVIC_PRIGROUP_PRE0_SUB4: 0 bits for pre-emption priority, 4 bits for subpriority + \arg NVIC_PRIGROUP_PRE1_SUB3: 1 bits for pre-emption priority, 3 bits for subpriority + \arg NVIC_PRIGROUP_PRE2_SUB2: 2 bits for pre-emption priority, 2 bits for subpriority + \arg NVIC_PRIGROUP_PRE3_SUB1: 3 bits for pre-emption priority, 1 bits for subpriority + \arg NVIC_PRIGROUP_PRE4_SUB0: 4 bits for pre-emption priority, 0 bits for subpriority + \param[out] none + \retval none +*/ +void nvic_priority_group_set(uint32_t nvic_prigroup) +{ + /* set the priority group value */ + SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup; +} + +/*! + \brief enable NVIC interrupt request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[in] nvic_irq_pre_priority: the pre-emption priority needed to set + \param[in] nvic_irq_sub_priority: the subpriority needed to set + \param[out] none + \retval none +*/ +void nvic_irq_enable(uint8_t nvic_irq, + uint8_t nvic_irq_pre_priority, + uint8_t nvic_irq_sub_priority) +{ + uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U; + + /* use the priority group value to get the temp_pre and the temp_sub */ + switch((SCB->AIRCR) & (uint32_t)0x700U) { + case NVIC_PRIGROUP_PRE0_SUB4: + temp_pre = 0U; + temp_sub = 0x4U; + break; + case NVIC_PRIGROUP_PRE1_SUB3: + temp_pre = 1U; + temp_sub = 0x3U; + break; + case NVIC_PRIGROUP_PRE2_SUB2: + temp_pre = 2U; + temp_sub = 0x2U; + break; + case NVIC_PRIGROUP_PRE3_SUB1: + temp_pre = 3U; + temp_sub = 0x1U; + break; + case NVIC_PRIGROUP_PRE4_SUB0: + temp_pre = 4U; + temp_sub = 0x0U; + break; + default: + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + temp_pre = 2U; + temp_sub = 0x2U; + break; + } + + /* get the temp_priority to fill the NVIC->IP register */ + temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre); + temp_priority |= nvic_irq_sub_priority & (0x0FU >> (0x4U - temp_sub)); + temp_priority = temp_priority << 0x04U; + NVIC->IP[nvic_irq] = (uint8_t)temp_priority; + + /* enable the selected IRQ */ + NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU); +} + +/*! + \brief disable NVIC interrupt request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(uint8_t nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC->ICER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU); + __DSB(); + __ISB(); +} + +/*! + \brief set the NVIC vector table base address + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \arg NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: vector table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); + __DSB(); +} + +/*! + \brief set the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the low power mode can be woke up + by all the enable and disable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_set(uint8_t lowpower_mode) +{ + SCB->SCR |= (uint32_t)lowpower_mode; +} + +/*! + \brief reset the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the low power mode only can be + woke up by the enable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_reset(uint8_t lowpower_mode) +{ + SCB->SCR &= (~(uint32_t)lowpower_mode); +} + +/*! + \brief set the systick clock source + \param[in] systick_clksource: the systick clock source needed to choose + \arg SYSTICK_CLKSOURCE_CKSYS: systick clock source is from CK_SYS + \arg SYSTICK_CLKSOURCE_CKSYS_DIV2: systick clock source is from CK_SYS/2 + \param[out] none + \retval none +*/ +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_CKSYS == systick_clksource) { + /* set the systick clock source from CK_SYS */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_CKSYS; + } else { + /* set the systick clock source from CK_SYS/2 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_CKSYS_DIV2; + } +} + +#if (__MPU_PRESENT == 1) + +/*! + \brief initialize mpu_region_init_struct with the default values + \param[in] mpu_init_struct: pointer to a mpu_region_init_struct structure + \param[out] none + \retval none +*/ +void mpu_region_struct_para_init(mpu_region_init_struct *mpu_init_struct) +{ + mpu_init_struct->region_number = MPU_REGION_NUMBER0; + mpu_init_struct->region_base_address = 0x00000000U; + mpu_init_struct->instruction_exec = MPU_INSTRUCTION_EXEC_PERMIT; + mpu_init_struct->access_permission = MPU_AP_NO_ACCESS; + mpu_init_struct->tex_type = MPU_TEX_TYPE0; + mpu_init_struct->access_shareable = MPU_ACCESS_SHAREABLE; + mpu_init_struct->access_cacheable = MPU_ACCESS_CACHEABLE; + mpu_init_struct->access_bufferable = MPU_ACCESS_BUFFERABLE; + mpu_init_struct->subregion_disable = MPU_SUBREGION_ENABLE; + mpu_init_struct->region_size = MPU_REGION_SIZE_32B; +} + +/*! + \brief configure the MPU region + \param[in] mpu_init_struct: MPU initialization structure + region_number: region number + MPU_REGION_NUMBERn (n=0,..,15) + region_base_address: region base address + region_size: MPU_REGION_SIZE_32B, MPU_REGION_SIZE_64B, MPU_REGION_SIZE_128B, MPU_REGION_SIZE_256B, MPU_REGION_SIZE_512B, + MPU_REGION_SIZE_1KB, MPU_REGION_SIZE_2KB, MPU_REGION_SIZE_4KB, MPU_REGION_SIZE_8KB, MPU_REGION_SIZE_16KB, + MPU_REGION_SIZE_32KB, MPU_REGION_SIZE_64KB, MPU_REGION_SIZE_128KB, MPU_REGION_SIZE_256KB, MPU_REGION_SIZE_512KB, + MPU_REGION_SIZE_1MB, MPU_REGION_SIZE_2MB, MPU_REGION_SIZE_4MB, MPU_REGION_SIZE_8MB, MPU_REGION_SIZE_16MB, + MPU_REGION_SIZE_32MB, MPU_REGION_SIZE_64MB, MPU_REGION_SIZE_128MB, MPU_REGION_SIZE_256MB, MPU_REGION_SIZE_512MB, + MPU_REGION_SIZE_1GB, MPU_REGION_SIZE_2GB, MPU_REGION_SIZE_4GB + subregion_disable: MPU_SUBREGION_ENABLE, MPU_SUBREGION_DISABLE + tex_type: MPU_TEX_TYPE0, MPU_TEX_TYPE1, MPU_TEX_TYPE2 + access_permission: MPU_AP_NO_ACCESS, MPU_AP_PRIV_RW, MPU_AP_PRIV_RW_UNPRIV_RO, MPU_AP_FULL_ACCESS, MPU_AP_PRIV_RO, + MPU_AP_PRIV_UNPRIV_RO + access_shareable: MPU_ACCESS_SHAREABLE, MPU_ACCESS_NON_SHAREABLE + access_cacheable: MPU_ACCESS_CACHEABLE, MPU_ACCESS_NON_CACHEABLE + access_bufferable: MPU_ACCESS_BUFFERABLE, MPU_ACCESS_NON_BUFFERABLE + instruction_exec: MPU_INSTRUCTION_EXEC_PERMIT, MPU_INSTRUCTION_EXEC_NOT_PERMIT + \param[out] none + \retval none +*/ +void mpu_region_config(mpu_region_init_struct *mpu_init_struct) +{ + MPU->RNR = mpu_init_struct->region_number; + MPU->RBAR = mpu_init_struct->region_base_address; + MPU->RASR = ((uint32_t)mpu_init_struct->instruction_exec << MPU_RASR_XN_Pos) | + ((uint32_t)mpu_init_struct->access_permission << MPU_RASR_AP_Pos) | + ((uint32_t)mpu_init_struct->tex_type << MPU_RASR_TEX_Pos)| + ((uint32_t)mpu_init_struct->access_shareable << MPU_RASR_S_Pos) | + ((uint32_t)mpu_init_struct->access_cacheable << MPU_RASR_C_Pos) | + ((uint32_t)mpu_init_struct->access_bufferable << MPU_RASR_B_Pos) | + ((uint32_t)mpu_init_struct->subregion_disable << MPU_RASR_SRD_Pos)| + ((uint32_t)mpu_init_struct->region_size << MPU_RASR_SIZE_Pos); +} + +/*! + \brief enable the MPU region + \param[in] none + \param[out] none + \retval none +*/ +void mpu_region_enable(void) +{ + MPU->RASR |= MPU_RASR_ENABLE_Msk; +} + +#endif /* __MPU_PRESENT */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospi.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospi.c new file mode 100644 index 0000000000..d1fbcbb337 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospi.c @@ -0,0 +1,1641 @@ +/*! + \file gd32h7xx_ospi.c + \brief OSPI driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_ospi.h" + +static void ospi_config(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct, ospi_regular_cmd_struct* cmd_struct); + +/*! + \brief reset the OSPI peripheral + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] none + \retval none +*/ +void ospi_deinit(uint32_t ospi_periph) +{ + switch(ospi_periph){ + case OSPI0: + /* reset OSPI0 */ + rcu_periph_reset_enable(RCU_OSPI0RST); + rcu_periph_reset_disable(RCU_OSPI0RST); + break; + case OSPI1: + /* reset OSPI1 */ + rcu_periph_reset_enable(RCU_OSPI1RST); + rcu_periph_reset_disable(RCU_OSPI1RST); + break; + default: + break; + } +} + +/*! + \brief initialize the parameters of OSPI struct with default values + \param[in] none + \param[out] ospi_struct: the initialized struct ospi_parameter_struct pointer + \retval none +*/ +void ospi_struct_init(ospi_parameter_struct *ospi_struct) +{ + /* configure the structure with default value */ + ospi_struct->prescaler = 2U; + ospi_struct->sample_shift = OSPI_SAMPLE_SHIFTING_NONE; + ospi_struct->fifo_threshold = OSPI_FIFO_THRESHOLD_4; + ospi_struct->device_size = OSPI_MESZ_512_MBS; + ospi_struct->wrap_size = OSPI_DIRECT; + ospi_struct->cs_hightime = OSPI_CS_HIGH_TIME_3_CYCLE; + ospi_struct->memory_type = OSPI_MICRON_MODE; + ospi_struct->delay_hold_cycle = OSPI_DELAY_HOLD_NONE; +} + +/*! + \brief initialize OSPI parameter + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] ospi_struct: OSPI parameter initialization stuct members of the structure + and the member values are shown as below: + prescaler: between 0 and 255 + fifo_threshold: OSPI_FIFO_THRESHOLD_x (x = 1, 2, ..., 31, 32) + sample_shift: OSPI_SAMPLE_SHIFTING_NONE, OSPI_SAMPLE_SHIFTING_HALF_CYCLE + device_size: OSPI_MESZ_x_BYTES (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_KBS (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_MBS (x = 2, 4, 8, ..., 2048, 4096) + cs_hightime: OSPI_CS_HIGH_TIME_x_CYCLE (x = 1, 2, ..., 63, 64) + memory_type: OSPI_MICRON_MODE, OSPI_MACRONIX_MODE, OSPI_STANDARD_MODE + OSPI_MACRONIX_RAM_MODE, + wrap_size: OSPI_DIRECT, OSPI_WRAP_16BYTES, OSPI_WRAP_32BYTES + OSPI_WRAP_64BYTES, OSPI_WRAP_128BYTES + delay_hold_cycle: OSPI_DELAY_HOLD_NONE, OSPI_DELAY_HOLD_QUARTER_CYCLE + \retval none +*/ +void ospi_init(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct) +{ + uint32_t reg = 0U; + + /* configure memory type, device size, chip select high time, delay block bypass, free running clock, clock mode */ + reg = OSPI_DCFG0(ospi_periph); + + reg &= ~(OSPI_DCFG0_DTYSEL | OSPI_DCFG0_MESZ | OSPI_DCFG0_CSHC); + + reg |= (ospi_struct->memory_type | ospi_struct->device_size | ospi_struct->cs_hightime); + + OSPI_DCFG0(ospi_periph) = reg; + + /* configure wrap size */ + OSPI_DCFG1(ospi_periph) = (OSPI_DCFG1(ospi_periph) & ~OSPI_DCFG1_WPSZ) | ospi_struct->wrap_size; + + /* configure FIFO threshold */ + OSPI_CTL(ospi_periph) = (OSPI_CTL(ospi_periph) & ~OSPI_CTL_FTL) | ospi_struct->fifo_threshold; + + /* wait till BUSY flag reset */ + while(RESET != (OSPI_STAT(ospi_periph) & OSPI_FLAG_BUSY)){ + } + + /* configure clock prescaler */ + OSPI_DCFG1(ospi_periph) = (OSPI_DCFG1(ospi_periph) & ~OSPI_DCFG1_PSC) | OSPI_PSC(ospi_struct->prescaler); + + /* configure sample shifting and delay hold quarter cycle */ + OSPI_TIMCFG(ospi_periph) = (OSPI_TIMCFG(ospi_periph) & ~(OSPI_TIMCFG_SSAMPLE | OSPI_TIMCFG_DEHQC)) | (ospi_struct->sample_shift | ospi_struct->delay_hold_cycle); +} + +/*! + \brief enable OSPI + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] none + \retval none +*/ +void ospi_enable(uint32_t ospi_periph) +{ + OSPI_CTL(ospi_periph) |= (uint32_t)OSPI_CTL_OSPIEN; +} + +/*! + \brief disable OSPI + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] none + \retval none +*/ +void ospi_disable(uint32_t ospi_periph) +{ + OSPI_CTL(ospi_periph) &= (uint32_t)(~OSPI_CTL_OSPIEN); +} + +/*! + \brief configure device memory type + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dtysel: OSPI device type select + only one parameter can be selected which is shown as below: + \arg OSPI_MICRON_MODE: micron mode + \arg OSPI_MACRONIX_MODE: micronix mode + \arg OSPI_STANDARD_MODE: standard mode + \arg OSPI_MACRONIX_RAM_MODE: micronix ram mode + \param[out] none + \retval none +*/ +void ospi_device_memory_type_config(uint32_t ospi_periph, uint32_t dtysel) +{ + OSPI_DCFG0(ospi_periph) &= (uint32_t)(~OSPI_RESERVE_MODE); + OSPI_DCFG0(ospi_periph) |= (uint32_t)dtysel; +} + +/*! + \brief configure device memory size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] mesz: device memory size + only one parameter can be selected which is shown as below: + OSPI_MESZ_x_BYTES (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_KBS (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_MBS (x = 2, 4, 8, ..., 2048, 4096) + \param[out] none + \retval none +*/ +void ospi_device_memory_size_config(uint32_t ospi_periph, uint32_t mesz) +{ + OSPI_DCFG0(ospi_periph) &= (uint32_t)(~OSPI_DCFG0_MESZ); + OSPI_DCFG0(ospi_periph) |= (uint32_t)mesz; +} + +/*! + \brief select functional mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] fmod: OSPI functional mode + only one parameter can be selected which is shown as below: + \arg OSPI_INDIRECT_WRITE: OSPI indirect write mode + \arg OSPI_INDIRECT_READ: OSPI indirect read mode + \arg OSPI_STATUS_POLLING: OSPI status polling mode + \arg OSPI_MEMORY_MAPPED: OSPI memory mapped mode + \param[out] none + \retval none +*/ +void ospi_functional_mode_config(uint32_t ospi_periph, uint32_t fmod) +{ + OSPI_CTL(ospi_periph) &= (uint32_t)(~OSPI_CTL_FMOD); + OSPI_CTL(ospi_periph) |= (uint32_t)fmod; +} + +/*! + \brief configure status polling mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] stop: OSPI automatic stop + \arg OSPI_AUTOMATIC_STOP_MATCH: status polling mode stop in match + \param[in] mode: OSPI match mode + only one parameter can be selected which is shown as below: + \arg OSPI_MATCH_MODE_AND: status polling match mode and + \arg OSPI_MATCH_MODE_OR: status polling match mode or + \param[out] none + \retval none +*/ +void ospi_status_polling_config(uint32_t ospi_periph, uint32_t stop, uint32_t mode) +{ + OSPI_CTL(ospi_periph) &= (uint32_t)(~(OSPI_CTL_SPS | OSPI_CTL_SPMOD)); + OSPI_CTL(ospi_periph) |= (uint32_t)(stop | mode); +} + +/*! + \brief configure status mask + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] mask: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_status_mask_config(uint32_t ospi_periph, uint32_t mask) +{ + OSPI_STATMK(ospi_periph) &= (uint32_t)(~OSPI_STATMK_MASK); + OSPI_STATMK(ospi_periph) |= (uint32_t)mask; +} + +/*! + \brief configure status match + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] match: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_status_match_config(uint32_t ospi_periph, uint32_t match) +{ + OSPI_STATMATCH(ospi_periph) &= (uint32_t)(~OSPI_STATMATCH_MATCH); + OSPI_STATMATCH(ospi_periph) |= (uint32_t)match; +} + +/*! + \brief configure interval cycle + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] interval: between 0 and 0xFFFF + \param[out] none + \retval none +*/ +void ospi_interval_cycle_config(uint32_t ospi_periph, uint16_t interval) +{ + OSPI_INTERVAL(ospi_periph) &= (uint32_t)(~OSPI_INTERVAL_INTERVAL); + OSPI_INTERVAL(ospi_periph) |= (uint32_t)interval; +} + +/*! + \brief configure OSPI fifo threshold level + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] ftl: FIFO threshold level + only one parameter can be selected which is shown as below: + OSPI_FIFO_THRESHOLD_x (x = 1, 2, ..., 31, 32) + \param[out] none + \retval none +*/ +void ospi_fifo_level_config(uint32_t ospi_periph, uint32_t ftl) +{ + OSPI_CTL(ospi_periph) &= (uint32_t)(~OSPI_CTL_FTL); + OSPI_CTL(ospi_periph) |= (uint32_t)ftl; +} + +/*! + \brief configure chip select high cycle + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] cshc: OSPI chip select high cycle + only one parameter can be selected which is shown as below: + \arg OSPI_CS_HIGH_TIME_x_CYCLE (x = 1, 2, ..., 63, 64) + \param[out] none + \retval none +*/ +void ospi_chip_select_high_cycle_config(uint32_t ospi_periph, uint32_t cshc) +{ + OSPI_DCFG0(ospi_periph) &= (uint32_t)(~OSPI_DCFG0_CSHC); + OSPI_DCFG0(ospi_periph) |= (uint32_t)cshc; +} + +/*! + \brief configure OSPI prescaler + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] psc: between 0 and 0xFF + \param[out] none + \retval none +*/ +void ospi_prescaler_config(uint32_t ospi_periph, uint32_t psc) +{ + OSPI_DCFG1(ospi_periph) &= (uint32_t)(~OSPI_DCFG1_PSC); + OSPI_DCFG1(ospi_periph) |= (uint32_t)(psc & (uint32_t)0xFFU); +} + +/*! + \brief configure dummy cycles number + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dumyc: number of dummy cycles + only one parameter can be selected which is shown as below: + \arg OSPI_DUMYC_CYCLES_x (x = 0, 1, 2, ..., 30, 31) + \param[out] none + \retval none +*/ +void ospi_dummy_cycles_config(uint32_t ospi_periph, uint32_t dumyc) +{ + OSPI_TIMCFG(ospi_periph) &= (uint32_t)(~OSPI_TIMCFG_DUMYC); + OSPI_TIMCFG(ospi_periph) |= (uint32_t)dumyc ; +} + +/*! + \brief delay hold 1/4 cycle + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dehqc: OSPI delay hold quarter cycle + only one parameter can be selected which is shown as below: + \arg OSPI_DELAY_HOLD_NONE: OSPI no delay hold cycle + \arg OSPI_DELAY_HOLD_QUARTER_CYCLE: OSPI delay hold 1/4 cycle + \param[out] none + \retval none +*/ +void ospi_delay_hold_cycle_config(uint32_t ospi_periph, uint32_t dehqc) +{ + OSPI_TIMCFG(ospi_periph) &= (uint32_t)(~OSPI_TIMCFG_DEHQC); + OSPI_TIMCFG(ospi_periph) |= (uint32_t)dehqc; +} + +/*! + \brief configure sample shift + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] ssample: OSPI sample shift + only one parameter can be selected which is shown as below: + \arg OSPI_SAMPLE_SHIFTING_NONE: OSPI no sample shift + \arg OSPI_SAMPLE_SHIFTING_HALF_CYCLE: OSPI have 1/2 cycle sample shift + \param[out] none + \retval none +*/ +void ospi_sample_shift_config(uint32_t ospi_periph, uint32_t ssample) +{ + OSPI_TIMCFG(ospi_periph) &= (uint32_t)(~OSPI_TIMCFG_SSAMPLE); + OSPI_TIMCFG(ospi_periph) |= (uint32_t)ssample; +} + +/*! + \brief configure data length + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dtlen: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_data_length_config(uint32_t ospi_periph, uint32_t dtlen) +{ + OSPI_DTLEN(ospi_periph) &= (uint32_t)(~OSPI_DTLEN_DTLEN); + OSPI_DTLEN(ospi_periph) |= (uint32_t)dtlen; +} + +/*! + \brief configure OSPI instruction + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] instruction: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_instruction_config(uint32_t ospi_periph, uint32_t instruction) +{ + OSPI_INS(ospi_periph) = (uint32_t)instruction; +} + +/*! + \brief configure OSPI instruction mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] imod: OSPI instruction mode + only one parameter can be selected which is shown as below: + \arg OSPI_INSTRUCTION_NONE: no instruction mode + \arg OSPI_INSTRUCTION_1_LINE: instruction mode on a single line + \arg OSPI_INSTRUCTION_2_LINES: instruction mode on two lines + \arg OSPI_INSTRUCTION_4_LINES: instruction mode on four lines + \arg OSPI_INSTRUCTION_8_LINES: instruction mode on eight lines + \param[out] none + \retval none +*/ +void ospi_instruction_mode_config(uint32_t ospi_periph, uint32_t imod) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_IMOD); + OSPI_TCFG(ospi_periph) |= (uint32_t)imod; +} + +/*! + \brief configure OSPI instruction size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] inssz: OSPI instruction size + only one parameter can be selected which is shown as below: + \arg OSPI_INSTRUCTION_8_BITS: instruction size on 8-bit address + \arg OSPI_INSTRUCTION_16_BITS: instruction size on 16-bit address + \arg OSPI_INSTRUCTION_24_BITS: instruction size on 24-bit address + \arg OSPI_INSTRUCTION_32_BITS: instruction size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_instruction_size_config(uint32_t ospi_periph, uint32_t inssz) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_INSSZ); + OSPI_TCFG(ospi_periph) |= (uint32_t)inssz; +} + +/*! + \brief configure OSPI address + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addr: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_address_config(uint32_t ospi_periph, uint32_t addr) +{ + OSPI_ADDR(ospi_periph) = (uint32_t)addr; +} + +/*! + \brief configure OSPI address mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrmod: OSPI address mode + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRESS_NONE: no address mode + \arg OSPI_ADDRESS_1_LINE: address mode on a single line + \arg OSPI_ADDRESS_2_LINES: address mode on two lines + \arg OSPI_ADDRESS_4_LINES: address mode on four lines + \arg OSPI_ADDRESS_8_LINES: address mode on eight lines + \param[out] none + \retval none +*/ +void ospi_address_mode_config(uint32_t ospi_periph, uint32_t addrmod) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_ADDRMOD); + OSPI_TCFG(ospi_periph) |= (uint32_t)addrmod; +} + +/*! + \brief configure OSPI address dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrdtr: OSPI address double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRDTR_MODE_DISABLE: address double transfer rate mode disable + \arg OSPI_ADDRDTR_MODE_ENABLE: address double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_address_dtr_config(uint32_t ospi_periph, uint32_t addrdtr) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_ADDRDTR); + OSPI_TCFG(ospi_periph) |= (uint32_t)addrdtr; +} + +/*! + \brief configure OSPI address size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrsz: OSPI address size + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRESS_8_BITS: address size on 8-bit address + \arg OSPI_ADDRESS_16_BITS: address size on 16-bit address + \arg OSPI_ADDRESS_24_BITS: address size on 24-bit address + \arg OSPI_ADDRESS_32_BITS: address size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_address_size_config(uint32_t ospi_periph, uint32_t addrsz) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_ADDRSZ); + OSPI_TCFG(ospi_periph) |= (uint32_t)addrsz; +} + +/*! + \brief configure OSPI alternate byte + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] alte: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_alternate_byte_config(uint32_t ospi_periph, uint32_t alte) +{ + OSPI_ALTE(ospi_periph) = (uint32_t)alte; +} + +/*! + \brief configure OSPI alternate byte mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] atlemod: OSPI alternate bytes mode + only one parameter can be selected which is shown as below: + \arg OSPI_ALTERNATE_BYTES_NONE: no alternate bytes mode + \arg OSPI_ALTERNATE_BYTES_1_LINE: alternate mode on a single line + \arg OSPI_ALTERNATE_BYTES_2_LINES: alternate bytes mode on two lines + \arg OSPI_ALTERNATE_BYTES_4_LINES: alternate bytes mode on four lines + \arg OSPI_ALTERNATE_BYTES_8_LINES: alternate bytes mode on eight lines + \param[out] none + \retval none +*/ +void ospi_alternate_byte_mode_config(uint32_t ospi_periph, uint32_t atlemod) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_ALTEMOD ); + OSPI_TCFG(ospi_periph) |= (uint32_t)atlemod; +} + +/*! + \brief configure OSPI alternate byte dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] abdtr: OSPI alternate bytes double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_ABDTR_MODE_DISABLE: alternate bytes double transfer rate mode disable + \arg OSPI_ABDTR_MODE_ENABLE: alternate bytes double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_alternate_byte_dtr_config(uint32_t ospi_periph, uint32_t abdtr) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_ABDTR); + OSPI_TCFG(ospi_periph) |= (uint32_t)abdtr; +} + +/*! + \brief configure OSPI alternate byte size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] altesz: OSPI alternate bytes size + only one parameter can be selected which is shown as below: + \arg OSPI_ALTERNATE_BYTES_8_BITS: alternate bytes size on 8-bit address + \arg OSPI_ALTERNATE_BYTES_16_BITS: alternate bytes size on 16-bit address + \arg OSPI_ALTERNATE_BYTES_24_BITS: alternate bytes size on 24-bit address + \arg OSPI_ALTERNATE_BYTES_32_BITS: alternate bytes size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_alternate_byte_size_config(uint32_t ospi_periph, uint32_t altesz) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_ABDTR); + OSPI_TCFG(ospi_periph) |= (uint32_t)altesz; +} + +/*! + \brief configure data mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] datamod: OSPI data mode + only one parameter can be selected which is shown as below: + \arg OSPI_DATA_NONE: no data mode + \arg OSPI_DATA_1_LINE: data mode on a single line + \arg OSPI_DATA_2_LINES: data mode on two lines + \arg OSPI_DATA_4_LINES: data mode on four lines + \arg OSPI_DATA_8_LINES: data mode on eight lines + \param[out] none + \retval none +*/ +void ospi_data_mode_config(uint32_t ospi_periph, uint32_t datamod) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_DATAMOD); + OSPI_TCFG(ospi_periph) |= (uint32_t)datamod ; +} + +/*! + \brief configure data dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dadtr: OSPI data double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_DADTR_MODE_DISABLE: data double transfer rate mode disable + \arg OSPI_DADTR_MODE_ENABLE: data double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_data_dtr_config(uint32_t ospi_periph, uint32_t dadtr) +{ + OSPI_TCFG(ospi_periph) &= (uint32_t)~(OSPI_TCFG_DADTR); + OSPI_TCFG(ospi_periph) |= (uint32_t)dadtr; +} + +/*! + \brief OSPI transmit data + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] data: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_data_transmit(uint32_t ospi_periph, uint32_t data) +{ + OSPI_DATA(ospi_periph) = (uint32_t)data; +} + +/*! + \brief OSPI receive data + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] none + \retval between 0 and 0xFFFFFFFF +*/ +uint32_t ospi_data_receive(uint32_t ospi_periph) +{ + return ((uint32_t)OSPI_DATA(ospi_periph)); +} + +/*! + \brief enable OSPI DMA + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] none + \retval none +*/ +void ospi_dma_enable(uint32_t ospi_periph) +{ + OSPI_CTL(ospi_periph) |= (uint32_t)OSPI_CTL_DMAEN; +} + +/*! + \brief disable OSPI DMA + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] none + \retval none +*/ +void ospi_dma_disable(uint32_t ospi_periph) +{ + OSPI_CTL(ospi_periph) &= (uint32_t)(~OSPI_CTL_DMAEN); +} + +/*! + \brief configure wrap size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] wpsz: OSPI wrap size set + only one parameter can be selected which is shown as below: + \arg OSPI_DIRECT: external memory indirect device does not support wrap read + \arg OSPI_WRAP_16BYTES: external memory device supports wrap size of 16 bytes + \arg OSPI_WRAP_32BYTES: external memory device supports wrap size of 32 bytes + \arg OSPI_WRAP_64BYTES: external memory device supports wrap size of 64 bytes + \arg OSPI_WRAP_128BYTES: external memory device supports wrap size of 128 bytes + \param[out] none + \retval none +*/ +void ospi_wrap_size_config(uint32_t ospi_periph, uint32_t wpsz) +{ + OSPI_DCFG1(ospi_periph) &= (uint32_t)(~OSPI_DCFG1_WPSZ); + OSPI_DCFG1(ospi_periph) |= (uint32_t)wpsz; +} + +/*! + \brief configure wrap instruction mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] instruction: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_wrap_instruction_config(uint32_t ospi_periph, uint32_t instruction) +{ + OSPI_WPINS(ospi_periph) = (uint32_t)instruction; +} + +/*! + \brief configure wrap instruction mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] imod: OSPI instruction mode + only one parameter can be selected which is shown as below: + \arg OSPI_INSTRUCTION_NONE: no instruction mode + \arg OSPI_INSTRUCTION_1_LINE: instruction mode on a single line + \arg OSPI_INSTRUCTION_2_LINES: instruction mode on two lines + \arg OSPI_INSTRUCTION_4_LINES: instruction mode on four lines + \arg OSPI_INSTRUCTION_8_LINES: instruction mode on eight lines + \param[out] none + \retval none +*/ +void ospi_wrap_instruction_mode_config(uint32_t ospi_periph, uint32_t imod) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_IMOD); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)imod; +} + +/*! + \brief configure wrap instruction size + \param[in] ospi_periph: OSPIx(x=0,1) + only one parameter can be selected which is shown as below: + \arg OSPI_INSTRUCTION_8_BITS: instruction size on 8-bit address + \arg OSPI_INSTRUCTION_16_BITS: instruction size on 16-bit address + \arg OSPI_INSTRUCTION_24_BITS: instruction size on 24-bit address + \arg OSPI_INSTRUCTION_32_BITS: instruction size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_wrap_instruction_size_config(uint32_t ospi_periph, uint32_t inssz) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_INSSZ); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)inssz; +} + +/*! + \brief configure wrap address + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addr: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_wrap_address_config(uint32_t ospi_periph, uint32_t addr) +{ + OSPI_ADDR(ospi_periph) = (uint32_t)addr; +} + +/*! + \brief configure wrap address mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrmod: OSPI address mode + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRESS_NONE: no address mode + \arg OSPI_ADDRESS_1_LINE: address mode on a single line + \arg OSPI_ADDRESS_2_LINES: address mode on two lines + \arg OSPI_ADDRESS_4_LINES: address mode on four lines + \arg OSPI_ADDRESS_8_LINES: address mode on eight lines + \param[out] none + \retval none +*/ +void ospi_wrap_address_mode_config(uint32_t ospi_periph, uint32_t addrmod) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_ADDRMOD); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)addrmod; +} + +/*! + \brief configure wrap address dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrdtr: OSPI address double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRDTR_MODE_DISABLE: address double transfer rate mode disable + \arg OSPI_ADDRDTR_MODE_ENABLE: address double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_wrap_address_dtr_config(uint32_t ospi_periph, uint32_t addrdtr) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_ADDRDTR); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)addrdtr; +} + +/*! + \brief configure wrap address size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrsz: OSPI address size + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRESS_8_BITS: address size on 8-bit address + \arg OSPI_ADDRESS_16_BITS: address size on 16-bit address + \arg OSPI_ADDRESS_24_BITS: address size on 24-bit address + \arg OSPI_ADDRESS_32_BITS: address size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_wrap_address_size_config(uint32_t ospi_periph, uint32_t addrsz) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_ADDRSZ); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)addrsz; +} + +/*! + \brief configure wrap alternate byte + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] alte: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_wrap_alternate_byte_config(uint32_t ospi_periph, uint32_t alte) +{ + OSPI_WPALTE(ospi_periph) = (uint32_t)alte; +} + +/*! + \brief configure wrap alternate byte mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] atlemod: OSPI alternate bytes mode + only one parameter can be selected which is shown as below: + \arg OSPI_ALTERNATE_BYTES_NONE: no alternate bytes mode + \arg OSPI_ALTERNATE_BYTES_1_LINE: alternate mode on a single line + \arg OSPI_ALTERNATE_BYTES_2_LINES: alternate bytes mode on two lines + \arg OSPI_ALTERNATE_BYTES_4_LINES: alternate bytes mode on four lines + \arg OSPI_ALTERNATE_BYTES_8_LINES: alternate bytes mode on eight lines + \param[out] none + \retval none +*/ +void ospi_wrap_alternate_byte_mode_config(uint32_t ospi_periph, uint32_t atlemod) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_ALTEMOD); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)atlemod; +} + +/*! + \brief configure wrap alternate byte dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] abdtr: OSPI alternate bytes double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_ABDTR_MODE_DISABLE: alternate bytes double transfer rate mode disable + \arg OSPI_ABDTR_MODE_ENABLE: alternate bytes double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_wrap_alternate_byte_dtr_config(uint32_t ospi_periph, uint32_t abdtr) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_ABDTR); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)abdtr; +} + +/*! + \brief configure wrap alternate byte size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] altesz: OSPI alternate bytes size + only one parameter can be selected which is shown as below: + \arg OSPI_ALTERNATE_BYTES_8_BITS: alternate bytes size on 8-bit address + \arg OSPI_ALTERNATE_BYTES_16_BITS: alternate bytes size on 16-bit address + \arg OSPI_ALTERNATE_BYTES_24_BITS: alternate bytes size on 24-bit address + \arg OSPI_ALTERNATE_BYTES_32_BITS: alternate bytes size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_wrap_alternate_byte_size_config(uint32_t ospi_periph, uint32_t altesz) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_ABDTR); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)altesz; +} + +/*! + \brief configure wrap data mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] datamod: OSPI data mode + only one parameter can be selected which is shown as below: + \arg OSPI_DATA_NONE: no data mode + \arg OSPI_DATA_1_LINE: data mode on a single line + \arg OSPI_DATA_2_LINES: data mode on two lines + \arg OSPI_DATA_4_LINES: data mode on four lines + \arg OSPI_DATA_8_LINES: data mode on eight lines + \param[out] none + \retval none +*/ +void ospi_wrap_data_mode_config(uint32_t ospi_periph, uint32_t datamod) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_DATAMOD); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)datamod; +} + +/*! + \brief configure wrap data mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dadtr: OSPI data double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_DADTR_MODE_DISABLE: data double transfer rate mode disable + \arg OSPI_DADTR_MODE_ENABLE: data double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_wrap_data_dtr_config(uint32_t ospi_periph, uint32_t dadtr) +{ + OSPI_WPTCFG(ospi_periph) &= (uint32_t)~(OSPI_WPTCFG_DADTR); + OSPI_WPTCFG(ospi_periph) |= (uint32_t)dadtr; +} + +/*! + \brief configure wrap dummy cycles number + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dumyc: between 0 and 0x1F + \param[out] none + \retval none +*/ +void ospi_wrap_dummy_cycles_config(uint32_t ospi_periph, uint32_t dumyc) +{ + OSPI_WPTIMCFG(ospi_periph) &= (uint32_t)(~OSPI_WPTIMCFG_DUMYC); + OSPI_WPTIMCFG(ospi_periph) |= (uint32_t)(dumyc << 0U); +} + +/*! + \brief delay hold 1/4 cycle in wrap + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dehqc: OSPI delay hold quarter cycle + only one parameter can be selected which is shown as below: + \arg OSPI_DELAY_HOLD_NONE: OSPI no delay hold cycle + \arg OSPI_DELAY_HOLD_QUARTER_CYCLE: OSPI delay hold 1/4 cycle + \param[out] none + \retval none +*/ +void ospi_wrap_delay_hold_cycle_config(uint32_t ospi_periph, uint32_t dehqc) +{ + OSPI_WPTIMCFG(ospi_periph) &= (uint32_t)(~OSPI_WPTIMCFG_DEHQC); + OSPI_WPTIMCFG(ospi_periph) |= (uint32_t)dehqc; +} + +/*! + \brief configure sample shift in wrap + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] ssample: OSPI sample shift + only one parameter can be selected which is shown as below: + \arg OSPI_SAMPLE_SHIFTING_NONE: OSPI no sample shift + \arg OSPI_SAMPLE_SHIFTING_HALF_CYCLE: OSPI have 1/2 cycle sample shift + \param[out] none + \retval none +*/ +void ospi_wrap_sample_shift_config(uint32_t ospi_periph, uint32_t ssample) +{ + OSPI_WPTIMCFG(ospi_periph) &= (uint32_t)(~OSPI_WPTIMCFG_SSAMPLE); + OSPI_WPTIMCFG(ospi_periph) |= (uint32_t)ssample; +} + +/*! + \brief configure write instruction + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] instruction: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_write_instruction_config(uint32_t ospi_periph, uint32_t instruction) +{ + OSPI_WINS(ospi_periph) = (uint32_t)instruction; +} + +/*! + \brief configure write instruction mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] imod: OSPI instruction mode + only one parameter can be selected which is shown as below: + \arg OSPI_INSTRUCTION_NONE: no instruction mode + \arg OSPI_INSTRUCTION_1_LINE: instruction mode on a single line + \arg OSPI_INSTRUCTION_2_LINES: instruction mode on two lines + \arg OSPI_INSTRUCTION_4_LINES: instruction mode on four lines + \arg OSPI_INSTRUCTION_8_LINES: instruction mode on eight lines + \param[out] none + \retval none +*/ +void ospi_write_instruction_mode_config(uint32_t ospi_periph, uint32_t imod) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_IMOD); + OSPI_WTCFG(ospi_periph) |= (uint32_t)imod; +} + +/*! + \brief configure write instruction size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] inssz: OSPI instruction size + only one parameter can be selected which is shown as below: + \arg OSPI_INSTRUCTION_8_BITS: instruction size on 8-bit address + \arg OSPI_INSTRUCTION_16_BITS: instruction size on 16-bit address + \arg OSPI_INSTRUCTION_24_BITS: instruction size on 24-bit address + \arg OSPI_INSTRUCTION_32_BITS: instruction size on 32-bit address + \param[in] instruction: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_write_instruction_size_config(uint32_t ospi_periph, uint32_t inssz) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_INSSZ); + OSPI_WTCFG(ospi_periph) |= (uint32_t)inssz; +} + +/*! + \brief configure write address + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addr: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_write_address_config(uint32_t ospi_periph, uint32_t addr) +{ + OSPI_ADDR(ospi_periph) = (uint32_t)addr; +} + +/*! + \brief configure write address mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrmod: OSPI address mode + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRESS_NONE: no address mode + \arg OSPI_ADDRESS_1_LINE: address mode on a single line + \arg OSPI_ADDRESS_2_LINES: address mode on two lines + \arg OSPI_ADDRESS_4_LINES: address mode on four lines + \arg OSPI_ADDRESS_8_LINES: address mode on eight lines + \param[out] none + \retval none +*/ +void ospi_write_address_mode_config(uint32_t ospi_periph, uint32_t addrmod) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_ADDRMOD); + OSPI_WTCFG(ospi_periph) |= (uint32_t)addrmod; +} + +/*! + \brief configure write address dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrdtr: OSPI address double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRDTR_MODE_DISABLE: address double transfer rate mode disable + \arg OSPI_ADDRDTR_MODE_ENABLE: address double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_write_address_dtr_config(uint32_t ospi_periph, uint32_t addrdtr) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_ADDRDTR); + OSPI_WTCFG(ospi_periph) |= (uint32_t)addrdtr; +} + +/*! + \brief configure write address size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] addrsz: OSPI address size + only one parameter can be selected which is shown as below: + \arg OSPI_ADDRESS_8_BITS: address size on 8-bit address + \arg OSPI_ADDRESS_16_BITS: address size on 16-bit address + \arg OSPI_ADDRESS_24_BITS: address size on 24-bit address + \arg OSPI_ADDRESS_32_BITS: address size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_write_address_size_config(uint32_t ospi_periph, uint32_t addrsz) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_ADDRSZ); + OSPI_WTCFG(ospi_periph) |= (uint32_t)addrsz; +} + +/*! + \brief configure write alternate byte + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] alte: between 0 and 0xFFFFFFFF + \param[out] none + \retval none +*/ +void ospi_write_alternate_byte_config(uint32_t ospi_periph, uint32_t alte) +{ + OSPI_WALTE(ospi_periph) = (uint32_t)alte; +} + +/*! + \brief configure write alternate bytes mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] atlemod: OSPI alternate bytes mode + only one parameter can be selected which is shown as below: + \arg OSPI_ALTERNATE_BYTES_NONE: no alternate bytes mode + \arg OSPI_ALTERNATE_BYTES_1_LINE: alternate mode on a single line + \arg OSPI_ALTERNATE_BYTES_2_LINES: alternate bytes mode on two lines + \arg OSPI_ALTERNATE_BYTES_4_LINES: alternate bytes mode on four lines + \arg OSPI_ALTERNATE_BYTES_8_LINES: alternate bytes mode on eight lines + \param[out] none + \retval none +*/ +void ospi_write_alternate_byte_mode_config(uint32_t ospi_periph, uint32_t atlemod) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_ALTEMOD); + OSPI_WTCFG(ospi_periph) |= (uint32_t)atlemod; +} + +/*! + \brief configure write alternate byte dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] abdtr: OSPI alternate bytes double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_ABDTR_MODE_DISABLE: alternate bytes double transfer rate mode disable + \arg OSPI_ABDTR_MODE_ENABLE: alternate bytes double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_write_alternate_byte_dtr_config(uint32_t ospi_periph, uint32_t abdtr) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_ABDTR); + OSPI_WTCFG(ospi_periph) |= (uint32_t)abdtr; +} + +/*! + \brief configure write alternate byte size + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] altesz: OSPI alternate bytes size + only one parameter can be selected which is shown as below: + \arg OSPI_ALTERNATE_BYTES_8_BITS: alternate bytes size on 8-bit address + \arg OSPI_ALTERNATE_BYTES_16_BITS: alternate bytes size on 16-bit address + \arg OSPI_ALTERNATE_BYTES_24_BITS: alternate bytes size on 24-bit address + \arg OSPI_ALTERNATE_BYTES_32_BITS: alternate bytes size on 32-bit address + \param[out] none + \retval none +*/ +void ospi_write_alternate_byte_size_config(uint32_t ospi_periph, uint32_t altesz) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_ALTESZ); + OSPI_WTCFG(ospi_periph) |= (uint32_t)altesz; +} + +/*! + \brief configure write data mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] datamod: OSPI data mode + only one parameter can be selected which is shown as below: + \arg OSPI_DATA_NONE: no data mode + \arg OSPI_DATA_1_LINE: data mode on a single line + \arg OSPI_DATA_2_LINES: data mode on two lines + \arg OSPI_DATA_4_LINES: data mode on four lines + \arg OSPI_DATA_8_LINES: data mode on eight lines + \param[out] none + \retval none +*/ +void ospi_write_data_mode_config(uint32_t ospi_periph, uint32_t datamod) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~OSPI_WTCFG_DATAMOD; + OSPI_WTCFG(ospi_periph) |= (uint32_t)datamod; +} + +/*! + \brief configure write data dtr + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dadtr: OSPI data double transfer rate + only one parameter can be selected which is shown as below: + \arg OSPI_DADTR_MODE_DISABLE: data double transfer rate mode disable + \arg OSPI_DADTR_MODE_ENABLE: data double transfer rate mode enable + \param[out] none + \retval none +*/ +void ospi_write_data_dtr_config(uint32_t ospi_periph, uint32_t dadtr) +{ + OSPI_WTCFG(ospi_periph) &= (uint32_t)~(OSPI_WTCFG_DADTR); + OSPI_WTCFG(ospi_periph) |= (uint32_t)dadtr; +} + +/*! + \brief configure write dummy cycles number + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] dumyc: number of dummy cycles + \arg OSPI_DUMYC_CYCLES_x (x = 0, 1, 2, ..., 30, 31) + \param[out] none + \retval none +*/ +void ospi_write_dummy_cycles_config(uint32_t ospi_periph, uint32_t dumyc) +{ + OSPI_WTIMCFG(ospi_periph) &= (uint32_t)(~OSPI_WTIMCFG_DUMYC); + OSPI_WTIMCFG(ospi_periph) |= (uint32_t)dumyc; +} + +/*! + \brief configure OSPI regular command parameter + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] ospi_struct: OSPI parameter initialization stuct members of the structure + and the member values are shown as below: + prescaler: between 0 and 255 + fifo_threshold: OSPI_FIFO_THRESHOLD_x (x = 1, 2, ..., 31, 32) + sample_shift: OSPI_SAMPLE_SHIFTING_NONE, OSPI_SAMPLE_SHIFTING_HALF_CYCLE + device_size: OSPI_MESZ_x_BYTES (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_KBS (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_MBS (x = 2, 4, 8, ..., 2048, 4096) + cs_hightime: OSPI_CS_HIGH_TIME_x_CYCLE (x = 1, 2, ..., 63, 64) + memory_type: OSPI_MICRON_MODE, OSPI_MACRONIX_MODE, OSPI_STANDARD_MODE + OSPI_MACRONIX_RAM_MODE + wrap_size: OSPI_DIRECT, OSPI_WRAP_16BYTES, OSPI_WRAP_32BYTES + OSPI_WRAP_64BYTES, OSPI_WRAP_128BYTES + \param[in] cmd_struct: structure that contains the command configuration information + and the member values are shown as below: + operation_type: OSPI_OPTYPE_COMMON_CFG, OSPI_OPTYPE_READ_CFG + OSPI_OPTYPE_WRITE_CFG, OSPI_OPTYPE_WRAP_CFG + instruction: between 0 and 0xFFFFFFFF + ins_mode: OSPI_INSTRUCTION_NONE, OSPI_INSTRUCTION_1_LINE, OSPI_INSTRUCTION_2_LINES + OSPI_INSTRUCTION_4_LINES, OSPI_INSTRUCTION_8_LINES + ins_size: OSPI_INSTRUCTION_8_BITS, OSPI_INSTRUCTION_16_BITS + OSPI_INSTRUCTION_24_BITS, OSPI_INSTRUCTION_32_BITS + address: between 0 and 0xFFFFFFFF + addr_mode: OSPI_ADDRESS_NONE, OSPI_ADDRESS_1_LINE, OSPI_ADDRESS_2_LINES + OSPI_ADDRESS_4_LINES, OSPI_ADDRESS_8_LINES + address_size: OSPI_ADDRESS_8_BITS, OSPI_ADDRESS_16_BITS + OSPI_ADDRESS_24_BITS, OSPI_ADDRESS_32_BITS + addr_dtr_mode: OSPI_ADDRDTR_MODE_DISABLE, OSPI_ADDTR_MODE_ENABLE + alter_bytes: between 0 and 0xFFFFFFFF + alter_bytes_mode: OSPI_ALTERNATE_BYTES_NONE, OSPI_ALTERNATE_BYTES_1_LINE + OSPI_ALTERNATE_BYTES_2_LINES, OSPI_ALTERNATE_BYTES_4_LINES + OSPI_ALTERNATE_BYTES_8_LINES + alter_bytes_size: OSPI_ALTERNATE_BYTES_8_BITS, OSPI_ALTERNATE_BYTES_16_BITS + OSPI_ALTERNATE_BYTES_24_BITS, OSPI_ALTERNATE_BYTES_32_BITS + alter_bytes_dtr_mode: OSPI_ABDTR_MODE_DISABLE, OSPI_ABDTR_MODE_ENABLE + data_mode: OSPI_DATA_NONE, OSPI_DATA_1_LINE, OSPI_DATA_2_LINES + OSPI_DATA_4_LINES, OSPI_DATA_8_LINES + nbdata: between 1 and 0xFFFFFFFF + data_dtr_mode: OSPI_DADTR_MODE_DISABLE, OSPI_DADTR_MODE_ENABLE + dummy_cycles: OSPI_DUMYC_CYCLES_x (x = 0, 1, 2, ..., 30, 31) + \param[out] none + \retval none +*/ +void ospi_command_config(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct, ospi_regular_cmd_struct *cmd_struct) +{ + if(((cmd_struct->operation_type == OSPI_OPTYPE_WRITE_CFG) || (cmd_struct->operation_type == OSPI_OPTYPE_WRAP_CFG)) || + ((cmd_struct->operation_type == OSPI_OPTYPE_READ_CFG) || (cmd_struct->operation_type == OSPI_OPTYPE_COMMON_CFG))){ + /* wait till busy flag is reset */ + while(RESET != (OSPI_STAT(ospi_periph) & OSPI_FLAG_BUSY)){ + } + + /* configure the registers */ + ospi_config(ospi_periph, ospi_struct, cmd_struct); + + if(cmd_struct->data_mode == OSPI_DATA_NONE){ + /* when there is no data phase, the transfer start as soon as the configuration is done + so wait until TC flag is set to go back in idle state */ + while(RESET == (OSPI_STAT(ospi_periph) & OSPI_FLAG_TC)){ + } + + OSPI_STATC(ospi_periph) = OSPI_STATC_TCC; + } + } +} + +/*! + \brief transmit data (this function is used only in indirect write mode) + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] pdata: pointer to data buffer + \param[out] none + \retval none +*/ +void ospi_transmit(uint32_t ospi_periph, uint8_t *pdata) +{ + uint32_t txcounter; + uint32_t address; + /* configure counters and size */ + txcounter = OSPI_DTLEN(ospi_periph) + 1U; + address = (uint32_t)pdata; + + /* configure CTL register with functional mode as indirect write */ + OSPI_CTL(ospi_periph) = (OSPI_CTL(ospi_periph) & ~OSPI_CTL_FMOD) | OSPI_INDIRECT_WRITE; + + do{ + /* wait till fifo threshold flag is set to send data */ + while(RESET != (OSPI_STAT(ospi_periph) & OSPI_FLAG_FT)){ + } + *((__IO uint8_t *)&OSPI_DATA(ospi_periph)) = *(uint8_t *)address; + address++; + txcounter--; + }while(txcounter > 0U); + + /* wait till transfer complete flag is set to go back in idle state */ + while(RESET == (OSPI_STAT(ospi_periph) & OSPI_FLAG_TC)){ + } + + /* clear transfer complete flag */ + OSPI_STATC(ospi_periph) = OSPI_STATC_TCC; +} + +/*! + \brief receive data (this function is used only in indirect read mode) + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] pdata: pointer to data buffer + \param[out] none + \retval none +*/ +void ospi_receive(uint32_t ospi_periph, uint8_t *pdata) +{ + uint32_t rxcounter; + uint32_t address; + uint32_t addr_reg = OSPI_ADDR(ospi_periph); + uint32_t ins_reg = OSPI_INS(ospi_periph); + + /* configure counters and size */ + rxcounter = OSPI_DTLEN(ospi_periph) + 1U; + address = (uint32_t)pdata; + + /* configure CTL register with functional mode as indirect read */ + OSPI_CTL(ospi_periph) = (OSPI_CTL(ospi_periph) & ~OSPI_CTL_FMOD) | OSPI_INDIRECT_READ; + + /* trigger the transfer by re-writing address or instruction register */ + if((OSPI_TCFG(ospi_periph) & OSPI_TCFG_ADDRMOD) != OSPI_ADDRESS_NONE){ + OSPI_ADDR(ospi_periph) = addr_reg; + }else{ + OSPI_INS(ospi_periph) = ins_reg; + } + + do{ + /* wait till fifo threshold or transfer complete flags are set to read received data */ + while(RESET == (OSPI_STAT(ospi_periph) & (OSPI_FLAG_FT | OSPI_FLAG_TC))){ + } + + *(uint8_t *)address = *((__IO uint8_t *)&OSPI_DATA(ospi_periph)); + address++; + rxcounter--; + + }while(rxcounter > 0U); + + /* wait till transfer complete flag is set to go back in idle state */ + while(RESET == (OSPI_STAT(ospi_periph) & OSPI_FLAG_TC)){ + } + + /* clear transfer complete flag */ + OSPI_STATC(ospi_periph) = OSPI_STATC_TCC; +} + +/*! + \brief configure the OSPI automatic polling mode (this function is used only in automatic polling mode) + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] ospi_struct: OSPI parameter initialization stuct members of the structure + and the member values are shown as below: + prescaler: between 0 and 255 + fifo_threshold: OSPI_FIFO_THRESHOLD_x (x = 1, 2, ..., 31, 32) + sample_shift: OSPI_SAMPLE_SHIFTING_NONE, OSPI_SAMPLE_SHIFTING_HALF_CYCLE + device_size: OSPI_MESZ_x_BYTES (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_KBS (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_MBS (x = 2, 4, 8, ..., 2048, 4096) + cs_hightime: OSPI_CS_HIGH_TIME_x_CYCLE (x = 1, 2, ..., 63, 64) + memory_type: OSPI_MICRON_MODE, OSPI_MACRONIX_MODE, OSPI_STANDARD_MODE + OSPI_MACRONIX_RAM_MODE + wrap_size: OSPI_DIRECT, OSPI_WRAP_16BYTES, OSPI_WRAP_32BYTES + OSPI_WRAP_64BYTES, OSPI_WRAP_128BYTES + \param[in] autopl_cfg_struct: OSPI autopolling stuct members of the structure + and the member values are shown as below: + match: between 0 and 0xFFFFFFFF + mask: between 0 and 0xFFFFFFFF + interval: between 0 and 0xFFFF + match_mode: OSPI_MATCH_MODE_AND, OSPI_MATCH_MODE_OR + automatic_stop: OSPI_AUTOMATIC_STOP_MATCH + \param[out] none + \retval none +*/ +void ospi_autopolling_mode(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct, ospi_autopolling_struct *autopl_cfg_struct) +{ + uint32_t addr_reg = OSPI_ADDR(ospi_periph); + uint32_t ins_reg = OSPI_INS(ospi_periph); + + if(autopl_cfg_struct->automatic_stop == OSPI_AUTOMATIC_STOP_MATCH){ + /* wait till busy flag is reset */ + while(RESET != (OSPI_STAT(ospi_periph) & OSPI_FLAG_BUSY)){ + } + + /* configure registers */ + OSPI_STATMATCH(ospi_periph) = autopl_cfg_struct->match; + OSPI_STATMK(ospi_periph) = autopl_cfg_struct->mask; + OSPI_INTERVAL(ospi_periph) = autopl_cfg_struct->interval; + OSPI_CTL(ospi_periph) = (OSPI_CTL(ospi_periph) & (~OSPI_CTL_SPMOD | ~OSPI_CTL_SPS | ~OSPI_CTL_FMOD)) | + (autopl_cfg_struct->match_mode | autopl_cfg_struct->automatic_stop | OSPI_STATUS_POLLING); + + /* trig the transfer by re-writing address or instruction register */ + if((OSPI_TCFG(ospi_periph) & OSPI_TCFG_ADDRMOD) != OSPI_ADDRESS_NONE){ + OSPI_ADDR(ospi_periph) = addr_reg; + }else{ + OSPI_INS(ospi_periph) = ins_reg; + } + + /* wait till status match flag is set to go back in idle state */ + while(RESET == (OSPI_STAT(ospi_periph) & OSPI_FLAG_SM)){ + } + + /* clear status match flag */ + OSPI_STATC(ospi_periph) = OSPI_STATC_SMC; + } +} + +/*! + \brief configure the registers for the regular command mode + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] ospi_struct: OSPI parameter initialization stuct members of the structure + and the member values are shown as below: + prescaler: between 0 and 255 + fifo_threshold: OSPI_FIFO_THRESHOLD_x (x = 1, 2, ..., 31, 32) + sample_shift: OSPI_SAMPLE_SHIFTING_NONE, OSPI_SAMPLE_SHIFTING_HALF_CYCLE + device_size: OSPI_MESZ_x_BYTES (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_KBS (x = 2, 4, 8, ..., 512, 1024) + OSPI_MESZ_x_MBS (x = 2, 4, 8, ..., 2048, 4096) + cs_hightime: OSPI_CS_HIGH_TIME_x_CYCLE (x = 1, 2, ..., 63, 64) + memory_type: OSPI_MICRON_MODE, OSPI_MACRONIX_MODE, OSPI_STANDARD_MODE + OSPI_MACRONIX_RAM_MODE + wrap_size: OSPI_DIRECT, OSPI_WRAP_16BYTES, OSPI_WRAP_32BYTES + OSPI_WRAP_64BYTES, OSPI_WRAP_128BYTES + \param[in] cmd_struct: structure that contains the command configuration information + and the member values are shown as below: + operation_type: OSPI_OPTYPE_COMMON_CFG, OSPI_OPTYPE_READ_CFG + OSPI_OPTYPE_WRITE_CFG, OSPI_OPTYPE_WRAP_CFG + instruction: between 0 and 0xFFFFFFFF + ins_mode: OSPI_INSTRUCTION_NONE, OSPI_INSTRUCTION_1_LINE, OSPI_INSTRUCTION_2_LINES + OSPI_INSTRUCTION_4_LINES, OSPI_INSTRUCTION_8_LINES + ins_size: OSPI_INSTRUCTION_8_BITS, OSPI_INSTRUCTION_16_BITS + OSPI_INSTRUCTION_24_BITS, OSPI_INSTRUCTION_32_BITS + address: between 0 and 0xFFFFFFFF + addr_mode: OSPI_ADDRESS_NONE, OSPI_ADDRESS_1_LINE, OSPI_ADDRESS_2_LINES + OSPI_ADDRESS_4_LINES, OSPI_ADDRESS_8_LINES + address_size: OSPI_ADDRESS_8_BITS, OSPI_ADDRESS_16_BITS + OSPI_ADDRESS_24_BITS, OSPI_ADDRESS_32_BITS + addr_dtr_mode: OSPI_ADDRDTR_MODE_DISABLE, OSPI_ADDTR_MODE_ENABLE + alter_bytes: between 0 and 0xFFFFFFFF + alter_bytes_mode: OSPI_ALTERNATE_BYTES_NONE, OSPI_ALTERNATE_BYTES_1_LINE + OSPI_ALTERNATE_BYTES_2_LINES, OSPI_ALTERNATE_BYTES_4_LINES + OSPI_ALTERNATE_BYTES_8_LINES + alter_bytes_size: OSPI_ALTERNATE_BYTES_8_BITS, OSPI_ALTERNATE_BYTES_16_BITS + OSPI_ALTERNATE_BYTES_24_BITS, OSPI_ALTERNATE_BYTES_32_BITS + alter_bytes_dtr_mode: OSPI_ABDTR_MODE_DISABLE, OSPI_ABDTR_MODE_ENABLE + data_mode: OSPI_DATA_NONE, OSPI_DATA_1_LINE, OSPI_DATA_2_LINES + OSPI_DATA_4_LINES, OSPI_DATA_8_LINES + nbdata: between 1 and 0xFFFFFFFF + data_dtr_mode: OSPI_DADTR_MODE_DISABLE, OSPI_DADTR_MODE_ENABLE + dummy_cycles: OSPI_DUMYC_CYCLES_x (x = 0, 1, 2, ..., 30, 31) + \param[out] none + \retval none +*/ +static void ospi_config(uint32_t ospi_periph, ospi_parameter_struct *ospi_struct, ospi_regular_cmd_struct* cmd_struct) +{ + __IO uint32_t *tcfg_reg, *timcfg_reg, *ins_reg, *alte_reg; + + /* re-initialize the value of the functional mode */ + OSPI_CTL(ospi_periph) &= ~OSPI_CTL_FMOD; + + if(cmd_struct->operation_type == OSPI_OPTYPE_WRITE_CFG){ + tcfg_reg = &(OSPI_WTCFG(ospi_periph)); + timcfg_reg = &(OSPI_WTIMCFG(ospi_periph)); + ins_reg = &(OSPI_WINS(ospi_periph)); + alte_reg = &(OSPI_WALTE(ospi_periph)); + }else if(cmd_struct->operation_type == OSPI_OPTYPE_WRAP_CFG){ + tcfg_reg = &(OSPI_WPTCFG(ospi_periph)); + timcfg_reg = &(OSPI_WPTIMCFG(ospi_periph)); + ins_reg = &(OSPI_WPINS(ospi_periph)); + alte_reg = &(OSPI_WPALTE(ospi_periph)); + }else{ + tcfg_reg = &(OSPI_TCFG(ospi_periph)); + timcfg_reg = &(OSPI_TIMCFG(ospi_periph)); + ins_reg = &(OSPI_INS(ospi_periph)); + alte_reg = &(OSPI_ALTE(ospi_periph)); + } + + if(cmd_struct->alter_bytes_mode != OSPI_ALTERNATE_BYTES_NONE){ + /* configure the ALTE register with alternate bytes value */ + *alte_reg = cmd_struct->alter_bytes; + + /* configure the TCFG register with alternate bytes communication parameters */ + *tcfg_reg = (*tcfg_reg & ~(OSPI_TCFG_ALTEMOD | OSPI_TCFG_ABDTR | OSPI_TCFG_ALTESZ)) | + (cmd_struct->alter_bytes_mode | cmd_struct->alter_bytes_dtr_mode | cmd_struct->alter_bytes_size); + } + + /* configure the TIMCFG register with the number of dummy cycles */ + *timcfg_reg = (*timcfg_reg & ~OSPI_TIMCFG_DUMYC) | cmd_struct->dummy_cycles; + + if(cmd_struct->data_mode != OSPI_DATA_NONE){ + if(cmd_struct->operation_type == OSPI_OPTYPE_COMMON_CFG){ + /* configure the DTLEN register with the number of data */ + OSPI_DTLEN(ospi_periph) = (cmd_struct->nbdata - 1U); + } + } + + + if(cmd_struct->ins_mode != OSPI_INSTRUCTION_NONE){ + if(cmd_struct->addr_mode != OSPI_ADDRESS_NONE){ + if(cmd_struct->data_mode != OSPI_DATA_NONE){ + /* command with instruction, address and data */ + /* configure the TCFG register with all communication parameters */ + *tcfg_reg &= ~(OSPI_TCFG_IMOD | OSPI_TCFG_INSSZ | + OSPI_TCFG_ADDRMOD | OSPI_TCFG_ADDRDTR | OSPI_TCFG_ADDRSZ | + OSPI_TCFG_DATAMOD | OSPI_TCFG_DADTR); + + *tcfg_reg = cmd_struct->ins_mode | cmd_struct->ins_size | + cmd_struct->addr_mode | cmd_struct->addr_dtr_mode | cmd_struct->addr_size | + cmd_struct->data_mode | cmd_struct->data_dtr_mode; + }else{ + /* command with instruction and address */ + /* configure the TCFG register with all communication parameters */ + *tcfg_reg &= ~(OSPI_TCFG_IMOD | OSPI_TCFG_INSSZ | + OSPI_TCFG_ADDRMOD | OSPI_TCFG_ADDRDTR | OSPI_TCFG_ADDRSZ); + + *tcfg_reg = cmd_struct->ins_mode | cmd_struct->ins_size | + cmd_struct->addr_mode | cmd_struct->addr_dtr_mode | cmd_struct->addr_size; + + /* the DHQC bit is linked with DDTR bit which should be activated */ + if((ospi_struct->delay_hold_cycle == OSPI_DELAY_HOLD_QUARTER_CYCLE) ){ + *tcfg_reg = (*tcfg_reg & ~OSPI_DADTR_MODE_ENABLE) | OSPI_DADTR_MODE_ENABLE; + } + } + + /* configure the INS register with the instruction value */ + *ins_reg = cmd_struct->instruction; + + /* configure the ADDR register with the address value */ + OSPI_ADDR(ospi_periph) = cmd_struct->address; + }else{ + if(cmd_struct->data_mode != OSPI_DATA_NONE){ + /* command with instruction and data */ + /* configure the TCFG register with all communication parameters */ + *tcfg_reg &= ~(OSPI_TCFG_IMOD | OSPI_TCFG_INSSZ | + OSPI_TCFG_DATAMOD | OSPI_TCFG_DADTR); + + *tcfg_reg = cmd_struct->ins_mode | cmd_struct->ins_size | + cmd_struct->data_mode | cmd_struct->data_dtr_mode; + }else{ + /* command with only instruction */ + /* configure the TCFG register with all communication parameters */ + *tcfg_reg &= ~(OSPI_TCFG_IMOD | OSPI_TCFG_INSSZ); + + *tcfg_reg = cmd_struct->ins_mode | cmd_struct->ins_size; + + /* the DEHQC bit is linked with DDTR bit which should be activated */ + if((ospi_struct->delay_hold_cycle == OSPI_DELAY_HOLD_QUARTER_CYCLE)){ + *tcfg_reg = (*tcfg_reg & ~OSPI_DADTR_MODE_ENABLE) | OSPI_DADTR_MODE_ENABLE; + } + } + + /* configure the INS register with the instruction value */ + *ins_reg = cmd_struct->instruction; + } + }else{ + if(cmd_struct->addr_mode != OSPI_ADDRESS_NONE){ + if(cmd_struct->data_mode != OSPI_DATA_NONE){ + /* command with address and data */ + + /* configure the TCFG register with all communication parameters */ + *tcfg_reg &= ~(OSPI_TCFG_ADDRMOD | OSPI_TCFG_ADDRDTR | OSPI_TCFG_ADDRSZ | + OSPI_TCFG_DATAMOD | OSPI_TCFG_DADTR); + + *tcfg_reg = cmd_struct->addr_mode | cmd_struct->addr_dtr_mode | cmd_struct->addr_size | + cmd_struct->data_mode | cmd_struct->data_dtr_mode; + }else{ + /* command with only address */ + + /* configure the TCFG register with all communication parameters */ + *tcfg_reg &= ~(OSPI_TCFG_ADDRMOD | OSPI_TCFG_ADDRDTR | OSPI_TCFG_ADDRSZ); + + *tcfg_reg = cmd_struct->addr_mode | cmd_struct->addr_dtr_mode | cmd_struct->addr_size; + } + + /* configure the ADDR register with the instruction value */ + OSPI_ADDR(ospi_periph) = cmd_struct->address; + } + } +} + +/*! + \brief enable OSPI interrupt + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] interrupt: OSPI interrupt + only one parameter can be selected which is shown as below: + \arg OSPI_INT_TERR: transfer error interrupt + \arg OSPI_INT_TC: transfer complete interrupt + \arg OSPI_INT_FT: fifo threshold interrupt + \arg OSPI_INT_SM: status match interrupt + \param[out] none + \retval none +*/ +void ospi_interrupt_enable(uint32_t ospi_periph, uint32_t interrupt) +{ + OSPI_CTL(ospi_periph) |= interrupt; + +} + +/*! + \brief disable OSPI interrupt + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] interrupt: OSPI interrupt + only one parameter can be selected which is shown as below: + \arg OSPI_INT_TERR: transfer error interrupt + \arg OSPI_INT_TC: transfer complete interrupt + \arg OSPI_INT_FT: fifo threshold interrupt + \arg OSPI_INT_SM: status match interrupt + \param[out] none + \retval none +*/ +void ospi_interrupt_disable(uint32_t ospi_periph, uint32_t interrupt) +{ + OSPI_CTL(ospi_periph) &= ~interrupt; +} + +/*! + \brief get OSPI fifo level + \param[in] ospi_periph: OSPIx(x=0,1) + \param[out] none + \retval 6-bit fifo level +*/ +uint32_t ospi_fifo_level_get(uint32_t ospi_periph) +{ + uint32_t fl; + fl = (OSPI_STAT(ospi_periph) & (uint32_t)OSPI_STAT_FL) >> 8U; + return fl; +} + +/*! + \brief get OSPI flag status + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] flag: OSPI flag status + only one parameter can be selected which is shown as below: + \arg OSPI_FLAG_TERR: transfer error flag + \arg OSPI_FLAG_TC: transfer complete flag + \arg OSPI_FLAG_FT: fifo threshold flag + \arg OSPI_FLAG_SM: status match flag + \arg OSPI_FLAG_BUSY: busy flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ospi_flag_get(uint32_t ospi_periph, uint32_t flag) +{ + if(RESET != (OSPI_STAT(ospi_periph) & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear OSPI flag status + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] flag: OSPI flag status + only one parameter can be selected which is shown as below: + \arg OSPI_FLAG_TERR: transfer error flag + \arg OSPI_FLAG_TC: transfer complete flag + \arg OSPI_FLAG_SM: status match flag + \param[out] none + \retval none +*/ +void ospi_flag_clear(uint32_t ospi_periph, uint32_t flag) +{ + OSPI_STATC(ospi_periph) = (uint32_t)flag; +} + +/*! + \brief get OSPI interrupt flag status + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] int_flag: OSPI interrupt flag status + only one parameter can be selected which is shown as below: + \arg OSPI_INT_FLAG_TERR: transfer error interrupt flag + \arg OSPI_INT_FLAG_TC: transfer complete interrupt flag + \arg OSPI_INT_FLAG_FT: fifo threshold interrupt flag + \arg OSPI_INT_FLAG_SM: status match interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ospi_interrupt_flag_get(uint32_t ospi_periph, uint32_t int_flag) +{ + uint32_t ret1 = RESET; + uint32_t ret2 = RESET; + + /* get the status of interrupt enable bit */ + ret1 = (OSPI_REG_VAL(ospi_periph, int_flag) & BIT(OSPI_BIT_POS(int_flag))); + /* get the status of interrupt flag */ + ret2 = (OSPI_REG_VAL2(ospi_periph, int_flag) & BIT(OSPI_BIT_POS2(int_flag))); + if(ret1 && ret2) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear OSPI interrupt flag status + \param[in] ospi_periph: OSPIx(x=0,1) + \param[in] int_flag: OSPI interrupt flag status + only one parameter can be selected which is shown as below: + \arg OSPI_INT_FLAG_TERR: transfer error interrupt flag + \arg OSPI_INT_FLAG_TC: transfer complete interrupt flag + \arg OSPI_INT_FLAG_SM: status match interrupt flag + \param[out] none + \retval none +*/ +void ospi_interrupt_flag_clear(uint32_t ospi_periph, uint32_t int_flag) +{ + OSPI_STATC(ospi_periph) |= BIT(OSPI_BIT_POS2(int_flag)); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospim.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospim.c new file mode 100644 index 0000000000..d50c6b4cde --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_ospim.c @@ -0,0 +1,206 @@ +/*! + \file gd32h7xx_ospim.c + \brief OSPIM driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_ospim.h" +#include "gd32h7xx_ospi.h" + +/*! + \brief reset the OSPIM peripheral + \param[in] none + \param[out] none + \retval none +*/ +void ospim_deinit(void) +{ + /* reset OSPIM */ + rcu_periph_reset_enable(RCU_OSPIMRST); + rcu_periph_reset_disable(RCU_OSPIMRST); +} + +/*! + \brief configurate SCK for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] sckconfg: enable or disable SCK + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT_SCK_DISABLE: disable SCK + \arg OSPIM_PORT_SCK_ENABLE: enable SCK + \param[out] none + \retval none +*/ +void ospim_port_sck_config(uint8_t port, uint32_t sckconfg) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SCKEN); + OSPIM_PCFG(port) |= (uint32_t)sckconfg; +} + + +/*! + \brief select source of SCK for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] sck_source: source of SCK + only one parameter can be selected which is shown as below: + \arg OSPIM_SCK_SOURCE_OSPI0_SCK: the source of SCK is OSPI0_SCK + \arg OSPIM_SCK_SOURCE_OSPI1_SCK: the source of SCK is OSPI1_SCK + \param[out] none + \retval none +*/ +void ospim_port_sck_source_select(uint8_t port, uint32_t sck_source) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPCK); + OSPIM_PCFG(port) |= (uint32_t)sck_source; +} + +/*! + \brief configurate CSN for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] csnconfig: enable or disable CSN + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT_CSN_DISABLE: disable CSN + \arg OSPIM_PORT_CSN_ENABLE: enable CSN + \param[out] none + \retval none +*/ +void ospim_port_csn_config(uint8_t port, uint32_t csnconfig) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_NCSEN); + OSPIM_PCFG(port) |= (uint32_t)csnconfig; +} + +/*! + \brief select source of CSN for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] csn_source: source of CSN + only one parameter can be selected which is shown as below: + \arg OSPIM_CSN_SOURCE_OSPI0_CSN: the source of CSN is OSPI0_CSN + \arg OSPIM_CSN_SOURCE_OSPI1_CSN: the source of CSN is OSPI1_CSN + \param[out] none + \retval none +*/ +void ospim_port_csn_source_select(uint8_t port, uint32_t csn_source) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPCS); + OSPIM_PCFG(port) |= (uint32_t)csn_source; +} + +/*! + \brief configurate IO[3:0] for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] ioconfig: enable or disable IO[3:0] + only one parameter can be selected which is shown as below: + \arg OSPIM_IO_LOW_DISABLE: disable IO[3:0] + \arg OSPIM_IO_LOW_ENABLE: enable IO[3:0] + \param[out] none + \retval none +*/ +void ospim_port_io3_0_config(uint8_t port, uint32_t ioconfig) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_POLEN); + OSPIM_PCFG(port) |= (uint32_t)ioconfig; +} + +/*! + \brief select source of IO[3:0] for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] csn_source: source of IO[3:0] + only one parameter can be selected which is shown as below: + \arg OSPIM_SRCPLIO_OSPI0_IO_LOW: select OSPI0_IO[3:0] + \arg OSPIM_SRCPLIO_OSPI0_IO_HIGH: select OSPI0_IO[7:4] + \arg OSPIM_SRCPLIO_OSPI1_IO_LOW: select OSPI1_IO[3:0] + \arg OSPIM_SRCPLIO_OSPI1_IO_HIGH: select OSPI1_IO[7:4] + \param[out] none + \retval none +*/ +void ospim_port_io3_0_source_select(uint8_t port, uint32_t io_source) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPLIO); + OSPIM_PCFG(port) |= (uint32_t)io_source; +} + +/*! + \brief configurate IO[7:4] for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] ioconfig: enable or disable IO[7:4] + only one parameter can be selected which is shown as below: + \arg OSPIM_IO_HIGH_DISABLE: disable IO[7:4] + \arg OSPIM_IO_HIGH_ENABLE: enable IO[7:4] + \param[out] none + \retval none +*/ +void ospim_port_io7_4_config(uint8_t port, uint32_t ioconfig) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_POHEN); + OSPIM_PCFG(port) |= (uint32_t)ioconfig; +} + +/*! + \brief select source of IO[7:4] for port + \param[in] port: number of port + only one parameter can be selected which is shown as below: + \arg OSPIM_PORT0: port 0 + \arg OSPIM_PORT1: port 1 + \param[in] csn_source: source of IO[7:4] + only one parameter can be selected which is shown as below: + \arg OSPIM_SRCPHIO_OSPI0_IO_LOW: select OSPI0_IO[3:0] + \arg OSPIM_SRCPHIO_OSPI0_IO_HIGH: select OSPI0_IO[7:4] + \arg OSPIM_SRCPHIO_OSPI1_IO_LOW: select OSPI1_IO[3:0] + \arg OSPIM_SRCPHIO_OSPI1_IO_HIGH: select OSPI1_IO[7:4] + \param[out] none + \retval none +*/ +void ospim_port_io7_4_source_select(uint8_t port, uint32_t io_source) +{ + OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPHIO); + OSPIM_PCFG(port) |= (uint32_t)io_source; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_pmu.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_pmu.c new file mode 100644 index 0000000000..7d1cd851d3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_pmu.c @@ -0,0 +1,583 @@ +/*! + \file gd32h7xx_pmu.c + \brief PMU driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_pmu.h" + +/* PMU register bit offset */ +#define PAR_TSW_IRCCNT_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of TSW_HSICNT in PMU_PAR */ + +/*! + \brief reset PMU register + \param[in] none + \param[out] none + \retval none +*/ +void pmu_deinit(void) +{ + /* reset PMU */ + rcu_periph_reset_enable(RCU_PMURST); + rcu_periph_reset_disable(RCU_PMURST); +} + +/*! + \brief select low voltage detector threshold + \param[in] lvdt_n: + only one parameter can be selected which is shown as below: + \arg PMU_LVDT_0: voltage threshold is 2.1V + \arg PMU_LVDT_1: voltage threshold is 2.3V + \arg PMU_LVDT_2: voltage threshold is 2.4V + \arg PMU_LVDT_3: voltage threshold is 2.6V + \arg PMU_LVDT_4: voltage threshold is 2.7V + \arg PMU_LVDT_5: voltage threshold is 2.9V + \arg PMU_LVDT_6: voltage threshold is 3.0V + \arg PMU_LVDT_7: input analog voltage on PB7 (compared with 0.8V) + \param[out] none + \retval none +*/ +void pmu_lvd_select(uint32_t lvdt_n) +{ + uint32_t temp; + temp = PMU_CTL0; + /* clear LVDT bits */ + temp &= ~PMU_CTL0_LVDT; + /* set LVDT bits according to lvdt_n */ + temp |= lvdt_n; + PMU_CTL0 = temp; +} + +/*! + \brief enable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_enable(void) +{ + PMU_CTL0 |= PMU_CTL0_LVDEN; +} + +/*! + \brief disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + PMU_CTL0 &= ~PMU_CTL0_LVDEN; +} + +/*! + \brief select analog voltage detector threshold + \param[in] avdt_n: + only one parameter can be selected which is shown as below: + \arg PMU_VAVDVC_0: voltage threshold of analog voltage detector is 1.7V + \arg PMU_VAVDVC_1: voltage threshold of analog voltage detector is 2.1V + \arg PMU_VAVDVC_2: voltage threshold of analog voltage detector is 2.5V + \arg PMU_VAVDVC_3: voltage threshold of analog voltage detector is 2.8V + \param[out] none + \retval none +*/ +void pmu_avd_select(uint32_t avdt_n) +{ + uint32_t temp; + temp = PMU_CTL0; + /* clear VAVDVC bits */ + temp &= ~PMU_CTL0_VAVDVC; + /* set VAVDVC bits according to avdt_n */ + temp |= avdt_n; + PMU_CTL0 = temp; +} + +/*! + \brief enable PMU analog voltage detector + \param[in] none + \param[out] none + \retval none +*/ +void pmu_avd_enable(void) +{ + PMU_CTL0 |= PMU_CTL0_VAVDEN; +} + +/*! + \brief disable PMU analog voltage detector + \param[in] none + \param[out] none + \retval none +*/ +void pmu_avd_disable(void) +{ + PMU_CTL0 &= ~PMU_CTL0_VAVDEN; +} + +/*! + \brief enable PMU V0.9V core voltage detector + \param[in] none + \param[out] none + \retval none +*/ +void pmu_cvd_enable(void) +{ + PMU_CTL0 |= PMU_CTL0_VOVDEN; +} + +/*! + \brief disable PMU V0.9V core voltage detector + \param[in] none + \param[out] none + \retval none +*/ +void pmu_cvd_disable(void) +{ + PMU_CTL0 &= ~PMU_CTL0_VOVDEN; +} + +/*! + \brief control the V0.9V core voltage level + \param[in] ldo_n: + only one parameter can be selected which is shown as below: + \arg PMU_LDOVS_0: LDO output voltage 0.8V mode + \arg PMU_LDOVS_1: LDO output voltage 0.85V mode + \arg PMU_LDOVS_2: LDO output voltage 0.9V mode + \arg PMU_LDOVS_3: LDO output voltage 0.95V mode + \arg PMU_LDOVS_4: LDO output voltage 0.975V mode + \arg PMU_LDOVS_5: LDO output voltage 1V mode + \param[out] none + \retval none +*/ +void pmu_ldo_output_select(uint32_t ldo_n) +{ + uint32_t temp; + temp = PMU_CTL3; + temp &= ~PMU_CTL3_LDOVS; + temp |= ldo_n; + PMU_CTL3 = temp; +} + +/*! + \brief Deep-sleep mode V0.9V core voltage select + \param[in] sldo: + only one parameter can be selected which is shown as below: + \arg PMU_SLDOVS_0: SLDOVS scale 0.6V + \arg PMU_SLDOVS_1: SLDOVS scale 0.7V + \arg PMU_SLDOVS_2: SLDOVS scale 0.8V + \arg PMU_SLDOVS_3: SLDOVS scale 0.9V + \param[out] none + \retval none +*/ +void pmu_sldo_output_select(uint32_t sldo_n) +{ + uint32_t temp; + temp = PMU_CTL0; + temp &= ~PMU_CTL0_SLDOVS; + temp |= sldo_n; + PMU_CTL0 = temp; +} + +/*! + \brief PMU VBAT battery charging resistor selection + \param[in] resistor: + only one parameter can be selected which is shown as below: + \arg PMU_VCRSEL_5K: 5kOhms resistor is selected for charing VBAT battery + \arg PMU_VCRSEL_1P5K: 1.5kOhms resistor is selected for charing VBAT battery + \param[out] none + \retval none +*/ +void pmu_vbat_charging_select(uint32_t resistor) +{ + PMU_CTL2 &= ~PMU_CTL2_VCRSEL; + PMU_CTL2 |= resistor; +} + +/*! + \brief enable VBAT battery charging + \param[in] none + \param[out] none + \retval none +*/ +void pmu_vbat_charging_enable(void) +{ + PMU_CTL2 |= PMU_CTL2_VCEN; +} + +/*! + \brief disable VBAT battery charging + \param[in] none + \param[out] none + \retval none +*/ +void pmu_vbat_charging_disable(void) +{ + PMU_CTL2 &= ~PMU_CTL2_VCEN; +} + +/*! + \brief enable VBAT and temperature monitoring + \param[in] none + \param[out] none + \retval none +*/ +void pmu_vbat_temp_moniter_enable(void) +{ + PMU_CTL1 |= PMU_CTL1_VBTMEN; +} + +/*! + \brief disable VBAT and temperature monitoring + \param[in] none + \param[out] none + \retval none +*/ +void pmu_vbat_temp_moniter_disable(void) +{ + PMU_CTL1 &= ~PMU_CTL1_VBTMEN; +} + +/*! + \brief enable USB regulator + \param[in] none + \param[out] none + \retval none +*/ +void pmu_usb_regulator_enable(void) +{ + PMU_CTL2 |= PMU_CTL2_USBSEN; +} + +/*! + \brief disable USB regulator + \param[in] none + \param[out] none + \retval none +*/ +void pmu_usb_regulator_disable(void) +{ + PMU_CTL2 &= ~PMU_CTL2_USBSEN; +} + +/*! + \brief enable VDD33USB voltage level detector + \param[in] none + \param[out] none + \retval none +*/ +void pmu_usb_voltage_detector_enable(void) +{ + PMU_CTL2 |= PMU_CTL2_VUSB33DEN; +} + +/*! + \brief disable VDD33USB voltage level detector + \param[in] none + \param[out] none + \retval none +*/ +void pmu_usb_voltage_detector_disable(void) +{ + PMU_CTL2 &= ~PMU_CTL2_VUSB33DEN; +} + +/*! + \brief power supply configurations + \param[in] smpsmode: + only one parameter can be selected which is shown as below: + \arg PMU_LDO_SUPPLY: V0.9V domains are suppplied from the LDO + \arg PMU_DIRECT_SMPS_SUPPLY: V0.9V domains are suppplied from the SMPS only + \arg PMU_SMPS_1V8_SUPPLIES_LDO: the SMPS 1.8V output supplies the LDO which supplies the V0.9V domains + \arg PMU_SMPS_2V5_SUPPLIES_LDO: the SMPS 2.5V output supplies the LDO which supplies the V0.9V domains + \arg PMU_SMPS_1V8_SUPPLIES_EXT_AND_LDO: the SMPS 1.8V output supplies an external circuits and the LDO. The V0.9V domains are suppplied from the LDO + \arg PMU_SMPS_2V5_SUPPLIES_EXT_AND_LDO: the SMPS 2.5V output supplies an external circuits and the LDO. The V0.9V domains are suppplied from the LDO + \arg PMU_SMPS_1V8_SUPPLIES_EXT: the SMPS 1.8V output supplies an external source which supplies the V0.9V domains + \arg PMU_SMPS_2V5_SUPPLIES_EXT: the SMPS 2.5V output supplies an external source which supplies the V0.9V domains + \arg PMU_BYPASS: the SMPS disabled and the LDO Bypass. The V0.9V domains are supplied from an external source + \param[out] none + \retval none +*/ +void pmu_smps_ldo_supply_config(uint32_t smpsmode) +{ + uint32_t temp; + temp = PMU_CTL2; + temp &= ~(PMU_CTL2_DVSVC | PMU_CTL2_DVSCFG | PMU_CTL2_DVSEN | PMU_CTL2_LDOEN | PMU_CTL2_BYPASS); + temp |= smpsmode; + PMU_CTL2 = temp; + + while(0U == (PMU_CTL3 & PMU_CTL3_VOVRF)) { + } + + /* When the SMPS supplies external circuits verify that DVSRF flag is set */ + if((smpsmode == PMU_SMPS_1V8_SUPPLIES_EXT_AND_LDO) || + (smpsmode == PMU_SMPS_2V5_SUPPLIES_EXT_AND_LDO) || + (smpsmode == PMU_SMPS_1V8_SUPPLIES_EXT) || + (smpsmode == PMU_SMPS_2V5_SUPPLIES_EXT)) { + while(0U == (PMU_CTL2 & PMU_CTL2_DVSRF)) { + } + } +} + +/*! + \brief enter sleep mode + \param[in] sleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M7 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + /* select WFI or WFE command to enter sleep mode */ + if(WFI_CMD == sleepmodecmd) { + __WFI(); + } else { + __WFE(); + __WFE(); + } +} + +/*! + \brief enter deepsleep mode + \param[in] deepsleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint8_t deepsleepmodecmd) +{ + /* clear standby mode */ + PMU_CTL0 &= ~((uint32_t)(PMU_CTL0_STBMOD)); + + /* set sleepdeep bit of Cortex-M7 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd) { + __WFI(); + } else { + __SEV(); + __WFE(); + __WFE(); + } + /* reset sleepdeep bit of Cortex-M7 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief enter standby mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_to_standbymode(void) +{ + /* set stbmod bit */ + PMU_CTL0 |= PMU_CTL0_STBMOD; + + /* reset wakeup flag */ + PMU_CTL0 |= PMU_CTL0_WURST; + + /* set sleepdeep bit of Cortex-M7 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + REG32( 0xE000E010U ) &= 0x00010004U; + REG32( 0xE000E180U ) = 0xFFFFFFF3U; + REG32( 0xE000E184U ) = 0xFFFFFDFFU; + REG32( 0xE000E188U ) = 0xFFFFFFFFU; + REG32( 0xE000E18CU ) = 0xFFFFFFFFU; + REG32( 0xE000E190U ) = 0xFFFFFFFFU; + REG32( 0xE000E194U ) = 0xFFFFFFFFU; + + /* enter standby mode */ + __WFI(); +} + +/*! + \brief enable PMU wakeup pin + \param[in] wakeup_pin: + only one parameter can be selected which is shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 + \arg PMU_WAKEUP_PIN3: WKUP Pin 3 + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin) +{ + PMU_CS |= wakeup_pin; +} + +/*! + \brief disable PMU wakeup pin + \param[in] wakeup_pin: + only one parameter can be selected which is shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 + \arg PMU_WAKEUP_PIN3: WKUP Pin 3 + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin) +{ + PMU_CS &= ~(wakeup_pin); +} + +/*! + \brief enable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL0 |= PMU_CTL0_BKPWEN; +} + +/*! + \brief disable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL0 &= ~PMU_CTL0_BKPWEN; +} + +/*! + \brief enable backup voltage stabilizer + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_voltage_stabilizer_enable(void) +{ + PMU_CTL1 |= PMU_CTL1_BKPVSEN; + while(RESET == (PMU_CTL1 & PMU_CTL1_BKPVSRF)) { + } +} + +/*! + \brief disable backup voltage stabilizer + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_voltage_stabilizer_disable(void) +{ + PMU_CTL1 &= ~PMU_CTL1_BKPVSEN; +} + +/*! + \brief configure IRC counter before enter Deep-sleep mode + \param[in] wait_time: 0x0~0x1F, IRC counter before enter Deep-sleep mode + \param[out] none + \retval none +*/ +void pmu_enter_deepsleep_wait_time_config(uint32_t wait_time) +{ + uint32_t temp; + temp = PMU_PAR; + temp &= ~PMU_PAR_TSW_IRCCNT; + temp |= (uint32_t)(wait_time << PAR_TSW_IRCCNT_OFFSET); + PMU_PAR = temp; +} + +/*! + \brief configure IRC counter before exit Deep-sleep mode + \param[in] wait_time: 0x0~0xFFF, IRC counter before exit Deep-sleep mode + \param[out] none + \retval none +*/ +void pmu_exit_deepsleep_wait_time_config(uint32_t wait_time) +{ + uint32_t temp; + temp = PMU_PAR; + temp &= ~PMU_PAR_CNT; + temp |= (uint32_t)(wait_time); + PMU_PAR = temp; +} + +/*! + \brief get flag state + \param[in] flag: + only one parameter can be selected which is shown as below: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVDF: low voltage detector status flag + \arg PMU_FLAG_VAVDF: VDDA analog voltage detector voltage output on VDDA flag + \arg PMU_FLAG_VOVDF: peripheral voltage on VDDA detector flag + \arg PMU_FLAG_VBATLF: VBAT level monitoring versus low threshold + \arg PMU_FLAG_VBATHF: VBAT level monitoring versus high threshold + \arg PMU_FLAG_TEMPLF: temperature level monitoring versus low threshold + \arg PMU_FLAG_TEMPHF: temperature level monitoring versus high threshold + \arg PMU_FLAG_DVSRF: step-down voltage stabilizer ready flag bit + \arg PMU_FLAG_USB33RF: USB supply ready flag bit + \arg PMU_FLAG_PWRRF: power Ready flag bit. + \param[out] none + \retval FlagStatus SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag) +{ + if(PMU_REG_VAL(flag) & BIT(PMU_BIT_POS(flag))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear flag bit + \param[in] flag_reset: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag_reset) +{ + if(PMU_FLAG_WAKEUP == flag_reset) { + PMU_CTL0 |= PMU_CTL0_WURST; + } else { + if(PMU_FLAG_STANDBY == flag_reset) { + PMU_CTL0 |= PMU_CTL0_STBRST; + } + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rameccmu.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rameccmu.c new file mode 100644 index 0000000000..b6d9c50379 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rameccmu.c @@ -0,0 +1,395 @@ +/*! + \file gd32h7xx_rameccmu.c + \brief RAMECCMU driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_rameccmu.h" + +#define RAMECCMU_REG_RESET_VALUE 0x00000000U + +/*! + \brief deinit RAMECCMU unit + \param[in] rameccmu_periph: RAMECCMUx(x=0,1) + \param[out] none + \retval none +*/ +void rameccmu_deinit(uint32_t rameccmu_periph) +{ + RAMECCMU_INT(rameccmu_periph) = RAMECCMU_REG_RESET_VALUE; + if(RAMECCMU0 == rameccmu_periph){ + /* reset RAMECCMU0_MONITOR0 registers */ + RAMECCMU_MXCTL(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + /* reset RAMECCMU0_MONITOR1 registers */ + RAMECCMU_MXCTL(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + /* reset RAMECCMU0_MONITOR2 registers */ + RAMECCMU_MXCTL(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + /* reset RAMECCMU0_MONITOR3 registers */ + RAMECCMU_MXCTL(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE; + /* reset RAMECCMU0_MONITOR4 registers */ + RAMECCMU_MXCTL(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE; + }else{ + /* reset RAMECCMU1_MONITOR0 registers */ + RAMECCMU_MXCTL(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE; + /* reset RAMECCMU1_MONITOR1 registers */ + RAMECCMU_MXCTL(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE; + /* reset RAMECCMU1_MONITOR2 registers */ + RAMECCMU_MXCTL(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXSTAT(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFADDR(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDL(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFDH(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + RAMECCMU_MXFECODE(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE; + } +} + +/*! + \brief get RAMECCMU monitor ECC failing address + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[out] none + \retval ECC error failing address +*/ +uint32_t rameccmu_monitor_failing_address_get(rameccmu_monitor_enum rameccmu_monitor) +{ + return RAMECCMU_MXFADDR(rameccmu_monitor); +} + +/*! + \brief get RAMECCMU monitor ECC failing data low 32 bits + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[out] none + \retval ECC failing data low 32 bits +*/ +uint32_t rameccmu_monitor_failing_data_low_bits_get(rameccmu_monitor_enum rameccmu_monitor) +{ + return RAMECCMU_MXFDL(rameccmu_monitor); +} + +/*! + \brief get RAMECCMU monitor ECC failing data high 32 bits + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[out] none + \retval ECC failing data high 32 bits +*/ +uint32_t rameccmu_monitor_failing_data_high_bits_get(rameccmu_monitor_enum rameccmu_monitor) +{ + return RAMECCMU_MXFDH(rameccmu_monitor); +} + +/*! + \brief get RAMECCMU monitor failing ECC error code + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[out] none + \retval ECC failing error code +*/ +uint32_t rameccmu_monitor_failing_ecc_error_code_get(rameccmu_monitor_enum rameccmu_monitor) +{ + return RAMECCMU_MXFECODE(rameccmu_monitor); +} + +/*! + \brief enable RAMECCMU global ECC interruput + \param[in] rameccmu_periph: RAMECCMU + only one parameter can be selected which is shown as below: + \arg RAMECCMU0: RAMECCMU for region 0 + \arg RAMECCMU1: RAMECCMU for region 1 + \param[in] interrupt: global ECC interruput + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_INT_ECC_GLOBAL_ERROR: ECC global error interrupt + \arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt + \param[out] none + \retval none +*/ +void rameccmu_global_interrupt_enable(uint32_t rameccmu_periph, uint32_t interrupt) +{ + RAMECCMU_INT(rameccmu_periph) |= interrupt; +} + +/*! + \brief disable RAMECCMU global ECC interruput + \param[in] rameccmu_periph: RAMECCMU + only one parameter can be selected which is shown as below: + \arg RAMECCMU0: RAMECCMU for region 0 + \arg RAMECCMU1: RAMECCMU for region 1 + \param[in] interrupt: global ECC interruput + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_INT_ECC_GLOBAL_ERROR: ECC global error interrupt + \arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt + \param[out] none + \retval none +*/ +void rameccmu_global_interrupt_disable(uint32_t rameccmu_periph, uint32_t interrupt) +{ + RAMECCMU_INT(rameccmu_periph) &= (uint32_t)(~interrupt); +} + +/*! + \brief enable RAMECCMU monitor ECC error interruput + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[in] monitor_interrupt: RAMECCMU monitor interruput + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt + \arg RAMECCMU_INT_ECC_ERROR_LATCHING: ECC error latching + \param[out] none + \retval none +*/ +void rameccmu_monitor_interrupt_enable(rameccmu_monitor_enum rameccmu_monitor, uint32_t monitor_interrupt) +{ + RAMECCMU_MXCTL(rameccmu_monitor) |= (uint32_t)monitor_interrupt << 1U; +} + +/*! + \brief disable RAMECCMU monitor ECC error interruput + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[in] monitor_interrupt: RAMECCMU monitor interruput + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt + \arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt + \arg RAMECCMU_INT_ECC_ERROR_LATCHING: ECC error latching + \param[out] none + \retval none +*/ +void rameccmu_monitor_interrupt_disable(rameccmu_monitor_enum rameccmu_monitor, uint32_t monitor_interrupt) +{ + RAMECCMU_MXCTL(rameccmu_monitor) &= (uint32_t)~((uint32_t)monitor_interrupt << 1U); +} + +/*! + \brief get RAMECCMU monitor ECC error flag + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[in] flag: RAMECCMU monitor flag + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag + \arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag + \arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag + \param[out] none + \retval RESET or SET +*/ +FlagStatus rameccmu_monitor_flag_get(rameccmu_monitor_enum rameccmu_monitor, uint32_t flag) +{ + if(RESET != ((RAMECCMU_MXSTAT(rameccmu_monitor)) & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear RAMECCMU monitor ECC error flag + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[in] flag: RAMECCMU monitor flag + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag + \arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag + \arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag + \param[out] none + \retval none +*/ +void rameccmu_monitor_flag_clear(rameccmu_monitor_enum rameccmu_monitor, uint32_t flag) +{ + RAMECCMU_MXSTAT(rameccmu_monitor) &= (uint32_t)(~flag); +} + +/*! + \brief get RAMECCMU monitor ECC interrupt error flag + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[in] int_flag: RAMECCMU monitor flag + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_INT_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag + \arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag + \arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag + \param[out] none + \retval none +*/ +FlagStatus rameccmu_monitor_interrupt_flag_get(rameccmu_monitor_enum rameccmu_monitor, uint32_t int_flag) +{ + uint32_t ret1 = RESET; + uint32_t ret2 = RESET; + + /* get the status of interrupt enable bit */ + ret1 = RAMECCMU_MXCTL(rameccmu_monitor) & (uint32_t)(int_flag << 2U); + /* get the status of interrupt flag */ + ret2 = RAMECCMU_MXSTAT(rameccmu_monitor) & int_flag; + + if(ret1 && ret2) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear RAMECCMU monitor interrupt ECC error flag + \param[in] rameccmu_monitor: RAMECCMU monitor + only one parameter can be selected which is shown as below: + \arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0 + \arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1 + \arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2 + \arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3 + \arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4 + \arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0 + \arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1 + \arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2 + \param[in] int_flag: RAMECCMU monitor flag + one or more parameters can be selected which are shown as below: + \arg RAMECCMU_INT_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag + \arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag + \arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag + \param[out] none + \retval none +*/ +void rameccmu_monitor_interrupt_flag_clear(rameccmu_monitor_enum rameccmu_monitor, uint32_t int_flag) +{ + RAMECCMU_MXSTAT(rameccmu_monitor) &= (uint32_t)(~int_flag); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rcu.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rcu.c new file mode 100644 index 0000000000..3da02b1d82 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rcu.c @@ -0,0 +1,2755 @@ +/*! + \file gd32h7xx_rcu.c + \brief RCU driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_rcu.h" + +/* define clock source */ +#define SEL_IRC64MDIV ((uint16_t)0U) /* IRC64M is selected as CK_SYS */ +#define SEL_HXTAL ((uint16_t)1U) /* HXTAL is selected as CK_SYS */ +#define SEL_LPIRC4M ((uint16_t)2U) /* LPIRC4M is selected as CK_SYS */ +#define SEL_PLL0P ((uint16_t)3U) /* PLL0P is selected as CK_SYS */ +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0x000fffffU) + +/* RCU IRC64M and LPIRC4M adjust value mask and offset */ +#define RCU_IRC64M_ADJUST_MASK ((uint8_t)0x7FU) +#define RCU_LPIRC4M_ADJUST_MASK ((uint8_t)0x3FU) +#define RCU_LPIRC4M_ADJUST_OFFSET ((uint32_t)2U) +/* RCU_PLLxN, RCU_PLLxP, RCU_PLLxQ, RCU_PLLxR offset */ +#define RCU_PLLNOFFSET ((uint32_t)6U) +#define RCU_PLLPOFFSET ((uint32_t)16U) +#define RCU_PLLROFFSET ((uint32_t)24U) +#define RCU_PLL1QOFFSET ((uint32_t)8U) +#define RCU_PLL2QOFFSET ((uint32_t)16U) + +/* function to calculate the PLL output frequency*/ +static uint32_t rcu_pll_clock_freq_cal(uint32_t pllinputfreq, uint32_t pll_psc, uint32_t pll_n, uint32_t fracn, uint32_t pll_pqr); + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC64M */ + RCU_CTL |= RCU_CTL_IRC64MEN; + while(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)){ + } + + RCU_CFG0 &= ~RCU_CFG0_SCS; + + /* reset CFG0 register */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | + RCU_CFG0_RTCDIV | RCU_CFG0_APB3PSC | RCU_CFG0_APB4PSC | RCU_CFG0_I2C0SEL); + /* reset CTL register */ + RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLL0EN | RCU_CTL_PLL1EN + | RCU_CTL_PLL2EN); + RCU_CTL &= ~(RCU_CTL_HXTALBPS); + /* reset PLL0 register */ + RCU_PLL0 = 0x01002020U; + /* reset PLL1 register */ + RCU_PLL1 = 0x01012020U; + /* reset PLL2 register */ + RCU_PLL2 = 0x01012020U; + /* reset PLLALL register */ + RCU_PLLALL = 0x00000000U; + /* reset PLL0FRA register */ + RCU_PLL0FRA = 0x00000000U; + /* reset PLL1FRA register */ + RCU_PLL1FRA = 0x00000000U; + /* reset PLL2FRA register */ + RCU_PLL2FRA = 0x00000000U; + /* reset INT register */ + RCU_INT = 0x14ff0000U; + /* reset ADDINT register */ + RCU_ADDINT = 0x00700000U; + /* reset CFG1 register */ + RCU_CFG1 = 0x00003F00U; + /* reset CFG2 register */ + RCU_CFG2 = 0x00000000U; + /* reset CFG3 register */ + RCU_CFG3 = 0x00000000U; + /* reset CFG4 register */ + RCU_CFG4 = 0x00000000U; + /* reset CFG5 register */ + RCU_CFG5 = 0x00000000U; +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_ENETx (x = 0,1): ENET1x clock + \arg RCU_ENETxTX (x = 0,1): ENET1TX xclock + \arg RCU_ENETxRX (x = 0,1): ENET1RXx clock + \arg RCU_ENETxPTP (x = 0,1): ENET1PTP clock + \arg RCU_USBHSx (x = 0,1): USBHS clock + \arg RCU_USBHSxULPI (x = 0,1): USBHSULPI clock + \arg RCU_DMAx (x = 0,1): DMA clock + \arg RCU_DMAMUX: DMAMUX clock + \arg RCU_DCI: DCI clock + \arg RCU_FAC: FAC clock + \arg RCU_SDIOx (x = 0,1): SDIO clock + \arg RCU_CAU: CAU clock + \arg RCU_HAU: HAU clock + \arg RCU_TRNG: TRNG clock + \arg RCU_TMU: TMU clock + \arg RCU_RAMECCMUx (x = 0,1): RAMECCMU clock + \arg RCU_EXMC: EXMC clock + \arg RCU_IPA: IPA clock + \arg RCU_MDMA: MDMMA clock + \arg RCU_OSPIM: OSPIM clock + \arg RCU_OSPIx (x = 0,1): OSPI0 clock + \arg RCU_RTDECx (x = 0,1): RTDEC0 clock + \arg RCU_CPU: CPU clock + \arg RCU_GPIOx (x = A,B,C,D,E,F,G,H,J,K): GPIO ports clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_CRC: CRC clock + \arg RCU_HWSEM: HWSEM clock + \arg RCU_TIMERx (x = 0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): TIMER clock + \arg RCU_RSPDIF: RSPDIF clock + \arg RCU_SPIx (x = 0,1,2,3,4,5): SPI clock + \arg RCU_MDIO: MDIO clock + \arg RCU_USARTx (x = 0,1,2,5): USART clock + \arg RCU_UARTx (x = 3,4,6,7): UART clock + \arg RCU_I2Cx (x = 0,1,2,3): I2C clock + \arg RCU_CTC: CTC clock + \arg RCU_DACHOLD: DACHOLD clock + \arg RCU_DAC: DAC clock + \arg RCU_ADCx (x = 0,1,2): ADC clock + \arg RCU_HPDF: HPDF clock + \arg RCU_SAIx (x = 0,1,2): SAI clock + \arg RCU_EDOUT: EDOUT clock + \arg RCU_TRIGSEL: TRIGSEL clock + \arg RCU_TLI: TLI clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_CMP: CMP clock + \arg RCU_VREF: VREF clock + \arg RCU_LPDTS: LPDTS clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC clock + \arg RCU_CANx (x = 0,1,2): can clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_enable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_ENETx (x = 0,1): ENET clock + \arg RCU_ENETxTX (x = 0,1): ENETTX clock + \arg RCU_ENETxRX (x = 0,1): ENETRX clock + \arg RCU_ENETxPTP (x = 0,1): ENETPTP clock + \arg RCU_USBHSx (x = 0,1): USBHS clock + \arg RCU_USBHSxULPI (x = 0,1): USBHSULPI clock + \arg RCU_DMAx (x = 0,1): DMA clock + \arg RCU_DMAMUX: DMAMUX clock + \arg RCU_DCI: DCI clock + \arg RCU_FAC: FAC clock + \arg RCU_SDIOx (x = 0,1): SDIO clock + \arg RCU_CAU: CAU clock + \arg RCU_HAU: HAU clock + \arg RCU_TRNG: TRNG clock + \arg RCU_TMU: TMU clock + \arg RCU_RAMECCMUx (x = 0,1): RAMECCMU clock + \arg RCU_EXMC: EXMC clock + \arg RCU_IPA: IPA clock + \arg RCU_MDMA: MDMMA clock + \arg RCU_OSPIM: OSPIM clock + \arg RCU_OSPIx (x = 0,1): OSPI0 clock + \arg RCU_RTDECx (x = 0,1): RTDEC0 clock + \arg RCU_CPU: CPU clock + \arg RCU_GPIOx (x = A,B,C,D,E,F,G,H,J,K): GPIO ports clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_CRC: CRC clock + \arg RCU_HWSEM: HWSEM clock + \arg RCU_TIMERx (x = 0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): TIMER clock + \arg RCU_RSPDIF: RSPDIF clock + \arg RCU_SPIx (x = 0,1,2,3,4,5): SPI clock + \arg RCU_MDIO: MDIO clock + \arg RCU_USARTx (x = 0,1,2,5): USART clock + \arg RCU_UARTx (x = 3,4,6,7): UART clock + \arg RCU_I2Cx (x = 0,1,2,3): I2C clock + \arg RCU_CTC: CTC clock + \arg RCU_DACHOLD: DACHOLD clock + \arg RCU_DAC: DAC clock + \arg RCU_ADCx (x = 0,1,2): ADC clock + \arg RCU_HPDF: HPDF clock + \arg RCU_SAIx (x = 0,1,2): SAI clock + \arg RCU_EDOUT: EDOUT clock + \arg RCU_TRIGSEL: TRIGSEL clock + \arg RCU_TLI: TLI clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_CMP: CMP clock + \arg RCU_VREF: VREF clock + \arg RCU_LPDTS: LPDTS clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC clock + \arg RCU_CANx (x = 0,1,2): can clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_disable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief enable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_ENETx_SLP (x = 0,1): ENET clock + \arg RCU_ENETxTX_SLP (x = 0,1): ENETTX clock + \arg RCU_ENETxRX_SLP (x = 0,1): ENETRX clock + \arg RCU_ENETxPTP_SLP (x = 0,1): ENETPTP clock + \arg RCU_USBHSx_SLP (x = 0,1): USBHS clock + \arg RCU_USBHSxULPI_SLP (x = 0,1): USBHSULPI clock + \arg RCU_SRAM0_SLP: SRAM0 clock + \arg RCU_SRAM1_SLP: SRAM1 clock + \arg RCU_DMAx_SLP (x = 0,1): DMA clock + \arg RCU_DMAMUX_SLP: DMAMUX clock + \arg RCU_DCI_SLP: DCI clock + \arg RCU_FAC_SLP: TRNG clock + \arg RCU_SDIOx_SLP (x = 0,1): SDIO clock + \arg RCU_CAU_SLP: CAU clock + \arg RCU_HAU_SLP: HAU clock + \arg RCU_TRNG_SLP: TRNG clock + \arg RCU_TMU_SLP: TMU clock + \arg RCU_RAMECCMUx_SLP (x = 0,1): RAMECCMU clock + \arg RCU_EXMC_SLP: EXMC clock + \arg RCU_IPA_SLP: IPA clock + \arg RCU_SDIOx_SLP (x = 0,1): SDIO clock + \arg RCU_MDMA_SLP: MDMMA clock + \arg RCU_OSPIM_SLP: OSPIM clock + \arg RCU_OSPIx_SLP (x = 0,1): OSPI0 clock + \arg RCU_RTDECx_SLP (x = 0,1): RTDEC0 clock + \arg RCU_AXISRAM_SLP: AXISRAM clock + \arg RCU_FMC_SLP: SRAM1 clock + \arg RCU_GPIOx_SLP (x = A,B,C,D,E,F,G,H,J,K): GPIO ports clock + \arg RCU_BKPSRAM_SLP: BKPSRAM clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_TIMERx_SLP (x = 0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): TIMER clock + \arg RCU_RSPDIF_SLP: RSPDIF clock + \arg RCU_SPIx_SLP (x = 0,1,2,3,4,5): SPI clock + \arg RCU_MDIO_SLP: MDIO clock + \arg RCU_USARTx_SLP (x = 0,1,2,5): USART clock + \arg RCU_UARTx_SLP (x = 3,4,6,7): UART clock + \arg RCU_I2Cx_SLP (x = 0,1,2,3): I2C clock + \arg RCU_CTC_SLP: CTC clock + \arg RCU_DACHOLD_SLP: DACHOLD clock + \arg RCU_DAC_SLP: DAC clock + \arg RCU_ADCx_SLP (x = 0,1,2): ADC clock + \arg RCU_HPDF_SLP: HPDF clock + \arg RCU_SAIx_SLP (x = 0,1,2): SAI clock + \arg RCU_EDOUT_SLP: EDOUT clock + \arg RCU_TRIGSEL_SLP: TRIGSEL clock + \arg RCU_TLI_SLP: TLI clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_CMP_SLP: CMP clock + \arg RCU_VREF_SLP: VREF clock + \arg RCU_LPDTS_SLP: LPDTS clock + \arg RCU_PMU_SLP: PMU clock + \arg RCU_CANx_SLP (x = 0,1,2): can clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_ENETx_SLP (x = 0,1): ENET clock + \arg RCU_ENETxTX_SLP (x = 0,1): ENETTX clock + \arg RCU_ENETxRX_SLP (x = 0,1): ENETRX clock + \arg RCU_ENETxPTP_SLP (x = 0,1): ENETPTP clock + \arg RCU_USBHSx_SLP (x = 0,1): USBHS clock + \arg RCU_USBHSxULPI_SLP (x = 0,1): USBHSULPI clock + \arg RCU_SRAM0_SLP: SRAM0 clock + \arg RCU_SRAM1_SLP: SRAM1 clock + \arg RCU_DMAx_SLP (x = 0,1): DMA clock + \arg RCU_DMAMUX_SLP: DMAMUX clock + \arg RCU_DCI_SLP: DCI clock + \arg RCU_FAC_SLP: TRNG clock + \arg RCU_SDIOx_SLP (x = 0,1): SDIO clock + \arg RCU_CAU_SLP: CAU clock + \arg RCU_HAU_SLP: HAU clock + \arg RCU_TRNG_SLP: TRNG clock + \arg RCU_TMU_SLP: TMU clock + \arg RCU_RAMECCMUx_SLP (x = 0,1): RAMECCMU clock + \arg RCU_EXMC_SLP: EXMC clock + \arg RCU_IPA_SLP: IPA clock + \arg RCU_SDIOx_SLP (x = 0,1): SDIO clock + \arg RCU_MDMA_SLP: MDMMA clock + \arg RCU_OSPIM_SLP: OSPIM clock + \arg RCU_OSPIx_SLP (x = 0,1): OSPI0 clock + \arg RCU_RTDECx_SLP (x = 0,1): RTDEC0 clock + \arg RCU_AXISRAM_SLP: AXISRAM clock + \arg RCU_FMC_SLP: SRAM1 clock + \arg RCU_GPIOx_SLP (x = A,B,C,D,E,F,G,H,J,K): GPIO ports clock + \arg RCU_BKPSRAM_SLP: BKPSRAM clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_TIMERx_SLP (x = 0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): TIMER clock + \arg RCU_RSPDIF_SLP: RSPDIF clock + \arg RCU_SPIx_SLP (x = 0,1,2,3,4,5): SPI clock + \arg RCU_MDIO_SLP: MDIO clock + \arg RCU_USARTx_SLP (x = 0,1,2,5): USART clock + \arg RCU_UARTx_SLP (x = 3,4,6,7): UART clock + \arg RCU_I2Cx_SLP (x = 0,1,2,3): I2C clock + \arg RCU_CTC_SLP: CTC clock + \arg RCU_DACHOLD_SLP: DACHOLD clock + \arg RCU_DAC_SLP: DAC clock + \arg RCU_ADCx_SLP (x = 0,1,2): ADC clock + \arg RCU_HPDF_SLP: HPDF clock + \arg RCU_SAIx_SLP (x = 0,1,2): SAI clock + \arg RCU_EDOUT_SLP: EDOUT clock + \arg RCU_TRIGSEL_SLP: TRIGSEL clock + \arg RCU_TLI_SLP: TLI clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_CMP_SLP: CMP clock + \arg RCU_VREF_SLP: VREF clock + \arg RCU_LPDTS_SLP: LPDTS clock + \arg RCU_PMU_SLP: PMU clock + \arg RCU_CANx_SLP (x = 0,1,2): can clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief reset the peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_ENETxRST (x = 0,1): reset ENET + \arg RCU_USBHSxRST (x = 0,1): reset USBHS + \arg RCU_DMAxRST (x = 0,1): reset DMA + \arg RCU_DMAMUXRST: reset DMAMUX + \arg RCU_DCIRST: reset DCI + \arg RCU_FACRST: reset FAC + \arg RCU_SDIOxRST (x = 0,1): reset SDIO + \arg RCU_CAURST: reset CAU + \arg RCU_HAURST: reset HAU + \arg RCU_TRNGRST: reset TRNG + \arg RCU_TMURST: reset TMU + \arg RCU_EXMCRST: reset EXMC + \arg RCU_IPARST: reset IPA + \arg RCU_MDMARST: reset MDMA + \arg RCU_OSPIMRST (x = 0,1): reset OSPIM + \arg RCU_OSPIxRST (x = 0,1): reset OSPI + \arg RCU_RTDECxRST (x = 0,1): reset RTDEC + \arg RCU_GPIOxRST (x = A,B,C,D,E,F,G,H,J,K): reset GPIO ports + \arg RCU_CRCRST: reset CRC + \arg RCU_HWSEMRST: reset HWSEM + \arg RCU_TIMERxRST (x = 0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): reset TIMER + \arg RCU_RSPDIFRST: reset RSPDIF + \arg RCU_SPIxRST (x = 0,1,2,3,4,5): reset SPI + \arg RCU_MDIORST: reset MDIO + \arg RCU_USARTxRST (x = 0,1,2,5): reset USART + \arg RCU_UARTxRST (x = 3,4,6,7): reset UART + \arg RCU_I2CxRST (x = 0,1,2,3): reset I2C + \arg RCU_CTCRST: reset CTC + \arg RCU_DACHOLDRST: reset DACHOLD + \arg RCU_DACRST: reset DAC + \arg RCU_ADCxRST (x = 0,1,2): reset ADC + \arg RCU_HPDFRST: reset HPDF + \arg RCU_SAIxRST (x = 0,1,2): reset SAI + \arg RCU_EDOUTRST: reset EDOUT + \arg RCU_TRIGSELRST: reset TRIGSEL + \arg RCU_TLIRST: reset TLI + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_CMPRST: reset CMP + \arg RCU_VREFRST: reset VREF + \arg RCU_LPDTSRST: reset LPDTS + \arg RCU_PMURST: reset PMU + \arg RCU_CANxRST (x = 0,1,2): reset CAN + \param[out] none + \retval none +*/ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief disable reset the peripheral + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_ENETxRST (x = 0,1): reset ENET + \arg RCU_USBHSxRST (x = 0,1): reset USBHS + \arg RCU_DMAxRST (x = 0,1): reset DMA + \arg RCU_DMAMUXRST: reset DMAMUX + \arg RCU_DCIRST: reset DCI + \arg RCU_FACRST: reset FAC + \arg RCU_SDIOxRST (x = 0,1): reset SDIO + \arg RCU_CAURST: reset CAU + \arg RCU_HAURST: reset HAU + \arg RCU_TRNGRST: reset TRNG + \arg RCU_TMURST: reset TMU + \arg RCU_EXMCRST: reset EXMC + \arg RCU_IPARST: reset IPA + \arg RCU_MDMARST : reset MDMA + \arg RCU_OSPIMRST (x = 0,1): reset OSPIM + \arg RCU_OSPIxRST (x = 0,1): reset OSPI + \arg RCU_RTDECxRST (x = 0,1): reset RTDEC + \arg RCU_GPIOxRST (x = A,B,C,D,E,F,G,H,J,K): reset GPIO ports + \arg RCU_CRCRST: reset CRC + \arg RCU_HWSEMRST: reset HWSEM + \arg RCU_TIMERxRST (x = 0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): reset TIMER + \arg RCU_RSPDIFRST: reset RSPDIF + \arg RCU_SPIxRST (x = 0,1,2,3,4,5): reset SPI + \arg RCU_MDIORST: reset MDIO + \arg RCU_USARTxRST (x = 0,1,2,5): reset USART + \arg RCU_UARTxRST (x = 3,4,6,7): reset UART + \arg RCU_I2CxRST (x = 0,1,2,3): reset I2C + \arg RCU_CTCRST: reset CTC + \arg RCU_DACHOLDRST: reset DACHOLD + \arg RCU_DACRST: reset DAC + \arg RCU_ADCxRST (x = 0,1,2): reset ADC + \arg RCU_HPDFRST: reset HPDF + \arg RCU_SAIxRST (x = 0,1,2): reset SAI + \arg RCU_EDOUTRST: reset EDOUT + \arg RCU_TRIGSELRST: reset TRIGSEL + \arg RCU_TLIRST: reset TLI + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_CMPRST: reset CMP + \arg RCU_VREFRST: reset VREF + \arg RCU_LPDTSRST: reset LPDTS + \arg RCU_PMURST: reset PMU + \arg RCU_CANxRST (x = 0,1,2): reset CAN + \param[out] none + \retval none +*/ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief reset the BKP + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP reset + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_disable(void) +{ + RCU_BDCTL &= ~RCU_BDCTL_BKPRST; +} + +/*! + \brief configure the system clock source + \param[in] ck_sys: system clock source select + only one parameter can be selected which is shown as below: + \arg RCU_CKSYSSRC_IRC64MDIV: select CK_IRC64MDIV as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_LPIRC4M: select CK_LPIRC4M as the CK_SYS source + \arg RCU_CKSYSSRC_PLL0P: select CK_PLL0P as the CK_SYS source + \param[out] none + \retval none +*/ +void rcu_system_clock_source_config(uint32_t ck_sys) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + reg &= ~RCU_CFG0_SCS; + RCU_CFG0 = (reg | ck_sys); +} + +/*! + \brief get the system clock source + \param[in] none + \param[out] none + \retval which clock is selected as CK_SYS source + \arg RCU_SCSS_IRC64MDIV: CK_IRC64MDIV is selected as the CK_SYS source + \arg RCU_SCSS_HXTAL: CK_HXTAL is selected as the CK_SYS source + \arg RCU_SCSS_LPIRC4M: CK_LPIRC4M is selected as the CK_SYS source + \arg RCU_SCSS_PLL0P: CK_PLL0P is selected as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & RCU_CFG0_SCSS); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_AHB_CKSYS_DIVx: (x = 1, 2, 4, 8, 16, 64, 128, 256, 512): CK_AHB is CK_SYS/x + \param[out] none + \retval none +*/ +void rcu_ahb_clock_config(uint32_t ck_ahb) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the AHBPSC bits and set according to ck_ahb */ + reg &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (reg | ck_ahb); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1 + \arg RCU_APB1_CKAHB_DIV2: select CK_AHB / 2 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV4: select CK_AHB / 4 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV8: select CK_AHB / 8 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV16: select CK_AHB / 16 as CK_APB1 + \param[out] none + \retval none +*/ +void rcu_apb1_clock_config(uint32_t ck_apb1) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the APB1PSC and set according to ck_apb1 */ + reg &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (reg | ck_apb1); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2 + \arg RCU_APB2_CKAHB_DIV2: select CK_AHB / 2 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV4: select CK_AHB / 4 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV8: select CK_AHB / 8 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV16: select CK_AHB / 16 as CK_APB2 + \param[out] none + \retval none +*/ +void rcu_apb2_clock_config(uint32_t ck_apb2) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the APB2PSC and set according to ck_apb2 */ + reg &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (reg | ck_apb2); +} + +/*! + \brief configure the APB3 clock prescaler selection + \param[in] ck_apb3: APB3 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB3_CKAHB_DIV1: select CK_AHB as CK_APB3 + \arg RCU_APB3_CKAHB_DIV2: select CK_AHB / 2 as CK_APB3 + \arg RCU_APB3_CKAHB_DIV4: select CK_AHB / 4 as CK_APB3 + \arg RCU_APB3_CKAHB_DIV8: select CK_AHB / 8 as CK_APB3 + \arg RCU_APB3_CKAHB_DIV16: select CK_AHB/ 16 as CK_APB3 + \param[out] none + \retval none +*/ +void rcu_apb3_clock_config(uint32_t ck_apb3) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the APB3PSC and set according to ck_apb3 */ + reg &= ~RCU_CFG0_APB3PSC; + RCU_CFG0 = (reg | ck_apb3); +} + +/*! + \brief configure the APB4 clock prescaler selection + \param[in] ck_apb4: APB4 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB4_CKAHB_DIV1: select CK_AHB as CK_APB4 + \arg RCU_APB4_CKAHB_DIV2: select CK_AHB / 2 as CK_APB4 + \arg RCU_APB4_CKAHB_DIV4: select CK_AHB / 4 as CK_APB4 + \arg RCU_APB4_CKAHB_DIV8: select CK_AHB / 8 as CK_APB4 + \arg RCU_APB4_CKAHB_DIV16: select CK_AHB / 16 as CK_APB4 + \param[out] none + \retval none +*/ +void rcu_apb4_clock_config(uint32_t ck_apb4) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the APB4PSC and set according to ck_apb4 */ + reg &= ~RCU_CFG0_APB4PSC; + RCU_CFG0 = (reg | ck_apb4); +} + +/*! + \brief configure the CK_OUT0 clock source and divider + \param[in] ckout0_src: CK_OUT0 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUT0SRC_IRC64MDIV: IRC64M selected + \arg RCU_CKOUT0SRC_LXTAL: LXTAL selected + \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT0SRC_PLL0P: PLL0P selected + \arg RCU_CKOUT0SRC_IRC48M: IRC48M selected + \arg RCU_CKOUT0SRC_PER: PER selected + \arg RCU_CKOUT0SRC_USBHS060M: USBHS0 60M selected + \arg RCU_CKOUT0SRC_USBHS160M: USBHS1 60M selected + \param[in] ckout0_div: CK_OUT0 divider + \arg RCU_CKOUT0_DIVx (x = 1,2,3,...15): CK_OUT0 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div) +{ + uint32_t reg; + + reg = RCU_CFG2; + /* reset the CKOUT0SRC, CKOUT0DIV and set according to ckout0_src and ckout0_div */ + reg &= ~(RCU_CFG2_CKOUT0SEL | RCU_CFG2_CKOUT0DIV); + RCU_CFG2 = (reg | ckout0_src | ckout0_div); +} + +/*! + \brief configure the CK_OUT1 clock source and divider + \param[in] ckout1_src: CK_OUT1 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUT1SRC_SYSTEMCLOCK: system clock selected + \arg RCU_CKOUT1SRC_PLL1R: PLL1R selected + \arg RCU_CKOUT1SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT1SRC_PLL0P: PLL0P selected + \arg RCU_CKOUT1SRC_LPIRC4M: LPIRC4M selected + \arg RCU_CKOUT1SRC_IRC32K: IRC32K selected + \arg RCU_CKOUT1SRC_PLL2R: PLL2R selected + \param[in] ckout1_div: CK_OUT1 divider + \arg RCU_CKOUT1_DIVx (x = 1,2,3,....15): CK_OUT1 is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div) +{ + uint32_t reg; + + reg = RCU_CFG2; + /* reset the CKOUT1SRC, CKOUT1DIV and set according to ckout1_src and ckout1_div */ + reg &= ~(RCU_CFG2_CKOUT1SEL | RCU_CFG2_CKOUT1DIV); + RCU_CFG2 = (reg | ckout1_src | ckout1_div); +} + +/*! + \brief configure the pll input and output clock range + \param[in] pll_idx: IDX_PLL, IDX_PLLx (x = 0,1,2) + \param[in] ck_input: input clock range + only one parameter can be selected which is shown as below: + \arg RCU_PLLxRNG_1M_2M (x = 0,1,2): input clock frequency: 1-2MHz + \arg RCU_PLLxRNG_2M_4M (x = 0,1,2): input clock frequency: 2-4MHz + \arg RCU_PLLxRNG_4M_8M (x = 0,1,2): input clock frequency: 4-8MHz + \arg RCU_PLLxRNG_8M_16M: input clock frequency: 8-16MHz + \param[in] ck_output: output clock range + only one parameter can be selected which is shown as below: + \arg RCU_PLLxVCO_192M_836M (x = 0,1,2): select wide VCO, range: 192-836MHz + \arg RCU_PLLxVCO_150M_420M (x = 0,1,2): select narrow VCO, range: 150-420MHz + \param[out] none + \retval none +*/ +void rcu_pll_input_output_clock_range_config(pll_idx_enum pll_idx, uint32_t ck_input, uint32_t ck_output) +{ + switch(pll_idx) { + case IDX_PLL0: + /* reset the PLLRNG/PLLVCOSEL bits and set according to ck_input/ck_output */ + RCU_PLLALL &= ~(RCU_PLLALL_PLL0RNG | RCU_PLLALL_PLL0VCOSEL); + RCU_PLLALL |= (ck_input | ck_output); + break; + case IDX_PLL1: + /* reset the PLLRNG/PLLVCOSEL bits and set according to ck_input/ck_output */ + RCU_PLLALL &= ~(RCU_PLLALL_PLL1RNG | RCU_PLLALL_PLL1VCOSEL); + RCU_PLLALL |= (ck_input | ck_output); + break; + case IDX_PLL2: + /* reset the PLLRNG/PLLVCOSEL bits and set according to ck_input/ck_output */ + RCU_PLLALL &= ~(RCU_PLLALL_PLL2RNG | RCU_PLLALL_PLL2VCOSEL); + RCU_PLLALL |= (ck_input | ck_output); + break; + default: + break; + } +} + +/*! + \brief configure fractional part of the multiplication factor for PLL VCO + \param[in] pll_idx: IDX_PLL, IDX_PLLx (x = 0,1,2) + \param[in] pll_fracn: fractional part of the multiplication factor + \arg this parameter should be selected between 0 and 8191 + \param[out] none + \retval none +*/ +void rcu_pll_fractional_config(pll_idx_enum pll_idx, uint32_t pll_fracn) +{ + switch(pll_idx) { + case IDX_PLL0: + /* reset the PLLFRAN and set according to pll_fracn */ + RCU_PLL0FRA &= ~(RCU_PLL0FRA_PLL0FRAN); + RCU_PLL0FRA |= pll_fracn; + break; + case IDX_PLL1: + /* reset the PLLFRAN and set according to pll_fracn */ + RCU_PLL1FRA &= ~(RCU_PLL1FRA_PLL1FRAN); + RCU_PLL1FRA |= pll_fracn; + break; + case IDX_PLL2: + /* reset the PLLFRAN and set according to pll_fracn */ + RCU_PLL2FRA &= ~(RCU_PLL2FRA_PLL2FRAN); + RCU_PLL2FRA |= pll_fracn; + break; + default: + break; + } +} + +/*! + \brief PLL fractional latch enable + \param[in] pll_idx: IDX_PLL,IDX_PLLx (x = 0,1,2) + \param[out] none + \retval none +*/ +void rcu_pll_fractional_latch_enable(pll_idx_enum pll_idx) +{ + switch(pll_idx) { + case IDX_PLL0: + /* set the PLL0FRAEN */ + RCU_PLL0FRA |= RCU_PLL0FRA_PLL0FRAEN ; + break; + case IDX_PLL1: + /* set the PLL1FRAEN */ + RCU_PLL1FRA |= RCU_PLL1FRA_PLL1FRAEN ; + break; + case IDX_PLL2: + /* set the PLL2FRAEN */ + RCU_PLL2FRA |= RCU_PLL2FRA_PLL2FRAEN ; + break; + default: + break; + } +} + +/*! + \brief PLL fractional latch disable + \param[in] pll_idx: IDX_PLL, IDX_PLLx (x = 1,2) + \param[out] none + \retval none +*/ +void rcu_pll_fractional_latch_disable(pll_idx_enum pll_idx) +{ + switch(pll_idx) { + case IDX_PLL0: + /* reset the PLL0FRAEN */ + RCU_PLL0FRA &= ~RCU_PLL0FRA_PLL0FRAEN ; + break; + case IDX_PLL1: + /* reset the PLL1FRAEN */ + RCU_PLL1FRA &= ~RCU_PLL1FRA_PLL1FRAEN ; + break; + case IDX_PLL2: + /* reset the PLL2FRAEN */ + RCU_PLL2FRA &= ~RCU_PLL2FRA_PLL2FRAEN ; + break; + default: + break; + } +} + +/*! + \brief configure PLL clock source + \param[in] pll_src: PLL clock source selection + \arg RCU_PLLSRC_IRC64MDIV: select IRC64MDIV as PLL source clock + \arg RCU_PLLSRC_LPIRC4M: select LPIRC4M as PLL source clock + \arg RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock + \param[out] none + \retval none +*/ +void rcu_pll_source_config(uint32_t pll_src) +{ + /* PLL clock source selection */ + RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL); + RCU_PLLALL |= pll_src; +} + +/*! + \brief configure the main PLL0 clock + \param[in] pll0_psc: the PLL0 VCO source clock prescaler + \arg this parameter should be selected between 1 and 63. When pll0_psc=0, the PLL0 VCO source clock prescaler close. + \param[in] pll0_n: the PLL0 VCO clock multi factor + \arg this parameter should be selected between 9 and 512 + \param[in] pll0_p: the PLL0P output frequency division factor from PLL0 VCO clock + \arg this parameter should be selected between 1 and 128 + \param[in] pll0_q: the PLL0 Q output frequency division factor from PLL0 VCO clock + \arg this parameter should be selected between 1 and 128 + \param[in] pll0_r: the PLL0 R output frequency division factor from PLL0 VCO clock + \arg this parameter should be selected between 1 and 128 + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_pll0_config(uint32_t pll0_psc, uint32_t pll0_n, uint32_t pll0_p, uint32_t pll0_q, uint32_t pll0_r) +{ + /* check the function parameter */ + if(CHECK_PLL0_PSC_VALID(pll0_psc) && CHECK_PLL0_N_VALID(pll0_n) && + CHECK_PLL0_P_VALID(pll0_p) && CHECK_PLL0_Q_VALID(pll0_q) && + CHECK_PLL0_R_VALID(pll0_r)) { + RCU_PLL0 &= ~(RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0N | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R); + RCU_PLL0 |= pll0_psc | ((pll0_n - 1U) << RCU_PLLNOFFSET) | ((pll0_p - 1U) << RCU_PLLPOFFSET) | + ((pll0_r - 1U) << RCU_PLLROFFSET); + RCU_PLLADDCTL &= ~RCU_PLLADDCTL_PLL0Q; + RCU_PLLADDCTL |= (pll0_q - 1U); + } else { + /* return status */ + return ERROR; + } + + /* return status */ + return SUCCESS; +} + +/*! + \brief configure the PLL1 clock + \param[in] pll1_psc: the PLL1 VCO source clock prescaler + \arg this parameter should be selected between 1 and 63. When pll1_psc = 0,the PLL1 VCO source clock prescaler close. + \param[in] pll1_n: the PLL1 VCO clock multi factor + \arg this parameter should be selected between 9 and 512 + \param[in] pll1_p: the PLL1 P output frequency division factor from PLL1 VCO clock + \arg this parameter should be selected between 1 and 128 + \param[in] pll1_q: the PLL1 Q output frequency division factor from PLL1 VCO clock + \arg this parameter should be selected between 1 and 128 + \param[in] pll1_r: the PLL1 R output frequency division factor from PLL1 VCO clock + \arg this parameter should be selected between 1 and 128 + + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_pll1_config(uint32_t pll1_psc, uint32_t pll1_n, uint32_t pll1_p, uint32_t pll1_q, uint32_t pll1_r) +{ + /* check the function parameter */ + if(CHECK_PLL1_PSC_VALID(pll1_psc) && CHECK_PLL1_N_VALID(pll1_n) && + CHECK_PLL1_P_VALID(pll1_p) && CHECK_PLL1_Q_VALID(pll1_q) && + CHECK_PLL1_R_VALID(pll1_r)) { + RCU_PLL1 = (pll1_psc | ((pll1_n - 1U) << RCU_PLLNOFFSET) | ((pll1_p - 1U) << RCU_PLLPOFFSET) | + ((pll1_r - 1U) << RCU_PLLROFFSET)); + RCU_PLLADDCTL &= ~RCU_PLLADDCTL_PLL1Q; + RCU_PLLADDCTL |= ((pll1_q - 1U) << RCU_PLL1QOFFSET); + } else { + /* return status */ + return ERROR; + } + + /* return status */ + return SUCCESS; +} + +/*! + \brief configure the PLL2 clock + \param[in] pll2_psc: the PLL2 VCO source clock prescaler + \arg this parameter should be selected between 0 and 63. When pll2_psc = 0,the PLL2 VCO source clock prescaler close + \param[in] pll2_n: the PLL2 VCO clock multi factor + \arg this parameter should be selected between 9 and 512 + \param[in] pll2_p: the PLL2 P output frequency division factor from PLL2 VCO clock + \arg this parameter should be selected between 1 and 128 + \param[in] pll2_q: the PLL2 Q output frequency division factor from PLL2 VCO clock + \arg this parameter should be selected between 1 and 128 + \param[in] pll2_r: the PLL2 R output frequency division factor from PLL2 VCO clock + \arg this parameter should be selected between 1 and 128 + + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_pll2_config(uint32_t pll2_psc, uint32_t pll2_n, uint32_t pll2_p, uint32_t pll2_q, uint32_t pll2_r) +{ + /* check the function parameter */ + if(CHECK_PLL2_PSC_VALID(pll2_psc) && CHECK_PLL2_N_VALID(pll2_n) && + CHECK_PLL2_P_VALID(pll2_p) && CHECK_PLL2_R_VALID(pll2_q) && + CHECK_PLL2_R_VALID(pll2_r)) { + RCU_PLL2 = (pll2_psc | ((pll2_n - 1U) << RCU_PLLNOFFSET) | ((pll2_p - 1U) << RCU_PLLPOFFSET) | + ((pll2_r - 1U) << RCU_PLLROFFSET)); + RCU_PLLADDCTL &= ~RCU_PLLADDCTL_PLL2Q; + RCU_PLLADDCTL |= ((pll2_q - 1U) << RCU_PLL2QOFFSET); + } else { + /* return status */ + return ERROR; + } + + /* return status */ + return SUCCESS; +} + +/*! + \brief enable the pllp pllq pllr divider output + \param[in] pllxy: the output pll enable + \arg RCU_PLL0P: PLL0P divider output enable + \arg RCU_PLL0Q: PLL0Q divider output enable + \arg RCU_PLL0R: PLL0R divider output enable + \arg RCU_PLL1P: PLL1P divider output enable + \arg RCU_PLL1Q: PLL1Q divider output enable + \arg RCU_PLL1R: PLL1R divider output enable + \arg RCU_PLL2P: PLL2P divider output enable + \arg RCU_PLL2Q: PLL2Q divider output enable + \arg RCU_PLL2R: PLL2R divider output enable + \param[out] none + \retval none +*/ +void rcu_pll_clock_output_enable(uint32_t pllxy) +{ + /* PLL divider output enable */ + RCU_PLLADDCTL |= pllxy; +} + +/*! + \brief disable the pllp pllq pllr divider output + \param[in] pllxy: the output pll disable + \arg RCU_PLL0P: PLL0P divider output disable + \arg RCU_PLL0Q: PLL0Q divider output disable + \arg RCU_PLL0R: PLL0R divider output disable + \arg RCU_PLL1P: PLL1P divider output disable + \arg RCU_PLL1Q: PLL1Q divider output disable + \arg RCU_PLL1R: PLL1R divider output disable + \arg RCU_PLL2P: PLL2P divider output disable + \arg RCU_PLL2Q: PLL2Q divider output disable + \arg RCU_PLL2R: PLL2R divider output disable + \param[out] none + \retval none +*/ +void rcu_pll_clock_output_disable(uint32_t pllxy) +{ + /* PLL divider output disable */ + RCU_PLLADDCTL &= ~(pllxy); +} + +/*! + \brief configure the PLLUSBHS0 clock + \param[in] pllusb_presel: PLLUSBHSPRE clock selection + \arg this parameter should be selected RCU_PLLUSBHSPRE_HXTAL or RCU_PLLUSBHSPRE_IRC48M + \param[in] pllusb_predv: the divider factor from PLLUSBHS clock + \arg this parameter should be selected between RCU_PLLUSBHSPRE_DIVx (x = 1...15) + \param[in] pllusb_mf: PLLUSBHS0 clock multiplication factor + \arg this parameter should be selected RCU_PLLUSBHS_MULx (x = 16,17...127) + \param[in] usbhsdv: the divider factor from USBHSDV clock + \arg this parameter should be selected RCU_USBHS_DIVx (x = 2,4...16) + + \param[out] none + \retval none +*/ +void rcu_pllusb0_config(uint32_t pllusb_presel, uint32_t pllusb_predv, uint32_t pllusb_mf, uint32_t usbhsdv) +{ + /* configure PLLUSBHS source selection */ + RCU_USBCLKCTL &= ~(RCU_USBCLKCTL_PLLUSBHS0PRESEL); + RCU_USBCLKCTL |= (pllusb_presel); + + RCU_PLLUSBCFG &= ~(RCU_PLLUSBCFG_PLLUSBHS0PREDV | RCU_PLLUSBCFG_USBHS0DV | RCU_PLLUSBCFG_PLLUSBHS0MF); + RCU_PLLUSBCFG |= (pllusb_predv | usbhsdv | pllusb_mf); +} + +/*! + \brief configure the PLLUSBHS1 clock + \param[in] pllusb_presel: PLLUSBHSPRE clock selection + \arg this parameter should be selected RCU_PLLUSBHSPRE_HXTAL or RCU_PLLUSBHSPRE_IRC48M + \param[in] pllusb_predv: the divider factor from PLLUSBHS clock + \arg this parameter should be selected between RCU_PLLUSBHSPRE_DIVx (x = 1...15) + \param[in] pllusb_mf: PLLUSBHS1 clock multiplication factor + \arg this parameter should be selected RCU_PLLUSBHS_MULx (x = 16,17..127) + \param[in] usbhsdv: the divider factor from USBHSDV clock + \arg this parameter should be selected RCU_USBHS_DIVx (x = 2,4...16) + + \param[out] none + \retval none +*/ +void rcu_pllusb1_config(uint32_t pllusb_presel, uint32_t pllusb_predv, uint32_t pllusb_mf, uint32_t usbhsdv) +{ + /* configure pllusb source selection */ + RCU_USBCLKCTL &= ~(RCU_USBCLKCTL_PLLUSBHS1PRESEL); + RCU_USBCLKCTL |= ((pllusb_presel << 8U)); + + RCU_PLLUSBCFG &= ~(RCU_PLLUSBCFG_PLLUSBHS1PREDV | RCU_PLLUSBCFG_USBHS1DV | RCU_PLLUSBCFG_PLLUSBHS1MF); + RCU_PLLUSBCFG |= ((pllusb_predv << 16U) | (usbhsdv << 16U) | (pllusb_mf << 16U)); +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_RTCSRC_NONE: no clock selected + \arg RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock + \arg RCU_RTCSRC_IRC32K: CK_IRC32K selected as RTC source clock + \arg RCU_RTCSRC_HXTAL_DIV_RTCDIV: CK_HXTAL / RTCDIV selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + uint32_t reg; + + reg = RCU_BDCTL; + /* reset the RTCSRC bits and set according to rtc_clock_source */ + reg &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL = (reg | rtc_clock_source); +} + +/*! + \brief configure the frequency division of RTC clock when HXTAL was selected as its clock source + \param[in] rtc_div: RTC clock frequency division + only one parameter can be selected which is shown as below: + \arg RCU_RTC_HXTAL_NONE: no clock for RTC + \arg RCU_RTC_HXTAL_DIVx: RTCDIV clock select CK_HXTAL / x (x = 2,3...63) + \param[out] none + \retval none +*/ +void rcu_rtc_div_config(uint32_t rtc_div) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the RTCDIV bits and set according to rtc_div value */ + reg &= ~RCU_CFG0_RTCDIV; + RCU_CFG0 = (reg | rtc_div); +} + +/*! + \brief configure the CK48M clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] ck48m_clock_source: CK48M clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CK48MSRC_PLL48M: CK_PLL48M selected as CK48M source clock + \arg RCU_CK48MSRC_IRC48M: CK_IRC48M selected as CK48M source clock + \param[out] none + \retval none +*/ +void rcu_ck48m_clock_config(uint32_t ck48m_clock_source) +{ + uint32_t reg; + + reg = RCU_ADDCTL0; + /* reset the CK48MSEL bit and set according to ck48m_clock_source */ + reg &= ~RCU_ADDCTL0_CK48MSEL; + RCU_ADDCTL0 = (reg | ck48m_clock_source); +} + +/*! + \brief configure the PLL48M clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] pll48m_clock_source: PLL48M clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PLL48MSRC_PLL0Q: CK_PLL0Q selected as PLL48M source clock + \arg RCU_PLL48MSRC_PLL2P: CK_PLL2P selected as PLL48M source clock + \param[out] none + \retval none +*/ +void rcu_pll48m_clock_config(uint32_t pll48m_clock_source) +{ + uint32_t reg; + + reg = RCU_ADDCTL0; + /* reset the PLL48MSEL bit and set according to pll48m_clock_source */ + reg &= ~RCU_ADDCTL0_PLL48MSEL; + RCU_ADDCTL0 = (reg | pll48m_clock_source); +} + +/*! + \brief configure the IRC64M clock divider selection + \param[in] ck_irc64mdiv: IRC64M clock divider selection + only one parameter can be selected which is shown as below: + \arg RCU_IRC64M_DIV1: CK_IRC64M / 1 + \arg RCU_IRC64M_DIV2: CK_IRC64M / 2 + \arg RCU_IRC64M_DIV4: CK_IRC64M / 4 + \arg RCU_IRC64M_DIV8: CK_IRC64M / 8 + \param[out] none + \retval none +*/ +void rcu_irc64mdiv_clock_config(uint32_t ck_irc64mdiv) +{ + uint32_t reg; + + reg = RCU_ADDCTL1; + /* reset the IRC64MDIV and set according to ck_irc64mdiv */ + reg &= ~RCU_ADDCTL1_IRC64MDIV; + RCU_ADDCTL1 = (reg | ck_irc64mdiv); +} +/*! + \brief get the irc64mdiv clock + \param[in] none + \param[out] none + \retval clock frequency of irc64mdiv: 64000000, 32000000, 16000000, 8000000 +*/ +uint32_t rcu_irc64mdiv_freq_get(void) +{ + uint32_t irc64m_freq = 0U; + + /* CK_IRC64MDIV = CK_IRC64M/1/2/4/8 */ + if(RCU_IRC64M_DIV1 == (RCU_ADDCTL1 & RCU_ADDCTL1_IRC64MDIV)) { + irc64m_freq = IRC64M_VALUE; + } else if(RCU_IRC64M_DIV2 == (RCU_ADDCTL1 & RCU_ADDCTL1_IRC64MDIV)) { + irc64m_freq = IRC64M_VALUE / 2U; + } else if(RCU_IRC64M_DIV4 == (RCU_ADDCTL1 & RCU_ADDCTL1_IRC64MDIV)) { + irc64m_freq = IRC64M_VALUE / 4U; + } else if(RCU_IRC64M_DIV8 == (RCU_ADDCTL1 & RCU_ADDCTL1_IRC64MDIV)) { + irc64m_freq = IRC64M_VALUE / 8U; + } else { + } + + return irc64m_freq; +} + +/*! + \brief configure the TIMER clock prescaler selection + \param[in] timer_clock_prescaler: TIMER clock selection + only one parameter can be selected which is shown as below: + \arg RCU_TIMER_PSC_MUL2: if APB1PSC / APB2PSC in RCU_CFG0 register is 0b0xx (CK_APBx = CK_AHB) + or 0b100 (CK_APBx = CK_AHB / 2), the TIMER clock is equal to CK_AHB (CK_TIMERx = CK_AHB). + or else, the TIMER clock is twice the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 2 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 2 x CK_APB2) + \arg RCU_TIMER_PSC_MUL4: if APB1PSC / APB2PSC in RCU_CFG0 register is 0b0xx(CK_APBx = CK_AHB), + 0b100 (CK_APBx = CK_AHB / 2), or 0b101 (CK_APBx = CK_AHB / 4), the TIMER clock is equal to CK_AHB (CK_TIMERx = CK_AHB). + or else, the TIMER clock is four timers the corresponding APB clock (TIMER in APB1 domain: CK_TIMERx = 4 x CK_APB1; + TIMER in APB2 domain: CK_TIMERx = 4 x CK_APB2) + \param[out] none + \retval none +*/ +void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler) +{ + /* configure the TIMERSEL bit and select the TIMER clock prescaler */ + if(timer_clock_prescaler == RCU_TIMER_PSC_MUL2) { + RCU_CFG1 &= timer_clock_prescaler; + } else { + RCU_CFG1 |= timer_clock_prescaler; + } +} + +/*! + \brief configure the SPI / I2S clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] spi_idx: IDX_SPIx (x = 0,1,2,3,4,5) + \param[in] ck_spi: SPI0 / SPI1 / SPI2 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_SPISRC_PLL0Q: CK_SPI select PLL0Q + \arg RCU_SPISRC_PLL1P: CK_SPI select PLL1P + \arg RCU_SPISRC_PLL2P: CK_SPI select PLL2P + \arg RCU_SPISRC_I2S_CKIN: CK_SPI select I2SCKIN + \arg RCU_SPISRC_PER: CK_SPI select PER + \param[in] ck_spi: SPI3 / SPI4 / SPI5 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_SPISRC_APB2: CK_SPI select CKAPB2 + \arg RCU_SPISRC_PLL1Q: CK_SPI select PLL1Q + \arg RCU_SPISRC_PLL2Q: CK_SPI select PLL2Q + \arg RCU_SPISRC_IRC64MDIV: CK_SPI select IRC64MDIV + \arg RCU_SPISRC_LPIRC4M: CK_SPI select LPIRC4M + \arg RCU_SPISRC_HXTAL: CK_SPI select HXTAL + \arg RCU_SPI5SRC_I2S_CKIN: CK_SPI select I2SCKIN (only for SPI5) + \param[out] none + \retval none +*/ +void rcu_spi_clock_config(spi_idx_enum spi_idx, uint32_t ck_spi) +{ + switch(spi_idx) { + case IDX_SPI0: + /* reset the SPI0SEL bits and set according to ck_spi */ + RCU_CFG5 &= ~RCU_CFG5_SPI0SEL; + RCU_CFG5 |= (uint32_t)ck_spi ; + break; + case IDX_SPI1: + /* reset the SPI1SEL bits and set according to ck_spi */ + RCU_CFG5 &= ~RCU_CFG5_SPI1SEL; + RCU_CFG5 |= (uint32_t)ck_spi << 4U ; + break; + case IDX_SPI2: + /* reset the SPI2SEL bits and set according to ck_spi */ + RCU_CFG5 &= ~RCU_CFG5_SPI2SEL; + RCU_CFG5 |= (uint32_t)ck_spi << 8U; + break; + case IDX_SPI3: + /* reset the SPI3SEL bits and set according to ck_spi */ + RCU_CFG5 &= ~RCU_CFG5_SPI3SEL; + RCU_CFG5 |= (uint32_t)ck_spi ; + break; + case IDX_SPI4: + /* reset the SPI4SEL bits and set according to ck_spi */ + RCU_CFG5 &= ~RCU_CFG5_SPI4SEL; + RCU_CFG5 |= (uint32_t)ck_spi << 4U; + break; + case IDX_SPI5: + /* reset the SPI5SEL bits and set according to ck_spi */ + RCU_CFG5 &= ~RCU_CFG5_SPI5SEL; + RCU_CFG5 |= (uint32_t)ck_spi << 8U; + break; + default: + break; + } +} + +/*! + \brief configure the SDIO clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] sdio_idx: IDX_SDIOx (x = 0,1) + \param[in] ck_sdio: SDIO clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_SDIO0SRC_PLL0Q: CK_SDIO0 select PLL0Q (only for SDIO0) + \arg RCU_SDIO0SRC_PLL1R: CK_SDIO0 select PLL1R (only for SDIO0) + \arg RCU_SDIO1SRC_PLL0Q: CK_SDIO1 select PLL0Q (only for SDIO1) + \arg RCU_SDIO1SRC_PLL1R: CK_SDIO1 select PLL1R (only for SDIO1) + \param[out] none + \retval none +*/ +void rcu_sdio_clock_config(sdio_idx_enum sdio_idx, uint32_t ck_sdio) +{ + switch(sdio_idx) { + case IDX_SDIO0: + /* reset the SDIO0SEL bits and set according to ck_sdio */ + RCU_CFG4 &= ~RCU_CFG4_SDIO0SEL; + RCU_CFG4 |= (uint32_t)ck_sdio; + break; + case IDX_SDIO1: + /* reset the SDIO1SEL bits and set according to ck_sdio */ + RCU_CFG3 &= ~RCU_CFG3_SDIO1SEL; + RCU_CFG3 |= (uint32_t)ck_sdio; + break; + default: + break; + } +} + +/*! + \brief configure the Deep-sleep wakeup system clock source selection + \param[in] ck_dspwussel: Deep-sleep wakeup system clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_DSPWUSSEL_IRC64MDIV: ck_dspwussel select IRC64MDIV + \arg RCU_DSPWUSSEL_LPIRC4M: ck_dspwussel select LPIRC4M + \param[out] none + \retval none +*/ +void rcu_deepsleep_wakeup_sys_clock_config(uint32_t ck_dspwussel) +{ + /* reset the DSPWUSSEL bits and set according to ck_dspwussel */ + RCU_CFG3 &= ~RCU_CFG3_DSPWUSSEL; + RCU_CFG3 |= ck_dspwussel; +} + +/*! + \brief configure the PLL2R divider used as input of TLI + \param[in] pll2_r_div: PLL2R divider used as input of TLI + only one parameter can be selected which is shown as below: + \arg RCU_PLL2R_DIVx (x = 2,4,8,16): PLL2R divided x used as input of TLI + \param[out] none + \retval none +*/ +void rcu_tli_clock_div_config(uint32_t pll2_r_div) +{ + uint32_t reg; + + reg = RCU_CFG1; + /* reset the PLL2RDIV bit and set according to pll2_r_div */ + reg &= ~RCU_CFG1_PLL2RDIV; + RCU_CFG1 = (reg | pll2_r_div); +} + +/*! + \brief configure the USARTx (x = 0,1,2,5) clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] usart_idx: IDX_USARTx (x = 0,1,2,5) + \param[in] ck_usart: USART clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_USARTSRC_APB: CK_USART select CK_APB1(USART1 / USART2) or CK_APB2(USART0 / USART5) + \arg RCU_USARTSRC_AHB: CK_USART select CK_AHB + \arg RCU_USARTSRC_LXTAL: CK_USART select CK_LXTAL + \arg RCU_USARTSRC_IRC64MDIV: CK_USART select CK_IRC64MDIV + \param[out] none + \retval none +*/ +void rcu_usart_clock_config(usart_idx_enum usart_idx, uint32_t ck_usart) +{ + switch(usart_idx) { + case IDX_USART0: + /* reset the USART0SEL bits and set according to ck_usart */ + RCU_CFG1 &= ~RCU_CFG1_USART0SEL; + RCU_CFG1 |= ck_usart; + break; + case IDX_USART1: + /* reset the USART1SEL bits and set according to ck_usart */ + RCU_CFG1 &= ~RCU_CFG1_USART1SEL; + RCU_CFG1 |= (uint32_t)ck_usart << 18U; + break; + case IDX_USART2: + /* reset the USART2SEL bits and set according to ck_usart */ + RCU_CFG1 &= ~RCU_CFG1_USART2SEL; + RCU_CFG1 |= (uint32_t)ck_usart << 20U; + break; + case IDX_USART5: + /* reset the USART5SEL bits and set according to ck_usart */ + RCU_CFG1 &= ~RCU_CFG1_USART5SEL; + RCU_CFG1 |= (uint32_t)ck_usart << 22U; + break; + default: + break; + } +} + +/*! + \brief configure the I2Cx (x = 0,1,2,3) clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] i2c_idx: IDX_I2Cx (x = 0,1,2,3) + \param[in] ck_i2c: I2C clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_I2CSRC_APB1: CK_I2C select CK_APB1 + \arg RCU_I2CSRC_PLL2R: CK_I2C select CK_PLL2R + \arg RCU_I2CSRC_IRC64MDIV: CK_I2C select CK_IRC64MDIV + \arg RCU_I2CSRC_LPIRC4M: CK_I2C select CK_LPIRC4M + \param[out] none + \retval none +*/ +void rcu_i2c_clock_config(i2c_idx_enum i2c_idx, uint32_t ck_i2c) +{ + switch(i2c_idx) { + case IDX_I2C0: + /* reset the I2C0SEL bits and set according to ck_i2c */ + RCU_CFG0 &= ~RCU_CFG0_I2C0SEL; + RCU_CFG0 |= ck_i2c << 30U; + break; + case IDX_I2C1: + /* reset the I2C1SEL bits and set according to ck_i2c */ + RCU_CFG3 &= ~RCU_CFG3_I2C1SEL; + RCU_CFG3 |= (uint32_t)ck_i2c; + break; + case IDX_I2C2: + /* reset the I2C2SEL bits and set according to ck_i2c */ + RCU_CFG3 &= ~RCU_CFG3_I2C2SEL; + RCU_CFG3 |= (uint32_t)ck_i2c << 2U; + break; + case IDX_I2C3: + /* reset the I2C4SEL bits and set according to ck_i2c */ + RCU_CFG3 &= ~RCU_CFG3_I2C3SEL; + RCU_CFG3 |= (uint32_t)ck_i2c << 4U; + break; + default: + break; + } +} + +/*! + \brief configure the CANx (x = 0,1,2) clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] can_idx: IDX_CANx (x = 0,1,2) + \param[in] ck_can: CAN clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CANSRC_HXTAL: CK_CAN select CK_HXTAL + \arg RCU_CANSRC_APB2: CK_CAN select CK_APB2 + \arg RCU_CANSRC_APB2_DIV2: CK_CAN select CK_APB2 / 2 + \arg RCU_CANSRC_IRC64MDIV: CK_CAN select CK_IRC64MDIV + \param[out] none + \retval none +*/ +void rcu_can_clock_config(can_idx_enum can_idx, uint32_t ck_can) +{ + switch(can_idx) { + case IDX_CAN0: + /* reset the CAN0SEL bits and set according to ck_can */ + RCU_CFG1 &= ~RCU_CFG1_CAN0SEL; + RCU_CFG1 |= ck_can ; + break; + case IDX_CAN1: + /* reset the CAN1SEL bits and set according to ck_can */ + RCU_CFG1 &= ~RCU_CFG1_CAN1SEL; + RCU_CFG1 |= (uint32_t)ck_can << 2U; + break; + case IDX_CAN2: + /* reset the CAN2SEL bits and set according to ck_can */ + RCU_CFG1 &= ~RCU_CFG1_CAN2SEL; + RCU_CFG1 |= (uint32_t)ck_can << 4U; + break; + default: + break; + } +} + +/*! + \brief configure the ADCx (x = 0,1,2) clock source selection + \param[in] adc_idx: IDX_ADCx (x = 0,1,2) + \param[in] ck_adc: ADC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_ADCSRC_PLL1P: CK_ADC select CK_PLL1P + \arg RCU_ADCSRC_PLL2R: CK_ADC select CK_PLL2R + \arg RCU_ADCSRC_PER: CK_ADC select CK_PER + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(adc_idx_enum adc_idx, uint32_t ck_adc) +{ + switch(adc_idx) { + case IDX_ADC0: + case IDX_ADC1: + /* reset the ADC0SEL/ADC1SEL bits and set according to ck_adc */ + RCU_CFG3 &= ~RCU_CFG3_ADC01SEL; + RCU_CFG3 |= ck_adc ; + break; + case IDX_ADC2: + /* reset the ADC2SEL bits and set according to ck_adc */ + RCU_CFG3 &= ~RCU_CFG3_ADC2SEL; + RCU_CFG3 |= (uint32_t)ck_adc << 2U; + break; + default: + break; + } +} + +/*! + \brief configure the SAIx (x = 0,1) clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] can_idx: IDX_SAIx (x = 0,1) + \param[in] ck_sai: SAI clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_SAISRC_PLL0Q: CK_SAI select CK_PLL0Q + \arg RCU_SAISRC_PLL1P: CK_SAI select CK_PLL2R + \arg RCU_SAISRC_PLL2P: CK_SAI select CK_PLL2P + \arg RCU_SAISRC_I2S_CKIN: CK_SAI select CK_PLL2R + \arg RCU_SAISRC_PER: CK_SAI select CK_PER + \param[out] none + \retval none +*/ +void rcu_sai_clock_config(sai_idx_enum sai_idx, uint32_t ck_sai) +{ + switch(sai_idx) { + case IDX_SAI0: + /* reset the SAI0SEL bits and set according to ck_sai */ + RCU_CFG2 &= ~RCU_CFG2_SAI0SEL; + RCU_CFG2 |= ck_sai ; + break; + case IDX_SAI1: + /* reset the SAI1SEL bits and set according to ck_sai */ + RCU_CFG2 &= ~RCU_CFG2_SAI1SEL; + RCU_CFG2 |= ck_sai << 4U; + break; + default: + break; + } +} + +/*! + \brief configure the SAI2Bx (x = 0,1) clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] sai2b_idx: IDX_SAI2Bx (x = 0,1) + \param[in] ck_sai2b: SAI clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_SAI2BSRC_PLL0Q: CK_SAI2B select CK_PLL0Q + \arg RCU_SAI2BSRC_PLL1P: CK_SAI2B select CK_PLL2R + \arg RCU_SAI2BSRC_PLL2P: CK_SAI2B select CK_PLL2P + \arg RCU_SAI2BSRC_I2S_CKIN: CK_SAI2B select I2S_CKIN + \arg RCU_SAI2BSRC_PER: CK_SAI2B select CK_PER + \arg RCU_SAI2BSRC_RSPDIF_SYMB: CK_SAI2B select CK_RSPDIF_SYMB + \param[out] none + \retval none +*/ +void rcu_sai2_block_clock_config(sai2b_idx_enum sai2b_idx, uint32_t ck_sai2b) +{ + switch(sai2b_idx) { + case IDX_SAI2B0: + /* reset the SAI2B0SEL bits and set according to ck_sai2b */ + RCU_CFG2 &= ~RCU_CFG2_SAI2B0SEL; + RCU_CFG2 |= ck_sai2b ; + break; + case IDX_SAI2B1: + /* reset the SAI2B1SEL bits and set according to ck_sai2b */ + RCU_CFG2 &= ~RCU_CFG2_SAI2B1SEL; + RCU_CFG2 |= ck_sai2b << 4U ; + break; + default: + break; + } +} + +/*! + \brief configure the RSPDIF clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] ck_rspdif: RSPDIF clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_RSPDIFSRC_PLL0Q: CK_RSPDIF select CK_PLL0Q + \arg RCU_RSPDIFSRC_PLL1R: CK_RSPDIF select CK_PLL1R + \arg RCU_RSPDIFSRC_PLL2R: CK_RSPDIF select CK_PLL2R + \arg RCU_RSPDIFSRC_IRC64MDIV: CK_RSPDIF select CK_IRC64MDIV + \param[out] none + \retval none +*/ +void rcu_rspdif_clock_config(uint32_t ck_rspdif) +{ + /* reset the RSPDIFSEL bits and set according to ck_rspdif */ + RCU_CFG1 &= ~RCU_CFG1_RSPDIFSEL; + RCU_CFG1 |= ck_rspdif; +} + +/*! + \brief configure the EXMC clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] ck_exmc: EXMC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_EXMCSRC_AHB: CK_EXMC select CK_AHB + \arg RCU_EXMCSRC_PLL0Q: CK_EXMC select CK_PLL0Q + \arg RCU_EXMCSRC_PLL1R: CK_EXMC select CK_PLL1R + \arg RCU_EXMCSRC_PER: CK_EXMC select CK_PER + \param[out] none + \retval none +*/ +void rcu_exmc_clock_config(uint32_t ck_exmc) +{ + /* reset the EXMCSEL bits and set according to ck_exmc */ + RCU_CFG4 &= ~(RCU_CFG4_EXMCSEL); + RCU_CFG4 |= ck_exmc ; +} + +/*! + \brief configure the HPDF clock source selection (need to check the target clock whether to ready before enabling or switching dynamically) + \param[in] ck_hpdf: HPDF clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_HPDFSRC_APB2: CK_HPDF select CK_APB2 + \arg RCU_HPDFSRC_AHB: CK_HPDF select CK_AHB + \param[out] none + \retval none +*/ +void rcu_hpdf_clock_config(uint32_t ck_hpdf) +{ + /* reset the HPDFSEL bits and set according to ck_hpdf */ + RCU_CFG1 &= ~RCU_CFG1_HPDFSEL; + RCU_CFG1 |= ck_hpdf ; +} + +/*! + \brief configure the PER clock source selection + \param[in] ck_per: PER clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PERSRC_IRC64MDIV: CK_PER select CK_IRC64MDIV + \arg RCU_PERSRC_LPIRC4M: CK_PER select CK_LPIRC4M + \arg RCU_PERSRC_HXTAL: CK_PER select CK_HXTAL + \param[out] none + \retval none +*/ +void rcu_per_clock_config(uint32_t ck_per) +{ + /* reset the PERSEL bits and set according to ck_per */ + RCU_CFG1 &= ~RCU_CFG1_PERSEL; + RCU_CFG1 |= ck_per ; +} + +/*! + \brief configure the PLL1Q prescaler + \param[in] usbhs_idx: IDX_USBHSx (x = 0,1) + \param[in] ck_usbhspsc: USBHS clock prescaler from CK_PLL1Q + only one parameter can be selected which is shown as below: + \arg RCU_USBHSPSC_DIV1: CK_PLL1Q / 1 + \arg RCU_USBHSPSC_DIV2: CK_PLL1Q / 2 + \arg RCU_USBHSPSC_DIV3: CK_PLL1Q / 3 + \arg RCU_USBHSPSC_DIV4: CK_PLL1Q / 4 + \arg RCU_USBHSPSC_DIV5: CK_PLL1Q / 5 + \arg RCU_USBHSPSC_DIV6: CK_PLL1Q / 6 + \arg RCU_USBHSPSC_DIV7: CK_PLL1Q / 7 + \arg RCU_USBHSPSC_DIV8: CK_PLL1Q / 8 + \param[out] none + \retval none +*/ +void rcu_usbhs_pll1qpsc_config(usbhs_idx_enum usbhs_idx, uint32_t ck_usbhspsc) +{ + switch(usbhs_idx) { + case IDX_USBHS0: + /* reset the USBHS0PSC bits and set according to ck_usbhspsc */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS0PSC; + RCU_USBCLKCTL |= ck_usbhspsc ; + break; + case IDX_USBHS1: + /* reset the USBHS1PSC bits and set according to ck_usbhspsc */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS1PSC; + RCU_USBCLKCTL |= (ck_usbhspsc << 3U) ; + break; + default: + break; + } +} + +/*! + \brief configure the USBHS48MSEL clock source selection + \param[in] usbhs_idx: IDX_USBHSx (x = 0,1) + \param[in] ck_usb48m: USBHS48MSEL clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_USB48MSRC_PLL0R: CK_USB48M select CK_PLL0R + \arg RCU_USB48MSRC_PLLUSBHS: CK_USB48M select CK_PLLUSBHSx / USBHxSDV + \arg RCU_USB48MSRC_PLL1Q: CK_USB48M select CK_PLL1Q / USBHSxPSC + \arg RCU_USB48MSRC_IRC48M: CK_USB48M select CK_IRC48M + \param[out] none + \retval none +*/ +void rcu_usb48m_clock_config(usbhs_idx_enum usbhs_idx, uint32_t ck_usb48m) +{ + switch(usbhs_idx) { + case IDX_USBHS0: + /* reset the USB048MSEL bits and set according to ck_usb48m */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS048MSEL; + RCU_USBCLKCTL |= ck_usb48m ; + break; + case IDX_USBHS1: + /* reset the USB148MSEL bits and set according to ck_usb48m */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS148MSEL; + RCU_USBCLKCTL |= (ck_usb48m << 8U) ; + break; + default: + break; + } +} + +/*! + \brief configure the USBHSSEL clock source selection + \param[in] usbhs_idx: IDX_USBHSx (x = 0,1) + \param[in] ck_usbhs: USBHSSEL clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_USBHSSEL_48M: CK_USBHS select 48M + \arg RCU_USBHSSEL_60M: CK_USBHS select 60M + \param[out] none + \retval none +*/ +void rcu_usbhs_clock_config(usbhs_idx_enum usbhs_idx, uint32_t ck_usbhs) +{ + switch(usbhs_idx) { + case IDX_USBHS0: + /* reset the USBHS0SEL bits and set according to ck_usbhs */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS0SEL; + RCU_USBCLKCTL |= ck_usbhs ; + break; + case IDX_USBHS1: + /* reset the USBHS1SEL bits and set according to ck_usbhs */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS1SEL; + RCU_USBCLKCTL |= (ck_usbhs << 8U) ; + break; + default: + break; + } +} + +/*! + \brief enable the USBHS clock source selection + \param[in] usbhs_idx: IDX_USBHSx (x = 0,1) + \param[out] none + \retval none +*/ +void rcu_usbhs_clock_selection_enable(usbhs_idx_enum usbhs_idx) +{ + switch(usbhs_idx) { + case IDX_USBHS0: + /* set the USB0SWEN bit */ + RCU_USBCLKCTL |= RCU_USBCLKCTL_USBHS0SWEN; + break; + case IDX_USBHS1: + /* set the USB1SWEN bit */ + RCU_USBCLKCTL |= RCU_USBCLKCTL_USBHS1SWEN; + break; + default: + break; + } +} + +/*! + \brief disable the USBHS clock source selection + \param[in] usbhs_idx: IDX_USBxHS (x = 0,1) + \param[out] none + \retval none +*/ +void rcu_usbhs_clock_selection_disable(usbhs_idx_enum usbhs_idx) +{ + switch(usbhs_idx) { + case IDX_USBHS0: + /* reset the USB0SWEN bit */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS0SWEN; + break; + case IDX_USBHS1: + /* reset the USB1SWEN bit */ + RCU_USBCLKCTL &= ~RCU_USBCLKCTL_USBHS1SWEN; + break; + default: + break; + } +} + +/*! + \brief configure the LXTAL drive capability + \param[in] lxtal_dricap: drive capability of LXTAL + only one parameter can be selected which is shown as below: + \arg RCU_LXTAL_LOWDRI: lower driving capability + \arg RCU_LXTAL_MED_LOWDRI: middle driving capability + \arg RCU_LXTAL_MED_HIGHDRI: higher driving capability + \arg RCU_LXTAL_HIGHDRI: stronger driving capability + \param[out] none + \retval none +*/ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap) +{ + uint32_t reg; + + reg = RCU_BDCTL; + + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + reg &= ~RCU_BDCTL_LXTALDRI; + RCU_BDCTL = (reg | lxtal_dricap); +} + +/*! + \brief wait for oscillator stabilization flags is SET or oscillator startup is timeout + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC64M: IRC64M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_LPIRC4M: LPIRC4M + \arg RCU_PLL0_CK: PLL0 + \arg RCU_PLL1_CK: PLL1 + \arg RCU_PLL2_CK: PLL2 + \arg RCU_PLLUSBHS0_CK: PLLUSBHS0 + \arg RCU_PLLUSBHS1_CK: PLLUSBHS1 + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + + switch(osci) { + /* wait HXTAL stable */ + case RCU_HXTAL: + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)) { + reval = SUCCESS; + } + break; + /* wait LXTAL stable */ + case RCU_LXTAL: + while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)) { + reval = SUCCESS; + } + break; + /* wait IRC64M stable */ + case RCU_IRC64M: + while((RESET == osci_stat) && (IRC64M_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_IRC64MSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC64MSTB)) { + reval = SUCCESS; + } + break; + /* wait IRC48M stable */ + case RCU_IRC48M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_IRC48MSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)) { + reval = SUCCESS; + } + break; + /* wait IRC32K stable */ + case RCU_IRC32K: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_IRC32KSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC32KSTB)) { + reval = SUCCESS; + } + break; + /* wait LPIRC4M stable */ + case RCU_LPIRC4M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_LPIRC4MSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_LPIRC4MSTB)) { + reval = SUCCESS; + } + break; + /* wait PLL0 stable */ + case RCU_PLL0_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLL0STB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLL0STB)) { + reval = SUCCESS; + } + break; + /* wait PLL1 stable */ + case RCU_PLL1_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLL1STB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLL1STB)) { + reval = SUCCESS; + } + break; + /* wait PLL2 stable */ + case RCU_PLL2_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLL2STB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLL2STB)) { + reval = SUCCESS; + } + break; + /* wait PLLUSBHS0 stable */ + case RCU_PLLUSBHS0_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLLUSBHS0STB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLUSBHS0STB)) { + reval = SUCCESS; + } + break; + /* wait PLLUSBHS1 stable */ + case RCU_PLLUSBHS1_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLLUSBHS1STB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLUSBHS1STB)) { + reval = SUCCESS; + } + break; + default: + break; + } + + /* return value */ + return reval; +} + +/*! + \brief turn on the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC64M: IRC64M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_LPIRC4M: LPIRC4M + \arg RCU_PLL0_CK: PLL0 + \arg RCU_PLL1_CK: PLL1 + \arg RCU_PLL2_CK: PLL2 + \arg RCU_PLLUSBHS0_CK: PLLUSBHS0 + \arg RCU_PLLUSBHS1_CK: PLLUSBHS1 + \param[out] none + \retval none +*/ +void rcu_osci_on(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief turn off the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC64M: IRC64M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_LPIRC4M: LPIRC4M + \arg RCU_PLL0_CK: PLL + \arg RCU_PLL1_CK: PLL1 + \arg RCU_PLL2_CK: PLL2 + \arg RCU_PLLUSBHS0_CK: PLLUSBHS0 + \arg RCU_PLLUSBHS1_CK: PLLUSBHS1 + \param[out] none + \retval none +*/ +void rcu_osci_off(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator (HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator (LXTAL) + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + + switch(osci) { + /* enable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg | RCU_CTL_HXTALBPS); + break; + /* enable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator (HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator (LXTAL) + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + + switch(osci) { + /* disable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg & ~RCU_CTL_HXTALBPS); + break; + /* disable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg & ~RCU_BDCTL_LXTALBPS); + break; + default: + break; + } +} + +/*! + \brief set the IRC64M adjust value + \param[in] irc64M_adjval: IRC64M adjust value, must be between 0 and 0x7F + \arg 0x00 - 0x7F + \param[out] none + \retval none +*/ +void rcu_irc64m_adjust_value_set(uint32_t irc64m_adjval) +{ + uint32_t reg; + + reg = RCU_CTL; + /* reset the IRC64MADJ bits and set according to irc64m_adjval */ + reg &= ~RCU_CTL_IRC64MADJ; + RCU_CTL = (reg | ((irc64m_adjval & RCU_IRC64M_ADJUST_MASK))); +} + +/*! + \brief set the LPIRC4M adjust value + \param[in] lpirc4M_adjval: LPIRC4M adjust value, must be between 0 and 0x3F + \arg 0x00 - 0x3F + \param[out] none + \retval none +*/ +void rcu_lpirc4m_adjust_value_set(uint32_t lpirc4m_adjval) +{ + uint32_t reg; + + reg = RCU_ADDCTL1; + /* reset the LPIRC4MTRIM bits and set according to lpirc4M_adjval */ + reg &= ~RCU_ADDCTL1_LPIRC4MTRIM; + RCU_ADDCTL1 = (reg | ((lpirc4m_adjval & RCU_LPIRC4M_ADJUST_MASK) << RCU_LPIRC4M_ADJUST_OFFSET)); +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL |= RCU_CTL_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL &= ~RCU_CTL_CKMEN; +} + +/*! + \brief enable the LXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_clock_monitor_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_LCKMEN; +} + +/*! + \brief disable the LXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_clock_monitor_disable(void) +{ + RCU_BDCTL &= ~RCU_BDCTL_LCKMEN; +} + +/*! + \brief function to calculate the PLL output frequency + \param[in] pllinputfreq: PLL0 / PLL1 / PLL2 input frequency + \arg this parameter should be selected between HXTAL_VALUE,irc64mdiv_freq or LPIRC4M_VALUE + \param[in] pll_psc: the PLL0 / PLL1 / PLL2 source clock prescaler + \arg this parameter should be selected between 1 and 63. + \param[in] pll_n: the PLL0 / PLL1 / PLL2 clock multi factor + \arg this parameter should be selected between 9 and 512 + \param[in] fracn: Fractional part of the multiplication factor for PLL0 / PLL1 / PLL2 VCO + \arg this parameter should be selected between 0 and 0x1FFF + \param[in] pll_pqr: the PLL P / Q / R output frequency division factor from PLL0 / PLL1 / PLL2 VCO clock + \arg this parameter should be selected between 1 and 128 + + \param[out] none + \retval uint32_t: PLL clock frequency +*/ +static uint32_t rcu_pll_clock_freq_cal(uint32_t pllinputfreq, uint32_t pll_psc, uint32_t pll_n, uint32_t fracn, uint32_t pll_pqr) +{ + float freq; + + freq = ((float)pllinputfreq / (float)pll_psc) * ((float)pll_n + ((float)fracn / (float)0x2000)); + + freq = freq / (float)pll_pqr; + + return (uint32_t)freq; +} + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + only one parameter can be selected which is shown as below: + \arg CK_SYS: system clock frequency + \arg CK_AHB: AHB clock frequency + \arg CK_APB1: APB1 clock frequency + \arg CK_APB2: APB2 clock frequency + \arg CK_APB3: APB3 clock frequency + \arg CK_APB4: APB4 clock frequency + \arg CK_PLL0P: PLL0P clock frequency + \arg CK_PLL0Q: PLL0Q clock frequency + \arg CK_PLL0R: PLL0R clock frequency + \arg CK_PLL1P: PLL1P clock frequency + \arg CK_PLL1Q: PLL1Q clock frequency + \arg CK_PLL1R: PLL1R clock frequency + \arg CK_PLL2P: PLL1P clock frequency + \arg CK_PLL2Q: PLL1Q clock frequency + \arg CK_PLL2R: PLL1R clock frequency + \arg CK_PER: PER clock frequency + \arg CK_USART0: USART0 clock frequency + \arg CK_USART1: USART1 clock frequency + \arg CK_USART2: USART2 clock frequency + \arg CK_USART5: USART5 clock frequency + \arg CK_IRC64MDIV: IRC64MDIV clock frequency + \arg CK_HXTAL: HXTAL clock frequency + \arg CK_LPIRC4M: LPIRC4M clock frequency + \param[out] none + \retval uint32_t: clock frequency of system, AHB, APB1, APB2, APB3, APB4, PLL, PER, USART, IRC64MDIV, HXTAL, LPIRC4M +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws, ck_freq = 0U, irc64mdiv_freq = 0U, fracn = 0U; + uint32_t cksys_freq, ahb_freq, apb1_freq, apb2_freq, apb3_freq, apb4_freq; + uint32_t pll0p_freq, pll0q_freq, pll0r_freq, pll1p_freq, pll1q_freq, pll1r_freq, pll2p_freq, pll2q_freq, pll2r_freq, per_freq, persel; + uint32_t pll0psc, pll1psc, pll2psc, pll0n, pll1n, pll2n, pllsel, pll0p, pll0q, pll0r, pll1p, pll1q, pll1r, pll2p, pll2q, pll2r, ck_src, idx, clk_exp; + uint32_t usart_freq = 0U; + + /* exponent of AHB, APB1 and APB2 clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb3_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb4_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + + irc64mdiv_freq = rcu_irc64mdiv_freq_get(); + sws = GET_BITS(RCU_CFG0, 2, 3); + + switch(sws) { + /* IRC64MDIV is selected as CK_SYS */ + case SEL_IRC64MDIV: + cksys_freq = irc64mdiv_freq; + break; + /* LPIRC4M is selected as CK_SYS */ + case SEL_LPIRC4M: + cksys_freq = LPIRC4M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLL0P is selected as CK_SYS */ + case SEL_PLL0P: + /* get the value of PLL0PSC[5:0] */ + pll0psc = GET_BITS(RCU_PLL0, 0U, 5U); + pll0n = (GET_BITS(RCU_PLL0, 6U, 14U) + 1U); + pll0p = (GET_BITS(RCU_PLL0, 16U, 22U) + 1U); + + if((RCU_PLL0FRA & RCU_PLL0FRA_PLL0FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL0FRA, 0U, 12U); + } + + /* PLL clock source selection, HXTAL or IRC64MDIV */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + cksys_freq = rcu_pll_clock_freq_cal(ck_src, pll0psc, pll0n, fracn, pll0p); + break; + /* IRC64MDIV is selected as CK_SYS */ + default: + cksys_freq = irc64mdiv_freq; + break; + } + + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + ahb_freq = cksys_freq >> clk_exp; + + /* calculate APB1 clock frequency */ + idx = GET_BITS(RCU_CFG0, 10, 12); + clk_exp = apb1_exp[idx]; + apb1_freq = ahb_freq >> clk_exp; + + /* calculate APB2 clock frequency */ + idx = GET_BITS(RCU_CFG0, 13, 15); + clk_exp = apb2_exp[idx]; + apb2_freq = ahb_freq >> clk_exp; + + /* calculate APB3 clock frequency */ + idx = GET_BITS(RCU_CFG0, 27, 29); + clk_exp = apb3_exp[idx]; + apb3_freq = ahb_freq >> clk_exp; + + /* calculate APB4 clock frequency */ + idx = GET_BITS(RCU_CFG0, 24, 26); + clk_exp = apb4_exp[idx]; + apb4_freq = ahb_freq >> clk_exp; + + /* return the clocks frequency */ + switch(clock) { + case CK_SYS: + ck_freq = cksys_freq; + break; + case CK_AHB: + ck_freq = ahb_freq; + break; + case CK_APB1: + ck_freq = apb1_freq; + break; + case CK_APB2: + ck_freq = apb2_freq; + break; + case CK_APB3: + ck_freq = apb3_freq; + break; + case CK_APB4: + ck_freq = apb4_freq; + break; + case CK_PLL0P: + pll0p_freq = 0U; + /* calculate pllp clock frequency */ + pll0psc = GET_BITS(RCU_PLL0, 0U, 5U); + pll0n = (GET_BITS(RCU_PLL0, 6U, 14U) + 1U); + pll0p = (GET_BITS(RCU_PLL0, 16U, 22U) + 1U); + + if((RCU_PLL0FRA & RCU_PLL0FRA_PLL0FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL0FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll0psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL0PEN) != 0U) { + pll0p_freq = rcu_pll_clock_freq_cal(ck_src, pll0psc, pll0n, fracn, pll0p); + } + } + + ck_freq = pll0p_freq; + break; + case CK_PLL0R: + pll0r_freq = 0U; + /* calculate pllr clock frequency */ + pll0psc = GET_BITS(RCU_PLL0, 0U, 5U); + pll0n = (GET_BITS(RCU_PLL0, 6U, 14U) + 1U); + pll0r = (GET_BITS(RCU_PLL0, 24U, 30U) + 1U); + + if((RCU_PLL0FRA & RCU_PLL0FRA_PLL0FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL0FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll0psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL0REN) != 0U) { + pll0r_freq = rcu_pll_clock_freq_cal(ck_src, pll0psc, pll0n, fracn, pll0r); + } + } + + ck_freq = pll0r_freq; + break; + case CK_PLL0Q: + pll0q_freq = 0U; + /* calculate pllq clock frequency */ + pll0psc = GET_BITS(RCU_PLL0, 0U, 5U); + pll0n = (GET_BITS(RCU_PLL0, 6U, 14U) + 1U); + pll0q = (GET_BITS(RCU_PLLADDCTL, 0U, 6U) + 1U); + + if((RCU_PLL0FRA & RCU_PLL0FRA_PLL0FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL0FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll0psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL0QEN) != 0U) { + pll0q_freq = rcu_pll_clock_freq_cal(ck_src, pll0psc, pll0n, fracn, pll0q); + } + } + + ck_freq = pll0q_freq; + break; + case CK_PLL1P: + pll1p_freq = 0U; + /* calculate pll1p clock frequency */ + pll1psc = GET_BITS(RCU_PLL1, 0U, 5U); + pll1n = (GET_BITS(RCU_PLL1, 6U, 14U) + 1U); + pll1p = (GET_BITS(RCU_PLL1, 16U, 22U) + 1U); + + if((RCU_PLL1FRA & RCU_PLL1FRA_PLL1FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL1FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll1psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL1PEN) != 0U) { + pll1p_freq = rcu_pll_clock_freq_cal(ck_src, pll1psc, pll1n, fracn, pll1p); + } + } + + ck_freq = pll1p_freq; + break; + case CK_PLL1R: + pll1r_freq = 0U; + /* calculate pll1r clock frequency */ + pll1psc = GET_BITS(RCU_PLL1, 0U, 5U); + pll1n = (GET_BITS(RCU_PLL1, 6U, 14U) + 1U); + pll1r = (GET_BITS(RCU_PLL1, 24U, 30U) + 1U); + + if((RCU_PLL1FRA & RCU_PLL1FRA_PLL1FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL1FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll1psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL1REN) != 0U) { + pll1r_freq = rcu_pll_clock_freq_cal(ck_src, pll1psc, pll1n, fracn, pll1r); + } + } + + ck_freq = pll1r_freq; + break; + case CK_PLL1Q: + pll1q_freq = 0U; + /* calculate pll1q clock frequency */ + pll1psc = GET_BITS(RCU_PLL1, 0U, 5U); + pll1n = (GET_BITS(RCU_PLL1, 6U, 14U) + 1U); + pll1q = (GET_BITS(RCU_PLLADDCTL, 8U, 14U) + 1U); + + if((RCU_PLL1FRA & RCU_PLL1FRA_PLL1FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL1FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll1psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL1QEN) != 0U) { + pll1q_freq = rcu_pll_clock_freq_cal(ck_src, pll1psc, pll1n, fracn, pll1q); + } + } + + ck_freq = pll1q_freq; + break; + case CK_PLL2P: + pll2p_freq = 0U; + /* calculate pll2p clock frequency */ + pll2psc = GET_BITS(RCU_PLL2, 0U, 5U); + pll2n = (GET_BITS(RCU_PLL2, 6U, 14U) + 1U); + pll2p = (GET_BITS(RCU_PLL2, 16U, 22U) + 1U); + + if((RCU_PLL2FRA & RCU_PLL2FRA_PLL2FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL2FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll2psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL2PEN) != 0U) { + pll2p_freq = rcu_pll_clock_freq_cal(ck_src, pll2psc, pll2n, fracn, pll2p); + } + } + + ck_freq = pll2p_freq; + break; + case CK_PLL2R: + pll2r_freq = 0U; + /* calculate pll2r clock frequency */ + pll2psc = GET_BITS(RCU_PLL2, 0U, 5U); + pll2n = (GET_BITS(RCU_PLL2, 6U, 14U) + 1U); + pll2r = (GET_BITS(RCU_PLL2, 24U, 30U) + 1U); + + if((RCU_PLL2FRA & RCU_PLL2FRA_PLL2FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL2FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll2psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL2REN) != 0U) { + pll2r_freq = rcu_pll_clock_freq_cal(ck_src, pll2psc, pll2n, fracn, pll2r); + } + } + + ck_freq = pll2r_freq; + break; + case CK_PLL2Q: + pll2q_freq = 0U; + /* calculate pll2q clock frequency */ + pll2psc = GET_BITS(RCU_PLL2, 0U, 5U); + pll2n = (GET_BITS(RCU_PLL2, 6U, 14U) + 1U); + pll2q = (GET_BITS(RCU_PLLADDCTL, 16U, 22U) + 1U); + + if((RCU_PLL2FRA & RCU_PLL2FRA_PLL2FRAEN) != 0U) { + fracn = GET_BITS(RCU_PLL2FRA, 0U, 12U); + } + + /* PLL clock source selection (HXTAL, IRC64MDIV or LPIRC4M) */ + pllsel = (RCU_PLLALL & RCU_PLLALL_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == pllsel) { + ck_src = irc64mdiv_freq; + } else { + ck_src = LPIRC4M_VALUE; + } + + if((pll2psc != 0U) && (ck_src != 0U)) { + if((RCU_PLLADDCTL & RCU_PLLADDCTL_PLL2QEN) != 0U) { + pll2q_freq = rcu_pll_clock_freq_cal(ck_src, pll2psc, pll2n, fracn, pll2q); + } + } + + ck_freq = pll2q_freq; + break; + case CK_PER: + /* calculate peripheral clock frequency */ + persel = (RCU_CFG1 & RCU_CFG1_PERSEL); + + if(RCU_PERSRC_HXTAL == persel) { + per_freq = HXTAL_VALUE; + } else if(RCU_PLLSRC_IRC64MDIV == persel) { + per_freq = irc64mdiv_freq; + } else { + per_freq = LPIRC4M_VALUE; + } + + ck_freq = per_freq; + break; + case CK_USART0: + /* calculate USART0 clock frequency */ + if(RCU_USARTSRC_APB == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = apb2_freq; + } else if(RCU_USARTSRC_AHB == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = ahb_freq; + } else if(RCU_USARTSRC_LXTAL == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = LXTAL_VALUE; + } else if(RCU_USARTSRC_IRC64MDIV == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = irc64mdiv_freq; + } else { + } + + ck_freq = usart_freq; + break; + case CK_USART1: + /* calculate USART1 clock frequency */ + if((RCU_USARTSRC_APB << 18U) == (RCU_CFG1 & RCU_CFG1_USART1SEL)) { + usart_freq = apb1_freq; + } else if((RCU_USARTSRC_AHB << 18U) == (RCU_CFG1 & RCU_CFG1_USART1SEL)) { + usart_freq = ahb_freq; + } else if((RCU_USARTSRC_LXTAL << 18U) == (RCU_CFG1 & RCU_CFG1_USART1SEL)) { + usart_freq = LXTAL_VALUE; + } else if((RCU_USARTSRC_IRC64MDIV << 18U) == (RCU_CFG1 & RCU_CFG1_USART1SEL)) { + usart_freq = irc64mdiv_freq; + } else { + } + + ck_freq = usart_freq; + break; + case CK_USART2: + /* calculate USART2 clock frequency */ + if((RCU_USARTSRC_APB << 20U) == (RCU_CFG1 & RCU_CFG1_USART2SEL)) { + usart_freq = apb1_freq; + } else if((RCU_USARTSRC_AHB << 20U) == (RCU_CFG1 & RCU_CFG1_USART2SEL)) { + usart_freq = ahb_freq; + } else if((RCU_USARTSRC_LXTAL << 20U) == (RCU_CFG1 & RCU_CFG1_USART2SEL)) { + usart_freq = LXTAL_VALUE; + } else if((RCU_USARTSRC_IRC64MDIV << 20U) == (RCU_CFG1 & RCU_CFG1_USART2SEL)) { + usart_freq = irc64mdiv_freq; + } else { + } + + ck_freq = usart_freq; + break; + case CK_USART5: + /* calculate USART5 clock frequency */ + if((RCU_USARTSRC_APB << 22U) == (RCU_CFG1 & RCU_CFG1_USART5SEL)) { + usart_freq = apb2_freq; + } else if((RCU_USARTSRC_AHB << 22U) == (RCU_CFG1 & RCU_CFG1_USART5SEL)) { + usart_freq = ahb_freq; + } else if((RCU_USARTSRC_LXTAL << 22U) == (RCU_CFG1 & RCU_CFG1_USART5SEL)) { + usart_freq = LXTAL_VALUE; + } else if((RCU_USARTSRC_IRC64MDIV << 22U) == (RCU_CFG1 & RCU_CFG1_USART5SEL)) { + usart_freq = irc64mdiv_freq; + } else { + } + + ck_freq = usart_freq; + break; + case CK_IRC64MDIV: + ck_freq = irc64mdiv_freq; + break; + case CK_HXTAL: + ck_freq = HXTAL_VALUE; + break; + case CK_LPIRC4M: + ck_freq = LPIRC4M_VALUE; + break; + default: + break; + } + + return ck_freq; +} + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_FLAG_IRC64MSTB: IRC64M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLL0STB: PLL0 stabilization flag + \arg RCU_FLAG_PLL1STB: PLL1 stabilization flag + \arg RCU_FLAG_PLL2STB: PLL2 stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC32KSTB: IRC32K stabilization flag + \arg RCU_FLAG_IRC48MSTB: IRC48M stabilization flag + \arg RCU_FLAG_LPIRC4MSTB: LPIRC4M stabilization flag + \arg RCU_FLAG_PLLUSBHS0STB: PLLUSBHS0 stabilization flag + \arg RCU_FLAG_PLLUSBHS1STB: PLLUSBHS1 stabilization flag + \arg RCU_FLAG_LCKMD: LXTAL clock failure detection flags + \arg RCU_FLAG_BORRST: BOR reset flags + \arg RCU_FLAG_EPRST: external PIN reset flag + \arg RCU_FLAG_PORRST: Power reset flag + \arg RCU_FLAG_SWRST: software reset flag + \arg RCU_FLAG_FWDGTRST: free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: window watchdog timer reset flag + \arg RCU_FLAG_LPRST: low-power reset flag + \param[out] none + \retval none +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + /* get the rcu flag */ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear all the reset flag + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief enable the stabilization interrupt + \param[in] interrupt: clock stabilization interrupt, refer to rcu_int_enum + Only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC64MSTB: IRC64M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLL0STB: PLL0 stabilization interrupt enable + \arg RCU_INT_PLL1STB: PLL1 stabilization interrupt enable + \arg RCU_INT_PLL2STB: PLL2 stabilization interrupt enable + \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt enable + \arg RCU_INT_LPIRC4MSTB: LPIRC4M stabilization interrupt enable + \arg RCU_INT_PLLUSBHS0STB: PLLUSBHS0 stabilization interrupt enable + \arg RCU_INT_PLLUSBHS1STB: PLLUSBHS1 stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum interrupt) +{ + RCU_REG_VAL(interrupt) |= BIT(RCU_BIT_POS(interrupt)); +} + + +/*! + \brief disable the stabilization interrupt + \param[in] interrupt: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC32KSTB: IRC32K stabilization interrupt disable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable + \arg RCU_INT_IRC64MSTB: IRC64M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLL0STB: PLL0 stabilization interrupt disable + \arg RCU_INT_PLL1STB: PLL1 stabilization interrupt disable + \arg RCU_INT_PLL2STB: PLL2 stabilization interrupt disable + \arg RCU_INT_IRC48MSTB: IRC48M stabilization interrupt disable + \arg RCU_INT_LPIRC4MSTB: LPIRC4M stabilization interrupt disable + \arg RCU_INT_PLLUSBHS0STB: PLLUSBHS0 stabilization interrupt disable + \arg RCU_INT_PLLUSBHS1STB: PLLUSBHS1 stabilization interrupt disable + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum interrupt) +{ + RCU_REG_VAL(interrupt) &= ~BIT(RCU_BIT_POS(interrupt)); +} + +/*! + \brief get the clock stabilization interrupt and ckm flags + \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC32KSTB: IRC32K stabilization interrupt flag + \arg RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC64MSTB: IRC64M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_PLL0STB: PLL0 stabilization interrupt flag + \arg RCU_INT_FLAG_PLL1STB: PLL1 stabilization interrupt flag + \arg RCU_INT_FLAG_PLL2STB: PLL2 stabilization interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \arg RCU_INT_FLAG_LCKM: LXTAL clock stuck interrupt flag + \arg RCU_INT_FLAG_LPIRC4MSTB: LPIRC4M stabilization interrupt flag + \arg RCU_INT_FLAG_IRC48MSTB: IRC48M stabilization interrupt flag + \arg RCU_INT_FLAG_PLLUSBHS0STB: PLLUSBHS0 stabilization interrupt flag + \arg RCU_INT_FLAG_PLLUSBHS1STB: PLLUSBHS1 stabilization interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) +{ + /* get the rcu interrupt flag */ + if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC32KSTB_CLR: IRC32K stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC64MSTB_CLR: IRC64M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLL0STB_CLR: PLL0 stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLL1STB_CLR: PLL1 stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLL2STB_CLR: PLL2 stabilization interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \arg RCU_INT_FLAG_LCKM: LXTAL clock stuck interrupt flag clear + \arg RCU_INT_FLAG_LPIRC4MSTB_CLR: LPIRC4M stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC48MSTB_CLR: IRC48M stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLUSBHS0STB_CLR: PLLUSBHS0 stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLUSBHS1STB_CLR: PLLUSBHS1 stabilization interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag) +{ + RCU_REG_VAL(int_flag) |= BIT(RCU_BIT_POS(int_flag)); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rspdif.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rspdif.c new file mode 100644 index 0000000000..0806c5cbc6 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rspdif.c @@ -0,0 +1,582 @@ +/*! + \file gd32h7xx_rspdif.c + \brief RSPDIF driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_rspdif.h" + +#define RSPDIF_INIT_MASK (uint32_t)0xFFC88004U /*!< RSPDIF parameter initialization mask */ + +#define RSPDIF_CKCNT5_OFFSET (uint32_t)16U /*!< RSPDIF the number of consecutive time clock cycles offset */ + +#define RSPDIF_DATA_F0_PREF_OFFSET (uint32_t)28U /*!< RSPDIF data format 0 preamble type offset */ +#define RSPDIF_DATA_F0_C_OFFSET (uint32_t)27U /*!< RSPDIF data format 0 channel status offset */ +#define RSPDIF_DATA_F0_U_OFFSET (uint32_t)26U /*!< RSPDIF data format 0 user bit offset */ +#define RSPDIF_DATA_F0_V_OFFSET (uint32_t)25U /*!< RSPDIF data format 0 validity bit offset */ +#define RSPDIF_DATA_F0_P_OFFSET (uint32_t)24U /*!< RSPDIF data format 0 parity error bit offset */ + +#define RSPDIF_DATA_F1_PREF_OFFSET (uint32_t)4U /*!< RSPDIF data format 1 preamble type offset */ +#define RSPDIF_DATA_F1_C_OFFSET (uint32_t)3U /*!< RSPDIF data format 1 channel status offset */ +#define RSPDIF_DATA_F1_U_OFFSET (uint32_t)2U /*!< RSPDIF data format 1 user bit offset */ +#define RSPDIF_DATA_F1_V_OFFSET (uint32_t)1U /*!< RSPDIF data format 1 validity bit offset */ +#define RSPDIF_DATA_F1_DATA_OFFSET (uint32_t)8U /*!< RSPDIF data format 1 data offset */ + +/*! + \brief reset the RSPDIF + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_deinit(void) +{ + rcu_periph_reset_enable(RCU_RSPDIFRST); + rcu_periph_reset_disable(RCU_RSPDIFRST); +} + +/*! + \brief initialize the parameters of RSPDIF structure with the default values + \param[in] none + \param[out] rspdif_parameter_struct: the initialized structure rspdif_parameter_struct pointer + \retval none +*/ +void rspdif_struct_para_init(rspdif_parameter_struct *rspdif_struct) +{ + /* configure the RSPDIF structure with the default values */ + rspdif_struct->input_sel = RSPDIF_INPUT_IN0; + rspdif_struct->max_retrie = RSPDIF_MAXRETRIES_15; + rspdif_struct->wait_activity = RSPDIF_WAIT_FOR_ACTIVITY_ON; + rspdif_struct->channel_sel = RSPDIF_CHANNEL_A; + rspdif_struct->sample_format = RSPDIF_DATAFORMAT_MSB; + rspdif_struct->sound_mode = RSPDIF_STEREOMODE_ENABLE; + rspdif_struct->pre_type = RSPDIF_PREAMBLE_TYPE_MASK_OFF; + rspdif_struct->channel_status_bit = RSPDIF_CHANNEL_STATUS_MASK_OFF; + rspdif_struct->validity_bit = RSPDIF_VALIDITY_MASK_OFF; + rspdif_struct->parity_error_bit = RSPDIF_PERROR_MASK_OFF; + rspdif_struct->symbol_clk = RSPDIF_SYMBOL_CLK_OFF; + rspdif_struct->bak_symbol_clk = RSPDIF_BACKUP_SYMBOL_CLK_OFF; +} + +/*! + \brief initialize the RSPDIF parameters + \param[in] rspdif_struct : RSPDIF parameter initialization stucture and the member values are shown as below: + input_sel : RSPDIF_INPUT_INx (x = 0 ~ 3) + max_retrie : RSPDIF_MAXRETRIES_NONE, RSPDIF_MAXRETRIES_3, RSPDIF_MAXRETRIES_15, RSPDIF_MAXRETRIES_63 + wait_activity : RSPDIF_WAIT_FOR_ACTIVITY_OFF, RSPDIF_WAIT_FOR_ACTIVITY_ON + channel_sel : RSPDIF_CHANNEL_A, RSPDIF_CHANNEL_B + sample_format : RSPDIF_DATAFORMAT_LSB, RSPDIF_DATAFORMAT_MSB, RSPDIF_DATAFORMAT_32BITS + sound_mode : RSPDIF_STEREOMODE_DISABLE, RSPDIF_STEREOMODE_ENABLE + pre_type : RSPDIF_PREAMBLE_TYPE_MASK_OFF, RSPDIF_PREAMBLE_TYPE_MASK_ON + channel_status_bit : RSPDIF_CHANNEL_STATUS_MASK_OFF, RSPDIF_CHANNEL_STATUS_MASK_ON + validity_bit : RSPDIF_VALIDITY_MASK_OFF, RSPDIF_VALIDITY_MASK_ON + parity_error_bit : RSPDIF_PERROR_MASK_OFF, RSPDIF_PERROR_MASK_ON + symbol_clk : RSPDIF_BACKUP_SYMBOL_CLK_OFF, RSPDIF_BACKUP_SYMBOL_CLK_ON + bak_symbol_clk : RSPDIF_SYMBOL_CLK_OFF, RSPDIF_SYMBOL_CLK_ON + \param[out] none + \retval none +*/ +void rspdif_init(rspdif_parameter_struct *rspdif_struct) +{ + uint32_t reg = 0U; + + reg = RSPDIF_CTL; + reg &= RSPDIF_INIT_MASK; + + /* select the RSPDIF input */ + reg |= rspdif_struct->input_sel; + /* configure the RSPDIF maximum allowed re-tries during synchronization phase */ + reg |= rspdif_struct->max_retrie; + /* configure the RSPDIF wait for activity on the selected input */ + reg |= rspdif_struct->wait_activity; + /* select the channel status from channel A or B */ + reg |= rspdif_struct->channel_sel; + /* configure the RSPDIF data samples format */ + reg |= rspdif_struct->sample_format; + /* select stereo or mono mode */ + reg |= rspdif_struct->sound_mode; + /* select whether the preamble type value into the RSPDIF_DATA */ + reg |= rspdif_struct->pre_type; + /* select whether the channel status and user bits are copied or not into the received frame */ + reg |= rspdif_struct->channel_status_bit; + /* select whether the validity bit is copied or not into the received frame */ + reg |= rspdif_struct->validity_bit; + /* select whether the parity error bit is copied or not into the received frame */ + reg |= rspdif_struct->parity_error_bit; + /* configure the RSPDIF symbol clock generation */ + reg |= rspdif_struct->symbol_clk; + /* configure the RSPDIF backup symbol clock generation */ + reg |= rspdif_struct->bak_symbol_clk; + + /* write to SPDIFRX_CTL register */ + RSPDIF_CTL = (uint32_t)reg; +} + +/*! + \brief specifies the RSPDIF peripheral state + \param[in] rspdif_state : + only one parameter can be selected which is shown as below: + \arg RSPDIF_STATE_SYNC: enable RSPDIF synchronization only + \arg RSPDIF_STATE_RCV : enable RSPDIF receiver + \param[out] none + \retval none +*/ +void rspdif_enable(uint32_t mode) +{ + uint32_t reg = 0U; + + reg = RSPDIF_CTL; + + /* clear RSPDIF state */ + reg &= ~(uint32_t)RSPDIF_CTL_RXCFG; + reg |= (uint32_t)mode; + + /* enable RSPDIF */ + RSPDIF_CTL = (uint32_t)reg; +} + +/*! + \brief disable RSPDIF + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_disable(void) +{ + /* clear RSPDIF state */ + RSPDIF_CTL &= ~(uint32_t)RSPDIF_CTL_RXCFG; +} + +/*! + \brief enable RSPDIF symbol clock + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_symbol_clock_enable(void) +{ + RSPDIF_CTL |= (uint32_t)RSPDIF_CTL_SCKEN; +} + +/*! + \brief disable RSPDIF symbol clock + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_symbol_clock_disable(void) +{ + RSPDIF_CTL &= ~(uint32_t)RSPDIF_CTL_SCKEN; +} + +/*! + \brief enable RSPDIF backup symbol clock + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_backup_symbol_clock_enable(void) +{ + RSPDIF_CTL |= (uint32_t)RSPDIF_CTL_BKSCKEN; +} + +/*! + \brief disable RSPDIF backup symbol clock + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_backup_symbol_clock_disable(void) +{ + RSPDIF_CTL &= ~(uint32_t)RSPDIF_CTL_BKSCKEN; +} + +/*! + \brief enable the RSPDIF receiver DMA + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_dma_enable(void) +{ + RSPDIF_CTL |= RSPDIF_CTL_DMAREN; +} + +/*! + \brief disable the RSPDIF receiver DMA + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_dma_disable(void) +{ + RSPDIF_CTL &= ~RSPDIF_CTL_DMAREN; +} + +/*! + \brief enable the RSPDIF control buffer DMA + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_control_buffer_dma_enable(void) +{ + RSPDIF_CTL |= RSPDIF_CTL_DMACBEN; +} + +/*! + \brief disable the RSPDIF control buffer DMA + \param[in] none + \param[out] none + \retval none +*/ +void rspdif_control_buffer_dma_disable(void) +{ + RSPDIF_CTL &= ~RSPDIF_CTL_DMACBEN; +} + +/*! + \brief RSPDIF read data + \param[in] none + \param[out] data_struct: RSPDIF data stucture and the member values are shown as below: + format : RSPDIF_DATAFORMAT_LSB, RSPDIF_DATAFORMAT_MSB,RSPDIF_DATAFORMAT_32BITS + preamble : RSPDIF_PREAMBLE_NONE,RSPDIF_PREAMBLE_B,RSPDIF_PREAMBLE_M,RSPDIF_PREAMBLE_W + channel_status : 0 or 1 + user_bit : 0 or 1 + validity : 0 or 1 + parity_err : 0 or 1 + data0 : 0 ~ 65535 + data1 : 0 ~ 65535 + \retval none +*/ +void rspdif_data_read(rspdif_data_struct *data_struct) +{ + /* get data format */ + data_struct->format = RSPDIF_CTL & RSPDIF_CTL_RXDF; + + switch(data_struct->format) { + /* data format 0 */ + case RSPDIF_DATAFORMAT_LSB: + /* the preamble type */ + data_struct->preamble = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_PREF) >> RSPDIF_DATA_F0_PREF_OFFSET); + /* channel status bit */ + data_struct->channel_status = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_C) >> RSPDIF_DATA_F0_C_OFFSET); + /* user bit */ + data_struct->user_bit = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_U) >> RSPDIF_DATA_F0_U_OFFSET); + /* validity bit */ + data_struct->validity = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_V) >> RSPDIF_DATA_F0_V_OFFSET); + /* parity error bit */ + data_struct->parity_err = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_P) >> RSPDIF_DATA_F0_P_OFFSET); + /* data value 0 */ + data_struct->data0 = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F0_DATA0); + /* data value 1 */ + data_struct->data1 = 0U; + break; + /* data format 1 */ + case RSPDIF_DATAFORMAT_MSB: + /* the preamble type */ + data_struct->preamble = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_PREF) >> RSPDIF_DATA_F1_PREF_OFFSET); + /* channel status bit */ + data_struct->channel_status = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_C) >> RSPDIF_DATA_F1_C_OFFSET); + /* user bit */ + data_struct->user_bit = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_U) >> RSPDIF_DATA_F1_U_OFFSET); + /* validity bit */ + data_struct->validity = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_V) >> RSPDIF_DATA_F1_V_OFFSET); + /* parity error bit */ + data_struct->parity_err = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F1_P); + /* data value 0 */ + data_struct->data0 = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_DATA0) >> RSPDIF_DATA_F1_DATA_OFFSET); + /* data value 1 */ + data_struct->data1 = 0U; + break; + /* data format 2 */ + case RSPDIF_DATAFORMAT_32BITS: + /* the preamble type */ + data_struct->preamble = 0U; + /* channel status bit */ + data_struct->channel_status = 0U; + /* user bit */ + data_struct->user_bit = 0U; + /* validity bit */ + data_struct->validity = 0U; + /* parity error bit */ + data_struct->parity_err = 0U; + /* data value 0 */ + data_struct->data0 = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F2_DATA1); + /* data value 1 */ + data_struct->data1 = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F2_DATA2); + break; + default: + break; + } +} + +/*! + \brief get duration of 5 symbols counted using rspdif_ck + \param[in] none + \param[out] none + \retval duration of 5 symbols counted using rspdif_ck +*/ +uint32_t rspdif_duration_of_symbols_get(void) +{ + return ((uint32_t)((RSPDIF_STAT & RSPDIF_STAT_CKCNT5) >> RSPDIF_CKCNT5_OFFSET)); +} + +/*! + \brief get user data information + \param[in] none + \param[out] none + \retval user data information +*/ +uint32_t rspdif_user_data_get(void) +{ + return ((uint32_t)(RSPDIF_CHSTAT & RSPDIF_CHSTAT_USER)); +} + +/*! + \brief get channel status information + \param[in] none + \param[out] none + \retval channel status information +*/ +uint32_t rspdif_channel_status_get(void) +{ + return ((uint32_t)((RSPDIF_CHSTAT & RSPDIF_CHSTAT_CHS) >> 16U)); +} + +/*! + \brief get start of block + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rspdif_start_block_status_get(void) +{ + if(RESET != (RSPDIF_CHSTAT & RSPDIF_CHSTAT_SOB)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief get threshold low estimation + \param[in] none + \param[out] none + \retval low threshold value +*/ +uint32_t rspdif_low_threshold_get(void) +{ + return ((uint32_t)((RSPDIF_DTH & RSPDIF_DTH_THLO) >> 16U)); +} + +/*! + \brief get threshold high estimation + \param[in] none + \param[out] none + \retval high threshold value +*/ +uint32_t rspdif_high_threshold_get(void) +{ + return ((uint32_t)(RSPDIF_DTH & RSPDIF_DTH_THHI)); +} + +/*! + \brief get RSPDIF flag status + \param[in] flag: RSPDIF flag status + only one parameter can be selected which is shown as below: + \arg RSPDIF_FLAG_RBNE : RSPDIF RX buffer is not empty + \arg RSPDIF_FLAG_CBNE : RSPDIF RX control buffer is not empty + \arg RSPDIF_FLAG_PERR : RSPDIF parity error + \arg RSPDIF_FLAG_RXORERR : RSPDIF RX overrun error + \arg RSPDIF_FLAG_SYNDB : RSPDIF synchronization block detected + \arg RSPDIF_FLAG_SYNDO : RSPDIF synchronization done + \arg RSPDIF_FLAG_FRERR : RSPDIF frame error + \arg RSPDIF_FLAG_SYNERR : RSPDIF synchronization error + \arg RSPDIF_FLAG_TMOUTERR : RSPDIF time out error + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rspdif_flag_get(uint16_t flag) +{ + if(RESET != (RSPDIF_STAT & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear RSPDIF flag + \param[in] flag: RSPDIF flag status + one or more parameters can be selected which is shown as below: + \arg RSPDIF_FLAG_PERR : RSPDIF parity error + \arg RSPDIF_FLAG_RXORERR : RSPDIF RX overrun error + \arg RSPDIF_FLAG_SYNDB : RSPDIF synchronization block detected + \arg RSPDIF_FLAG_SYNDO : RSPDIF synchronization done + \param[out] none + \retval none +*/ +void rspdif_flag_clear(uint16_t flag) +{ + RSPDIF_STATC |= flag; +} + +/*! + \brief enable RSPDIF interrupt + \param[in] interrupt: RSPDIF interrupt + one or more parameters can be selected which is shown as below: + \arg RSPDIF_INT_RBNE : RSPDIF RX buffer is not empty interrupt + \arg RSPDIF_INT_CBNE : RSPDIF RX control buffer is not empty interrupt + \arg RSPDIF_INT_PERR : RSPDIF parity error interrupt + \arg RSPDIF_INT_RXORERR: RSPDIF RX overrun error interrupt + \arg RSPDIF_INT_SYNDB : RSPDIF synchronization block detected interrupt + \arg RSPDIF_INT_SYNDO : RSPDIF synchronization done interrupt + \arg RSPDIF_INT_RXDCERR: RSPDIF data decoding error interrupt + \param[out] none + \retval none +*/ +void rspdif_interrupt_enable(uint8_t interrupt) +{ + RSPDIF_INTEN |= (uint32_t)interrupt; +} + +/*! + \brief disable RSPDIF interrupt + \param[in] interrupt: RSPDIF interrupt + one or more parameters can be selected which is shown as below: + \arg RSPDIF_INT_RBNE : RSPDIF RX buffer is not empty interrupt + \arg RSPDIF_INT_CBNE : RSPDIF RX control buffer is not empty interrupt + \arg RSPDIF_INT_PERR : RSPDIF parity error interrupt + \arg RSPDIF_INT_RXORERR: RSPDIF RX overrun error interrupt + \arg RSPDIF_INT_SYNDB : RSPDIF synchronization block detected interrupt + \arg RSPDIF_INT_SYNDO : RSPDIF synchronization done interrupt + \arg RSPDIF_INT_RXDCERR: RSPDIF data decoding error interrupt + \param[out] none + \retval none +*/ +void rspdif_interrupt_disable(uint8_t interrupt) +{ + RSPDIF_INTEN &= ~(uint32_t)interrupt; +} + +/*! + \brief get RSPDIF interrupt flag status + \param[in] int_flag: RSPDIF interrupt flag status + only one parameter can be selected which is shown as below: + \arg RSPDIF_INT_FLAG_RBNE : RSPDIF RX buffer is not empty interrupt flag + \arg RSPDIF_INT_FLAG_CBNE : RSPDIF RX control buffer is not empty interrupt flag + \arg RSPDIF_INT_FLAG_PERR : RSPDIF parity error interrupt flag + \arg RSPDIF_INT_FLAG_RXORERR : RSPDIF RX overrun error interrupt flag + \arg RSPDIF_INT_FLAG_SYNDB : RSPDIF synchronization block detected interrupt flag + \arg RSPDIF_INT_FLAG_SYNDO : RSPDIF synchronization done interrupt flag + \arg RSPDIF_INT_FLAG_FRERR : RSPDIF frame error interrupt flag + \arg RSPDIF_INT_FLAG_SYNERR : RSPDIF synchronization error interrupt flag + \arg RSPDIF_INT_FLAG_TMOUTERR : RSPDIF time out error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rspdif_interrupt_flag_get(uint16_t int_flag) +{ + uint32_t reg1 = RSPDIF_STAT; + uint32_t reg2 = RSPDIF_INTEN; + + switch(int_flag) { + /* RSPDIF RX buffer is not empty interrupt */ + case RSPDIF_INT_FLAG_RBNE: + reg1 = reg1 & RSPDIF_STAT_RBNE; + reg2 = reg2 & RSPDIF_INTEN_RBNEIE; + break; + /* RSPDIF RX control buffer is not empty interrupt */ + case RSPDIF_INT_FLAG_CBNE: + reg1 = reg1 & RSPDIF_STAT_CBNE; + reg2 = reg2 & RSPDIF_INTEN_CBNEIE; + break; + /* RSPDIF parity error interrupt */ + case RSPDIF_INT_FLAG_PERR: + reg1 = reg1 & RSPDIF_STAT_PERR; + reg2 = reg2 & RSPDIF_INTEN_PERRIE; + break; + /* RSPDIF RX overrun error interrupt */ + case RSPDIF_INT_FLAG_RXORERR: + reg1 = reg1 & RSPDIF_STAT_RXORERR; + reg2 = reg2 & RSPDIF_INTEN_RXORERRIE; + break; + /* RSPDIF synchronization block detected interrupt */ + case RSPDIF_INT_FLAG_SYNDB: + reg1 = reg1 & RSPDIF_STAT_SYNDB; + reg2 = reg2 & RSPDIF_INTEN_SYNDBIE; + break; + /* RSPDIF synchronization done interrupt */ + case RSPDIF_INT_FLAG_SYNDO: + reg1 = reg1 & RSPDIF_STAT_SYNDO; + reg2 = reg2 & RSPDIF_INTEN_SYNDOIE; + break; + /* RSPDIF frame error interrupt */ + case RSPDIF_INT_FLAG_FRERR: + reg1 = reg1 & RSPDIF_STAT_FRERR; + reg2 = reg2 & RSPDIF_INTEN_RXDCERRIE; + break; + /* RSPDIF synchronization error interrupt */ + case RSPDIF_INT_FLAG_SYNERR: + reg1 = reg1 & RSPDIF_STAT_SYNERR; + reg2 = reg2 & RSPDIF_INTEN_RXDCERRIE; + break; + /* RSPDIF time out error interrupt */ + case RSPDIF_INT_FLAG_TMOUTERR: + reg1 = reg1 & RSPDIF_STAT_TMOUTERR; + reg2 = reg2 & RSPDIF_INTEN_RXDCERRIE; + break; + default : + break; + } + /*get RSPDIF interrupt flag status */ + if((0U != reg1) && (0U != reg2)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear RSPDIF interrupt flag status + \param[in] int_flag: RSPDIF interrupt flag status + one or more parameters can be selected which is shown as below: + \arg RSPDIF_INT_FLAG_PERR : RSPDIF parity error interrupt flag + \arg RSPDIF_INT_FLAG_RXORERR : RSPDIF RX overrun error interrupt flag + \arg RSPDIF_INT_FLAG_SYNDB : RSPDIF synchronization block detected interrupt flag + \arg RSPDIF_INT_FLAG_SYNDO : RSPDIF synchronization done interrupt flag + \param[out] none + \retval none +*/ +void rspdif_interrupt_flag_clear(uint16_t int_flag) +{ + RSPDIF_STATC |= int_flag ; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtc.c new file mode 100644 index 0000000000..aa38862b02 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtc.c @@ -0,0 +1,1265 @@ +/*! + \file gd32h7xx_rtc.c + \brief RTC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_rtc.h" + +/* RTC timeout value */ +#define RTC_WTWF_TIMEOUT ((uint32_t)0x00004000U) /*!< wakeup timer can be written flag timeout */ +#define RTC_INITM_TIMEOUT ((uint32_t)0x00004000U) /*!< initialization state flag timeout */ +#define RTC_RSYNF_TIMEOUT ((uint32_t)0x00008000U) /*!< register synchronization flag timeout */ +#define RTC_HRFC_TIMEOUT ((uint32_t)0x20000000U) /*!< recalibration pending flag timeout */ +#define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ +#define RTC_ALRMXWF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be written flag timeout */ + +/*! + \brief reset most of the RTC registers + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + /* After Backup domain reset, some of the RTC registers are write-protected: RTC_TIME, RTC_DATE, RTC_PSC, + RTC_HRFC, RTC_SHIFTCTL, the bit INITM in RTC_STAT and the bits CS, S1H, A1H, REFEN in RTC_CTL. */ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* RTC_TAMP register is not under write protection */ + RTC_TAMP = RTC_REGISTER_RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* RTC alarmx related registers are not under the protection of RTC_WPK, different from former GD32MCU */ + RTC_CTL &= ((uint32_t)~(RTC_CTL_ALRM0EN | RTC_CTL_ALRM1EN)); + /* to write RTC_ALRMxTD and RTC_ALRMxSS register, 1 ALRMxEN bit in RTC_CTL register should be reset as the condition + 2 or in INIT mode */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM1TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + RTC_ALRM1SS = RTC_REGISTER_RESET; + + /* 1 only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2: 0] + 2 or configure the wakeup timer in INIT mode*/ + RTC_CTL &= ((uint32_t)~RTC_CTL_WTEN); + /* wait until the WTWF flag to be set */ + do { + flag_status = RTC_STAT & RTC_STAT_WTWF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET == flag_status) { + error_status = ERROR; + } else { + RTC_CTL &= ((uint32_t)~RTC_CTL_WTCS); + RTC_WUT = RTC_WUT_RESET; + + /* reset RTC_CTL register, this can be done without the init mode */ + RTC_CTL &= RTC_REGISTER_RESET; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status) { + /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. + in order to read calendar from shadow register, not the real registers being reset */ + RTC_TIME = RTC_REGISTER_RESET; + RTC_DATE = RTC_DATE_RESET; + + RTC_PSC = RTC_PSC_RESET; + RTC_CTL = RTC_REGISTER_RESET; + + /* reset RTC_STAT register, also exit init mode. + at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ + RTC_STAT = RTC_STAT_RESET; + + /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + + RTC_ALRM1TD = RTC_REGISTER_RESET; + RTC_ALRM1SS = RTC_REGISTER_RESET; + + /* reset RTC_SHIFTCTL and RTC_HRFC register, and the bits S1H, A1H, REFEN in RTC_CTL, these can be done without the init mode */ + RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_HRFC = RTC_REGISTER_RESET; + + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + } + return error_status; +} + +/*! + \brief initialize RTC registers + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the RTC peripheral + members of the structure and the member values are shown as below: + year: 0x0 - 0x99(BCD format) + month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + date: 0x1 - 0x31(BCD format) + day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the RTC display_format chose + minute: 0x0 - 0x59(BCD format) + second: 0x0 - 0x59(BCD format) + factor_asyn: 0x0 - 0x7F + factor_syn: 0x0 - 0x7FFF + am_pm: RTC_AM, RTC_PM + display_format: RTC_24HOUR, RTC_12HOUR + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct *rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; + uint32_t reg_time = 0U, reg_date = 0U; + + reg_date = (DATE_YR(rtc_initpara_struct->year) | \ + DATE_DOW(rtc_initpara_struct->day_of_week) | \ + DATE_MON(rtc_initpara_struct->month) | \ + DATE_DAY(rtc_initpara_struct->date)); + + reg_time = (rtc_initpara_struct->am_pm | \ + TIME_HR(rtc_initpara_struct->hour) | \ + TIME_MN(rtc_initpara_struct->minute) | \ + TIME_SC(rtc_initpara_struct->second)); + + /* 1st: disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status) { + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn) | \ + PSC_FACTOR_S(rtc_initpara_struct->factor_syn)); + + RTC_TIME = (uint32_t)reg_time; + RTC_DATE = (uint32_t)reg_date; + + RTC_CTL &= (uint32_t)(~RTC_CTL_CS); + RTC_CTL |= rtc_initpara_struct->display_format; + + /* 3rd: exit init mode */ + rtc_init_mode_exit(); + + /* 4th: wait the RSYNF flag to set */ + error_status = rtc_register_sync_wait(); + } + + /* 5th: enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enter RTC init mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + volatile uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)) { + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do { + flag_status = RTC_STAT & RTC_STAT_INITF; + } while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status) { + error_status = SUCCESS; + } + } else { + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief exit RTC init mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + registers are updated + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + if((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)) { + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* firstly clear RSYNF flag */ + RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); + + /* wait until RSYNF flag to be set */ + do { + flag_status = RTC_STAT & RTC_STAT_RSYNF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status) { + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + } else { + error_status = SUCCESS; + } + + return error_status; +} + +/*! + \brief get current time and date + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the RTC peripheral + members of the structure and the member values are shown as below: + year: 0x0 - 0x99(BCD format) + month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + date: 0x1 - 0x31(BCD format) + day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the RTC display_format chose + minute: 0x0 - 0x59(BCD format) + second: 0x0 - 0x59(BCD format) + factor_asyn: 0x0 - 0x7F + factor_syn: 0x0 - 0x7FFF + am_pm: RTC_AM, RTC_PM + display_format: RTC_24HOUR, RTC_12HOUR + \retval none +*/ +void rtc_current_time_get(rtc_parameter_struct *rtc_initpara_struct) +{ + uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U; + + temp_tr = (uint32_t)RTC_TIME; + temp_dr = (uint32_t)RTC_DATE; + temp_pscr = (uint32_t)RTC_PSC; + temp_ctlr = (uint32_t)RTC_CTL; + + /* get current time and construct rtc_parameter_struct structure */ + rtc_initpara_struct->year = (uint8_t)GET_DATE_YR(temp_dr); + rtc_initpara_struct->month = (uint8_t)GET_DATE_MON(temp_dr); + rtc_initpara_struct->date = (uint8_t)GET_DATE_DAY(temp_dr); + rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->hour = (uint8_t)GET_TIME_HR(temp_tr); + rtc_initpara_struct->minute = (uint8_t)GET_TIME_MN(temp_tr); + rtc_initpara_struct->second = (uint8_t)GET_TIME_SC(temp_tr); + rtc_initpara_struct->factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); + rtc_initpara_struct->factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); + rtc_initpara_struct->am_pm = (uint32_t)(temp_tr & RTC_TIME_PM); + rtc_initpara_struct->display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); +} + +/*! + \brief get current subsecond value + \param[in] none + \param[out] none + \retval current subsecond value +*/ +uint32_t rtc_subsecond_get(void) +{ + uint32_t reg = 0U; + /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */ + reg = (uint32_t)RTC_SS; + /* read RTC_DATE to unlock the 3 shadow registers */ + (void)(RTC_DATE); + + return reg; +} + +/*! + \brief configure RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the RTC display_format + alarm_minute: 0x0 - 0x59(BCD format) + alarm_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \param[out] none + \retval none +*/ +void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct *rtc_alarm_time) +{ + uint32_t reg_alrmtd = 0U; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + reg_alrmtd = (rtc_alarm_time->alarm_mask | \ + rtc_alarm_time->weekday_or_date | \ + rtc_alarm_time->am_pm | \ + ALRMTD_DAY(rtc_alarm_time->alarm_day) | \ + ALRMTD_HR(rtc_alarm_time->alarm_hour) | \ + ALRMTD_MN(rtc_alarm_time->alarm_minute) | \ + ALRMTD_SC(rtc_alarm_time->alarm_second)); + + if(RTC_ALARM0 == rtc_alarm) { + RTC_ALRM0TD = (uint32_t)reg_alrmtd; + + } else { + RTC_ALRM1TD = (uint32_t)reg_alrmtd; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure subsecond of RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[in] mask_subsecond: alarm subsecond mask + only one parameter can be selected which is shown as below: + \arg RTC_MSKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MSKSSC_1_14: mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared + \arg RTC_MSKSSC_2_14: mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared + \arg RTC_MSKSSC_3_14: mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared + \arg RTC_MSKSSC_4_14: mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared + \arg RTC_MSKSSC_5_14: mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared + \arg RTC_MSKSSC_6_14: mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared + \arg RTC_MSKSSC_7_14: mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared + \arg RTC_MSKSSC_8_14: mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared + \arg RTC_MSKSSC_9_14: mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared + \arg RTC_MSKSSC_10_14: mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared + \arg RTC_MSKSSC_11_14: mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared + \arg RTC_MSKSSC_12_14: mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared + \arg RTC_MSKSSC_13_14: mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared + \arg RTC_MSKSSC_14: mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared + \arg RTC_MSKSSC_NONE: mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared + \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF) + \param[out] none + \retval none +*/ +void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint32_t subsecond) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + if(ERROR != (rtc_init_mode_enter())) + { + if(RTC_ALARM0 == rtc_alarm) { + RTC_ALRM0SS = mask_subsecond | subsecond; + } else { + RTC_ALRM1SS = mask_subsecond | subsecond; + } + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the RTC display_format + alarm_minute: 0x0 - 0x59(BCD format) + alarm_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct *rtc_alarm_time) +{ + uint32_t reg_alrmtd = 0U; + + /* get the value of RTC_ALRM0TD register */ + if(RTC_ALARM0 == rtc_alarm) { + reg_alrmtd = RTC_ALRM0TD; + } else { + reg_alrmtd = RTC_ALRM1TD; + } + /* get alarm parameters and construct the rtc_alarm_struct structure */ + rtc_alarm_time->alarm_mask = reg_alrmtd & RTC_ALARM_ALL_MASK; + rtc_alarm_time->am_pm = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_PM); + rtc_alarm_time->weekday_or_date = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_DOWS); + rtc_alarm_time->alarm_day = (uint8_t)GET_ALRMTD_DAY(reg_alrmtd); + rtc_alarm_time->alarm_hour = (uint8_t)GET_ALRMTD_HR(reg_alrmtd); + rtc_alarm_time->alarm_minute = (uint8_t)GET_ALRMTD_MN(reg_alrmtd); + rtc_alarm_time->alarm_second = (uint8_t)GET_ALRMTD_SC(reg_alrmtd); +} + +/*! + \brief get RTC alarm subsecond + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] none + \retval RTC alarm subsecond value +*/ +uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm) +{ + if(RTC_ALARM0 == rtc_alarm) { + return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); + } else { + return ((uint32_t)(RTC_ALRM1SS & RTC_ALRM1SS_SSC)); + } +} + +/*! + \brief enable RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] none + \retval none +*/ +void rtc_alarm_enable(uint8_t rtc_alarm) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + if(RTC_ALARM0 == rtc_alarm) { + RTC_CTL |= RTC_CTL_ALRM0EN; + } else { + RTC_CTL |= RTC_CTL_ALRM1EN; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC alarm + \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(uint8_t rtc_alarm) +{ + volatile uint32_t time_index = RTC_ALRMXWF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of alarm */ + if(RTC_ALARM0 == rtc_alarm) { + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + /* wait until ALRM0WF flag to be set after the alarm is disabled */ + do { + flag_status = RTC_STAT & RTC_STAT_ALRM0WF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } else { + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM1EN); + /* wait until ALRM1WF flag to be set after the alarm is disabled */ + do { + flag_status = RTC_STAT & RTC_STAT_ALRM1WF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } + + if((uint32_t)RESET != flag_status) { + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC time-stamp + \param[in] edge: specify which edge to detect of time-stamp + only one parameter can be selected which is shown as below: + \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event + \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event + \param[out] none + \retval none +*/ +void rtc_timestamp_enable(uint32_t edge) +{ + uint32_t reg_ctl = 0U; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the bits to be configured in RTC_CTL */ + reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN))); + + /* new configuration */ + reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN); + + RTC_CTL = (uint32_t)reg_ctl; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC time-stamp + \param[in] none + \param[out] none + \retval none +*/ +void rtc_timestamp_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the TSEN bit */ + RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure RTC time-stamp internal event + \param[in] mode: specify which internal or external event to be detected + only one parameter can be selected which is shown as below: + \arg RTC_ITSEN_DISABLE: disable RTC time-stamp internal event + \arg RTC_ITSEN_ENABLE: enable RTC time-stamp internal event + \param[out] none + \retval none +*/ +void rtc_timestamp_internalevent_config(uint32_t mode) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + if(mode == RTC_ITSEN_ENABLE) { + RTC_CTL |= RTC_CTL_ITSEN; + } else { + RTC_CTL &= ~(uint32_t)RTC_CTL_ITSEN; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC timestamp time and date + \param[in] none + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + parameters for RTC time-stamp configuration + members of the structure and the member values are shown as below: + timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + timestamp_date: 0x1 - 0x31(BCD format) + timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY + timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the RTC display_format + timestamp_minute: 0x0 - 0x59(BCD format) + timestamp_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_timestamp_get(rtc_timestamp_struct *rtc_timestamp) +{ + uint32_t temp_tts = 0U, temp_dts = 0U; + + /* get the value of time_stamp registers */ + temp_tts = (uint32_t)RTC_TTS; + temp_dts = (uint32_t)RTC_DTS; + + /* get timestamp time and construct the rtc_timestamp_struct structure */ + rtc_timestamp->am_pm = (uint32_t)(temp_tts & RTC_TTS_PM); + rtc_timestamp->timestamp_month = (uint8_t)GET_DTS_MON(temp_dts); + rtc_timestamp->timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts); + rtc_timestamp->timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts); + rtc_timestamp->timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts); + rtc_timestamp->timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts); + rtc_timestamp->timestamp_second = (uint8_t)GET_TTS_SC(temp_tts); +} + +/*! + \brief get RTC time-stamp subsecond + \param[in] none + \param[out] none + \retval RTC time-stamp subsecond value +*/ +uint32_t rtc_timestamp_subsecond_get(void) +{ + return ((uint32_t)RTC_SSTS); +} + +/*! + \brief enable RTC tamper + \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains + parameters for RTC tamper configuration + members of the structure and the member values are shown as below: + detecting tamper event can using edge mode or level mode + (1) using edge mode configuration: + tamper_source: RTC_TAMPER0, RTC_TAMPER1 + tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING + tamper_filter: RTC_FLT_EDGE + tamper_with_timestamp: DISABLE, ENABLE + (2) using level mode configuration: + tamper_source: RTC_TAMPER0, RTC_TAMPER1 + tamper_trigger:RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH + tamper_filter: RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S + tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192, + RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024, + RTC_FREQ_DIV512, RTC_FREQ_DIV256 + tamper_precharge_enable: DISABLE, ENABLE + tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C + tamper_with_timestamp: DISABLE, ENABLE + \param[out] none + \retval none +*/ +void rtc_tamper_enable(rtc_tamper_struct *rtc_tamper) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~(rtc_tamper->tamper_source); + + /* tamper filter must be used when the tamper source is voltage level detection */ + RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT; + + /* the tamper source is voltage level detection */ + if((uint32_t)(rtc_tamper->tamper_filter) != RTC_FLT_EDGE) { + RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT); + + /* check if the tamper pin need precharge, if need, then configure the precharge time */ + if(DISABLE == rtc_tamper->tamper_precharge_enable) { + RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; + } else { + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_precharge_time); + } + + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_sample_frequency); + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_filter); + + /* configure the tamper trigger */ + RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_LEVEL_LOW != rtc_tamper->tamper_trigger) { + RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS); + } + } else { + /* configure the tamper trigger */ + RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->tamper_trigger) { + RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS); + } + } + RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; + if(DISABLE != rtc_tamper->tamper_with_timestamp) { + /* the tamper event also cause a time-stamp event */ + RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS; + } + /* enable tamper */ + RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_source); +} + +/*! + \brief disable RTC tamper + \param[in] source: specify which tamper source to be disabled + only one parameter can be selected which is shown as below: + \arg RTC_TAMPER0 + \arg RTC_TAMPER1 + \param[out] none + \retval none +*/ +void rtc_tamper_disable(uint32_t source) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~source; + +} + +/*! + \brief select the RTC output pin + \param[in] outputpin: specify the RTC output pin is PC13 or PB2 + \arg RTC_OUT_PC13: the RTC output pin is PC13 + \arg RTC_OUT_PB2: the RTC output pin is PB2 + \param[out] none + \retval none +*/ +void rtc_output_pin_select(uint32_t outputpin) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status) { + RTC_CFG &= (uint32_t)(~RTC_CFG_OUT2EN); + RTC_CFG |= (uint32_t)(outputpin); + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure RTC alarm output source + \param[in] source: specify signal to output + only one parameter can be selected which is shown as below: + \arg RTC_ALARM0_HIGH: when the alarm0 flag is set, the output pin is high + \arg RTC_ALARM0_LOW: when the alarm0 flag is set, the output pin is low + \arg RTC_ALARM1_HIGH: when the alarm1 flag is set, the output pin is high + \arg RTC_ALARM1_LOW: when the alarm1 flag is set, the output pin is low + \arg RTC_WAKEUP_HIGH: when the wakeup flag is set, the output pin is high + \arg RTC_WAKEUP_LOW: when the wakeup flag is set, the output pin is low + \param[in] mode: specify the output pin mode when output alarm signal or auto wakeup signal + \arg RTC_ALARM_OUTPUT_OD: open drain mode + \arg RTC_ALARM_OUTPUT_PP: push pull mode + \param[out] none + \retval none +*/ +void rtc_alarm_output_config(uint32_t source, uint32_t mode) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= ~(RTC_CTL_OS | RTC_CTL_OPOL); + + RTC_CTL |= (uint32_t)(source); + /* alarm output */ + RTC_CFG |= (uint32_t)(mode); + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure RTC calibration output source + \param[in] source: specify signal to output + \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 1Hz signal + \param[out] none + \retval none +*/ +void rtc_calibration_output_config(uint32_t source) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_COS); + + RTC_CTL |= (uint32_t)(source); + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief adjust the daylight saving time by adding or substracting one hour from the current time + \param[in] operation: hour adjustment operation + only one parameter can be selected which is shown as below: + \arg RTC_CTL_A1H: add one hour + \arg RTC_CTL_S1H: substract one hour + \param[out] none + \retval none +*/ +void rtc_hour_adjust(uint32_t operation) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint32_t)(operation); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief adjust RTC second or subsecond value of current time + \param[in] add: add 1s to current time or not + only one parameter can be selected which is shown as below: + \arg RTC_SHIFT_ADD1S_RESET: no effect + \arg RTC_SHIFT_ADD1S_SET: add 1s to current time + \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) +{ + uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + uint32_t temp = 0U; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a shift operation is ongoing */ + do { + flag_status = RTC_STAT & RTC_STAT_SOPF; + } while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + /* check if the function of reference clock detection is disabled */ + temp = RTC_CTL & RTC_CTL_REFEN; + if((RESET == flag_status) && (RESET == temp)) { + RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status) { + RTC_CTL |= (uint32_t)RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief disable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status) { + RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC auto wakeup function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_wakeup_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_WTEN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC auto wakeup function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_disable(void) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= ~RTC_CTL_WTEN; + /* wait until the WTWF flag to be set */ + do { + flag_status = RTC_STAT & RTC_STAT_WTWF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET == flag_status) { + error_status = ERROR; + } else { + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief set RTC auto wakeup timer clock + \param[in] wakeup_clock: + \arg WAKEUP_RTCCK_DIV16: RTC auto wakeup timer clock is RTC clock divided by 16 + \arg WAKEUP_RTCCK_DIV8: RTC auto wakeup timer clock is RTC clock divided by 8 + \arg WAKEUP_RTCCK_DIV4: RTC auto wakeup timer clock is RTC clock divided by 4 + \arg WAKEUP_RTCCK_DIV2: RTC auto wakeup timer clock is RTC clock divided by 2 + \arg WAKEUP_CKSPRE: RTC auto wakeup timer clock is ckspre + \arg WAKEUP_CKSPRE_2EXP16: RTC auto wakeup timer clock is ckspre and wakeup timer add 2exp16 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2:0] */ + /* wait until the WTWF flag to be set */ + do { + flag_status = RTC_STAT & RTC_STAT_WTWF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET == flag_status) { + error_status = ERROR; + } else { + RTC_CTL &= (uint32_t)~ RTC_CTL_WTCS; + RTC_CTL |= (uint32_t)wakeup_clock; + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief set wakeup timer value + \param[in] wakeup_timer: 0x0000-0xffff + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* wait until the WTWF flag to be set */ + do { + flag_status = RTC_STAT & RTC_STAT_WTWF; + } while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET == flag_status) { + error_status = ERROR; + } else { + RTC_WUT = (uint32_t)wakeup_timer; + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief get wakeup timer value + \param[in] none + \param[out] none + \retval wakeup timer value +*/ +uint16_t rtc_wakeup_timer_get(void) +{ + return (uint16_t)RTC_WUT; +} + +/*! + \brief configure RTC smooth calibration + \param[in] window: select calibration window + \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz + \param[in] plus: add RTC clock or not + \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 RTC clock + \arg RTC_CALIBRATION_PLUS_RESET: no effect + \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus) +{ + volatile uint32_t time_index = RTC_HRFC_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a smooth calibration operation is ongoing */ + do { + flag_status = RTC_STAT & RTC_STAT_SCPF; + } while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status) { + RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be enabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM0: alarm0 interrupt + \arg RTC_INT_ALARM1: alarm1 interrupt + \arg RTC_INT_TAMP_ALL: tamper detection interrupt + \arg RTC_INT_WAKEUP: wakeup timer interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enable the interrupts in RTC_CTL register */ + RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_INT_TAMP_ALL); + /* enable the interrupts in RTC_TAMP register */ + RTC_TAMP |= (uint32_t)(interrupt & RTC_INT_TAMP_ALL); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be disabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM0: alarm0 interrupt + \arg RTC_INT_ALARM1: alarm1 interrupt + \arg RTC_INT_TAMP_ALL: tamper detection interrupt + \arg RTC_INT_WAKEUP: wakeup timer interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* disable the interrupts in RTC_CTL register */ + RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~(RTC_TAMP_TPIE)); + /* disable the interrupts in RTC_TAMP register */ + RTC_TAMP &= (uint32_t)~(interrupt & (RTC_TAMP_TPIE)); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief check specified flag + \param[in] flag: specify which flag to check + \arg RTC_FLAG_SCP: smooth calibration pending flag + \arg RTC_FLAG_TP1: RTC tamper 1 detected flag + \arg RTC_FLAG_TP0: RTC tamper 0 detected flag + \arg RTC_FLAG_TSOVR: time-stamp overflow flag + \arg RTC_FLAG_TS: time-stamp flag + \arg RTC_FLAG_ALARM0: alarm0 occurs flag + \arg RTC_FLAG_ALARM1: alarm1 occurs flag + \arg RTC_FLAG_WT: wakeup timer occurs flag + \arg RTC_FLAG_INIT: initialization state flag + \arg RTC_FLAG_RSYN: register synchronization flag + \arg RTC_FLAG_YCM: year configuration mark status flag + \arg RTC_FLAG_SOP: shift function operation pending flag + \arg RTC_FLAG_ALARM0W: alarm0 configuration can be written flag + \arg RTC_FLAG_ALARM1W: alarm1 configuration can be written flag + \arg RTC_FLAG_WTW: wakeup timer can be written flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtc_flag_get(uint32_t flag) +{ + FlagStatus flag_state = RESET; + + if((uint32_t)RESET != (RTC_STAT & flag)) { + flag_state = SET; + } + return flag_state; +} + +/*! + \brief clear specified flag + \param[in] flag: specify which flag to clear + \arg RTC_FLAG_TP1: RTC tamper 1 detected flag + \arg RTC_FLAG_TP0: RTC tamper 0 detected flag + \arg RTC_FLAG_TSOVR: time-stamp overflow flag + \arg RTC_FLAG_TS: time-stamp flag + \arg RTC_FLAG_WT: wakeup timer occurs flag + \arg RTC_FLAG_ALARM0: alarm0 occurs flag + \arg RTC_FLAG_ALARM1: alarm1 occurs flag + \arg RTC_FLAG_RSYN: register synchronization flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(uint32_t flag) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_STAT &= (uint32_t)(~flag); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtdec.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtdec.c new file mode 100644 index 0000000000..20b6174b76 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_rtdec.c @@ -0,0 +1,384 @@ +/*! + \file gd32h7xx_rtdec.c + \brief RTDEC driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_rtdec.h" + +/* RTDEC firmware version offset macro */ +#define ARE_FMVER_OFFSET (uint32_t)0x00000010U) + +/*! + \brief reset RTDEC + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[out] none + \retval none +*/ +void rtdec_deinit(uint32_t rtdec_periph) +{ + if(RTDEC0 == rtdec_periph){ + /* reset RTDEC0 */ + rcu_periph_reset_enable(RCU_RTDEC0RST); + rcu_periph_reset_disable(RCU_RTDEC0RST); + } + if(RTDEC1 == rtdec_periph) { + /* reset RTDEC1 */ + rcu_periph_reset_enable(RCU_RTDEC1RST); + rcu_periph_reset_disable(RCU_RTDEC1RST); + } +} + +/*! + \brief initialize the parameters of RTDEC struct with default values + \param[in] none + \param[out] rtdec_parameter_struct: the initialized struct rtdec_parameter_struct pointer + \retval none +*/ +void rtdec_struct_para_init(rtdec_parameter_struct* rtdec_struct) +{ + /* configure the structure with default value */ + rtdec_struct->access_mode = (uint8_t)RTDEC_MODE_DATA_ACCESS; + rtdec_struct->key_crc = 0x00U; + rtdec_struct->fw_version = 0x0000U; + rtdec_struct->key = 0x00000000U; + rtdec_struct->nonce = 0x00000000U; + rtdec_struct->start_addr = 0x00000000U; + rtdec_struct->end_addr = 0x00000000U; +} + +/*! + \brief initialize RTDEC + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[in] rtdec_struct: RTDEC parameter initialization stuct members of the structure + and the member values are shown as below: + access_mode: RTDEC_MODE_CODE_ACCESS, RTDEC_MODE_DATA_ACCESS, RTDEC_MODE_BOTH_ACCESS + key_crc: CRC value of area key + fw_version: area firmware version + key: area key + nonce: area nonce + start_addr: area start address + end_addr: area end address + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtdec_init(uint32_t rtdec_periph, uint32_t rtdec_area, rtdec_parameter_struct *rtdec_struct) +{ + uint8_t key_crc_reg = 0U; + uint32_t key_nonce_addr = 0U; + + /* write the correct MODE[1:0] value and firmware version in ARExCFG register */ + RTDEC_ARE_CFG(rtdec_periph, rtdec_area) &= ~(uint32_t)(RTDEC_MODE | RTDEC_ARE_FMVER); + RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= ((uint32_t)(rtdec_struct->access_mode)) | (uint32_t)(((uint32_t)(rtdec_struct->fw_version) << ARE_FMVER_OFFSET); + + /* program ARExKEY registers */ + key_nonce_addr = (uint32_t)rtdec_struct->key; + RTDEC_ARE_KEY0(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr; + key_nonce_addr += 4U; + RTDEC_ARE_KEY1(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr; + key_nonce_addr += 4U; + RTDEC_ARE_KEY2(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr; + key_nonce_addr += 4U; + RTDEC_ARE_KEY3(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr; + + /* check the key CRC */ + key_crc_reg = (uint8_t)GET_BITS(RTDEC_ARE_CFG(rtdec_periph, rtdec_area), 8U, 15U); + + if(key_crc_reg != rtdec_struct->key_crc){ + return ERROR; + } + + /* program ARExNONCE registers */ + key_nonce_addr = (uint32_t)rtdec_struct->nonce; + RTDEC_ARE_NONCE0(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr; + key_nonce_addr += 4U; + RTDEC_ARE_NONCE1(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr; + + /* write the start address and end address of area */ + RTDEC_ARE_SADDR(rtdec_periph, rtdec_area) = rtdec_struct->start_addr; + RTDEC_ARE_EADDR(rtdec_periph, rtdec_area) = rtdec_struct->end_addr; + + return SUCCESS; +} + +/*! + \brief configure RTDEC area data attribute + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[in] access_mode: allowed access mode of data + only one parameter can be selected which is shown as below: + \arg RTDEC_MODE_CODE_ACCESS: code/instruction access only + \arg RTDEC_MODE_DATA_ACCESS: data access only + \arg RTDEC_MODE_BOTH_ACCESS: code and data access + \param[in] firmware_version: 16-bit number, version of data + \param[out] none + \retval none +*/ +void rtdec_config(uint32_t rtdec_periph, uint32_t rtdec_area, uint8_t access_mode, uint16_t firmware_version) +{ + /* write the correct MODE[1:0] value and firmware version in ARExCFG register */ + RTDEC_ARE_CFG(rtdec_periph, rtdec_area) &= ~(uint32_t)(RTDEC_MODE | RTDEC_ARE_FMVER); + RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= ((uint32_t)access_mode) | ((uint32_t)((uint32_t)firmware_version << ARE_FMVER_OFFSET); +} + +/*! + \brief configure RTDEC key or register lock + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[in]: lock_type: key lock or register lock + \arg: RTDEC_ARE_CFG_LK: register lock + \arg: RTDEC_ARE_K_LK: key lock + \param[out] none + \retval none +*/ +void rtdec_lock(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t lock_type) +{ + RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= lock_type; +} + +/*! + \brief initialize RTDEC area address + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[in]: saddr: area start address, the 4 MSB bits and the 12 LSB bits are ignored + \param[in]: eaddr: area end address, the 4 MSB bits and the 12 LSB bits are ignored + \param[out] none + \retval none +*/ +void rtdec_addr_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t saddr, uint32_t eaddr) +{ + /* write the start address and end address of area */ + RTDEC_ARE_SADDR(rtdec_periph, rtdec_area) = saddr; + RTDEC_ARE_EADDR(rtdec_periph, rtdec_area) = eaddr; +} + +/*! + \brief initialize RTDEC nonce, nonce follows little endian format + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[in]: nonce: an array containing 64-bit nonce data, little endian format + \param[out] none + \retval none +*/ +void rtdec_nonce_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t* nonce) +{ + uint32_t nonce_addr = (uint32_t)nonce; + + /* program ARExNONCE registers */ + RTDEC_ARE_NONCE0(rtdec_periph, rtdec_area) = *(uint32_t *)(nonce_addr); + nonce_addr += 4U; + RTDEC_ARE_NONCE1(rtdec_periph, rtdec_area) = *(uint32_t *)(nonce_addr); +} + +/*! + \brief initialize RTDEC key, key follows little endian format + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[in]: key: an array containing 128-bit key data, little endian format + \param[out] none + \retval none +*/ +void rtdec_key_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t* key) +{ + uint32_t key_addr = (uint32_t)key; + + /* program ARExKEY registers */ + RTDEC_ARE_KEY0(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr); + key_addr += 4U; + RTDEC_ARE_KEY1(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr); + key_addr += 4U; + RTDEC_ARE_KEY2(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr); + key_addr += 4U; + RTDEC_ARE_KEY3(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr); +} + +/*! + \brief get CRC value of RTDEC key data + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[out] none + \retval CRC value +*/ +uint8_t rtdec_key_crc_get(uint32_t rtdec_periph, uint32_t rtdec_area) +{ + return (uint8_t)GET_BITS(RTDEC_ARE_CFG(rtdec_periph, rtdec_area), 8U, 15U); +} + +/*! + \brief enable RTDEC area + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[out] none + \retval none +*/ +void rtdec_enable(uint32_t rtdec_periph, uint32_t rtdec_area) +{ + RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= RTDEC_ARE_EN; +} + +/*! + \brief disable RTDEC area + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3) + \param[out] none + \retval none +*/ +void rtdec_disable(uint32_t rtdec_periph, uint32_t rtdec_area) +{ + RTDEC_ARE_CFG(rtdec_periph, rtdec_area) &= ~RTDEC_ARE_EN; +} + +/*! + \brief get RTDEC error flag + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in]: flag: error flag + only one parameter can be selected which is shown as below: + \arg RTDEC_FLAG_SEC_ERROR: security error flag + \arg RTDEC_FLAG_MODE_ERROR: access mode error flag + \arg RTDEC_FLAG_KEY_ERROR: key error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtdec_flag_get(uint32_t rtdec_periph, uint32_t flag) +{ + if(RESET != (RTDEC_INTF(rtdec_periph) & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear RTDEC error flag + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in]: flag: error flag + only one parameter can be selected which is shown as below: + \arg RTDEC_FLAG_SEC_ERROR: security error flag + \arg RTDEC_FLAG_MODE_ERROR: access mode error flag + \arg RTDEC_FLAG_KEY_ERROR: key error flag + \param[out] none + \retval none +*/ +void rtdec_flag_clear(uint32_t rtdec_periph, uint32_t flag) +{ + RTDEC_INTC(rtdec_periph) |= flag; +} + +/*! + \brief enable RTDEC interrupt + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in]: interrupt: interrupt type + one or more parameters can be selected which is shown as below: + \arg RTDEC_INT_SEC: security error interrupt + \arg RTDEC_INT_MODE: access mode error interrupt + \arg RTDEC_INT_KEY: key error interrupt + \param[out] none + \retval none +*/ +void rtdec_interrupt_enable(uint32_t rtdec_periph, uint32_t interrupt) +{ + RTDEC_INTEN(rtdec_periph) |= interrupt; +} + +/*! + \brief disable RTDEC interrupt + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in]: interrupt: interrupt type + one or more parameters can be selected which is shown as below: + \arg RTDEC_INT_SEC: security error interrupt + \arg RTDEC_INT_MODE: access mode error interrupt + \arg RTDEC_INT_KEY: key error interrupt + \param[out] none + \retval none +*/ +void rtdec_interrupt_disable(uint32_t rtdec_periph, uint32_t interrupt) +{ + RTDEC_INTEN(rtdec_periph) &= ~interrupt; +} + +/*! + \brief get RTDEC interrupt flag + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in]: int_flag: interrupt flag + only one parameter can be selected which is shown as below: + \arg RTDEC_INT_FLAG_SEC_ERROR: security error interrupt flag + \arg RTDEC_INT_FLAG_MODE_ERROR: access mode error interrupt flag + \arg RTDEC_INT_FLAG_KEY_ERROR: key error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtdec_interrupt_flag_get(uint32_t rtdec_periph, uint32_t int_flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + switch(int_flag){ + /* RTDEC security error interrupt */ + case RTDEC_INT_FLAG_SEC_ERROR: + interrupt_flag = RTDEC_INTF(rtdec_periph) & int_flag; + interrupt_enable = RTDEC_INTEN(rtdec_periph) & RTDEC_INT_SEC; + break; + /* RTDEC execute-only or execute-never error interrupt */ + case RTDEC_INT_FLAG_MODE_ERROR: + interrupt_flag = RTDEC_INTF(rtdec_periph) & int_flag; + interrupt_enable = RTDEC_INTEN(rtdec_periph) & RTDEC_INT_MODE; + break; + /* RTDEC key error interrupt */ + case RTDEC_INT_FLAG_KEY_ERROR: + interrupt_flag = RTDEC_INTF(rtdec_periph) & int_flag; + interrupt_enable = RTDEC_INTEN(rtdec_periph) & RTDEC_INT_KEY; + break; + default: + break; + } + /* get RTDEC interrupt flag status */ + if(interrupt_flag && interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear RTDEC interrupt flag + \param[in] rtdec_periph: RTDECx(x = 0, 1) + \param[in]: int_flag: interrupt flag + only one parameter can be selected which is shown as below: + \arg RTDEC_INT_FLAG_SEC_ERROR: security error interrupt flag + \arg RTDEC_INT_FLAG_MODE_ERROR: access mode error interrupt flag + \arg RTDEC_INT_FLAG_KEY_ERROR: key error interrupt flag + \param[out] none + \retval none +*/ +void rtdec_interrupt_flag_clear(uint32_t rtdec_periph, uint32_t int_flag) +{ + RTDEC_INTC(rtdec_periph) |= int_flag; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sai.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sai.c new file mode 100644 index 0000000000..8ef910aff7 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sai.c @@ -0,0 +1,792 @@ +/*! + \file gd32h7xx_sai.c + \brief SAI driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_sai.h" + +/* SAI pdm mode microphone delay mask */ +#define PDM_MICROPHONE_DELAY_MASK ((uint32_t)0x00000007U) +/*!< bit offset of MTFCNT in SAI_CFG1 */ +#define CFG1_MTFCNT_OFFSET ((uint32_t)0x00000007U) + +/*! + \brief reset SAI + \param[in] sai_periph: SAIx(x = 0,1,2) + \param[out] none + \retval none +*/ +void sai_deinit(uint32_t sai_periph) +{ + switch(sai_periph) { + case SAI0: + /* reset SAI0 */ + rcu_periph_reset_enable(RCU_SAI0RST); + rcu_periph_reset_disable(RCU_SAI0RST); + break; + case SAI1: + /* reset SAI1 */ + rcu_periph_reset_enable(RCU_SAI1RST); + rcu_periph_reset_disable(RCU_SAI1RST); + break; + case SAI2: + /* reset SAI2 */ + rcu_periph_reset_enable(RCU_SAI2RST); + rcu_periph_reset_disable(RCU_SAI2RST); + break; + default: + break; + } +} + +/*! + \brief initialize the parameter of SAI structure with a default value + \param[in] none + \param[out] sai_init_stuct: the initialization data needed to initialize SAI + \retval none +*/ +void sai_struct_para_init(sai_parameter_struct *sai_init_stuct) +{ + /* initialize the initpara struct member with the default value */ + sai_init_stuct->operating_mode = SAI_MASTER_TRANSMITTER; + sai_init_stuct->protocol = SAI_PROTOCOL_POLYMORPHIC; + sai_init_stuct->data_width = SAI_DATAWIDTH_32BIT; + sai_init_stuct->shift_dir = SAI_SHIFT_MSB; + sai_init_stuct->sample_edge = SAI_SAMPEDGE_FALLING; + sai_init_stuct->sync_mode = SAI_SYNCMODE_ASYNC; + sai_init_stuct->output_drive = SAI_OUTPUT_WITH_SAIEN; + sai_init_stuct->clk_div_bypass = SAI_CLKDIV_BYPASS_OFF; + sai_init_stuct->mclk_div = SAI_MCLKDIV_1; + sai_init_stuct->mclk_oversampling = SAI_MCLK_OVERSAMP_256; + sai_init_stuct->mclk_enable = SAI_MCLK_DISABLE; + sai_init_stuct->fifo_threshold = SAI_FIFOTH_EMPTY; +} + +/*! + \brief initialize the parameter of SAI frame structure with a default value + \param[in] none + \param[out] sai_frame_init_struct: the initialization data needed to initialize SAI frame + \retval none +*/ +void sai_frame_struct_para_init(sai_frame_parameter_struct *sai_frame_init_struct) +{ + /* initialize the initpara struct member with the default value */ + sai_frame_init_struct->frame_width = 256U; + sai_frame_init_struct->frame_sync_width = 128U; + sai_frame_init_struct->frame_sync_function = SAI_FS_FUNC_START; + sai_frame_init_struct->frame_sync_polarity = SAI_FS_POLARITY_LOW; + sai_frame_init_struct->frame_sync_offset = SAI_FS_OFFSET_BEGINNING; +} + +/*! + \brief initialize the parameter of SAI slot structure with a default value + \param[in] none + \param[out] sai_slot_init_struct: the initialization data needed to initialize SAI slot + \retval none +*/ +void sai_slot_struct_para_init(sai_slot_parameter_struct *sai_slot_init_struct) +{ + /* initialize the initpara struct member with the default value */ + sai_slot_init_struct->slot_number = 16U; + sai_slot_init_struct->slot_width = SAI_SLOT_WIDTH_DATA; + sai_slot_init_struct->data_offset = 0U; + sai_slot_init_struct->slot_active = SAI_SLOT_ACTIVE_NONE; +} + +/*! + \brief initialize SAI + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x = 0,1) + \param[in] sai_struct: SAI parameter initialization stuct members of the structure + and the member values are shown as below: + operating_mode: SAI_MASTER_TRANSMITTER, SAI_MASTER_RECEIVER, SAI_SLAVE_TRANSMITTER, SAI_SLAVE_RECEIVER; + protocol: SAI_PROTOCOL_POLYMORPHIC, SAI_PROTOCOL_SPDIF, SAI_PROTOCOL_AC97 + data_width: SAI_DATA_WIDTH_xBIT (x = 8, 10, 16, 20, 24, 32) + shift_dir: SAI_SHIFT_MSB, SAI_SHIFT_LSB + sample_edge: SAI_SAMPEDGE_FALLING, SAI_SAMPEDGE_RISING + sync_mode: SAI_SYNCMODE_ASYNC, SAI_SYNCMODE_OTHERBLOCK, SAI_SYNCMODE_EXTERNALSAI + output_drive: SAI_OUTPUT_WITH_SAIEN, SAI_OUTPUT_NOW + clk_div_bypass: SAI_CLKDIV_BYPASS_OFF, SAI_CLKDIV_BYPASS_ON + mck_div: SAI_MCLKDIV_x (x = 1,2,..,63) + mck_oversampling: SAI_MASTERCLK_OVERSAMP_256, SAI_MASTERCLK_OVERSAMP_512 + mck_enable: SAI_MASTERCLK_DISABLE, SAI_MASTERCLK_ENABLE + fifo_threshold: SAI_FIFOTH_EMPTY, SAI_FIFOTH_QUARTER, SAI_FIFOTH_HALF, SAI_FIFOTH_THREE_QUARTER, SAI_FIFOTH_FULL + \param[out] none + \retval none +*/ +void sai_init(uint32_t sai_periph, uint32_t block, sai_parameter_struct *sai_struct) +{ + uint32_t reg = 0U; + + /* configure the SAI CFGR0 value */ + reg = SAI_CFG0(sai_periph, block); + reg &= ~(SAI_CFG0_OPTMOD | SAI_CFG0_PROT | \ + SAI_CFG0_DATAWD | SAI_CFG0_SHIFTDIR | \ + SAI_CFG0_SAMPEDGE | SAI_CFG0_SYNCMOD | \ + SAI_CFG0_ODRIV | SAI_CFG0_BYPASS | \ + SAI_CFG0_MDIV | SAI_CFG0_MOSPR | \ + SAI_CFG0_MCLKEN | SAI_CFG0_SAIEN); + + reg |= (uint32_t)(sai_struct->operating_mode | sai_struct->protocol | \ + sai_struct->data_width | sai_struct->shift_dir | \ + sai_struct->sample_edge | sai_struct->sync_mode | \ + sai_struct->output_drive | sai_struct->clk_div_bypass | \ + sai_struct->mclk_div | sai_struct->mclk_oversampling | \ + sai_struct->mclk_enable); + SAI_CFG0(sai_periph, block) = reg; + + /* configure the SAI CFGR1 FIFO threshold */ + reg = SAI_CFG1(sai_periph, block); + reg &= ~SAI_CFG1_FFTH; + reg |= (uint32_t)(sai_struct->fifo_threshold); + SAI_CFG1(sai_periph, block) = reg; +} + +/*! + \brief initialize SAI frame + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] sai_frame_struct: SAI frame parameter initialization stuct members of the structure + and the member values are shown as below: + frame_width: 1~256, frame width + frame_sync_width: 1~128, frame synchronization active width + frame_sync_function: SAI_FS_FUNC_START, SAI_FS_FUNC_START_CHANNEL + frame_sync_polarity: SAI_FS_POLARITY_LOW, SAI_FS_POLARITY_HIGH + frame_sync_offset: SAI_FS_OFFSET_BEGINNING, SAI_FS_OFFSET_ONEBITBEFORE + \param[out] none + \retval none +*/ +void sai_frame_init(uint32_t sai_periph, uint32_t block, sai_frame_parameter_struct *sai_frame_struct) +{ + uint32_t reg = 0U; + reg = SAI_FCFG(sai_periph, block); + reg &= ~(SAI_FCFG_FWD | SAI_FCFG_FSAWD | SAI_FCFG_FSFUNC | \ + SAI_FCFG_FSPL | SAI_FCFG_FSOST); + reg |= (uint32_t)(sai_frame_struct->frame_sync_offset | \ + sai_frame_struct->frame_sync_polarity | \ + sai_frame_struct->frame_sync_function | \ + ((sai_frame_struct->frame_sync_width - 1U) << 8U) | \ + (sai_frame_struct->frame_width - 1U)); + /* config the SAI freame */ + SAI_FCFG(sai_periph, block) = reg; +} + +/*! + \brief initialize SAI slot + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] sai_slot_struct: SAI slot parameter initialization stuct members of the structure + and the member values are shown as below: + slot_number: 1~16, slot number + slot_width: SAI_SLOTWIDTH_DATA, SAI_SLOTWIDTH_16BIT, SAI_SLOTWIDTH_32BIT + data_offset: 0~31, data offset + slot_active: one or more parameters can be selected, SAI_SLOT_ACTIVE_NONE, SAI_SLOT_ACTIVE_x(x=0..15), SAI_SLOT_ACTIVE_ALL + \param[out] none + \retval none +*/ +void sai_slot_init(uint32_t sai_periph, uint32_t block, sai_slot_parameter_struct *sai_slot_struct) +{ + uint32_t reg = 0U; + reg = SAI_SCFG(sai_periph, block); + reg &= ~(SAI_SCFG_DATAOST | SAI_SCFG_SLOTWD | SAI_SCFG_SLOTNUM | SAI_SCFG_SLOTAV); + reg = (uint32_t)(((sai_slot_struct->slot_number - 1U) << 8U) | \ + sai_slot_struct->slot_width | \ + sai_slot_struct->data_offset | \ + sai_slot_struct->slot_active); + /* configure the SAI slot */ + SAI_SCFG(sai_periph, block) = reg; +} + +/*! + \brief SAI enable + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[out] none + \retval none +*/ +void sai_enable(uint32_t sai_periph, uint32_t block) +{ + SAI_CFG0(sai_periph, block) |= SAI_CFG0_SAIEN; +} + +/*! + \brief SAI disable + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[out] none + \retval none +*/ +void sai_disable(uint32_t sai_periph, uint32_t block) +{ + SAI_CFG0(sai_periph, block) &= ~SAI_CFG0_SAIEN; +} + +/*! + \brief SAI serial data near inactive slot output management + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] sdout: serial data output management + only one parameter can be selected which is shown as below: + \arg SAI_SDLINE_DRIVE: SD line output is driven entirely during the audio frame + \arg SAI_SDLINE_RELEASE: SD line output is released near inactive slots + \param[out] none + \retval none +*/ +void sai_sdoutput_config(uint32_t sai_periph, uint32_t block, uint32_t sdout) +{ + SAI_CFG1(sai_periph, block) &= ~SAI_CFG1_SDOM; + SAI_CFG1(sai_periph, block) |= sdout; +} + +/*! + \brief configure SAI mono mode + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[in] mono: stereo and mono mode selection + only one parameter can be selected which is shown as below: + \arg SAI_STEREO_MODE: stereo mode + \arg SAI_MONO_MODE: mono mode + \param[out] none + \retval none +*/ +void sai_monomode_config(uint32_t sai_periph, uint32_t block, uint32_t mono) +{ + SAI_CFG0(sai_periph, block) &= ~SAI_CFG0_MONO; + SAI_CFG0(sai_periph, block) |= mono ; +} + +/*! + \brief configure SAI companding mode + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[in] compander: compander mode + only one parameter can be selected which is shown as below: + \arg SAI_COMPANDER_OFF: no compansion applies + \arg SAI_COMPANDER_ULAW: u-law algorithm + \arg SAI_COMPANDER_ALAW: A-law algorithm + \param[in] complement:complement mode + only one parameter can be selected which is shown as below: + \arg SAI_COMPLEMENT_1S: data represented in 1's complement form + \arg SAI_COMPLEMENT_2S: data represented in 2's complement form + \param[out] none + \retval none +*/ +void sai_companding_config(uint32_t sai_periph, uint32_t block, uint32_t compander, + uint32_t complement) +{ + uint32_t reg = 0U; + reg = SAI_CFG1(sai_periph, block); + reg &= ~(SAI_CFG1_CPLMOD | SAI_CFG1_CPAMOD); + reg |= (compander | complement); + SAI_CFG1(sai_periph, block) = reg; +} + +/*! + \brief SAI mute detected enable or mute send enable + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[out] none + \retval none +*/ +void sai_mute_enable(uint32_t sai_periph, uint32_t block) +{ + SAI_CFG1(sai_periph, block) |= SAI_CFG1_MT; +} + +/*! + \brief SAI mute detected disable or mute send disable + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[out] none + \retval none +*/ +void sai_mute_disable(uint32_t sai_periph, uint32_t block) +{ + SAI_CFG1(sai_periph, block) &= ~SAI_CFG1_MT; +} + +/*! + \brief configure SAI mute value + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[in] value: mute value + only one parameter can be selected which are shown as below: + \arg SAI_MUTESENT_0: 0 is sent via the serial data line when mute is on + \arg SAI_MUTESENT_LASTFREAM: If SLOTNUM is less or equals to two, last frame is sent via the serial data line + \param[out] none + \retval none +*/ +void sai_mute_value_config(uint32_t sai_periph, uint32_t block, uint32_t value) +{ + SAI_CFG1(sai_periph, block) &= ~SAI_CFG1_MTVAL; + SAI_CFG1(sai_periph, block) |= value; +} + +/*! + \brief configure SAI mute frame count + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[in] count: 0~63, mute frame count + \param[out] none + \retval none +*/ +void sai_mute_count_config(uint32_t sai_periph, uint32_t block, uint32_t count) +{ + uint32_t reg = 0U; + reg = SAI_CFG1(sai_periph, block); + reg &= ~SAI_CFG1_MTFCNT; + reg |= count << CFG1_MTFCNT_OFFSET; + SAI_CFG1(sai_periph, block) = reg; +} + +/*! + \brief SAI transmit data + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[in] data: 32-bit data + \param[out] none + \retval none +*/ +void sai_data_transmit(uint32_t sai_periph, uint32_t block, uint32_t data) +{ + SAI_DATA(sai_periph, block) = data; +} + +/*! + \brief SAI receive data + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[out] none + \retval received data +*/ +uint32_t sai_data_receive(uint32_t sai_periph, uint32_t block) +{ + return SAI_DATA(sai_periph, block); +} + +/*! + \brief get SAI fifo status + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[out] none + \retval state of fifo + \arg FIFO_EMPTY: empty + \arg FIFO_EMPTY_TO_1_4_FULL: empty < fifo_level <= 1/4_full + \arg FIFO_1_4_FULL_TO_1_2_FULL: 1/4_full < fifo_level <= 1/2_full + \arg FIFO_1_2_FULL_TO_3_4_FULL: 1/2_full < fifo_level <= 3/4_full + \arg FIFO_3_4_FULL_TO_FULL: 3/4_full < fifo_level < full + \arg FIFO_FULL: full +*/ +sai_fifo_state_enum sai_fifo_status_get(uint32_t sai_periph, uint32_t block) +{ + sai_fifo_state_enum sai_fifo_state = FIFO_EMPTY; + + if(SAI_FIFO_STAT_EMPTY == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) { + sai_fifo_state = FIFO_EMPTY; + } else if(SAI_FIFO_STAT_QUARTER == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) { + sai_fifo_state = FIFO_EMPTY_TO_1_4_FULL; + } else if(SAI_FIFO_STAT_HALF == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) { + sai_fifo_state = FIFO_1_4_FULL_TO_1_2_FULL; + } else if(SAI_FIFO_STAT_THREE_QUARTER == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) { + sai_fifo_state = FIFO_1_2_FULL_TO_3_4_FULL; + } else if(SAI_FIFO_STAT_NEARFULL == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) { + sai_fifo_state = FIFO_3_4_FULL_TO_FULL; + } else { + sai_fifo_state = FIFO_FULL; + } + + return sai_fifo_state; +} + +/*! + \brief SAI fifo flush + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[out] none + \retval none +*/ +void sai_fifo_flush(uint32_t sai_periph, uint32_t block) +{ + SAI_CFG1(sai_periph, block) |= SAI_CFG1_FLUSH; +} + +/*! + \brief enable SAI dma + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[out] none + \retval none +*/ +void sai_dma_enable(uint32_t sai_periph, uint32_t block) +{ + SAI_CFG0(sai_periph, block) |= SAI_CFG0_DMAEN; +} + +/*! + \brief disable SAI dma + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx (x=0,1) + \param[out] none + \retval none +*/ +void sai_dma_disable(uint32_t sai_periph, uint32_t block) +{ + SAI_CFG0(sai_periph, block) &= ~SAI_CFG0_DMAEN; +} + +/*! + \brief SAI synchronization input select + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] input: specify which external SAI to be select for synchronization + only one parameter can be selected which are shown as below: + \arg SAI_SYNCINPUT_SAI0: SAI1 or SAI2 selects the synchronization coming from SAI0 + \arg SAI_SYNCINPUT_SAI1: SAI0 or SAI2 selects the synchronization coming from SAI1 + \arg SAI_SYNCINPUT_SAI2: SAI0 or SAI1 selects the synchronization coming from SAI2 + \param[out] none + \retval none +*/ +void sai_sync_input_config(uint32_t sai_periph, uint32_t input) +{ + uint32_t reg = 0U; + reg = SAI_SYNCFG(sai_periph); + reg &= ~SAI_SYNCFG_SYNI; + reg |= input; + SAI_SYNCFG(sai_periph) = reg; +} + +/*! + \brief SAI synchronization output select + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] output: specify which block to be used for further synchronization for others SAI + only one parameter can be selected which are shown as below: + \arg SAI_SYNCOUTPUT_OFF: no synchronization output signals + \arg SAI_SYNCOUTPUT_BLOCK0: block 0 used for further synchronization for others SAI + \arg SAI_SYNCOUTPUT_BLOCK1: block 1 used for further synchronization for others SAI + \param[out] none + \retval none +*/ +void sai_sync_output_config(uint32_t sai_periph, uint32_t output) +{ + uint32_t reg = 0U; + reg = SAI_SYNCFG(sai_periph); + reg &= ~SAI_SYNCFG_SYNO; + reg |= output; + SAI_SYNCFG(sai_periph) = reg; +} + +/*! + \brief enable SAI pdm mode + \param[in] sai_periph: SAIx(x=0,1,2) + \param[out] none + \retval none +*/ +void sai_pdm_enable(uint32_t sai_periph) +{ + SAI_PDMCTL(sai_periph) |= SAI_PDMCTL_PDMEN; +} + +/*! + \brief disable SAI pdm mode + \param[in] sai_periph: SAIx(x=0,1,2) + \param[out] none + \retval none +*/ +void sai_pdm_disable(uint32_t sai_periph) +{ + SAI_PDMCTL(sai_periph) &= ~SAI_PDMCTL_PDMEN; +} + +/*! + \brief configure SAI pdm mode microphone number + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] microphonenum: 2, 4, 6 or 8(not applicable to GD32H7xx), select microphones number + \param[out] none + \retval none +*/ +void sai_pdm_microphone_number_config(uint32_t sai_periph, uint32_t microphonenum) +{ + uint32_t temp = SAI_PDMCTL(sai_periph); + temp &= ~SAI_PDMCTL_MICNUMSEL; + temp |= ((microphonenum / 2U - 1U) << 4U); + SAI_PDMCTL(sai_periph) = temp; +} + +/*! + \brief configure SAI pdm mode microphone delay + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] microphone: specify which microphone delay parameter to config + only one parameter can be selected which are shown as below: + \arg SAI_PDM_MICROPHONE0_L: microphone 0 channel left + \arg SAI_PDM_MICROPHONE0_R: microphone 0 channel right + \arg SAI_PDM_MICROPHONE1_L: microphone 1 channel left + \arg SAI_PDM_MICROPHONE1_R: microphone 1 channel right + \arg SAI_PDM_MICROPHONE2_L: microphone 2 channel left + \arg SAI_PDM_MICROPHONE2_R: microphone 2 channel right + \arg SAI_PDM_MICROPHONE3_L: microphone 3 channel left, (not applicable to GD32H7xx) + \arg SAI_PDM_MICROPHONE3_R: microphone 3 channel right, (not applicable to GD32H7xx) + \param[in] delay: 0~7, the microphone data flow delay period + \param[out] none + \retval none +*/ +void sai_pdm_delay_config(uint32_t sai_periph, uint32_t microphone, uint32_t delay) +{ + uint32_t temp = SAI_PDMCFG(sai_periph); + temp &= ~(PDM_MICROPHONE_DELAY_MASK << (microphone * 4U)); + temp |= (delay << (microphone * 4U)); + SAI_PDMCFG(sai_periph) = temp; +} + +/*! + \brief enable SAI pdm mode clock line 0 + \param[in] sai_periph: SAIx(x=0,1,2) + \param[out] none + \retval none +*/ +void sai_pdm_clk0_enable(uint32_t sai_periph) +{ + SAI_PDMCTL(sai_periph) |= SAI_PDMCTL_CLKL0EN; +} + +/*! + \brief disable SAI pdm mode clock line 0 + \param[in] sai_periph: SAIx(x=0,1,2) + \param[out] none + \retval none +*/ +void sai_pdm_clk0_disable(uint32_t sai_periph) +{ + SAI_PDMCTL(sai_periph) &= ~SAI_PDMCTL_CLKL0EN; +} + +/*! + \brief enable SAI pdm mode clock line 1 + \param[in] sai_periph: SAIx(x=0,1,2) + \param[out] none + \retval none +*/ +void sai_pdm_clk1_enable(uint32_t sai_periph) +{ + SAI_PDMCTL(sai_periph) |= SAI_PDMCTL_CLKL1EN; +} + +/*! + \brief disable SAI pdm mode clock line 1 + \param[in] sai_periph: SAIx(x=0,1,2) + \param[out] none + \retval none +*/ +void sai_pdm_clk1_disable(uint32_t sai_periph) +{ + SAI_PDMCTL(sai_periph) &= ~SAI_PDMCTL_CLKL1EN; +} + +/*! + \brief enable the SAI interrupt + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] interrupt: specify which interrupt to enable + one or more parameters can be selected which are shown as below: + \arg SAI_INT_OUERR: FIFO overrun or underrun interrupt enable + \arg SAI_INT_MTDET: mute detection interrupt enable + \arg SAI_INT_ERRCK: error clock interrupt enable + \arg SAI_INT_FFREQ: FIFO request interrupt enable + \arg SAI_INT_ACNRDY: audio codec not ready interrupt enable + \arg SAI_INT_FSADET: frame synchronization advanced detection interrupt enable + \arg SAI_INT_FSPDET: frame synchronization postpone detection interrupt enable + \param[out] none + \retval none +*/ +void sai_interrupt_enable(uint32_t sai_periph, uint32_t block, uint32_t interrupt) +{ + SAI_INTEN(sai_periph, block) |= interrupt; +} + +/*! + \brief disable the SAI interrupt + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] interrupt: specify which interrupt to disable + one or more parameters can be selected which are shown as below: + \arg SAI_INT_OUERR: FIFO overrun or underrun interrupt + \arg SAI_INT_MTDET: mute detection interrupt + \arg SAI_INT_ERRCK: error clock interrupt + \arg SAI_INT_FFREQ: FIFO request interrupt + \arg SAI_INT_ACNRDY: audio codec not ready interrupt + \arg SAI_INT_FSADET: frame synchronization advanced detection interrupt + \arg SAI_INT_FSPDET: frame synchronization postpone detection interrupt + \param[out] none + \retval none +*/ +void sai_interrupt_disable(uint32_t sai_periph, uint32_t block, uint32_t interrupt) +{ + SAI_INTEN(sai_periph, block) &= ~interrupt; +} + +/*! + \brief get the SAI interrupt flag + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] interrupt: specify which interrupt flag to get + only one parameter can be selected which are shown as below: + \arg SAI_FLAG_OUERR: FIFO overrun or underrun interrupt flag + \arg SAI_FLAG_MTDET: mute detection interrupt flag + \arg SAI_FLAG_ERRCK: error clock interrupt flag + \arg SAI_FLAG_FFREQ: FIFO request interrupt flag + \arg SAI_FLAG_ACNRDY: audio codec not ready interrupt flag + \arg SAI_FLAG_FSADET: frame synchronization advanced detection interrupt flag + \arg SAI_FLAG_FSPDET: frame synchronization postpone detection interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sai_interrupt_flag_get(uint32_t sai_periph, uint32_t block, uint32_t interrupt) +{ + uint32_t inten = 0U; + inten = SAI_INTEN(sai_periph, block) & interrupt; + if((RESET != (SAI_STAT(sai_periph, block) & interrupt)) && (RESET != inten)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the SAI interrupt flag + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] interrupt: specify which interrupt flag to clear + one or more parameters can be selected which are shown as below: + \arg SAI_FLAG_OUERR: FIFO overrun or underrun interrupt flag + \arg SAI_FLAG_MTDET: mute detection interrupt flag + \arg SAI_FLAG_ERRCK: error clock interrupt flag + \arg SAI_FLAG_ACNRDY: audio codec not ready interrupt flag + \arg SAI_FLAG_FSADET: frame synchronization advanced detection interrupt flag + \arg SAI_FLAG_FSPDET: frame synchronization postpone detection interrupt flag + \param[out] none + \retval none +*/ +void sai_interrupt_flag_clear(uint32_t sai_periph, uint32_t block, uint32_t interrupt) +{ + SAI_INTC(sai_periph, block) = interrupt; +} + +/*! + \brief get the SAI flag + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] flag: specify which flag to get + only one parameter can be selected which are shown as below: + \arg SAI_FLAG_OUERR: FIFO overrun or underrun flag + \arg SAI_FLAG_MTDET: mute detection flag + \arg SAI_FLAG_ERRCK: error clock flag + \arg SAI_FLAG_FFREQ: FIFO request flag + \arg SAI_FLAG_ACNRDY: audio codec not ready flag + \arg SAI_FLAG_FSADET: frame synchronization advanced detection flag + \arg SAI_FLAG_FSPDET: frame synchronization postpone detection flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sai_flag_get(uint32_t sai_periph, uint32_t block, uint32_t flag) +{ + if(RESET != (SAI_STAT(sai_periph, block) & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the SAI flag + \param[in] sai_periph: SAIx(x=0,1,2) + \param[in] block: specify which bolck is initialized + only one parameter can be selected which is shown as below: + \arg SAI_BLOCKx(x=0,1) + \param[in] flag: specify which flag to clear + one or more parameters can be selected which are shown as below: + \arg SAI_FLAG_OUERR: FIFO overrun or underrun flag + \arg SAI_FLAG_MTDET: mute detection flag + \arg SAI_FLAG_ERRCK: error clock flag + \arg SAI_FLAG_ACNRDY: audio codec not ready flag + \arg SAI_FLAG_FSADET: frame synchronization advanced detection flag + \arg SAI_FLAG_FSPDET: frame synchronization postpone detection flag + \param[out] none + \retval none +*/ +void sai_flag_clear(uint32_t sai_periph, uint32_t block, uint32_t flag) +{ + SAI_INTC(sai_periph, block) = flag; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sdio.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sdio.c new file mode 100644 index 0000000000..da54fd723e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_sdio.c @@ -0,0 +1,1032 @@ +/*! + \file gd32h7xx_sdio.c + \brief SDIO driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_sdio.h" + +/* IDMA buffer value offset macro */ +#define SDIO_IDMACTL_IDMASIZE_OFFSET ((uint32_t)5U) + +/*! + \brief deinitialize the SDIO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_deinit(uint32_t sdio_periph) +{ + switch(sdio_periph) { + /* reset SDIO0 */ + case SDIO0: + rcu_periph_reset_enable(RCU_SDIO0RST); + rcu_periph_reset_disable(RCU_SDIO0RST); + break; + /* reset SDIO1 */ + case SDIO1: + rcu_periph_reset_enable(RCU_SDIO1RST); + rcu_periph_reset_disable(RCU_SDIO1RST); + break; + default: + break; + } +} + +/*! + \brief configure the SDIO clock + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] clock_edge: SDIO_CLK clock edge + only one parameter can be selected which is shown as below: + \arg SDIO_SDIOCLKEDGE_RISING: select the rising edge of the SDIOCLK to generate SDIO_CLK + \arg SDIO_SDIOCLKEDGE_FALLING: select the falling edge of the SDIOCLK to generate SDIO_CLK + \param[in] clock_powersave: SDIO_CLK clock dynamic switch on/off for power saving + only one parameter can be selected which is shown as below: + \arg SDIO_CLOCKPWRSAVE_ENABLE: SDIO_CLK closed when bus is idle + \arg SDIO_CLOCKPWRSAVE_DISABLE: SDIO_CLK clock is always on + \param[in] clock_division: clock division, less than 1024 + \param[out] none + \retval none +*/ +void sdio_clock_config(uint32_t sdio_periph, uint32_t clock_edge, uint32_t clock_powersave, uint32_t clock_division) +{ + uint32_t clock_config = 0U; + clock_config = SDIO_CLKCTL(sdio_periph); + /* reset the CLKEDGE, CLKPWRSAV, DIV */ + clock_config &= ~(SDIO_CLKCTL_CLKEDGE | SDIO_CLKCTL_CLKPWRSAV | SDIO_CLKCTL_DIV); + /* configure the SDIO_CLKCTL according to the parameters */ + clock_config |= (clock_edge | clock_powersave | clock_division); + SDIO_CLKCTL(sdio_periph) = clock_config; +} + +/*! + \brief set receive clock + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] clock_receive: SDIO_CLK receive clock selection + only one parameter can be selected which is shown as below: + \arg SDIO_RECEIVECLOCK_INCLK: select SDIO_IN_CLK clock + \arg SDIO_RECEIVECLOCK_CLKIN: select SDIO_CLKIN clock + \arg SDIO_RECEIVECLOCK_FBCLK: select SDIO_FB_CLK clock + \param[out] none + \retval none +*/ +void sdio_clock_receive_set(uint32_t sdio_periph, uint32_t clock_receive) +{ + uint32_t clock_config = 0U; + clock_config = SDIO_CLKCTL(sdio_periph); + /* reset the RCLK */ + clock_config &= ~SDIO_CLKCTL_RCLK; + /* configure the SDIO_CLKCTL according to the parameters */ + clock_config |= clock_receive; + SDIO_CLKCTL(sdio_periph) = clock_config; +} + +/*! + \brief enable hardware clock control + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_hardware_clock_enable(uint32_t sdio_periph) +{ + SDIO_CLKCTL(sdio_periph) |= SDIO_CLKCTL_HWEN; +} + +/*! + \brief disable hardware clock control + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_hardware_clock_disable(uint32_t sdio_periph) +{ + SDIO_CLKCTL(sdio_periph) &= ~SDIO_CLKCTL_HWEN; +} + +/*! + \brief set different SDIO card bus mode + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] bus_mode: SDIO card bus mode + only one parameter can be selected which is shown as below: + \arg SDIO_BUSMODE_1BIT: 1-bit SDIO card bus mode + \arg SDIO_BUSMODE_4BIT: 4-bit SDIO card bus mode + \arg SDIO_BUSMODE_8BIT: 8-bit SDIO card bus mode + \param[out] none + \retval none +*/ +void sdio_bus_mode_set(uint32_t sdio_periph, uint32_t bus_mode) +{ + /* reset the SDIO card bus mode bits */ + SDIO_CLKCTL(sdio_periph) &= ~SDIO_CLKCTL_BUSMODE; + /* set the bus mode according to bus_mode */ + SDIO_CLKCTL(sdio_periph) |= bus_mode; +} + +/*! + \brief set SDIO bus speed + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] bus_mode: SDIO card bus speed + only one parameter can be selected which is shown as below: + \arg SDIO_BUSSPEED_LOW: DS, HS, SDR12, SDR25 bus speed + \arg SDIO_BUSSPEED_HIGH: SDR50, SDR104, DDR50 bus speed + \param[out] none + \retval none +*/ +void sdio_bus_speed_set(uint32_t sdio_periph, uint32_t bus_speed) +{ + /* reset the SDIO card bus speed bits */ + SDIO_CLKCTL(sdio_periph) &= ~SDIO_CLKCTL_BUSSP; + /* set the bus mode according to bus_mode */ + SDIO_CLKCTL(sdio_periph) |= bus_speed; +} + +/*! + \brief set SDIO data rate + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] data_rate: SDIO card data rate + only one parameter can be selected which is shown as below: + \arg SDIO_DATA_RATE_SDR: SDR bus mode selected + \arg SDIO_DATA_RATE_DDR: DDR bus mode selected + \param[out] none + \retval none +*/ +void sdio_data_rate_set(uint32_t sdio_periph, uint32_t data_rate) +{ + /* reset the SDIO card data rate */ + SDIO_CLKCTL(sdio_periph) &= ~SDIO_CLKCTL_DRSEL; + /* set the bus mode according to data_rate */ + SDIO_CLKCTL(sdio_periph) |= data_rate; +} + +/*! + \brief set direction polarity of data and command + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] dirpl: SDIO direction polarity + only one parameter can be selected which is shown as below: + \arg SDIO_DIRECTION_SIGNAL_LOW: direction signal is low, the voltage transceiver IOs driven as output + \arg SDIO_DIRECTION_SIGNAL_HIGH: direction signal is high, the voltage transceiver IOs driven as output + \param[out] none + \retval none +*/ +void sdio_direction_polarity_set(uint32_t sdio_periph, uint32_t dirpl) +{ + /* reset the SDIO_PWRCTL_DIRPS */ + SDIO_PWRCTL(sdio_periph) &= ~SDIO_PWRCTL_DIRPS; + /* set the direction polarity according to dirpl */ + SDIO_PWRCTL(sdio_periph) |= dirpl; +} + +/*! + \brief set the SDIO power state + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] power_state: SDIO power state + only one parameter can be selected which is shown as below: + \arg SDIO_POWER_ON: SDIO power on + \arg SDIO_POWER_CYCLE:SDIO power cycle + \arg SDIO_POWER_OFF: SDIO power off + \param[out] none + \retval none +*/ +void sdio_power_state_set(uint32_t sdio_periph, uint32_t power_state) +{ + /* set SDIO_PWRCTL according to power_state */ + SDIO_PWRCTL(sdio_periph) &= ~SDIO_PWRCTL_PWRCTL; + SDIO_PWRCTL(sdio_periph) |= power_state; +} + +/*! + \brief get the SDIO power state + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval SDIO power state +*/ +uint32_t sdio_power_state_get(uint32_t sdio_periph) +{ + return SDIO_PWRCTL(sdio_periph); +} + +/*! + \brief configure the command and response + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] cmd_index: command index, refer to the related specifications + \param[in] cmd_argument: command argument, refer to the related specifications + \param[in] response_type: response type + only one parameter can be selected which is shown as below: + \arg SDIO_RESPONSETYPE_NO: no response + \arg SDIO_RESPONSETYPE_SHORT: short response + \arg SDIO_RESPONSETYPE_SHORT_NOCRC: short response without CRC + \arg SDIO_RESPONSETYPE_LONG: long response + \param[out] none + \retval none +*/ +void sdio_command_response_config(uint32_t sdio_periph, uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type) +{ + uint32_t cmd_config = 0U; + /* disable the CSM */ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_CSMEN; + /* reset the command index, command argument and response type */ + SDIO_CMDAGMT(sdio_periph) &= ~SDIO_CMDAGMT_CMDAGMT; + SDIO_CMDAGMT(sdio_periph) = cmd_argument; + cmd_config = SDIO_CMDCTL(sdio_periph); + cmd_config &= ~(SDIO_CMDCTL_CMDIDX | SDIO_CMDCTL_CMDRESP); + /* configure SDIO_CMDCTL and SDIO_CMDAGMT according to the parameters */ + cmd_config |= (cmd_index | response_type); + SDIO_CMDCTL(sdio_periph) = cmd_config; +} + +/*! + \brief set the command state machine wait type + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] wait_type: wait type + only one parameter can be selected which is shown as below: + \arg SDIO_WAITTYPE_NO: not wait interrupt + \arg SDIO_WAITTYPE_INTERRUPT: wait interrupt + \arg SDIO_WAITTYPE_DATAEND: wait the end of data transfer + \param[out] none + \retval none +*/ +void sdio_wait_type_set(uint32_t sdio_periph, uint32_t wait_type) +{ + /* reset INTWAIT and WAITDEND */ + SDIO_CMDCTL(sdio_periph) &= ~(SDIO_CMDCTL_INTWAIT | SDIO_CMDCTL_WAITDEND); + /* set the wait type according to wait_type */ + SDIO_CMDCTL(sdio_periph) |= wait_type; +} + +/*! + \brief enable the CSM transfer command mode(treats the command as a data transfer command) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_trans_start_enable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) |= SDIO_CMDCTL_TREN; +} + +/*! + \brief disable the CSM transfer command mode(treats the command as a data transfer command) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_trans_start_disable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_TREN; +} + +/*! + \brief enable the CSM stop command mode(treats the command as a data stop transfer command) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_trans_stop_enable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) |= SDIO_CMDCTL_TRSTOP; +} + +/*! + \brief disable the CSM stop command mode(treats the command as a data stop transfer command) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_trans_stop_disable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_TRSTOP; +} + +/*! + \brief enable the CSM(command state machine) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_csm_enable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) |= SDIO_CMDCTL_CSMEN; +} + +/*! + \brief disable the CSM(command state machine) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_csm_disable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_CSMEN; +} + +/*! + \brief get the last response command index + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval last response command index +*/ +uint8_t sdio_command_index_get(uint32_t sdio_periph) +{ + return (uint8_t)SDIO_RSPCMDIDX(sdio_periph); +} + +/*! + \brief get the response for the last received command + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] sdio_responsex: SDIO response + only one parameter can be selected which is shown as below: + \arg SDIO_RESPONSE0: card response[31:0]/card response[127:96] + \arg SDIO_RESPONSE1: card response[95:64] + \arg SDIO_RESPONSE2: card response[63:32] + \arg SDIO_RESPONSE3: card response[31:1], plus bit 0 + \param[out] none + \retval response for the last received command +*/ +uint32_t sdio_response_get(uint32_t sdio_periph, uint32_t sdio_responsex) +{ + uint32_t resp_content = 0U; + + /* get the content of the last response */ + switch(sdio_responsex) { + case SDIO_RESPONSE0: + resp_content = SDIO_RESP0(sdio_periph); + break; + case SDIO_RESPONSE1: + resp_content = SDIO_RESP1(sdio_periph); + break; + case SDIO_RESPONSE2: + resp_content = SDIO_RESP2(sdio_periph); + break; + case SDIO_RESPONSE3: + resp_content = SDIO_RESP3(sdio_periph); + break; + default: + break; + } + return resp_content; +} + +/*! + \brief disable the DSM status hold + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_hold_enable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) |= SDIO_CMDCTL_HOLD; +} + +/*! + \brief enable the DSM status hold + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_hold_disable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_HOLD; +} + +/*! + \brief enable the SDIO suspend mode (the CSM treats the command as a Suspend command or Resume command) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_suspend_enable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) |= SDIO_CMDCTL_CMDSR; +} + +/*! + \brief disable the SDIO suspend mode (the CSM treats the command as a Suspend command or Resume command) + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_suspend_disable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_CMDSR; +} + +/*! + \brief configure the data timeout, data length and data block size + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] data_timeout: data timeout period in card bus clock periods + \param[in] data_length: number of data bytes to be transferred + \param[in] data_blocksize: size of data block for block transfer + only one parameter can be selected which is shown as below: + \arg SDIO_DATABLOCKSIZE_1BYTE: block size = 1 byte + \arg SDIO_DATABLOCKSIZE_2BYTES: block size = 2 bytes + \arg SDIO_DATABLOCKSIZE_4BYTES: block size = 4 bytes + \arg SDIO_DATABLOCKSIZE_8BYTES: block size = 8 bytes + \arg SDIO_DATABLOCKSIZE_16BYTES: block size = 16 bytes + \arg SDIO_DATABLOCKSIZE_32BYTES: block size = 32 bytes + \arg SDIO_DATABLOCKSIZE_64BYTES: block size = 64 bytes + \arg SDIO_DATABLOCKSIZE_128BYTES: block size = 128 bytes + \arg SDIO_DATABLOCKSIZE_256BYTES: block size = 256 bytes + \arg SDIO_DATABLOCKSIZE_512BYTES: block size = 512 bytes + \arg SDIO_DATABLOCKSIZE_1024BYTES: block size = 1024 bytes + \arg SDIO_DATABLOCKSIZE_2048BYTES: block size = 2048 bytes + \arg SDIO_DATABLOCKSIZE_4096BYTES: block size = 4096 bytes + \arg SDIO_DATABLOCKSIZE_8192BYTES: block size = 8192 bytes + \arg SDIO_DATABLOCKSIZE_16384BYTES: block size = 16384 bytes + \param[out] none + \retval none +*/ +void sdio_data_config(uint32_t sdio_periph, uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize) +{ + /* reset data timeout, data length and data block size */ + SDIO_DATATO(sdio_periph) &= ~SDIO_DATATO_DATATO; + SDIO_DATALEN(sdio_periph) &= ~SDIO_DATALEN_DATALEN; + SDIO_DATACTL(sdio_periph) &= ~SDIO_DATACTL_BLKSZ; + /* configure the related parameters of data */ + SDIO_DATATO(sdio_periph) = data_timeout; + SDIO_DATALEN(sdio_periph) = data_length; + SDIO_DATACTL(sdio_periph) |= data_blocksize; +} + +/*! + \brief configure the data transfer mode and direction + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] transfer_mode: mode of data transfer + only one parameter can be selected which is shown as below: + \arg SDIO_TRANSMODE_BLOCKCOUNT: Block count data transfer + \arg SDIO_TRANSMODE_MULTIBYTE: multibyte data transfer (only SD/SD I/O) + \arg SDIO_TRANSMODE_STREAM: stream transfer (only eMMC) + \arg SDIO_TRANSMODE_BLOCKCMD12: Block data transfer ends with CMD12 + \param[in] transfer_direction: data transfer direction, read or write + only one parameter can be selected which is shown as below: + \arg SDIO_TRANSDIRECTION_TOCARD: write data to card + \arg SDIO_TRANSDIRECTION_TOSDIO: read data from card + \param[out] none + \retval none +*/ +void sdio_data_transfer_config(uint32_t sdio_periph, uint32_t transfer_mode, uint32_t transfer_direction) +{ + uint32_t data_trans = 0U; + /* reset the data transfer mode, transfer direction and set according to the parameters */ + data_trans = SDIO_DATACTL(sdio_periph); + data_trans &= ~(SDIO_DATACTL_TRANSMOD | SDIO_DATACTL_DATADIR); + data_trans |= (transfer_mode | transfer_direction); + SDIO_DATACTL(sdio_periph) = data_trans; +} + +/*! + \brief enable the DSM(data state machine) for data transfer + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dsm_enable(uint32_t sdio_periph) +{ + SDIO_DATACTL(sdio_periph) |= SDIO_DATACTL_DATAEN; +} + +/*! + \brief disable the DSM(data state machine) for data transfer + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dsm_disable(uint32_t sdio_periph) +{ + SDIO_DATACTL(sdio_periph) &= ~SDIO_DATACTL_DATAEN; +} + +/*! + \brief write data(one word) to the transmit FIFO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] data: 32-bit data write to card + \param[out] none + \retval none +*/ +void sdio_data_write(uint32_t sdio_periph, uint32_t data) +{ + SDIO_FIFO(sdio_periph) = data; +} + +/*! + \brief read data(one word) from the receive FIFO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval received data +*/ +uint32_t sdio_data_read(uint32_t sdio_periph) +{ + return SDIO_FIFO(sdio_periph); +} + +/*! + \brief get the number of remaining data bytes to be transferred to card + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval number of remaining data bytes to be transferred +*/ +uint32_t sdio_data_counter_get(uint32_t sdio_periph) +{ + return SDIO_DATACNT(sdio_periph); +} + +/*! + \brief enable the reset of fifo + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_fifo_reset_enable(uint32_t sdio_periph) +{ + SDIO_DATACTL(sdio_periph) |= SDIO_DATACTL_FIFOREST; +} + +/*! + \brief disable the reset of fifo + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_fifo_reset_disable(uint32_t sdio_periph) +{ + SDIO_DATACTL(sdio_periph) &= ~SDIO_DATACTL_FIFOREST; +} + +/*! + \brief set IDMA buffer mode and size + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] buffer_mode: set IDMA buffer mode + only one parameter can be selected which is shown as below: + \arg SDIO_IDMA_SINGLE_BUFFER: single buffer mode + \arg SDIO_IDMA_DOUBLE_BUFFER: double buffer mode + \param[in] buffer_size: 0-0xFF, set IDMA buffer size + \param[out] none + \retval none +*/ +void sdio_idma_set(uint32_t sdio_periph, uint32_t buffer_mode, uint32_t buffer_size) +{ + /* reset the SDIO_IDMACTL_BUFMOD */ + SDIO_IDMACTL(sdio_periph) &= ~SDIO_IDMACTL_BUFMOD; + /* reset the SDIO_IDMASIZE_IDMASIZE */ + SDIO_IDMASIZE(sdio_periph) &= ~SDIO_IDMASIZE_IDMASIZE; + /* set the buffer mode according to buffer_mode */ + SDIO_IDMACTL(sdio_periph) |= buffer_mode; + /* set the buffer size according to buffer_size */ + SDIO_IDMASIZE(sdio_periph) |= ((buffer_size & BITS(0, 7)) << SDIO_IDMACTL_IDMASIZE_OFFSET); +} + +/*! + \brief set IDMA buffer0 address + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] buffer_address: the address of idma buffer0, buffer_address[0:1] should be 0b'00; + \param[out] none + \retval none +*/ +void sdio_idma_buffer0_address_set(uint32_t sdio_periph, uint32_t buffer_address) +{ + /* reset the SDIO_IDMAADDR0_IDMAADDR0 */ + SDIO_IDMAADDR0(sdio_periph) &= ~SDIO_IDMAADDR0_IDMAADDR0; + /* set the buffer0 address according to buffer_address */ + SDIO_IDMAADDR0(sdio_periph) |= (buffer_address & BITS(2, 31)); +} + +/*! + \brief set IDMA buffer1 address + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] buffer_address: the address of idma buffer1, buffer_address[0:1] should be 0b'00; + \param[out] none + \retval none +*/ +void sdio_idma_buffer1_address_set(uint32_t sdio_periph, uint32_t buffer_address) +{ + /* reset the SDIO_IDMAADDR1_IDMAADDR1 */ + SDIO_IDMAADDR1(sdio_periph) &= ~SDIO_IDMAADDR1_IDMAADDR1; + /* set the buffer1 address according to buffer_address */ + SDIO_IDMAADDR1(sdio_periph) |= (buffer_address & BITS(2, 31)); +} + +/*! + \brief get the IDMA double buffer address selection bit + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval IDMA buffer selection: SDIO_IDMA_BUFFER0 or SDIO_IDMA_BUFFER1 +*/ +uint32_t sdio_buffer_selection_get(uint32_t sdio_periph) +{ + return SDIO_IDMACTL(sdio_periph) & SDIO_IDMACTL_BUFSEL; +} + +/*! + \brief select IDMA buffer + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] buffer_select: the buffer to be used + only one parameter can be selected which is shown as below: + \arg SDIO_IDMA_BUFFER0: select buffer0 + \arg SDIO_IDMA_BUFFER1: select buffer1 + \param[out] none + \retval none +*/ +void sdio_idma_buffer_select(uint32_t sdio_periph, uint32_t buffer_select) +{ + /* reset the SDIO_IDMACTL_BUFSEL */ + SDIO_IDMACTL(sdio_periph) &= ~SDIO_IDMACTL_BUFSEL; + /* select buffer according to buffer_select */ + SDIO_IDMACTL(sdio_periph) |= buffer_select; +} + +/*! + \brief enable the IDMA request for SDIO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_idma_enable(uint32_t sdio_periph) +{ + SDIO_IDMACTL(sdio_periph) |= SDIO_IDMACTL_IDMAEN; +} + +/*! + \brief disable the IDMA request for SDIO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_idma_disable(uint32_t sdio_periph) +{ + SDIO_IDMACTL(sdio_periph) &= ~SDIO_IDMACTL_IDMAEN; +} + +/*! + \brief get the flags state of SDIO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] flag: flags state of SDIO + one or more parameters can be selected which are shown as below: + \arg SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag + \arg SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag + \arg SDIO_FLAG_CMDTMOUT: command response timeout flag + \arg SDIO_FLAG_DTTMOUT: data timeout flag + \arg SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag + \arg SDIO_FLAG_RXORE: received FIFO overrun error occurs flag + \arg SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag + \arg SDIO_FLAG_CMDSEND: command sent (no response required) flag + \arg SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag + \arg SDIO_FLAG_DTHOLD: data transfer hold flag + \arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_FLAG_DTABORT: data transfer aborted by CMD12 flag + \arg SDIO_FLAG_CMDSTA: command path active state flag + \arg SDIO_FLAG_DATSTA: data path active state flag + \arg SDIO_FLAG_TFH: transmit FIFO is half empty flag: at least 8 words can be written into the FIFO + \arg SDIO_FLAG_RFH: receive FIFO is half full flag: at least 8 words can be read in the FIFO + \arg SDIO_FLAG_TFF: transmit FIFO is full flag + \arg SDIO_FLAG_RFF: receive FIFO is full flag + \arg SDIO_FLAG_TFE: transmit FIFO is empty flag + \arg SDIO_FLAG_RFE: receive FIFO is empty flag + \arg SDIO_FLAG_DAT0BSY: DAT0 line signal keep busy flag + \arg SDIO_FLAG_DAT0BSYEND: DAT0 line signal changed form busy to ready flag + \arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag + \arg SDIO_FLAG_ACKFAIL: boot acknowledgment received and check fail flag + \arg SDIO_FLAG_ACKTO: boot acknowledgment timeout flag + \arg SDIO_FLAG_VOLSWEND: voltage switch critical timing section end + \arg SDIO_FLAG_CLKSTOP: SDIO_CLK stopped in voltage switch procedure flag + \arg SDIO_FLAG_IDMAERR: IDMA transfer error flag + \arg SDIO_FLAG_IDMAEND: IDMA transfer end flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sdio_flag_get(uint32_t sdio_periph, uint32_t flag) +{ + FlagStatus temp_flag = RESET; + if(RESET != (SDIO_STAT(sdio_periph) & flag)) { + temp_flag = SET; + } + return temp_flag; +} + +/*! + \brief clear the pending flags of SDIO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] flag: flags state of SDIO + one or more parameters can be selected which are shown as below: + \arg SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag + \arg SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag + \arg SDIO_FLAG_CMDTMOUT: command response timeout flag + \arg SDIO_FLAG_DTTMOUT: data timeout flag + \arg SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag + \arg SDIO_FLAG_RXORE: received FIFO overrun error occurs flag + \arg SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag + \arg SDIO_FLAG_CMDSEND: command sent (no response required) flag + \arg SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag + \arg SDIO_FLAG_DTHOLD: data transfer hold flag + \arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_FLAG_DTABORT: data transfer aborted (by CMD12) flag + \arg SDIO_FLAG_DAT0BSYEND: DAT0 line signal changed form busy to ready flag + \arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag + \arg SDIO_FLAG_ACKFAIL: boot acknowledgment received and check fail + \arg SDIO_FLAG_ACKTO: boot acknowledgment timeout flag + \arg SDIO_FLAG_VOLSWEND: voltage switch critical timing section end flag + \arg SDIO_FLAG_CLKSTOP: SDIO_CLK stopped in voltage switch procedure flag + \arg SDIO_FLAG_IDMAERR: IDMA transfer error occurs flag + \arg SDIO_FLAG_IDMAEND: IDMA transfer end flag + \param[out] none + \retval none +*/ +void sdio_flag_clear(uint32_t sdio_periph, uint32_t flag) +{ + SDIO_INTC(sdio_periph) = flag; +} + +/*! + \brief enable the SDIO interrupt + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] int_flag: interrupt flags state of SDIO + one or more parameters can be selected which are shown as below: + \arg SDIO_INT_CCRCERR: SDIO CCRCERR interrupt + \arg SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt + \arg SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt + \arg SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt + \arg SDIO_INT_TXURE: SDIO TXURE interrupt + \arg SDIO_INT_RXORE: SDIO RXORE interrupt + \arg SDIO_INT_CMDRECV: SDIO CMDRECV interrupt + \arg SDIO_INT_CMDSEND: SDIO CMDSEND interrupt + \arg SDIO_INT_DTEND: SDIO DTEND interrupt + \arg SDIO_INT_DTHOLD: SDIO DTHOLD interrupt + \arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt + \arg SDIO_INT_DTABORT: SDIO DTABORT interrupt + \arg SDIO_INT_TFH: SDIO TFH interrupt + \arg SDIO_INT_RFH: SDIO RFH interrupt + \arg SDIO_INT_RFF: SDIO RFF interrupt + \arg SDIO_INT_TFE: SDIO TFE interrupt + \arg SDIO_INT_DAT0BSYEND: SDIO DAT0BSYEND interrupt + \arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt + \arg SDIO_INT_ACKFAIL: SDIO ACKFAIL interrupt + \arg SDIO_INT_ACKTO: SDIO ACKTO interrupt + \arg SDIO_INT_VOLSWEND: SDIO VOLSWEND interrupt + \arg SDIO_INT_CLKSTOP: SDIO CLKSTOP interrupt + \arg SDIO_INT_IDMAERR: SDIO IDMAERR interrupt + \arg SDIO_INT_IDMAEND: SDIO IDMAEND interrupt + \param[out] none + \retval none +*/ +void sdio_interrupt_enable(uint32_t sdio_periph, uint32_t int_flag) +{ + SDIO_INTEN(sdio_periph) |= int_flag; +} + +/*! + \brief enable the SDIO interrupt + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] int_flag: interrupt flags state of SDIO + one or more parameters can be selected which are shown as below: + \arg SDIO_INT_CCRCERR: SDIO CCRCERR interrupt + \arg SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt + \arg SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt + \arg SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt + \arg SDIO_INT_TXURE: SDIO TXURE interrupt + \arg SDIO_INT_RXORE: SDIO RXORE interrupt + \arg SDIO_INT_CMDRECV: SDIO CMDRECV interrupt + \arg SDIO_INT_CMDSEND: SDIO CMDSEND interrupt + \arg SDIO_INT_DTEND: SDIO DTEND interrupt + \arg SDIO_INT_DTHOLD: SDIO DTHOLD interrupt + \arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt + \arg SDIO_INT_DTABORT: SDIO DTABORT interrupt + \arg SDIO_INT_TFH: SDIO TFH interrupt + \arg SDIO_INT_RFH: SDIO RFH interrupt + \arg SDIO_INT_RFF: SDIO RFF interrupt + \arg SDIO_INT_TFE: SDIO TFE interrupt + \arg SDIO_INT_DAT0BSYEND: SDIO DAT0BSYEND interrupt + \arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt + \arg SDIO_INT_ACKFAIL: SDIO ACKFAIL interrupt + \arg SDIO_INT_ACKTO: SDIO ACKTO interrupt + \arg SDIO_INT_VOLSWEND: SDIO VOLSWEND interrupt + \arg SDIO_INT_CLKSTOP: SDIO CLKSTOP interrupt + \arg SDIO_INT_IDMAERR: SDIO IDMAERR interrupt + \arg SDIO_INT_IDMAEND: SDIO IDMAEND interrupt + \param[out] none + \retval none +*/ +void sdio_interrupt_disable(uint32_t sdio_periph, uint32_t int_flag) +{ + SDIO_INTEN(sdio_periph) &= ~int_flag; +} + +/*! + \brief get the interrupt flags state of SDIO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] int_flag: interrupt flags state of SDIO + one or more parameters can be selected which are shown as below: + \arg SDIO_INT_FLAG_CCRCERR: SDIO CCRCERR interrupt flag + \arg SDIO_INT_FLAG_DTCRCERR: SDIO DTCRCERR interrupt flag + \arg SDIO_INT_FLAG_CMDTMOUT: SDIO CMDTMOUT interrupt flag + \arg SDIO_INT_FLAG_DTTMOUT: SDIO DTTMOUT interrupt flag + \arg SDIO_INT_FLAG_TXURE: SDIO TXURE interrupt flag + \arg SDIO_INT_FLAG_RXORE: SDIO RXORE interrupt flag + \arg SDIO_INT_FLAG_CMDRECV: SDIO CMDRECV interrupt flag + \arg SDIO_INT_FLAG_CMDSEND: SDIO CMDSEND interrupt flag + \arg SDIO_INT_FLAG_DTEND: SDIO DTEND interrupt flag + \arg SDIO_INT_FLAG_DTHOLD: SDIO DTHOLD interrupt flag + \arg SDIO_INT_FLAG_DTBLKEND: SDIO DTBLKEND interrupt flag + \arg SDIO_INT_FLAG_DTABORT: SDIO DTABORT interrupt flag + \arg SDIO_INT_FLAG_TFH: SDIO TFH interrupt flag + \arg SDIO_INT_FLAG_RFH: SDIO RFH interrupt flag + \arg SDIO_INT_FLAG_RFF: SDIO RFF interrupt flag + \arg SDIO_INT_FLAG_TFE: SDIO TFE interrupt flag + \arg SDIO_INT_FLAG_DAT0BSYEND: SDIO DAT0BSYEND interrupt flag + \arg SDIO_INT_FLAG_SDIOINT: SDIO SDIOINT interrupt flag + \arg SDIO_INT_FLAG_ACKFAIL: SDIO ACKFAIL interrupt flag + \arg SDIO_INT_FLAG_ACKTO: SDIO ACKTO interrupt flag + \arg SDIO_INT_FLAG_VOLSWEND: SDIO VOLSWEND interrupt flag + \arg SDIO_INT_FLAG_CLKSTOP: SDIO CLKSTOP interrupt flag + \arg SDIO_INT_FLAG_IDMAERR: SDIO IDMAERR interrupt flag + \arg SDIO_INT_FLAG_IDMAEND: SDIO IDMAEND interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sdio_interrupt_flag_get(uint32_t sdio_periph, uint32_t int_flag) +{ + FlagStatus temp_flag = RESET; + if(RESET != (SDIO_STAT(sdio_periph) & int_flag)) { + temp_flag = SET; + } + return temp_flag; +} + +/*! + \brief clear the interrupt pending flags of SDIO + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] int_flag: interrupt flags state of SDIO + one or more parameters can be selected which are shown as below: + \arg SDIO_INT_FLAG_CCRCERR: SDIO CCRCERR interrupt flag + \arg SDIO_INT_FLAG_DTCRCERR: SDIO DTCRCERR interrupt flag + \arg SDIO_INT_FLAG_CMDTMOUT: SDIO CMDTMOUT interrupt flag + \arg SDIO_INT_FLAG_DTTMOUT: SDIO DTTMOUT interrupt flag + \arg SDIO_INT_FLAG_TXURE: SDIO TXURE interrupt flag + \arg SDIO_INT_FLAG_RXORE: SDIO RXORE interrupt flag + \arg SDIO_INT_FLAG_CMDRECV: SDIO CMDRECV interrupt flag + \arg SDIO_INT_FLAG_CMDSEND: SDIO CMDSEND interrupt flag + \arg SDIO_INT_FLAG_DTEND: SDIO DTEND interrupt flag + \arg SDIO_INT_FLAG_DTHOLD: SDIO DTHOLD interrupt flag + \arg SDIO_INT_FLAG_DTBLKEND: SDIO DTBLKEND interrupt flag + \arg SDIO_INT_FLAG_DTABORT: SDIO DTABORT interrupt flag + \arg SDIO_INT_FLAG_DAT0BSYEND: SDIO DAT0BSYEND interrupt flag + \arg SDIO_INT_FLAG_SDIOINT: SDIO SDIOINT interrupt flag + \arg SDIO_INT_FLAG_ACKFAIL: SDIO ACKFAIL interrupt flag + \arg SDIO_INT_FLAG_ACKTO: SDIO ACKTO interrupt flag + \arg SDIO_INT_FLAG_VOLSWEND: SDIO VOLSWEND interrupt flag + \arg SDIO_INT_FLAG_CLKSTOP: SDIO CLKSTOP interrupt flag + \arg SDIO_INT_FLAG_IDMAERR: SDIO IDMAERR interrupt flag + \arg SDIO_INT_FLAG_IDMAEND: SDIO IDMAEND interrupt flag + \param[out] none + \retval none +*/ +void sdio_interrupt_flag_clear(uint32_t sdio_periph, uint32_t int_flag) +{ + SDIO_INTC(sdio_periph) = int_flag; +} + +/*! + \brief enable voltage switch + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_voltage_switch_enable(uint32_t sdio_periph) +{ + SDIO_PWRCTL(sdio_periph) |= SDIO_PWRCTL_VSEN; +} + +/*! + \brief disable voltage switch + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_voltage_switch_disable(uint32_t sdio_periph) +{ + SDIO_PWRCTL(sdio_periph) &= ~SDIO_PWRCTL_VSEN; +} + +/*! + \brief enable voltage switch sequence + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_voltage_switch_sequence_enable(uint32_t sdio_periph) +{ + SDIO_PWRCTL(sdio_periph) |= SDIO_PWRCTL_VSSTART; +} + +/*! + \brief disable voltage switch sequence + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_voltage_switch_sequence_disable(uint32_t sdio_periph) +{ + SDIO_PWRCTL(sdio_periph) &= ~SDIO_PWRCTL_VSSTART; +} + +/*! + \brief set boot mode + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] boot_mode: mode of SDIO boot + only one parameter can be selected which is shown as below: + \arg SDIO_BOOTMODE_NORMAL: normal boot mode + \arg SDIO_BOOTMODE_ALTERNATIVE: alternative boot mode + \param[out] none + \retval none +*/ +void sdio_boot_mode_set(uint32_t sdio_periph, uint32_t boot_mode) +{ + /* reset boot mode selection bit */ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_BOOTMOD; + /* set boot mode according to the boot_mode */ + SDIO_CMDCTL(sdio_periph) |= boot_mode; +} + +/*! + \brief enbale DSM(data state machine) boot acknowledgment + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_boot_ack_enable(uint32_t sdio_periph) +{ + SDIO_DATACTL(sdio_periph) |= SDIO_DATACTL_ACKEN; +} + +/*! + \brief disbale DSM(data state machine) boot acknowledgment + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_boot_ack_disable(uint32_t sdio_periph) +{ + SDIO_DATACTL(sdio_periph) &= ~SDIO_DATACTL_ACKEN; +} + +/*! + \brief set boot ACK timeout period + \param[in] sdio_periph: SDIOx(x=0,1) + \param[in] timeout: boot ACK timeout period + \param[out] none + \retval none +*/ +void sdio_boot_acktimeout_set(uint32_t sdio_periph, uint32_t timeout) +{ + SDIO_ACKTO(sdio_periph) &= ~SDIO_ACKTO_ACKTO; + SDIO_ACKTO(sdio_periph) |= timeout & SDIO_ACKTO_ACKTO; +} + +/*! + \brief enable boot operation + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_boot_enable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) |= SDIO_CMDCTL_BOOTMODEN; +} + +/*! + \brief disable boot operation + \param[in] sdio_periph: SDIOx(x=0,1) + \param[out] none + \retval none +*/ +void sdio_boot_disable(uint32_t sdio_periph) +{ + SDIO_CMDCTL(sdio_periph) &= ~SDIO_CMDCTL_BOOTMODEN; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_spi.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_spi.c new file mode 100644 index 0000000000..f65dba23e6 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_spi.c @@ -0,0 +1,1487 @@ +/*! + \file gd32h7xx_spi.c + \brief SPI driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_spi.h" + +#define SPI_ERROR_HANDLE(s) do{}while(1) + +/* external clock value to ckin */ +#define I2S_CKIN_VALUE ((uint32_t)0U) + +/* SPI fifo data size */ +#define SPI_DATASIZE_SUBTRACT_ONE ((uint8_t)0x01U) + +/* SPI/I2S parameter initialization mask */ +#define SPI_INIT_MASK ((uint32_t)0x00003040U) +#define I2S_INIT_MASK ((uint32_t)0xFFFFF047U) +#define I2S_FULL_DUPLEX_MASK ((uint32_t)0x0000F040U) + +/* default value */ +#define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00020000U) /*!< default value of SPI_I2SCTL register */ + +/* I2S clock source selection, multiplication and division mask */ +#define I2S_CLOCK_MUL_MASK ((uint32_t)0x0000F000U) /*!< I2S clock multiplication mask */ +#define I2S_CLOCK_DIV_MASK ((uint32_t)0x00030000U) /*!< I2S clock division mask */ + + + +/*! + \brief reset SPI and I2S + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph){ + case SPI0: + /* reset SPI0 and I2S0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1 and I2S1 */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + case SPI2: + /* reset SPI2 and I2S2 */ + rcu_periph_reset_enable(RCU_SPI2RST); + rcu_periph_reset_disable(RCU_SPI2RST); + break; + case SPI3: + /* reset SPI3 */ + rcu_periph_reset_enable(RCU_SPI3RST); + rcu_periph_reset_disable(RCU_SPI3RST); + break; + case SPI4: + /* reset SPI4 */ + rcu_periph_reset_enable(RCU_SPI4RST); + rcu_periph_reset_disable(RCU_SPI4RST); + break; + case SPI5: + /* reset SPI5 and I2S5 */ + rcu_periph_reset_enable(RCU_SPI5RST); + rcu_periph_reset_disable(RCU_SPI5RST); + break; + default : + break; + } +} + +/*! + \brief initialize the parameters of SPI struct with default values + \param[in] spi_struct: SPI parameter structure + \param[out] spi_parameter_struct: the initialized struct spi_parameter_struct pointer + \retval none +*/ +void spi_struct_para_init(spi_parameter_struct *spi_struct) +{ + /* configure the structure with default value */ + spi_struct->device_mode = SPI_SLAVE; + spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_struct->data_size = SPI_DATASIZE_8BIT; + spi_struct->nss = SPI_NSS_HARD; + spi_struct->endian = SPI_ENDIAN_MSB; + spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + spi_struct->prescale = SPI_PSC_2; +} + +/*! + \brief initialize SPI parameter + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_struct: SPI parameter initialization stuct members of the structure + and the member values are shown as below: + device_mode: SPI_MASTER, SPI_SLAVE + trans_mode: SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY, + SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT + data_size: SPI_DATASIZE_4BIT, SPI_DATASIZE_5BIT, SPI_DATASIZE_6BIT + SPI_DATASIZE_7BIT, SPI_DATASIZE_8BIT, SPI_DATASIZE_9BIT + SPI_DATASIZE_10BIT, SPI_DATASIZE_11BIT, SPI_DATASIZE_12BIT + SPI_DATASIZE_13BIT, SPI_DATASIZE_14BIT, SPI_DATASIZE_15BIT + SPI_DATASIZE_16BIT, SPI_DATASIZE_17BIT, SPI_DATASIZE_18BIT + SPI_DATASIZE_19BIT, SPI_DATASIZE_20BIT, SPI_DATASIZE_21BIT + SPI_DATASIZE_22BIT, SPI_DATASIZE_23BIT, SPI_DATASIZE_24BIT + SPI_DATASIZE_25BIT, SPI_DATASIZE_26BIT, SPI_DATASIZE_27BIT + SPI_DATASIZE_28BIT, SPI_DATASIZE_29BIT, SPI_DATASIZE_30BIT + SPI_DATASIZE_31BIT, SPI_DATASIZE_32BIT + nss: SPI_NSS_SOFT, SPI_NSS_HARD + endian: SPI_ENDIAN_MSB, SPI_ENDIAN_LSB + clock_polarity_phase: SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE + SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE + prescale: SPI_PSC_n (n=2,4,8,16,32,64,128,256) + \param[out] none + \retval none +*/ +void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct) +{ + uint32_t reg1 = 0U, reg2 = 0U; + reg1 = SPI_CFG0(spi_periph); + reg2 = SPI_CFG1(spi_periph); + + /* select SPI as master or slave */ + reg2 |= spi_struct->device_mode; + /* select SPI transfer mode */ + reg2 |= spi_struct->trans_mode; + /* select SPI frame size */ + reg1 &= (uint32_t)(~SPI_CFG0_DZ); + reg1 |= spi_struct->data_size; + /* select SPI NSS use hardware or software */ + reg2 |= spi_struct->nss; + /* select SPI LSB or MSB */ + reg2 |= spi_struct->endian; + /* select SPI polarity and phase */ + reg2 |= spi_struct->clock_polarity_phase; + /* select SPI prescale to adjust transmit speed */ + reg1 |= spi_struct->prescale; + + /* write to SPI_CFG0 & SPI_CFG1 register */ + SPI_CFG0(spi_periph) = (uint32_t)reg1; + SPI_CFG1(spi_periph) = (uint32_t)reg2; + + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); +} + +/*! + \brief enable SPI + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief disable SPI + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief initialize I2S parameter + \param[in] spi_periph: SPIx(x=0,1,2,5) + \param[in] i2s_mode: I2S operation mode + only one parameter can be selected which is shown as below: + \arg I2S_MODE_SLAVETX: I2S slave transmit mode + \arg I2S_MODE_SLAVERX: I2S slave receive mode + \arg I2S_MODE_MASTERTX: I2S master transmit mode + \arg I2S_MODE_MASTERRX: I2S master receive mode + \param[in] i2s_standard: I2S standard + only one parameter can be selected which is shown as below: + \arg I2S_STD_PHILLIPS: I2S phillips standard + \arg I2S_STD_MSB: I2S MSB standard + \arg I2S_STD_LSB: I2S LSB standard + \arg I2S_STD_PCMSHORT: I2S PCM short standard + \arg I2S_STD_PCMLONG: I2S PCM long standard + \param[in] i2s_ckpl: I2S idle state clock polarity + only one parameter can be selected which is shown as below: + \arg I2S_CKPL_LOW: I2S clock polarity low level + \arg I2S_CKPL_HIGH: I2S clock polarity high level + \param[out] none + \retval none +*/ +void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl) +{ + uint32_t reg= 0U; + reg = SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)i2s_mode; + /* select I2S standard */ + reg |= (uint32_t)i2s_standard; + /* select I2S polarity */ + reg |= (uint32_t)i2s_ckpl; + + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief configure I2S prescaler + \param[in] spi_periph: SPIx(x=0,1,2,5) + \param[in] i2s_audiosample: I2S audio sample rate + only one parameter can be selected which is shown as below: + \arg I2S_AUDIOSAMPLE_8K: audio sample rate is 8KHz + \arg I2S_AUDIOSAMPLE_11K: audio sample rate is 11KHz + \arg I2S_AUDIOSAMPLE_16K: audio sample rate is 16KHz + \arg I2S_AUDIOSAMPLE_22K: audio sample rate is 22KHz + \arg I2S_AUDIOSAMPLE_32K: audio sample rate is 32KHz + \arg I2S_AUDIOSAMPLE_44K: audio sample rate is 44KHz + \arg I2S_AUDIOSAMPLE_48K: audio sample rate is 48KHz + \arg I2S_AUDIOSAMPLE_96K: audio sample rate is 96KHz + \arg I2S_AUDIOSAMPLE_192K: audio sample rate is 192KHz + \param[in] i2s_frameformat: I2S data length and channel length + only one parameter can be selected which is shown as below: + \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit + \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit + \param[in] i2s_mckout: I2S master clock output + only one parameter can be selected which is shown as below: + \arg I2S_MCKOUT_ENABLE: I2S master clock output enable + \arg I2S_MCKOUT_DISABLE: I2S master clock output disable + \param[out] none + \retval none +*/ +void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout) +{ + uint32_t i2sdiv = 2U, i2sof = 0U; + uint32_t clks = 0U; + uint32_t i2sclock = 0U; + uint32_t i2s_clk_sel = 0U; + uint32_t spi0_2_clksel[5] = {CK_PLL0Q, CK_PLL1P, CK_PLL2P, I2S_CKIN_VALUE, CK_PER}; + uint32_t spi3_5_clksel[7] = {CK_APB2, CK_PLL1Q, CK_PLL2Q, CK_IRC64MDIV, CK_LPIRC4M, CK_HXTAL, I2S_CKIN_VALUE}; + + /* judge whether the audiosample is 0 */ + if(0U == i2s_audiosample){ + SPI_ERROR_HANDLE("the parameter can not be 0 \r\n"); + } + + /* get the I2S clock source */ + switch(spi_periph){ + case SPI0: + /* I2S0 clock source selection */ + i2s_clk_sel = RCU_CFG5 & RCU_CFG5_SPI0SEL; + if(3U == i2s_clk_sel){ + i2sclock = spi0_2_clksel[i2s_clk_sel]; + }else{ + i2sclock = rcu_clock_freq_get((rcu_clock_freq_enum)spi0_2_clksel[i2s_clk_sel]); + } + break; + case SPI1: + /* I2S1 clock source selection */ + i2s_clk_sel = (RCU_CFG5 & RCU_CFG5_SPI1SEL) >> 4U; + if(3U == i2s_clk_sel){ + i2sclock = spi0_2_clksel[i2s_clk_sel]; + }else{ + i2sclock = rcu_clock_freq_get((rcu_clock_freq_enum)spi0_2_clksel[i2s_clk_sel]); + } + break; + case SPI2: + /* I2S2 clock source selection */ + i2s_clk_sel = (RCU_CFG5 & RCU_CFG5_SPI2SEL) >> 8U; + if(3U == i2s_clk_sel){ + i2sclock = spi0_2_clksel[i2s_clk_sel]; + }else{ + i2sclock = rcu_clock_freq_get((rcu_clock_freq_enum)spi0_2_clksel[i2s_clk_sel]); + } + break; + case SPI5: + /* I2S5 clock source selection */ + i2s_clk_sel = (RCU_CFG5 & RCU_CFG5_SPI5SEL) >> 20U; + if(3U > i2s_clk_sel){ + i2sclock = rcu_clock_freq_get((rcu_clock_freq_enum)spi3_5_clksel[i2s_clk_sel]); + }else{ + i2sclock = spi3_5_clksel[i2s_clk_sel]; + } + break; + default : + break; + } + + /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ + if(I2S_MCKOUT_ENABLE == i2s_mckout){ + clks = (uint32_t)(((i2sclock / 256U) * 10U) / i2s_audiosample); + }else{ + if(I2S_FRAMEFORMAT_DT16B_CH16B == i2s_frameformat){ + clks = (uint32_t)(((i2sclock / 32U) *10U ) / i2s_audiosample); + }else{ + clks = (uint32_t)(((i2sclock / 64U) *10U ) / i2s_audiosample); + } + } + + /* remove the floating point */ + clks = (clks + 5U) / 10U; + i2sof = (clks & 0x00000001U); + i2sdiv = ((clks - i2sof) / 2U); + + /* set the default values */ + if((i2sdiv < 2U) || (i2sdiv > 255U)){ + i2sdiv = 2U; + i2sof = 0U; + } + /* clear SPI_I2SCTL_DIV and SPI_I2SCTL_OF and SPI_I2SCTL_MCKOEN bits */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DIV | SPI_I2SCTL_OF | SPI_I2SCTL_MCKOEN)); + /* configure SPI_I2SPSC */ + SPI_I2SCTL(spi_periph) |= (uint32_t)((i2sdiv << 16U) | (i2sof << 24U) | i2s_mckout); + + /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN)); + /* configure data frame format */ + SPI_I2SCTL(spi_periph) |= (uint32_t)i2s_frameformat; +} + +/*! + \brief enable I2S + \param[in] spi_periph: SPIx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief disable I2S + \param[in] spi_periph: SPIx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \brief SPI MOSI and MISO pin swap + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] io_cfg: SPI IO swap config + only one parameter can be selected which is shown as below: + \arg SPI_IO_SWAP: SPI MOSI and MISO swap + \arg SPI_IO_NORMAL: SPI MOSI and MISO no swap + \param[out] none + \retval none +*/ +void spi_io_config(uint32_t spi_periph, uint32_t io_cfg) +{ + if(SPI_IO_SWAP == io_cfg){ + SPI_CFG1(spi_periph) |= (uint32_t)SPI_CFG1_SWPMIO; + } + else{ + SPI_CFG1(spi_periph) &= (uint32_t)(~SPI_CFG1_SWPMIO); + } +} + +/*! + \brief set delay between active edge of NSS and start transfer or receive data in SPI master mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] delay_cycle: SPI_NSS_IDLENESS_00CYCLE, SPI_NSS_IDLENESS_01CYCLE, SPI_NSS_IDLENESS_02CYCLE, + SPI_NSS_IDLENESS_03CYCLE, SPI_NSS_IDLENESS_04CYCLE, SPI_NSS_IDLENESS_05CYCLE, + SPI_NSS_IDLENESS_06CYCLE, SPI_NSS_IDLENESS_07CYCLE, SPI_NSS_IDLENESS_08CYCLE, + SPI_NSS_IDLENESS_09CYCLE, SPI_NSS_IDLENESS_10CYCLE, SPI_NSS_IDLENESS_11CYCLE, + SPI_NSS_IDLENESS_12CYCLE, SPI_NSS_IDLENESS_13CYCLE, SPI_NSS_IDLENESS_14CYCLE, + SPI_NSS_IDLENESS_15CYCLE + \param[out] none + \retval none +*/ +void spi_nss_idleness_delay_set(uint32_t spi_periph, uint32_t delay_cycle) +{ + /* acquire SPI_CFG1 register */ + uint32_t reg = SPI_CFG1(spi_periph); + reg &= (uint32_t)(~SPI_CFG1_MSSD); + reg |= (uint32_t)delay_cycle; + /* assign regiser */ + SPI_CFG1(spi_periph) = reg; +} + +/*! + \brief set SPI master data frame delay + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] delay_cycle: SPI_DATA_IDLENESS_00CYCLE, SPI_DATA_IDLENESS_01CYCLE, SPI_DATA_IDLENESS_02CYCLE, + SPI_DATA_IDLENESS_03CYCLE, SPI_DATA_IDLENESS_04CYCLE, SPI_DATA_IDLENESS_05CYCLE, + SPI_DATA_IDLENESS_06CYCLE, SPI_DATA_IDLENESS_07CYCLE, SPI_DATA_IDLENESS_08CYCLE, + SPI_DATA_IDLENESS_09CYCLE, SPI_DATA_IDLENESS_10CYCLE, SPI_DATA_IDLENESS_11CYCLE, + SPI_DATA_IDLENESS_12CYCLE, SPI_DATA_IDLENESS_13CYCLE, SPI_DATA_IDLENESS_14CYCLE, + SPI_DATA_IDLENESS_15CYCLE + \param[out] none + \retval none +*/ +void spi_data_frame_delay_set(uint32_t spi_periph, uint32_t delay_cycle) +{ + /* acquire SPI_CFG1 register */ + uint32_t reg = SPI_CFG1(spi_periph); + reg &= (uint32_t)(~SPI_CFG1_MDFD); + reg |= (uint32_t)delay_cycle; + /* assign regiser */ + SPI_CFG1(spi_periph) = reg; +} + +/*! + \brief set SPI master mode rx clock delay + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] delay_unit: master mode receive clock delay + it can be 0-0x1f + \param[out] none + \retval none +*/ +void spi_master_receive_clock_delay_set(uint32_t spi_periph, uint32_t delay_unit) +{ + SPI_RXDLYCK(spi_periph) &= (uint32_t)(~SPI_RXDLYCK_MRXDEN); + SPI_RXDLYCK(spi_periph) &= (uint32_t)(~SPI_RXDLYCK_MRXD); + SPI_RXDLYCK(spi_periph) |= (uint32_t)(delay_unit << 6U); +} + +/*! + \brief set SPI slave mode rx clock delay + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] delay_unit: slave mode receive clock delay + it can be 0-0x1f + \param[out] none + \retval none +*/ +void spi_slave_receive_clock_delay_set(uint32_t spi_periph, uint32_t delay_unit) +{ + SPI_RXDLYCK(spi_periph) &= (uint32_t)(~SPI_RXDLYCK_SRXDEN); + SPI_RXDLYCK(spi_periph) &= (uint32_t)(~SPI_RXDLYCK_SRXD); + SPI_RXDLYCK(spi_periph) |= (uint32_t)delay_unit; +} + +/*! + \brief clear SPI master mode rx clock delay + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_master_receive_clock_delay_clear(uint32_t spi_periph) +{ + SPI_RXDLYCK(spi_periph) |= (uint32_t)SPI_RXDLYCK_MRXDEN; +} + +/*! + \brief clear SPI slave mode rx clock delay + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_slave_receive_clock_delay_clear(uint32_t spi_periph) +{ + SPI_RXDLYCK(spi_periph) |= (uint32_t)SPI_RXDLYCK_SRXDEN; +} + +/*! + \brief SPI NSS output control + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] nss_ctl: nss control bit + only one parameter can be selected which is shown as below: + \arg SPI_NSS_HOLD_UNTIL_TRANS_END: SPI NSS remains active level until data transfer complete + \arg SPI_NSS_INVALID_PULSE: SPI data frames are interleaved with NSS invalid pulses + \param[out] none + \retval none +*/ +void spi_nss_output_control(uint32_t spi_periph, uint32_t nss_ctl) +{ + if(SPI_NSS_HOLD_UNTIL_TRANS_END == nss_ctl){ + SPI_CFG1(spi_periph) &= (uint32_t)(~SPI_CFG1_NSSCTL); + } + else{ + SPI_CFG1(spi_periph) |= (uint32_t)SPI_CFG1_NSSCTL; + } +} + +/*! + \brief set SPI NSS active polarity + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] polarity: SPI NSS active level + only one parameter can be selected which is shown as below: + \arg SPI_NSS_POLARITY_HIGH: SPI NSS high level is active + \arg SPI_NSS_POLARITY_LOW: SPI NSS low level is active + \param[out] none + \retval none +*/ +void spi_nss_polarity_set(uint32_t spi_periph, uint32_t polarity) +{ + if(SPI_NSS_POLARITY_HIGH == polarity){ + SPI_CFG1(spi_periph) |= (uint32_t)SPI_CFG1_NSSIOPL; + } + else{ + SPI_CFG1(spi_periph) &= (uint32_t)(~SPI_CFG1_NSSIOPL); + } +} + +/*! + \brief enable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_output_enable(uint32_t spi_periph) +{ + SPI_CFG1(spi_periph) |= (uint32_t)SPI_CFG1_NSSDRV; +} + +/*! + \brief disable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_output_disable(uint32_t spi_periph) +{ + SPI_CFG1(spi_periph) &= (uint32_t)(~SPI_CFG1_NSSDRV); +} + +/*! + \brief SPI NSS pin high level in software mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_internal_high(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_NSSI; +} + +/*! + \brief SPI NSS pin low level in software mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_nss_internal_low(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_NSSI); +} + +/*! + \brief enable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data use DMA + \arg SPI_DMA_RECEIVE: SPI receive data use DMA + \param[out] none + \retval none +*/ +void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma) +{ + if(SPI_DMA_TRANSMIT == spi_dma){ + SPI_CFG0(spi_periph) |= (uint32_t)SPI_CFG0_DMATEN; + }else{ + SPI_CFG0(spi_periph) |= (uint32_t)SPI_CFG0_DMAREN; + } +} + +/*! + \brief disable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data use DMA + \arg SPI_DMA_RECEIVE: SPI receive data use DMA + \param[out] none + \retval none +*/ +void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma) +{ + if(SPI_DMA_TRANSMIT == spi_dma){ + SPI_CFG0(spi_periph) &= (uint32_t)(~SPI_CFG0_DMATEN); + }else{ + SPI_CFG0(spi_periph) &= (uint32_t)(~SPI_CFG0_DMAREN); + } +} + +/*! + \brief configure SPI/I2S data frame size + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] frame_size: SPI_DATASIZE_4BIT, SPI_DATASIZE_5BIT, SPI_DATASIZE_6BIT, + SPI_DATASIZE_7BIT, SPI_DATASIZE_8BIT, SPI_DATASIZE_9BIT, + SPI_DATASIZE_10BIT, SPI_DATASIZE_11BIT, SPI_DATASIZE_12BIT, + SPI_DATASIZE_13BIT, SPI_DATASIZE_14BIT, SPI_DATASIZE_15BIT, + SPI_DATASIZE_16BIT, SPI_DATASIZE_17BIT, SPI_DATASIZE_18BIT, + SPI_DATASIZE_19BIT, SPI_DATASIZE_20BIT, SPI_DATASIZE_21BIT, + SPI_DATASIZE_22BIT, SPI_DATASIZE_23BIT, SPI_DATASIZE_24BIT, + SPI_DATASIZE_25BIT, SPI_DATASIZE_26BIT, SPI_DATASIZE_27BIT, + SPI_DATASIZE_28BIT, SPI_DATASIZE_29BIT, SPI_DATASIZE_30BIT, + SPI_DATASIZE_31BIT, SPI_DATASIZE_32BIT + \param[out] none + \retval none +*/ +void spi_i2s_data_frame_size_config(uint32_t spi_periph, uint32_t frame_size) +{ + uint32_t reg = SPI_CFG0(spi_periph); + /* confige SPI_CFG0_DZ bits */ + reg &= (uint32_t)(~SPI_CFG0_DZ); + reg |= (uint32_t)frame_size; + SPI_CFG0(spi_periph) = reg; +} + +/*! + \brief SPI/I2S transmit data + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] data: 32-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph, uint32_t data) +{ + SPI_TDATA(spi_periph) = (uint32_t)data; +} + +/*! + \brief SPI/I2S receive data + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 32-bit data +*/ +uint32_t spi_i2s_data_receive(uint32_t spi_periph) +{ + return ((uint32_t)SPI_RDATA(spi_periph)); +} + +/*! + \brief configure SPI bidirectional transfer direction + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] transfer_direction: SPI transfer direction + only one parameter can be selected which is shown as below: + \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode + \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode + \retval none +*/ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction) +{ + if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){ + /* set the transmit only mode */ + SPI_CFG1(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; + }else{ + /* set the receive only mode */ + SPI_CFG1(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief SPI/I2S master start transfer + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] transfer_start: transfer start bit + only one parameter can be selected which is shown as below: + \arg SPI_TRANS_START: the master transmission is occurring, + or has been temporarily suspended by automatic suspend + \arg SPI_TRANS_IDLE: the master transfer is idle status + \retval none +*/ +void spi_master_transfer_start(uint32_t spi_periph, uint32_t transfer_start) +{ + if(SPI_TRANS_START == transfer_start){ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_MSTART; + }else{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_MSTART); + } +} + +/*! + \brief configure SPI current data number + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] current_num: SPI transfer current data number + it can be 0-0xFFFF + \retval none +*/ +void spi_current_data_num_config(uint32_t spi_periph, uint32_t current_num) +{ + uint32_t reg = SPI_CTL1(spi_periph); + /* confige SPI current data number */ + reg &= (uint32_t)(~BITS(0,15)); + reg |= (uint32_t)current_num; + SPI_CTL1(spi_periph) = reg; +} + +/*! + \brief configure SPI reload data number + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] reload_num: SPI transfer reload data number + it can be 0-0xFFFF + \retval none +*/ +void spi_reload_data_num_config(uint32_t spi_periph, uint32_t reload_num) +{ + uint32_t reg = SPI_CTL1(spi_periph); + /* confige SPI reload data number */ + reg &= (uint32_t)(~BITS(16,31)); + reg |= (uint32_t)(reload_num << 16U); + SPI_CTL1(spi_periph) = reg; +} + +/*! + \brief set SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] crc_poly: CRC polynomial value + \param[out] none + \retval none +*/ +void spi_crc_polynomial_set(uint32_t spi_periph,uint32_t crc_poly) +{ + /* enable SPI CRC */ + SPI_CFG0(spi_periph) |= (uint32_t)SPI_CFG0_CRCEN; + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 32-bit CRC polynomial +*/ +uint32_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + return ((uint32_t)SPI_CRCPOLY(spi_periph)); +} + +/*! + \brief configure SPI CRC length + \param[in] spi_periph: (x=0,1,2,3,4,5) + \param[in] crc_size: SPI_CRCSIZE_4BIT, SPI_CRCSIZE_5BIT, SPI_CRCSIZE_6BIT, + SPI_CRCSIZE_7BIT, SPI_CRCSIZE_8BIT, SPI_CRCSIZE_9BIT, SPI_CRCSIZE_10BIT, + SPI_CRCSIZE_11BIT, SPI_CRCSIZE_12BIT, SPI_CRCSIZE_13BIT, SPI_CRCSIZE_14BIT, + SPI_CRCSIZE_15BIT, SPI_CRCSIZE_16BIT, SPI_CRCSIZE_17BIT, SPI_CRCSIZE_18BIT, + SPI_CRCSIZE_19BIT, SPI_CRCSIZE_20BIT, SPI_CRCSIZE_21BIT, SPI_CRCSIZE_22BIT, + SPI_CRCSIZE_23BIT, SPI_CRCSIZE_24BIT, SPI_CRCSIZE_25BIT, SPI_CRCSIZE_26BIT, + SPI_CRCSIZE_27BIT, SPI_CRCSIZE_28BIT, SPI_CRCSIZE_29BIT, SPI_CRCSIZE_30BIT, + SPI_CRCSIZE_31BIT, SPI_CRCSIZE_32BIT + \param[out] none + \retval none +*/ +void spi_crc_length_config(uint32_t spi_periph, uint32_t crc_size) +{ + uint32_t reg = SPI_CFG0(spi_periph); + /* confige SPI_CFG0_CRCSZ bits */ + reg &= (uint32_t)(~SPI_CFG0_CRCSZ); + reg |= (uint32_t)crc_size; + SPI_CFG0(spi_periph) = reg; +} + +/*! + \brief turn on CRC function + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CFG0(spi_periph) |= (uint32_t)SPI_CFG0_CRCEN; +} + +/*! + \brief turn off CRC function + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_CFG0(spi_periph) &= (uint32_t)(~SPI_CFG0_CRCEN); +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] crc: SPI crc value + only one parameter can be selected which is shown as below: + \arg SPI_CRC_TX: get transmit crc value + \arg SPI_CRC_RX: get receive crc value + \param[out] none + \retval 32-bit CRC value +*/ +uint32_t spi_crc_get(uint32_t spi_periph, uint8_t crc) +{ + if(SPI_CRC_TX == crc){ + return ((uint32_t)(SPI_TCRC(spi_periph))); + }else{ + return ((uint32_t)(SPI_RCRC(spi_periph))); + } +} + +/*! + \brief enable SPI CRC full size(33 bit or 17 bit) polynomial + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_full_size_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCFS; +} + +/*! + \brief disable SPI CRC full size(33 bit or 17 bit) polynomial + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_full_size_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCFS); +} + +/*! + \brief configure SPI TCRC init pattern + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] init_pattern: SPI crc value + only one parameter can be selected which is shown as below: + \arg SPI_TCRC_INIT_1: use all 1 pattern + \arg SPI_TCRC_INIT_0: use all 0 pattern + \param[out] none + \retval none +*/ +void spi_tcrc_init_pattern(uint32_t spi_periph, uint32_t init_pattern) +{ + if(init_pattern == SPI_TCRC_INIT_1){ + SPI_CTL0(spi_periph) |= (uint32_t)(SPI_CTL0_TXCRCI); + }else{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_TXCRCI); + } +} + +/*! + \brief configure SPI RCRC init pattern + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] init_pattern: SPI crc value + only one parameter can be selected which is shown as below: + \arg SPI_RCRC_INIT_1: use all 1 pattern + \arg SPI_RCRC_INIT_0: use all 0 pattern + \param[out] none + \retval none +*/ +void spi_rcrc_init_pattern(uint32_t spi_periph, uint32_t init_pattern) +{ + if(init_pattern == SPI_RCRC_INIT_1){ + SPI_CTL0(spi_periph) |= (uint32_t)(SPI_CTL0_RXCRCI); + }else{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_RXCRCI); + } +} + +/*! + \brief enable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_ti_mode_enable(uint32_t spi_periph) +{ + SPI_CFG1(spi_periph) |= (uint32_t)SPI_CFG1_TMOD; +} + +/*! + \brief disable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_ti_mode_disable(uint32_t spi_periph) +{ + SPI_CFG1(spi_periph) &= (uint32_t)(~SPI_CFG1_TMOD); +} + +/*! + \brief enable quad wire SPI + \param[in] spi_periph: SPIx(x=3,4) + \param[out] none + \retval none +*/ +void spi_quad_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief disable quad wire SPI + \param[in] spi_periph: SPIx(x=3,4) + \param[out] none + \retval none +*/ +void spi_quad_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD); +} + +/*! + \brief enable quad wire SPI write + \param[in] spi_periph: SPIx(x=3,4) + \param[out] none + \retval none +*/ +void spi_quad_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief enable quad wire SPI read + \param[in] spi_periph: SPIx(x=3,4) + \param[out] none + \retval none +*/ +void spi_quad_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief enable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(x=3,4) + \param[out] none + \retval none +*/ +void spi_quad_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + + /*! + \brief disable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(x=3,4) + \param[out] none + \retval none +*/ + void spi_quad_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} + +/*! + \brief slave transmitter underrun detected operation + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] ur_ope: underrun operation + only one parameter can be selected which is shown as below: + \arg SPI_CONFIG_REGISTER_PATTERN: slave send a constant value defined by the SPI_URDATA register + \arg SPI_CONFIG_LAST_RECEIVED: slave send the lastly data frame received from master + \arg SPI_CONFIG_LAST_TRANSMITTED: slave send its lastly transmitted data frame + \param[out] none + \retval none +*/ +void spi_underrun_operation(uint32_t spi_periph, uint32_t ur_ope) +{ + /* acquire SPI_CFG0 register */ + uint32_t reg = SPI_CFG0(spi_periph); + reg &= (uint32_t)(~SPI_CFG0_TXUROP); + reg |= (uint32_t)ur_ope; + /* assign regiser */ + SPI_CFG0(spi_periph) = reg; +} + +/*! + \brief configure slave transmitter underrun detected + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] ur_cfg: underrun config + only one parameter can be selected which is shown as below: + \arg SPI_DETECT_BEGIN_DATA_FRAME: underrun detected at start of data frame (no bit 1 protection) + \arg SPI_DETECT_END_DATA_FRAME: underrun detected at end of last data frame + \arg SPI_DETECT_BEGIN_ACTIVE_NSS: underrun detected at start of NSS signal + \param[out] none + \retval none +*/ +void spi_underrun_config(uint32_t spi_periph, uint32_t ur_cfg) +{ + /* acquire SPI_CFG0 register */ + uint32_t reg = SPI_CFG0(spi_periph); + reg &= (uint32_t)(~SPI_CFG0_TXURDT); + reg |= (uint32_t)ur_cfg; + /* assign regiser */ + SPI_CFG0(spi_periph) = ur_cfg; +} + +/*! + \brief configure underrun data at slave mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] udata: underrun data + it can be 0-0xFFFFFFFF + \param[out] none + \retval none +*/ +void spi_underrun_data_config(uint32_t spi_periph, uint32_t udata) +{ + SPI_URDATA(spi_periph) = (uint32_t)udata; +} + +/*! + \brief configure SPI suspend in receive mode + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] sus_mode: suspend mode + only one parameter can be selected which is shown as below: + \arg SPI_AUTO_SUSPEND: until the overrun condition is reached, + the SPI stream is suspended in the full RxFIFO state + \arg SPI_CONTINUOUS: SPI stream/clock generation is continuous whether or not an overrun occurs + \param[out] none + \retval none +*/ +void spi_suspend_mode_config(uint32_t spi_periph, uint32_t sus_mode) +{ + if(SPI_AUTO_SUSPEND == sus_mode){ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_MASP; + }else{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_MASP); + } +} + +/*! + \brief SPI master mode suspend request + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_suspend_request(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_MSPDR; +} + +/*! + \brief enable SPI related IOs AF + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_related_ios_af_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_IOAFEN); +} + +/*! + \brief disable SPI related IOs AF + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_related_ios_af_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_IOAFEN; +} + +/*! + \brief SPI af gpio control + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] ctl: gpio control bit + only one parameter can be selected which is shown as below: + \arg SPI_GPIO_CONTROL: SPI always control all associated GPIO + \arg SPI_GPIO_FREE: SPI do not control GPIO when disabled + \param[out] none + \retval none +*/ +void spi_af_gpio_control(uint32_t spi_periph, uint32_t ctl) +{ + if(SPI_GPIO_CONTROL == ctl){ + SPI_CFG1(spi_periph) |= (uint32_t)SPI_CFG1_AFCTL; + }else{ + SPI_CFG1(spi_periph) &= (uint32_t)(~SPI_CFG1_AFCTL); + } +} + +/*! + \brief enable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_RP: RP interrupt + \arg SPI_I2S_INT_TP: TP interrupt + \arg SPI_I2S_INT_DP: DP interrupt + \arg SPI_I2S_INT_ESTC: end of transfer or suspend or TxFIFO clear interrupt + \arg SPI_I2S_INT_TXF: transmission filled interrupt + \arg SPI_I2S_INT_TXURE: underrun error interrupt + \arg SPI_I2S_INT_RXORE: overrun error interrupt + \arg SPI_I2S_INT_CRCER: CRC error interrupt + \arg SPI_I2S_INT_FE: TI frame error interrupt + \arg SPI_I2S_INT_CONFE: mode error interrupt + \arg SPI_I2S_INT_TXSERF: TXSER reload interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S RP interrupt */ + case SPI_I2S_INT_RP: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_RPIE; + break; + /* SPI/I2S TP interrupt */ + case SPI_I2S_INT_TP: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_TPIE; + break; + /* SPI/I2S DP interrupt */ + case SPI_I2S_INT_DP: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_DPIE; + break; + /* SPI/I2S end of transfer or suspend or TXFIFO clear interrupt */ + case SPI_I2S_INT_ESTC: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_ESTCIE; + break; + /* SPI/I2S transmission filled interrupt */ + case SPI_I2S_INT_TXF: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_TXFIE; + break; + /* SPI/I2S underrun error interrupt */ + case SPI_I2S_INT_TXURE: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_TXUREIE; + break; + /* SPI/I2S overrun error interrupt*/ + case SPI_I2S_INT_RXORE: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_RXOREIE; + break; + /* SPI/I2S CRC error interrupt */ + case SPI_I2S_INT_CRCER: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_CRCERIE; + break; + /* SPI TI frame error interrupt */ + case SPI_I2S_INT_FE: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_FEIE; + break; + /* SPI/I2S mode error interrupt */ + case SPI_I2S_INT_CONFE: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_CONFEIE; + break; + /* SPI/I2S TXSER reload interrupt */ + case SPI_I2S_INT_TXSERF: + SPI_INT(spi_periph) |= (uint32_t)SPI_INT_TXSERFIE; + break; + default: + break; + } +} + +/*! + \brief disable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_RP: RP interrupt + \arg SPI_I2S_INT_TP: TP interrupt + \arg SPI_I2S_INT_DP: DP interrupt + \arg SPI_I2S_INT_ESTC: end of transfer or suspend or TXFIFO clear interrupt + \arg SPI_I2S_INT_TXF: transmission filled interrupt + \arg SPI_I2S_INT_TXURE: underrun error interrupt + \arg SPI_I2S_INT_RXORE: overrun error interrupt + \arg SPI_I2S_INT_CRCER: CRC error interrupt + \arg SPI_I2S_INT_FE: TI frame error interrupt + \arg SPI_I2S_INT_CONFE: mode error interrupt + \arg SPI_I2S_INT_TXSERF: TXSER reload interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S RP interrupt */ + case SPI_I2S_INT_RP: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_RPIE); + break; + /* SPI/I2S TP interrupt */ + case SPI_I2S_INT_TP: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_TPIE); + break; + /* SPI/I2S DP interrupt */ + case SPI_I2S_INT_DP: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_DPIE); + break; + /* SPI/I2S end of transfer or suspend or TXFIFO clear interrupt */ + case SPI_I2S_INT_ESTC: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_ESTCIE); + break; + /* SPI/I2S transmission filled interrupt */ + case SPI_I2S_INT_TXF: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_TXFIE); + break; + /* SPI/I2S underrun error interrupt */ + case SPI_I2S_INT_TXURE: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_TXUREIE); + break; + /* SPI/I2S overrun error interrupt*/ + case SPI_I2S_INT_RXORE: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_RXOREIE); + break; + /* SPI/I2S CRC error interrupt */ + case SPI_I2S_INT_CRCER: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_CRCERIE); + break; + /* SPI TI frame error interrupt */ + case SPI_I2S_INT_FE: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_FEIE); + break; + /* SPI/I2S mode error interrupt */ + case SPI_I2S_INT_CONFE: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_CONFEIE); + break; + /* SPI/I2S TXSER reload interrupt */ + case SPI_I2S_INT_TXSERF: + SPI_INT(spi_periph) &= (uint32_t)(~SPI_INT_TXSERFIE); + break; + default: + break; + } +} + +/*! + \brief get SPI and I2S interrupt flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] interrupt: SPI/I2S interrupt flag status + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_FLAG_RP: RP interrupt flag + \arg SPI_I2S_INT_FLAG_TP: TP interrupt flag + \arg SPI_I2S_INT_FLAG_DP: DP interrupt flag + \arg SPI_I2S_INT_FLAG_ET: end of transfer or receive interrupt flag + \arg SPI_I2S_INT_FLAG_TXF: transmission filled interrupt flag + \arg SPI_I2S_INT_FLAG_TXURERR: underrun error interrupt flag + \arg SPI_I2S_INT_FLAG_RXORERR: overrun error interrupt flag + \arg SPI_I2S_INT_FLAG_CRCERR: CRC error interrupt flag + \arg SPI_I2S_INT_FLAG_FERR: TI frame error interrupt flag + \arg SPI_I2S_INT_FLAG_CONFERR: mode error interrupt flag + \arg SPI_I2S_INT_FLAG_TXSERF: TXSER reload interrupt flag + \arg SPI_I2S_INT_FLAG_SPD: suspend interrupt flag + \arg SPI_I2S_INT_FLAG_TC: TxFIFO clear interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt) +{ + uint32_t reg1 = SPI_STAT(spi_periph); + uint32_t reg2 = SPI_INT(spi_periph); + + switch(interrupt){ + /* SPI/I2S RP interrupt */ + case SPI_I2S_INT_FLAG_RP: + reg1 = reg1 & SPI_STAT_RP; + reg2 = reg2 & SPI_INT_RPIE; + break; + /* SPI/I2S TP interrupt */ + case SPI_I2S_INT_FLAG_TP: + reg1 = reg1 & SPI_STAT_TP; + reg2 = reg2 & SPI_INT_TPIE; + break; + /* SPI/I2S DP interrupt */ + case SPI_I2S_INT_FLAG_DP: + reg1 = reg1 & SPI_STAT_DP; + reg2 = reg2 & SPI_INT_DPIE; + break; + /* SPI end of transfer or receive interrupt */ + case SPI_I2S_INT_FLAG_ET: + reg1 = reg1 & SPI_STAT_ET; + reg2 = reg2 & SPI_INT_ESTCIE; + break; + /* SPI transmission filled interrupt */ + case SPI_I2S_INT_FLAG_TXF: + reg1 = reg1 & SPI_STAT_TXF; + reg2 = reg2 & SPI_INT_TXFIE; + break; + /* SPI/I2S underrun error interrupt */ + case SPI_I2S_INT_FLAG_TXURERR: + reg1 = reg1 & SPI_STAT_TXURERR; + reg2 = reg2 & SPI_INT_TXUREIE; + break; + /* SPI/I2S overrun error interrupt */ + case SPI_I2S_INT_FLAG_RXORERR: + reg1 = reg1 & SPI_STAT_RXORERR; + reg2 = reg2 & SPI_INT_RXOREIE; + break; + /* SPI/I2S CRC error interrupt */ + case SPI_I2S_INT_FLAG_CRCERR: + reg1 = reg1 & SPI_STAT_CRCERR; + reg2 = reg2 & SPI_INT_CRCERIE; + break; + /* SPI TI frame error interrupt */ + case SPI_I2S_INT_FLAG_FERR: + reg1 = reg1 & SPI_STAT_FERR; + reg2 = reg2 & SPI_INT_FEIE; + break; + /* SPI/I2S mode error interrupt */ + case SPI_I2S_INT_FLAG_CONFERR: + reg1 = reg1 & SPI_STAT_CONFERR; + reg2 = reg2 & SPI_INT_CONFEIE; + break; + /* SPI/I2S TXSER reload interrupt */ + case SPI_I2S_INT_FLAG_TXSERF: + reg1 = reg1 & SPI_STAT_TXSERF; + reg2 = reg2 & SPI_INT_TXSERFIE; + break; + /* SPI suspend interrupt */ + case SPI_I2S_INT_FLAG_SPD: + reg1 = reg1 & SPI_STAT_SPD; + reg2 = reg2 & SPI_INT_ESTCIE; + break; + /* SPI TXFIFO clear interrupt */ + case SPI_I2S_INT_FLAG_TC: + reg1 = reg1 & SPI_STAT_TC; + reg2 = reg2 & SPI_INT_ESTCIE; + break; + default : + break; + } + /*get SPI/I2S interrupt flag status */ + if(reg1 && reg2){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] flag: SPI/I2S flag status + only one parameter can be selected which is shown as below: + \arg SPI_FLAG_RP: RP flag + \arg SPI_FLAG_TP: TP flag + \arg SPI_FLAG_DP: DP flag + \arg SPI_FLAG_ET: end of transfer or receive flag + \arg SPI_FLAG_TXF: transmission filled flag + \arg SPI_FLAG_TXURERR: underrun error flag + \arg SPI_FLAG_RXORERR: overrun error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: TI frame error flag + \arg SPI_FLAG_CONFERR: mode error flag + \arg SPI_FLAG_TXSERF: TXSER reload flag + \arg SPI_FLAG_SPD: suspend flag + \arg SPI_FLAG_TC: TxFIFO clear flag + \arg SPI_FLAG_RWNE: the word of RXFIFO is not empty flag + + \arg I2S_FLAG_RP: RP flag + \arg I2S_FLAG_TP: TP flag + \arg I2S_FLAG_DP: DP flag + \arg I2S_FLAG_ET: end of transfer or receive flag + \arg I2S_FLAG_TXF: transmission filled flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_RXORERR: overrun error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag) +{ + if(SPI_STAT(spi_periph) & flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear SPI and I2S flag + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] flag: SPI/I2S flag status + only one parameter can be selected which is shown as below: + \arg SPI_STATC_ETC: clear the end of transfer flag + \arg SPI_STATC_TXFC: clear the send transmission filled flag + \arg SPI_STATC_TXURERRC: clear the transmission underrun error flag + \arg SPI_STATC_RXORERRC: clear the reception overrun error flag + \arg SPI_STATC_CRCERRC: clear the CRC error flag + \arg SPI_STATC_FERRC: clear the SPI TI format error flag + \arg SPI_STATC_CONFERRC: clear the configuration error flag + \arg SPI_STATC_TXSERFC: clear the TXSERF flag + \arg SPI_STATC_SPDC: clear the suspend flag + \param[out] none + \retval none +*/ +void spi_i2s_flag_clear(uint32_t spi_periph, uint32_t flag) +{ + SPI_STATC(spi_periph) |= (uint32_t)flag; +} + +/*! + \brief get SPI and I2S RXFIFO packing level + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 2-bit RXFIFO packing data frame number +*/ +uint32_t spi_i2s_rxfifo_plevel_get(uint32_t spi_periph) +{ + return ((uint32_t)((SPI_STAT(spi_periph) & SPI_STAT_RPLVL) >> 13U)); +} + +/*! + \brief get SPI and I2S remaining data frames number in the TXSIZE session + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 32-bit value +*/ +uint32_t spi_i2s_remain_data_num_get(uint32_t spi_periph) +{ + return ((uint32_t)((SPI_STAT(spi_periph) & SPI_STAT_CTXSIZE) >> 16U)); +} + +/*! + \brief set SPI FIFO threshold level + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] fifo_thl: SPI_FIFO_TH_01DATA, SPI_FIFO_TH_02DATA, SPI_FIFO_TH_03DATA, + SPI_FIFO_TH_04DATA, SPI_FIFO_TH_05DATA, SPI_FIFO_TH_06DATA, + SPI_FIFO_TH_07DATA, SPI_FIFO_TH_08DATA, SPI_FIFO_TH_09DATA, + SPI_FIFO_TH_10DATA, SPI_FIFO_TH_11DATA, SPI_FIFO_TH_12DATA, + SPI_FIFO_TH_13DATA, SPI_FIFO_TH_14DATA, SPI_FIFO_TH_15DATA, + SPI_FIFO_TH_16DATA + \param[out] none + \retval none +*/ +void spi_fifo_threshold_level_set(uint32_t spi_periph, uint32_t fifo_thl) +{ + SPI_CFG0(spi_periph) &= (uint32_t)(~SPI_CFG0_FIFOLVL); + SPI_CFG0(spi_periph) |= (uint32_t)fifo_thl; +} + +/*! + \brief enable SPI word access + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_word_access_enable(uint32_t spi_periph) +{ + SPI_CFG0(spi_periph) |= (uint32_t)SPI_CFG0_WORDEN; +} + +/*! + \brief disable SPI word access + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_word_access_disable(uint32_t spi_periph) +{ + SPI_CFG0(spi_periph) &= (uint32_t)(~SPI_CFG0_WORDEN); +} + +/*! + \brief enable SPI byte access + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_byte_access_enable(uint32_t spi_periph) +{ + SPI_CFG0(spi_periph) |= (uint32_t)SPI_CFG0_BYTEN; +} + +/*! + \brief disable SPI byte access + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_byte_access_disable(uint32_t spi_periph) +{ + SPI_CFG0(spi_periph) &= (uint32_t)(~SPI_CFG0_BYTEN); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_syscfg.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_syscfg.c new file mode 100644 index 0000000000..10b03bec08 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_syscfg.c @@ -0,0 +1,645 @@ +/*! + \file gd32h7xx_syscfg.c + \brief SYSCFG driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_syscfg.h" +/*! + \brief reset the SYSCFG registers + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_SYSCFGRST); + rcu_periph_reset_disable(RCU_SYSCFGRST); +} + +/*! + \brief enable I2Cx(x=0,1,2,3) fast mode plus or I2C fast mode plus PBx(x=6,7,8,9) + \param[in] i2c_fmp + one or more parameters can be selected which are shown as below: + \arg SYSCFG_I2C0_FMP: I2C0 fast mode plus + \arg SYSCFG_I2C1_FMP: I2C1 fast mode plus + \arg SYSCFG_I2C2_FMP: I2C2 fast mode plus + \arg SYSCFG_I2C3_FMP: I2C3 fast mode plus + \arg SYSCFG_I2C_FMP_PB6: I2C fast mode plus on PB6 pin + \arg SYSCFG_I2C_FMP_PB7: I2C fast mode plus on PB7 pin + \arg SYSCFG_I2C_FMP_PB8: I2C fast mode plus on PB8 pin + \arg SYSCFG_I2C_FMP_PB9: I2C fast mode plus on PB9 pin + \param[out] none + \retval none +*/ +void syscfg_i2c_fast_mode_plus_enable(uint32_t i2c_fmp) +{ + SYSCFG_PMCFG |= i2c_fmp; +} + +/*! + \brief disable I2Cx(x=0,1,2,3) fast mode plus or I2C fast mode plus PBx(x=6,7,8,9) + \param[in] i2c_fmp + one or more parameters can be selected which are shown as below: + \arg SYSCFG_I2C0_FMP: I2C0 fast mode plus + \arg SYSCFG_I2C1_FMP: I2C1 fast mode plus + \arg SYSCFG_I2C2_FMP: I2C2 fast mode plus + \arg SYSCFG_I2C3_FMP: I2C3 fast mode plus + \arg SYSCFG_I2C_FMP_PB6: I2C fast mode plus on PB6 pin + \arg SYSCFG_I2C_FMP_PB7: I2C fast mode plus on PB7 pin + \arg SYSCFG_I2C_FMP_PB8: I2C fast mode plus on PB8 pin + \arg SYSCFG_I2C_FMP_PB9: I2C fast mode plus on PB9 pin + \param[out] none + \retval none +*/ +void syscfg_i2c_fast_mode_plus_disable(uint32_t i2c_fmp) +{ + SYSCFG_PMCFG &= (uint32_t)(~i2c_fmp); +} + +/*! + \brief open analog switch (Pxy and Pxy_C are separated pads) + \param[in] gpio_answ: GPIO analog switch + one or more parameters can be selected which are shown as below: + \arg SYSCFG_PA0_ANALOG_SWITCH: PA0 analog switch + \arg SYSCFG_PA1_ANALOG_SWITCH: PA1 analog switch + \arg SYSCFG_PC2_ANALOG_SWITCH: PC2 analog switch + \arg SYSCFG_PC3_ANALOG_SWITCH: PC3 analog switch + \param[out] none + \retval none +*/ +void syscfg_analog_switch_enable(uint32_t gpio_answ) +{ + SYSCFG_PMCFG |= gpio_answ; +} + +/*! + \brief close analog switch (Pxy and Pxy_C are connected through the analog switch) + \param[in] gpio_answ: GPIO analog switch + one or more parameters can be selected which are shown as below: + \arg SYSCFG_PA0_ANALOG_SWITCH: PA0 analog switch + \arg SYSCFG_PA1_ANALOG_SWITCH: PA1 analog switch + \arg SYSCFG_PC2_ANALOG_SWITCH: PC2 analog switch + \arg SYSCFG_PC3_ANALOG_SWITCH: PC3 analog switch + \param[out] none + \retval none +*/ +void syscfg_analog_switch_disable(uint32_t gpio_answ) +{ + SYSCFG_PMCFG &= (uint32_t)(~gpio_answ); +} + +/*! + \brief configure the PHY interface for the ethernet MAC + \param[in] enet_periph: ENETx(x=0,1) + \param[in] phy_interface: specifies the media interface mode + only one parameter can be selected which is shown as below: + \arg SYSCFG_ENET_PHY_MII: MII mode is selected + \arg SYSCFG_ENET_PHY_RMII: RMII mode is selected + \param[out] none + \retval none +*/ +void syscfg_enet_phy_interface_config(uint32_t ethernet, uint32_t phy_interface) +{ + uint32_t reg; + /* read the value of SYSCFG_PMCFG register */ + reg = SYSCFG_PMCFG; + /* configure the ENET media interface */ + if(ENET0 == ethernet) { + reg &= ~SYSCFG_PMCFG_ENET0_PHY_SEL; + reg |= ENET0_MEDIA_INTERFACE(phy_interface); + } else { + reg &= ~SYSCFG_PMCFG_ENET1_PHY_SEL; + reg |= ENET1_MEDIA_INTERFACE(phy_interface); + } + SYSCFG_PMCFG = reg; +} + +/*! + \brief configure the GPIO pin as EXTI Line + \param[in] exti_port: specify the GPIO port used in EXTI + only one parameter can be selected which is shown as below: + \arg EXTI_SOURCE_GPIOx(x = A,B,C,D,E,F,G,H,J,K): EXTI GPIO port + \param[in] exti_pin: specify the EXTI line + only one parameter can be selected which is shown as below: + \arg EXTI_SOURCE_PINx(GPIOA x = 0..15,GPIOB x = 0..15,GPIOC x = 0..15,GPIOD x = 0..15,GPIOE x = 0..15, + GPIOF x = 0..15,GPIOG x = 0..15,GPIOH x = 0..15,GPIOI x = 0..15,GPIOJ x = 8,9,10,11, GPIOK x = 0,1,2,4,5,6): EXTI GPIO pin + \param[out] none + \retval none +*/ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) +{ + uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); + uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); + + switch(exti_pin / EXTI_SS_JSTEP) { + case EXTISS0: + /* clear EXTI source line(0..3) */ + SYSCFG_EXTISS0 &= clear_exti_mask; + /* configure EXTI soure line(0..3) */ + SYSCFG_EXTISS0 |= config_exti_mask; + break; + case EXTISS1: + /* clear EXTI soure line(4..7) */ + SYSCFG_EXTISS1 &= clear_exti_mask; + /* configure EXTI soure line(4..7) */ + SYSCFG_EXTISS1 |= config_exti_mask; + break; + case EXTISS2: + /* clear EXTI soure line(8..11) */ + SYSCFG_EXTISS2 &= clear_exti_mask; + /* configure EXTI soure line(8..11) */ + SYSCFG_EXTISS2 |= config_exti_mask; + break; + case EXTISS3: + /* clear EXTI soure line(12..15) */ + SYSCFG_EXTISS3 &= clear_exti_mask; + /* configure EXTI soure line(12..15) */ + SYSCFG_EXTISS3 |= config_exti_mask; + break; + default: + break; + } +} + +/*! + \brief enable module lockup function (function can be disabled by system reset) + \param[in] lockup: + one or more parameters can be selected which are shown as below: + \arg SYSCFG_LVD_LOCKUP: LVD signal + \arg SYSCFG_CPU_LOCKUP: CPU lockup signal + \arg SYSCFG_BKPRAM_LOCKUP: Region 2 backup SRAM ECC double error signal + \arg SYSCFG_SRAM1_LOCKUP: Region 1 SRAM1 ECC double error signal + \arg SYSCFG_SRAM0_LOCKUP: Region 1 SRAM0 ECC double error signal + \arg SYSCFG_DTCM_LOCKUP: Region 0 DTCM ECC double error signal + \arg SYSCFG_ITCM_LOCKUP: Region 0 ITCM-RAM ECC double error signal + \arg SYSCFG_AXIRAM_LOCKUP: Region 0 AXI-SRAM ECC double error signal + \param[out] none + \retval none +*/ +void syscfg_lockup_enable(uint32_t lockup) +{ + SYSCFG_LKCTL |= lockup; +} + +/*! + \brief select timer channel input source + \param[in] timer_input: TIMER channel input select, refer to timer_channel_input_enum + \arg TIMER7_CI0_INPUT_TIMER7_CH0: select CMP1 output as TIMER7 CI0 + \arg TIMER7_CI0_INPUT_CMP1_OUT: select TIMER7 CH0 as TIMER7 CI0 + \arg TIMER7_CI1_INPUT_TIMER7_CH1: select TIMER7 CH1 as TIMER7 CI1 + \arg TIMER7_CI2_INPUT_TIMER7_CH2: select TIMER7 CH2 as TIMER7 CI2 + \arg TIMER7_CI3_INPUT_TIMER7_CH3: select TIMER7 CH3 as TIMER7 CI3 + \arg TIMER0_CI0_INPUT_TIMER0_CH0: select CMP0 output as TIMER0 CI0 + \arg TIMER0_CI0_INPUT_CMP0_OUT: select TIMER0 CH0 as TIMER0 CI0 + \arg TIMER0_CI1_INPUT_TIMER0_CH1: select TIMER0 CH1 as TIMER0 CI1 + \arg TIMER0_CI2_INPUT_TIMER0_CH2: select TIMER0 CH2 as TIMER0 CI2 + \arg TIMER0_CI3_INPUT_TIMER0_CH3: select TIMER0 CH3 as TIMER0 CI3 + \arg TIMER2_CI0_INPUT_TIMER2_CH0: select TIMER2 CH0 as TIMER2 CI0 + \arg TIMER2_CI0_INPUT_CMP0_OUT: select CMP0 as TIMER2 CI0 + \arg TIMER2_CI0_INPUT_CMP1_OUT: select CMP1 as TIMER2 CI0 + \arg TIMER2_CI0_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 as TIMER2 CI0 + \arg TIMER2_CI1_INPUT_TIMER2_CH1: select TIMER2 CH1 as TIMER2 CI1 + \arg TIMER2_CI2_INPUT_TIMER2_CH2: select TIMER2 CH2 as TIMER2 CI2 + \arg TIMER2_CI3_INPUT_TIMER2_CH3: select TIMER2 CH3 as TIMER2 CI3 + \arg TIMER1_CI0_INPUT_TIMER1_CH0: select TIMER1 CH0 as TIMER1 CI0 + \arg TIMER1_CI1_INPUT_TIMER1_CH1: select TIMER1 CH1 as TIMER1 CI1 + \arg TIMER1_CI2_INPUT_TIMER1_CH2: select TIMER1 CH2 as TIMER1 CI2 + \arg TIMER1_CI3_INPUT_TIMER1_CH3: select TIMER1 CH3 as TIMER1 CI3 + \arg TIMER1_CI3_INPUT_CMP0_OUT: select CMP0 output as TIMER1 CI3 + \arg TIMER1_CI3_INPUT_CMP1_OUT: select CMP1 output as TIMER1 CI3 + \arg TIMER1_CI3_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER1 CI3 + \arg TIMER4_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER4 CI0 + \arg TIMER4_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER4 CI1 + \arg TIMER4_CI2_INPUT_TIMER4_CH2: select TIMER4 CH2 as TIMER4 CI2 + \arg TIMER4_CI3_INPUT_TIMER4_CH3: select TIMER4 CH3 as TIMER4 CI3 + \arg TIMER3_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER3 CI0 + \arg TIMER3_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER3 CI1 + \arg TIMER3_CI2_INPUT_TIMER3_CH2: select TIMER3 CH2 as TIMER3 CI2 + \arg TIMER3_CI3_INPUT_TIMER3_CH3: select TIMER3 CH3 as TIMER3 CI3 + \arg TIMER23_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER23 CI0 + \arg TIMER23_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER23 CI1 + \arg TIMER23_CI2_INPUT_TIMER23_CH2: select TIMER23 CH2 as TIMER23 CI2 + \arg TIMER23_CI3_INPUT_TIMER23_CH3: select TIMER23 CH3 as TIMER23 CI3 + \arg TIMER22_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER22 CI0 + \arg TIMER22_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER22 CI1 + \arg TIMER22_CI2_INPUT_TIMER22_CH2: select TIMER22 CH2 as TIMER22 CI2 + \arg TIMER22_CI3_INPUT_TIMER22_CH3: select TIMER22 CH3 as TIMER22 CI3 + \arg TIMER22_CI3_INPUT_CMP0_OUT: select CMP0 output as TIMER22 CI3 + \arg TIMER22_CI3_INPUT_CMP1_OUT: select CMP1 output as TIMER22 CI3 + \arg TIMER22_CI3_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER22 CI3 + \arg TIMER31_CI0_INPUT_TIMER31_CH0: select TIMER31 CH0 as TIMER31 CI0 + \arg TIMER31_CI0_INPUT_CMP0_OUT: select CMP0 output as TIMER31 CI0 + \arg TIMER31_CI0_INPUT_CMP1_OUT: select CMP1 output as TIMER31 CI0 + \arg TIMER31_CI0_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER31 CI0 + \arg TIMER31_CI1_INPUT_TIMER31_CH1: select TIMER31 CH1 as TIMER31 CI1 + \arg TIMER31_CI2_INPUT_TIMER31_CH2: select TIMER31 CH2 as TIMER31 CI2 + \arg TIMER31_CI3_INPUT_TIMER31_CH3: select TIMER31 CH3 as TIMER31 CI3 + \arg TIMER30_CI0_INPUT_TIMER30_CH0: select TIMER30 CH0 as TIMER30 CI0 + \arg TIMER30_CI0_INPUT_CMP0_OUT: select CMP0 output as TIMER30 CI0 + \arg TIMER30_CI0_INPUT_CMP1_OUT: select CMP1 output as TIMER30 CI0 + \arg TIMER30_CI0_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER30 CI0 + \arg TIMER30_CI1_INPUT_TIMER30_CH1: select TIMER30 CH1 as TIMER30 CI1 + \arg TIMER30_CI2_INPUT_TIMER30_CH2: select TIMER30 CH2 as TIMER30 CI2 + \arg TIMER30_CI3_INPUT_TIMER30_CH3: select TIMER30 CH3 as TIMER30 CI3 + \arg TIMER14_CI0_INPUT_TIMER14_CH0: select TIMER14 CH0 as TIMER14 CI0 + \arg TIMER14_CI0_INPUT_TIMER1_CH0: select TIMER1 CH0 as TIMER14 CI0 + \arg TIMER14_CI0_INPUT_TIMER2_CH0: select TIMER2 CH0 as TIMER14 CI0 + \arg TIMER14_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER14 CI0 + \arg TIMER14_CI0_INPUT_LXTAL: select LXTAL as TIMER14 CI0 + \arg TIMER14_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER14 CI0 + \arg TIMER14_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER14 CI0 + \arg TIMER14_CI1_INPUT_TIMER14_CH1: select TIMER14 CH1 as TIMER14 CI1 + \arg TIMER14_CI1_INPUT_TIMER1_CH1: select TIMER1 CH1 as TIMER14 CI1 + \arg TIMER14_CI1_INPUT_TIMER2_CH1: select TIMER2 CH1 as TIMER14 CI1 + \arg TIMER14_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER14 CI1 + \arg TIMER40_CI0_INPUT_TIMER40_CH0: select TIMER40 CH0 as TIMER40 CI0 + \arg TIMER40_CI0_INPUT_TIMER2_CH0: select TIMER2 CH0 as TIMER40 CI0 + \arg TIMER40_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER40 CI0 + \arg TIMER40_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER40 CI0 + \arg TIMER40_CI0_INPUT_LXTAL: select LXTAL as TIMER40 CI0 + \arg TIMER40_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER40 CI0 + \arg TIMER40_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER40 CI0 + \arg TIMER40_CI1_INPUT_TIMER40_CH1: select TIMER40 CH1 as TIMER40 CI0 + \arg TIMER40_CI1_INPUT_TIMER2_CH1: select TIMER2 CH1 as TIMER40 CI0 + \arg TIMER40_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER40 CI0 + \arg TIMER40_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER40 CI0 + \arg TIMER41_CI0_INPUT_TIMER41_CH0: select TIMER41 CH0 as TIMER41 CI0 + \arg TIMER41_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER41 CI0 + \arg TIMER41_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER41 CI0 + \arg TIMER41_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER41 CI0 + \arg TIMER41_CI0_INPUT_LXTAL: select LXTAL as TIMER41 CI0 + \arg TIMER41_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER41 CI0 + \arg TIMER41_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER41 CI0 + \arg TIMER41_CI1_INPUT_TIMER41_CH1: select TIMER41 CH1 as TIMER41 CI1 + \arg TIMER41_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER41 CI1 + \arg TIMER41_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER41 CI1 + \arg TIMER41_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER41 CI1 + \arg TIMER42_CI0_INPUT_TIMER42_CH0: select TIMER42 CH0 as TIMER42 CI0 + \arg TIMER42_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER42 CI0 + \arg TIMER42_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER42 CI0 + \arg TIMER42_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER42 CI0 + \arg TIMER42_CI0_INPUT_LXTAL: select LXTAL as TIMER42 CI0 + \arg TIMER42_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER42 CI0 + \arg TIMER42_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER42 CI0 + \arg TIMER42_CI1_INPUT_TIMER42_CH1: select TIMER42 CH1 as TIMER42 CI1 + \arg TIMER42_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER42 CI1 + \arg TIMER42_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER42 CI1 + \arg TIMER42_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER42 CI1 + \arg TIMER15_CI0_INPUT_TIMER15_CH0: select TIMER15 CH0 as TIMER15 CI0 + \arg TIMER15_CI0_INPUT_IRC32K: select IRC32K as TIMER15 CI0 + \arg TIMER15_CI0_INPUT_LXTAL: select LXTAL as TIMER15 CI0 + \arg TIMER15_CI0_INPUT_WKUP_IT: select WKUP IT as TIMER15 CI0 + \arg TIMER16_CI0_INPUT_TIMER16_CH0: select TIMER16 CH0 as TIMER16 CI0 + \arg TIMER16_CI0_INPUT_HXTAL_RTCDIV: select HXTAL/RTCDIV 1M as TIMER16 CI0 + \arg TIMER16_CI0_INPUT_CKOUT0: select CKOUT0 as TIMER16 CI0 + \arg TIMER43_CI0_INPUT_TIMER43_CH0: select TIMER43 CH0 as TIMER43 CI0 + \arg TIMER43_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER43 CI0 + \arg TIMER43_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER43 CI0 + \arg TIMER43_CI0_INPUT_TIMER30_CH0: select TIMER30 CH0 as TIMER43 CI0 + \arg TIMER43_CI0_INPUT_LXTAL: select LXTAL as TIMER43 CI0 + \arg TIMER43_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER43 CI0 + \arg TIMER43_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER43 CI0 + \arg TIMER43_CI1_INPUT_TIMER43_CH1: select TIMER43 CH1 as TIMER43 CI1 + \arg TIMER43_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER43 CI1 + \arg TIMER43_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER43 CI1 + \arg TIMER43_CI1_INPUT_TIMER30_CH1: select TIMER30 CH1 as TIMER43 CI1 + \arg TIMER44_CI0_INPUT_TIMER44_CH0: select TIMER44 CH0 as TIMER44 CI0 + \arg TIMER44_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER44 CI0 + \arg TIMER44_CI0_INPUT_TIMER30_CH0: select TIMER30 CH0 as TIMER44 CI0 + \arg TIMER44_CI0_INPUT_TIMER31_CH0: select TIMER31 CH0 as TIMER44 CI0 + \arg TIMER44_CI0_INPUT_LXTAL: select LXTAL as TIMER44 CI0 + \arg TIMER44_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER44 CI0 + \arg TIMER44_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER44 CI0 + \arg TIMER44_CI1_INPUT_TIMER44_CH1: select TIMER44 CH1 as TIMER44 CI1 + \arg TIMER44_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER44 CI1 + \arg TIMER44_CI1_INPUT_TIMER30_CH1: select TIMER30 CH1 as TIMER44 CI1 + \arg TIMER44_CI1_INPUT_TIMER31_CH1: select TIMER31 CH1 as TIMER44 CI1 + \param[out] none + \retval none +*/ +void syscfg_timer_input_source_select(timer_channel_input_enum timer_input) +{ + uint32_t clear_timer_mask = ~((uint32_t)TIMER_IS_MASK << (TIMER_BIT_POS(timer_input))); + uint32_t config_timer_mask = (TIMER_SEL_VAL(timer_input) << TIMER_BIT_POS(timer_input)); + + switch(TIMER_REG_INDEX(timer_input)) { + case TIMERCISEL0: + /* clear TIMER channel input select */ + SYSCFG_TIMERCISEL0 &= clear_timer_mask; + /* config TIMER channel input */ + SYSCFG_TIMERCISEL0 |= config_timer_mask; + break; + case TIMERCISEL1: + /* clear TIMER channel input select */ + SYSCFG_TIMERCISEL1 &= clear_timer_mask; + /* config TIMER channel input */ + SYSCFG_TIMERCISEL1 |= config_timer_mask; + break; + case TIMERCISEL2: + /* clear TIMER channel input select */ + SYSCFG_TIMERCISEL2 &= clear_timer_mask; + /* config TIMER channel input */ + SYSCFG_TIMERCISEL2 |= config_timer_mask; + break; + case TIMERCISEL3: + /* clear TIMER channel input select */ + SYSCFG_TIMERCISEL3 &= clear_timer_mask; + /* config TIMER channel input */ + SYSCFG_TIMERCISEL3 |= config_timer_mask; + break; + case TIMERCISEL4: + /* clear TIMER channel input select */ + SYSCFG_TIMERCISEL4 &= clear_timer_mask; + /* config TIMER channel input */ + SYSCFG_TIMERCISEL4 |= config_timer_mask; + break; + case TIMERCISEL5: + /* clear TIMER channel input select */ + SYSCFG_TIMERCISEL5 &= clear_timer_mask; + /* config TIMER channel input */ + SYSCFG_TIMERCISEL5 |= config_timer_mask; + break; + case TIMERCISEL6: + /* clear TIMER channel input select */ + SYSCFG_TIMERCISEL6 &= clear_timer_mask; + /* config TIMER channel input */ + SYSCFG_TIMERCISEL6 |= config_timer_mask; + break; + default: + break; + } +} + +/*! + \brief configure the I/O compensation cell + \param[in] syscfg_cps: specifies the I/O compensation cell mode + only one parameter can be selected which is shown as below: + \arg SYSCFG_IO_COMPENSATION_ENABLE: I/O compensation cell is enabled + \arg SYSCFG_IO_COMPENSATION_DISABLE: I/O compensation cell is disabled + \param[out] none + \retval none +*/ +void syscfg_io_compensation_config(uint32_t syscfg_cps) +{ + uint32_t reg; + + reg = SYSCFG_CPSCTL; + /* reset the SYSCFG_CPSCTL_CPS_EN bit and set according to syscfg_compensation */ + reg &= ~SYSCFG_CPSCTL_CPS_EN; + SYSCFG_CPSCTL = (reg | syscfg_cps); +} + +/*! + \brief enable I/O speed optimization, high-speed at low-voltage + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_io_low_voltage_speed_optimization_enable(void) +{ + SYSCFG_CPSCTL |= SYSCFG_CPSCTL_IOSPDOP; +} + +/*! + \brief disable I/O speed optimization, high-speed at low-voltage + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_io_low_voltage_speed_optimization_disable(void) +{ + SYSCFG_CPSCTL &= ~SYSCFG_CPSCTL_IOSPDOP; +} + +/*! + \brief set P/N MOS compensation value + \param[in] mos + only one parameter can be selected which is shown as below: + \arg NMOS_COMPENSATION: NMOS + \arg PMOS_COMPENSATION: PMOS + \param[in] code: P/N MOS compensation value + \param[out] none + \retval none +*/ +void syscfg_pnmos_compensation_code_set(uint32_t mos, uint32_t code) +{ + uint32_t value; + value = SYSCFG_CPSCCCFG; + if(NMOS_COMPENSATION == mos) { + value &= ~SYSCFG_CPSCCCFG_NCPSCC; + value |= (code & 0x0FU); + } else { + value &= ~SYSCFG_CPSCCCFG_PCPSCC; + value |= ((code & 0x0FU) << 4U); + } + SYSCFG_CPSCCCFG = value; +} + +/*! + \brief set secure SRAM size + \param[in] SRAM size + only one parameter can be selected which is shown as below: + \arg SECURE_SRAM_SIZE_0KB: secure SRAM size is 0KB + \arg SECURE_SRAM_SIZE_32KB: secure SRAM size is 32KB + \arg SECURE_SRAM_SIZE_64KB: secure SRAM size is 64KB + \arg SECURE_SRAM_SIZE_128KB: secure SRAM size is 128KB + \param[out] none + \retval none +*/ +void syscfg_secure_sram_size_set(uint32_t size) +{ + SYSCFG_SRAMCFG0 &= (uint32_t)(~SYSCFG_SRAMCFG0_SECURE_SRAM_SIZE); + SYSCFG_SRAMCFG0 |= size; +} + +/*! + \brief get secure SRAM size + \param[in] none + \param[out] none + \retval SRAM size + \arg SECURE_SRAM_SIZE_0KB: secure SRAM size is 0KB + \arg SECURE_SRAM_SIZE_32KB: secure SRAM size is 32KB + \arg SECURE_SRAM_SIZE_64KB: secure SRAM size is 64KB + \arg SECURE_SRAM_SIZE_128KB: secure SRAM size is 128KB +*/ +uint32_t syscfg_secure_sram_size_get(void) +{ + return (SYSCFG_SRAMCFG0 & SYSCFG_SRAMCFG0_SECURE_SRAM_SIZE); +} + +/*! + \brief get BOOT mode + \param[in] none + \param[out] none + \retval boot mode + \arg BOOT_SRAM: BOOT from SRAM (ITCM/DTCM/RAM shared/AXI SRAM) + \arg BOOT_SECURITY: BOOT from Security + \arg BOOT_SYSTEM: BOOT_SYS (BootLoader) + \arg BOOT_USER_FLASH: BOOT_USER (User flash OSPI0/1) +*/ +uint32_t syscfg_bootmode_get(void) +{ + return ((SYSCFG_USERCFG & SYSCFG_USERCFG_BOOT_MODE) >> 4U); +} + +/*! + \brief enable TCM wait state + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_tcm_wait_state_enable(void) +{ + SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE; +} + +/*! + \brief disable TCM wait state + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_tcm_wait_state_disable(void) +{ + SYSCFG_SRAMCFG1 &= ~SYSCFG_SRAMCFG1_TCM_WAITSTATE; +} + +/*! + \brief enable FPU interrupt + \param[in] fpu_int: FPU interrupt + one or more parameters can be selected which are shown as below: + \arg SYSCFG_FPUINT_INEXACT: inexact interrupt + \arg SYSCFG_FPUINT_INPUT_ABNORMAL: input abnormal interrupt + \arg SYSCFG_FPUINT_OVERFLOW: overflow interrupt + \arg SYSCFG_FPUINT_UNDERFLOW: underflow interrupt + \arg SYSCFG_FPUINT_DIV0: divide-by-zero interrupt + \arg SYSCFG_FPUINT_INVALID_OPERATION: invalid operation interrupt + \param[out] none + \retval none +*/ +void syscfg_fpu_interrupt_enable(uint32_t fpu_int) +{ + SYSCFG_FPUINTEN |= fpu_int; +} + +/*! + \brief disable FPU interrupt + \param[in] fpu_int: FPU interrupt + one or more parameters can be selected which are shown as below: + \arg SYSCFG_FPUINT_INEXACT: inexact interrupt + \arg SYSCFG_FPUINT_INPUT_ABNORMAL: input abnormal interrupt + \arg SYSCFG_FPUINT_OVERFLOW: overflow interrupt + \arg SYSCFG_FPUINT_UNDERFLOW: underflow interrupt + \arg SYSCFG_FPUINT_DIV0: divide-by-zero interrupt + \arg SYSCFG_FPUINT_INVALID_OPERATION: invalid operation interrupt + \param[out] none + \retval none +*/ +void syscfg_fpu_interrupt_disable(uint32_t fpu_int) +{ + SYSCFG_FPUINTEN &= (uint32_t)(~fpu_int); +} + +/*! + \brief get compensation cell flags + \param[in] cps_flag: compensation flag + \arg SYSCFG_FLAG_IO_LOW_VOLTAGE: I/O in low voltage state flag, product supply voltage is working below 2.5V + \arg SYSCFG_FLAG_COMPENSATION_READY: I/O compensation cell ready flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus syscfg_compensation_flag_get(uint32_t cps_flag) +{ + if(SYSCFG_CPSCTL & cps_flag) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief get the ICACHE or DCACHE detection and error information + \param[in] cache: + only one parameter can be selected which is shown as below: + \arg ICACHE_STATUS: select ICACHE + \arg DCACHE_STATUS: select DCACHE + \param[in] status: + only one parameter can be selected which is shown as below: + \arg CPU_CACHE_ERROR_DETECTION: select detection information + \arg CPU_CACHE_ERROR_BANK: select error information + \param[out] none + \retval value +*/ +uint32_t syscfg_cpu_cache_status_get(uint32_t cache, uint32_t status) +{ + uint32_t value = 0U; + switch(cache) { + /* get ICACHE information */ + case ICACHE_STATUS: + if(CPU_CACHE_ERROR_DETECTION == status) { + /* return detection information */ + value = (uint32_t)((SYSCFG_CPUICAC & SYSCFG_CPUICAC_CPU_ICDET) >> 28U); + } else { + /* return error bank information */ + value = (uint32_t)((SYSCFG_CPUICAC & SYSCFG_CPUICAC_CPU_ICERR) >> 6U); + } + break; + /* get DCACHE information */ + case DCACHE_STATUS: + if(CPU_CACHE_ERROR_DETECTION == status) { + /* return detection information */ + value = (uint32_t)((SYSCFG_CPUDCAC & SYSCFG_CPUICAC_CPU_ICDET) >> 28U); + } else { + /* return error bank information */ + value = (uint32_t)((SYSCFG_CPUDCAC & SYSCFG_CPUICAC_CPU_ICERR) >> 6U); + } + break; + default: + break; + } + return value; +} + +/*! + \brief get brownout reset threshold level + \param[in] none + \param[out] none + \retval BOR level + \arg BOR_OFF: no BOR function + \arg BOR_THRESHOLD_VAL1: BOR threshold value 1 + \arg BOR_THRESHOLD_VAL2: BOR threshold value 2 + \arg BOR_THRESHOLD_VAL3: BOR threshold value 3 +*/ +uint32_t syscfg_brownout_reset_threshold_level_get(void) +{ + return (SYSCFG_USERCFG & SYSCFG_USERCFG_BOR_TH); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_timer.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_timer.c new file mode 100644 index 0000000000..9dc172819a --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_timer.c @@ -0,0 +1,4055 @@ +/*! + \file gd32h7xx_timer.c + \brief TIMER driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_timer.h" + +/* TIMER init parameter mask */ +#define ALIGNEDMODE_MASK ((uint32_t)0x00000060U) /*!< TIMER init parameter aligne dmode mask */ +#define COUNTERDIRECTION_MASK ((uint32_t)0x00000010U) /*!< TIMER init parameter counter direction mask */ +#define CLOCKDIVISION_MASK ((uint32_t)0x00000300U) /*!< TIMER init parameter clock division value mask */ +#define TIMER_CNT_UPIFBU_MASK ((uint32_t)0x80000000U) /*!< the UPIFBU bit mask */ + +/*! + \brief deinit a TIMER + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph) { + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER1: + /* reset TIMER1 */ + rcu_periph_reset_enable(RCU_TIMER1RST); + rcu_periph_reset_disable(RCU_TIMER1RST); + break; + case TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER3: + /* reset TIMER3 */ + rcu_periph_reset_enable(RCU_TIMER3RST); + rcu_periph_reset_disable(RCU_TIMER3RST); + break; + case TIMER4: + /* reset TIMER4 */ + rcu_periph_reset_enable(RCU_TIMER4RST); + rcu_periph_reset_disable(RCU_TIMER4RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER6: + /* reset TIMER6 */ + rcu_periph_reset_enable(RCU_TIMER6RST); + rcu_periph_reset_disable(RCU_TIMER6RST); + break; + case TIMER7: + /* reset TIMER7 */ + rcu_periph_reset_enable(RCU_TIMER7RST); + rcu_periph_reset_disable(RCU_TIMER7RST); + break; + case TIMER14: + /* reset TIMER14 */ + rcu_periph_reset_enable(RCU_TIMER14RST); + rcu_periph_reset_disable(RCU_TIMER14RST); + break; + case TIMER15: + /* reset TIMER15 */ + rcu_periph_reset_enable(RCU_TIMER15RST); + rcu_periph_reset_disable(RCU_TIMER15RST); + break; + case TIMER16: + /* reset TIMER16 */ + rcu_periph_reset_enable(RCU_TIMER16RST); + rcu_periph_reset_disable(RCU_TIMER16RST); + break; + case TIMER22: + /* reset TIMER22 */ + rcu_periph_reset_enable(RCU_TIMER22RST); + rcu_periph_reset_disable(RCU_TIMER22RST); + break; + case TIMER23: + /* reset TIMER23 */ + rcu_periph_reset_enable(RCU_TIMER23RST); + rcu_periph_reset_disable(RCU_TIMER23RST); + break; + case TIMER30: + /* reset TIMER30 */ + rcu_periph_reset_enable(RCU_TIMER30RST); + rcu_periph_reset_disable(RCU_TIMER30RST); + break; + case TIMER31: + /* reset TIMER31 */ + rcu_periph_reset_enable(RCU_TIMER31RST); + rcu_periph_reset_disable(RCU_TIMER31RST); + break; + case TIMER40: + /* reset TIMER40 */ + rcu_periph_reset_enable(RCU_TIMER40RST); + rcu_periph_reset_disable(RCU_TIMER40RST); + break; + case TIMER41: + /* reset TIMER41 */ + rcu_periph_reset_enable(RCU_TIMER41RST); + rcu_periph_reset_disable(RCU_TIMER41RST); + break; + case TIMER42: + /* reset TIMER42 */ + rcu_periph_reset_enable(RCU_TIMER42RST); + rcu_periph_reset_disable(RCU_TIMER42RST); + break; + case TIMER43: + /* reset TIMER43 */ + rcu_periph_reset_enable(RCU_TIMER43RST); + rcu_periph_reset_disable(RCU_TIMER43RST); + break; + case TIMER44: + /* reset TIMER44 */ + rcu_periph_reset_enable(RCU_TIMER44RST); + rcu_periph_reset_disable(RCU_TIMER44RST); + break; + case TIMER50: + /* reset TIMER50 */ + rcu_periph_reset_enable(RCU_TIMER50RST); + rcu_periph_reset_disable(RCU_TIMER50RST); + break; + case TIMER51: + /* reset TIMER51 */ + rcu_periph_reset_enable(RCU_TIMER51RST); + rcu_periph_reset_disable(RCU_TIMER51RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER init parameter struct with a default value + \param[in] initpara: init parameter struct + \param[out] none + \retval none +*/ +void timer_struct_para_init(timer_parameter_struct *initpara) +{ + /* initialize the init parameter struct member with the default value */ + initpara->prescaler = 0U; + initpara->alignedmode = TIMER_COUNTER_EDGE; + initpara->counterdirection = TIMER_COUNTER_UP; + initpara->period = 0xFFFFFFFFFFFFFFFFU; + initpara->clockdivision = TIMER_CKDIV_DIV1; + initpara->repetitioncounter = 0U; +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] initpara: init parameter struct + prescaler: prescaler value of the counter clock, 0~65535 + alignedmode: TIMER_COUNTER_EDGE, TIMER_COUNTER_CENTER_DOWN, TIMER_COUNTER_CENTER_UP, TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP, TIMER_COUNTER_DOWN + period: counter auto reload value, 0~0xFFFF(TIMERx(x=0,7,14~16,40~44)) + 0~0xFFFFFFFF(TIMERx(x=1~6,22,23,30,31)) + 0~0xFFFFFFFFFFFFFFFF(TIMERx(x=50,51)) + clockdivision: TIMER_CKDIV_DIV1, TIMER_CKDIV_DIV2, TIMER_CKDIV_DIV4(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + repetitioncounter: counter repetition value, 0~0xFF, use TIMER_CREP0 register(TIMERx(x=0,7,14~16,40~44) + 0xFF~0xFFFFFFFF, use TIMER_CREP1 register(TIMERx(x=0,7,14~16,40~44) + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct *initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph) || \ + (TIMER3 == timer_periph) || (TIMER4 == timer_periph) || (TIMER22 == timer_periph) || (TIMER23 == timer_periph) || \ + (TIMER30 == timer_periph) || (TIMER31 == timer_periph)) { + TIMER_CTL0(timer_periph) &= (~(uint32_t)(TIMER_CTL0_DIR | TIMER_CTL0_CAM)); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->alignedmode & ALIGNEDMODE_MASK); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->counterdirection & COUNTERDIRECTION_MASK); + } + + /* configure the autoreload value */ + if((TIMER50 == timer_periph) || (TIMER51 == timer_periph)) { + TIMER_CARL(timer_periph) = (uint32_t)initpara->period; + TIMER_CARH(timer_periph) = (uint32_t)(initpara->period >> 32U); + } else { + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + } + + /* configure the clock division value */ + if((TIMER5 != timer_periph) && (TIMER6 != timer_periph) && (TIMER50 != timer_periph) && (TIMER51 != timer_periph)) { + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_CKDIV); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->clockdivision & CLOCKDIVISION_MASK); + } + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || \ + (TIMER16 == timer_periph) || (TIMER40 == timer_periph) || (TIMER41 == timer_periph) || (TIMER42 == timer_periph) || \ + (TIMER43 == timer_periph) || (TIMER44 == timer_periph)) { + /* configure the repetition counter value */ + if(initpara->repetitioncounter <= 255U) { + TIMER_CFG(timer_periph) &= (~(uint32_t)TIMER_CFG_CREPSEL); + TIMER_CREP0(timer_periph) = (uint32_t)initpara->repetitioncounter; + } else { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CREPSEL; + TIMER_CREP1(timer_periph) = (uint32_t)initpara->repetitioncounter; + } + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; +} + +/*! + \brief enable a TIMER + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief disable a TIMER + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_CEN); +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_ARSE); +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_UPDIS); +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] aligned: center-aligned mode + only one parameter can be selected which is shown as below: + \arg TIMER_COUNTER_EDGE: edge-aligned mode + \arg TIMER_COUNTER_CENTER_DOWN: center-aligned and counting down assert mode + \arg TIMER_COUNTER_CENTER_UP: center-aligned and counting up assert mode + \arg TIMER_COUNTER_CENTER_BOTH: center-aligned and counting up/down assert mode + \param[out] none + \retval none +*/ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)aligned; +} + +/*! + \brief set TIMER counter up direction + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_DIR); +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] prescaler: prescaler value, 0~0xFFFF + \param[in] pscreload: prescaler reload mode + only one parameter can be selected which is shown as below: + \arg TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now + \arg TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event + \param[out] none + \retval none +*/ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint32_t pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)prescaler; + + if(TIMER_PSC_RELOAD_NOW == pscreload) { + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] ccsel: repetition register selection + only one parameter can be selected which is shown as below: + \arg TIMER_CREP0_ENABLE: The update event rate is depended to TIMERx_CREP0 register + \arg TIMER_CREP1_ENABLE: The update event rate is depended to TIMERx_CREP1 register + \param[in] repetition: the counter repetition value, 0~0xFF, use TIMER_CREP0 register, + 0~0xFFFFFFFF, use TIMER_CREP1 register + \param[out] none + \retval none +*/ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t ccsel, uint32_t repetition) +{ + if(TIMER_CREP0_ENABLE == ccsel) { + TIMER_CFG(timer_periph) &= (~(uint32_t)TIMER_CFG_CREPSEL); + TIMER_CREP0(timer_periph) = (uint32_t)repetition; + } else if(TIMER_CREP1_ENABLE == ccsel) { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CREPSEL; + TIMER_CREP1(timer_periph) = (uint32_t)repetition; + } else { + /* illegal parameters */ + } +} + +/*! + \brief read TIMER runtime repetition register value + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[out] none + \retval counter repetition value in TIMER_CREP1 register, 0~0xFFFFFFFF +*/ +uint32_t timer_runtime_repetition_value_read(uint32_t timer_periph) +{ + return (TIMER_CREP1(timer_periph)); +} + +/*! + \brief configure TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] autoreload: the counter auto-reload value, 0~0xFFFF, TIMERx(x=0,2,3,7,14~16,30,31,40~44) + 0~0xFFFFFFFF, TIMERx(x=1,4,5,6,22,23) + 0~0xFFFFFFFFFFFFFFFF, TIMERx(x=50,51) + \param[out] none + \retval none +*/ +void timer_autoreload_value_config(uint32_t timer_periph, uint64_t autoreload) +{ + /* configure TIMER50/TIMER51 autoreload register value (64-bit) */ + if((TIMER50 == timer_periph) || (TIMER51 == timer_periph)) { + TIMER_CARL(timer_periph) = (uint32_t)autoreload; + TIMER_CARH(timer_periph) = (uint32_t)(autoreload >> 32U); + } else { + /* configure other TIMER autoreload register value (32-bit or 16-bit) */ + TIMER_CAR(timer_periph) = (uint32_t)autoreload; + } +} + +/*! + \brief get TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval counter auto reload register value, 0~0xFFFF, TIMERx(x=0,2,3,7,14~16,30,31,40~44) + 0~0xFFFFFFFF, TIMERx(x=1,4,5,6,22,23) + 0~0xFFFFFFFFFFFFFFFF, TIMERx(x=50,51) +*/ +uint64_t timer_autoreload_value_read(uint32_t timer_periph) +{ + uint64_t autoreload = 0U; + /* read TIMER50/TIMER51 autoreload register value (64-bit) */ + if((TIMER50 == timer_periph) || (TIMER51 == timer_periph)) { + autoreload = (((uint64_t)TIMER_CARH(timer_periph)) << 32U); + autoreload |= TIMER_CARL(timer_periph); + } else { + /* read other TIMER autoreload register value (32-bit or 16-bit) */ + autoreload = TIMER_CAR(timer_periph); + } + return autoreload; +} + +/*! + \brief configure TIMER counter register value + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] counter: the counter value, 0~0xFFFF, TIMERx(x=0,2,3,7,14~16,30,31,40~44) + 0~0xFFFFFFFF, TIMERx(x=1,4,5,6,22,23) + 0~0xFFFFFFFFFFFFFFFF, TIMERx(x=50,51) + \param[out] none + \retval none +*/ +void timer_counter_value_config(uint32_t timer_periph, uint64_t counter) +{ + /* configure TIMER50/TIMER51 counter value (64-bit) */ + if((TIMER50 == timer_periph) || (TIMER51 == timer_periph)) { + TIMER_CNTL(timer_periph) = (uint32_t)counter; + TIMER_CNTH(timer_periph) = (uint32_t)(counter >> 32U); + if(TIMER_CTL0(timer_periph) & TIMER_CTL0_UPIFBUEN) { + TIMER_CNTH(timer_periph) &= (~TIMER_CNT_UPIFBU_MASK); + } + } else { + /* configure other TIMER counter value (32-bit or 16-bit) */ + if(TIMER_CTL0(timer_periph) & TIMER_CTL0_UPIFBUEN) { + counter &= (~TIMER_CNT_UPIFBU_MASK); + } + TIMER_CNT(timer_periph) = (uint32_t)counter; + } +} + +/*! + \brief read TIMER counter value + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval counter value: 0~0xFFFF, TIMERx(x=0,2,3,7,14~16,30,31,40~44) + 0~0xFFFFFFFF, TIMERx(x=1,4,5,6,22,23) + 0~0xFFFFFFFFFFFFFFFF, TIMERx(x=50,51) +*/ +uint64_t timer_counter_read(uint32_t timer_periph) +{ + uint64_t count_value = 0U; + + /* read TIMER50/TIMER51 counter value (64-bit) */ + if((TIMER50 == timer_periph) || (TIMER51 == timer_periph)) { + count_value = (uint64_t)TIMER_CNTH(timer_periph); + if((TIMER_CTL0(timer_periph) & TIMER_CTL0_UPIFBUEN)) { + count_value &= (uint64_t)(~TIMER_CNT_UPIFBU_MASK); + } + count_value <<= 32U; + count_value |= (uint64_t)TIMER_CNTL(timer_periph); + } else { + /* read other TIMER counter value (32-bit or 16-bit) */ + count_value = (uint64_t)TIMER_CNT(timer_periph); + if((TIMER_CTL0(timer_periph) & TIMER_CTL0_UPIFBUEN)) { + count_value &= (uint64_t)(~TIMER_CNT_UPIFBU_MASK); + } + } + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval prescaler register value, 0~0xFFFF +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t)(TIMER_PSC(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] spmode: single pulse mode + only one parameter can be selected which is shown as below: + \arg TIMER_SP_MODE_SINGLE: single pulse mode + \arg TIMER_SP_MODE_REPETITIVE: repetitive pulse mode + \param[out] none + \retval none +*/ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode) +{ + if(TIMER_SP_MODE_SINGLE == spmode) { + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM; + } else if(TIMER_SP_MODE_REPETITIVE == spmode) { + TIMER_CTL0(timer_periph) &= (~((uint32_t)TIMER_CTL0_SPM)); + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure timer delayable single pulse mode + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] dspmode: delayable SPM mode + only one parameter can be selected which is shown as below: + \arg TIMER_OC_MODE_DSPM0: delayable SPM mode 0 + \arg TIMER_OC_MODE_DSPM1: delayable SPM mode 1 + \param[in] cnt_dir: counter direction selection + only one parameter can be selected which is shown as below: + TIMER_COUNTER_UP: count up + TIMER_COUNTER_DOWN: count down + \param[out] none + \retval none +*/ +void timer_delayable_single_pulse_mode_config(uint32_t timer_periph, uint16_t channel, uint32_t dspmode, uint16_t cnt_dir) +{ + /* timer run in single mode*/ + timer_single_pulse_mode_config(timer_periph, TIMER_SP_MODE_SINGLE); + /* set the CHxCOMCTL/MCHxCOMCTL bits */ + timer_channel_output_mode_config(timer_periph, channel, dspmode); + /* set the Restart + event slave mode */ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_RESTART_EVENT); + /* set the counter direction in edge-aligned mode*/ + TIMER_CTL0(timer_periph) &= (~(uint32_t)(TIMER_CTL0_DIR | TIMER_CTL0_CAM)); + TIMER_CTL0(timer_periph) |= (uint32_t)(cnt_dir & COUNTERDIRECTION_MASK); + /* set the CHxCV/MCHxCV */ + if(TIMER_COUNTER_UP == cnt_dir) { + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = 0U; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = 0U; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = 0U; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = 0U; + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCH0CV(timer_periph) = 0U; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCH1CV(timer_periph) = 0U; + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCH2CV(timer_periph) = 0U; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCH3CV(timer_periph) = 0U; + break; + default: + break; + } + } else if(TIMER_COUNTER_DOWN == cnt_dir) { + /* read the CAR value */ + uint64_t value = timer_autoreload_value_read(timer_periph); + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCH0CV(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCH1CV(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCH2CV(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCH3CV(timer_periph) = (uint32_t)value; + break; + default: + break; + } + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] update: + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATE_SRC_GLOBAL: update generate by setting of UPG bit or the counter overflow/underflow, + or the slave mode controller trigger + \arg TIMER_UPDATE_SRC_REGULAR: update generate only by counter overflow/underflow + \param[out] none + \retval none +*/ +void timer_update_source_config(uint32_t timer_periph, uint32_t update) +{ + if(TIMER_UPDATE_SRC_REGULAR == update) { + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + } else if(TIMER_UPDATE_SRC_GLOBAL == update) { + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_UPS); + } else { + /* illegal parameters */ + } +} + +/*! + \brief enable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] dma: specify which DMA to enable + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA request, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMA_CMTD: channel commutation DMA request, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_DMA_MCH0D: multi mode channel 0 DMA request, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMA_MCH1D: multi mode channel 1 DMA request, TIMERx(x=0,7) + \arg TIMER_DMA_MCH2D: multi mode channel 2 DMA request, TIMERx(x=0,7) + \arg TIMER_DMA_MCH3D: multi mode channel 3 DMA request, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint32_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] dma: specify which DMA to enable + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA request, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMA_CMTD: channel commutation DMA request, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_DMA_MCH0D: multi mode channel 0 DMA request, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMA_MCH1D: multi mode channel 1 DMA request, TIMERx(x=0,7) + \arg TIMER_DMA_MCH2D: multi mode channel 2 DMA request, TIMERx(x=0,7) + \arg TIMER_DMA_MCH3D: multi mode channel 3 DMA request, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint32_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] dma_request: channel DMA request source selection + only one parameter can be selected which is shown as below: + \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel n is sent when channel n event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel n is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + } else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request) { + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_DMAS); + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure the TIMER DMA transfer + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] dma_baseaddr: DMA access base address + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_CREP0: DMA transfer address is TIMER_CREP0, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMACFG_DMATA_MCHCTL0: DMA transfer address is TIMER_MCHCTL0, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMACFG_DMATA_MCHCTL1: DMA transfer address is TIMER_MCHCTL1, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_MCHCTL2: DMA transfer address is TIMER_MCHCTL2, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMACFG_DMATA_MCH0CV: DMA transfer address is TIMER_MCH0CV, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMACFG_DMATA_MCH1CV: DMA transfer address is TIMER_MCH1CV, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_MCH2CV: DMA transfer address is TIMER_MCH2CV, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_MCH3CV: DMA transfer address is TIMER_MCH3CV, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_CH0COMV_ADD: DMA transfer address is TIMER_CH0COMV_ADD, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CH1COMV_ADD: DMA transfer address is TIMER_CH1COMV_ADD, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CH2COMV_ADD: DMA transfer address is TIMER_CH2COMV_ADD, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CH3COMV_ADD: DMA transfer address is TIMER_CH3COMV_ADD, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CTL2: DMA transfer address is TIMER_CTL2, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_DMACFG_DMATA_FCCHP0: DMA transfer address is TIMER_FCCHP0, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_FCCHP1: DMA transfer address is TIMER_FCCHP1, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_FCCHP2: DMA transfer address is TIMER_FCCHP2, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_FCCHP3: DMA transfer address is TIMER_FCCHP3, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_AFCTL0: DMA transfer address is TIMER_AFCTL0, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_DMACFG_DMATA_AFCTL1: DMA transfer address is TIMER_AFCTL1, TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_WDGPER: DMA transfer address is TIMER_WDGPER, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_DMACFG_DMATA_CREP1: DMA transfer address is TIMER_CREP1, TIMERx(x=0,7,14~16,40~44) + \param[in] dma_lenth: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1~38): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] event: the timer software event generation sources + one or more parameters can be selected which are shown as below: + \arg TIMER_EVENT_SRC_UPG: update event generation, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_EVENT_SRC_BRK0G: BREAK0 event generation, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_EVENT_SRC_BRK1G: BREAK1 event generation, TIMERx(x=0,7) + \arg TIMER_EVENT_SRC_MCH0G: multi mode channel 0 capture or compare event generation, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_EVENT_SRC_MCH1G: multi mode channel 1 capture or compare event generation, TIMERx(x=0,7) + \arg TIMER_EVENT_SRC_MCH2G: multi mode channel 2 capture or compare event generation, TIMERx(x=0,7) + \arg TIMER_EVENT_SRC_MCH3G: multi mode channel 3 capture or compare event generation, TIMERx(x=0,7) + \arg TIMER_EVENT_SRC_CH0COMADDG: channel 0 additional compare event generation, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_EVENT_SRC_CH1COMADDG: channel 1 additional compare event generation, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_EVENT_SRC_CH2COMADDG: channel 2 additional compare event generation, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_EVENT_SRC_CH3COMADDG: channel 3 additional compare event generation, TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint32_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief initialize TIMER break parameter struct with a default value + \param[in] breakpara: TIMER break parameter struct + \param[out] none + \retval none +*/ +void timer_break_struct_para_init(timer_break_parameter_struct *breakpara) +{ + /* initialize the break parameter struct member with the default value */ + breakpara->runoffstate = TIMER_ROS_STATE_DISABLE; + breakpara->ideloffstate = TIMER_IOS_STATE_DISABLE; + breakpara->deadtime = 0U; + breakpara->outputautostate = TIMER_OUTAUTO_DISABLE; + breakpara->protectmode = TIMER_CCHP_PROT_OFF; + breakpara->break0state = TIMER_BREAK0_DISABLE; + breakpara->break0filter = 0U; + breakpara->break0polarity = TIMER_BREAK0_POLARITY_LOW; + breakpara->break0lock = TIMER_BREAK0_LK_DISABLE; + breakpara->break0release = TIMER_BREAK0_UNRELEASE; + breakpara->break1state = TIMER_BREAK1_DISABLE; + breakpara->break1filter = 0U; + breakpara->break1polarity = TIMER_BREAK1_POLARITY_LOW; + breakpara->break1lock = TIMER_BREAK1_LK_DISABLE; + breakpara->break1release = TIMER_BREAK1_UNRELEASE; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE, TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE, TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + outputautostate: TIMER_OUTAUTO_ENABLE, TIMER_OUTAUTO_DISABLE + protectmode: TIMER_CCHP_PROT_OFF, TIMER_CCHP_PROT_0, TIMER_CCHP_PROT_1, TIMER_CCHP_PROT_2 + break0state: TIMER_BREAK0_ENABLE, TIMER_BREAK0_DISABLE + break0filter: 0~15 + break0polarity: TIMER_BREAK0_POLARITY_LOW, TIMER_BREAK0_POLARITY_HIGH + break0lock: TIMER_BREAK0_LK_ENABLE, TIMER_BREAK0_LK_DISABLE + break0release: TIMER_BREAK0_RELEASE, TIMER_BREAK0_UNRELEASE + break1state: TIMER_BREAK1_ENABLE, TIMER_BREAK1_DISABLE + break1filter: 0~15 + break1polarity: TIMER_BREAK1_POLARITY_LOW, TIMER_BREAK1_POLARITY_HIGH + break1lock: TIMER_BREAK1_LK_ENABLE, TIMER_BREAK1_LK_DISABLE + break1release: TIMER_BREAK1_RELEASE, TIMER_BREAK1_UNRELEASE + \param[out] none + \retval none +*/ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara) +{ + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | + ((uint32_t)(breakpara->ideloffstate)) | + ((uint32_t)(breakpara->deadtime)) | + ((uint32_t)(breakpara->outputautostate)) | + ((uint32_t)(breakpara->protectmode)) | + ((uint32_t)(breakpara->break0state)) | + ((uint32_t)(breakpara->break0filter)) | + ((uint32_t)(breakpara->break0polarity)) | + ((uint32_t)(breakpara->break0lock)) | + ((uint32_t)(breakpara->break0release)) | + ((uint32_t)(breakpara->break1state)) | + ((uint32_t)(breakpara->break1filter)) | + ((uint32_t)(breakpara->break1polarity)) | + ((uint32_t)(breakpara->break1lock)) | + ((uint32_t)(breakpara->break1release))); + } else if((TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph) || (TIMER40 == timer_periph) || \ + (TIMER41 == timer_periph) || (TIMER42 == timer_periph) || (TIMER43 == timer_periph) || (TIMER44 == timer_periph)) { + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | + ((uint32_t)(breakpara->ideloffstate)) | + ((uint32_t)(breakpara->deadtime)) | + ((uint32_t)(breakpara->outputautostate)) | + ((uint32_t)(breakpara->protectmode)) | + ((uint32_t)(breakpara->break0state)) | + ((uint32_t)(breakpara->break0filter)) | + ((uint32_t)(breakpara->break0polarity)) | + ((uint32_t)(breakpara->break0lock)) | + ((uint32_t)(breakpara->break0release))); + } else { + /* illegal parameters */ + } +} + +/*! + \brief enable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signals, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BREAK1: BREAK1 input signals, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph, uint16_t break_num) +{ + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK0EN; + } else if(TIMER_BREAK1 == break_num) { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK1EN; + } else { + } +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signals, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BREAK1: BREAK1 input signals, TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph, uint16_t break_num) +{ + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_BRK0EN); + } else if(TIMER_BREAK1 == break_num) { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_BRK1EN); + } else { + } +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_OAEN); +} + +/*! + \brief configure TIMER primary output function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; + } else { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN); + } +} + +/*! + \brief configure channel commutation control shadow register + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE; + } else { + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE); + } +} + +/*! + \brief configure TIMER channel control shadow register update control + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] ccuctl: channel control shadow register update control + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set + \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs + \arg TIMER_UPDATECTL_CCUOVER: the shadow registers update by when the overflow event occurs + \arg TIMER_UPDATECTL_CCUUNDER: the shadow registers update by when the underflow event occurs + \arg TIMER_UPDATECTL_CCUOVERUNDER: the shadow registers update by when the overflow or underflow event occurs + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint32_t ccuctl) +{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + TIMER_CTL1(timer_periph) |= (uint32_t)ccuctl; +} + +/*! + \brief initialize TIMER channel output parameter struct with a default value + \param[in] ocpara: TIMER channel n output parameter struct + \param[out] none + \retval none +*/ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara) +{ + /* initialize the channel output parameter struct member with the default value */ + ocpara->outputstate = TIMER_CCX_DISABLE; + ocpara->outputnstate = TIMER_CCXN_DISABLE; + ocpara->ocpolarity = TIMER_OC_POLARITY_HIGH; + ocpara->ocnpolarity = TIMER_OCN_POLARITY_HIGH; + ocpara->ocidlestate = TIMER_OC_IDLE_STATE_LOW; + ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[in] ocpara: TIMER channel output parameter struct + outputstate: TIMER_CCX_ENABLE, TIMER_CCX_DISABLE + outputnstate: TIMER_CCXN_ENABLE, TIMER_CCXN_DISABLE + ocpolarity: TIMER_OC_POLARITY_HIGH, TIMER_OC_POLARITY_LOW + ocnpolarity: TIMER_OCN_POLARITY_HIGH, TIMER_OCN_POLARITY_LOW + ocidlestate: TIMER_OC_IDLE_STATE_LOW, TIMER_OC_IDLE_STATE_HIGH + ocnidlestate: TIMER_OCN_IDLE_STATE_LOW, TIMER_OCN_IDLE_STATE_HIGH + \param[out] none + \retval none +*/ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct *ocpara) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputstate; + /* reset the CH0P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + /* set the CH0P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocpolarity; + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || \ + (TIMER16 == timer_periph) || (TIMER40 == timer_periph) || (TIMER41 == timer_periph) || (TIMER42 == timer_periph) || \ + (TIMER43 == timer_periph) || (TIMER44 == timer_periph)) { + + /* reset the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + /* set the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + + /* reset the MCH0P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0P); + /* set the MCH0P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity; + + /* reset the ISO0 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0); + /* set the ISO0 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate; + + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate; + } + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->outputstate) << 4U); + /* reset the CH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + /* set the CH1P bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->ocpolarity) << 4U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + /* reset the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + /* set the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->outputnstate) << 4U); + /* reset the MCH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1P); + /* set the MCH1P bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->ocnpolarity) << 4U); + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= ((uint32_t)(ocpara->ocidlestate) << 2U); + /* reset the ISO1N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N); + /* set the ISO1N bit */ + TIMER_CTL1(timer_periph) |= ((uint32_t)(ocpara->ocnidlestate) << 2U); + } + + if((TIMER14 == timer_periph) || (TIMER40 == timer_periph) || (TIMER41 == timer_periph) || (TIMER42 == timer_periph) || \ + (TIMER43 == timer_periph) || (TIMER44 == timer_periph)) { + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= ((uint32_t)(ocpara->ocidlestate) << 2U); + } + + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->outputstate) << 8U); + /* reset the CH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + /* set the CH2P bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->ocpolarity) << 8U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + /* reset the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + /* set the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->outputnstate) << 8U); + /* reset the MCH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2P); + /* set the MCH2P bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->ocnpolarity) << 8U); + /* reset the ISO2 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2); + /* set the ISO2 bit */ + TIMER_CTL1(timer_periph) |= ((uint32_t)(ocpara->ocidlestate) << 4U); + /* reset the ISO2N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N); + /* set the ISO2N bit */ + TIMER_CTL1(timer_periph) |= ((uint32_t)(ocpara->ocnidlestate) << 4U); + } + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->outputstate) << 12U); + /* reset the CH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + /* set the CH3P bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->ocpolarity) << 12U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + /* reset the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + /* set the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->outputnstate) << 12U); + /* reset the MCH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3P); + /* set the MCH3P bit */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(ocpara->ocnpolarity) << 12U); + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= ((uint32_t)(ocpara->ocidlestate) << 6U); + /* reset the ISO3N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3N); + /* set the ISO3N bit */ + TIMER_CTL1(timer_periph) |= ((uint32_t)(ocpara->ocnidlestate) << 6U); + } + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] ocmode: channel output compare mode + only one parameter can be selected which is shown as below: + \arg TIMER_OC_MODE_TIMING: timing mode + \arg TIMER_OC_MODE_ACTIVE: active mode + \arg TIMER_OC_MODE_INACTIVE: inactive mode + \arg TIMER_OC_MODE_TOGGLE: toggle mode + \arg TIMER_OC_MODE_LOW: force low mode + \arg TIMER_OC_MODE_HIGH: force high mode + \arg TIMER_OC_MODE_PWM0: PWM mode 0 + \arg TIMER_OC_MODE_PWM1: PWM mode 1 + \arg TIMER_OC_MODE_DSPM0: delayable SPM mode 0 + \arg TIMER_OC_MODE_DSPM1: delayable SPM mode 1 + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint32_t ocmode) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= ((ocmode) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) |= ocmode; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); + TIMER_CHCTL1(timer_periph) |= ((ocmode) << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0COMCTL); + TIMER_MCHCTL0(timer_periph) |= ocmode; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1COMCTL); + TIMER_MCHCTL0(timer_periph) |= ((ocmode) << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2COMCTL); + TIMER_MCHCTL1(timer_periph) |= ocmode; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3COMCTL); + TIMER_MCHCTL1(timer_periph) |= ((ocmode) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] pulse: channel output pulse value + \param[out] none + \retval none +*/ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCH3CV(timer_periph) = (uint32_t)pulse; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] ocshadow: channel output compare shadow + only one parameter can be selected which is shown as below: + \arg TIMER_OC_SHADOW_ENABLE: channel output compare shadow enable + \arg TIMER_OC_SHADOW_DISABLE: channel output compare shadow disable + \arg TIMER_OMC_SHADOW_ENABLE: multi mode channel output compare shadow enable + \arg TIMER_OMC_SHADOW_DISABLE: multi mode channel output compare shadow disable + \param[out] none + \retval none +*/ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0COMSEN); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1COMSEN); + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2COMSEN); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3COMSEN); + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)(ocshadow) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] occlear: channel output clear function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_CLEAR_ENABLE: channel output clear function enable + \arg TIMER_OC_CLEAR_DISABLE: channel output clear function disable + \arg TIMER_OMC_CLEAR_ENABLE: multi mode channel output clear function enable + \arg TIMER_OMC_CLEAR_DISABLE: multi mode channel output clear function disable + \param[out] none + \retval none +*/ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)occlear << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)occlear << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0COMCEN); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1COMCEN); + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)occlear << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2COMCEN); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3COMCEN); + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)occlear << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] ocpolarity: channel output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high + \arg TIMER_OC_POLARITY_LOW: channel output polarity is low + \arg TIMER_OMC_POLARITY_HIGH: multi mode channel output polarity is high + \arg TIMER_OMC_POLARITY_LOW: multi mode channel output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocpolarity << 12U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH0FP); + TIMER_MCHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH1FP); + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)ocpolarity << 2U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH2FP); + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4U); + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH3FP); + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)ocpolarity << 6U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[in] ocnpolarity: channel complementary output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high + \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1P); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocnpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2P); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocnpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3P); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocnpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] state: TIMER channel enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable + \arg TIMER_MCCX_ENABLE: multi mode channel enable + \arg TIMER_MCCX_DISABLE: multi mode channel disable + \param[out] none + \retval none +*/ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)state; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)state << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)state << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)state << 12U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state); + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(state << 4U)); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(state << 8U)); + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(state << 12U)); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,7,14,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,7)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,7)) + \param[in] ocnstate: TIMER channel complementary output enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocnstate << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocnstate << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ocnstate << 12U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER channel input parameter struct with a default value + \param[in] icpara: TIMER channel input parameter struct + \param[out] none + \retval none +*/ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct *icpara) +{ + /* initialize the channel input parameter struct member with the default value */ + icpara->icpolarity = TIMER_IC_POLARITY_RISING; + icpara->icselection = TIMER_IC_SELECTION_DIRECTTI; + icpara->icprescaler = TIMER_IC_PSC_DIV1; + icpara->icfilter = 0U; +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] icpara: TIMER channel input parameter struct + icpolarity: TIMER_IC_POLARITY_RISING, TIMER_IC_POLARITY_FALLING, TIMER_IC_POLARITY_BOTH_EDGE + icselection: TIMER_IC_SELECTION_DIRECTTI, TIMER_IC_SELECTION_INDIRECTTI, TIMER_IC_SELECTION_ITS, TIMER_IC_SELECTION_PAIR + icprescaler: TIMER_IC_PSC_DIV1, TIMER_IC_PSC_DIV2, TIMER_IC_PSC_DIV4, TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpara) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL0(timer_periph) |= (uint32_t)icpara->icselection << 28U; + } else { + TIMER_CHCTL0(timer_periph) |= ((uint32_t)icpara->icselection); + } + + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(icpara->icpolarity) << 4U); + + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL0(timer_periph) |= ((uint32_t)icpara->icselection) << 29U; + } else { + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection) << 8U; + } + + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and MCH2P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P | TIMER_CHCTL2_MCH2P)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(icpara->icpolarity) << 8U); + + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL1(timer_periph) |= ((uint32_t)icpara->icselection << 28U); + } else { + TIMER_CHCTL1(timer_periph) |= ((uint32_t)(icpara->icselection)); + } + + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + + /* reset the CH3P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P | TIMER_CHCTL2_MCH3P)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(icpara->icpolarity) << 12U); + + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL1(timer_periph) |= ((uint32_t)icpara->icselection << 29U); + } else { + TIMER_CHCTL1(timer_periph) |= ((uint32_t)(icpara->icselection) << 8U); + } + + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + /* reset the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + + /* reset the MCH0FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH0FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= TIMER_IMC_POLARITY_RISING; + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= TIMER_IMC_POLARITY_FALLING; + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= TIMER_IMC_POLARITY_BOTH_EDGE; + break; + default: + break; + } + + /* reset the MCH0MS bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)icpara->icselection << 28U); + } else { + TIMER_MCHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + } + + /* reset the MCH0CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0CAPFLT); + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)(icpara->icfilter) << 4U); + + /* set the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH0EN; + break; + + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + /* reset the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + + /* reset the MCH1FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH1FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_RISING << 2U; + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_FALLING << 2U; + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 2U; + break; + default: + break; + } + + /* reset the MCH1MS bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)icpara->icselection << 29U); + } else { + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)(icpara->icselection) << 8U); + } + + /* reset the MCH1CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1CAPFLT); + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)(icpara->icfilter) << 12U); + + /* set the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH1EN; + break; + + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + /* reset the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + + /* reset the MCH2FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH2FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_RISING << 4U; + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_FALLING << 4U; + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 4U; + break; + default: + break; + } + + /* reset the MCH2MS bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)icpara->icselection << 28U); + } else { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)(icpara->icselection)); + } + + /* reset the MCH2CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2CAPFLT); + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)(icpara->icfilter) << 4U); + + /* set the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH2EN; + break; + + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + /* reset the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + + /* reset the MCH3FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH3FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_RISING << 6U; + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_FALLING << 6U; + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 6U; + break; + default: + break; + } + + /* reset the MCH3MS bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)icpara->icselection << 29U); + } else { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)(icpara->icselection) << 8U); + } + + /* reset the MCH3CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3CAPFLT); + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)(icpara->icfilter) << 12U); + + /* set the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH3EN; + break; + default: + break; + } + + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, channel, (uint16_t)(icpara->icprescaler)); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] prescaler: channel input capture prescaler value + only one parameter can be selected which is shown as below: + \arg TIMER_IC_PSC_DIV1: no prescaler + \arg TIMER_IC_PSC_DIV2: divided by 2 + \arg TIMER_IC_PSC_DIV4: divided by 4 + \arg TIMER_IC_PSC_DIV8: divided by 8 + \param[out] none + \retval none +*/ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL0(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC); + TIMER_CHCTL1(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0CAPPSC); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1CAPPSC); + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2CAPPSC); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3CAPPSC); + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[out] none + \retval channel capture compare register value, 0~0xFFFFFFFF +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value = 0U; + + switch(channel) { + case TIMER_CH_0: + /* read TIMER_CH_0 capture compare register value */ + count_value = TIMER_CH0CV(timer_periph); + break; + case TIMER_CH_1: + /* read TIMER_CH_1 capture compare register value */ + count_value = TIMER_CH1CV(timer_periph); + break; + case TIMER_CH_2: + /* read TIMER_CH_2 capture compare register value */ + count_value = TIMER_CH2CV(timer_periph); + break; + case TIMER_CH_3: + /* read TIMER_CH_3 capture compare register value */ + count_value = TIMER_CH3CV(timer_periph); + break; + case TIMER_MCH_0: + /* read TIMER_MCH_0 capture compare register value */ + count_value = TIMER_MCH0CV(timer_periph); + break; + case TIMER_MCH_1: + /* read TIMER_MCH_1 capture compare register value */ + count_value = TIMER_MCH1CV(timer_periph); + break; + case TIMER_MCH_2: + /* read TIMER_MCH_2 capture compare register value */ + count_value = TIMER_MCH2CV(timer_periph); + break; + case TIMER_MCH_3: + /* read TIMER_MCH_3 capture compare register value */ + count_value = TIMER_MCH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \param[in] icpwm: TIMER channel input pwm parameter struct + icpolarity: TIMER_IC_POLARITY_RISING, TIMER_IC_POLARITY_FALLING + icselection: TIMER_IC_SELECTION_DIRECTTI, TIMER_IC_SELECTION_INDIRECTTI + icprescaler: TIMER_IC_PSC_DIV1, TIMER_IC_PSC_DIV2, TIMER_IC_PSC_DIV4, TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpwm) +{ + uint16_t icpolarity = 0U; + uint16_t icselection = 0U; + + /* set channel input polarity */ + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity) { + icpolarity = TIMER_IC_POLARITY_FALLING; + } else { + icpolarity = TIMER_IC_POLARITY_RISING; + } + /* set channel input mode selection */ + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection) { + icselection = TIMER_IC_SELECTION_INDIRECTTI; + } else { + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == channel) { + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + /* set the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + /* set the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)icpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)icselection << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + } else { + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + /* set the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)(icpwm->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + /* set the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] hallmode: + only one parameter can be selected which is shown as below: + \arg TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable + \arg TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable + \param[out] none + \retval none +*/ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode) +{ + if(TIMER_HALLINTERFACE_ENABLE == hallmode) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S; + } else if(TIMER_HALLINTERFACE_DISABLE == hallmode) { + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_TI0S); + } else { + /* illegal parameters */ + } +} + +/*! + \brief initialize TIMER multi mode channel output parameter struct + \param[in] omcpara: TIMER multi mode channel output parameter struct + \param[out] none + \retval none +*/ +void timer_multi_mode_channel_output_parameter_struct_init(timer_omc_parameter_struct *omcpara) +{ + /* initialize the multi mode channel output parameter struct with the default value */ + omcpara->outputmode = TIMER_MCH_MODE_COMPLEMENTARY; + omcpara->outputstate = TIMER_MCCX_DISABLE; + omcpara->ocpolarity = TIMER_OMC_POLARITY_LOW; +} + +/*! + \brief configure TIMER multi mode channel output function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] omcpara: TIMER multi mode channel output parameter struct + outputmode: TIMER_MCH_MODE_INDEPENDENTLY, TIMER_MCH_MODE_COMPLEMENTARY + outputstate: TIMER_MCCX_ENABLE, TIMER_MCCX_DISABLE + ocpolarity: TIMER_OMC_POLARITY_HIGH, TIMER_OMC_POLARITY_LOW + \param[out] none + \retval none +*/ +void timer_multi_mode_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_omc_parameter_struct *omcpara) +{ + switch(channel) { + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 20U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 20U); + /* reset the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + /* set the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(omcpara->outputstate); + /* reset the MCH0FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH0FP); + /* set the MCH0FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)omcpara->ocpolarity; + + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0MS); + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 22U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 22U); + /* reset the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + /* set the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputstate) << 4U); + /* reset the MCH1FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH1FP); + /* set the MCH1FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->ocpolarity) << 2U); + + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1MS); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 24U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 24U); + /* reset the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + /* set the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputstate) << 8U); + /* reset the MCH2FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH2FP); + /* set the MCH2FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->ocpolarity) << 4U); + + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2MS); + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 26U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 26U); + /* reset the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + /* set the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputstate) << 12U); + /* reset the MCH3FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH3FP); + /* set the MCH3FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->ocpolarity) << 6U); + + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3MS); + break; + default: + break; + } +} + +/*! + \brief multi mode channel mode select + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,14~16,40~44)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7)) + \param[in] multi_mode_sel: multi mode channel mode selection + only one parameter can be selected which is shown as below: + \arg TIMER_MCH_MODE_INDEPENDENTLY: multi mode channel work in independently mode + \arg TIMER_MCH_MODE_COMPLEMENTARY: multi mode channel work in complementary output mode + \param[out] none + \retval none +*/ +void timer_multi_mode_channel_mode_config(uint32_t timer_periph, uint32_t channel, uint32_t multi_mode_sel) +{ + uint32_t reg; + reg = TIMER_CTL2(timer_periph); + + reg &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << (((channel & 0xFU) << 1U) + 20U))); + reg |= (uint32_t)(multi_mode_sel << (((channel & 0xFU) << 1U) + 20U)); + + TIMER_CTL2(timer_periph) = reg; +} + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] intrigger: input trigger source + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered channel 0 input(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered channel 1 input(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_ETIFP: filtered external trigger input(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_SMCFG_TRGSEL_CI2FE2: filtered channel 2 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_CI3FE3: filtered channel 3 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_MCI0FEM0: filtered multi mode channel 0 input(TIMERx(x=0,7,14,40~44)) + \arg TIMER_SMCFG_TRGSEL_MCI1FEM1: filtered multi mode channel 1 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_MCI2FEM2: filtered multi mode channel 2 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_MCI3FEM3: filtered multi mode channel 3 input(TIMERx(x=0,7)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI4: internal trigger 4 for General-L0 timer(TIMERx(x=1,2,22,23,30,31)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI5: internal trigger 5 for General-L0 timer(TIMERx(x=1,22,23,30)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI7: internal trigger 7 for General-L0 timer(TIMERx(x=4)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI9: internal trigger 9 for General-L0 timer(TIMERx(x=22,23)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI10: internal trigger 10 for General-L0 timer(TIMERx(x=22,23)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI11: internal trigger 11 for General-L0 timer(TIMERx(x=22,23)) + \arg TIMER_SMCFG_TRGSEL_ITI12: internal trigger 12(TIMERx(x=0~4,7,23,30,31)) + \arg TIMER_SMCFG_TRGSEL_ITI13: internal trigger 13(TIMERx(x=0~4,7,22,30,31)) + \arg TIMER_SMCFG_TRGSEL_ITI14: internal trigger 14(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger) +{ + uint8_t TIMERx_temp = 0U; + uint32_t TIMERxCFG_temp = 0U; + volatile uint32_t *TIMERxCFG_addr; + uint8_t i = 0U; + uint32_t TIMERxCFG0_value, TIMERxCFG1_value, TIMERxCFG2_value; + + switch(timer_periph){ + case TIMER0: + TIMERx_temp = SYSCFG_TIMER0; + break; + case TIMER1: + TIMERx_temp = SYSCFG_TIMER1; + break; + case TIMER2: + TIMERx_temp = SYSCFG_TIMER2; + break; + case TIMER3: + TIMERx_temp = SYSCFG_TIMER3; + break; + case TIMER4: + TIMERx_temp = SYSCFG_TIMER4; + break; + case TIMER7: + TIMERx_temp = SYSCFG_TIMER7; + break; + case TIMER14: + TIMERx_temp = SYSCFG_TIMER14; + break; + case TIMER22: + TIMERx_temp = SYSCFG_TIMER22; + break; + case TIMER23: + TIMERx_temp = SYSCFG_TIMER23; + break; + case TIMER30: + TIMERx_temp = SYSCFG_TIMER30; + break; + case TIMER31: + TIMERx_temp = SYSCFG_TIMER31; + break; + case TIMER40: + TIMERx_temp = SYSCFG_TIMER40; + break; + case TIMER41: + TIMERx_temp = SYSCFG_TIMER41; + break; + case TIMER42: + TIMERx_temp = SYSCFG_TIMER42; + break; + case TIMER43: + TIMERx_temp = SYSCFG_TIMER43; + break; + case TIMER44: + TIMERx_temp = SYSCFG_TIMER44; + break; + default: + break; + } + + /* read SYSCFG_TIMERCFG0 register value */ + TIMERxCFG0_value = SYSCFG_TIMERCFG0(TIMERx_temp) & 0x7FFF7FFFU; + /* read SYSCFG_TIMERCFG1 register value */ + TIMERxCFG1_value = SYSCFG_TIMERCFG1(TIMERx_temp) & 0x001F7FFFU; + /* read SYSCFG_TIMERCFG2 register value */ + TIMERxCFG2_value = SYSCFG_TIMERCFG2(TIMERx_temp) & 0x001F0000U; + + if((0U == TIMERxCFG0_value)&&(0U == TIMERxCFG1_value)&&(0U == TIMERxCFG2_value)){ + TIMERxCFG_temp = (BITS(16, 20) & ((uint32_t)(intrigger) << 16U)); + TIMERxCFG_addr = &SYSCFG_TIMERCFG2(TIMERx_temp); + }else{ + if((SYSCFG_TIMERCFG0(TIMERx_temp) & 0x7FFF7FFFU) != 0U){ + for(i = 0U; i < 3U; i++){ + if((SYSCFG_TIMERCFG0(TIMERx_temp) & (BITS(0,4) << (i * 5U))) != 0U){ + TIMERxCFG_temp = ((BITS(0, 4)<< (i * 5U)) & ((uint32_t)(intrigger) << (i * 5U))); + break; + } + } + for(i = 3U; i < 6U; i++){ + if((SYSCFG_TIMERCFG0(TIMERx_temp) & (BITS(0,4) << ((i * 5U)+1U))) != 0U){ + TIMERxCFG_temp = ((BITS(0, 4)<< ((i * 5U)+1U)) & ((uint32_t)(intrigger) << ((i * 5U)+1U))); + break; + } + } + TIMERxCFG_addr = &SYSCFG_TIMERCFG0(TIMERx_temp); + }else if((SYSCFG_TIMERCFG1(TIMERx_temp) & 0x001F7FFFU) != 0U){ + for(i = 6U; i < 10U; i++){ + if(i < 9U){ + if((SYSCFG_TIMERCFG1(TIMERx_temp) & (BITS(0,4) << ((i-6U)*5U))) != 0U){ + TIMERxCFG_temp = ((BITS(0, 4)<< ((i-6U)*5U)) & ((uint32_t)(intrigger) << ((i-6U)*5U))); + break; + } + }else{ + if((SYSCFG_TIMERCFG1(TIMERx_temp) & (BITS(0,4) << ((i-6U)*5U+1U))) != 0U){ + TIMERxCFG_temp = ((BITS(0, 4)<< ((i-6U)*5U+1U)) & ((uint32_t)(intrigger) << ((i-6U)*5U+1U))); + } + } + } + TIMERxCFG_addr = &SYSCFG_TIMERCFG1(TIMERx_temp); + }else{ + TIMERxCFG_temp = (BITS(16, 20) & ((uint32_t)(intrigger) << 16U)); + TIMERxCFG_addr = &SYSCFG_TIMERCFG2(TIMERx_temp); + } + } + REG32(TIMERxCFG_addr) = TIMERxCFG_temp; +} + +/*! + \brief select TIMER master mode output 0 trigger source + \param[in] timer_periph: TIMERx(x=0~7,14,22,23,30,31,50,51) + \param[in] outrigger: trigger output 0 source + only one parameter can be selected which is shown as below: + \arg TIMER_TRI_OUT0_SRC_RESET: the UPG bit as trigger output 0(TIMERx(x=0~7,14,22,23,30,31,50,51)) + \arg TIMER_TRI_OUT0_SRC_ENABLE: the counter enable signal as trigger output 0(TIMERx(x=0~7,14,22,23,30,31,50,51)) + \arg TIMER_TRI_OUT0_SRC_UPDATE: update event as trigger output 0(TIMERx(x=0~7,14,22,23,30,31,50,51)) + \arg TIMER_TRI_OUT0_SRC_CH0: a capture or a compare match occurred in channel 0 as trigger output 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_TRI_OUT0_SRC_O0CPRE: O0CPRE as trigger output 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_TRI_OUT0_SRC_O1CPRE: O1CPRE as trigger output 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_TRI_OUT0_SRC_O2CPRE: O2CPRE as trigger output 0(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_TRI_OUT0_SRC_O3CPRE: O3CPRE as trigger output 0(TIMERx(x=0~4,7,22,23,30,31)) + \param[out] none + \retval none +*/ +void timer_master_output0_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + uint32_t reg; + + reg = TIMER_CTL1(timer_periph); + reg &= (~(uint32_t)TIMER_CTL1_MMC0); + reg |= (uint32_t)outrigger; + TIMER_CTL1(timer_periph) = reg; +} + +/*! + \brief select TIMER master mode output 1 trigger source + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] outrigger: trigger output 1 source + only one parameter can be selected which is shown as below: + \arg TIMER_TRI_OUT1_SRC_RESET: the UPG bit as trigger output 1 + \arg TIMER_TRI_OUT1_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output 1 + \arg TIMER_TRI_OUT1_SRC_UPDATE: update event as trigger output 1 + \arg TIMER_TRI_OUT1_SRC_CH0: a capture or a compare match occurred in channel 0 as trigger output 1 + \arg TIMER_TRI_OUT1_SRC_O0CPRE: O0CPRE as trigger output 1 + \arg TIMER_TRI_OUT1_SRC_O1CPRE: O1CPRE as trigger output 1 + \arg TIMER_TRI_OUT1_SRC_O2CPRE: O2CPRE as trigger output 1 + \arg TIMER_TRI_OUT1_SRC_O3CPRE: O3CPRE as trigger output 1 + \param[out] none + \retval none +*/ +void timer_master_output1_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + uint32_t reg; + + reg = TIMER_CTL1(timer_periph); + reg &= (~(uint32_t)TIMER_CTL1_MMC1); + reg |= (uint32_t)outrigger; + TIMER_CTL1(timer_periph) = reg; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] slavemode: slave mode + only one parameter can be selected which is shown as below: + \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_QUAD_DECODER_MODE0: quadrature decoder mode 0(x=0~4,7,22,23,30,31) + \arg TIMER_QUAD_DECODER_MODE1: quadrature decoder mode 1(x=0~4,7,22,23,30,31)(x=0~4,7,22,23,30,31) + \arg TIMER_QUAD_DECODER_MODE2: quadrature decoder 2(x=0~4,7,22,23,30,31) + \arg TIMER_SLAVE_MODE_RESTART: restart mode(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_SLAVE_MODE_PAUSE: pause mode(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_SLAVE_MODE_EVENT: event mode(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_SLAVE_MODE_RESTART_EVENT: restart + event mode(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_NONQUAD_MODE0: non-quadrature decoder mode 0(x=0~4,7,22,23,30,31) + \arg TIMER_NONQUAD_MODE1: non-quadrature decoder mode 1(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) +{ + uint8_t TIMERx_temp = 0U; + uint32_t TIMERxCFG_temp = 0U; + volatile uint32_t *TIMERxCFG_addr; + uint32_t trigger_temp = 0U; + uint8_t i = 0U; + uint32_t TIMERxCFG0_value, TIMERxCFG1_value, TIMERxCFG2_value; + + switch(timer_periph){ + case TIMER0: + TIMERx_temp = SYSCFG_TIMER0; + break; + case TIMER1: + TIMERx_temp = SYSCFG_TIMER1; + break; + case TIMER2: + TIMERx_temp = SYSCFG_TIMER2; + break; + case TIMER3: + TIMERx_temp = SYSCFG_TIMER3; + break; + case TIMER4: + TIMERx_temp = SYSCFG_TIMER4; + break; + case TIMER7: + TIMERx_temp = SYSCFG_TIMER7; + break; + case TIMER14: + TIMERx_temp = SYSCFG_TIMER14; + break; + case TIMER22: + TIMERx_temp = SYSCFG_TIMER22; + break; + case TIMER23: + TIMERx_temp = SYSCFG_TIMER23; + break; + case TIMER30: + TIMERx_temp = SYSCFG_TIMER30; + break; + case TIMER31: + TIMERx_temp = SYSCFG_TIMER31; + break; + case TIMER40: + TIMERx_temp = SYSCFG_TIMER40; + break; + case TIMER41: + TIMERx_temp = SYSCFG_TIMER41; + break; + case TIMER42: + TIMERx_temp = SYSCFG_TIMER42; + break; + case TIMER43: + TIMERx_temp = SYSCFG_TIMER43; + break; + case TIMER44: + TIMERx_temp = SYSCFG_TIMER44; + break; + default: + break; + } + + if(slavemode <= 5U){ + TIMERxCFG_addr = &SYSCFG_TIMERCFG0(TIMERx_temp); + }else if((slavemode >= 6U)&&(slavemode <= 9U)){ + TIMERxCFG_addr = &SYSCFG_TIMERCFG1(TIMERx_temp); + }else{ + TIMERxCFG_addr = &SYSCFG_TIMERCFG2(TIMERx_temp); + } + + /* read SYSCFG_TIMERCFG0 register value */ + TIMERxCFG0_value = SYSCFG_TIMERCFG0(TIMERx_temp) & 0x7FFF7FFFU; + /* read SYSCFG_TIMERCFG1 register value */ + TIMERxCFG1_value = SYSCFG_TIMERCFG1(TIMERx_temp) & 0x001F7FFFU; + /* read SYSCFG_TIMERCFG2 register value */ + TIMERxCFG2_value = SYSCFG_TIMERCFG2(TIMERx_temp) & 0x001F0000U; + + if((0U == TIMERxCFG0_value)&&(0U == TIMERxCFG1_value)&&(0U == TIMERxCFG2_value)){ + if(slavemode <= 2U){ + TIMERxCFG_temp = (uint32_t)0x1F << (slavemode * 5U); + }else if((slavemode <= 5U)&&(slavemode >= 3U)){ + TIMERxCFG_temp = (uint32_t)0x1F << ((slavemode * 5U) + 1U); + }else if((slavemode <= 8U)&&(slavemode >= 6U)){ + TIMERxCFG_temp = (uint32_t)0x1F << ((slavemode-6U) * 5U); + }else if(slavemode == 9U){ + TIMERxCFG_temp = (uint32_t)0x1F << (((slavemode-6U) * 5U) + 1U); + }else{ + TIMERxCFG_temp = (uint32_t)0x1F << (((slavemode-12U) * 5U) + 1U); + } + }else{ + if((SYSCFG_TIMERCFG0(TIMERx_temp) & 0x7FFF7FFFU) != 0U){ + for(i = 0U; i < 3U; i++){ + if((SYSCFG_TIMERCFG0(TIMERx_temp) & (BITS(0,4) << (i * 5U))) != 0U){ + trigger_temp = (SYSCFG_TIMERCFG0(TIMERx_temp) & (BITS(0,4) << (i * 5U))) >> (i * 5U); + SYSCFG_TIMERCFG0(TIMERx_temp)=0U; + break; + } + } + for(i = 3U; i < 6U; i++){ + if((SYSCFG_TIMERCFG0(TIMERx_temp) & (BITS(0,4) << ((i * 5U)+1U))) != 0U){ + trigger_temp = (SYSCFG_TIMERCFG0(TIMERx_temp) & (BITS(0,4) << ((i * 5U)+1U))) >> ((i * 5U)+1U); + SYSCFG_TIMERCFG0(TIMERx_temp)=0U; + break; + } + } + }else if((SYSCFG_TIMERCFG1(TIMERx_temp) & 0x001F7FFFU) != 0U){ + for(i = 6U; i < 10U; i++){ + if(i < 9U){ + if((SYSCFG_TIMERCFG1(TIMERx_temp) & (BITS(0,4) << ((i-6U)*5U))) != 0U){ + trigger_temp = (SYSCFG_TIMERCFG1(TIMERx_temp) & (BITS(0,4) << ((i-6U) * 5U))) >> ((i-6U) * 5U); + SYSCFG_TIMERCFG1(TIMERx_temp)=0U; + break; + } + }else{ + if((SYSCFG_TIMERCFG1(TIMERx_temp) & (BITS(0,4) << ((i-6U)*5U+1U))) != 0U){ + trigger_temp = (SYSCFG_TIMERCFG1(TIMERx_temp) & (BITS(0,4) << ((i-6U)*5U+1U))) >> ((i-6U)*5U+1U); + SYSCFG_TIMERCFG1(TIMERx_temp)=0U; + } + } + } + }else{ + trigger_temp = (SYSCFG_TIMERCFG2(TIMERx_temp) & (BITS(0,4) << 16U)) >> 16U; + SYSCFG_TIMERCFG2(TIMERx_temp)=0U; + } + + if(slavemode <= 2U){ + TIMERxCFG_temp = trigger_temp << (slavemode * 5U); + }else if((slavemode <= 5U)&&(slavemode >= 3U)){ + TIMERxCFG_temp = trigger_temp << ((slavemode * 5U) + 1U); + }else if((slavemode <= 8U)&&(slavemode >= 6U)){ + TIMERxCFG_temp = trigger_temp << ((slavemode-6U) * 5U); + }else if(slavemode == 9U){ + TIMERxCFG_temp = trigger_temp << (((slavemode-6U) * 5U) + 1U); + }else{ + TIMERxCFG_temp = trigger_temp << (((slavemode-12U) * 5U) + 1U); + } + } + REG32(TIMERxCFG_addr) = TIMERxCFG_temp; +} + +/*! + \brief configure TIMER master slave mode + \param[in] TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] masterslave: master slave mode + only one parameter can be selected which is shown as below: + \arg TIMER_MASTER_SLAVE_MODE_ENABLE: master slave mode enable + \arg TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable + \param[out] none + \retval none +*/ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave) +{ + if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave) { + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM; + } else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave) { + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_MSM); + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] extprescaler: external trigger prescaler + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: external trigger polarity + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC)); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extprescaler | extpolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << 8U); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] decomode: quadrature decoder mode + only one parameter can be selected which is shown as below: + \arg TIMER_QUAD_DECODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level + \arg TIMER_QUAD_DECODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level + \arg TIMER_QUAD_DECODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input + \param[in] ic0polarity: input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[in] ic1polarity: input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity) +{ + /* configure the quadrature decoder mode */ + timer_slave_mode_select(timer_periph, decomode); + + /* configure input capture selection */ + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS)) & ((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI | ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + /* configure channel input capture polarity */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity | ((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER non-quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] decomode: non-quadrature decoder mode + only one parameter can be selected which is shown as below: + \arg TIMER_NONQUAD_DECODER_MODE0: non-quadrature decoder mode 0 + \arg TIMER_NONQUAD_DECODER_MODE1: non-quadrature decoder mode 1 + \param[in] ic1polarity: input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[out] none + \retval none +*/ +void timer_non_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic1polarity) +{ + /* configure the quadrature decoder mode */ + timer_slave_mode_select(timer_periph, decomode); + + /* configure input capture selection */ + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS)) & ((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI | ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + /* configure channel input capture polarity */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic1polarity << 4U); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_DISABLE); +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] intrigger: internal trigger selection + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI4: internal trigger 4 for General-L0 timer(TIMERx(x=1,2,22,23,30,31)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI5: internal trigger 5 for General-L0 timer(TIMERx(x=1,22,23,30)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI7: internal trigger 7 for General-L0 timer(TIMERx(x=4)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI9: internal trigger 9 for General-L0 timer(TIMERx(x=22,23)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI10: internal trigger 10 for General-L0 timer(TIMERx(x=22,23)) + \arg TIMER_L0_SMCFG_TRGSEL_ITI11: internal trigger 11 for General-L0 timer(TIMERx(x=22,23)) + \arg TIMER_SMCFG_TRGSEL_ITI12: internal trigger 12(TIMERx(x=0~4,7,23,30,31)) + \arg TIMER_SMCFG_TRGSEL_ITI13: internal trigger 13(TIMERx(x=0~4,7,22,30,31)) + \arg TIMER_SMCFG_TRGSEL_ITI14: internal trigger 14(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \param[out] none + \retval none +*/ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger) +{ + /* select TIMER slave mode */ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_EXTERNAL0); + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, intrigger); +} + +/*! + \brief configure TIMER the external trigger as external clock input + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] extrigger: external trigger selection + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered channel 0 input(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered channel 1 input(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_SMCFG_TRGSEL_CI2FE2: filtered channel 2 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_CI3FE3: filtered channel 3 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_MCI0FEM0: filtered multi mode channel 0 input(TIMERx(x=0,7,14,40~44)) + \arg TIMER_SMCFG_TRGSEL_MCI1FEM1: filtered multi mode channel 1 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_MCI2FEM2: filtered multi mode channel 2 input(TIMERx(x=0,7)) + \arg TIMER_SMCFG_TRGSEL_MCI3FEM3: filtered multi mode channel 3 input(TIMERx(x=0,7)) + \param[in] extpolarity: external input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: active high or rising edge active + \arg TIMER_IC_POLARITY_FALLING: active low or falling edge active + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger) { + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + /* set the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)extpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + } else if(TIMER_SMCFG_TRGSEL_CI2FE2 == extrigger) { + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + /* reset the CH2P and MCH2P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P | TIMER_CHCTL2_MCH2P)); + /* set the CH2P and MCH2P bits */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)extpolarity << 8U); + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + /* set the CH2MS bit */ + TIMER_CHCTL1(timer_periph) |= ((uint32_t)TIMER_IC_SELECTION_DIRECTTI); + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + /* set the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) |= (uint32_t)(extfilter << 4U); + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + } else if(TIMER_SMCFG_TRGSEL_CI3FE3 == extrigger) { + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + /* reset the CH3P and MCH3P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P | TIMER_CHCTL2_MCH3P)); + /* set the CH3P and MCH3P bits */ + TIMER_CHCTL2(timer_periph) |= ((uint32_t)extpolarity << 12U); + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + /* set the CH3MS bit */ + TIMER_CHCTL1(timer_periph) |= ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + /* set the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) |= (uint32_t)(extfilter << 12U); + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + } else if(TIMER_SMCFG_TRGSEL_MCI0FEM0 == extrigger) { + /* reset the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + /* reset the MCH0FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH0FP); + /* set the MCH0FP bit */ + if(TIMER_IC_POLARITY_RISING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_RISING; + } else if(TIMER_IC_POLARITY_FALLING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_FALLING; + } else { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE; + } + /* reset the MCH0MS bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0MS); + /* set the MCH0MS bit */ + TIMER_MCHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI; + /* reset the MCH0CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0CAPFLT); + /* reset the MCH0CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) |= (uint32_t)(extfilter << 4U); + /* set the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH0EN; + } else if(TIMER_SMCFG_TRGSEL_MCI1FEM1 == extrigger) { + /* reset the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + /* reset the MCH1FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH1FP); + /* set the MCH1FP bit */ + if(TIMER_IC_POLARITY_RISING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_RISING << 2U; + } else if(TIMER_IC_POLARITY_FALLING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_FALLING << 2U; + } else { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 2U; + } + /* reset the MCH1MS bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1MS); + /* set the MCH1MS bit */ + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the MCH1CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1CAPFLT); + /* set the MCH1CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) |= (uint32_t)(extfilter << 12U); + /* set the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH1EN; + } else if(TIMER_SMCFG_TRGSEL_MCI2FEM2 == extrigger) { + /* reset the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + /* reset the MCH2FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH2FP); + /* set the MCH2FP bit */ + if(TIMER_IC_POLARITY_RISING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_RISING << 4U; + } else if(TIMER_IC_POLARITY_FALLING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_FALLING << 4U; + } else { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 4U; + } + /* reset the MCH2MS bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2MS); + /* set the MCH2MS bit */ + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)TIMER_IC_SELECTION_DIRECTTI); + /* reset the MCH2CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2CAPFLT); + /* set the MCH2CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) |= (uint32_t)(extfilter << 4U); + /* set the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH2EN; + } else if(TIMER_SMCFG_TRGSEL_MCI3FEM3 == extrigger) { + /* reset the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + /* reset the MCH3FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH3FP); + /* set the MCH3FP bit */ + if(TIMER_IC_POLARITY_RISING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_RISING << 6U; + } else if(TIMER_IC_POLARITY_FALLING == extpolarity) { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_FALLING << 6U; + } else { + TIMER_MCHCTL2(timer_periph) |= (uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 6U; + } + /* reset the MCH3MS bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3MS); + /* set the MCH3MS bit */ + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the MCH3CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3CAPFLT); + /* set the MCH3CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) |= (uint32_t)(extfilter << 12U); + /* set the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH3EN; + } else { + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + /* set the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)extpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + } + + /* select TIMER slave mode */ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_EXTERNAL0); + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, extrigger); +} + +/*! + \brief configure TIMER the external clock mode0 + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \param[in] extprescaler: external trigger prescaler + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: external input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + /* select TIMER slave mode */ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_EXTERNAL0); + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] extprescaler: external trigger prescaler + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: external input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_disable(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC1); +} + +/*! + \brief configure TIMER write CHxVAL register selection + \param[in] timer_periph: TIMERx(x=0~4,14~16,22,23,30,31,40~44) + \param[in] ccsel: write CHxVAL register selection + only one parameter can be selected which is shown as below: + \arg TIMER_CHVSEL_DISABLE: no effect + \arg TIMER_CHVSEL_ENABLE: when write the CHxVAL register, if the write value is same as the CHxVAL value, the write access is ignored + \param[out] none + \retval none +*/ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel) +{ + if(TIMER_CHVSEL_ENABLE == ccsel) { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL; + } else if(TIMER_CHVSEL_DISABLE == ccsel) { + TIMER_CFG(timer_periph) &= (~(uint32_t)TIMER_CFG_CHVSEL); + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER output value selection + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] outsel: output value selection + only one parameter can be selected which is shown as below: + \arg TIMER_OUTSEL_DISABLE: no effect + \arg TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel) +{ + if(TIMER_OUTSEL_ENABLE == outsel) { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL; + } else if(TIMER_OUTSEL_DISABLE == outsel) { + TIMER_CFG(timer_periph) &= (~(uint32_t)TIMER_CFG_OUTSEL); + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure commutation control shadow register update selection + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] cssel: commutation control shadow register selection + only one parameter can be selected which is shown as below: + \arg TIMER_CCUSEL_DISABLE: the shadow registers update when the counter generates an overflow/ underflow event + \arg TIMER_CCUSEL_ENABLE: the shadow registers update when the counter generates an overflow/ underflow event and the repetition counter value is zero + \param[out] none + \retval none +*/ +void timer_commutation_control_shadow_register_config(uint32_t timer_periph, uint16_t ccssel) +{ + if(TIMER_CCUSEL_ENABLE == ccssel) { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CCUSEL; + } else if(TIMER_CCUSEL_DISABLE == ccssel) { + TIMER_CFG(timer_periph) &= (~(uint32_t)TIMER_CFG_CCUSEL); + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER output match pulse selection + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[in] pulsesel: output match pulse selection + only one parameter can be selected which is shown as below: + \arg TIMER_PULSE_OUTPUT_NORMAL: channel output normal + \arg TIMER_PULSE_OUTPUT_CNT_UP: pulse output only when counting up + \arg TIMER_PULSE_OUTPUT_CNT_DOWN: pulse output only when counting down + \arg TIMER_PULSE_OUTPUT_CNT_BOTH: pulse output when counting up or down + \param[out] none + \retval none +*/ +void timer_output_match_pulse_select(uint32_t timer_periph, uint32_t channel, uint16_t pulsesel) +{ + uint32_t reg; + reg = TIMER_CTL2(timer_periph); + + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 8U)); + reg |= (uint32_t)((uint32_t)pulsesel << 8U); + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 10U)); + reg |= (uint32_t)((uint32_t)pulsesel << 10U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 12U)); + reg |= (uint32_t)((uint32_t)pulsesel << 12U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 14U)); + reg |= (uint32_t)((uint32_t)pulsesel << 14U); + break; + default: + break; + } + TIMER_CTL2(timer_periph) = reg; +} + +/*! + \brief configure the TIMER composite PWM mode + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_composite_pwm_mode_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= (uint32_t)(TIMER_CTL2_CH0CPWMEN << channel); + } else { + TIMER_CTL2(timer_periph) &= (~(uint32_t)(TIMER_CTL2_CH0CPWMEN << channel)); + } +} + +/*! + \brief configure the TIMER composite PWM mode output pulse value + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[in] pulse: channel compare value, 0~0xFFFFFFFF + \param[in] add_pulse: channel additional compare value, 0~0xFFFFFFFF + \param[out] none + \retval none +*/ +void timer_channel_composite_pwm_mode_output_pulse_value_config(uint32_t timer_periph, uint32_t channel, uint32_t pulse, uint32_t add_pulse) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + TIMER_CH0COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + TIMER_CH1COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + TIMER_CH2COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + TIMER_CH3COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel additional compare value + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[in] value: channel additional compare value, 0~0xFFFFFFFF + \param[out] none + \retval none +*/ +void timer_channel_additional_compare_value_config(uint32_t timer_periph, uint16_t channel, uint32_t value) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0COMV_ADD(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1COMV_ADD(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2COMV_ADD(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3COMV_ADD(timer_periph) = (uint32_t)value; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel additional output shadow function + \param[in] timer_periph: TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14~16,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[in] aocshadow: channel additional output compare shadow + only one parameter can be selected which is shown as below: + \arg TIMER_ADD_SHADOW_ENABLE: channel additional compare output shadow enable + \arg TIMER_ADD_SHADOW_DISABLE: channel additional compare output shadow disable + \param[out] none + \retval none +*/ +void timer_channel_additional_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t aocshadow) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMADDSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 28U); + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMADDSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 29U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMADDSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 28U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMADDSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 29U); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel additional compare value + \param[in] timer_periph: TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0~4,7,14,22,23,30,31,40~44)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0~4,7,22,23,30,31)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0~4,7,22,23,30,31)) + \param[out] none + \retval value: channel additional compare value, 0~0xFFFFFFFF +*/ +uint32_t timer_channel_additional_compare_value_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t value = 0U; + switch(channel) { + case TIMER_CH_0: + /* read CH0COMV_ADD value */ + value = TIMER_CH0COMV_ADD(timer_periph); + break; + case TIMER_CH_1: + /* read CH1COMV_ADD value */ + value = TIMER_CH1COMV_ADD(timer_periph); + break; + case TIMER_CH_2: + /* read CH2COMV_ADD value */ + value = TIMER_CH2COMV_ADD(timer_periph); + break; + case TIMER_CH_3: + /* read CH3COMV_ADD value */ + value = TIMER_CH3COMV_ADD(timer_periph); + break; + default: + break; + } + return value; +} + +/*! + \brief configure the TIMER break source + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signals, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BREAK1: BREAK1 input signals, TIMERx(x=0,7) + \param[in] break_src: break source + only one parameter can be selected which is shown as below: + \arg TIMER_BRKIN0: BRKIN0 alternate function input enable, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BRKIN1: BRKIN1 alternate function input enable, TIMERx(x=0,7) + \arg TIMER_BRKIN2: BRKIN2 alternate function input enable, TIMERx(x=0,7) + \arg TIMER_BRKCMP0: CMP0 input enable, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BRKCMP1: CMP1 input enable, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BRKHPDF: HPDF input enable, TIMERx(x=0,7,14~16,40~44) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_break_external_source_config(uint32_t timer_periph, uint16_t break_num, uint32_t break_src, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + if(TIMER_BREAK0 == break_num) { + TIMER_AFCTL0(timer_periph) |= break_src; + } else if(TIMER_BREAK1 == break_num) { + TIMER_AFCTL1(timer_periph) |= break_src; + } else { + /* illegal parameters */ + } + } else { + if(TIMER_BREAK0 == break_num) { + TIMER_AFCTL0(timer_periph) &= (~break_src); + } else if(TIMER_BREAK1 == break_num) { + TIMER_AFCTL1(timer_periph) &= (~break_src); + } else { + /* illegal parameters */ + } + } +} + +/*! + \brief configure TIMER break polarity + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signal, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BREAK1: BREAK1 input signal, TIMERx(x=0,7) + \param[in] break_src: break source + only one parameter can be selected which is shown as below: + \arg TIMER_BRKIN0: BRKIN0 alternate function input enable, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BRKIN1: BRKIN1 alternate function input enable, TIMERx(x=0,7) + \arg TIMER_BRKIN2: BRKIN2 alternate function input enable, TIMERx(x=0,7) + \arg TIMER_BRKCMP0: CMP0 input enable, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BRKCMP1: CMP1 input enable, TIMERx(x=0,7,14~16,40~44) + \param[in] bkinpolarity: break polarity + only one parameter can be selected which is shown as below: + TIMER_BRKIN_POLARITY_LOW: input signal will not be inverted + TIMER_BRKIN_POLARITY_HIGH: input signal will be inverted + \param[out] none + \retval none +*/ +void timer_break_external_polarity_config(uint32_t timer_periph, uint16_t break_num, uint32_t break_src, uint16_t bkinpolarity) +{ + if(TIMER_BREAK0 == break_num) { + switch(break_src) { + case TIMER_BRKIN0: + TIMER_AFCTL0(timer_periph) &= (~(uint32_t)TIMER_BRKIN0P); + TIMER_AFCTL0(timer_periph) |= ((uint32_t)bkinpolarity << 16U); + break; + case TIMER_BRKIN1: + TIMER_AFCTL0(timer_periph) &= (~(uint32_t)TIMER_BRKIN1P); + TIMER_AFCTL0(timer_periph) |= ((uint32_t)bkinpolarity << 17U); + break; + case TIMER_BRKIN2: + TIMER_AFCTL0(timer_periph) &= (~(uint32_t)TIMER_BRKIN2P); + TIMER_AFCTL0(timer_periph) |= ((uint32_t)bkinpolarity << 18U); + break; + case TIMER_BRKCMP0: + TIMER_AFCTL0(timer_periph) &= (~(uint32_t)TIMER_BRKCMP0P); + TIMER_AFCTL0(timer_periph) |= ((uint32_t)bkinpolarity << 25U); + break; + case TIMER_BRKCMP1: + TIMER_AFCTL0(timer_periph) &= (~(uint32_t)TIMER_BRKCMP1P); + TIMER_AFCTL0(timer_periph) |= ((uint32_t)bkinpolarity << 26U); + break; + default: + break; + } + } else { + switch(break_src) { + case TIMER_BRKIN0: + TIMER_AFCTL1(timer_periph) &= (~(uint32_t)TIMER_BRKIN0P); + TIMER_AFCTL1(timer_periph) |= ((uint32_t)bkinpolarity << 16U); + break; + case TIMER_BRKIN1: + TIMER_AFCTL1(timer_periph) &= (~(uint32_t)TIMER_BRKIN1P); + TIMER_AFCTL1(timer_periph) |= ((uint32_t)bkinpolarity << 17U); + break; + case TIMER_BRKIN2: + TIMER_AFCTL1(timer_periph) &= (~(uint32_t)TIMER_BRKIN2P); + TIMER_AFCTL1(timer_periph) |= ((uint32_t)bkinpolarity << 18U); + break; + case TIMER_BRKCMP0: + TIMER_AFCTL1(timer_periph) &= (~(uint32_t)TIMER_BRKCMP0P); + TIMER_AFCTL1(timer_periph) |= ((uint32_t)bkinpolarity << 25U); + break; + case TIMER_BRKCMP1: + TIMER_AFCTL1(timer_periph) &= (~(uint32_t)TIMER_BRKCMP1P); + TIMER_AFCTL1(timer_periph) |= ((uint32_t)bkinpolarity << 26U); + break; + default: + break; + } + } +} + +/*! + \brief configure TIMER break lock function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: enable BREAK0 lock function, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BREAK1: enable BREAK1 lock function, TIMERx(x=0,7) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_break_lock_config(uint32_t timer_periph, uint16_t break_num, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK0LK; + } else { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK1LK; + } + } else { + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_BRK0LK); + } else { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_BRK1LK); + } + } +} + +/*! + \brief release the TIMER break lock function + \param[in] timer_periph: TIMERx(x=0,7,14~16,40~44) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: release the BREAK0 lock function, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_BREAK1: release the BREAK1 lock function, TIMERx(x=0,7) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_break_lock_release_config(uint32_t timer_periph, uint16_t break_num, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK0REL; + } else { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK1REL; + } + } else { + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_BRK0REL); + } else { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_BRK1REL); + } + } +} + +/*! + \brief configure the TIMER channel break function + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \arg TIMER_CH_2: TIMER channel 2 + \arg TIMER_CH_3: TIMER channel 3 + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_break_control_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= (uint32_t)(TIMER_CTL2_BRKENCH0 << channel); + } else { + TIMER_CTL2(timer_periph) &= (~(uint32_t)(TIMER_CTL2_BRKENCH0 << channel)); + } +} + +/*! + \brief configure the TIMER channel free dead time function + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \arg TIMER_CH_2: TIMER channel 2 + \arg TIMER_CH_3: TIMER channel 3 + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_dead_time_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= (uint32_t)(TIMER_CTL2_DTIENCH0 << channel); + } else { + TIMER_CTL2(timer_periph) &= (~(uint32_t)(TIMER_CTL2_DTIENCH0 << channel)); + } +} + +/*! + \brief initialize TIMER channel free complementary parameter struct with a default value + \param[in] freecompara: TIMER channel free complementary parameter struct + \param[out] none + \retval none +*/ +void timer_free_complementary_struct_para_init(timer_free_complementary_parameter_struct *freecompara) +{ + /* initialize the channel free complementary parameter struct member with the default value */ + freecompara->freecomstate = TIMER_FCCHP_STATE_DISABLE; + freecompara->runoffstate = TIMER_ROS_STATE_DISABLE; + freecompara->ideloffstate = TIMER_IOS_STATE_DISABLE; + freecompara->deadtime = 0U; +} + +/*! + \brief configure channel free complementary protection + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \arg TIMER_CH_2: TIMER channel 2 + \arg TIMER_CH_3: TIMER channel 3 + \param[in] fcpara: TIMER channel free complementary parameter struct + freecomstate: TIMER_FCCHP_STATE_ENABLE, TIMER_FCCHP_STATE_DISABLE + runoffstate: TIMER_ROS_STATE_ENABLE, TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE, TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + \param[out] none + \retval none +*/ +void timer_channel_free_complementary_config(uint32_t timer_periph, uint16_t channel, timer_free_complementary_parameter_struct *fcpara) +{ + switch(channel) { + case TIMER_CH_0: + TIMER_FCCHP0(timer_periph) &= (~(uint32_t)(TIMER_FCCHP0_DTCFG | TIMER_FCCHP0_IOS | TIMER_FCCHP0_ROS | TIMER_FCCHP0_FCCHP0EN)); + TIMER_FCCHP0(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP0(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP0(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP0(timer_periph) |= fcpara->freecomstate; + break; + case TIMER_CH_1: + TIMER_FCCHP1(timer_periph) &= (~(uint32_t)(TIMER_FCCHP1_DTCFG | TIMER_FCCHP1_IOS | TIMER_FCCHP1_ROS | TIMER_FCCHP1_FCCHP1EN)); + TIMER_FCCHP1(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP1(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP1(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP1(timer_periph) |= fcpara->freecomstate; + break; + case TIMER_CH_2: + TIMER_FCCHP2(timer_periph) &= (~(uint32_t)(TIMER_FCCHP2_DTCFG | TIMER_FCCHP2_IOS | TIMER_FCCHP2_ROS | TIMER_FCCHP2_FCCHP2EN)); + TIMER_FCCHP2(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP2(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP2(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP2(timer_periph) |= fcpara->freecomstate; + break; + case TIMER_CH_3: + TIMER_FCCHP3(timer_periph) &= (~(uint32_t)(TIMER_FCCHP3_DTCFG | TIMER_FCCHP3_IOS | TIMER_FCCHP3_ROS | TIMER_FCCHP3_FCCHP3EN)); + TIMER_FCCHP3(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP3(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP3(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP3(timer_periph) |= fcpara->freecomstate; + break; + default: + break; + } +} + +/*! + \brief configure quadrature decoder signal disconnection detection watchdog value + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] value: watchdog counter period value, 0~0xFFFFFFFF + \param[out] none + \retval none +*/ +void timer_watchdog_value_config(uint32_t timer_periph, uint32_t value) +{ + TIMER_WDGPER(timer_periph) = value; +} + +/*! + \brief read quadrature decoder signal disconnection detection watchdog value + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval watchdog counter period register value, 0~0xFFFFFFFF +*/ +uint32_t timer_watchdog_value_read(uint32_t timer_periph) +{ + return (TIMER_WDGPER(timer_periph)); +} + +/*! + \brief configure quadrature decoder signal disconnection detection function + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_decoder_disconnection_detection_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= TIMER_DECDISCONNECTDEN; + } else { + TIMER_CTL2(timer_periph) &= (~TIMER_DECDISCONNECTDEN); + } +} + +/*! + \brief configure quadrature decoder signal jump detection function + \param[in] timer_periph: TIMERx(x=0~4,7,22,23,30,31) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_decoder_jump_detection_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= TIMER_DECJUMPDEN; + } else { + TIMER_CTL2(timer_periph) &= (~TIMER_DECJUMPDEN); + } +} + +/*! + \brief configure the UPIF bit backup function + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_upif_backup_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPIFBUEN; + } else { + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_UPIFBUEN); + } +} + +/*! + \brief get the UPIFBU bit in the TIMERx_CNT register + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[out] none + \retval UPIFBUStatus: VALID_SET or VALID_RESET or INVALID + \ret VALID_SET: the UPIFBU is valid and value is 1 + \ret VALID_RESET: the UPIFBU is valid and value is 0 + \ret INVALID: the UPIFBU is invalid +*/ +UPIFBUStatus timer_upifbu_bit_get(uint32_t timer_periph) +{ + if((TIMER_CTL0(timer_periph) & TIMER_CTL0_UPIFBUEN)) { + if((TIMER50 == timer_periph) || (TIMER51 == timer_periph)) { + if(TIMER_CNTH(timer_periph) & TIMER_CNT_UPIFBU) { + return VALID_SET; + } else { + return VALID_RESET; + } + } else { + if(TIMER_CNT(timer_periph) & TIMER_CNT_UPIFBU) { + return VALID_SET; + } else { + return VALID_RESET; + } + } + } else { + return INVALID; + } +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] flag: the TIMER flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_FLAG_CH0: channel 0 capture or compare flag, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_FLAG_CH1: channel 1 capture or compare flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_FLAG_CH2: channel 2 capture or compare flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CH3: channel 3 capture or compare flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_FLAG_BRK0: BREAK0 flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_BRK1: BREAK1 flag, TIMERx(x=0,7) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_SYSB: system source break flag, TIMERx(x=0,7) + \arg TIMER_FLAG_DECJ: quadrature decoder signal jump flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_DECDIS: quadrature decoder signal disconnection flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_MCH0: multi mode channel 0 capture or compare flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_MCH1: multi mode channel 1 capture or compare flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH2: multi mode channel 2 capture or compare flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH3: multi mode channel 3 capture or compare flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH0O: multi mode channel 0 overcapture flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_MCH1O: multi mode channel 1 overcapture flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH2O: multi mode channel 2 overcapture flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH3O: multi mode channel 3 overcapture flag, TIMERx(x=0,7) + \arg TIMER_FLAG_CH0COMADD: channel 0 additional compare flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_FLAG_CH1COMADD: channel 1 additional compare flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_FLAG_CH2COMADD: channel 2 additional compare flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CH3COMADD: channel 3 additional compare flag, TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if(RESET != (TIMER_INTF(timer_periph) & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] flag: the TIMER flags + one or more parameters can be selected which are shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_FLAG_CH0: channel 0 capture or compare flag, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_FLAG_CH1: channel 1 capture or compare flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_FLAG_CH2: channel 2 capture or compare flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CH3: channel 3 capture or compare flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_FLAG_BRK0: BREAK0 flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_BRK1: BREAK1 flag, TIMERx(x=0,7) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_SYSB: system source break flag, TIMERx(x=0,7) + \arg TIMER_FLAG_DECJ: quadrature decoder signal jump flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_DECDIS: quadrature decoder signal disconnection flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_MCH0: multi mode channel 0 capture or compare flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_MCH1: multi mode channel 1 capture or compare flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH2: multi mode channel 2 capture or compare flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH3: multi mode channel 3 capture or compare flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH0O: multi mode channel 0 overcapture flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_FLAG_MCH1O: multi mode channel 1 overcapture flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH2O: multi mode channel 2 overcapture flag, TIMERx(x=0,7) + \arg TIMER_FLAG_MCH3O: multi mode channel 3 overcapture flag, TIMERx(x=0,7) + \arg TIMER_FLAG_CH0COMADD: channel 0 additional compare flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_FLAG_CH1COMADD: channel 1 additional compare flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_FLAG_CH2COMADD: channel 2 additional compare flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_FLAG_CH3COMADD: channel 3 additional compare flag, TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)flag); +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] interrupt: timer interrupt source + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_UP: update interrupt, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_INT_CH0: channel 0 capture or compare interrupt, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_INT_CH1: channel 1 capture or compareinterrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_CH2: channel 2 capture or compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_CH3: channel 3 capture or compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_CMT: channel commutation interrupt, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_TRG: trigger interrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_BRK: break interrupt, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_DECJ: quadrature decoder signal jump interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_DECDIS: quadrature decoder signal disconnection interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_MCH0: multi mode channel 0 capture or compare interrupt, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_MCH1: multi mode channel 1 capture or compare interrupt, TIMERx(x=0,7) + \arg TIMER_INT_MCH2: multi mode channel 2 capture or compare interrupt, TIMERx(x=0,7) + \arg TIMER_INT_MCH3: multi mode channel 3 capture or compare interrupt, TIMERx(x=0,7) + \arg TIMER_INT_CH0COMADD: channel 0 additional compare interrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_CH1COMADD: channel 1 additional compare interrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_CH2COMADD: channel 2 additional compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_CH3COMADD: channel 3 additional compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; +} + +/*! + \brief disable the TIMER interrupt + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] interrupt: timer interrupt source + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_UP: update interrupt, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_INT_CH0: channel 0 capture or compare interrupt, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_INT_CH1: channel 1 capture or compareinterrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_CH2: channel 2 capture or compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_CH3: channel 3 capture or compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_CMT: channel commutation interrupt, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_TRG: trigger interrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_BRK: break interrupt, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_DECJ: quadrature decoder signal jump interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_DECDIS: quadrature decoder signal disconnection interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_MCH0: multi mode channel 0 capture or compare interrupt, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_MCH1: multi mode channel 1 capture or compare interrupt, TIMERx(x=0,7) + \arg TIMER_INT_MCH2: multi mode channel 2 capture or compare interrupt, TIMERx(x=0,7) + \arg TIMER_INT_MCH3: multi mode channel 3 capture or compare interrupt, TIMERx(x=0,7) + \arg TIMER_INT_CH0COMADD: channel 0 additional compare interrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_CH1COMADD: channel 1 additional compare interrupt, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_CH2COMADD: channel 2 additional compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_CH3COMADD: channel 3 additional compare interrupt, TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get timer interrupt flags + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] int_flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_INT_FLAG_CH0: channel 0 capture or compare interrupt flag, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_INT_FLAG_CH1: channel 1 capture or compare interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_FLAG_CH2: channel 2 capture or compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_CH3: channel 3 capture or compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_FLAG_BRK0: BREAK0 interrupt flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_FLAG_BRK1: BREAK1 interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_SYSB: system source break interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_DECJ: quadrature decoder signal jump interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_DECDIS: quadrature decoder signal disconnection interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_MCH0: multi mode channel 0 capture or compare interrupt flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_FLAG_MCH1: multi mode channel 1 capture or compare interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_MCH2: multi mode channel 2 capture or compare interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_MCH3: multi mode channel 3 capture or compare interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_CH0COMADD: channel 0 additional compare interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_INT_FLAG_CH1COMADD: channel 1 additional compare interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_INT_FLAG_CH2COMADD: channel 2 additional compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_CH3COMADD: channel 3 additional compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t int_flag) +{ + uint32_t val; + + if(TIMER_INT_FLAG_BRK1 == int_flag) { + val = (TIMER_DMAINTEN(timer_periph) & TIMER_DMAINTEN_BRKIE); + } else if(TIMER_INT_FLAG_SYSB == int_flag) { + val = (TIMER_DMAINTEN(timer_periph) & TIMER_DMAINTEN_BRKIE); + } else { + val = (TIMER_DMAINTEN(timer_periph) & int_flag); + } + + if((RESET != (TIMER_INTF(timer_periph) & int_flag)) && (RESET != val)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flags + \param[in] timer_periph: TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \param[in] int_flag: the timer interrupt flags + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0~7,14~16,22,23,30,31,40~44,50,51) + \arg TIMER_INT_FLAG_CH0: channel 0 capture or compare interrupt flag, TIMERx(x=0~4,7,14~16,22,23,30,31,40~44) + \arg TIMER_INT_FLAG_CH1: channel 1 capture or compare interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_FLAG_CH2: channel 2 capture or compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_CH3: channel 3 capture or compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31,40~44) + \arg TIMER_INT_FLAG_BRK0: BREAK0 interrupt flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_FLAG_BRK1: BREAK1 interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_SYSB: system source break interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_DECJ: quadrature decoder signal jump interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_DECDIS: quadrature decoder signal disconnection interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_MCH0: multi mode channel 0 capture or compare interrupt flag, TIMERx(x=0,7,14~16,40~44) + \arg TIMER_INT_FLAG_MCH1: multi mode channel 1 capture or compare interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_MCH2: multi mode channel 2 capture or compare interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_MCH3: multi mode channel 3 capture or compare interrupt flag, TIMERx(x=0,7) + \arg TIMER_INT_FLAG_CH0COMADD: channel 0 additional compare interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_INT_FLAG_CH1COMADD: channel 1 additional compare interrupt flag, TIMERx(x=0~4,7,14,22,23,30,31) + \arg TIMER_INT_FLAG_CH2COMADD: channel 2 additional compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \arg TIMER_INT_FLAG_CH3COMADD: channel 3 additional compare interrupt flag, TIMERx(x=0~4,7,22,23,30,31) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t int_flag) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)int_flag); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tli.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tli.c new file mode 100644 index 0000000000..be9dee750f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tli.c @@ -0,0 +1,598 @@ +/*! + \file gd32h7xx_tli.c + \brief TLI driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_tli.h" + +/* TLI default value */ +#define TLI_DEFAULT_VALUE 0x00000000U +#define TLI_OPAQUE_VALUE 0x000000FFU + +/*! + \brief deinitialize TLI registers + \param[in] none + \param[out] none + \retval none +*/ +void tli_deinit(void) +{ + rcu_periph_reset_enable(RCU_TLIRST); + rcu_periph_reset_disable(RCU_TLIRST); +} + +/*! + \brief initialize the parameters of TLI parameter structure with the default values, it is suggested + that call this function after a tli_parameter_struct structure is defined + \param[in] none + \param[out] tli_struct: the data needed to initialize TLI + synpsz_vpsz: size of the vertical synchronous pulse + synpsz_hpsz: size of the horizontal synchronous pulse + backpsz_vbpsz: size of the vertical back porch plus synchronous pulse + backpsz_hbpsz: size of the horizontal back porch plus synchronous pulse + activesz_vasz: size of the vertical active area width plus back porch and synchronous pulse + activesz_hasz: size of the horizontal active area width plus back porch and synchronous pulse + totalsz_vtsz: vertical total size of the display, including active area, back porch, synchronous + totalsz_htsz: vorizontal total size of the display, including active area, back porch, synchronous + backcolor_red: background value red + backcolor_green: background value green + backcolor_blue: background value blue + signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGHT + signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGHT + signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGHT + signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI + \retval none +*/ +void tli_struct_para_init(tli_parameter_struct *tli_struct) +{ + /* initialize the struct parameters with default values */ + tli_struct->synpsz_vpsz = TLI_DEFAULT_VALUE; + tli_struct->synpsz_hpsz = TLI_DEFAULT_VALUE; + tli_struct->backpsz_vbpsz = TLI_DEFAULT_VALUE; + tli_struct->backpsz_hbpsz = TLI_DEFAULT_VALUE; + tli_struct->activesz_vasz = TLI_DEFAULT_VALUE; + tli_struct->activesz_hasz = TLI_DEFAULT_VALUE; + tli_struct->totalsz_vtsz = TLI_DEFAULT_VALUE; + tli_struct->totalsz_htsz = TLI_DEFAULT_VALUE; + tli_struct->backcolor_red = TLI_DEFAULT_VALUE; + tli_struct->backcolor_green = TLI_DEFAULT_VALUE; + tli_struct->backcolor_blue = TLI_DEFAULT_VALUE; + tli_struct->signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW; + tli_struct->signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW; + tli_struct->signalpolarity_de = TLI_DE_ACTLIVE_LOW; + tli_struct->signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI; +} + +/*! + \brief initialize TLI display timing parameters + \param[in] tli_struct: the data needed to initialize TLI + synpsz_vpsz: size of the vertical synchronous pulse + synpsz_hpsz: size of the horizontal synchronous pulse + backpsz_vbpsz: size of the vertical back porch plus synchronous pulse + backpsz_hbpsz: size of the horizontal back porch plus synchronous pulse + activesz_vasz: size of the vertical active area width plus back porch and synchronous pulse + activesz_hasz: size of the horizontal active area width plus back porch and synchronous pulse + totalsz_vtsz: vertical total size of the display, including active area, back porch, synchronous + totalsz_htsz: vorizontal total size of the display, including active area, back porch, synchronous + backcolor_red: background value red + backcolor_green: background value green + backcolor_blue: background value blue + signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGH + signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGH + signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGHT + signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI + \param[out] none + \retval none +*/ +void tli_init(tli_parameter_struct *tli_struct) +{ + /* synchronous pulse size configuration */ + TLI_SPSZ &= ~(TLI_SPSZ_VPSZ | TLI_SPSZ_HPSZ); + TLI_SPSZ = (uint32_t)((uint32_t)tli_struct->synpsz_vpsz | ((uint32_t)tli_struct->synpsz_hpsz << 16U)); + /* back-porch size configuration */ + TLI_BPSZ &= ~(TLI_BPSZ_VBPSZ | TLI_BPSZ_HBPSZ); + TLI_BPSZ = (uint32_t)((uint32_t)tli_struct->backpsz_vbpsz | ((uint32_t)tli_struct->backpsz_hbpsz << 16U)); + /* active size configuration */ + TLI_ASZ &= ~(TLI_ASZ_VASZ | TLI_ASZ_HASZ); + TLI_ASZ = (tli_struct->activesz_vasz | (tli_struct->activesz_hasz << 16U)); + /* total size configuration */ + TLI_TSZ &= ~(TLI_TSZ_VTSZ | TLI_TSZ_HTSZ); + TLI_TSZ = (tli_struct->totalsz_vtsz | (tli_struct->totalsz_htsz << 16U)); + /* background color configuration */ + TLI_BGC &= ~(TLI_BGC_BVB | (TLI_BGC_BVG) | (TLI_BGC_BVR)); + TLI_BGC = (tli_struct->backcolor_blue | (tli_struct->backcolor_green << 8U) | (tli_struct->backcolor_red << 16U)); + TLI_CTL &= ~(TLI_CTL_HPPS|TLI_CTL_VPPS | TLI_CTL_DEPS|TLI_CTL_CLKPS); + TLI_CTL |= (tli_struct->signalpolarity_hs | tli_struct->signalpolarity_vs | \ + tli_struct->signalpolarity_de | tli_struct->signalpolarity_pixelck); +} + +/*! + \brief configure TLI dither function + \param[in] dither_stat + only one parameter can be selected which is shown as below: + \arg TLI_DITHER_ENABLE + \arg TLI_DITHER_DISABLE + \param[out] none + \retval none +*/ +void tli_dither_config(uint8_t dither_stat) +{ + if(TLI_DITHER_ENABLE == dither_stat){ + TLI_CTL |= TLI_CTL_DFEN; + } else { + TLI_CTL &= ~(TLI_CTL_DFEN); + } +} + +/*! + \brief enable TLI + \param[in] none + \param[out] none + \retval none +*/ +void tli_enable(void) +{ + TLI_CTL |= TLI_CTL_TLIEN; +} + +/*! + \brief disable TLI + \param[in] none + \param[out] none + \retval none +*/ +void tli_disable(void) +{ + TLI_CTL &= ~(TLI_CTL_TLIEN); +} + +/*! + \brief configure TLI reload mode + \param[in] reload_mod + only one parameter can be selected which is shown as below: + \arg TLI_FRAME_BLANK_RELOAD_EN + \arg TLI_REQUEST_RELOAD_EN + \param[out] none + \retval none +*/ +void tli_reload_config(uint8_t reload_mod) +{ + if(TLI_FRAME_BLANK_RELOAD_EN == reload_mod){ + /* the layer configuration will be reloaded at frame blank */ + TLI_RL |= TLI_RL_FBR; + } else { + /* the layer configuration will be reloaded after this bit sets */ + TLI_RL |= TLI_RL_RQR; + } +} + +/*! + \brief initialize the parameters of TLI layer structure with the default values, it is suggested + that call this function after a tli_layer_parameter_struct structure is defined + \param[in] none + \param[out] layer_struct: TLI Layer parameter struct + layer_window_rightpos: window right position + layer_window_leftpos: window left position + layer_window_bottompos: window bottom position + layer_window_toppos: window top position + layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565, + LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8, + LAYER_PPF_AL44,LAYER_PPF_AL88 + layer_sa: specified alpha + layer_default_alpha: the default color alpha + layer_default_red: the default color red + layer_default_green: the default color green + layer_default_blue: the default color blue + layer_acf1: LAYER_ACF1_SA,LAYER_ACF1_PASA + layer_acf2: LAYER_ACF2_SA,LAYER_ACF2_PASA + layer_frame_bufaddr: frame buffer base address + layer_frame_buf_stride_offset: frame buffer stride offset + layer_frame_line_length: frame line length + layer_frame_total_line_number: frame total line number + \retval none +*/ +void tli_layer_struct_para_init(tli_layer_parameter_struct *layer_struct) +{ + /* initialize the struct parameters with default values */ + layer_struct->layer_window_rightpos = TLI_DEFAULT_VALUE; + layer_struct->layer_window_leftpos = TLI_DEFAULT_VALUE; + layer_struct->layer_window_bottompos = TLI_DEFAULT_VALUE; + layer_struct->layer_window_toppos = TLI_DEFAULT_VALUE; + layer_struct->layer_ppf = LAYER_PPF_ARGB8888; + layer_struct->layer_sa = TLI_OPAQUE_VALUE; + layer_struct->layer_default_alpha = TLI_DEFAULT_VALUE; + layer_struct->layer_default_red = TLI_DEFAULT_VALUE; + layer_struct->layer_default_green = TLI_DEFAULT_VALUE; + layer_struct->layer_default_blue = TLI_DEFAULT_VALUE; + layer_struct->layer_acf1 = LAYER_ACF1_PASA; + layer_struct->layer_acf2 = LAYER_ACF2_PASA; + layer_struct->layer_frame_bufaddr = TLI_DEFAULT_VALUE; + layer_struct->layer_frame_buf_stride_offset = TLI_DEFAULT_VALUE; + layer_struct->layer_frame_line_length = TLI_DEFAULT_VALUE; + layer_struct->layer_frame_total_line_number = TLI_DEFAULT_VALUE; +} + +/*! + \brief initialize TLI layer + \param[in] layerx: LAYERx(x=0,1) + \param[in] layer_struct: TLI Layer parameter struct + layer_window_rightpos: window right position + layer_window_leftpos: window left position + layer_window_bottompos: window bottom position + layer_window_toppos: window top position + layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565, + LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8, + LAYER_PPF_AL44,LAYER_PPF_AL88 + layer_sa: specified alpha + layer_default_alpha: the default color alpha + layer_default_red: the default color red + layer_default_green: the default color green + layer_default_blue: the default color blue + layer_acf1: LAYER_ACF1_SA,LAYER_ACF1_PASA + layer_acf2: LAYER_ACF2_SA,LAYER_ACF2_PASA + layer_frame_bufaddr: frame buffer base address + layer_frame_buf_stride_offset: frame buffer stride offset + layer_frame_line_length: frame line length + layer_frame_total_line_number: frame total line number + \param[out] none + \retval none +*/ +void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct) +{ + /* configure layer window horizontal position */ + TLI_LXHPOS(layerx) &= ~(TLI_LXHPOS_WLP | (TLI_LXHPOS_WRP)); + TLI_LXHPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_leftpos | ((uint32_t)layer_struct->layer_window_rightpos << 16U)); + /* configure layer window vertical position */ + TLI_LXVPOS(layerx) &= ~(TLI_LXVPOS_WTP | (TLI_LXVPOS_WBP)); + TLI_LXVPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_toppos | ((uint32_t)layer_struct->layer_window_bottompos << 16U)); + /* configure layer packeted pixel format */ + TLI_LXPPF(layerx) &= ~(TLI_LXPPF_PPF); + TLI_LXPPF(layerx) = layer_struct->layer_ppf; + /* configure layer specified alpha */ + TLI_LXSA(layerx) &= ~(TLI_LXSA_SA); + TLI_LXSA(layerx) = layer_struct->layer_sa; + /* configure layer default color */ + TLI_LXDC(layerx) &= ~(TLI_LXDC_DCB | (TLI_LXDC_DCG) | (TLI_LXDC_DCR) | (TLI_LXDC_DCA)); + TLI_LXDC(layerx) = (uint32_t)((uint32_t)layer_struct->layer_default_blue | + ((uint32_t)layer_struct->layer_default_green << 8U) | + ((uint32_t)layer_struct->layer_default_red << 16U) | + ((uint32_t)layer_struct->layer_default_alpha << 24U)); + + /* configure layer alpha calculation factors */ + TLI_LXBLEND(layerx) &= ~(TLI_LXBLEND_ACF2 | (TLI_LXBLEND_ACF1)); + TLI_LXBLEND(layerx) = ((layer_struct->layer_acf2) | (layer_struct->layer_acf1)); + /* configure layer frame buffer base address */ + TLI_LXFBADDR(layerx) &= ~(TLI_LXFBADDR_FBADD); + TLI_LXFBADDR(layerx) = (layer_struct->layer_frame_bufaddr); + /* configure layer frame line length */ + TLI_LXFLLEN(layerx) &= ~(TLI_LXFLLEN_FLL | (TLI_LXFLLEN_STDOFF)); + TLI_LXFLLEN(layerx) = (uint32_t)((uint32_t)layer_struct->layer_frame_line_length | ((uint32_t)layer_struct->layer_frame_buf_stride_offset << 16U)); + /* configure layer frame total line number */ + TLI_LXFTLN(layerx) &= ~(TLI_LXFTLN_FTLN); + TLI_LXFTLN(layerx) = (uint32_t)(layer_struct->layer_frame_total_line_number); + +} + +/*! + \brief reconfigure window position + \param[in] layerx: LAYERx(x=0,1) + \param[in] offset_x: new horizontal offset + \param[in] offset_y: new vertical offset + \param[out] none + \retval none +*/ +void tli_layer_window_offset_modify(uint32_t layerx,uint16_t offset_x,uint16_t offset_y) +{ + /* configure window start position */ + uint32_t layer_ppf, line_num, hstart, vstart; + uint32_t line_length = 0U; + TLI_LXHPOS(layerx) &= ~(TLI_LXHPOS_WLP | (TLI_LXHPOS_WRP)); + TLI_LXVPOS(layerx) &= ~(TLI_LXVPOS_WTP | (TLI_LXVPOS_WBP)); + hstart = (uint32_t)offset_x + (((TLI_BPSZ & TLI_BPSZ_HBPSZ) >> 16U) + 1U); + vstart = (uint32_t)offset_y + ((TLI_BPSZ & TLI_BPSZ_VBPSZ) + 1U); + line_num = (TLI_LXFTLN(layerx) & TLI_LXFTLN_FTLN); + layer_ppf = (TLI_LXPPF(layerx) & TLI_LXPPF_PPF); + /* the bytes of a line equal TLI_LXFLLEN_FLL bits value minus 3 */ + switch(layer_ppf){ + case LAYER_PPF_ARGB8888: + /* each pixel includes 4bytes, when pixel format is ARGB8888 */ + line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) -3U) / 4U); + break; + case LAYER_PPF_RGB888: + /* each pixel includes 3bytes, when pixel format is RGB888 */ + line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) - 3U) / 3U); + break; + case LAYER_PPF_RGB565: + case LAYER_PPF_ARGB1555: + case LAYER_PPF_ARGB4444: + case LAYER_PPF_AL88: + /* each pixel includes 2bytes, when pixel format is RGB565,ARG1555,ARGB4444 or AL88 */ + line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) - 3U) / 2U); + break; + case LAYER_PPF_L8: + case LAYER_PPF_AL44: + /* each pixel includes 1byte, when pixel format is L8 or AL44 */ + line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) - 3U)); + break; + default: + break; + } + /* reconfigure window position */ + TLI_LXHPOS(layerx) = (hstart | ((hstart+line_length - 1U) << 16U)); + TLI_LXVPOS(layerx) = (vstart | ((vstart+line_num - 1U) << 16U)); +} + +/*! + \brief initialize the parameters of TLI layer LUT structure with the default values, it is suggested + that call this function after a tli_layer_lut_parameter_struct structure is defined + \param[in] none + \param[out] lut_struct: TLI layer LUT parameter struct + layer_table_addr: look up table write address + layer_lut_channel_red: red channel of a LUT entry + layer_lut_channel_green: green channel of a LUT entry + layer_lut_channel_blue: blue channel of a LUT entry + \retval none +*/ +void tli_lut_struct_para_init(tli_layer_lut_parameter_struct *lut_struct) +{ + /* initialize the struct parameters with default values */ + lut_struct->layer_table_addr = TLI_DEFAULT_VALUE; + lut_struct->layer_lut_channel_red = TLI_DEFAULT_VALUE; + lut_struct->layer_lut_channel_green = TLI_DEFAULT_VALUE; + lut_struct->layer_lut_channel_blue = TLI_DEFAULT_VALUE; +} + +/*! + \brief initialize TLI layer LUT + \param[in] layerx: LAYERx(x=0,1) + \param[in] lut_struct: TLI layer LUT parameter struct + layer_table_addr: look up table write address + layer_lut_channel_red: red channel of a LUT entry + layer_lut_channel_green: green channel of a LUT entry + layer_lut_channel_blue: blue channel of a LUT entry + \param[out] none + \retval none +*/ +void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct) +{ + TLI_LXLUT(layerx) = (uint32_t)(((uint32_t)lut_struct->layer_lut_channel_blue) | + ((uint32_t)lut_struct->layer_lut_channel_green << 8U) | + ((uint32_t)lut_struct->layer_lut_channel_red << 16U) | + ((uint32_t)lut_struct->layer_table_addr << 24U)); +} + +/*! + \brief initialize TLI layer color key + \param[in] layerx: LAYERx(x=0,1) + \param[in] redkey: color key red + \param[in] greenkey: color key green + \param[in] bluekey: color key blue + \param[out] none + \retval none +*/ +void tli_color_key_init(uint32_t layerx,uint8_t redkey,uint8_t greenkey,uint8_t bluekey) +{ + TLI_LXCKEY(layerx) = (((uint32_t)bluekey) | ((uint32_t)greenkey << 8U) | ((uint32_t)redkey << 16U)); +} + +/*! + \brief enable TLI layer + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_layer_enable(uint32_t layerx) +{ + TLI_LXCTL(layerx) |= TLI_LXCTL_LEN; +} + +/*! + \brief disable TLI layer + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_layer_disable(uint32_t layerx) +{ + TLI_LXCTL(layerx) &= ~(TLI_LXCTL_LEN); +} + +/*! + \brief enable TLI layer color keying + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_color_key_enable(uint32_t layerx) +{ + TLI_LXCTL(layerx) |= TLI_LXCTL_CKEYEN; +} + +/*! + \brief disable TLI layer color keying + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_color_key_disable(uint32_t layerx) +{ + TLI_LXCTL(layerx) &= ~(TLI_LXCTL_CKEYEN); +} + +/*! + \brief enable TLI layer LUT + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_lut_enable(uint32_t layerx) +{ + TLI_LXCTL(layerx) |= TLI_LXCTL_LUTEN; +} + +/*! + \brief disable TLI layer LUT + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_lut_disable(uint32_t layerx) +{ + TLI_LXCTL(layerx) &= ~(TLI_LXCTL_LUTEN); +} + +/*! + \brief set line mark value + \param[in] line_num: line number + \param[out] none + \retval none +*/ +void tli_line_mark_set(uint16_t line_num) +{ + TLI_LM &= ~(TLI_LM_LM); + TLI_LM = (uint32_t)line_num; +} + +/*! + \brief get current displayed position + \param[in] none + \param[out] none + \retval position of current pixel +*/ +uint32_t tli_current_pos_get(void) +{ + return TLI_CPPOS; +} + +/*! + \brief enable TLI interrupt + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_LM: line mark interrupt + \arg TLI_INT_FE: FIFO error interrupt + \arg TLI_INT_TE: transaction error interrupt + \arg TLI_INT_LCR: layer configuration reloaded interrupt + \param[out] none + \retval none +*/ +void tli_interrupt_enable(uint32_t int_flag) +{ + TLI_INTEN |= (int_flag); +} + +/*! + \brief disable TLI interrupt + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_LM: line mark interrupt + \arg TLI_INT_FE: FIFO error interrupt + \arg TLI_INT_TE: transaction error interrupt + \arg TLI_INT_LCR: layer configuration reloaded interrupt + \param[out] none + \retval none +*/ +void tli_interrupt_disable(uint32_t int_flag) +{ + TLI_INTEN &= ~(int_flag); +} + +/*! + \brief get TLI interrupt flag + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_FLAG_LM: line mark interrupt flag + \arg TLI_INT_FLAG_FE: FIFO error interrupt flag + \arg TLI_INT_FLAG_TE: transaction error interrupt flag + \arg TLI_INT_FLAG_LCR: layer configuration reloaded interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus tli_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t state; + state = TLI_INTF; + if(state & int_flag){ + state = TLI_INTEN; + if(state & int_flag){ + return SET; + } + } + return RESET; +} + +/*! + \brief clear TLI interrupt flag + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_FLAG_LM: line mark interrupt flag + \arg TLI_INT_FLAG_FE: FIFO error interrupt flag + \arg TLI_INT_FLAG_TE: transaction error interrupt flag + \arg TLI_INT_FLAG_LCR: layer configuration reloaded interrupt flag + \param[out] none + \retval none +*/ +void tli_interrupt_flag_clear(uint32_t int_flag) +{ + TLI_INTC |= (int_flag); +} + +/*! + \brief get TLI flag or state in TLI_INTF register or TLI_STAT register + \param[in] flag: TLI flags or states + only one parameter can be selected which is shown as below: + \arg TLI_FLAG_VDE: current VDE state + \arg TLI_FLAG_HDE: current HDE state + \arg TLI_FLAG_VS: current VS status of the TLI + \arg TLI_FLAG_HS: current HS status of the TLI + \arg TLI_FLAG_LM: line mark interrupt flag + \arg TLI_FLAG_FE: FIFO error interrupt flag + \arg TLI_FLAG_TE: transaction error interrupt flag + \arg TLI_FLAG_LCR: layer configuration reloaded interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus tli_flag_get(uint32_t flag) +{ + uint32_t stat; + /* choose which register to get flag or state */ + if(flag >> 31U){ + stat = TLI_INTF; + }else{ + stat = TLI_STAT; + } + if(flag & stat){ + return SET; + }else{ + return RESET; + } +} + diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tmu.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tmu.c new file mode 100644 index 0000000000..a87efafa34 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_tmu.c @@ -0,0 +1,236 @@ +/*! + \file gd32h7xx_tmu.c + \brief TMU driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_tmu.h" + +#define MASK_LOW_HALFWORD ((uint32_t)0xFFFF0000U) +#define MASK_HIGH_HALFWORD ((uint32_t)0x0000FFFFU) + +/*! + \brief reset the TMU registers + \param[in] none + \param[out] none + \retval none +*/ +void tmu_deinit(void) +{ + rcu_periph_reset_enable(RCU_TMURST); + rcu_periph_reset_disable(RCU_TMURST); +} + +/*! + \brief initialize the parameters of TMU struct with the default values + \param[in] init_struct: pointer to init parameter struct + \param[out] none + \retval none +*/ +void tmu_struct_para_init(tmu_parameter_struct* init_struct) +{ + /* set the struct with the default values */ + init_struct->mode = TMU_MODE_COS; + init_struct->iterations_number = TMU_ITERATION_STEPS_20; + init_struct->scale = TMU_SCALING_FACTOR_1; + init_struct->dma_read = TMU_READ_DMA_DISABLE; + init_struct->dma_write = TMU_WRITE_DMA_DISABLE; + init_struct->read_times = TMU_READ_TIMES_1; + init_struct->write_times = TMU_WRITE_TIMES_1; + init_struct->output_width = TMU_OUTPUT_WIDTH_32; + init_struct->input_width = TMU_INPUT_WIDTH_32; +} + +/*! + \brief initialize TMU + \param[in] init_struct: pointer to init parameter struct + mode: TMU_MODE_COS,TMU_MODE_SIN,TMU_MODE_ATAN2,TMU_MODE_MODULUS,TMU_MODE_ATAN, + TMU_MODE_COSH,TMU_MODE_SINH,TMU_MODE_ATANH,TMU_MODE_LN,TMU_MODE_SQRT + iterations_number: TMU_ITERATION_STEPS_x(x=4,8,12,..24) + scale: TMU_SCALING_FACTOR_x(x=1,2,4,8,16,32,64,128) + dma_read: TMU_READ_DMA_DISABLE, TMU_READ_DMA_ENABLE + dma_write: TMU_WRITE_DMA_DISABLE, TMU_WRITE_DMA_ENABLE + read_times: TMU_READ_TIMES_1, TMU_READ_TIMES_2 + write_times: TMU_WRITE_TIMES_1, TMU_WRITE_TIMES_2 + output_width: TMU_OUTPUT_WIDTH_32, TMU_OUTPUT_WIDTH_16 + input_width: TMU_INPUT_WIDTH_32, TMU_INPUT_WIDTH_16 + \param[out] none + \retval none +*/ +void tmu_init(tmu_parameter_struct* init_struct) +{ + uint32_t reg = 0U; + reg |= ( init_struct->mode | init_struct->iterations_number | init_struct->scale |\ + init_struct->dma_read | init_struct->dma_write | init_struct->read_times |\ + init_struct->write_times | init_struct->output_width | init_struct->input_width); + TMU_CS = reg; +} + +/*! + \brief enable TMU read interrupt + \param[in] none + \param[out] none + \retval none +*/ +void tmu_read_interrupt_enable(void) +{ + TMU_CS |= TMU_CS_RIE; +} + +/*! + \brief disable TMU read interrupt + \param[in] none + \param[out] none + \retval none +*/ +void tmu_read_interrupt_disable(void) +{ + TMU_CS &= ~TMU_CS_RIE; +} + +/*! + \brief enable TMU DMA read request + \param[in] none + \param[out] none + \retval none +*/ +void tmu_dma_read_enable(void) +{ + TMU_CS |= TMU_CS_RDEN; +} + +/*! + \brief disable TMU DMA read request + \param[in] none + \param[out] none + \retval none +*/ +void tmu_dma_read_disable(void) +{ + TMU_CS &= ~TMU_CS_RDEN; +} + +/*! + \brief enable TMU DMA write request + \param[in] none + \param[out] none + \retval none +*/ +void tmu_dma_write_enable(void) +{ + TMU_CS |= TMU_CS_WDEN; +} + +/*! + \brief disable TMU DMA write request + \param[in] none + \param[out] none + \retval none +*/ +void tmu_dma_write_disable(void) +{ + TMU_CS &= ~TMU_CS_WDEN; +} + +/*! + \brief write one data in q1.31 format + \param[in] data: the first input data only + \param[out] none + \retval none +*/ +void tmu_one_q31_write(uint32_t data) +{ + TMU_IDATA = data; +} + +/*! + \brief write two data in q1.31 format + \param[in] data1: the first input data + \param[in] data2: the second input data + \param[out] none + \retval none +*/ +void tmu_two_q31_write(uint32_t data1, uint32_t data2) +{ + TMU_IDATA = data1; + TMU_IDATA = data2; +} + +/*! + \brief write two data in q1.15 format + \param[in] data1: the first input data + \param[in] data2: the second input data (this data is meaningless in mode4 ~ mode9) + \param[out] none + \retval none +*/ +void tmu_two_q15_write(uint16_t data1, uint16_t data2) +{ + TMU_IDATA = ((((uint32_t)data1) & MASK_HIGH_HALFWORD)| (((uint32_t)data2 << 16U) & MASK_LOW_HALFWORD)); +} + +/*! + \brief read one data in q1.31 format + \param[in] none + \param[out] p: pointer to the first output data only + \retval none +*/ +void tmu_one_q31_read(uint32_t* p) +{ + *p = TMU_ODATA; +} + +/*! + \brief read two data in q1.31 format + \param[in] none + \param[out] p1: pointer to the first output data + \param[out] p2: pointer to the second output data + \retval none +*/ +void tmu_two_q31_read(uint32_t* p1, uint32_t* p2) +{ + *p1 = TMU_ODATA; + *p2 = TMU_ODATA; +} + +/*! + \brief read two data in q1.15 format + \param[in] none + \param[out] p1: pointer to the first output data + \param[out] p2: pointer to the second output data (this data is meaningless in mode4, mode7 ~ mode9) + \retval none +*/ +void tmu_two_q15_read(uint16_t* p1, uint16_t* p2) +{ + uint32_t data; + data = TMU_ODATA; + *p1 = (uint16_t)data; + *p2 = (uint16_t)(data >> 16U); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trigsel.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trigsel.c new file mode 100644 index 0000000000..f5d24004a0 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trigsel.c @@ -0,0 +1,513 @@ +/*! + \file gd32h7xx_trigsel.c + \brief TRIGSEL driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_trigsel.h" + +/* TRIGSEL target register redefine */ +#define TRIGSEL_TARGET_REG(target_periph) (REG32(TRIGSEL + ((uint32_t)(target_periph) & BITS(2,31)))) /*!< target peripheral register */ +#define TRIGSEL_TARGET_PERIPH_SHIFT(target_periph) (((uint32_t)(target_periph) & BITS(0,1)) << 3U) /*!< bit offset in target peripheral register */ +#define TRIGSEL_TARGET_PERIPH_MASK(target_periph) ((uint32_t)(BITS(0,7) << TRIGSEL_TARGET_PERIPH_SHIFT(target_periph))) /*!< bit mask in target peripheral register */ + +/*! + \brief deinitialize TRIGSEL + \param[in] none + \param[out] none + \retval none +*/ +void trigsel_deinit(void) +{ + rcu_periph_reset_enable(RCU_TRIGSELRST); + rcu_periph_reset_disable(RCU_TRIGSELRST); +} + +/*! + \brief set the trigger input signal for target peripheral + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG + \arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG + \arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG + \arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG + \arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG + \arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG + \arg TRIGSEL_OUTPUT_DAC_OUT0_EXTRG: output target peripheral DAC_OUT0_EXTRG + \arg TRIGSEL_OUTPUT_DAC_OUT1_EXTRG: output target peripheral DAC_OUT1_EXTRG + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG + \arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI + \arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI + \arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI + \arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI + \arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI + \arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI + \arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI + \arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI + \arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI + \arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI + \arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG + \arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR + \arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14 + \arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14 + \arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14 + \arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14 + \arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14 + \arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14 + \arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14 + \arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14 + \arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14 + \arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14 + \arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14 + \arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14 + \arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14 + \arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14 + \arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14 + \arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14 + \param[in] trigger_source: trigger source value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_INPUT_0: trigger input source 0 + \arg TRIGSEL_INPUT_1: trigger input source 1 + \arg TRIGSEL_INPUT_TRIGSEL_IN0: trigger input source TRIGSEL_IN0 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN1: trigger input source TRIGSEL_IN1 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN2: trigger input source TRIGSEL_IN2 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN3: trigger input source TRIGSEL_IN3 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN4: trigger input source TRIGSEL_IN4 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN5: trigger input source TRIGSEL_IN5 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN6: trigger input source TRIGSEL_IN6 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN7: trigger input source TRIGSEL_IN7 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN8: trigger input source TRIGSEL_IN8 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN9: trigger input source TRIGSEL_IN9 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN10: trigger input source TRIGSEL_IN10 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN11: trigger input source TRIGSEL_IN11 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN12: trigger input source TRIGSEL_IN12 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN13: trigger input source TRIGSEL_IN13 pin + \arg TRIGSEL_INPUT_LXTAL_TRG: trigger input source LXTAL_TRG + \arg TRIGSEL_INPUT_TIMER0_TRGO0: trigger input source TIMER0 TRGO0 + \arg TRIGSEL_INPUT_TIMER0_TRGO1: trigger input source TIMER0 TRGO1 + \arg TRIGSEL_INPUT_TIMER0_CH0: trigger input source TIMER0 CH0 + \arg TRIGSEL_INPUT_TIMER0_CH1: trigger input source TIMER0 CH1 + \arg TRIGSEL_INPUT_TIMER0_CH2: trigger input source TIMER0 CH2 + \arg TRIGSEL_INPUT_TIMER0_CH3: trigger input source TIMER0 CH3 + \arg TRIGSEL_INPUT_TIMER0_MCH0: trigger input source TIMER0 MCH0 + \arg TRIGSEL_INPUT_TIMER0_MCH1: trigger input source TIMER0 MCH1 + \arg TRIGSEL_INPUT_TIMER0_MCH2: trigger input source TIMER0 MCH2 + \arg TRIGSEL_INPUT_TIMER0_MCH3: trigger input source TIMER0 MCH3 + \arg TRIGSEL_INPUT_TIMER0_BRKIN0: trigger input source TIMER0 BRKIN0 + \arg TRIGSEL_INPUT_TIMER0_BRKIN1: trigger input source TIMER0 BRKIN1 + \arg TRIGSEL_INPUT_TIMER0_BRKIN2: trigger input source TIMER0 BRKIN2 + \arg TRIGSEL_INPUT_TIMER0_ETI: trigger input source TIMER0 ETI + \arg TRIGSEL_INPUT_TIMER1_TRGO0: trigger input source TIMER1 TRGO0 + \arg TRIGSEL_INPUT_TIMER1_CH0: trigger input source TIMER1 CH0 + \arg TRIGSEL_INPUT_TIMER1_CH1: trigger input source TIMER1 CH1 + \arg TRIGSEL_INPUT_TIMER1_CH2: trigger input source TIMER1 CH2 + \arg TRIGSEL_INPUT_TIMER1_CH3: trigger input source TIMER1 CH2 + \arg TRIGSEL_INPUT_TIMER1_ETI: trigger input source TIMER1 ETI + \arg TRIGSEL_INPUT_TIMER2_TRGO0: trigger input source TIMER2 TRGO0 + \arg TRIGSEL_INPUT_TIMER2_CH0: trigger input source TIMER2 CH0 + \arg TRIGSEL_INPUT_TIMER2_CH1: trigger input source TIMER2 CH1 + \arg TRIGSEL_INPUT_TIMER2_CH2: trigger input source TIMER2 CH2 + \arg TRIGSEL_INPUT_TIMER2_CH3: trigger input source TIMER2 CH3 + \arg TRIGSEL_INPUT_TIMER2_ETI: trigger input source TIMER2 ETI + \arg TRIGSEL_INPUT_TIMER3_TRGO0: trigger input source TIMER3 TRGO0 + \arg TRIGSEL_INPUT_TIMER3_CH0: trigger input source TIMER3 CH0 + \arg TRIGSEL_INPUT_TIMER3_CH1: trigger input source TIMER3 CH1 + \arg TRIGSEL_INPUT_TIMER3_CH2: trigger input source TIMER3 CH2 + \arg TRIGSEL_INPUT_TIMER3_CH3: trigger input source TIMER3 CH3 + \arg TRIGSEL_INPUT_TIMER3_ETI: trigger input source TIMER3 ETI + \arg TRIGSEL_INPUT_TIMER4_TRGO0: trigger input source TIMER4 TRGO0 + \arg TRIGSEL_INPUT_TIMER4_CH0: trigger input source TIMER4 CH0 + \arg TRIGSEL_INPUT_TIMER4_CH1: trigger input source TIMER4 CH1 + \arg TRIGSEL_INPUT_TIMER4_CH2: trigger input source TIMER4 CH2 + \arg TRIGSEL_INPUT_TIMER4_CH3: trigger input source TIMER4 CH3 + \arg TRIGSEL_INPUT_TIMER4_ETI: trigger input source TIMER4 ETI + \arg TRIGSEL_INPUT_TIMER5_TRGO0: trigger input source TIMER5 TRGO0 + \arg TRIGSEL_INPUT_TIMER6_TRGO0: trigger input source TIMER6 TRGO0 + \arg TRIGSEL_INPUT_TIMER7_TRGO0: trigger input source TIMER7 TRGO0 + \arg TRIGSEL_INPUT_TIMER7_TRGO1: trigger input source TIMER7 TRGO1 + \arg TRIGSEL_INPUT_TIMER7_CH0: trigger input source TIMER7 CH0 + \arg TRIGSEL_INPUT_TIMER7_CH1: trigger input source TIMER7 CH1 + \arg TRIGSEL_INPUT_TIMER7_CH2: trigger input source TIMER7 CH2 + \arg TRIGSEL_INPUT_TIMER7_CH3: trigger input source TIMER7 CH3 + \arg TRIGSEL_INPUT_TIMER7_MCH0: trigger input source TIMER7 MCH0 + \arg TRIGSEL_INPUT_TIMER7_MCH1: trigger input source TIMER7 MCH1 + \arg TRIGSEL_INPUT_TIMER7_MCH2: trigger input source TIMER7 MCH2 + \arg TRIGSEL_INPUT_TIMER7_MCH3: trigger input source TIMER7 MCH3 + \arg TRIGSEL_INPUT_TIMER7_BRKIN0: trigger input source TIMER7 BRKIN0 + \arg TRIGSEL_INPUT_TIMER7_BRKIN1: trigger input source TIMER7 BRKIN1 + \arg TRIGSEL_INPUT_TIMER7_BRKIN2: trigger input source TIMER7 BRKIN2 + \arg TRIGSEL_INPUT_TIMER7_ETI: trigger input source TIMER7 ETI + \arg TRIGSEL_INPUT_TIMER14_TRGO0: trigger input source TIMER14 TRGO0 + \arg TRIGSEL_INPUT_TIMER14_CH0: trigger input source TIMER14 CH0 + \arg TRIGSEL_INPUT_TIMER14_CH1: trigger input source TIMER14 CH1 + \arg TRIGSEL_INPUT_TIMER14_MCH0: trigger input source TIMER14 MCH0 + \arg TRIGSEL_INPUT_TIMER14_BRKIN: trigger input source TIMER14 BRKIN + \arg TRIGSEL_INPUT_TIMER15_CH0: trigger input source TIMER15 CH0 + \arg TRIGSEL_INPUT_TIMER15_MCH0: trigger input source TIMER15 MCH0 + \arg TRIGSEL_INPUT_TIMER15_BRKIN: trigger input source TIMER15 BRKIN + \arg TRIGSEL_INPUT_TIMER16_CH0: trigger input source TIMER16 CH0 + \arg TRIGSEL_INPUT_TIMER16_MCH0: trigger input source TIMER16 MCH0 + \arg TRIGSEL_INPUT_TIMER16_BRKIN: trigger input source TIMER16 BRKIN + \arg TRIGSEL_INPUT_TIMER22_TRGO0: trigger input source TIMER22 TRGO0 + \arg TRIGSEL_INPUT_TIMER22_CH0: trigger input source TIMER22 CH0 + \arg TRIGSEL_INPUT_TIMER22_CH1: trigger input source TIMER22 CH1 + \arg TRIGSEL_INPUT_TIMER22_CH2: trigger input source TIMER22 CH2 + \arg TRIGSEL_INPUT_TIMER22_CH3: trigger input source TIMER22 CH3 + \arg TRIGSEL_INPUT_TIMER22_ETI: trigger input source TIMER22 ETI + \arg TRIGSEL_INPUT_TIMER23_TRGO0: trigger input source TIMER23 TRGO0 + \arg TRIGSEL_INPUT_TIMER23_CH0: trigger input source TIMER23 CH0 + \arg TRIGSEL_INPUT_TIMER23_CH1: trigger input source TIMER23 CH1 + \arg TRIGSEL_INPUT_TIMER23_CH2: trigger input source TIMER23 CH2 + \arg TRIGSEL_INPUT_TIMER23_CH3: trigger input source TIMER23 CH3 + \arg TRIGSEL_INPUT_TIMER23_ETI: trigger input source TIMER23 ETI + \arg TRIGSEL_INPUT_TIMER30_TRGO0: trigger input source TIMER30 TRGO0 + \arg TRIGSEL_INPUT_TIMER30_CH0: trigger input source TIMER30 CH0 + \arg TRIGSEL_INPUT_TIMER30_CH1: trigger input source TIMER30 CH1 + \arg TRIGSEL_INPUT_TIMER30_CH2: trigger input source TIMER30 CH2 + \arg TRIGSEL_INPUT_TIMER30_CH3: trigger input source TIMER30 CH3 + \arg TRIGSEL_INPUT_TIMER30_ETI: trigger input source TIMER30 ETI + \arg TRIGSEL_INPUT_TIMER31_TRGO0: trigger input source TIMER31 TRGO0 + \arg TRIGSEL_INPUT_TIMER31_CH0: trigger input source TIMER31 CH0 + \arg TRIGSEL_INPUT_TIMER31_CH1: trigger input source TIMER31 CH1 + \arg TRIGSEL_INPUT_TIMER31_CH2: trigger input source TIMER31 CH2 + \arg TRIGSEL_INPUT_TIMER31_CH3: trigger input source TIMER31 CH3 + \arg TRIGSEL_INPUT_TIMER31_ETI: trigger input source TIMER31 ETI + \arg TRIGSEL_INPUT_TIMER40_TRGO0: trigger input source TIMER40 TRGO0 + \arg TRIGSEL_INPUT_TIMER40_CH0: trigger input source TIMER40 CH0 + \arg TRIGSEL_INPUT_TIMER40_CH1: trigger input source TIMER40 CH1 + \arg TRIGSEL_INPUT_TIMER40_MCH0: trigger input source TIMER40 MCH0 + \arg TRIGSEL_INPUT_TIMER40_BRKIN: trigger input source TIMER40 BRKIN + \arg TRIGSEL_INPUT_TIMER41_TRGO0: trigger input source TIMER41 TRGO0 + \arg TRIGSEL_INPUT_TIMER41_CH0: trigger input source TIMER41 CH0 + \arg TRIGSEL_INPUT_TIMER41_CH1: trigger input source TIMER41 CH1 + \arg TRIGSEL_INPUT_TIMER41_MCH0: trigger input source TIMER41 MCH0 + \arg TRIGSEL_INPUT_TIMER41_BRKIN: trigger input source TIMER41 BRKIN + \arg TRIGSEL_INPUT_TIMER42_TRGO0: trigger input source TIMER42 TRGO0 + \arg TRIGSEL_INPUT_TIMER42_CH0: trigger input source TIMER42 CH0 + \arg TRIGSEL_INPUT_TIMER42_CH1: trigger input source TIMER42 CH1 + \arg TRIGSEL_INPUT_TIMER42_MCH0: trigger input source TIMER42 MCH0 + \arg TRIGSEL_INPUT_TIMER42_BRKIN: trigger input source TIMER42 BRKIN + \arg TRIGSEL_INPUT_TIMER43_TRGO0: trigger input source TIMER43 TRGO0 + \arg TRIGSEL_INPUT_TIMER43_CH0: trigger input source TIMER43 CH0 + \arg TRIGSEL_INPUT_TIMER43_CH1: trigger input source TIMER43 CH1 + \arg TRIGSEL_INPUT_TIMER43_MCH0: trigger input source TIMER43 MCH0 + \arg TRIGSEL_INPUT_TIMER43_BRKIN: trigger input source TIMER43 BRKIN + \arg TRIGSEL_INPUT_TIMER44_TRGO0: trigger input source TIMER44 TRGO0 + \arg TRIGSEL_INPUT_TIMER44_CH0: trigger input source TIMER44 CH0 + \arg TRIGSEL_INPUT_TIMER44_CH1: trigger input source TIMER44 CH1 + \arg TRIGSEL_INPUT_TIMER44_MCH0: trigger input source TIMER44 MCH0 + \arg TRIGSEL_INPUT_TIMER44_BRKIN: trigger input source TIMER44 BRKIN + \arg TRIGSEL_INPUT_TIMER50_TRGO0: trigger input source TIMER50 TRGO0 + \arg TRIGSEL_INPUT_TIMER51_TRGO0: trigger input source TIMER51 TRGO0 + \arg TRIGSEL_INPUT_RTC_ALARM: trigger input source RTC alarm + \arg TRIGSEL_INPUT_RTC_TPTS: trigger input source RTC TPTS + \arg TRIGSEL_INPUT_ADC0_WD0_OUT: trigger input source ADC0 watchdog0 output + \arg TRIGSEL_INPUT_ADC0_WD1_OUT: trigger input source ADC0 watchdog1 output + \arg TRIGSEL_INPUT_ADC0_WD2_OUT: trigger input source ADC0 watchdog2 output + \arg TRIGSEL_INPUT_ADC1_WD0_OUT: trigger input source ADC1 watchdog0 output + \arg TRIGSEL_INPUT_ADC1_WD1_OUT: trigger input source ADC1 watchdog1 output + \arg TRIGSEL_INPUT_ADC1_WD2_OUT: trigger input source ADC1 watchdog2 output + \arg TRIGSEL_INPUT_ADC2_WD0_OUT: trigger input source ADC2 watchdog0 output + \arg TRIGSEL_INPUT_ADC2_WD1_OUT: trigger input source ADC2 watchdog1 output + \arg TRIGSEL_INPUT_ADC2_WD2_OUT: trigger input source ADC2 watchdog2 output + \arg TRIGSEL_INPUT_CMP0_OUT: trigger input source CMP0_OUT + \arg TRIGSEL_INPUT_CMP1_OUT: trigger input source CMP1_OUT + \arg TRIGSEL_INPUT_SAI0_AFS_OUT: trigger input source SAI0_AFS_OUT + \arg TRIGSEL_INPUT_SAI0_BFS_OUT: trigger input source SAI0_BFS_OUT + \arg TRIGSEL_INPUT_SAI2_AFS_OUT: trigger input source SAI2_AFS_OUT + \arg TRIGSEL_INPUT_SAI2_BFS_OUT: trigger input source SAI2_BFS_OUT + \param[out] none + \retval none +*/ +void trigsel_init(trigsel_periph_enum target_periph, trigsel_source_enum trigger_source) +{ + /* if register write is enabled, set trigger source to target peripheral */ + if (RESET == trigsel_register_lock_get(target_periph)){ + TRIGSEL_TARGET_REG(target_periph) &= ~TRIGSEL_TARGET_PERIPH_MASK(target_periph); + TRIGSEL_TARGET_REG(target_periph) |= ((uint32_t)trigger_source << TRIGSEL_TARGET_PERIPH_SHIFT(target_periph)) & TRIGSEL_TARGET_PERIPH_MASK(target_periph); + } +} + +/*! + \brief get the trigger input signal for target peripheral + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG + \arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG + \arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG + \arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG + \arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG + \arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG + \arg TRIGSEL_OUTPUT_DAC_OUT0_EXTRG: output target peripheral DAC_OUT0_EXTRG + \arg TRIGSEL_OUTPUT_DAC_OUT1_EXTRG: output target peripheral DAC_OUT1_EXTRG + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG + \arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI + \arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI + \arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI + \arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI + \arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI + \arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI + \arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI + \arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI + \arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI + \arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI + \arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG + \arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR + \arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14 + \arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14 + \arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14 + \arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14 + \arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14 + \arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14 + \arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14 + \arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14 + \arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14 + \arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14 + \arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14 + \arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14 + \arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14 + \arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14 + \arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14 + \arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14 + \param[out] none + \retval trigger_source: trigger source value(0~177) +*/ +trigsel_source_enum trigsel_trigger_source_get(trigsel_periph_enum target_periph) +{ + trigsel_source_enum trigger_source; + + trigger_source = (trigsel_source_enum)((TRIGSEL_TARGET_REG(target_periph) & TRIGSEL_TARGET_PERIPH_MASK(target_periph)) >> TRIGSEL_TARGET_PERIPH_SHIFT(target_periph)); + + return trigger_source; +} + +/*! + \brief lock the trigger register + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG + \arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG + \arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG + \arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG + \arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG + \arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG + \arg TRIGSEL_OUTPUT_DAC_OUT0_EXTRG: output target peripheral DAC_OUT0_EXTRG + \arg TRIGSEL_OUTPUT_DAC_OUT1_EXTRG: output target peripheral DAC_OUT1_EXTRG + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG + \arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI + \arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI + \arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI + \arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI + \arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI + \arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI + \arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI + \arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI + \arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI + \arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI + \arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG + \arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR + \arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14 + \arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14 + \arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14 + \arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14 + \arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14 + \arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14 + \arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14 + \arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14 + \arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14 + \arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14 + \arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14 + \arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14 + \arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14 + \arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14 + \arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14 + \arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14 + \param[out] none + \retval none +*/ +void trigsel_register_lock_set(trigsel_periph_enum target_periph) +{ + /*!< lock target peripheral register */ + TRIGSEL_TARGET_REG(target_periph) |= TRIGSEL_TARGET_LK; +} + +/*! + \brief get the trigger register lock status + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG + \arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG + \arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG + \arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG + \arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG + \arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG + \arg TRIGSEL_OUTPUT_DAC_OUT0_EXTRG: output target peripheral DAC_OUT0_EXTRG + \arg TRIGSEL_OUTPUT_DAC_OUT1_EXTRG: output target peripheral DAC_OUT1_EXTRG + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG + \arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI + \arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI + \arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI + \arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI + \arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI + \arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI + \arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI + \arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI + \arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI + \arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI + \arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG + \arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR + \arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14 + \arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14 + \arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14 + \arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14 + \arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14 + \arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14 + \arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14 + \arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14 + \arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14 + \arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14 + \arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14 + \arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14 + \arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14 + \arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14 + \arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14 + \arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14 + \param[out] none + \retval SET or RESET +*/ +FlagStatus trigsel_register_lock_get(trigsel_periph_enum target_periph) +{ + if(RESET != (TRIGSEL_TARGET_REG(target_periph) & TRIGSEL_TARGET_LK)){ + return SET; + }else{ + return RESET; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trng.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trng.c new file mode 100644 index 0000000000..a51fb9acf5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_trng.c @@ -0,0 +1,426 @@ +/*! + \file gd32h7xx_trng.c + \brief TRNG driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_trng.h" + +/*! + \brief deinitialize the TRNG + \param[in] none + \param[out] none + \retval none +*/ +void trng_deinit(void) +{ + rcu_periph_reset_enable(RCU_TRNGRST); + rcu_periph_reset_disable(RCU_TRNGRST); +} + +/*! + \brief enable the TRNG interface + \param[in] none + \param[out] none + \retval none +*/ +void trng_enable(void) +{ + uint32_t trng_config = TRNG_CTL; + trng_config &= ~TRNG_CTL_CONDRST; + trng_config |= TRNG_CTL_TRNGEN; + TRNG_CTL = trng_config; +} + +/*! + \brief disable the TRNG interface + \param[in] none + \param[out] none + \retval none +*/ +void trng_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_TRNGEN; +} + +/*! + \brief lock the TRNG control bits + \param[in] none + \param[out] none + \retval none +*/ +void trng_lock(void) +{ + TRNG_CTL |= TRNG_CTL_LK; +} + +/*! + \brief configure TRNG working mode + \param[in] mode_select: the TRNG working mode + only one parameter can be selected which is shown as below: + \arg TRNG_MODSEL_LFSR: TRNG working in LFSR mode + \arg TRNG_MODSEL_NIST: TRNG working in NIST mode + \param[out] none + \retval none +*/ +void trng_mode_config(trng_modsel_enum mode_select) +{ + uint32_t trng_config = TRNG_CTL; + + trng_config &= ~TRNG_CTL_MODSEL; + trng_config |= mode_select; + TRNG_CTL = trng_config; +} + +/*! + \brief enable the TRNG post-processing module + \param[in] none + \param[out] none + \retval none +*/ +void trng_postprocessing_enable(void) +{ + TRNG_CTL |= TRNG_CTL_PPEN; +} + +/*! + \brief disable the TRNG post-processing module + \param[in] none + \param[out] none + \retval none +*/ +void trng_postprocessing_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_PPEN; +} + +/*! + \brief enable the TRNG conditioning module + \param[in] none + \param[out] none + \retval none +*/ +void trng_conditioning_enable(void) +{ + TRNG_CTL |= TRNG_CTL_CONDEN; +} + +/*! + \brief disable the TRNG conditioning module + \param[in] none + \param[out] none + \retval none +*/ +void trng_conditioning_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_CONDEN; +} + +/*! + \brief configure TRNG conditioning module input bitwidth + \param[in] input_bitwidth: the input bit width + only one parameter can be selected which is shown as below: + \arg TRNG_INMOD_256BIT: conditioning module input bitwidth 256bits + \arg TRNG_INMOD_440BIT: conditioning module input bitwidth 440bits + \param[out] none + \retval none +*/ +void trng_conditioning_input_bitwidth(trng_inmod_enum input_bitwidth) +{ + uint32_t trng_config = TRNG_CTL; + + trng_config &= ~TRNG_CTL_INMOD; + trng_config |= input_bitwidth; + TRNG_CTL = trng_config; +} + +/*! + \brief configure TRNG conditioning module output bitwidth + \param[in] output_bitwidth: + only one parameter can be selected which is shown as below: + \arg TRNG_OUTMOD_128BIT: conditioning module output bitwidth 128bits + \arg TRNG_OUTMOD_256BIT: conditioning module output bitwidth 256bits + \param[out] none + \retval none +*/ +void trng_conditioning_output_bitwidth(trng_outmod_enum output_bitwidth) +{ + uint32_t trng_config = TRNG_CTL; + + trng_config &= ~TRNG_CTL_OUTMOD; + trng_config |= (uint32_t)output_bitwidth; + TRNG_CTL = trng_config; +} + +/*! + \brief enable TRNG replace test + \param[in] none + \param[out] none + \retval none +*/ +void trng_replace_test_enable(void) +{ + TRNG_CTL |= TRNG_CTL_RTEN; +} + +/*! + \brief disable TRNG replace test + \param[in] none + \param[out] none + \retval none +*/ +void trng_replace_test_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_RTEN; +} + +/*! + \brief enable hash algorithm init when conditioning module enabled + \param[in] none + \param[out] none + \retval none +*/ +void trng_hash_init_enable(void) +{ + TRNG_CTL |= TRNG_CTL_INIT; +} + +/*! + \brief disable hash algorithm init when conditioning module enabled + \param[in] none + \param[out] none + \retval none +*/ +void trng_hash_init_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_INIT; +} + +/*! + \brief configure TRNG analog power mode + \param[in] powermode: the power mode selection + only one parameter can be selected which is shown as below: + \arg TRNG_NR_ULTRALOW: TRNG analog power mode ultralow + \arg TRNG_NR_LOW: TRNG analog power mode low + \arg TRNG_NR_MEDIUM: TRNG analog power mode medium + \arg TRNG_NR_HIGH: TRNG analog power mode high + \param[out] none + \retval none +*/ +void trng_powermode_config(uint32_t powermode) +{ + uint32_t trng_config = TRNG_CTL; + + trng_config &= ~TRNG_CTL_NR; + trng_config |= powermode; + TRNG_CTL = trng_config; +} + +/*! + \brief configure TRNG clock divider + \param[in] clkdiv: TRNG clock divider + only one parameter can be selected which is shown as below: + \arg TRNG_CLK_DIVx (x=1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768) + \param[out] none + \retval none +*/ +void trng_clockdiv_config(uint32_t clkdiv) +{ + uint32_t trng_config = TRNG_CTL; + + trng_config &= ~TRNG_CTL_CLKDIV; + trng_config |= clkdiv; + TRNG_CTL = trng_config; +} + +/*! + \brief enable the TRNG clock error detection + \param[in] none + \param[out] none + \retval none +*/ +void trng_clockerror_detection_enable(void) +{ + TRNG_CTL |= TRNG_CTL_CED; +} + +/*! + \brief disable the TRNG clock error detection + \param[in] none + \param[out] none + \retval none +*/ +void trng_clockerror_detection_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_CED; +} + +/*! + \brief get the true random data + \param[in] none + \param[out] none + \retval the generated random data +*/ +uint32_t trng_get_true_random_data(void) +{ + return (TRNG_DATA); +} + +/*! + \brief enable the conditioning logic reset + \param[in] none + \param[out] none + \retval none +*/ +void trng_conditioning_reset_enable(void) +{ + TRNG_CTL |= TRNG_CTL_CONDRST; +} + +/*! + \brief disable the conditioning logic reset + \param[in] none + \param[out] none + \retval none +*/ +void trng_conditioning_reset_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_CONDRST; +} + +/*! + \brief configure the conditioning module hash algorithm + \param[in] module_algo: module hash algorithm + only one parameter can be selected which is shown as below: + \arg TRNG_ALGO_SHA1: TRNG conditioning module hash SHA1 + \arg TRNG_ALGO_MD5: TRNG conditioning module hash MD5 + \arg TRNG_ALGO_SHA224: TRNG conditioning module hash SHA224 + \arg TRNG_ALGO_SHA256: TRNG conditioning module hash SHA256 + \param[out] none + \retval none +*/ +void trng_conditioning_algo_config(uint32_t module_algo) +{ + uint32_t tmp = TRNG_CTL; + + tmp &= ~(TRNG_CTL_ALGO); + tmp |= module_algo; + TRNG_CTL = tmp; +} + +/*! + \brief configure health tests default value + \param[in] adpo_threshold: adaptive proportion test threshold value + \param[in] rep_threshold: repetitive (00/11) test threshold value + \param[out] none + \retval none +*/ +void trng_health_tests_config(uint32_t adpo_threshold, uint8_t rep_threshold) +{ + uint32_t tmp = TRNG_HTCFG; + + tmp &= ~(TRNG_HTCFG_APTTH | TRNG_HTCFG_RCTTH); + tmp |= (((uint32_t)(adpo_threshold << 16U) & TRNG_HTCFG_APTTH) | (rep_threshold & TRNG_HTCFG_RCTTH)); + TRNG_HTCFG = tmp; +} + +/*! + \brief get the TRNG status flags + \param[in] flag: TRNG status flag, refer to trng_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_FLAG_DRDY: random data ready status + \arg TRNG_FLAG_CECS: clock error current status + \arg TRNG_FLAG_SECS: seed error current status + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus trng_flag_get(trng_flag_enum flag) +{ + if(RESET != (TRNG_STAT & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief enable the TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_enable(void) +{ + TRNG_CTL |= TRNG_CTL_IE; +} + +/*! + \brief disable the TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_IE; +} + +/*! + \brief get the TRNG interrupt flags + \param[in] int_flag: TRNG interrupt flag, refer to trng_int_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag + \arg TRNG_INT_FLAG_SEIF: seed error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag) +{ + if(RESET != (TRNG_STAT & int_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the TRNG interrupt flags + \param[in] int_flag: TRNG interrupt flag, refer to trng_int_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag + \arg TRNG_INT_FLAG_SEIF: seed error interrupt flag + \param[out] none + \retval none +*/ +void trng_interrupt_flag_clear(trng_int_flag_enum int_flag) +{ + TRNG_STAT &= ~(uint32_t)int_flag; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_usart.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_usart.c new file mode 100644 index 0000000000..98f553f487 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_usart.c @@ -0,0 +1,1534 @@ +/*! + \file gd32h7xx_usart.c + \brief USART driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_usart.h" + +/* USART register bit offset */ +#define CTL1_ADDR0_OFFSET ((uint32_t)24U) /* bit offset of ADDR0 in USART_CTL1 */ +#define CTL2_ADDR1_OFFSET ((uint32_t)24U) /* bit offset of ADDR1 in USART_CTL2 */ +#define GP_GUAT_OFFSET ((uint32_t)8U) /* bit offset of GUAT in USART_GP */ +#define CTL2_SCRTNUM_OFFSET ((uint32_t)17U) /* bit offset of SCRTNUM in USART_CTL2 */ +#define RT_BL_OFFSET ((uint32_t)24U) /* bit offset of BL in USART_RT */ +#define CTL0_DEA_OFFSET ((uint32_t)21U) /* bit offset of DEA in USART_CTL0 */ +#define CTL0_DED_OFFSET ((uint32_t)16U) /* bit offset of DED in USART_CTL0 */ +#define FCS_RFCNT_3_4_OFFSET ((uint32_t)3U) /* bit offset of RFCNT[4:3] in USART_FCS */ + +/*! + \brief reset USART + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph){ + case USART0: + /* reset USART0 */ + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + /* reset USART1 */ + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + case USART2: + /* reset USART2 */ + rcu_periph_reset_enable(RCU_USART2RST); + rcu_periph_reset_disable(RCU_USART2RST); + break; + case UART3: + /* reset UART3 */ + rcu_periph_reset_enable(RCU_UART3RST); + rcu_periph_reset_disable(RCU_UART3RST); + break; + case UART4: + /* reset UART4 */ + rcu_periph_reset_enable(RCU_UART4RST); + rcu_periph_reset_disable(RCU_UART4RST); + break; + case USART5: + /* reset USART5 */ + rcu_periph_reset_enable(RCU_USART5RST); + rcu_periph_reset_disable(RCU_USART5RST); + break; + case UART6: + /* reset UART6 */ + rcu_periph_reset_enable(RCU_UART6RST); + rcu_periph_reset_disable(RCU_UART6RST); + break; + case UART7: + /* reset UART7 */ + rcu_periph_reset_enable(RCU_UART7RST); + rcu_periph_reset_disable(RCU_UART7RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] baudval: baud rate value + \param[out] none + \retval none +*/ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval) +{ + uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U; + switch(usart_periph){ + /* get clock frequency */ + case USART0: + /* get USART0 clock */ + uclk = rcu_clock_freq_get(CK_USART0); + break; + case USART1: + /* get USART1 clock */ + uclk = rcu_clock_freq_get(CK_USART1); + break; + case USART2: + /* get USART2 clock */ + uclk = rcu_clock_freq_get(CK_USART2); + break; + case UART3: + /* get UART3 clock */ + uclk = rcu_clock_freq_get(CK_APB1); + break; + case UART4: + /* get UART4 clock */ + uclk = rcu_clock_freq_get(CK_APB1); + break; + case USART5: + /* get USART5 clock */ + uclk = rcu_clock_freq_get(CK_USART5); + break; + case UART6: + /* get UART6 clock */ + uclk = rcu_clock_freq_get(CK_APB1); + break; + case UART7: + /* get UART7 clock */ + uclk = rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + /* oversampling by 8, configure the value of USART_BAUD */ + udiv = ((2U * uclk) + baudval / 2U) / baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = (udiv >> 1U) & 0x00000007U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + }else{ + /* oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk + baudval / 2U) / baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = udiv & 0x0000000fU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] paritycfg: USART parity configure + only one parameter can be selected which is shown as below: + \arg USART_PM_NONE: no parity + \arg USART_PM_ODD: odd parity + \arg USART_PM_EVEN: even parity + \param[out] none + \retval none +*/ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 PM, PCEN bits */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); + /* configure USART parity mode */ + USART_CTL0(usart_periph) |= paritycfg; +} + +/*! + \brief configure USART word length + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] wlen: USART word length configure + only one parameter can be selected which is shown as below: + \arg USART_WL_8BIT : 8 bits + \arg USART_WL_9BIT : 9 bits + \arg USART_WL_7BIT : 7 bits + \arg USART_WL_10BIT: 10 bits + \param[out] none + \retval none +*/ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 WL bit */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_WL0 | USART_CTL0_WL1); + /* configure USART word length */ + USART_CTL0(usart_periph) |= wlen; +} + +/*! + \brief configure USART stop bit length + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] stblen: USART stop bit configure + only one parameter can be selected which is shown as below: + \arg USART_STB_1BIT: 1 bit + \arg USART_STB_0_5BIT: 0.5bit + \arg USART_STB_2BIT: 2 bits + \arg USART_STB_1_5BIT: 1.5bit + \param[out] none + \retval none +*/ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL1 STB bits */ + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + USART_CTL1(usart_periph) |= stblen; +} + +/*! + \brief enable USART + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UEN; +} + +/*! + \brief disable USART + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); +} + +/*! + \brief configure USART transmitter + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] txconfig: enable or disable USART transmitter + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_ENABLE: enable USART transmission + \arg USART_TRANSMIT_DISABLE: enable USART transmission + \param[out] none + \retval none +*/ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_TEN; + /* configure transfer mode */ + USART_CTL0(usart_periph) |= txconfig; +} + +/*! + \brief configure USART receiver + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] rxconfig: enable or disable USART receiver + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_ENABLE: enable USART reception + \arg USART_RECEIVE_DISABLE: disable USART reception + \param[out] none + \retval none +*/ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_REN; + /* configure receiver mode */ + USART_CTL0(usart_periph) |= rxconfig; +} + +/*! + \brief data is transmitted/received with the LSB/MSB first + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] msbf: LSB/MSB + only one parameter can be selected which is shown as below: + \arg USART_MSBF_LSB: LSB first + \arg USART_MSBF_MSB: MSB first + \param[out] none + \retval none +*/ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* configure LSB or MSB first */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_MSBF); + USART_CTL1(usart_periph) |= (USART_CTL1_MSBF & msbf); +} + +/*! + \brief USART inverted configure + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] invertpara: refer to usart_invert_enum + only one parameter can be selected which is shown as below: + \arg USART_DINV_ENABLE: data bit level inversion + \arg USART_DINV_DISABLE: data bit level not inversion + \arg USART_TXPIN_ENABLE: TX pin level inversion + \arg USART_TXPIN_DISABLE: TX pin level not inversion + \arg USART_RXPIN_ENABLE: RX pin level inversion + \arg USART_RXPIN_DISABLE: RX pin level not inversion + \arg USART_SWAP_ENABLE: swap TX/RX pins + \arg USART_SWAP_DISABLE: not swap TX/RX pins + \param[out] none + \retval none +*/ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* inverted or not the specified signal */ + switch(invertpara){ + case USART_DINV_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_DINV; + break; + case USART_DINV_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_DINV); + break; + case USART_TXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_TINV; + break; + case USART_TXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_TINV); + break; + case USART_RXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_RINV; + break; + case USART_RXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_RINV); + break; + case USART_SWAP_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_STRP; + break; + case USART_SWAP_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_STRP); + break; + default: + break; + } +} + +/*! + \brief enable the USART overrun function + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_overrun_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* enable overrun function */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_OVRD); +} + +/*! + \brief disable the USART overrun function + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_overrun_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* disable overrun function */ + USART_CTL2(usart_periph) |= USART_CTL2_OVRD; +} + +/*! + \brief configure the USART oversample mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] oversamp: oversample value + only one parameter can be selected which is shown as below: + \arg USART_OVSMOD_8: oversampling by 8 + \arg USART_OVSMOD_16: oversampling by 16 + \param[out] none + \retval none +*/ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear OVSMOD bit */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD); + USART_CTL0(usart_periph) |= oversamp; +} + +/*! + \brief configure the sample bit method + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] osb: sample bit + only one parameter can be selected which is shown as below: + \arg USART_OSB_1BIT: 1 bit + \arg USART_OSB_3BIT: 3 bits + \param[out] none + \retval none +*/ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); + USART_CTL2(usart_periph) |= osb; +} + +/*! + \brief enable receiver timeout + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_RTEN; +} + +/*! + \brief disable receiver timeout + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN); +} + +/*! + \brief configure receiver timeout threshold + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] rtimeout: 0x00000000-0x00FFFFFF, receiver timeout value in terms of number of baud clocks + \param[out] none + \retval none +*/ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout) +{ + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= rtimeout; +} + +/*! + \brief USART transmit data function + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint16_t data) +{ + USART_TDATA(usart_periph) = USART_TDATA_TDATA & (uint32_t)data; +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval data of received +*/ +uint16_t usart_data_receive(uint32_t usart_periph) +{ + return (uint16_t)(GET_BITS(USART_RDATA(usart_periph), 0U, 8U)); +} + +/*! + \brief enable USART command + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] cmdtype: command type + only one parameter can be selected which is shown as below: + \arg USART_CMD_SBKCMD: send break command + \arg USART_CMD_MMCMD: mute mode command + \arg USART_CMD_RXFCMD: receive data flush command + \arg USART_CMD_TXFCMD: transmit data flush request + \param[out] none + \retval none +*/ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype) +{ + USART_CMD(usart_periph) |= (cmdtype); +} + +/*! + \brief enable address 0 match mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_address_0_match_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_AMEN0; +} + +/*! + \brief disable address 0 match mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_address_0_match_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_AMEN0); +} + +/*! + \brief enable address 1 match mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_address_1_match_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_AMEN1; +} + +/*! + \brief disable address 1 match mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_address_1_match_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_AMEN1); +} + +/*! + \brief configure address 0 of the USART + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] addr: 0x00-0xFF, address of USART terminal + \param[out] none + \retval none +*/ +void usart_address_0_config(uint32_t usart_periph, uint8_t addr) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR0); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR0 & (((uint32_t)addr) << CTL1_ADDR0_OFFSET)); +} + +/*! + \brief configure address 1 of the USART + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] addr: 0x00-0xFF, address of USART terminal + \param[out] none + \retval none +*/ +void usart_address_1_config(uint32_t usart_periph, uint8_t addr) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_ADDR1); + USART_CTL2(usart_periph) |= (USART_CTL2_ADDR1 & (((uint32_t)addr) << CTL2_ADDR1_OFFSET)); +} + +/*! + \brief configure address 0 detection mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] addmod: address detection mode + only one parameter can be selected which is shown as below: + \arg USART_ADDM0_4BIT: 4 bits + \arg USART_ADDM0_FULLBIT: full bits + \param[out] none + \retval none +*/ +void usart_address_0_detection_mode_config(uint32_t usart_periph, uint32_t addmod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDM0); + USART_CTL1(usart_periph) |= USART_CTL1_ADDM0 & (addmod); +} + +/*! + \brief configure address 1 detection mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] addmod: address detection mode + only one parameter can be selected which is shown as below: + \arg USART_ADDM1_4BIT: 4 bits + \arg USART_ADDM1_FULLBIT: full bits + \param[out] none + \retval none +*/ +void usart_address_1_detection_mode_config(uint32_t usart_periph, uint32_t addmod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_ADDM1); + USART_CTL2(usart_periph) |= USART_CTL2_ADDM1 & (addmod); +} + +/*! + \brief enable mute mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_MEN; +} + +/*! + \brief disable mute mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_MEN); +} + +/*! + \brief configure wakeup method in mute mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] wmethod: two methods be used to enter or exit the mute mode + only one parameter can be selected which is shown as below: + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mark + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmethod; +} + +/*! + \brief enable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief LIN break detection length + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] lblen: LIN break detection length + only one parameter can be selected which is shown as below: + \arg USART_LBLEN_10B: 10 bits break detection + \arg USART_LBLEN_11B: 11 bits break detection + \param[out] none + \retval none +*/ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= USART_CTL1_LBLEN & (lblen); +} + +/*! + \brief enable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_halfduplex_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_HDEN; +} + +/*! + \brief disable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_halfduplex_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable clock + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_clock_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable clock + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_clock_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN); +} + +/*! + \brief configure USART synchronous mode parameters + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] clen: last bit clock pulse + only one parameter can be selected which is shown as below: + \arg USART_CLEN_NONE: clock pulse of the last data bit (MSB) is not output to the CK pin + \arg USART_CLEN_EN: clock pulse of the last data bit (MSB) is output to the CK pin + \param[in] cph: clock phase + only one parameter can be selected which is shown as below: + \arg USART_CPH_1CK: first clock transition is the first data capture edge + \arg USART_CPH_2CK: second clock transition is the first data capture edge + \param[in] cpl: clock polarity + only one parameter can be selected which is shown as below: + \arg USART_CPL_LOW: steady low value on CK pin + \arg USART_CPL_HIGH: steady high value on CK pin + \param[out] none + \retval none +*/ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset USART_CTL1 CLEN,CPH,CPL bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + + USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen); + USART_CTL1(usart_periph) |= (USART_CTL1_CPH & cph); + USART_CTL1(usart_periph) |= (USART_CTL1_CPL & cpl); +} + +/*! + \brief configure guard time value in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] guat: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat) << GP_GUAT_OFFSET)); +} + +/*! + \brief enable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief disable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief enable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief disable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief enable early NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph) +{ + USART_FCS(usart_periph) |= USART_FCS_ELNACK; +} + +/*! + \brief disable early NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph) +{ + USART_FCS(usart_periph) &= ~USART_FCS_ELNACK; +} + +/*! + \brief configure smartcard auto-retry number + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] scrtnum: 0x00000000-0x00000007, smartcard auto-retry number + \param[out] none + \retval none +*/ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCRTNUM); + USART_CTL2(usart_periph) |= (USART_CTL2_SCRTNUM & (scrtnum << CTL2_SCRTNUM_OFFSET)); +} + +/*! + \brief configure block length + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] bl: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << RT_BL_OFFSET)); +} + +/*! + \brief enable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power or SmartCard mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] psc: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= psc; +} + +/*! + \brief configure IrDA low-power + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] irlp: IrDA low-power or normal + only one parameter can be selected which is shown as below: + \arg USART_IRLP_LOW: low-power + \arg USART_IRLP_NORMAL: normal + \param[out] none + \retval none +*/ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP); + USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp); +} + +/*! + \brief configure hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] rtsconfig: enable or disable RTS + only one parameter can be selected which is shown as below: + \arg USART_RTS_ENABLE: enable RTS + \arg USART_RTS_DISABLE: disable RTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN); + USART_CTL2(usart_periph) |= rtsconfig; +} + +/*! + \brief configure hardware flow control CTS + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] ctsconfig: enable or disable CTS + only one parameter can be selected which is shown as below: + \arg USART_CTS_ENABLE: enable CTS + \arg USART_CTS_DISABLE: disable CTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~USART_CTL2_CTSEN; + USART_CTL2(usart_periph) |= ctsconfig; +} + + /*! + \brief configure hardware flow control coherence mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] hcm: + only one parameter can be selected which is shown as below: + \arg USART_HCM_NONE: nRTS signal equals to the rxne status register + \arg USART_HCM_EN: nRTS signal is set when the last data bit has been sampled + \param[out] none + \retval none +*/ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_HCM); + USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm); +} + +/*! + \brief enable RS485 driver + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_rs485_driver_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_DEM; +} + +/*! + \brief disable RS485 driver + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_rs485_driver_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEM); +} + +/*! + \brief configure driver enable assertion time + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] deatime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DEA); + USART_CTL0(usart_periph) |= (USART_CTL0_DEA & ((deatime) << CTL0_DEA_OFFSET)); +} + +/*! + \brief configure driver enable de-assertion time + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] dedtime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DED); + USART_CTL0(usart_periph) |= (USART_CTL0_DED & ((dedtime) << CTL0_DED_OFFSET)); +} + +/*! + \brief configure driver enable polarity mode + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] dep: DE signal + only one parameter can be selected which is shown as below: + \arg USART_DEP_HIGH: DE signal is active high + \arg USART_DEP_LOW: DE signal is active low + \param[out] none + \retval none +*/ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset DEP bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEP); + USART_CTL2(usart_periph) |= (USART_CTL2_DEP & dep); +} + +/*! + \brief configure USART DMA reception + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] dmacmd: enable or disable DMA for reception + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_DMA_ENABLE: USART enable DMA for reception + \arg USART_RECEIVE_DMA_DISABLE: USART disable DMA for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_DENR; + ctl |= dmacmd; + /* configure DMA reception */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] dmacmd: enable or disable DMA for transmission + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_DMA_ENABLE: USART enable DMA for transmission + \arg USART_TRANSMIT_DMA_DISABLE: USART disable DMA for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL2(usart_periph); + ctl &= ~USART_CTL2_DENT; + ctl |= dmacmd; + /* configure DMA transmission */ + USART_CTL2(usart_periph) = ctl; +} + +/*! + \brief disable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_DDRE; +} + +/*! + \brief enable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_DDRE); +} + +/*! + \brief enable USART to wakeup the mcu from deep-sleep mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_wakeup_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UESM; +} + +/*! + \brief disable USART to wakeup the mcu from deep-sleep mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_wakeup_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM); +} + +/*! + \brief configure the USART wakeup mode from deep-sleep mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] wum: wakeup mode + only one parameter can be selected which is shown as below: + \arg USART_WUM_ADDR: WUF active on address match + \arg USART_WUM_STARTB: WUF active on start bit + \arg USART_WUM_RBNE: WUF active on RBNE + \param[out] none + \retval none +*/ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset WUM bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_WUM); + USART_CTL2(usart_periph) |= USART_CTL2_WUM & (wum); +} + +/*! + \brief enable FIFO + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_fifo_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* set FEN bit */ + USART_FCS(usart_periph) |= USART_FCS_FEN; +} + +/*! + \brief disable FIFO + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_fifo_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset FEN bit */ + USART_FCS(usart_periph) &= ~(USART_FCS_FEN); +} + +/*! + \brief configure transmit FIFO threshold + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] txthreshold: transmit FIFO threshold + only one parameter can be selected which is shown as below: + \arg USART_TFTCFG_THRESHOLD_1_8: transmit FIFO reaches 1/8 of its depth + \arg USART_TFTCFG_THRESHOLD_1_4: transmit FIFO reaches 1/4 of its depth + \arg USART_TFTCFG_THRESHOLD_1_2: transmit FIFO reaches 1/2 of its depth + \arg USART_TFTCFG_THRESHOLD_3_4: transmit FIFO reaches 3/4 of its depth + \arg USART_TFTCFG_THRESHOLD_7_8: transmit FIFO reaches 7/8 of its depth + \arg USART_TFTCFG_THRESHOLD_EMPTY: transmit FIFO becomes empty + \param[out] none + \retval none +*/ +void usart_transmit_fifo_threshold_config(uint32_t usart_periph, uint32_t txthreshold) +{ + USART_FCS(usart_periph) &= ~(USART_FCS_TFTCFG); + USART_FCS(usart_periph) |= txthreshold; +} + +/*! + \brief configure receive FIFO threshold + \param[in] usart_periph: receive FIFO threshold + only one parameter can be selected which is shown as below: + \arg USART_RFTCFG_THRESHOLD_1_8: receive FIFO reaches 1/8 of its depth + \arg USART_RFTCFG_THRESHOLD_1_4: receive FIFO reaches 1/4 of its depth + \arg USART_RFTCFG_THRESHOLD_1_2: receive FIFO reaches 1/2 of its depth + \arg USART_RFTCFG_THRESHOLD_3_4: receive FIFO reaches 3/4 of its depth + \arg USART_RFTCFG_THRESHOLD_7_8: receive FIFO reaches 7/8 of its depth + \arg USART_RFTCFG_THRESHOLD_FULL: receive FIFO becomes full + \param[out] none + \retval none +*/ +void usart_receive_fifo_threshold_config(uint32_t usart_periph, uint32_t rxthreshold) +{ + USART_FCS(usart_periph) &= ~(USART_FCS_RFTCFG); + USART_FCS(usart_periph) |= rxthreshold; +} + +/*! + \brief read receive FIFO counter number + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[out] none + \retval uint8_t: receive FIFO counter number +*/ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph) +{ + uint32_t cnt = 0U; + + cnt |= GET_BITS(USART_FCS(usart_periph), 12U, 14U); + cnt |= (GET_BITS(USART_FCS(usart_periph), 1U, 2U) << FCS_RFCNT_3_4_OFFSET); + + return (uint8_t)(cnt); +} + +/*! + \brief get flag in STAT/CHC/FCS register + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_RFNE: receive FIFO not empty(when FIFO is enabled) + \arg USART_FLAG_RBNE: read data buffer not empty(when FIFO is disabled) + \arg USART_FLAG_TC: transmission completed + \arg USART_FLAG_TFNF: transmit FIFO not full(when FIFO is enabled) + \arg USART_FLAG_TBE: transmit data register empty(when FIFO is disabled) + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_CTS: CTS level + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_AM0: address 0 match flag + \arg USART_FLAG_AM1: address 1 match flag + \arg USART_FLAG_SB: send break flag + \arg USART_FLAG_RWU: receiver wakeup from mute mode. + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_TEA: transmit enable acknowledge flag + \arg USART_FLAG_REA: receive enable acknowledge flag + \arg USART_FLAG_EPERR: early parity error flag + \arg USART_FLAG_RFE: receive FIFO empty flag + \arg USART_FLAG_RFF: receive FIFO full flag + \arg USART_FLAG_TFT: transmit FIFO threshold flag + \arg USART_FLAG_TFE: transmit FIFO empty flag + \arg USART_FLAG_TFF: transmit FIFO full flag + \arg USART_FLAG_RFT: receive FIFO threshold flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) +{ + if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART status + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise detected flag + \arg USART_FLAG_ORERR: overrun error flag + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_TC: transmission complete flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_AM0: address 0 match flag + \arg USART_FLAG_AM1: address 1 match flag + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_EPERR: early parity error flag + \arg USART_FLAG_TFE: transmit FIFO empty flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + if(USART_FLAG_AM1 == flag){ + USART_INTC(usart_periph) |= USART_INTC_AMC1; + }else if(USART_FLAG_EPERR == flag){ + USART_CHC(usart_periph) &= (uint32_t)(~USART_CHC_EPERR); + }else if(USART_FLAG_TFE == flag){ + USART_FCS(usart_periph) |= USART_FCS_TFEC; + }else{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); + } +} + +/*! + \brief enable USART interrupt + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] interrupt: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RFNE: receive FIFO not empty interrupt and overrun error interrupt(when FIFO is enabled) + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt enable interrupt(when FIFO is disabled) + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TFNF: transmit FIFO not full interrupt(when FIFO is enabled) + \arg USART_INT_TBE: transmit data register empty interrupt(when FIFO is disabled) + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM0: address 0 match interrupt + \arg USART_INT_AM1: address 1 match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_TFE: transmit FIFO empty interrupt + \arg USART_INT_TFT: transmit FIFO threshold interrupt + \arg USART_INT_RFT: receive FIFO threshold interrupt + \arg USART_INT_RFF: receive FIFO full interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt) +{ + USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt)); +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] interrupt: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RFNE: receive FIFO not empty interrupt and overrun error interrupt(when FIFO is enabled) + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt enable interrupt(when FIFO is disabled) + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TFNF: transmit FIFO not full interrupt(when FIFO is enabled) + \arg USART_INT_TBE: transmit data register empty interrupt(when FIFO is disabled) + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM0: address 0 match interrupt + \arg USART_INT_AM1: address 1 match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_TFE: transmit FIFO empty interrupt + \arg USART_INT_TFT: transmit FIFO threshold interrupt + \arg USART_INT_RFT: receive FIFO threshold interrupt + \arg USART_INT_RFF: receive FIFO full interrupt + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt) +{ + USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt)); +} + +/*! + \brief get USART interrupt and flag status + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_EB: end of block interrupt and flag + \arg USART_INT_FLAG_RT: receiver timeout interrupt and flag + \arg USART_INT_FLAG_AM0: address 0 match interrupt and flag + \arg USART_INT_FLAG_AM1: address 1 match interrupt and flag + \arg USART_INT_FLAG_PERR: parity error interrupt and flag + \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag(when FIFO is disabled) + \arg USART_INT_FLAG_TFNF: transmit FIFO not full interrupt and flag(when FIFO is enabled) + \arg USART_INT_FLAG_TC: transmission complete interrupt and flag + \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag(when FIFO is disabled) + \arg USART_INT_FLAG_RFNE: receive FIFO not empty interrupt and flag(when FIFO is enabled) + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag(when FIFO is disabled) + \arg USART_INT_FLAG_RFNE_ORERR: receive FIFO not empty interrupt and overrun error flag(when FIFO is enabled) + \arg USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag + \arg USART_INT_FLAG_LBD: LIN break detected interrupt and flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt and flag + \arg USART_INT_FLAG_CTS: CTS interrupt and flag + \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag + \arg USART_INT_FLAG_TFT: transmit FIFO threshold interrupt and flag + \arg USART_INT_FLAG_TFE: transmit FIFO empty interrupt and flag + \arg USART_INT_FLAG_RFT: receive FIFO threshold interrupt and flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag))); + + if(flagstatus && intenable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART interrupt flag + \param[in] usart_periph: USARTx(x=0,1,2,5), UARTx(x=3,4,6,7) + \param[in] flag: USART interrupt flag + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_PERR: parity error flag + \arg USART_INT_FLAG_ERR_FERR: frame error flag + \arg USART_INT_FLAG_ERR_NERR: noise detected flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_IDLE: idle line detected flag + \arg USART_INT_FLAG_TC: transmission complete flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_RT: receiver timeout flag + \arg USART_INT_FLAG_EB: end of block flag + \arg USART_INT_FLAG_AM0: address 0 match flag + \arg USART_INT_FLAG_AM1: address 1 match flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_INT_FLAG_RFT: receive FIFO threshold reach interrupt and flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \arg USART_INT_FLAG_TFE: transmit FIFO empty interrupt and flag + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + if(USART_INT_FLAG_TFE == int_flag){ + USART_FCS(usart_periph) |= USART_FCS_TFEC; + }else if(USART_INT_FLAG_RFF == int_flag){ + USART_FCS(usart_periph) &= (uint32_t)(~USART_FCS_RFFIF); + }else if(USART_INT_FLAG_RFT == int_flag){ + USART_FCS(usart_periph) &= (uint32_t)(~USART_FCS_RFTIF); + }else{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(int_flag)); + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_vref.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_vref.c new file mode 100644 index 0000000000..6ff2f99005 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_vref.c @@ -0,0 +1,153 @@ +/*! + \file gd32h7xx_vref.c + \brief VREF driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32h7xx_vref.h" + +/*! + \brief deinitialize the VREF + \param[in] none + \param[out] none + \retval none +*/ +void vref_deinit(void) +{ + rcu_periph_reset_enable(RCU_VREFRST); + rcu_periph_reset_disable(RCU_VREFRST); +} + +/*! + \brief enable VREF + \param[in] none + \param[out] none + \retval none +*/ +void vref_enable(void) +{ + VREF_CS |= VREF_EN; +} + +/*! + \brief disable VREF + \param[in] none + \param[out] none + \retval none +*/ +void vref_disable(void) +{ + VREF_CS &= (uint32_t)~VREF_EN; +} + +/*! + \brief enable VREF high impendance mode + \param[in] none + \param[out] none + \retval none +*/ +void vref_high_impedance_mode_enable(void) +{ + VREF_CS |= VREF_HIGH_IMPEDANCE_MODE; +} + +/*! + \brief disable VREF high impendance mode + \param[in] none + \param[out] none + \retval none +*/ +void vref_high_impedance_mode_disable(void) +{ + VREF_CS &= (uint32_t)~VREF_HIGH_IMPEDANCE_MODE; +} + +/*! + \brief get the status of VREF + \param[in] none + \param[out] none + \retval the status of VREF output + \arg SET: the VREF output is ready + \arg RESET: the VREF output is not ready +*/ +FlagStatus vref_status_get(void) +{ + if(RESET != (VREF_CS & (uint32_t)VREF_CS_VREFRDY)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief select the VREF voltage reference + \param[in] vref_voltage: voltage reference select, + only one parameter can be selected which is shown as below: + \arg VREF_VOLTAGE_SEL_2_5V: VREF voltage reference select 2.5 V + \arg VREF_VOLTAGE_SEL_2_048V: VREF voltage reference select 2.048 V + \arg VREF_VOLTAGE_SEL_1_8V: VREF voltage reference select 1.8 V + \arg VREF_VOLTAGE_SEL_1_5V: VREF voltage reference select 1.5 V + \param[out] none + \retval none +*/ +void vref_voltage_select(uint32_t vref_voltage) +{ + uint32_t temp = VREF_CS; + + /* clear old value */ + temp &= ~(uint32_t)VREF_VOLTAGE_SEL_1_5V; + temp |= (uint32_t)vref_voltage; + + VREF_CS = temp; +} + +/*! + \brief set the calibration value of VREF + \param[in] value: calibration value (0x00 - 0x3F) + \param[out] none + \retval none +*/ +void vref_calib_value_set(uint8_t value) +{ + VREF_CALIB = (uint32_t)(VREF_CALIB_VREFCAL & value); +} + +/*! + \brief get the calibration value of VREF + \param[in] none + \param[out] none + \retval calibration value (0x00 - 0x3F) +*/ +uint8_t vref_calib_value_get(void) +{ + uint8_t temp = (uint8_t)VREF_CALIB; + return temp; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_wwdgt.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_wwdgt.c new file mode 100644 index 0000000000..780e65d499 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_standard_peripheral/Source/gd32h7xx_wwdgt.c @@ -0,0 +1,131 @@ +/*! + \file gd32h7xx_wwdgt.c + \brief WWDGT driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + + +#include "gd32h7xx_wwdgt.h" + +/* WWDGT_CTL register value */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) +/* WWDGT_CFG register value */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) + +/*! + \brief reset the window watchdog timer configuration + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_deinit(void) +{ + rcu_periph_reset_enable(RCU_WWDGTRST); + rcu_periph_reset_disable(RCU_WWDGTRST); +} + +/*! + \brief start the WWDGT counter + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure the WWDGT counter value + \param[in] counter_value: 0x00 - 0x7F + \param[out] none + \retval none +*/ +void wwdgt_counter_update(uint16_t counter_value) +{ + WWDGT_CTL = (uint32_t)(CTL_CNT(counter_value)); +} + +/*! + \brief configure counter value, window value, and prescaler divider value + \param[in] counter: 0x0000 - 0x007F + \param[in] window: 0x0000 - 0x007F + \param[in] prescaler: WWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK3/4096)/1 + \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK3/4096)/2 + \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK3/4096)/4 + \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK3/4096)/8 + \param[out] none + \retval none +*/ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler) +{ + WWDGT_CTL = (uint32_t)(CTL_CNT(counter)); + WWDGT_CFG = (uint32_t)(CFG_WIN(window) | prescaler); +} + +/*! + \brief enable early wakeup interrupt of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_interrupt_enable(void) +{ + WWDGT_CFG |= WWDGT_CFG_EWIE; +} + +/*! + \brief check early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus wwdgt_flag_get(void) +{ + if (RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)){ + return SET; + } + + return RESET; +} + +/*! + \brief clear early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_flag_clear(void) +{ + WWDGT_STAT = (uint32_t)RESET; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_core.h new file mode 100644 index 0000000000..72090e92a3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_core.h @@ -0,0 +1,320 @@ +/*! + \file audio_core.h + \brief the header file of USB audio device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __AUDIO_CORE_H +#define __AUDIO_CORE_H + +#include "usbd_enum.h" + +#define FORMAT_24BIT(x) (uint8_t)(x);(uint8_t)((x) >> 8U);(uint8_t)((x) >> 16U) + +/* number of sub-packets in the audio transfer buffer. you can modify this value but always make sure + that it is an even number and higher than 3 */ +#define OUT_PACKET_NUM 200U + +/* total size of the audio transfer buffer */ +#define OUT_BUF_MARGIN 0U +#define TOTAL_OUT_BUF_SIZE ((uint32_t)((SPEAKER_OUT_PACKET + OUT_BUF_MARGIN) * OUT_PACKET_NUM)) + +#define AD_CONFIG_DESC_SET_LEN (sizeof(usb_desc_config_set)) +#define AD_INTERFACE_DESC_SIZE 9U + +#define USB_AD_DESC_SIZ 0x09U +#define AD_STANDARD_EP_DESC_SIZE 0x09U +#define AD_STREAMING_EP_DESC_SIZE 0x07U + +/* audio interface class code */ +#define USB_CLASS_AUDIO 0x01U + +/* audio interface subclass codes */ +#define AD_SUBCLASS_CONTROL 0x01U +#define AD_SUBCLASS_AUDIOSTREAMING 0x02U +#define AD_SUBCLASS_MIDISTREAMING 0x03U + +/* audio interface protocol codes */ +#define AD_PROTOCOL_UNDEFINED 0x00U +#define AD_STREAMING_GENERAL 0x01U +#define AD_STREAMING_FORMAT_TYPE 0x02U + +/* audio class-specific descriptor types */ +#define AD_DESCTYPE_UNDEFINED 0x20U +#define AD_DESCTYPE_DEVICE 0x21U +#define AD_DESCTYPE_CONFIGURATION 0x22U +#define AD_DESCTYPE_STRING 0x23U +#define AD_DESCTYPE_INTERFACE 0x24U +#define AD_DESCTYPE_ENDPOINT 0x25U + +/* audio control interface descriptor subtypes */ +#define AD_CONTROL_HEADER 0x01U +#define AD_CONTROL_INPUT_TERMINAL 0x02U +#define AD_CONTROL_OUTPUT_TERMINAL 0x03U +#define AD_CONTROL_MIXER_UNIT 0x04U +#define AD_CONTROL_SELECTOR_UNIT 0x05U +#define AD_CONTROL_FEATURE_UNIT 0x06U +#define AD_CONTROL_PROCESSING_UNIT 0x07U +#define AD_CONTROL_EXTENSION_UNIT 0x08U + +#define AD_INPUT_TERMINAL_DESC_SIZE 0x0CU +#define AD_OUTPUT_TERMINAL_DESC_SIZE 0x09U +#define AD_STREAMING_INTERFACE_DESC_SIZE 0x07U + +#define AD_CONTROL_MUTE 0x01U +#define AD_CONTROL_VOLUME 0x02U + +#define AD_FORMAT_TYPE_I 0x01U +#define AD_FORMAT_TYPE_III 0x03U + +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01U +#define AD_ENDPOINT_GENERAL 0x01U + +#define AD_REQ_UNDEFINED 0x00U +#define AD_REQ_SET_CUR 0x01U +#define AD_REQ_GET_CUR 0x81U +#define AD_REQ_SET_MIN 0x02U +#define AD_REQ_GET_MIN 0x82U +#define AD_REQ_SET_MAX 0x03U +#define AD_REQ_GET_MAX 0x83U +#define AD_REQ_SET_RES 0x04U +#define AD_REQ_GET_RES 0x84U +#define AD_REQ_SET_MEM 0x05U +#define AD_REQ_GET_MEM 0x85U +#define AD_REQ_GET_STAT 0xFFU + +#define AD_OUT_STREAMING_CTRL 0x05U +#define AD_IN_STREAMING_CTRL 0x02U + +/* audio stream interface number */ +enum +{ +#ifdef USE_USB_AD_MICPHONE + MIC_INTERFACE_COUNT, +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + SPEAK_INTERFACE_COUNT, +#endif /* USE_USB_AD_SPEAKER */ + CONFIG_DESC_AS_ITF_COUNT, +}; + +#define AC_ITF_TOTAL_LEN (sizeof(usb_desc_AC_itf) + CONFIG_DESC_AS_ITF_COUNT*(sizeof(usb_desc_input_terminal) + \ + sizeof(usb_desc_mono_feature_unit) + sizeof(usb_desc_output_terminal))) + +#pragma pack(1) + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< header descriptor subtype */ + uint16_t bcdADC; /*!< audio device class specification release number in binary-coded decimal */ + uint16_t wTotalLength; /*!< total number of bytes */ + uint8_t bInCollection; /*!< the number of the streaming interfaces */ +#ifdef USE_USB_AD_MICPHONE + uint8_t baInterfaceNr0; /*!< interface number of the streaming interfaces */ +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + uint8_t baInterfaceNr1; /*!< interface number of the streaming interfaces */ +#endif /* USE_USB_AD_SPEAKER */ +} usb_desc_AC_itf; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< AS_GENERAL descriptor subtype */ + uint8_t bTerminalLink; /*!< the terminal ID */ + uint8_t bDelay; /*!< delay introduced by the data path */ + uint16_t wFormatTag; /*!< the audio data format */ +} usb_desc_AS_itf; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< INPUT_TERMINAL descriptor subtype. */ + uint8_t bTerminalID; /*!< constant uniquely identifying the terminal within the audio function */ + uint16_t wTerminalType; /*!< constant characterizing the type of terminal */ + uint8_t bAssocTerminal; /*!< ID of the output terminal */ + uint8_t bNrChannels; /*!< number of logical output channels */ + uint16_t wChannelConfig; /*!< describes the spatial location of the logical channels */ + uint8_t iChannelNames; /*!< index of a string descriptor */ + uint8_t iTerminal; /*!< index of a string descriptor */ +} usb_desc_input_terminal; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< OUTPUT_TERMINAL descriptor subtype */ + uint8_t bTerminalID; /*!< constant uniquely identifying the terminal within the audio function */ + uint16_t wTerminalType; /*!< constant characterizing the type of terminal */ + uint8_t bAssocTerminal; /*!< constant, identifying the input terminal to which this output terminal is associated */ + uint8_t bSourceID; /*!< ID of the unit or terminal */ + uint8_t iTerminal; /*!< index of a string descriptor */ +} usb_desc_output_terminal; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< FEATURE_UNIT descriptor subtype */ + uint8_t bUnitID; /*!< constant uniquely identifying the unit within the audio function */ + uint8_t bSourceID; /*!< ID of the unit or terminal */ + uint8_t bControlSize; /*!< size in bytes of an element of the bmaControls() array */ + uint8_t bmaControls0; /*!< a bit set to 1 indicates that the mentioned control is supported for master channel 0 */ + uint8_t bmaControls1; /*!< a bit set to 1 indicates that the mentioned control is supported for logical channel 1 */ + uint8_t iFeature; /*!< index of a string descriptor */ +} usb_desc_mono_feature_unit; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< FEATURE_UNIT descriptor subtype */ + uint8_t bUnitID; /*!< constant uniquely identifying the unit within the audio function */ + uint8_t bSourceID; /*!< ID of the unit or terminal */ + uint8_t bControlSize; /*!< size in bytes of an element of the bmaControls() array */ + uint16_t bmaControls0; /*!< a bit set to 1 indicates that the mentioned control is supported for master channel 0 */ + uint16_t bmaControls1; /*!< a bit set to 1 indicates that the mentioned control is supported for logical channel 1 */ + uint16_t bmaControls2; /*!< a bit set to 1 indicates that the mentioned control is supported for logical channel 2 */ + uint8_t iFeature; /*!< index of a string descriptor */ +} usb_desc_stereo_feature_unit; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< FORMAT_TYPE descriptor subtype */ + uint8_t bFormatType; /*!< constant identifying the format type */ + uint8_t bNrChannels; /*!< indicates the number of physical channels in the audio data stream */ + uint8_t bSubFrameSize; /*!< the number of bytes occupied by one audio subframe */ + uint8_t bBitResolution; /*!< the number of effectively used bits from the available bits in an audio subframe */ + uint8_t bSamFreqType; /*!< indicates how the sampling frequency can be programmed */ + uint8_t bSamFreq[3]; /*!< sampling frequency ns in Hz for this isochronous data endpoint */ +} usb_desc_format_type; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bEndpointAddress; /*!< the address of the endpoint */ + uint8_t bmAttributes; /*!< transfer type and synchronization type */ + uint16_t wMaxPacketSize; /*!< maximum packet size this endpoint is capable of sending or receiving */ + uint8_t bInterval; /*!< left to the designer's discretion */ + uint8_t bRefresh; /*!< reset to 0 */ + uint8_t bSynchAddress; /*!< reset to 0 */ +} usb_desc_std_ep; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bDescriptorSubtype; /*!< EP_GENERAL descriptor subtype */ + uint8_t bmAttributes; /*!< transfer type and synchronization type */ + uint8_t bLockDelayUnits; /*!< indicates the units used for the wLockDelay field */ + uint16_t wLockDelay; /*!< indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry */ +} usb_desc_AS_ep; + +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bEndpointAddress; /*!< EP_GENERAL descriptor subtype */ + uint8_t bmAttributes; /*!< transfer type and synchronization type */ + uint16_t wMaxPacketSize; /*!< maximum packet size this endpoint is capable of sending or receiving */ + uint8_t bInterval; /*!< polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type */ + uint8_t Refresh; /*!< bRefresh 1~9, power of 2 */ + uint8_t bSynchAddress; /* bSynchAddress */ +} usb_desc_FeedBack_ep; + +#pragma pack() + +/* USB configuration descriptor structure */ +typedef struct +{ + usb_desc_config config; + usb_desc_itf std_itf; + usb_desc_AC_itf ac_itf; + +#ifdef USE_USB_AD_MICPHONE + usb_desc_input_terminal mic_in_terminal; + usb_desc_mono_feature_unit mic_feature_unit; + usb_desc_output_terminal mic_out_terminal; +#endif + +#ifdef USE_USB_AD_SPEAKER + usb_desc_input_terminal speak_in_terminal; + usb_desc_mono_feature_unit speak_feature_unit; + usb_desc_output_terminal speak_out_terminal; +#endif /* USE_USB_AD_SPEAKER */ + +#ifdef USE_USB_AD_MICPHONE + usb_desc_itf mic_std_as_itf_zeroband; + usb_desc_itf mic_std_as_itf_opera; + usb_desc_AS_itf mic_as_itf; + usb_desc_format_type mic_format_typeI; + usb_desc_std_ep mic_std_endpoint; + usb_desc_AS_ep mic_as_endpoint; +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + usb_desc_itf speak_std_as_itf_zeroband; + usb_desc_itf speak_std_as_itf_opera; + usb_desc_AS_itf speak_as_itf; + usb_desc_format_type speak_format_typeI; + usb_desc_std_ep speak_std_endpoint; + usb_desc_AS_ep speak_as_endpoint; + usb_desc_FeedBack_ep speak_feedback_endpoint; +#endif /* USE_USB_AD_SPEAKER */ +} usb_desc_config_set; + +typedef struct +{ + /* main buffer for audio data out transfers and its relative pointers */ + uint8_t isoc_out_buff[TOTAL_OUT_BUF_SIZE]; + uint8_t* isoc_out_wrptr; + uint8_t* isoc_out_rdptr; + uint16_t buf_free_size; + uint16_t dam_tx_len; + + __IO uint32_t actual_freq; + __IO uint8_t play_flag; + uint8_t feedback_freq[3] __attribute__ ((aligned (4))); + uint32_t cur_sam_freq; + + /* usb receive buffer */ + uint8_t usb_rx_buffer[SPEAKER_OUT_MAX_PACKET]; + + /* main buffer for audio control requests transfers and its relative variables */ + uint8_t audioctl[64]; + uint8_t audioctl_unit; + uint32_t audioctl_len; +} usbd_audio_handler; + +extern usb_desc audio_desc; +extern usb_class_core usbd_audio_cb; +extern usbd_audio_handler audio_handler; + +#endif /* __AUDIO_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_out_itf.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_out_itf.h new file mode 100644 index 0000000000..37c2d5cae3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Include/audio_out_itf.h @@ -0,0 +1,49 @@ +/*! + \file audio_out_itf.h + \brief audio OUT (playback) interface header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __AUDIO_OUT_ITF_H +#define __AUDIO_OUT_ITF_H + +#include "usbd_conf.h" +#include "string.h" + +typedef struct { + uint8_t (*audio_init) (uint32_t audio_freq, uint32_t volume); + uint8_t (*audio_deinit) (void); + uint8_t (*audio_cmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd); +} audio_fops_struct; + +extern audio_fops_struct audio_out_fops; + +#endif /* __AUDIO_OUT_ITF_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_core.c new file mode 100644 index 0000000000..622a2170d8 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_core.c @@ -0,0 +1,959 @@ +/*! + \file audio_core.c + \brief USB audio device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "audio_out_itf.h" +#include "audio_core.h" +#include +#include + +#define USBD_VID 0x28E9U +#define USBD_PID 0x9574U + +#define VOL_MIN 0U /* volume Minimum Value */ +#define VOL_MAX 100U /* volume Maximum Value */ +#define VOL_RES 1U /* volume Resolution */ +#define VOL_0dB 70U /* 0dB is in the middle of VOL_MIN and VOL_MAX */ + +#ifdef USE_USB_AD_MICPHONE +extern volatile uint32_t count_data; +extern const char wavetestdata[]; +#define LENGTH_DATA (1747 * 32) +#endif /* USE_USB_AD_MICPHONE */ + +__ALIGN_BEGIN usbd_audio_handler audio_handler __ALIGN_END; + +/* local function prototypes ('static') */ +static uint8_t audio_init (usb_dev *udev, uint8_t config_index); +static uint8_t audio_deinit (usb_dev *udev, uint8_t config_index); +static uint8_t audio_req_handler (usb_dev *udev, usb_req *req); +static uint8_t audio_set_intf (usb_dev *udev, usb_req *req); +static uint8_t audio_ctlx_out (usb_dev *udev); +static uint8_t audio_data_in (usb_dev *udev, uint8_t ep_num); +static uint8_t audio_data_out (usb_dev *udev, uint8_t ep_num); +static uint8_t audio_sof (usb_dev *udev); +static uint8_t audio_iso_in_incomplete (usb_dev *udev); +static uint8_t audio_iso_out_incomplete (usb_dev *udev); +static uint32_t usbd_audio_spk_get_feedback(usb_dev *udev); +static void get_feedback_fs_rate(uint32_t rate, uint8_t *buf); + +usb_class_core usbd_audio_cb = { + .init = audio_init, + .deinit = audio_deinit, + .req_proc = audio_req_handler, + .set_intf = audio_set_intf, + .ctlx_out = audio_ctlx_out, + .data_in = audio_data_in, + .data_out = audio_data_out, + .SOF = audio_sof, + .incomplete_isoc_in = audio_iso_in_incomplete, + .incomplete_isoc_out = audio_iso_out_incomplete +}; + +/* note:it should use the c99 standard when compiling the below codes */ +/* USB standard device descriptor */ +__ALIGN_BEGIN const usb_desc_dev audio_dev_desc __ALIGN_END = +{ + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV + }, + .bcdUSB = 0x0200U, + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM +}; + +/* USB device configuration descriptor */ +__ALIGN_BEGIN const usb_desc_config_set audio_config_set __ALIGN_END = +{ + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = AD_CONFIG_DESC_SET_LEN, + .bNumInterfaces = 0x01U + CONFIG_DESC_AS_ITF_COUNT, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0xC0U, + .bMaxPower = 0x32U + }, + + .std_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x00U, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = AD_SUBCLASS_CONTROL, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, + .iInterface = 0x00U + }, + + .ac_itf = + { + .header = + { + .bLength = sizeof(usb_desc_AC_itf), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = 0x01U, + .bcdADC = 0x0100U, + .wTotalLength = AC_ITF_TOTAL_LEN, + .bInCollection = CONFIG_DESC_AS_ITF_COUNT, +#ifdef USE_USB_AD_MICPHONE + .baInterfaceNr0 = 0x01U, +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + .baInterfaceNr1 = 0x02U +#endif /* USE_USB_AD_SPEAKER */ + }, + +#ifdef USE_USB_AD_MICPHONE + .mic_in_terminal = + { + .header = + { + .bLength = sizeof(usb_desc_input_terminal), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = 0x02U, + .bTerminalID = 0x01U, + .wTerminalType = 0x0201U, + .bAssocTerminal = 0x00U, + .bNrChannels = 0x02U, + .wChannelConfig = 0x0003U, + .iChannelNames = 0x00U, + .iTerminal = 0x00U + }, + + .mic_feature_unit = + { + .header = + { + .bLength = sizeof(usb_desc_mono_feature_unit), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_CONTROL_FEATURE_UNIT, + .bUnitID = AD_IN_STREAMING_CTRL, + .bSourceID = 0x01U, + .bControlSize = 0x01U, + .bmaControls0 = AD_CONTROL_MUTE | AD_CONTROL_VOLUME, + .bmaControls1 = 0x00U, + .iFeature = 0x00U + }, + + .mic_out_terminal = + { + .header = + { + .bLength = sizeof(usb_desc_output_terminal), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_CONTROL_OUTPUT_TERMINAL, + .bTerminalID = 0x03U, + .wTerminalType = 0x0101U, + .bAssocTerminal = 0x00U, + .bSourceID = 0x02U, + .iTerminal = 0x00U + }, +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + .speak_in_terminal = + { + .header = + { + .bLength = sizeof(usb_desc_input_terminal), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_CONTROL_INPUT_TERMINAL, + .bTerminalID = 0x04U, + .wTerminalType = 0x0101U, + .bAssocTerminal = 0x00U, + .bNrChannels = 0x02U, + .wChannelConfig = 0x0003U, + .iChannelNames = 0x00U, + .iTerminal = 0x00U + }, + + .speak_feature_unit = + { + .header = + { + .bLength = sizeof(usb_desc_mono_feature_unit), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_CONTROL_FEATURE_UNIT, + .bUnitID = AD_OUT_STREAMING_CTRL, + .bSourceID = 0x04U, + .bControlSize = 0x01U, + .bmaControls0 = AD_CONTROL_MUTE | AD_CONTROL_VOLUME, + .bmaControls1 = 0x00U, + .iFeature = 0x00U + }, + + .speak_out_terminal = + { + .header = + { + .bLength = sizeof(usb_desc_output_terminal), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_CONTROL_OUTPUT_TERMINAL, + .bTerminalID = 0x06U, + .wTerminalType = 0x0301U, + .bAssocTerminal = 0x00U, + .bSourceID = 0x05U, + .iTerminal = 0x00U + }, +#endif /* USE_USB_AD_SPEAKER */ + +#ifdef USE_USB_AD_MICPHONE + .mic_std_as_itf_zeroband = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x01U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x00U, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = AD_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, + .iInterface = 0x00U + }, + + .mic_std_as_itf_opera = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x01U, + .bAlternateSetting = 0x01U, + .bNumEndpoints = 0x01U, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = AD_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, + .iInterface = 0x00U + }, + + .mic_as_itf = + { + .header = + { + .bLength = sizeof(usb_desc_AS_itf), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_STREAMING_GENERAL, + .bTerminalLink = 0x03U, + .bDelay = 0x01U, + .wFormatTag = 0x0001U, + }, + + .mic_format_typeI = + { + .header = + { + .bLength = sizeof(usb_desc_format_type), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_STREAMING_FORMAT_TYPE, + .bFormatType = AD_FORMAT_TYPE_I, + .bNrChannels = MIC_IN_CHANNEL_NBR, + .bSubFrameSize = 0x02U, + .bBitResolution = MIC_IN_BIT_RESOLUTION, + .bSamFreqType = 0x01U, + .bSamFreq[0] = (uint8_t)USBD_MIC_FREQ, + .bSamFreq[1] = USBD_MIC_FREQ >> 8U, + .bSamFreq[2] = USBD_MIC_FREQ >> 16U + }, + + .mic_std_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_std_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = AD_IN_EP, + .bmAttributes = USB_ENDPOINT_TYPE_ISOCHRONOUS, + .wMaxPacketSize = MIC_IN_PACKET, + .bInterval = 0x01U, + .bRefresh = 0x00U, + .bSynchAddress = 0x00U + }, + + .mic_as_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_AS_ep), + .bDescriptorType = AD_DESCTYPE_ENDPOINT + }, + .bDescriptorSubtype = AD_ENDPOINT_GENERAL, + .bmAttributes = 0x00U, + .bLockDelayUnits = 0x00U, + .wLockDelay = 0x0000U, + }, +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + .speak_std_as_itf_zeroband = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x02U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x00U, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = AD_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, + .iInterface = 0x00U + }, + + .speak_std_as_itf_opera = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x02U, + .bAlternateSetting = 0x01U, + .bNumEndpoints = 0x02U, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = AD_SUBCLASS_AUDIOSTREAMING, + .bInterfaceProtocol = AD_PROTOCOL_UNDEFINED, + .iInterface = 0x00U + }, + + .speak_as_itf = + { + .header = + { + .bLength = sizeof(usb_desc_AS_itf), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_STREAMING_GENERAL, + .bTerminalLink = 0x04U, + .bDelay = 0x01U, + .wFormatTag = 0x0001U, + }, + + .speak_format_typeI = + { + .header = + { + .bLength = sizeof(usb_desc_format_type), + .bDescriptorType = AD_DESCTYPE_INTERFACE + }, + .bDescriptorSubtype = AD_STREAMING_FORMAT_TYPE, + .bFormatType = AD_FORMAT_TYPE_I, + .bNrChannels = SPEAKER_OUT_CHANNEL_NBR, + .bSubFrameSize = 0x02U, + .bBitResolution = SPEAKER_OUT_BIT_RESOLUTION, + .bSamFreqType = 0x01U, + .bSamFreq[0] = (uint8_t)USBD_SPEAKER_FREQ, + .bSamFreq[1] = USBD_SPEAKER_FREQ >> 8U, + .bSamFreq[2] = USBD_SPEAKER_FREQ >> 16U + }, + + .speak_std_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_std_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = AD_OUT_EP, + .bmAttributes = USB_EP_ATTR_ISO | USB_EP_ATTR_ASYNC, + .wMaxPacketSize = SPEAKER_OUT_PACKET, + .bInterval = 0x01U, + .bRefresh = 0x00U, + .bSynchAddress = AD_FEEDBACK_IN_EP, + }, + + .speak_as_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_AS_ep), + .bDescriptorType = AD_DESCTYPE_ENDPOINT + }, + .bDescriptorSubtype = AD_ENDPOINT_GENERAL, + .bmAttributes = 0x00U, + .bLockDelayUnits = 0x00U, + .wLockDelay = 0x0000U, + }, + + .speak_feedback_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_FeedBack_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = AD_FEEDBACK_IN_EP, + .bmAttributes = USB_EP_ATTR_ISO | USB_EP_ATTR_ASYNC | USB_EP_ATTR_FEEDBACK, + .wMaxPacketSize = FEEDBACK_IN_PACKET, + .bInterval = 0x01U, + .Refresh = FEEDBACK_IN_INTERVAL, /* refresh every 32(2^5) ms */ + .bSynchAddress = 0x00U, + }, +#endif /* USE_USB_AD_SPEAKER */ +}; + +/* USB language ID descriptor */ +static __ALIGN_BEGIN const usb_desc_LANGID usbd_language_id_desc __ALIGN_END = +{ + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR + }, + + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +static __ALIGN_BEGIN const usb_desc_str manufacturer_string __ALIGN_END = +{ + .header = + { + .bLength = USB_STRING_LEN(10), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +static __ALIGN_BEGIN const usb_desc_str product_string __ALIGN_END = +{ + .header = + { + .bLength = USB_STRING_LEN(14), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'A', 'u', 'd', 'i', 'o'} +}; + +/* USBD serial string */ +static __ALIGN_BEGIN usb_desc_str serial_string __ALIGN_END = +{ + .header = + { + .bLength = USB_STRING_LEN(12), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +/* USB string descriptor */ +void *const usbd_audio_strings[] = +{ + [STR_IDX_LANGID] = (uint8_t *)&usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *)&manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *)&product_string, + [STR_IDX_SERIAL] = (uint8_t *)&serial_string +}; + +/* USB descriptor configure */ +usb_desc audio_desc = { + .dev_desc = (uint8_t *)&audio_dev_desc, + .config_desc = (uint8_t *)&audio_config_set, + .strings = usbd_audio_strings +}; + +/*! + \brief initialize the AUDIO device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_init (usb_dev *udev, uint8_t config_index) +{ + memset((void *)&audio_handler, 0, sizeof(usbd_audio_handler)); + +#ifdef USE_USB_AD_MICPHONE +{ + usb_desc_std_ep std_ep = audio_config_set.mic_std_endpoint; + + usb_desc_ep ep = { + .header = std_ep.header, + .bEndpointAddress = std_ep.bEndpointAddress, + .bmAttributes = std_ep.bmAttributes, + .wMaxPacketSize = std_ep.wMaxPacketSize, + .bInterval = std_ep.bInterval + }; + + /* initialize TX endpoint */ + usbd_ep_setup (udev, &ep); +} +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER +{ + audio_handler.isoc_out_rdptr = audio_handler.isoc_out_buff; + audio_handler.isoc_out_wrptr = audio_handler.isoc_out_buff; + + usb_desc_std_ep std_ep = audio_config_set.speak_std_endpoint; + + usb_desc_ep ep1 = { + .header = std_ep.header, + .bEndpointAddress = std_ep.bEndpointAddress, + .bmAttributes = std_ep.bmAttributes, + .wMaxPacketSize = SPEAKER_OUT_MAX_PACKET, + .bInterval = std_ep.bInterval + }; + + /* initialize RX endpoint */ + usbd_ep_setup (udev, &ep1); + + /* prepare out endpoint to receive next audio packet */ + usbd_ep_recev (udev, AD_OUT_EP, audio_handler.usb_rx_buffer, SPEAKER_OUT_MAX_PACKET); + + /* initialize the audio output hardware layer */ + if (USBD_OK != audio_out_fops.audio_init(USBD_SPEAKER_FREQ, DEFAULT_VOLUME)) { + return USBD_FAIL; + } + + usb_desc_FeedBack_ep feedback_ep = audio_config_set.speak_feedback_endpoint; + + usb_desc_ep ep2 = { + .header = feedback_ep.header, + .bEndpointAddress = feedback_ep.bEndpointAddress, + .bmAttributes = feedback_ep.bmAttributes, + .wMaxPacketSize = feedback_ep.wMaxPacketSize, + .bInterval = feedback_ep.bInterval + }; + + /* initialize Tx endpoint */ + usbd_ep_setup (udev, &ep2); +} +#endif /* USE_USB_AD_SPEAKER */ + + return USBD_OK; +} + +/*! + \brief de-initialize the AUDIO device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_deinit (usb_dev *udev, uint8_t config_index) +{ +#ifdef USE_USB_AD_MICPHONE + /* deinitialize AUDIO endpoints */ + usbd_ep_clear(udev, AD_IN_EP); +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + /* deinitialize AUDIO endpoints */ + usbd_ep_clear(udev, AD_OUT_EP); + + /* deinitialize the audio output hardware layer */ + if (USBD_OK != audio_out_fops.audio_deinit()) { + return USBD_FAIL; + } + + /* deinitialize AUDIO endpoints */ + usbd_ep_clear(udev, AD_FEEDBACK_IN_EP); +#endif /* USE_USB_AD_SPEAKER */ + + return USBD_OK; +} + +/*! + \brief handle the AUDIO class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_req_handler (usb_dev *udev, usb_req *req) +{ + uint8_t status = REQ_NOTSUPP; + + usb_transc *transc_in = &udev->dev.transc_in[0]; + usb_transc *transc_out = &udev->dev.transc_out[0]; + + switch (req->bRequest) { + case AD_REQ_GET_CUR: + transc_in->xfer_buf = audio_handler.audioctl; + transc_in->remain_len = req->wLength; + + status = REQ_SUPP; + break; + + case AD_REQ_SET_CUR: + if (req->wLength) { + transc_out->xfer_buf = audio_handler.audioctl; + transc_out->remain_len = req->wLength; + + udev->dev.class_core->command = AD_REQ_SET_CUR; + + audio_handler.audioctl_len = req->wLength; + audio_handler.audioctl_unit = BYTE_HIGH(req->wIndex); + + status = REQ_SUPP; + } + break; + + case AD_REQ_GET_MIN: + *((uint16_t *)audio_handler.audioctl) = VOL_MIN; + transc_in->xfer_buf = audio_handler.audioctl; + transc_in->remain_len = req->wLength; + status = REQ_SUPP; + break; + + case AD_REQ_GET_MAX: + *((uint16_t *)audio_handler.audioctl) = VOL_MAX; + transc_in->xfer_buf = audio_handler.audioctl; + transc_in->remain_len = req->wLength; + status = REQ_SUPP; + break; + + case AD_REQ_GET_RES: + *((uint16_t *)audio_handler.audioctl) = VOL_RES; + transc_in->xfer_buf = audio_handler.audioctl; + transc_in->remain_len = req->wLength; + status = REQ_SUPP; + break; + + default: + break; + } + + return status; +} + +/*! + \brief handle the AUDIO set interface requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_set_intf(usb_dev *udev, usb_req *req) +{ + udev->dev.class_core->alter_set = req->wValue; + + if(0xFF != req->wValue){ + if (req->wValue != 0){ + /* deinit audio handler */ + memset((void *)&audio_handler, 0, sizeof(usbd_audio_handler)); + + audio_handler.play_flag = 0; + audio_handler.isoc_out_rdptr = audio_handler.isoc_out_buff; + audio_handler.isoc_out_wrptr = audio_handler.isoc_out_buff; + + /* feedback calculate sample freq */ + audio_handler.actual_freq = I2S_ACTUAL_SAM_FREQ(USBD_SPEAKER_FREQ); + get_feedback_fs_rate(audio_handler.actual_freq, audio_handler.feedback_freq); + + /* send feedback data of estimated frequence*/ + usbd_ep_send(udev, AD_FEEDBACK_IN_EP, audio_handler.feedback_freq, FEEDBACK_IN_PACKET); + } else { + /* stop audio output */ + audio_out_fops.audio_cmd(audio_handler.isoc_out_rdptr, SPEAKER_OUT_PACKET/2, AD_CMD_STOP); + + audio_handler.play_flag = 0; + audio_handler.isoc_out_rdptr = audio_handler.isoc_out_buff; + audio_handler.isoc_out_wrptr = audio_handler.isoc_out_buff; + + usbd_fifo_flush (udev, AD_IN_EP); + usbd_fifo_flush (udev, AD_FEEDBACK_IN_EP); + usbd_fifo_flush (udev, AD_OUT_EP); + } + } + + return 0; +} + +/*! + \brief handles the control transfer OUT callback + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_ctlx_out (usb_dev *udev) +{ +#ifdef USE_USB_AD_SPEAKER + /* handles audio control requests data */ + /* check if an audio_control request has been issued */ + if (AD_REQ_SET_CUR == udev->dev.class_core->command) { + /* in this driver, to simplify code, only SET_CUR request is managed */ + + /* check for which addressed unit the audio_control request has been issued */ + if (AD_OUT_STREAMING_CTRL == audio_handler.audioctl_unit) { + /* in this driver, to simplify code, only one unit is manage */ + + /* reset the audioctl_cmd variable to prevent re-entering this function */ + udev->dev.class_core->command = 0U; + + audio_handler.audioctl_len = 0U; + } + } +#endif /* USE_USB_AD_SPEAKER */ + + return USBD_OK; +} + +/*! + \brief handles the audio IN data stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_data_in (usb_dev *udev, uint8_t ep_num) +{ +#ifdef USE_USB_AD_MICPHONE + if(ep_num == EP_ID(AD_IN_EP)){ + if(count_data < LENGTH_DATA){ + /* Prepare next buffer to be sent: dummy data */ + usbd_ep_send(udev, AD_IN_EP,(uint8_t*)&wavetestdata[count_data],MIC_IN_PACKET); + count_data += MIC_IN_PACKET; + } else { + usbd_ep_send(udev, AD_IN_EP,(uint8_t*)wavetestdata,MIC_IN_PACKET); + count_data = MIC_IN_PACKET; + } + } +#endif /* USE_USB_AD_MICPHONE */ + +#ifdef USE_USB_AD_SPEAKER + if(ep_num == EP_ID(AD_FEEDBACK_IN_EP)){ + /* calculate feedback actual freq */ + audio_handler.actual_freq = usbd_audio_spk_get_feedback(udev); + get_feedback_fs_rate(audio_handler.actual_freq, audio_handler.feedback_freq); + + usbd_ep_send(udev, AD_FEEDBACK_IN_EP, audio_handler.feedback_freq, FEEDBACK_IN_PACKET); + } +#endif /* USE_USB_AD_SPEAKER */ + + return USBD_OK; +} + +/*! + \brief handles the audio OUT data stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_data_out (usb_dev *udev, uint8_t ep_num) +{ + uint16_t usb_rx_length, tail_len; + + /* get receive length */ + usb_rx_length = ((usb_core_driver *)udev)->dev.transc_out[ep_num].xfer_count; + + if(audio_handler.isoc_out_wrptr >= audio_handler.isoc_out_rdptr){ + audio_handler.buf_free_size = TOTAL_OUT_BUF_SIZE + audio_handler.isoc_out_rdptr - audio_handler.isoc_out_wrptr; + }else{ + audio_handler.buf_free_size = audio_handler.isoc_out_rdptr - audio_handler.isoc_out_wrptr; + } + + /* free buffer enough to save rx data */ + if(audio_handler.buf_free_size > usb_rx_length){ + if(audio_handler.isoc_out_wrptr >= audio_handler.isoc_out_rdptr){ + tail_len = audio_handler.isoc_out_buff + TOTAL_OUT_BUF_SIZE - audio_handler.isoc_out_wrptr; + + if(tail_len >= usb_rx_length){ + memcpy(audio_handler.isoc_out_wrptr, audio_handler.usb_rx_buffer, usb_rx_length); + + /* increment the buffer pointer */ + audio_handler.isoc_out_wrptr += usb_rx_length; + + /* increment the Buffer pointer or roll it back when all buffers are full */ + if(audio_handler.isoc_out_wrptr >= (audio_handler.isoc_out_buff + TOTAL_OUT_BUF_SIZE)){ + /* all buffers are full: roll back */ + audio_handler.isoc_out_wrptr = audio_handler.isoc_out_buff; + } + }else{ + memcpy(audio_handler.isoc_out_wrptr, audio_handler.usb_rx_buffer, tail_len); + /* adjust write pointer */ + audio_handler.isoc_out_wrptr = audio_handler.isoc_out_buff; + + memcpy(audio_handler.isoc_out_wrptr, &audio_handler.usb_rx_buffer[tail_len], usb_rx_length - tail_len); + /* adjust write pointer */ + audio_handler.isoc_out_wrptr += usb_rx_length - tail_len; + } + }else{ + memcpy(audio_handler.isoc_out_wrptr, audio_handler.usb_rx_buffer, usb_rx_length); + + /* increment the buffer pointer */ + audio_handler.isoc_out_wrptr += usb_rx_length; + } + } + + /* Toggle the frame index */ + udev->dev.transc_out[ep_num].frame_num = (udev->dev.transc_out[ep_num].frame_num)? 0U:1U; + + /* prepare out endpoint to receive next audio packet */ + usbd_ep_recev (udev, AD_OUT_EP, audio_handler.usb_rx_buffer, SPEAKER_OUT_MAX_PACKET); + + if(audio_handler.isoc_out_wrptr >= audio_handler.isoc_out_rdptr){ + audio_handler.buf_free_size = TOTAL_OUT_BUF_SIZE + audio_handler.isoc_out_rdptr - audio_handler.isoc_out_wrptr; + }else{ + audio_handler.buf_free_size = audio_handler.isoc_out_rdptr - audio_handler.isoc_out_wrptr; + } + + if ((0U == audio_handler.play_flag) && (audio_handler.buf_free_size < TOTAL_OUT_BUF_SIZE/2)) { + /* enable start of streaming */ + audio_handler.play_flag = 1U; + + /* initialize the audio output hardware layer */ + if (USBD_OK != audio_out_fops.audio_cmd(audio_handler.isoc_out_rdptr, SPEAKER_OUT_MAX_PACKET/2, AD_CMD_PLAY)) { + return USBD_FAIL; + } + + audio_handler.dam_tx_len = SPEAKER_OUT_MAX_PACKET; + } + + return USBD_OK; +} + +/*! + \brief handles the SOF event (data buffer update and synchronization) + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_sof (usb_dev *udev) +{ + return USBD_OK; +} + +/*! + \brief handles the audio ISO IN Incomplete event + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_iso_in_incomplete (usb_dev *udev) +{ + (void)usb_txfifo_flush (&udev->regs, EP_ID(AD_FEEDBACK_IN_EP)); + + audio_handler.actual_freq = usbd_audio_spk_get_feedback(udev); + get_feedback_fs_rate(audio_handler.actual_freq, audio_handler.feedback_freq); + + /* send feedback data of estimated frequence*/ + usbd_ep_send(udev, AD_FEEDBACK_IN_EP, audio_handler.feedback_freq, FEEDBACK_IN_PACKET); + + return USBD_OK; +} + +/*! + \brief handles the audio ISO OUT Incomplete event + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +static uint8_t audio_iso_out_incomplete (usb_dev *udev) +{ + return USBD_OK; +} + +/*! + \brief calculate feedback sample frequency + \param[in] udev: pointer to USB device instance + \param[out] none + \retval feedback frequency value +*/ +static uint32_t usbd_audio_spk_get_feedback(usb_dev *udev) +{ + static uint32_t fb_freq; + + /* calculate buffer free size */ + if(audio_handler.isoc_out_wrptr >= audio_handler.isoc_out_rdptr){ + audio_handler.buf_free_size = TOTAL_OUT_BUF_SIZE + audio_handler.isoc_out_rdptr - audio_handler.isoc_out_wrptr; + }else{ + audio_handler.buf_free_size = audio_handler.isoc_out_rdptr - audio_handler.isoc_out_wrptr; + } + + /* calculate feedback frequency */ + if(audio_handler.buf_free_size <= (TOTAL_OUT_BUF_SIZE/4)){ + fb_freq = I2S_ACTUAL_SAM_FREQ(USBD_SPEAKER_FREQ) - FEEDBACK_FREQ_OFFSET; + }else if(audio_handler.buf_free_size >= (TOTAL_OUT_BUF_SIZE*3/4)){ + fb_freq = I2S_ACTUAL_SAM_FREQ(USBD_SPEAKER_FREQ) + FEEDBACK_FREQ_OFFSET; + }else{ + fb_freq = I2S_ACTUAL_SAM_FREQ(USBD_SPEAKER_FREQ); + } + + return fb_freq; +} + +/*! + \brief get feedback value from rate in USB full speed + \param[in] rate: sample frequence + \param[in] buf: pointer to result buffer + \param[out] none + \retval USB device operation status +*/ +static void get_feedback_fs_rate(uint32_t rate, uint8_t *buf) +{ + rate = ((rate / 1000) << 14) | ((rate % 1000) << 4); + + buf[0] = rate; + buf[1] = rate >> 8; + buf[2] = rate >> 16; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_out_itf.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_out_itf.c new file mode 100644 index 0000000000..04176dcba8 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/audio/Source/audio_out_itf.c @@ -0,0 +1,168 @@ +/*! + \file audio_out_itf.c + \brief audio OUT (playback) interface functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "audio_core.h" +#include "audio_out_itf.h" + +/* local function prototypes ('static') */ +static uint8_t init (uint32_t audio_freq, uint32_t volume); +static uint8_t deinit (void); +static uint8_t audio_cmd (uint8_t* pbuf, uint32_t size, uint8_t cmd); + +/* local variable defines */ +static uint8_t audio_state = AD_STATE_INACTIVE; + +audio_fops_struct audio_out_fops = +{ + .audio_init = init, + .audio_deinit = deinit, + .audio_cmd = audio_cmd, +}; + +/*! + \brief initialize and configures all required resources + \param[in] audio_freq: statrt_up audio frequency + \param[in] volume: start_up volume to be set + \param[out] none + \retval AD_OK if all operations succeed, otherwise, AD_FAIL. +*/ +static uint8_t init (uint32_t audio_freq, uint32_t volume) +{ + static uint32_t initialized = 0U; + + /* check if the low layer has already been initialized */ + if (0U == initialized) { + /* initialize GPIO */ + codec_gpio_init(); + + /* initialize i2s */ + codec_audio_interface_init(audio_freq); + + /* initialize DMA */ + codec_dma_init(); + + /* prevent reinitializing the interface again */ + initialized = 1U; + } + + /* update the audio state machine */ + audio_state = AD_STATE_ACTIVE; + + return AD_OK; +} + +/*! + \brief free all resources used by low layer and stops audio-play function + \param[in] none + \param[out] none + \retval AD_OK if all operations succeed, otherwise, AD_FAIL. +*/ +static uint8_t deinit (void) +{ + /* update the audio state machine */ + audio_state = AD_STATE_INACTIVE; + + return AD_OK; +} + +/*! + \brief play, stop, pause or resume current file + \param[in] pbuf: address from which file should be played + \param[in] size: size of the current buffer/file + \param[in] cmd: command to be executed, can be: + \arg AD_CMD_PLAY + \arg AD_CMD_PAUSE + \arg AD_CMD_RESUME + \arg AD_CMD_STOP + \param[out] none + \retval AD_OK if all operations succeed, otherwise, AD_FAIL. +*/ +static uint8_t audio_cmd (uint8_t* pbuf, uint32_t size, uint8_t cmd) +{ + /* check the current state */ + if ((AD_STATE_INACTIVE == audio_state) || (AD_STATE_ERROR == audio_state)) { + audio_state = AD_STATE_ERROR; + + return AD_FAIL; + } + + switch (cmd) { + /* process the play command */ + case AD_CMD_PLAY: + /* if current state is active or stopped */ + if ((AD_STATE_ACTIVE == audio_state) || \ + (AD_STATE_STOPPED == audio_state) || \ + (AD_STATE_PLAYING == audio_state)) { + audio_play((uint32_t)pbuf, size); + audio_state = AD_STATE_PLAYING; + + return AD_OK; + } else if (AD_STATE_PAUSED == audio_state) { + audio_pause_resume(AD_RESUME, (uint32_t)pbuf, (size/2)); + audio_state = AD_STATE_PLAYING; + + return AD_OK; + } else { + return AD_FAIL; + } + + /* process the stop command */ + case AD_CMD_STOP: + if (AD_STATE_PLAYING != audio_state) { + /* unsupported command */ + return AD_FAIL; + } else { + audio_stop(); + audio_state = AD_STATE_STOPPED; + + return AD_OK; + } + + /* process the pause command */ + case AD_CMD_PAUSE: + if (AD_STATE_PLAYING != audio_state) { + /* unsupported command */ + return AD_FAIL; + } else { + audio_pause_resume(AD_PAUSE, (uint32_t)pbuf, (size/2)); + audio_state = AD_STATE_PAUSED; + + return AD_OK; + } + + /* unsupported command */ + default: + return AD_FAIL; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Include/cdc_acm_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Include/cdc_acm_core.h new file mode 100644 index 0000000000..45f1c115a2 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Include/cdc_acm_core.h @@ -0,0 +1,66 @@ +/*! + \file cdc_acm_core.h + \brief the header file of cdc acm driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __CDC_ACM_CORE_H +#define __CDC_ACM_CORE_H + +#include "usbd_enum.h" +#include "usb_cdc.h" + +#define USB_CDC_RX_LEN USB_CDC_DATA_PACKET_SIZE + +typedef struct { + uint8_t packet_sent; + uint8_t packet_receive; + + __ALIGN_BEGIN uint8_t data[USB_CDC_RX_LEN] __ALIGN_END; + __ALIGN_BEGIN uint8_t cmd[USB_CDC_CMD_PACKET_SIZE] __ALIGN_END; + + uint32_t receive_length; + + acm_line line_coding; +} usb_cdc_handler; + +extern usb_desc cdc_desc; +extern usb_class_core cdc_class; + +/* function declarations */ +/* check CDC ACM is ready for data transfer */ +uint8_t cdc_acm_check_ready(usb_dev *udev); +/* send CDC ACM data */ +void cdc_acm_data_send(usb_dev *udev); +/* receive CDC ACM data */ +void cdc_acm_data_receive(usb_dev *udev); + +#endif /* __CDC_ACM_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Source/cdc_acm_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Source/cdc_acm_core.c new file mode 100644 index 0000000000..d8c5d337cd --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/cdc/Source/cdc_acm_core.c @@ -0,0 +1,514 @@ +/*! + \file cdc_acm_core.c + \brief CDC ACM driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "cdc_acm_core.h" + +#define USBD_VID 0x28E9U +#define USBD_PID 0x018AU + +/* note:it should use the C99 standard when compiling the below codes */ +/* USB standard device descriptor */ +__ALIGN_BEGIN const usb_desc_dev cdc_dev_desc __ALIGN_END = { + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV, + }, + .bcdUSB = 0x0200U, + .bDeviceClass = USB_CLASS_CDC, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM, +}; + +/* USB device configuration descriptor */ +__ALIGN_BEGIN const usb_cdc_desc_config_set cdc_config_desc __ALIGN_END = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG, + }, + .wTotalLength = USB_CDC_ACM_CONFIG_DESC_SIZE, + .bNumInterfaces = 0x02U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0x80U, + .bMaxPower = 0x32U + }, + + .cmd_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x01U, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, + .iInterface = 0x00U + }, + + .cdc_header = + { + .header = + { + .bLength = sizeof(usb_desc_header_func), + .bDescriptorType = USB_DESCTYPE_CS_INTERFACE + }, + .bDescriptorSubtype = 0x00U, + .bcdCDC = 0x0110U + }, + + .cdc_call_managment = + { + .header = + { + .bLength = sizeof(usb_desc_call_managment_func), + .bDescriptorType = USB_DESCTYPE_CS_INTERFACE + }, + .bDescriptorSubtype = 0x01U, + .bmCapabilities = 0x00U, + .bDataInterface = 0x01U + }, + + .cdc_acm = + { + .header = + { + .bLength = sizeof(usb_desc_acm_func), + .bDescriptorType = USB_DESCTYPE_CS_INTERFACE + }, + .bDescriptorSubtype = 0x02U, + .bmCapabilities = 0x02U, + }, + + .cdc_union = + { + .header = + { + .bLength = sizeof(usb_desc_union_func), + .bDescriptorType = USB_DESCTYPE_CS_INTERFACE + }, + .bDescriptorSubtype = 0x06U, + .bMasterInterface = 0x00U, + .bSlaveInterface0 = 0x01U, + }, + + .cdc_cmd_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP, + }, + .bEndpointAddress = CDC_CMD_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = USB_CDC_CMD_PACKET_SIZE, + .bInterval = 0x0AU + }, + + .cdc_data_interface = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF, + }, + .bInterfaceNumber = 0x01U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x02U, + .bInterfaceClass = USB_CLASS_DATA, + .bInterfaceSubClass = 0x00U, + .bInterfaceProtocol = USB_CDC_PROTOCOL_NONE, + .iInterface = 0x00U + }, + + .cdc_out_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP, + }, + .bEndpointAddress = CDC_DATA_OUT_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = USB_CDC_DATA_PACKET_SIZE, + .bInterval = 0x00U + }, + + .cdc_in_endpoint = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = CDC_DATA_IN_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = USB_CDC_DATA_PACKET_SIZE, + .bInterval = 0x00U + } +}; + +/* USB language ID Descriptor */ +__ALIGN_BEGIN static const usb_desc_LANGID usbd_language_id_desc __ALIGN_END = { + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +__ALIGN_BEGIN static const usb_desc_str manufacturer_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(10U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +__ALIGN_BEGIN static const usb_desc_str product_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'C', 'D', 'C', '_', 'A', 'C', 'M'} +}; + +/* USB serial string */ +__ALIGN_BEGIN static usb_desc_str serial_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +/* USB string descriptor set */ +void *const usbd_cdc_strings[] = { + [STR_IDX_LANGID] = (uint8_t *) &usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *) &manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *) &product_string, + [STR_IDX_SERIAL] = (uint8_t *) &serial_string +}; + +usb_desc cdc_desc = { + .dev_desc = (uint8_t *) &cdc_dev_desc, + .config_desc = (uint8_t *) &cdc_config_desc, + .strings = usbd_cdc_strings +}; + +/* local function prototypes ('static') */ +static uint8_t cdc_acm_init(usb_dev *udev, uint8_t config_index); +static uint8_t cdc_acm_deinit(usb_dev *udev, uint8_t config_index); +static uint8_t cdc_acm_req(usb_dev *udev, usb_req *req); +static uint8_t cdc_ctlx_out(usb_dev *udev); +static uint8_t cdc_acm_in(usb_dev *udev, uint8_t ep_num); +static uint8_t cdc_acm_out(usb_dev *udev, uint8_t ep_num); + +/* USB CDC device class callbacks structure */ +usb_class_core cdc_class = { + .command = NO_CMD, + .alter_set = 0U, + + .init = cdc_acm_init, + .deinit = cdc_acm_deinit, + .req_proc = cdc_acm_req, + + .ctlx_out = cdc_ctlx_out, + .data_in = cdc_acm_in, + .data_out = cdc_acm_out +}; + +/*! + \brief check CDC ACM is ready for data transfer + \param[in] udev: pointer to USB device instance + \param[out] none + \retval 0 if CDC is ready, 5 else +*/ +uint8_t cdc_acm_check_ready(usb_dev *udev) +{ + if(udev->dev.class_data[CDC_COM_INTERFACE] != NULL) { + usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE]; + + if((1U == cdc->packet_receive) && (1U == cdc->packet_sent)) { + return 0U; + } + } + + return 1U; +} + +/*! + \brief send CDC ACM data + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +void cdc_acm_data_send(usb_dev *udev) +{ + usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE]; + + if(0U != cdc->receive_length) { + cdc->packet_sent = 0U; + + usbd_ep_send(udev, CDC_DATA_IN_EP, (uint8_t *)(cdc->data), cdc->receive_length); + + cdc->receive_length = 0U; + } +} + +/*! + \brief receive CDC ACM data + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation status +*/ +void cdc_acm_data_receive(usb_dev *udev) +{ + usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE]; + + cdc->packet_receive = 0U; + cdc->packet_sent = 0U; + + usbd_ep_recev(udev, CDC_DATA_OUT_EP, (uint8_t *)(cdc->data), USB_CDC_DATA_PACKET_SIZE); +} + +/*! + \brief initialize the CDC ACM device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t cdc_acm_init(usb_dev *udev, uint8_t config_index) +{ + static usb_cdc_handler cdc_handler; + + /* initialize the data TX endpoint */ + usbd_ep_setup(udev, &(cdc_config_desc.cdc_in_endpoint)); + + /* initialize the data RX endpoint */ + usbd_ep_setup(udev, &(cdc_config_desc.cdc_out_endpoint)); + + /* initialize the command TX endpoint */ + usbd_ep_setup(udev, &(cdc_config_desc.cdc_cmd_endpoint)); + + /* initialize CDC handler structure */ + cdc_handler.packet_receive = 1U; + cdc_handler.packet_sent = 1U; + cdc_handler.receive_length = 0U; + + cdc_handler.line_coding = (acm_line) { + .dwDTERate = 115200, + .bCharFormat = 0, + .bParityType = 0, + .bDataBits = 0x08 + }; + + udev->dev.class_data[CDC_COM_INTERFACE] = (void *)&cdc_handler; + + return USBD_OK; +} + +/*! + \brief de-initialize the CDC ACM device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t cdc_acm_deinit(usb_dev *udev, uint8_t config_index) +{ + /* deinitialize the data TX/RX endpoint */ + usbd_ep_clear(udev, CDC_DATA_IN_EP); + usbd_ep_clear(udev, CDC_DATA_OUT_EP); + + /* deinitialize the command TX endpoint */ + usbd_ep_clear(udev, CDC_CMD_EP); + + return USBD_OK; +} + +/*! + \brief handle the CDC ACM class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t cdc_acm_req(usb_dev *udev, usb_req *req) +{ + usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE]; + + usb_transc *transc = NULL; + + switch(req->bRequest) { + case SEND_ENCAPSULATED_COMMAND: + /* no operation for this driver */ + break; + + case GET_ENCAPSULATED_RESPONSE: + /* no operation for this driver */ + break; + + case SET_COMM_FEATURE: + /* no operation for this driver */ + break; + + case GET_COMM_FEATURE: + /* no operation for this driver */ + break; + + case CLEAR_COMM_FEATURE: + /* no operation for this driver */ + break; + + case SET_LINE_CODING: + transc = &udev->dev.transc_out[0]; + /* set the value of the current command to be processed */ + udev->dev.class_core->alter_set = req->bRequest; + + /* enable EP0 prepare to receive command data packet */ + transc->remain_len = req->wLength; + transc->xfer_buf = cdc->cmd; + break; + + case GET_LINE_CODING: + transc = &udev->dev.transc_in[0]; + + cdc->cmd[0] = (uint8_t)(cdc->line_coding.dwDTERate); + cdc->cmd[1] = (uint8_t)(cdc->line_coding.dwDTERate >> 8); + cdc->cmd[2] = (uint8_t)(cdc->line_coding.dwDTERate >> 16); + cdc->cmd[3] = (uint8_t)(cdc->line_coding.dwDTERate >> 24); + cdc->cmd[4] = cdc->line_coding.bCharFormat; + cdc->cmd[5] = cdc->line_coding.bParityType; + cdc->cmd[6] = cdc->line_coding.bDataBits; + + transc->xfer_buf = cdc->cmd; + transc->remain_len = 7U; + break; + + case SET_CONTROL_LINE_STATE: + /* no operation for this driver */ + break; + + case SEND_BREAK: + /* no operation for this driver */ + break; + + default: + break; + } + + return USBD_OK; +} + +static uint8_t cdc_ctlx_out(usb_dev *udev) +{ + usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE]; + + if(NO_CMD != udev->dev.class_core->alter_set) { + /* process the command data */ + cdc->line_coding.dwDTERate = (uint32_t)((uint32_t)cdc->cmd[0] | + ((uint32_t)cdc->cmd[1] << 8U) | + ((uint32_t)cdc->cmd[2] << 16U) | + ((uint32_t)cdc->cmd[3] << 24U)); + + cdc->line_coding.bCharFormat = cdc->cmd[4]; + cdc->line_coding.bParityType = cdc->cmd[5]; + cdc->line_coding.bDataBits = cdc->cmd[6]; + + udev->dev.class_core->alter_set = NO_CMD; + } + + return USBD_OK; +} + +/*! + \brief handle CDC ACM data + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier + \param[out] none + \retval USB device operation status +*/ +static uint8_t cdc_acm_in(usb_dev *udev, uint8_t ep_num) +{ + usb_transc *transc = &udev->dev.transc_in[EP_ID(ep_num)]; + + usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE]; + + if((0U == transc->xfer_len % transc->max_len) && (0U != transc->xfer_len)) { + usbd_ep_send(udev, ep_num, NULL, 0U); + } else { + cdc->packet_sent = 1U; + } + + return USBD_OK; +} + +/*! + \brief handle CDC ACM data + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier + \param[out] none + \retval USB device operation status +*/ +static uint8_t cdc_acm_out(usb_dev *udev, uint8_t ep_num) +{ + usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE]; + + cdc->packet_receive = 1U; + cdc->receive_length = ((usb_core_driver *)udev)->dev.transc_out[ep_num].xfer_count; + + return USBD_OK; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_core.h new file mode 100644 index 0000000000..afe3106c58 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_core.h @@ -0,0 +1,176 @@ +/*! + \file dfu_core.h + \brief the header file of USB DFU device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DFU_CORE_H +#define __DFU_CORE_H + +#include "usbd_enum.h" + +/* DFU class code */ +#define USB_DFU_CLASS 0xFEU + +/* DFU subclass code */ +#define USB_DFU_SUBCLASS_UPGRADE 0x01U + +/* DFU protocol code */ +#define USB_DFU_PROTOCL_RUNTIME 0x01U +#define USB_DFU_PROTOCL_DFU 0x02U + +/* manifestation state */ +#define MANIFEST_COMPLETE 0x00U +#define MANIFEST_IN_PROGRESS 0x01U + +/* DFU attributes code */ +#define USB_DFU_CAN_DOWNLOAD 0x01U +#define USB_DFU_CAN_UPLOAD 0x02U +#define USB_DFU_MANIFEST_TOLERANT 0x04U +#define USB_DFU_WILL_DETACH 0x08U + +/* special commands with download request */ +#define GET_COMMANDS 0x00U +#define SET_ADDRESS_POINTER 0x21U +#define ERASE 0x41U + +/* memory operation command */ +#define CMD_ERASE 0U +#define CMD_WRITE 1U + +#define _BYTE1(x) (uint8_t)((x) & 0xFFU) /*!< addressing cycle 1st byte */ +#define _BYTE2(x) (uint8_t)(((x) & 0xFF00U) >> 8U) /*!< addressing cycle 2nd byte */ +#define _BYTE3(x) (uint8_t)(((x) & 0xFF0000U) >> 16U) /*!< addressing cycle 3rd byte */ + +#define FLASH_ERASE_TIMEOUT 60U +#define FLASH_WRITE_TIMEOUT 80U + +/* bit detach capable = bit 3 in bmAttributes field */ +#define DFU_DETACH_MASK (uint8_t)(0x10U) + +#define USB_SERIAL_STR_LEN 0x06U + +#define USB_DFU_CONFIG_DESC_SIZE 27U + +#define DFU_DESC_TYPE 0x21U + +/* DFU device state defines */ +typedef enum { + STATE_APP_IDLE = 0x00U, + STATE_APP_DETACH, + STATE_DFU_IDLE, + STATE_DFU_DNLOAD_SYNC, + STATE_DFU_DNBUSY, + STATE_DFU_DNLOAD_IDLE, + STATE_DFU_MANIFEST_SYNC, + STATE_DFU_MANIFEST, + STATE_DFU_MANIFEST_WAIT_RESET, + STATE_DFU_UPLOAD_IDLE, + STATE_DFU_ERROR +} dfu_state; + +/* DFU device status defines */ +typedef enum { + STATUS_OK = 0x00U, + STATUS_ERR_TARGET, + STATUS_ERR_FILE, + STATUS_ERR_WRITE, + STATUS_ERR_ERASE, + STATUS_ERR_CHECK_ERASED, + STATUS_ERR_PROG, + STATUS_ERR_VERIFY, + STATUS_ERR_ADDRESS, + STATUS_ERR_NOTDONE, + STATUS_ERR_FIRMWARE, + STATUS_ERR_VENDOR, + STATUS_ERR_USBR, + STATUS_ERR_POR, + STATUS_ERR_UNKNOWN, + STATUS_ERR_STALLEDPKT +} dfu_status; + +/* DFU class-specific requests */ +typedef enum { + DFU_DETACH = 0U, + DFU_DNLOAD, + DFU_UPLOAD, + DFU_GETSTATUS, + DFU_CLRSTATUS, + DFU_GETSTATE, + DFU_ABORT, + DFU_REQ_MAX +} dfu_requests; + +#pragma pack(1) + +/* USB DFU function descriptor structure */ +typedef struct +{ + usb_desc_header header; /*!< descriptor header, including type and size */ + uint8_t bmAttributes; /*!< DFU attributes */ + uint16_t wDetachTimeOut; /*!< time, in milliseconds, that the device will wait after receipt of the DFU_DETACH request. If */ + uint16_t wTransferSize; /*!< maximum number of bytes that the device can accept per control-write transaction */ + uint16_t bcdDFUVersion; /*!< numeric expression identifying the version of the DFU Specification release. */ +} usb_desc_dfu_func; + +#pragma pack() + +/* USB configuration descriptor structure */ +typedef struct +{ + usb_desc_config config; + usb_desc_itf dfu_itf; + usb_desc_dfu_func dfu_func; +} usb_dfu_desc_config_set; + +typedef struct +{ + uint8_t bStatus; + uint8_t bwPollTimeout0; + uint8_t bwPollTimeout1; + uint8_t bwPollTimeout2; + uint8_t bState; + uint8_t iString; + + uint8_t manifest_state; + uint32_t data_len; + uint16_t block_num; + uint32_t base_addr; + + uint8_t buf[TRANSFER_SIZE]; +} usbd_dfu_handler; + +typedef void (*app_func) (void); + +extern usb_desc dfu_desc; +extern usb_class_core dfu_class; + +#endif /* DFU_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_mal.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_mal.h new file mode 100644 index 0000000000..55a85c23d7 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Include/dfu_mal.h @@ -0,0 +1,83 @@ +/*! + \file dfu_mal.h + \brief USB DFU device media access layer header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DFU_MAL_H +#define __DFU_MAL_H + +#include "usbd_conf.h" + +typedef struct _dfu_mal_prop +{ + const uint8_t* pstr_desc; + + uint8_t (*mal_init) (void); + uint8_t (*mal_deinit) (void); + uint8_t (*mal_erase) (uint32_t addr); + uint8_t (*mal_write) (uint8_t *buf, uint32_t addr, uint32_t len); + uint8_t* (*mal_read) (uint8_t *buf, uint32_t addr, uint32_t len); + uint8_t (*mal_checkaddr) (uint32_t addr); + + const uint32_t erase_timeout; + const uint32_t write_timeout; +} dfu_mal_prop; + +typedef enum +{ + MAL_OK = 0, + MAL_FAIL +} MAL_Status; + +#define _1st_BYTE(x) (uint8_t)((x) & 0xFF) /*!< addressing cycle 1st byte */ +#define _2nd_BYTE(x) (uint8_t)(((x) & 0xFF00) >> 8) /*!< addressing cycle 2nd byte */ +#define _3rd_BYTE(x) (uint8_t)(((x) & 0xFF0000) >> 16) /*!< addressing cycle 3rd byte */ + +#define SET_POLLING_TIMEOUT(x) buffer[0] = _1st_BYTE(x);\ + buffer[1] = _2nd_BYTE(x);\ + buffer[2] = _3rd_BYTE(x); + +/* function declarations */ +/* initialize the memory media on the GD32 */ +uint8_t dfu_mal_init(void); +/* deinitialize the memory media on the GD32 */ +uint8_t dfu_mal_deinit(void); +/* erase a memory sector */ +uint8_t dfu_mal_erase(uint32_t addr); +/* write data to sectors of memory */ +uint8_t dfu_mal_write(uint8_t *buf, uint32_t addr, uint32_t len); +/* read data from sectors of memory */ +uint8_t* dfu_mal_read(uint8_t *buf, uint32_t addr, uint32_t len); +/* get the status of a given memory and store in buffer */ +uint8_t dfu_mal_getstatus(uint32_t addr, uint8_t cmd, uint8_t *buffer); + +#endif /* __DFU_MAL_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_core.c new file mode 100644 index 0000000000..93c5ca6c8f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_core.c @@ -0,0 +1,642 @@ +/*! + \file dfu_core.c + \brief USB DFU device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "dfu_core.h" +#include "drv_usb_hw.h" +#include "dfu_mal.h" +#include "flash_if.h" +#include + +#define USBD_VID 0x28E9U +#define USBD_PID 0x0189U + +/* local function prototypes ('static') */ +static uint8_t dfu_init(usb_dev *udev, uint8_t config_index); +static uint8_t dfu_deinit(usb_dev *udev, uint8_t config_index); +static uint8_t dfu_req_handler(usb_dev *udev, usb_req *req); +static uint8_t dfu_ctlx_in(usb_dev *udev); +static void dfu_detach(usb_dev *udev, usb_req *req); +static void dfu_dnload(usb_dev *udev, usb_req *req); +static void dfu_upload(usb_dev *udev, usb_req *req); +static void dfu_getstatus(usb_dev *udev, usb_req *req); +static void dfu_clrstatus(usb_dev *udev, usb_req *req); +static void dfu_getstate(usb_dev *udev, usb_req *req); +static void dfu_abort(usb_dev *udev, usb_req *req); +static void dfu_mode_leave(usb_dev *udev); +static uint8_t dfu_getstatus_complete(usb_dev *udev); + +static void (*dfu_request_process[])(usb_dev *udev, usb_req *req) = { + [DFU_DETACH] = dfu_detach, + [DFU_DNLOAD] = dfu_dnload, + [DFU_UPLOAD] = dfu_upload, + [DFU_GETSTATUS] = dfu_getstatus, + [DFU_CLRSTATUS] = dfu_clrstatus, + [DFU_GETSTATE] = dfu_getstate, + [DFU_ABORT] = dfu_abort +}; + +/* note:it should use the c99 standard when compiling the below codes */ +/* USB standard device descriptor */ +const __ALIGN_BEGIN usb_desc_dev dfu_dev_desc __ALIGN_END = { + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV + }, + .bcdUSB = 0x0200U, + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM +}; + +/* USB device configuration descriptor */ +const __ALIGN_BEGIN usb_dfu_desc_config_set dfu_config_desc __ALIGN_END = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = USB_DFU_CONFIG_DESC_SIZE, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0x80U, + .bMaxPower = 0x32U + }, + + .dfu_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x00U, + .bInterfaceClass = USB_DFU_CLASS, + .bInterfaceSubClass = USB_DFU_SUBCLASS_UPGRADE, + .bInterfaceProtocol = USB_DFU_PROTOCL_DFU, + .iInterface = 0x05U + }, + + .dfu_func = + { + .header = + { + .bLength = sizeof(usb_desc_dfu_func), + .bDescriptorType = DFU_DESC_TYPE + }, + .bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_CAN_UPLOAD | USB_DFU_WILL_DETACH, + .wDetachTimeOut = 0x00FFU, + .wTransferSize = TRANSFER_SIZE, + .bcdDFUVersion = 0x011AU, + }, +}; + +/* USB language ID Descriptor */ +static const __ALIGN_BEGIN usb_desc_LANGID usbd_language_id_desc __ALIGN_END = { + .header = { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +static const __ALIGN_BEGIN usb_desc_str manufacturer_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(10U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +static const __ALIGN_BEGIN usb_desc_str product_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'D', 'F', 'U'} +}; + +/* USBD serial string */ +static __ALIGN_BEGIN usb_desc_str serial_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(2U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +/* USB configure string */ +static const __ALIGN_BEGIN usb_desc_str config_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(15U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', ' ', 'U', 'S', 'B', ' ', 'C', 'O', 'N', 'F', 'I', 'G'} +}; + +static const __ALIGN_BEGIN usb_desc_str interface_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(44U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'@', 'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', 'F', 'l', 'a', 's', 'h', ' ', '/', '0', 'x', '0', '8', '0', '0', + '0', '0', '0', '0', '/', '1', '6', '*', '0', '0', '1', 'K', 'a', ',', '4', '8', '*', '0', '0', '1', 'K', 'g' + } +}; + +void *const usbd_dfu_strings[] = { + [STR_IDX_LANGID] = (uint8_t *) &usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *) &manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *) &product_string, + [STR_IDX_SERIAL] = (uint8_t *) &serial_string, + [STR_IDX_CONFIG] = (uint8_t *) &config_string, + [STR_IDX_ITF] = (uint8_t *) &interface_string +}; + +usb_desc dfu_desc = { + .dev_desc = (uint8_t *) &dfu_dev_desc, + .config_desc = (uint8_t *) &dfu_config_desc, + .strings = usbd_dfu_strings +}; + +usb_class_core dfu_class = { + .init = dfu_init, + .deinit = dfu_deinit, + .req_proc = dfu_req_handler, + .ctlx_in = dfu_ctlx_in +}; + +/*! + \brief initialize the DFU device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t dfu_init(usb_dev *udev, uint8_t config_index) +{ + static usbd_dfu_handler dfu_handler; + + /* unlock the internal flash */ + dfu_mal_init(); + + memset((void *)&dfu_handler, 0, sizeof(usbd_dfu_handler)); + + dfu_handler.base_addr = APP_LOADED_ADDR; + dfu_handler.manifest_state = MANIFEST_COMPLETE; + dfu_handler.bState = STATE_DFU_IDLE; + dfu_handler.bStatus = STATUS_OK; + + udev->dev.class_data[USBD_DFU_INTERFACE] = (void *)&dfu_handler; + + return USBD_OK; +} + +/*! + \brief de-initialize the DFU device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t dfu_deinit(usb_dev *udev, uint8_t config_index) +{ + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + /* restore device default state */ + memset(udev->dev.class_data[USBD_DFU_INTERFACE], 0, sizeof(usbd_dfu_handler)); + + dfu->bState = STATE_DFU_IDLE; + dfu->bStatus = STATUS_OK; + + /* lock the internal flash */ + dfu_mal_deinit(); + + return USBD_OK; +} + +/*! + \brief handle the DFU class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t dfu_req_handler(usb_dev *udev, usb_req *req) +{ + if(req->bRequest < DFU_REQ_MAX) { + dfu_request_process[req->bRequest](udev, req); + } else { + return USBD_FAIL; + } + + return USBD_OK; +} + +/*! + \brief handle data Stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: the endpoint number + \param[out] none + \retval USB device operation status +*/ +static uint8_t dfu_ctlx_in(usb_dev *udev) +{ + dfu_getstatus_complete(udev); + + return USBD_OK; +} + +/*! + \brief leave DFU mode and reset device to jump to user loaded code + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void dfu_mode_leave(usb_dev *udev) +{ + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + dfu->manifest_state = MANIFEST_COMPLETE; + + if(dfu_config_desc.dfu_func.bmAttributes & 0x04U) { + dfu->bState = STATE_DFU_MANIFEST_SYNC; + } else { + dfu->bState = STATE_DFU_MANIFEST_WAIT_RESET; + + /* lock the internal flash */ + dfu_mal_deinit(); + + /* generate system reset to allow jumping to the user code */ + NVIC_SystemReset(); + } +} + +/*! + \brief handle data IN stage in control endpoint 0 + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation status + */ +static uint8_t dfu_getstatus_complete(usb_dev *udev) +{ + uint32_t addr; + + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + if(STATE_DFU_DNBUSY == dfu->bState) { + /* decode the special command */ + if(0U == dfu->block_num) { + if(1U == dfu->data_len) { + if(GET_COMMANDS == dfu->buf[0]) { + /* no operation */ + } + } else if(5U == dfu->data_len) { + if(SET_ADDRESS_POINTER == dfu->buf[0]) { + /* set flash operation address */ + dfu->base_addr = *(uint32_t *)(dfu->buf + 1U); + } else if(ERASE == dfu->buf[0]) { + dfu->base_addr = *(uint32_t *)(dfu->buf + 1U); + + dfu_mal_erase(dfu->base_addr); + } else { + /* no operation */ + } + } else { + /* no operation */ + } + } else if(dfu->block_num > 1U) { /* regular download command */ + /* decode the required address */ + addr = (dfu->block_num - 2U) * TRANSFER_SIZE + dfu->base_addr; + + dfu_mal_write(dfu->buf, addr, dfu->data_len); + + dfu->block_num = 0U; + } else { + /* no operation */ + } + + dfu->data_len = 0U; + + /* update the device state and poll timeout */ + dfu->bState = STATE_DFU_DNLOAD_SYNC; + + return USBD_OK; + } else if(STATE_DFU_MANIFEST == dfu->bState) { /* manifestation in progress */ + /* start leaving DFU mode */ + dfu_mode_leave(udev); + } else { + /* no operation */ + } + + return USBD_OK; +} + +/*! + \brief handle the DFU_DETACH request + \param[in] udev: pointer to USB device instance + \param[in] req: DFU class request + \param[out] none + \retval none. +*/ +static void dfu_detach(usb_dev *udev, usb_req *req) +{ + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + switch(dfu->bState) { + case STATE_DFU_IDLE: + case STATE_DFU_DNLOAD_SYNC: + case STATE_DFU_DNLOAD_IDLE: + case STATE_DFU_MANIFEST_SYNC: + case STATE_DFU_UPLOAD_IDLE: + dfu->bStatus = STATUS_OK; + dfu->bState = STATE_DFU_IDLE; + dfu->iString = 0U; /* iString */ + + dfu->block_num = 0U; + dfu->data_len = 0U; + break; + + default: + break; + } + + /* check the detach capability in the DFU functional descriptor */ + if(dfu_config_desc.dfu_func.wDetachTimeOut & DFU_DETACH_MASK) { + usbd_disconnect(udev); + + usbd_connect(udev); + } else { + /* wait for the period of time specified in detach request */ + usb_mdelay(4U); + } +} + +/*! + \brief handle the DFU_DNLOAD request + \param[in] udev: pointer to USB device instance + \param[in] req: DFU class request + \param[out] none + \retval none +*/ +static void dfu_dnload(usb_dev *udev, usb_req *req) +{ + usb_transc *transc = &udev->dev.transc_out[0]; + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + switch(dfu->bState) { + case STATE_DFU_IDLE: + case STATE_DFU_DNLOAD_IDLE: + if(req->wLength > 0U) { + /* update the global length and block number */ + dfu->block_num = req->wValue; + dfu->data_len = req->wLength; + + dfu->bState = STATE_DFU_DNLOAD_SYNC; + + transc->remain_len = dfu->data_len; + transc->xfer_buf = dfu->buf; + } else { + dfu->manifest_state = MANIFEST_IN_PROGRESS; + dfu->bState = STATE_DFU_MANIFEST_SYNC; + } + break; + + default: + break; + } +} + +/*! + \brief handles the DFU_UPLOAD request. + \param[in] udev: pointer to USB device instance + \param[in] req: DFU class request + \param[out] none + \retval none +*/ +static void dfu_upload(usb_dev *udev, usb_req *req) +{ + uint8_t *phy_addr = NULL; + uint32_t addr = 0U; + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + usb_transc *transc = &udev->dev.transc_in[0]; + + if(req->wLength <= 0U) { + dfu->bState = STATE_DFU_IDLE; + return; + } + + switch(dfu->bState) { + case STATE_DFU_IDLE: + case STATE_DFU_UPLOAD_IDLE: + /* update the global length and block number */ + dfu->block_num = req->wValue; + dfu->data_len = req->wLength; + + /* DFU get command */ + if(0U == dfu->block_num) { + /* update the state machine */ + dfu->bState = (dfu->data_len > 3U) ? STATE_DFU_IDLE : STATE_DFU_UPLOAD_IDLE; + + /* store the values of all supported commands */ + dfu->buf[0] = GET_COMMANDS; + dfu->buf[1] = SET_ADDRESS_POINTER; + dfu->buf[2] = ERASE; + + /* send the status data over EP0 */ + transc->xfer_buf = &(dfu->buf[0]); + transc->remain_len = 3U; + } else if(dfu->block_num > 1U) { + dfu->bState = STATE_DFU_UPLOAD_IDLE; + + /* change is accelerated */ + addr = (dfu->block_num - 2U) * TRANSFER_SIZE + dfu->base_addr; + + /* return the physical address where data are stored */ + phy_addr = dfu_mal_read(dfu->buf, addr, dfu->data_len); + + /* send the status data over EP0 */ + transc->xfer_buf = phy_addr; + transc->remain_len = dfu->data_len; + } else { + dfu->bState = STATUS_ERR_STALLEDPKT; + } + break; + + default: + dfu->data_len = 0U; + dfu->block_num = 0U; + break; + } +} + +/*! + \brief handle the DFU_GETSTATUS request + \param[in] udev: pointer to USB device instance + \param[in] req: DFU class request + \param[out] none + \retval none +*/ +static void dfu_getstatus(usb_dev *udev, usb_req *req) +{ + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + usb_transc *transc = &udev->dev.transc_in[0]; + + switch(dfu->bState) { + case STATE_DFU_DNLOAD_SYNC: + if(0U != dfu->data_len) { + dfu->bState = STATE_DFU_DNBUSY; + + if(0U == dfu->block_num) { + if(ERASE == dfu->buf[0]) { + dfu_mal_getstatus(dfu->base_addr, CMD_ERASE, (uint8_t *)&dfu->bwPollTimeout0); + } else { + dfu_mal_getstatus(dfu->base_addr, CMD_WRITE, (uint8_t *)&dfu->bwPollTimeout0); + } + } + } else { + dfu->bState = STATE_DFU_DNLOAD_IDLE; + } + break; + + case STATE_DFU_MANIFEST_SYNC: + if(MANIFEST_IN_PROGRESS == dfu->manifest_state) { + dfu->bState = STATE_DFU_MANIFEST; + dfu->bwPollTimeout0 = 1U; + } else if((MANIFEST_COMPLETE == dfu->manifest_state) && \ + (dfu_config_desc.dfu_func.bmAttributes & 0x04U)) { + dfu->bState = STATE_DFU_IDLE; + dfu->bwPollTimeout0 = 0U; + } else { + /* no operation */ + } + break; + + default: + break; + } + + /* send the status data of DFU interface to host over EP0 */ + transc->xfer_buf = (uint8_t *) & (dfu->bStatus); + transc->remain_len = 6U; +} + +/*! + \brief handle the DFU_CLRSTATUS request + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void dfu_clrstatus(usb_dev *udev, usb_req *req) +{ + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + if(STATE_DFU_ERROR == dfu->bState) { + dfu->bStatus = STATUS_OK; + dfu->bState = STATE_DFU_IDLE; + } else { + /* state error */ + dfu->bStatus = STATUS_ERR_UNKNOWN; + dfu->bState = STATE_DFU_ERROR; + } + + dfu->iString = 0U; /* iString: index = 0 */ +} + +/*! + \brief handle the DFU_GETSTATE request + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void dfu_getstate(usb_dev *udev, usb_req *req) +{ + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + usb_transc *transc = &udev->dev.transc_in[0]; + + /* send the current state of the DFU interface to host */ + transc->xfer_buf = &(dfu->bState); + transc->remain_len = 1U; +} + +/*! + \brief handle the DFU_ABORT request + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void dfu_abort(usb_dev *udev, usb_req *req) +{ + usbd_dfu_handler *dfu = (usbd_dfu_handler *)udev->dev.class_data[USBD_DFU_INTERFACE]; + + switch(dfu->bState) { + case STATE_DFU_IDLE: + case STATE_DFU_DNLOAD_SYNC: + case STATE_DFU_DNLOAD_IDLE: + case STATE_DFU_MANIFEST_SYNC: + case STATE_DFU_UPLOAD_IDLE: + dfu->bStatus = STATUS_OK; + dfu->bState = STATE_DFU_IDLE; + dfu->iString = 0U; /* iString: index = 0 */ + + dfu->block_num = 0U; + dfu->data_len = 0U; + break; + + default: + break; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_mal.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_mal.c new file mode 100644 index 0000000000..30ccc9d563 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/dfu/Source/dfu_mal.c @@ -0,0 +1,218 @@ +/*! + \file dfu_mal.c + \brief USB DFU device media access layer functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "dfu_mal.h" +#include "flash_if.h" +#include "drv_usb_hw.h" +#include "usbd_transc.h" + +extern usb_core_driver usb_dfu_dev; + +extern struct { + uint8_t buf[TRANSFER_SIZE]; + uint16_t data_len; + uint16_t block_num; + uint32_t base_addr; +} prog; + +dfu_mal_prop *tMALTab[MAX_USED_MEMORY_MEDIA] = { + &DFU_Flash_cb +}; + +/* The list of memory interface string descriptor pointers. This list + can be updated whenever a memory has to be added or removed */ +const uint8_t *USBD_DFU_StringDesc[MAX_USED_MEMORY_MEDIA] = { + (const uint8_t *)FLASH_IF_STRING +}; + +static uint8_t dfu_mal_checkaddr(uint32_t addr); + +/*! + \brief initialize the memory media on the GD32 + \param[in] none + \param[out] none + \retval MAL_OK +*/ +uint8_t dfu_mal_init(void) +{ + uint32_t mem_index = 0U; + + /* initialize all supported memory medias */ + for(mem_index = 0U; mem_index < MAX_USED_MEMORY_MEDIA; mem_index++) { + /* check if the memory media exists */ + if(NULL != tMALTab[mem_index]->mal_init) { + tMALTab[mem_index]->mal_init(); + } + } + + return MAL_OK; +} + +/*! + \brief deinitialize the memory media on the GD32 + \param[in] none + \param[out] none + \retval MAL_OK +*/ +uint8_t dfu_mal_deinit(void) +{ + uint32_t mem_index = 0U; + + /* deinitializes all supported memory medias */ + for(mem_index = 0U; mem_index < MAX_USED_MEMORY_MEDIA; mem_index++) { + /* check if the memory media exists */ + if(NULL != tMALTab[mem_index]->mal_deinit) { + tMALTab[mem_index]->mal_deinit(); + } + } + + return MAL_OK; +} + +/*! + \brief erase a memory sector + \param[in] addr: memory sector address/code + \param[out] none + \retval MAL_OK +*/ +uint8_t dfu_mal_erase(uint32_t addr) +{ + uint32_t mem_index = dfu_mal_checkaddr(addr); + + if(mem_index < MAX_USED_MEMORY_MEDIA) { + /* check if the operation is supported */ + if(NULL != tMALTab[mem_index]->mal_erase) { + return tMALTab[mem_index]->mal_erase(addr); + } else { + return MAL_FAIL; + } + } else { + return MAL_FAIL; + } +} + +/*! + \brief write data to sectors of memory + \param[in] buf: the data buffer to be write + \param[in] addr: memory sector address/code + \param[in] len: data length + \param[out] none + \retval MAL_OK +*/ +uint8_t dfu_mal_write(uint8_t *buf, uint32_t addr, uint32_t len) +{ + uint32_t mem_index = dfu_mal_checkaddr(addr); + + if(mem_index < MAX_USED_MEMORY_MEDIA) { + /* check if the operation is supported */ + if(NULL != tMALTab[mem_index]->mal_write) { + return tMALTab[mem_index]->mal_write(buf, addr, len); + } else { + return MAL_FAIL; + } + } else { + return MAL_FAIL; + } +} + +/*! + \brief read data from sectors of memory + \param[in] buf: the data buffer to be write + \param[in] addr: memory sector address/code + \param[in] len: data length + \param[out] none + \retval pointer to buffer +*/ +uint8_t *dfu_mal_read(uint8_t *buf, uint32_t addr, uint32_t len) +{ + uint32_t mem_index = 0U; + + if(mem_index < MAX_USED_MEMORY_MEDIA) { + /* check if the operation is supported */ + if(NULL != tMALTab[mem_index]->mal_read) { + return tMALTab[mem_index]->mal_read(buf, addr, len); + } else { + return buf; + } + } else { + return buf; + } +} + +/*! + \brief get the status of a given memory and store in buffer + \param[in] addr: memory sector address/code + \param[in] cmd: 0 for erase and 1 for write + \param[in] buffer: pointer to the buffer where the status data will be stored + \param[out] none + \retval MAL_OK if all operations are OK, MAL_FAIL else +*/ +uint8_t dfu_mal_getstatus(uint32_t addr, uint8_t cmd, uint8_t *buffer) +{ + uint32_t mem_index = dfu_mal_checkaddr(addr); + + if(mem_index < MAX_USED_MEMORY_MEDIA) { + if(cmd & 0x01U) { + SET_POLLING_TIMEOUT(tMALTab[mem_index]->write_timeout); + } else { + SET_POLLING_TIMEOUT(tMALTab[mem_index]->erase_timeout); + } + + return MAL_OK; + } else { + return MAL_FAIL; + } +} + +/*! + \brief check the address is supported + \param[in] addr: memory sector address/code + \param[out] none + \retval index of the addressed memory +*/ +static uint8_t dfu_mal_checkaddr(uint32_t addr) +{ + uint8_t mem_index = 0U; + + /* check with all supported memories */ + for(mem_index = 0U; mem_index < MAX_USED_MEMORY_MEDIA; mem_index++) { + /* if the check address is supported, return the memory index */ + if(MAL_OK == tMALTab[mem_index]->mal_checkaddr(addr)) { + return mem_index; + } + } + + /* if there is no memory found, return MAX_USED_MEMORY_MEDIA */ + return (MAX_USED_MEMORY_MEDIA); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/custom_hid_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/custom_hid_core.h new file mode 100644 index 0000000000..2f6ab0ac0f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/custom_hid_core.h @@ -0,0 +1,66 @@ +/*! + \file custom_hid_core.h + \brief definitions for HID core + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __CUSTOM_HID_CORE_H +#define __CUSTOM_HID_CORE_H + +#include "usbd_enum.h" +#include "usb_hid.h" + +#define DESC_LEN_REPORT 96U +#define DESC_LEN_CONFIG 41U +#define NO_CMD 0xFFU +#define MAX_PERIPH_NUM 4U + +typedef struct { + __ALIGN_BEGIN uint8_t data[2] __ALIGN_END; + uint8_t reportID; + uint8_t idlestate; + uint8_t protocol; +} custom_hid_handler; + +typedef struct { + void (*periph_config[MAX_PERIPH_NUM])(void); +} hid_fop_handler; + +extern usb_desc custom_hid_desc; +extern usb_class_core usbd_custom_hid_cb; + +/* function declarations */ +/* register HID interface operation functions */ +uint8_t custom_hid_itfop_register (usb_dev *udev, hid_fop_handler *hid_fop); +/* send custom HID report */ +uint8_t custom_hid_report_send (usb_dev *udev, uint8_t *report, uint32_t len); + +#endif /* __CUSTOM_HID_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/standard_hid_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/standard_hid_core.h new file mode 100644 index 0000000000..96a8ae5b59 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/standard_hid_core.h @@ -0,0 +1,70 @@ +/*! + \file standard_hid_core.h + \brief definitions for HID core + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __STANDARD_HID_CORE_H +#define __STANDARD_HID_CORE_H + +#include "usbd_enum.h" +#include "usb_hid.h" + +#define USB_BOS_DESC_SIZE 0x0C +#define USB_DEVICE_CAPABITY 0x10 + +#define USB_HID_CONFIG_DESC_LEN 0x22U +#define USB_HID_REPORT_DESC_LEN 0x2EU + +#define NO_CMD 0xFFU + +typedef struct { + uint32_t protocol; + uint32_t idle_state; + __ALIGN_BEGIN uint8_t data[HID_IN_PACKET] __ALIGN_END; + __IO uint8_t prev_transfer_complete; +} standard_hid_handler; + +typedef struct { + void (*hid_itf_config) (void); + void (*hid_itf_data_process) (usb_dev *udev); +} hid_fop_handler; + +extern usb_desc hid_desc; +extern usb_class_core usbd_hid_cb; + +/* function declarations */ +/* register HID interface operation functions */ +uint8_t hid_itfop_register (usb_dev *udev, hid_fop_handler *hid_fop); +/* send keyboard report */ +uint8_t hid_report_send (usb_dev *udev, uint8_t *report, uint32_t len); + +#endif /* __STANDARD_HID_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/std_hid_mouse_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/std_hid_mouse_core.h new file mode 100644 index 0000000000..8c5a9cf2ac --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Include/std_hid_mouse_core.h @@ -0,0 +1,71 @@ +/*! + \file std_hid_mouse_core.h + \brief definitions for HID Mouse core + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __STD_HID_MOUSE_CORE_H +#define __STD_HID_MOUSE_CORE_H + +#include "usbd_enum.h" +#include "usb_hid.h" + +#define USB_HID_CONFIG_DESC_LEN 0x22U +#define USB_HID_REPORT_DESC_LEN 0x34U + +#define MOUSE_LEFT_BUTTON 0x01U +#define MOUSE_RIGHT_BUTTON 0x02U + +#define NO_CMD 0xFFU + +typedef struct { + uint32_t protocol; + uint32_t idle_state; + + uint8_t data[HID_IN_PACKET]; + __IO uint8_t prev_transfer_complete; +} standard_mice_handler; + +typedef struct { + void (*mice_itf_config) (void); + void (*mice_itf_data_process) (usb_dev *udev); +} mice_fop_handler; + +extern usb_desc hid_mouse_desc; +extern usb_class_core usbd_hid_cb; + +/* function declarations */ +/* register HID interface operation functions */ +uint8_t hid_itfop_register (usb_dev *udev, mice_fop_handler *hid_fop); +/* send mouse report */ +uint8_t hid_report_send (usb_dev *udev, uint8_t *report, uint16_t len); + +#endif /* __STD_HID_MOUSE_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/custom_hid_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/custom_hid_core.c new file mode 100644 index 0000000000..86e039d5d5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/custom_hid_core.c @@ -0,0 +1,463 @@ +/*! + \file custom_hid_core.c + \brief custom HID class driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "custom_hid_core.h" +#include "usbd_enum.h" +#include + +#define USBD_VID 0x28E9U +#define USBD_PID 0x028AU + +/* Note:it should use the C99 standard when compiling the below codes */ +/* USB standard device descriptor */ +__ALIGN_BEGIN const usb_desc_dev custom_hid_dev_desc __ALIGN_END = { + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV, + }, + .bcdUSB = 0x0200U, + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM, +}; + +/* USB device configuration descriptor */ +__ALIGN_BEGIN const usb_hid_desc_config_set custom_hid_config_desc __ALIGN_END = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = DESC_LEN_CONFIG, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0x80U, + .bMaxPower = 0x32U + }, + + .hid_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x02U, + .bInterfaceClass = USB_HID_CLASS, + .bInterfaceSubClass = 0x00U, + .bInterfaceProtocol = 0x00U, + .iInterface = 0x00U + }, + + .hid_vendor = + { + .header = + { + .bLength = sizeof(usb_desc_hid), + .bDescriptorType = USB_DESCTYPE_HID + }, + .bcdHID = 0x0111U, + .bCountryCode = 0x00U, + .bNumDescriptors = 0x01U, + .bDescriptorType = USB_DESCTYPE_REPORT, + .wDescriptorLength = DESC_LEN_REPORT, + }, + + .hid_epin = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = CUSTOMHID_IN_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = CUSTOMHID_IN_PACKET, + .bInterval = 0x02U + }, + + .hid_epout = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = CUSTOMHID_OUT_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = CUSTOMHID_OUT_PACKET, + .bInterval = 0x02U + } +}; + +/* USB language ID descriptor */ +__ALIGN_BEGIN static const usb_desc_LANGID usbd_language_id_desc __ALIGN_END = { + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +__ALIGN_BEGIN static const usb_desc_str manufacturer_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(10U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +__ALIGN_BEGIN static const usb_desc_str product_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(14U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'C', 'u', 's', 't', 'o', 'm', 'H', 'I', 'D'} +}; + +/* USB serial string */ +__ALIGN_BEGIN static usb_desc_str serial_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +/* USB string descriptor set */ +void *const usbd_hid_strings[] = { + [STR_IDX_LANGID] = (uint8_t *) &usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *) &manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *) &product_string, + [STR_IDX_SERIAL] = (uint8_t *) &serial_string +}; + +usb_desc custom_hid_desc = { + .dev_desc = (uint8_t *) &custom_hid_dev_desc, + .config_desc = (uint8_t *) &custom_hid_config_desc, + .strings = usbd_hid_strings +}; + +__ALIGN_BEGIN const uint8_t customhid_report_descriptor[DESC_LEN_REPORT] __ALIGN_END = { + 0x06, 0x00, 0xFF, /* USAGE_PAGE (Vendor Defined: 0xFF00) */ + 0x09, 0x00, /* USAGE (Custom Device) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + + /* led 1 */ + 0x85, 0x11, /* REPORT_ID (0x11) */ + 0x09, 0x01, /* USAGE (LED 1) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */ + + /* led 2 */ + 0x85, 0x12, /* REPORT_ID (0x12) */ + 0x09, 0x02, /* USAGE (LED 2) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */ + + /* led 3 */ + 0x85, 0x13, /* REPORT_ID (0x13) */ + 0x09, 0x03, /* USAGE (LED 3) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */ + + /* led 4 */ + 0x85, 0x14, /* REPORT_ID (0x14) */ + 0x09, 0x04, /* USAGE (LED 4) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */ + + /* wakeup key */ + 0x85, 0x15, /* REPORT_ID (0x15) */ + 0x09, 0x05, /* USAGE (Push Button) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs,Vol) */ + + 0x75, 0x07, /* REPORT_SIZE (7) */ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs,Vol) */ + + /* tamper key */ + 0x85, 0x16, /* REPORT_ID (0x16) */ + 0x09, 0x06, /* USAGE (Push Button) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs,Vol) */ + + 0x75, 0x07, /* REPORT_SIZE (7) */ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs,Vol) */ + + 0xc0 /* END_COLLECTION */ +}; + +/* local function prototypes ('static') */ +static uint8_t custom_hid_init(usb_dev *udev, uint8_t config_index); +static uint8_t custom_hid_deinit(usb_dev *udev, uint8_t config_index); +static uint8_t custom_hid_req_handler(usb_dev *udev, usb_req *req); + +static uint8_t custom_hid_data_in(usb_dev *udev, uint8_t ep_num); +static uint8_t custom_hid_data_out(usb_dev *udev, uint8_t ep_num); + +usb_class_core usbd_custom_hid_cb = { + .command = NO_CMD, + .alter_set = 0U, + + .init = custom_hid_init, + .deinit = custom_hid_deinit, + + .req_proc = custom_hid_req_handler, + + .data_in = custom_hid_data_in, + .data_out = custom_hid_data_out +}; + +/*! + \brief register HID interface operation functions + \param[in] udev: pointer to USB device instance + \param[in] hid_fop: HID operation functions structure + \param[out] none + \retval USB device operation status +*/ +uint8_t custom_hid_itfop_register(usb_dev *udev, hid_fop_handler *hid_fop) +{ + if(NULL != hid_fop) { + udev->dev.user_data = hid_fop; + + return USBD_OK; + } + + return USBD_FAIL; +} + +/*! + \brief send custom HID report + \param[in] udev: pointer to USB device instance + \param[in] report: pointer to HID report + \param[in] len: data length + \param[out] none + \retval USB device operation status +*/ +uint8_t custom_hid_report_send(usb_dev *udev, uint8_t *report, uint32_t len) +{ + usbd_ep_send(udev, CUSTOMHID_IN_EP, report, len); + + return USBD_OK; +} + +/*! + \brief initialize the HID device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t custom_hid_init(usb_dev *udev, uint8_t config_index) +{ + static custom_hid_handler hid_handler; + + memset((void *)&hid_handler, 0U, sizeof(custom_hid_handler)); + + /* initialize the data TX endpoint */ + usbd_ep_setup(udev, &(custom_hid_config_desc.hid_epin)); + + /* initialize the data RX endpoint */ + usbd_ep_setup(udev, &(custom_hid_config_desc.hid_epout)); + + /* prepare receive data */ + usbd_ep_recev(udev, CUSTOMHID_OUT_EP, hid_handler.data, 2U); + + udev->dev.class_data[CUSTOM_HID_INTERFACE] = (void *)&hid_handler; + + if(udev->dev.user_data != NULL) { + for(uint8_t i = 0U; i < MAX_PERIPH_NUM; i++) { + if(((hid_fop_handler *)udev->dev.user_data)->periph_config[i] != NULL) { + ((hid_fop_handler *)udev->dev.user_data)->periph_config[i](); + } + } + } + + return USBD_OK; +} + +/*! + \brief de-initialize the HID device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t custom_hid_deinit(usb_dev *udev, uint8_t config_index) +{ + /* deinitialize HID endpoints */ + usbd_ep_clear(udev, CUSTOMHID_IN_EP); + usbd_ep_clear(udev, CUSTOMHID_OUT_EP); + + return USBD_OK; +} + +/*! + \brief handle the HID class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t custom_hid_req_handler(usb_dev *udev, usb_req *req) +{ + usb_transc *transc = &udev->dev.transc_in[0]; + + custom_hid_handler *hid = (custom_hid_handler *)udev->dev.class_data[CUSTOM_HID_INTERFACE]; + + switch(req->bRequest) { + case GET_REPORT: + break; + + case GET_IDLE: + transc->xfer_buf = (uint8_t *)&hid->idlestate; + transc->remain_len = 1U; + break; + + case GET_PROTOCOL: + transc->xfer_buf = (uint8_t *)&hid->protocol; + transc->remain_len = 1U; + break; + + case SET_REPORT: + hid->reportID = (uint8_t)(req->wValue); + break; + + case SET_IDLE: + hid->idlestate = (uint8_t)(req->wValue >> 8U); + break; + + case SET_PROTOCOL: + hid->protocol = (uint8_t)(req->wValue); + break; + + case USB_GET_DESCRIPTOR: + if(USB_DESCTYPE_REPORT == (req->wValue >> 8U)) { + transc->remain_len = USB_MIN(DESC_LEN_REPORT, req->wLength); + transc->xfer_buf = (uint8_t *)customhid_report_descriptor; + } + break; + + default: + return USBD_FAIL; + } + + return USBD_OK; +} + +/*! + \brief handle custom HID data + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier + \param[out] none + \retval USB device operation status +*/ +static uint8_t custom_hid_data_in(usb_dev *udev, uint8_t ep_num) +{ + return USBD_OK; +} + +/*! + \brief handle custom HID data + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier + \param[out] none + \retval USB device operation status +*/ +static uint8_t custom_hid_data_out(usb_dev *udev, uint8_t ep_num) +{ + custom_hid_handler *hid = (custom_hid_handler *)udev->dev.class_data[CUSTOM_HID_INTERFACE]; + + switch(hid->data[0]) { + case 0x11U: + if(RESET != hid->data[1]) { + gd_eval_led_on(LED1); + } else { + gd_eval_led_off(LED1); + } + break; + + case 0x12U: + if(RESET != hid->data[1]) { + gd_eval_led_on(LED2); + } else { + gd_eval_led_off(LED2); + } + break; + + default: + break; + } + + usbd_ep_recev(udev, CUSTOMHID_OUT_EP, hid->data, 2U); + + return USBD_OK; + +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/standard_hid_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/standard_hid_core.c new file mode 100644 index 0000000000..572044acc0 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/standard_hid_core.c @@ -0,0 +1,488 @@ +/*! + \file standard_hid_core.c + \brief HID class driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "standard_hid_core.h" +#include + +#define USBD_VID 0x28e9U +#define USBD_PID 0x0380U + +/* Note:it should use the C99 standard when compiling the below codes */ +/* USB standard device descriptor */ +__ALIGN_BEGIN const usb_desc_dev hid_dev_desc __ALIGN_END = { + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV + }, +#if (1 == LPM_ENABLED) + .bcdUSB = 0x0201U, +#else + .bcdUSB = 0x0200U, +#endif /* LPM_ENABLED */ + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM +}; + +__ALIGN_BEGIN const usb_hid_desc_config_set hid_config_desc __ALIGN_END = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = USB_HID_CONFIG_DESC_LEN, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0xA0U, + .bMaxPower = 0x32U + }, + + .hid_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x01U, + .bInterfaceClass = USB_HID_CLASS, + .bInterfaceSubClass = USB_HID_SUBCLASS_BOOT_ITF, + .bInterfaceProtocol = USB_HID_PROTOCOL_KEYBOARD, + .iInterface = 0x00U + }, + + .hid_vendor = + { + .header = + { + .bLength = sizeof(usb_desc_hid), + .bDescriptorType = USB_DESCTYPE_HID + }, + .bcdHID = 0x0111U, + .bCountryCode = 0x00U, + .bNumDescriptors = 0x01U, + .bDescriptorType = USB_DESCTYPE_REPORT, + .wDescriptorLength = USB_HID_REPORT_DESC_LEN, + }, + + .hid_epin = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = HID_IN_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = HID_IN_PACKET, + .bInterval = 0x01U + } +}; + +__ALIGN_BEGIN const usb_hid_desc_config_set other_speed_hid_config_desc __ALIGN_END = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_OTHER_SPD_CONFIG + }, + .wTotalLength = USB_HID_CONFIG_DESC_LEN, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0xA0U, + .bMaxPower = 0x32U + }, + + .hid_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x01U, + .bInterfaceClass = USB_HID_CLASS, + .bInterfaceSubClass = USB_HID_SUBCLASS_BOOT_ITF, + .bInterfaceProtocol = USB_HID_PROTOCOL_KEYBOARD, + .iInterface = 0x00U + }, + + .hid_vendor = + { + .header = + { + .bLength = sizeof(usb_desc_hid), + .bDescriptorType = USB_DESCTYPE_HID + }, + .bcdHID = 0x0111U, + .bCountryCode = 0x00U, + .bNumDescriptors = 0x01U, + .bDescriptorType = USB_DESCTYPE_REPORT, + .wDescriptorLength = USB_HID_REPORT_DESC_LEN, + }, + + .hid_epin = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = HID_IN_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = HID_IN_PACKET, + .bInterval = 0x01U + } +}; + +__ALIGN_BEGIN const uint8_t usbd_qualifier_desc[10] __ALIGN_END = { + 0x0A, + 0x06, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00 +}; + +#if (1 == LPM_ENABLED) + +/* USBD BOS descriptor */ +__ALIGN_BEGIN uint8_t usbd_bos_desc[USB_BOS_DESC_SIZE] __ALIGN_END = { + 0x05, + USB_DESCTYPE_BOS, + 0x0C, + 0x00, + 0x01, /* 1 device capability desc */ + + /* device capability*/ + 0x07, + USB_DEVICE_CAPABITY, + 0x02, + 0x06, /* LPM capability bit set */ + 0x00, + 0x00, + 0x00 +}; + +#endif /* LPM_ENABLED */ + +/* USB language ID Descriptor */ +__ALIGN_BEGIN const usb_desc_LANGID usbd_language_id_desc __ALIGN_END = { + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +__ALIGN_BEGIN static const usb_desc_str manufacturer_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(10U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +__ALIGN_BEGIN static const usb_desc_str product_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(17U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'K', 'e', 'y', 'b', 'o', 'a', 'r', 'd'} +}; + +/* USBD serial string */ +__ALIGN_BEGIN static usb_desc_str serial_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +void *const usbd_hid_strings[] = { + [STR_IDX_LANGID] = (uint8_t *) &usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *) &manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *) &product_string, + [STR_IDX_SERIAL] = (uint8_t *) &serial_string +}; + +usb_desc hid_desc = { + .dev_desc = (uint8_t *) &hid_dev_desc, + .config_desc = (uint8_t *) &hid_config_desc, +#if (1 == LPM_ENABLED) + .bos_desc = (uint8_t *) &usbd_bos_desc, +#endif /* LPM_ENABLED */ + +#ifdef USE_USB_HS + .other_speed_config_desc = (uint8_t *) &other_speed_hid_config_desc, + .qualifier_desc = (uint8_t *) &usbd_qualifier_desc, +#endif + .strings = usbd_hid_strings +}; + +__ALIGN_BEGIN const uint8_t hid_report_desc[USB_HID_REPORT_DESC_LEN] __ALIGN_END = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x06, /* USAGE (Keyboard) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + + 0x05, 0x07, /* USAGE_PAGE (Keyboard/Keypad) */ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x95, 0x08, /* REPORT_COUNT (8) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ + + 0x95, 0x06, /* REPORT_COUNT (6) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x26, 0xFF, 0x00, /* LOGICAL_MAXIMUM (255) */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard/Keypad) */ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated)) */ + 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + + 0xc0 /* END_COLLECTION */ +}; + +/* local function prototypes ('static') */ +static uint8_t hid_init(usb_dev *udev, uint8_t config_index); +static uint8_t hid_deinit(usb_dev *udev, uint8_t config_index); +static uint8_t hid_req(usb_dev *udev, usb_req *req); +static uint8_t hid_data_in(usb_dev *udev, uint8_t ep_num); + +usb_class_core usbd_hid_cb = { + .command = NO_CMD, + .alter_set = 0U, + + .init = hid_init, + .deinit = hid_deinit, + .req_proc = hid_req, + .data_in = hid_data_in +}; + +/*! + \brief register HID interface operation functions + \param[in] udev: pointer to USB device instance + \param[in] hid_fop: HID operation function structure + \param[out] none + \retval USB device operation status +*/ +uint8_t hid_itfop_register(usb_dev *udev, hid_fop_handler *hid_fop) +{ + if(NULL != hid_fop) { + udev->dev.user_data = (void *)hid_fop; + + return USBD_OK; + } + + return USBD_FAIL; +} + +/*! + \brief send keyboard report + \param[in] udev: pointer to USB device instance + \param[in] report: pointer to HID report + \param[in] len: data length + \param[out] none + \retval USB device operation status +*/ +uint8_t hid_report_send(usb_dev *udev, uint8_t *report, uint32_t len) +{ + standard_hid_handler *hid = (standard_hid_handler *)udev->dev.class_data[USBD_HID_INTERFACE]; + + hid->prev_transfer_complete = 0U; + + usbd_ep_send(udev, HID_IN_EP, report, len); + + return USBD_OK; +} + +/*! + \brief initialize the HID device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_init(usb_dev *udev, uint8_t config_index) +{ + static standard_hid_handler hid_handler; + + memset((void *)&hid_handler, 0U, sizeof(standard_hid_handler)); + + /* initialize the data TX endpoint */ + usbd_ep_setup(udev, &(hid_config_desc.hid_epin)); + + hid_handler.prev_transfer_complete = 1U; + + udev->dev.class_data[USBD_HID_INTERFACE] = (void *)&hid_handler; + + if(NULL != udev->dev.user_data) { + ((hid_fop_handler *)udev->dev.user_data)->hid_itf_config(); + } + + return USBD_OK; +} + +/*! + \brief de-initialize the HID device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_deinit(usb_dev *udev, uint8_t config_index) +{ + /* deinitialize HID endpoints */ + usbd_ep_clear(udev, HID_IN_EP); + + return USBD_OK; +} + +/*! + \brief handle the HID class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_req(usb_dev *udev, usb_req *req) +{ + usb_transc *transc = &udev->dev.transc_in[0]; + + standard_hid_handler *hid = (standard_hid_handler *)udev->dev.class_data[USBD_HID_INTERFACE]; + + switch(req->bRequest) { + case GET_REPORT: + /* no use for this driver */ + break; + + case GET_IDLE: + transc->xfer_buf = (uint8_t *)&hid->idle_state; + + transc->remain_len = 1U; + break; + + case GET_PROTOCOL: + transc->xfer_buf = (uint8_t *)&hid->protocol; + + transc->remain_len = 1U; + break; + + case SET_REPORT: + /* no use for this driver */ + break; + + case SET_IDLE: + hid->idle_state = (uint8_t)(req->wValue >> 8U); + break; + + case SET_PROTOCOL: + hid->protocol = (uint8_t)(req->wValue); + break; + + case USB_GET_DESCRIPTOR: + if(USB_DESCTYPE_REPORT == (req->wValue >> 8U)) { + transc->remain_len = USB_MIN(USB_HID_REPORT_DESC_LEN, req->wLength); + transc->xfer_buf = (uint8_t *)hid_report_desc; + + return REQ_SUPP; + } else if(USB_DESCTYPE_HID == (req->wValue >> 8U)) { + transc->remain_len = USB_MIN(9U, req->wLength); + transc->xfer_buf = (uint8_t *)(&(hid_config_desc.hid_vendor)); + } + break; + + default: + break; + } + + return USBD_OK; +} + +/*! + \brief handle data stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_data_in(usb_dev *udev, uint8_t ep_num) +{ + standard_hid_handler *hid = (standard_hid_handler *)udev->dev.class_data[USBD_HID_INTERFACE]; + + if(0U != hid->data[2]) { + hid->data[2] = 0x00U; + + usbd_ep_send(udev, HID_IN_EP, hid->data, HID_IN_PACKET); + } else { + hid->prev_transfer_complete = 1U; + } + + return USBD_OK; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/std_hid_mouse_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/std_hid_mouse_core.c new file mode 100644 index 0000000000..a57f1fe5f0 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/hid/Source/std_hid_mouse_core.c @@ -0,0 +1,385 @@ +/*! + \file std_hid_mouse_core.c + \brief HID class driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "std_hid_mouse_core.h" +#include + +#define USBD_VID 0x28e9U +#define USBD_PID 0x0381U + +/* Note:it should use the C99 standard when compiling the below codes */ +/* USB standard device descriptor */ +const usb_desc_dev hid_dev_desc = { + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV + }, + .bcdUSB = 0x0200U, + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM +}; + +const usb_hid_desc_config_set hid_config_desc = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = USB_HID_CONFIG_DESC_LEN, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0xA0U, + .bMaxPower = 0x32U + }, + + .hid_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x01U, + .bInterfaceClass = USB_HID_CLASS, + .bInterfaceSubClass = USB_HID_SUBCLASS_BOOT_ITF, + .bInterfaceProtocol = USB_HID_PROTOCOL_MOUSE, + .iInterface = 0x00U + }, + + .hid_vendor = + { + .header = + { + .bLength = sizeof(usb_desc_hid), + .bDescriptorType = USB_DESCTYPE_HID + }, + .bcdHID = 0x0111U, + .bCountryCode = 0x00U, + .bNumDescriptors = 0x01U, + .bDescriptorType = USB_DESCTYPE_REPORT, + .wDescriptorLength = USB_HID_REPORT_DESC_LEN, + }, + + .hid_epin = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = HID_IN_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = HID_IN_PACKET, + .bInterval = 0x40U + } +}; + +/* USB language ID Descriptor */ +const usb_desc_LANGID usbd_language_id_desc = { + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +static const usb_desc_str manufacturer_string = { + .header = + { + .bLength = USB_STRING_LEN(10), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +static const usb_desc_str product_string = { + .header = + { + .bLength = USB_STRING_LEN(14), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'M', 'o', 'u', 's', 'e'} +}; + +/* USB serial string */ +static usb_desc_str serial_string = { + .header = + { + .bLength = USB_STRING_LEN(12), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +static void *const usbd_hid_strings[] = { + [STR_IDX_LANGID] = (uint8_t *) &usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *) &manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *) &product_string, + [STR_IDX_SERIAL] = (uint8_t *) &serial_string +}; + +usb_desc hid_mouse_desc = { + .dev_desc = (uint8_t *) &hid_dev_desc, + .config_desc = (uint8_t *) &hid_config_desc, + .strings = usbd_hid_strings +}; + +const uint8_t hid_report_desc[USB_HID_REPORT_DESC_LEN] = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x02, /* USAGE (Mouse) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x09, 0x01, /* USAGE (Pointer) */ + + 0xa1, 0x00, /* COLLECTION (Physical) */ + 0x05, 0x09, /* USAGE_PAGE (Button) */ + 0x19, 0x01, /* USAGE_MINIMUM (1) */ + 0x29, 0x03, /* USAGE_MAXIMUM (3) */ + + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x95, 0x03, /* REPORT_COUNT (3) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x05, /* REPORT_SIZE (5) */ + 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */ + + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x30, /* USAGE (X) */ + 0x09, 0x31, /* USAGE (Y) */ + 0x09, 0x38, /* USAGE (Wheel) */ + + 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ + 0x25, 0x7F, /* LOGICAL_MAXIMUM (127) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x03, /* REPORT_COUNT (3) */ + 0x81, 0x06, /* INPUT (Data,Var,Rel) */ + 0xc0, /* END_COLLECTION */ + 0xc0 /* END_COLLECTION */ +}; + +/* local function prototypes ('static') */ +static uint8_t hid_init(usb_dev *udev, uint8_t config_index); +static uint8_t hid_deinit(usb_dev *udev, uint8_t config_index); +static uint8_t hid_req(usb_dev *udev, usb_req *req); +static uint8_t hid_data_in(usb_dev *udev, uint8_t ep_num); + +usb_class_core usbd_hid_cb = { + .command = NO_CMD, + .alter_set = 0U, + + .init = hid_init, + .deinit = hid_deinit, + .req_proc = hid_req, + .data_in = hid_data_in +}; + +/*! + \brief register HID interface operation functions + \param[in] udev: pointer to USB device instance + \param[in] hid_fop: HID operation functions structure + \param[out] none + \retval USB device operation status +*/ +uint8_t hid_itfop_register(usb_dev *udev, mice_fop_handler *hid_fop) +{ + if(NULL != hid_fop) { + udev->dev.user_data = (void *)hid_fop; + + return USBD_OK; + } + + return USBD_FAIL; +} + +/*! + \brief send mouse report + \param[in] udev: pointer to USB device instance + \param[in] report: pointer to HID report + \param[in] len: data length + \param[out] none + \retval USB device operation status +*/ +uint8_t hid_report_send(usb_dev *udev, uint8_t *report, uint16_t len) +{ + standard_mice_handler *hid = (standard_mice_handler *)udev->dev.class_data[USBD_HID_INTERFACE]; + + if(USBD_CONFIGURED == udev->dev.cur_status) { + if(1 == hid->prev_transfer_complete) { + hid->prev_transfer_complete = 0U; + usbd_ep_send(udev, HID_IN_EP, report, len); + } + } + + return USBD_OK; +} + +/*! + \brief initialize the HID device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_init(usb_dev *udev, uint8_t config_index) +{ + static standard_mice_handler mice_handler; + + memset((void *)&mice_handler, 0U, sizeof(standard_mice_handler)); + + /* initialize the data Tx endpoint */ + usbd_ep_setup(udev, &(hid_config_desc.hid_epin)); + + mice_handler.prev_transfer_complete = 1U; + + udev->dev.class_data[USBD_HID_INTERFACE] = (void *)&mice_handler; + + if(NULL != udev->dev.user_data) { + ((mice_fop_handler *)(udev->dev.user_data))->mice_itf_config(); + } + + return USBD_OK; +} + +/*! + \brief de-initialize the HID device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_deinit(usb_dev *udev, uint8_t config_index) +{ + /* deinitialize HID endpoints */ + usbd_ep_clear(udev, HID_IN_EP); + + return USBD_OK; +} + +/*! + \brief handle the HID class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_req(usb_dev *udev, usb_req *req) +{ + usb_transc *transc = &udev->dev.transc_in[0]; + + standard_mice_handler *hid = (standard_mice_handler *)udev->dev.class_data[USBD_HID_INTERFACE]; + + switch(req->bRequest) { + case GET_REPORT: + /* no use for this driver */ + break; + + case GET_IDLE: + transc->xfer_buf = (uint8_t *)&hid->idle_state; + + transc->remain_len = 1U; + break; + + case GET_PROTOCOL: + transc->xfer_buf = (uint8_t *)&hid->protocol; + + transc->remain_len = 1U; + break; + + case SET_REPORT: + /* no use for this driver */ + break; + + case SET_IDLE: + hid->idle_state = (uint8_t)(req->wValue >> 8U); + break; + + case SET_PROTOCOL: + hid->protocol = (uint8_t)(req->wValue); + break; + + case USB_GET_DESCRIPTOR: + if(USB_DESCTYPE_REPORT == (req->wValue >> 8U)) { + transc->remain_len = USB_MIN(USB_HID_REPORT_DESC_LEN, req->wLength); + transc->xfer_buf = (uint8_t *)hid_report_desc; + + return REQ_SUPP; + } + break; + + default: + break; + } + + return USBD_OK; +} + +/*! + \brief handle data stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier + \param[out] none + \retval USB device operation status +*/ +static uint8_t hid_data_in(usb_dev *udev, uint8_t ep_num) +{ + standard_mice_handler *hid = (standard_mice_handler *)udev->dev.class_data[USBD_HID_INTERFACE]; + + if(0U == hid->data[0]) { + hid->prev_transfer_complete = 1U; + } else { + hid->data[0] = 0U; + usbd_ep_send(udev, HID_IN_EP, hid->data, HID_IN_PACKET); + } + + return USBD_OK; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Include/usb_iap_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Include/usb_iap_core.h new file mode 100644 index 0000000000..81d1e68bdc --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Include/usb_iap_core.h @@ -0,0 +1,91 @@ +/*! + \file usb_iap_core.h + \brief the header file of IAP driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USB_IAP_CORE_H +#define __USB_IAP_CORE_H + +#include "usbd_enum.h" +#include "usb_hid.h" + +#define USB_SERIAL_STRING_SIZE 0x06U + +#ifdef USE_USB_FS + #define USB_DESC_LEN_IAP_REPORT 35U +#elif defined(USE_USB_HS) + #define USB_DESC_LEN_IAP_REPORT 36U +#else + #error "please select 'USE_USB_FS' or 'USE_USB_HS'" +#endif + +#define USB_DESC_LEN_IAP_CONFIG_SET 41U + +/* special commands with download request */ +#define IAP_OPTION_BYTE1 0x01U +#define IAP_ERASE 0x02U +#define IAP_DNLOAD 0x03U +#define IAP_LEAVE 0x04U +#define IAP_GETBIN_ADDRESS 0x05U +#define IAP_OPTION_BYTE2 0x06U + +typedef struct +{ + __ALIGN_BEGIN uint8_t report_buf[IAP_OUT_PACKET + 1U] __ALIGN_END; + __ALIGN_BEGIN uint8_t option_byte[IAP_IN_PACKET] __ALIGN_END; + + /* state machine variables */ + uint8_t dev_status[IAP_IN_PACKET]; + uint8_t bin_addr[IAP_IN_PACKET]; + + uint8_t reportID; + uint8_t flag; + + uint32_t protocol; + uint32_t idlestate; + + uint16_t transfer_times; + uint16_t page_count; + uint32_t file_length; + uint32_t base_address; +} usbd_iap_handler; + +typedef void (*app_func) (void); + +extern usb_desc iap_desc; +extern usb_class_core iap_class; + +/* function declarations */ +/* send IAP report */ +uint8_t iap_report_send (usb_dev *udev, uint8_t *report, uint32_t len); + +#endif /* __USB_IAP_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Source/usb_iap_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Source/usb_iap_core.c new file mode 100644 index 0000000000..32ebd876d5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/iap/Source/usb_iap_core.c @@ -0,0 +1,553 @@ +/*! + \file usb_iap_core.c + \brief IAP driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usb_iap_core.h" +#include "flash_operation.h" +#include + +#define USBD_VID 0x28E9U +#define USBD_PID 0x0228U + +/* Note:it should use the C99 standard when compiling the below codes */ +/* USB standard device descriptor */ +__ALIGN_BEGIN const usb_desc_dev iap_dev_desc __ALIGN_END = { + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV + }, + .bcdUSB = 0x0200U, + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM +}; + +__ALIGN_BEGIN const usb_hid_desc_config_set iap_config_desc __ALIGN_END = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = USB_DESC_LEN_IAP_CONFIG_SET, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0x80U, + .bMaxPower = 0x32U + }, + + .hid_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x02U, + .bInterfaceClass = USB_HID_CLASS, + .bInterfaceSubClass = 0x00U, + .bInterfaceProtocol = 0x00U, + .iInterface = 0x00U + }, + + .hid_vendor = + { + .header = + { + .bLength = sizeof(usb_desc_hid), + .bDescriptorType = USB_DESCTYPE_HID + }, + .bcdHID = 0x0111U, + .bCountryCode = 0x00U, + .bNumDescriptors = 0x01U, + .bDescriptorType = USB_DESCTYPE_REPORT, + .wDescriptorLength = USB_DESC_LEN_IAP_REPORT, + }, + + .hid_epin = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = IAP_IN_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = IAP_IN_PACKET, + .bInterval = 0x01U + }, + + .hid_epout = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = IAP_OUT_EP, + .bmAttributes = USB_EP_ATTR_INT, + .wMaxPacketSize = IAP_OUT_PACKET, + .bInterval = 0x01U + } +}; + +/* USB language ID Descriptor */ +__ALIGN_BEGIN const usb_desc_LANGID usbd_language_id_desc __ALIGN_END = { + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +static const __ALIGN_BEGIN usb_desc_str manufacturer_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(10U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +static const __ALIGN_BEGIN usb_desc_str product_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'I', 'A', 'P'} +}; + +/* USB serial string */ +static __ALIGN_BEGIN usb_desc_str serial_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(2U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +void *const usbd_iap_strings[] = { + [STR_IDX_LANGID] = (uint8_t *) &usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *) &manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *) &product_string, + [STR_IDX_SERIAL] = (uint8_t *) &serial_string +}; + +usb_desc iap_desc = { + .dev_desc = (uint8_t *) &iap_dev_desc, + .config_desc = (uint8_t *) &iap_config_desc, + .strings = usbd_iap_strings +}; + +/* local function prototypes ('static') */ +static uint8_t iap_init(usb_dev *udev, uint8_t config_index); +static uint8_t iap_deinit(usb_dev *udev, uint8_t config_index); +static uint8_t iap_req_handler(usb_dev *udev, usb_req *req); +static uint8_t iap_data_out(usb_dev *udev, uint8_t ep_num); + +/* IAP requests management functions */ +static void iap_req_erase(usb_dev *udev); +static void iap_req_dnload(usb_dev *udev); +static void iap_req_optionbyte(usb_dev *udev, uint8_t option_num); +static void iap_req_leave(usb_dev *udev); +static void iap_address_send(usb_dev *udev); + +usb_class_core iap_class = { + .init = iap_init, + .deinit = iap_deinit, + .req_proc = iap_req_handler, + .data_out = iap_data_out +}; + +/* USB custom HID device report descriptor */ +__ALIGN_BEGIN const uint8_t iap_report_desc[USB_DESC_LEN_IAP_REPORT] __ALIGN_END = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x00, /* USAGE (Custom Device) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + + /* IAP command and data */ + 0x85, 0x01, /* REPORT_ID (0x01) */ + 0x09, 0x01, /* USAGE (IAP command) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ +#ifdef USE_USB_FS + 0x95, REPORT_OUT_COUNT, +#else + 0x96, BYTE_LOW(REPORT_OUT_COUNT), BYTE_HIGH(REPORT_OUT_COUNT), /* REPORT_COUNT (57) */ +#endif + 0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */ + + /* device status and option byte */ + 0x85, 0x02, /* REPORT_ID (0x02) */ + 0x09, 0x02, /* USAGE (Status and option byte) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xff, /* LOGICAL_MAXIMUM (255) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, REPORT_IN_COUNT, /* REPORT_COUNT (60) */ + 0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */ + + 0xc0 /* END_COLLECTION */ +}; + +/*! + \brief send IAP report + \param[in] udev: pointer to USB device instance + \param[in] report: pointer to HID report + \param[in] len: data length + \param[out] none + \retval USB device operation status +*/ +uint8_t iap_report_send(usb_dev *udev, uint8_t *report, uint32_t len) +{ + usbd_ep_send(udev, IAP_IN_EP, report, len); + + return USBD_OK; +} + +/*! + \brief initialize the IAP device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t iap_init(usb_dev *udev, uint8_t config_index) +{ + static usbd_iap_handler iap_handler; + + /* initialize TX endpoint */ + usbd_ep_setup(udev, &(iap_config_desc.hid_epin)); + + /* initialize RX endpoint */ + usbd_ep_setup(udev, &(iap_config_desc.hid_epout)); + + /* unlock the internal flash */ + fmc_unlock(); + + memset((void *)&iap_handler, 0U, sizeof(usbd_iap_handler)); + + /* prepare receive data */ + usbd_ep_recev(udev, IAP_OUT_EP, iap_handler.report_buf, IAP_OUT_PACKET); + + iap_handler.base_address = APP_LOADED_ADDR; + + udev->dev.class_data[USBD_IAP_INTERFACE] = (void *)&iap_handler; + + return USBD_OK; +} + +/*! + \brief deinitialize the IAP device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t iap_deinit(usb_dev *udev, uint8_t config_index) +{ + /* deinitialize IAP endpoints */ + usbd_ep_clear(udev, IAP_IN_EP); + usbd_ep_clear(udev, IAP_OUT_EP); + + /* lock the internal flash */ + fmc_lock(); + + return USBD_OK; +} + +/*! + \brief handle the IAP class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t iap_req_handler(usb_dev *udev, usb_req *req) +{ + usb_transc *transc = &udev->dev.transc_in[0]; + + usbd_iap_handler *iap = (usbd_iap_handler *)udev->dev.class_data[USBD_IAP_INTERFACE]; + + switch(req->bRequest) { + case GET_REPORT: + /* no use for this driver */ + break; + + case GET_IDLE: + transc->xfer_buf = (uint8_t *)&iap->idlestate; + transc->remain_len = 1U; + break; + + case GET_PROTOCOL: + transc->xfer_buf = (uint8_t *)&iap->protocol; + transc->remain_len = 1U; + break; + + case SET_REPORT: + iap->reportID = (uint8_t)(req->wValue); + break; + + case SET_IDLE: + iap->idlestate = (uint8_t)(req->wValue >> 8U); + break; + + case SET_PROTOCOL: + iap->protocol = (uint8_t)(req->wValue); + break; + + case USB_GET_DESCRIPTOR: + if(USB_DESCTYPE_REPORT == (req->wValue >> 8U)) { + transc->remain_len = USB_MIN(USB_DESC_LEN_IAP_REPORT, req->wLength); + transc->xfer_buf = (uint8_t *)iap_report_desc; + } + break; + + default: + return USBD_FAIL; + } + + return USBD_OK; +} + +/*! + \brief handle data out stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier + \param[out] none + \retval none +*/ +static uint8_t iap_data_out(usb_dev *udev, uint8_t ep_num) +{ + usbd_iap_handler *iap = (usbd_iap_handler *)udev->dev.class_data[USBD_IAP_INTERFACE]; + + if(0x01U == iap->report_buf[0]) { + switch(iap->report_buf[1]) { + case IAP_DNLOAD: + iap_req_dnload(udev); + break; + + case IAP_ERASE: + iap_req_erase(udev); + break; + + case IAP_OPTION_BYTE1: + iap_req_optionbyte(udev, 0x01U); + break; + + case IAP_LEAVE: + iap_req_leave(udev); + break; + + case IAP_GETBIN_ADDRESS: + iap_address_send(udev); + break; + + case IAP_OPTION_BYTE2: + iap_req_optionbyte(udev, 0x02U); + break; + + default: + break; + } + } + + usbd_ep_recev(udev, IAP_OUT_EP, iap->report_buf, IAP_OUT_PACKET); + + return USBD_OK; +} + +/*! + \brief handle the IAP_DNLOAD request + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void iap_req_dnload(usb_dev *udev) +{ + usbd_iap_handler *iap = (usbd_iap_handler *)udev->dev.class_data[USBD_IAP_INTERFACE]; + + if(0U != iap->transfer_times) { + if(1U == iap->transfer_times) { + iap_data_write(&iap->report_buf[2], iap->base_address, iap->file_length % TRANSFER_SIZE); + + iap->dev_status[0] = 0x02U; + iap->dev_status[1] = 0x02U; + iap_report_send(udev, iap->dev_status, IAP_IN_PACKET); + } else { + iap_data_write(&iap->report_buf[2], iap->base_address, TRANSFER_SIZE); + + iap->base_address += TRANSFER_SIZE; + } + + iap->transfer_times--; + } +} + +/*! + \brief handle the IAP_ERASE request + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void iap_req_erase(usb_dev *udev) +{ + uint32_t addr = 0U; + + usbd_iap_handler *iap = (usbd_iap_handler *)udev->dev.class_data[USBD_IAP_INTERFACE]; + + /* get base address to erase */ + iap->base_address = iap->report_buf[2]; + iap->base_address |= (uint32_t)iap->report_buf[3] << 8U; + iap->base_address |= (uint32_t)iap->report_buf[4] << 16U; + iap->base_address |= (uint32_t)iap->report_buf[5] << 24U; + + /* get file length */ + iap->file_length = iap->report_buf[7]; + iap->file_length |= (uint32_t)iap->report_buf[8] << 8U; + iap->file_length |= (uint32_t)iap->report_buf[9] << 16U; + iap->file_length |= (uint32_t)iap->report_buf[10] << 24U; + + if(0U == (iap->file_length % TRANSFER_SIZE)) { + iap->transfer_times = (uint16_t)(iap->file_length / TRANSFER_SIZE); + } else { + iap->transfer_times = (uint16_t)(iap->file_length / TRANSFER_SIZE + 1U); + } + + /* check if the address is in protected area */ + if(IS_PROTECTED_AREA(iap->base_address)) { + return; + } + + addr = iap->base_address; + + /* unlock the flash program erase controller */ + fmc_unlock(); + + flash_erase(addr, iap->file_length, iap->report_buf); + + fmc_lock(); + + iap->dev_status[0] = 0x02U; + iap->dev_status[1] = 0x01U; + + usbd_ep_send(udev, IAP_IN_EP, iap->dev_status, IAP_IN_PACKET); +} + +/*! + \brief handle the IAP_OPTION_BYTE request + \param[in] udev: pointer to USB device instance + \param[in] option_num: number of option byte + \param[out] none + \retval none +*/ +static void iap_req_optionbyte(usb_dev *udev, uint8_t option_num) +{ + uint8_t i = 0U, opt_count = 0U; + uint32_t address = 0U, ob = 0U; + + usbd_iap_handler *iap = (usbd_iap_handler *)udev->dev.class_data[USBD_IAP_INTERFACE]; + + iap->option_byte[0] = 0x02U; + + if(0x01U == option_num) { + address = OPT_BYTE_ADDR; + } else { + return; + } + + opt_count = REPORT_IN_COUNT / 4; + + for(i = 0U; i < opt_count; i++) { + ob = REG32(address + 4 * i); + + iap->option_byte[1 + 4 * i] = (uint8_t)ob; + iap->option_byte[2 + 4 * i] = (uint8_t)(ob >> 8); + iap->option_byte[3 + 4 * i] = (uint8_t)(ob >> 16); + iap->option_byte[4 + 4 * i] = (uint8_t)(ob >> 24); + } + + iap_report_send(udev, iap->option_byte, IAP_IN_PACKET); +} + +/*! + \brief handle the IAP_LEAVE request + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void iap_req_leave(usb_dev *udev) +{ + /* lock the internal flash */ + fmc_lock(); + + /* generate system reset to allow jumping to the user code */ + NVIC_SystemReset(); +} + +/*! + \brief handle the IAP_SEND_ADDRESS request + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void iap_address_send(usb_dev *udev) +{ + usbd_iap_handler *iap = (usbd_iap_handler *)udev->dev.class_data[USBD_IAP_INTERFACE]; + + iap->bin_addr[0] = 0x02U; + + iap->bin_addr[1] = (uint8_t)(APP_LOADED_ADDR); + iap->bin_addr[2] = (uint8_t)(APP_LOADED_ADDR >> 8U); + iap->bin_addr[3] = (uint8_t)(APP_LOADED_ADDR >> 16U); + iap->bin_addr[4] = (uint8_t)(APP_LOADED_ADDR >> 24U); + + iap_report_send(udev, iap->bin_addr, IAP_IN_PACKET); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_bbb.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_bbb.h new file mode 100644 index 0000000000..fcabda2f09 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_bbb.h @@ -0,0 +1,102 @@ +/*! + \file usbd_msc_bbb.h + \brief the header file of the usbd_msc_bot.c file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_MSC_BBB_H +#define __USBD_MSC_BBB_H + +#include "usbd_core.h" +#include "msc_bbb.h" +#include "usbd_msc_mem.h" +#include "usbd_msc_scsi.h" + +/* MSC BBB state */ +enum msc_bbb_state { + BBB_IDLE = 0U, /*!< idle state */ + BBB_DATA_OUT, /*!< data OUT state */ + BBB_DATA_IN, /*!< data IN state */ + BBB_LAST_DATA_IN, /*!< last data IN state */ + BBB_SEND_DATA /*!< send immediate data state */ +}; + +/* MSC BBB status */ +enum msc_bbb_status { + BBB_STATUS_NORMAL = 0U, /*!< normal status */ + BBB_STATUS_RECOVERY, /*!< recovery status*/ + BBB_STATUS_ERROR /*!< error status */ +}; + +typedef struct +{ + __ALIGN_BEGIN uint8_t bbb_data[MSC_MEDIA_PACKET_SIZE] __ALIGN_END; + + uint8_t max_lun; + + uint8_t bbb_state; + uint8_t bbb_status; + + uint32_t bbb_datalen; + + __ALIGN_BEGIN msc_bbb_cbw bbb_cbw __ALIGN_END; + __ALIGN_BEGIN msc_bbb_csw bbb_csw __ALIGN_END; + + uint8_t scsi_sense_head; + uint8_t scsi_sense_tail; + + uint32_t scsi_blk_size[MEM_LUN_NUM]; + uint32_t scsi_blk_nbr[MEM_LUN_NUM]; + + uint32_t scsi_blk_addr; + uint32_t scsi_blk_len; + uint32_t scsi_disk_pop; + + __ALIGN_BEGIN msc_scsi_sense scsi_sense[SENSE_LIST_DEEPTH] __ALIGN_END; +} usbd_msc_handler; + +/* function declarations */ +/* initialize the BBB process */ +void msc_bbb_init (usb_core_driver *udev); +/* reset the BBB machine */ +void msc_bbb_reset (usb_core_driver *udev); +/* deinitialize the BBB machine */ +void msc_bbb_deinit (usb_core_driver *udev); +/* handle BBB data IN stage */ +void msc_bbb_data_in (usb_core_driver *udev, uint8_t ep_num); +/* handle BBB data OUT stage */ +void msc_bbb_data_out (usb_core_driver *udev, uint8_t ep_num); +/* send the CSW(command status wrapper) */ +void msc_bbb_csw_send (usb_core_driver *udev, uint8_t csw_status); +/* complete the clear feature request */ +void msc_bbb_clrfeature (usb_core_driver *udev, uint8_t ep_num); + +#endif /* __USBD_MSC_BBB_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_core.h new file mode 100644 index 0000000000..0dde4e0853 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_core.h @@ -0,0 +1,59 @@ +/*! + \file usbd_msc_core.h + \brief the header file of USB MSC device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_MSC_CORE_H +#define __USBD_MSC_CORE_H + +#include "usbd_core.h" +#include "usb_msc.h" + +#define USB_MSC_CONFIG_DESC_SIZE 32U + +#define MSC_EPIN_SIZE MSC_DATA_PACKET_SIZE +#define MSC_EPOUT_SIZE MSC_DATA_PACKET_SIZE + +/* USB configuration descriptor structure */ +typedef struct +{ + usb_desc_config config; + + usb_desc_itf msc_itf; + usb_desc_ep msc_epin; + usb_desc_ep msc_epout; +} usb_desc_config_set; + +extern usb_desc msc_desc; +extern usb_class_core msc_class; + +#endif /* __USBD_MSC_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_data.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_data.h new file mode 100644 index 0000000000..6a9d540f30 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_data.h @@ -0,0 +1,49 @@ +/*! + \file usbd_msc_data.h + \brief the header file of the usbd_msc_data.c file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_MSC_DATA_H +#define __USBD_MSC_DATA_H + +#include "usbd_conf.h" + +#define MODE_SENSE6_LENGTH 8U +#define MODE_SENSE10_LENGTH 8U +#define INQUIRY_PAGE00_LENGTH 96U +#define FORMAT_CAPACITIES_LENGTH 20U + +extern const uint8_t msc_page00_inquiry_data[]; +extern const uint8_t msc_mode_sense6_data[]; +extern const uint8_t msc_mode_sense10_data[]; + +#endif /* __USBD_MSC_DATA_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_efs.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_efs.h new file mode 100644 index 0000000000..8851b08413 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_efs.h @@ -0,0 +1,57 @@ +/*! + \file usbh_msc_efs.h + \brief the header file of the usbh_msc_efs.c file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_MSC_EFS_H +#define __USBD_MSC_EFS_H + +struct hwInterface +{ + /*FILE *imageFile;*/ + int32_t sectorCount; +}; + +typedef struct hwInterface hwInterface; + +#define EFS_ERROR -1 +#define EFS_PASS 0 + +/* function declarations */ +/* initialize the mass storage parameters */ +int8_t if_initInterface(hwInterface* file, char* opts); +/* read a sector from the disc and store it in a user supplied buffer */ +int8_t if_readBuf(hwInterface* file, uint32_t address, uint8_t* buf); +/* write a sector of data on the disc from a user supplied buffer */ +int8_t if_writeBuf(hwInterface* file, uint32_t address, uint8_t* buf); + +#endif /*__USBD_MSC_EFS_H*/ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_mem.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_mem.h new file mode 100644 index 0000000000..876d303e15 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_mem.h @@ -0,0 +1,59 @@ +/*! + \file usbd_msc_mem.h + \brief header file for storage memory + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_MSC_MEM_H +#define __USBD_MSC_MEM_H + +#include "usbd_conf.h" + +#define USBD_STD_INQUIRY_LENGTH 36U + +typedef struct +{ + int8_t (*mem_init) (uint8_t lun); + int8_t (*mem_ready) (uint8_t lun); + int8_t (*mem_protected) (uint8_t lun); + int8_t (*mem_read) (uint8_t lun, uint8_t *buf, uint32_t block_addr, uint16_t block_len); + int8_t (*mem_write) (uint8_t lun, uint8_t *buf, uint32_t block_addr, uint16_t block_len); + int8_t (*mem_maxlun) (void); + + uint8_t *mem_toc_data; + uint8_t *mem_inquiry_data[MEM_LUN_NUM]; + uint32_t mem_block_size[MEM_LUN_NUM]; + uint32_t mem_block_len[MEM_LUN_NUM]; +}usbd_mem_cb; + +extern usbd_mem_cb *usbd_mem_fops; + +#endif /* __USBD_MSC_MEM_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_scsi.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_scsi.h new file mode 100644 index 0000000000..f928d87804 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Include/usbd_msc_scsi.h @@ -0,0 +1,50 @@ +/*! + \file usbd_msc_scsi.h + \brief the header file of the usbd_msc_scsi.c file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_MSC_SCSI_H +#define __USBD_MSC_SCSI_H + +#include "usbd_msc_data.h" +#include "usbd_msc_bbb.h" +#include "msc_scsi.h" + +#define SENSE_LIST_DEEPTH 4U + +/* function declarations */ +/* process SCSI commands */ +int8_t scsi_process_cmd (usb_core_driver *udev, uint8_t lun, uint8_t *cmd); +/* load the last error code in the error list */ +void scsi_sense_code (usb_core_driver *udev, uint8_t lun, uint8_t skey, uint8_t asc); + +#endif /* __USBD_MSC_SCSI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_bbb.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_bbb.c new file mode 100644 index 0000000000..a8db20b565 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_bbb.c @@ -0,0 +1,286 @@ +/*! + \file usbd_msc_bbb.c + \brief USB BBB(Bulk/Bulk/Bulk) protocol core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_enum.h" +#include "usbd_msc_bbb.h" + +/* local function prototypes ('static') */ +static void msc_bbb_cbw_decode (usb_core_driver *udev); +static void msc_bbb_data_send (usb_core_driver *udev, uint8_t *pbuf, uint32_t Len); +static void msc_bbb_abort (usb_core_driver *udev); + +/*! + \brief initialize the BBB process + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +void msc_bbb_init (usb_core_driver *udev) +{ + uint8_t lun_num; + + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_state = BBB_IDLE; + msc->bbb_status = BBB_STATUS_NORMAL; + + /* initializes the storage logic unit */ + for(lun_num = 0U; lun_num < MEM_LUN_NUM; lun_num++) { + usbd_mem_fops->mem_init(lun_num); + } + + /* flush the RX FIFO */ + usbd_fifo_flush (udev, MSC_OUT_EP); + + /* flush the TX FIFO */ + usbd_fifo_flush (udev, MSC_IN_EP); + + /* prepare endpoint to receive the first BBB CBW */ + usbd_ep_recev (udev, MSC_OUT_EP, (uint8_t *)&msc->bbb_cbw, BBB_CBW_LENGTH); +} + +/*! + \brief reset the BBB machine + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +void msc_bbb_reset (usb_core_driver *udev) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_state = BBB_IDLE; + msc->bbb_status = BBB_STATUS_RECOVERY; + + /* prepare endpoint to receive the first BBB command */ + usbd_ep_recev (udev, MSC_OUT_EP, (uint8_t *)&msc->bbb_cbw, BBB_CBW_LENGTH); +} + +/*! + \brief de-initialize the BBB machine + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +void msc_bbb_deinit (usb_core_driver *udev) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_state = BBB_IDLE; +} + +/*! + \brief handle BBB data IN stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval none +*/ +void msc_bbb_data_in (usb_core_driver *udev, uint8_t ep_num) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + switch (msc->bbb_state) { + case BBB_DATA_IN: + if (scsi_process_cmd (udev, msc->bbb_cbw.bCBWLUN, &msc->bbb_cbw.CBWCB[0]) < 0) { + msc_bbb_csw_send (udev, CSW_CMD_FAILED); + } + break; + + case BBB_SEND_DATA: + case BBB_LAST_DATA_IN: + msc_bbb_csw_send (udev, CSW_CMD_PASSED); + break; + + default: + break; + } +} + +/*! + \brief handle BBB data OUT stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval none +*/ +void msc_bbb_data_out (usb_core_driver *udev, uint8_t ep_num) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + switch (msc->bbb_state) { + case BBB_IDLE: + msc_bbb_cbw_decode (udev); + break; + + case BBB_DATA_OUT: + if (scsi_process_cmd (udev, msc->bbb_cbw.bCBWLUN, &msc->bbb_cbw.CBWCB[0]) < 0) { + msc_bbb_csw_send (udev, CSW_CMD_FAILED); + } + break; + + default: + break; + } +} + +/*! + \brief send the CSW(command status wrapper) + \param[in] udev: pointer to USB device instance + \param[in] csw_status: CSW status + \param[out] none + \retval none +*/ +void msc_bbb_csw_send (usb_core_driver *udev, uint8_t csw_status) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_csw.dCSWSignature = BBB_CSW_SIGNATURE; + msc->bbb_csw.bCSWStatus = csw_status; + msc->bbb_state = BBB_IDLE; + + usbd_ep_send (udev, MSC_IN_EP, (uint8_t *)&msc->bbb_csw, BBB_CSW_LENGTH); + + /* prepare endpoint to receive next command */ + usbd_ep_recev (udev, MSC_OUT_EP, (uint8_t *)&msc->bbb_cbw, BBB_CBW_LENGTH); +} + +/*! + \brief complete the clear feature request + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval none +*/ +void msc_bbb_clrfeature (usb_core_driver *udev, uint8_t ep_num) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + if (BBB_STATUS_ERROR == msc->bbb_status)/* bad CBW signature */ { + usbd_ep_stall(udev, MSC_IN_EP); + + msc->bbb_status = BBB_STATUS_NORMAL; + } else if((0x80U == (ep_num & 0x80U)) && (BBB_STATUS_RECOVERY != msc->bbb_status)) { + msc_bbb_csw_send (udev, CSW_CMD_FAILED); + } else { + + } +} + +/*! + \brief decode the CBW command and set the BBB state machine accordingly + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void msc_bbb_cbw_decode (usb_core_driver *udev) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_csw.dCSWTag = msc->bbb_cbw.dCBWTag; + msc->bbb_csw.dCSWDataResidue = msc->bbb_cbw.dCBWDataTransferLength; + + if ((BBB_CBW_LENGTH != usbd_rxcount_get (udev, MSC_OUT_EP)) || + (BBB_CBW_SIGNATURE != msc->bbb_cbw.dCBWSignature)|| + (msc->bbb_cbw.bCBWLUN > 1U) || + (msc->bbb_cbw.bCBWCBLength < 1U) || + (msc->bbb_cbw.bCBWCBLength > 16U)) { + /* illegal command handler */ + scsi_sense_code (udev, msc->bbb_cbw.bCBWLUN, ILLEGAL_REQUEST, INVALID_CDB); + + msc->bbb_status = BBB_STATUS_ERROR; + + msc_bbb_abort (udev); + } else { + if (scsi_process_cmd (udev, msc->bbb_cbw.bCBWLUN, &msc->bbb_cbw.CBWCB[0]) < 0) { + msc_bbb_abort (udev); + } else if ((BBB_DATA_IN != msc->bbb_state) && + (BBB_DATA_OUT != msc->bbb_state) && + (BBB_LAST_DATA_IN != msc->bbb_state)) { /* burst xfer handled internally */ + if (msc->bbb_datalen > 0U) { + msc_bbb_data_send (udev, msc->bbb_data, msc->bbb_datalen); + } else if (0U == msc->bbb_datalen) { + msc_bbb_csw_send (udev, CSW_CMD_PASSED); + } else { + + } + } else { + + } + } +} + +/*! + \brief send the requested data + \param[in] udev: pointer to USB device instance + \param[in] buf: pointer to data buffer + \param[in] len: data length + \param[out] none + \retval none +*/ +static void msc_bbb_data_send (usb_core_driver *udev, uint8_t *buf, uint32_t len) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + len = USB_MIN (msc->bbb_cbw.dCBWDataTransferLength, len); + + msc->bbb_csw.dCSWDataResidue -= len; + msc->bbb_csw.bCSWStatus = CSW_CMD_PASSED; + msc->bbb_state = BBB_SEND_DATA; + + usbd_ep_send (udev, MSC_IN_EP, buf, len); +} + +/*! + \brief abort the current transfer + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +static void msc_bbb_abort (usb_core_driver *udev) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + if ((0U == msc->bbb_cbw.bmCBWFlags) && + (0U != msc->bbb_cbw.dCBWDataTransferLength) && + (BBB_STATUS_NORMAL == msc->bbb_status)) { + usbd_ep_stall(udev, MSC_OUT_EP); + } + + usbd_ep_stall(udev, MSC_IN_EP); + + if (msc->bbb_status == BBB_STATUS_ERROR) { + usbd_ep_recev (udev, MSC_OUT_EP, (uint8_t *)&msc->bbb_cbw, BBB_CBW_LENGTH); + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_core.c new file mode 100644 index 0000000000..ecf27da940 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_core.c @@ -0,0 +1,393 @@ +/*! + \file usbd_msc_core.c + \brief USB MSC device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_enum.h" +#include "usbd_msc_bbb.h" +#include "usbd_msc_core.h" +#include + +#define USBD_VID 0x28E9U +#define USBD_PID 0x028FU + +/* local function prototypes ('static') */ +static uint8_t msc_core_init (usb_dev *udev, uint8_t config_index); +static uint8_t msc_core_deinit (usb_dev *udev, uint8_t config_index); +static uint8_t msc_core_req (usb_dev *udev, usb_req *req); +static uint8_t msc_core_in (usb_dev *udev, uint8_t ep_num); +static uint8_t msc_core_out (usb_dev *udev, uint8_t ep_num); + +usb_class_core msc_class = +{ + .init = msc_core_init, + .deinit = msc_core_deinit, + + .req_proc = msc_core_req, + + .data_in = msc_core_in, + .data_out = msc_core_out +}; + +/* note: it should use the C99 standard when compiling the below codes */ +/* USB standard device descriptor */ +__ALIGN_BEGIN const usb_desc_dev msc_dev_desc __ALIGN_END = +{ + .header = { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV + }, + .bcdUSB = 0x0200U, + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM +}; + +/* USB device configuration descriptor */ +__ALIGN_BEGIN const usb_desc_config_set msc_config_desc __ALIGN_END = +{ + .config = + { + .header = { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = USB_MSC_CONFIG_DESC_SIZE, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0xC0U, + .bMaxPower = 0x32U + }, + + .msc_itf = + { + .header = { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x02U, + .bInterfaceClass = USB_CLASS_MSC, + .bInterfaceSubClass = USB_MSC_SUBCLASS_SCSI, + .bInterfaceProtocol = USB_MSC_PROTOCOL_BBB, + .iInterface = 0x00U + }, + + .msc_epin = + { + .header = { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = MSC_IN_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = MSC_EPIN_SIZE, + .bInterval = 0x00U + }, + + .msc_epout = + { + .header = { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = MSC_OUT_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = MSC_EPOUT_SIZE, + .bInterval = 0x00U + } +}; + +/* USB device other speed configuration descriptor */ +__ALIGN_BEGIN const usb_desc_config_set other_speed_msc_config_desc __ALIGN_END = +{ + .config = + { + .header = { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_OTHER_SPD_CONFIG + }, + .wTotalLength = USB_MSC_CONFIG_DESC_SIZE, + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0xC0U, + .bMaxPower = 0x32U + }, + + .msc_itf = + { + .header = { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x02U, + .bInterfaceClass = USB_CLASS_MSC, + .bInterfaceSubClass = USB_MSC_SUBCLASS_SCSI, + .bInterfaceProtocol = USB_MSC_PROTOCOL_BBB, + .iInterface = 0x00U + }, + + .msc_epin = + { + .header = { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = MSC_IN_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = 64U, + .bInterval = 0x00U + }, + + .msc_epout = + { + .header = { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = MSC_OUT_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = 64U, + .bInterval = 0x00U + } +}; + +__ALIGN_BEGIN const uint8_t usbd_qualifier_desc[10] __ALIGN_END = +{ + 0x0A, + 0x06, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00 +}; + +/* USB language ID descriptor */ +__ALIGN_BEGIN const usb_desc_LANGID usbd_language_id_desc __ALIGN_END = +{ + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +__ALIGN_BEGIN static const usb_desc_str manufacturer_string __ALIGN_END = +{ + .header = + { + .bLength = USB_STRING_LEN(10U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +__ALIGN_BEGIN static const usb_desc_str product_string __ALIGN_END = +{ + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'M', 'S', 'C'} +}; + +/* USBD serial string */ +__ALIGN_BEGIN static usb_desc_str serial_string __ALIGN_END = +{ + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +/* USB string descriptor */ +void *const usbd_msc_strings[] = +{ + [STR_IDX_LANGID] = (uint8_t *)&usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *)&manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *)&product_string, + [STR_IDX_SERIAL] = (uint8_t *)&serial_string +}; + +usb_desc msc_desc = { + .dev_desc = (uint8_t *)&msc_dev_desc, + .config_desc = (uint8_t *)&msc_config_desc, + .strings = usbd_msc_strings, +#ifdef USE_USB_HS + .other_speed_config_desc = (uint8_t *)&other_speed_msc_config_desc, + .qualifier_desc = (uint8_t *)&usbd_qualifier_desc, +#endif +}; + +static uint8_t usbd_msc_maxlun = 0U; + +/*! + \brief initialize the MSC device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t msc_core_init (usb_dev *udev, uint8_t config_index) +{ + static usbd_msc_handler msc_handler; + + memset((void *)&msc_handler, 0U, sizeof(usbd_msc_handler)); + + udev->dev.class_data[USBD_MSC_INTERFACE] = (void *)&msc_handler; + + /* configure MSC TX endpoint */ + usbd_ep_setup (udev, &(msc_config_desc.msc_epin)); + + /* configure MSC RX endpoint */ + usbd_ep_setup (udev, &(msc_config_desc.msc_epout)); + + /* initialize the BBB layer */ + msc_bbb_init(udev); + + return USBD_OK; +} + +/*! + \brief de-initialize the MSC device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t msc_core_deinit (usb_dev *udev, uint8_t config_index) +{ + /* clear MSC endpoints */ + usbd_ep_clear (udev, MSC_IN_EP); + usbd_ep_clear (udev, MSC_OUT_EP); + + /* deinitialize the BBB layer */ + msc_bbb_deinit(udev); + + return USBD_OK; +} + +/*! + \brief handle the MSC class-specific and standard requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t msc_core_req (usb_dev *udev, usb_req *req) +{ + usb_transc *transc = &udev->dev.transc_in[0]; + + switch (req->bRequest) { + case BBB_GET_MAX_LUN : + if((0U == req->wValue) && + (1U == req->wLength) && + (0x80U == (req->bmRequestType & 0x80U))) { + usbd_msc_maxlun = (uint8_t)usbd_mem_fops->mem_maxlun(); + + transc->xfer_buf = &usbd_msc_maxlun; + transc->remain_len = 1U; + } else { + return USBD_FAIL; + } + break; + + case BBB_RESET : + if((0U == req->wValue) && + (0U == req->wLength) && + (0x80U != (req->bmRequestType & 0x80U))) { + msc_bbb_reset(udev); + } else { + return USBD_FAIL; + } + break; + + case USB_CLEAR_FEATURE: + msc_bbb_clrfeature (udev, (uint8_t)req->wIndex); + break; + + default: + return USBD_FAIL; + } + + return USBD_OK; +} + +/*! + \brief handle data in stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: the endpoint number + \param[out] none + \retval none +*/ +static uint8_t msc_core_in (usb_dev *udev, uint8_t ep_num) +{ + msc_bbb_data_in(udev, ep_num); + + return USBD_OK; +} + +/*! + \brief handle data out stage + \param[in] udev: pointer to USB device instance + \param[in] ep_num: the endpoint number + \param[out] none + \retval none +*/ +static uint8_t msc_core_out (usb_dev *udev, uint8_t ep_num) +{ + msc_bbb_data_out (udev, ep_num); + + return USBD_OK; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_data.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_data.c new file mode 100644 index 0000000000..9b7d307cf9 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_data.c @@ -0,0 +1,73 @@ +/*! + \file usbd_msc_data.c + \brief USB MSC vital inquiry pages and sense data + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_msc_data.h" + +/* USB mass storage page 0 inquiry data */ +const uint8_t msc_page00_inquiry_data[] = +{ + 0x00U, + 0x00U, + 0x00U, + 0x00U, + (INQUIRY_PAGE00_LENGTH - 4U), + 0x80U, + 0x83U, +}; + +/* USB mass storage sense 6 data */ +const uint8_t msc_mode_sense6_data[] = +{ + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U +}; + +/* USB mass storage sense 10 data */ +const uint8_t msc_mode_sense10_data[] = +{ + 0x00U, + 0x06U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U, + 0x00U +}; diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_efs.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_efs.c new file mode 100644 index 0000000000..25e201691a --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_efs.c @@ -0,0 +1,92 @@ +/*! + \file usbh_msc_efs.c + \brief this file is the interface between file systems and host MSC class + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "efs.h" +#include "usbd_msc_core.h" +#include "usbd_msc_mem.h" +#include "usbd_msc_scsi.h" +#include "usbd_msc_bbb.h" +#include "usbd_msc_efs.h" + +/*! + \brief initialize the mass storage parameters + \param[in] file: file pointer + \param[in] opts: optional parameter, not used here + \param[out] none + \retval status: 0(pass), -1(fail) +*/ +int8_t if_initInterface(hwInterface* file, char* opts) +{ + file->sectorCount = usbd_mem_fops->mem_block_len[0]; + + return(EFS_PASS); +} + +/*! + \brief read a sector from the disc and store it in a user supplied buffer + \param[in] file: file pointer + \param[in] address: an LBA address, relative to the beginning of the disc + \param[in] buf: buffer where the data will be stored after reading + \param[out] none + \retval status: 0(pass), -1(fail) +*/ +int8_t if_readBuf(hwInterface* file, uint32_t address, uint8_t* buf) +{ + int8_t status = EFS_ERROR; + + if (0U == usbd_mem_fops->mem_read(0U, buf, address, 1U)) { + status = EFS_PASS; + } + + return(status); +} + +/*! + \brief write a sector of data on the disc from a user supplied buffer + \param[in] file: file pointer + \param[in] address: an LBA address, relative to the beginning of the disc + \param[in] buf: buffer where the data will be taken to write + \param[out] none + \retval status: 0(pass), -1(fail) +*/ +int8_t if_writeBuf(hwInterface* file, uint32_t address, uint8_t* buf) +{ + int8_t status = EFS_ERROR; + + if (0U == usbd_mem_fops->mem_write(0U, buf, address, 1U)) { + status = EFS_PASS; + } + + return(status); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_scsi.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_scsi.c new file mode 100644 index 0000000000..632918dfec --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/msc/Source/usbd_msc_scsi.c @@ -0,0 +1,724 @@ +/*! + \file usbd_msc_scsi.c + \brief USB SCSI layer functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_enum.h" +#include "usbd_msc_bbb.h" +#include "usbd_msc_scsi.h" +#include "usbd_msc_data.h" + +/* local function prototypes ('static') */ +static int8_t scsi_test_unit_ready (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_mode_select6 (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_mode_select10 (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_inquiry (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_read_format_capacity (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_read_capacity10 (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_request_sense (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_mode_sense6 (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_toc_cmd_read (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_mode_sense10 (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_write10 (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_read10 (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static int8_t scsi_verify10 (usb_core_driver *udev, uint8_t lun, uint8_t *params); + +static int8_t scsi_process_read (usb_core_driver *udev, uint8_t lun); +static int8_t scsi_process_write (usb_core_driver *udev, uint8_t lun); + +static inline int8_t scsi_check_address_range (usb_core_driver *udev, uint8_t lun, uint32_t blk_offset, uint16_t blk_nbr); +static inline int8_t scsi_format_cmd (usb_core_driver *udev, uint8_t lun); +static inline int8_t scsi_start_stop_unit (usb_core_driver *udev, uint8_t lun, uint8_t *params); +static inline int8_t scsi_allow_medium_removal (usb_core_driver *udev, uint8_t lun, uint8_t *params); + +/*! + \brief process SCSI commands + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +int8_t scsi_process_cmd(usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + switch (params[0]) { + case SCSI_TEST_UNIT_READY: + return scsi_test_unit_ready (udev, lun, params); + + case SCSI_REQUEST_SENSE: + return scsi_request_sense (udev, lun, params); + + case SCSI_INQUIRY: + return scsi_inquiry (udev, lun, params); + + case SCSI_START_STOP_UNIT: + return scsi_start_stop_unit (udev, lun, params); + + case SCSI_ALLOW_MEDIUM_REMOVAL: + return scsi_allow_medium_removal (udev, lun, params); + + case SCSI_MODE_SENSE6: + return scsi_mode_sense6 (udev, lun, params); + + case SCSI_MODE_SENSE10: + return scsi_mode_sense10 (udev, lun, params); + + case SCSI_READ_FORMAT_CAPACITIES: + return scsi_read_format_capacity (udev, lun, params); + + case SCSI_READ_CAPACITY10: + return scsi_read_capacity10 (udev, lun, params); + + case SCSI_READ10: + return scsi_read10 (udev, lun, params); + + case SCSI_WRITE10: + return scsi_write10 (udev, lun, params); + + case SCSI_VERIFY10: + return scsi_verify10 (udev, lun, params); + + case SCSI_FORMAT_UNIT: + return scsi_format_cmd (udev, lun); + + case SCSI_READ_TOC_DATA: + return scsi_toc_cmd_read (udev, lun, params); + + case SCSI_MODE_SELECT6: + return scsi_mode_select6 (udev, lun, params); + + case SCSI_MODE_SELECT10: + return scsi_mode_select10 (udev, lun, params); + + default: + scsi_sense_code (udev, lun, ILLEGAL_REQUEST, INVALID_CDB); + return -1; + } +} + +/*! + \brief load the last error code in the error list + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] skey: sense key + \param[in] asc: additional sense key + \param[out] none + \retval none +*/ +void scsi_sense_code (usb_core_driver *udev, uint8_t lun, uint8_t skey, uint8_t asc) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->scsi_sense[msc->scsi_sense_tail].SenseKey = skey; + msc->scsi_sense[msc->scsi_sense_tail].ASC = asc; + msc->scsi_sense_tail++; + + if (SENSE_LIST_DEEPTH == msc->scsi_sense_tail) { + msc->scsi_sense_tail = 0U; + } +} + +/*! + \brief process SCSI Test Unit Ready command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_test_unit_ready (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + /* case 9 : Hi > D0 */ + if (0U != msc->bbb_cbw.dCBWDataTransferLength) { + scsi_sense_code (udev, msc->bbb_cbw.bCBWLUN, ILLEGAL_REQUEST, INVALID_CDB); + + return -1; + } + + if (0 != usbd_mem_fops->mem_ready(lun)) { + scsi_sense_code(udev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + + return -1; + } + + msc->bbb_datalen = 0U; + + return 0; +} + +/*! + \brief process Inquiry command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_mode_select6 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_datalen = 0U; + + return 0; +} + +/*! + \brief process inquiry command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_mode_select10 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_datalen = 0U; + + return 0; +} + +/*! + \brief process inquiry command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_inquiry (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + uint8_t *page = NULL; + uint16_t len = 0U; + + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + if (params[1] & 0x01U) { + page = (uint8_t *)msc_page00_inquiry_data; + + len = INQUIRY_PAGE00_LENGTH; + } else { + page = (uint8_t *)usbd_mem_fops->mem_inquiry_data[lun]; + + len = (uint16_t)(page[4] + 5U); + + if (params[4] <= len) { + len = params[4]; + } + } + + msc->bbb_datalen = len; + + while (len) { + len--; + msc->bbb_data[len] = page[len]; + } + + return 0; +} + +/*! + \brief process read capacity 10 command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_read_capacity10 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + uint32_t blk_num = usbd_mem_fops->mem_block_len[lun] - 1U; + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->scsi_blk_nbr[lun] = usbd_mem_fops->mem_block_len[lun]; + msc->scsi_blk_size[lun] = usbd_mem_fops->mem_block_size[lun]; + + msc->bbb_data[0] = (uint8_t)(blk_num >> 24U); + msc->bbb_data[1] = (uint8_t)(blk_num >> 16U); + msc->bbb_data[2] = (uint8_t)(blk_num >> 8U); + msc->bbb_data[3] = (uint8_t)(blk_num); + + msc->bbb_data[4] = (uint8_t)(msc->scsi_blk_size[lun] >> 24U); + msc->bbb_data[5] = (uint8_t)(msc->scsi_blk_size[lun] >> 16U); + msc->bbb_data[6] = (uint8_t)(msc->scsi_blk_size[lun] >> 8U); + msc->bbb_data[7] = (uint8_t)(msc->scsi_blk_size[lun]); + + msc->bbb_datalen = 8U; + + return 0; +} + +/*! + \brief process read format capacity command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_read_format_capacity (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + uint16_t i = 0U; + uint32_t blk_size = usbd_mem_fops->mem_block_size[lun]; + uint32_t blk_num = usbd_mem_fops->mem_block_len[lun]; + uint32_t blk_nbr = blk_num - 1U; + + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + for (i = 0U; i < 12U; i++) { + msc->bbb_data[i] = 0U; + } + + msc->bbb_data[3] = 0x08U; + msc->bbb_data[4] = (uint8_t)(blk_nbr >> 24U); + msc->bbb_data[5] = (uint8_t)(blk_nbr >> 16U); + msc->bbb_data[6] = (uint8_t)(blk_nbr >> 8U); + msc->bbb_data[7] = (uint8_t)(blk_nbr); + + msc->bbb_data[8] = 0x02U; + msc->bbb_data[9] = (uint8_t)(blk_size >> 16U); + msc->bbb_data[10] = (uint8_t)(blk_size >> 8U); + msc->bbb_data[11] = (uint8_t)(blk_size); + + msc->bbb_datalen = 12U; + + return 0; +} + +/*! + \brief process mode sense6 command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_mode_sense6 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + uint16_t len = 8U; + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_datalen = len; + + while (len) { + len--; + msc->bbb_data[len] = msc_mode_sense6_data[len]; + } + + return 0; +} + +/*! + \brief process mode sense10 command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_mode_sense10 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + uint16_t len = 8U; + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_datalen = len; + + while (len) { + len--; + msc->bbb_data[len] = msc_mode_sense10_data[len]; + } + + return 0; +} + +/*! + \brief process request sense command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_request_sense (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + uint8_t i = 0U; + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + for (i = 0U; i < REQUEST_SENSE_DATA_LEN; i++) { + msc->bbb_data[i] = 0U; + } + + msc->bbb_data[0] = 0x70U; + msc->bbb_data[7] = REQUEST_SENSE_DATA_LEN - 6U; + + if ((msc->scsi_sense_head != msc->scsi_sense_tail)) { + msc->bbb_data[2] = msc->scsi_sense[msc->scsi_sense_head].SenseKey; + msc->bbb_data[12] = msc->scsi_sense[msc->scsi_sense_head].ASC; + msc->bbb_data[13] = msc->scsi_sense[msc->scsi_sense_head].ASCQ; + msc->scsi_sense_head++; + + if (msc->scsi_sense_head == SENSE_LIST_DEEPTH) { + msc->scsi_sense_head = 0U; + } + } + + msc->bbb_datalen = USB_MIN(REQUEST_SENSE_DATA_LEN, params[4]); + + return 0; +} + +/*! + \brief process start stop unit command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static inline int8_t scsi_start_stop_unit (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_datalen = 0U; + msc->scsi_disk_pop = 1U; + + return 0; +} + +/*! + \brief process allow medium removal command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static inline int8_t scsi_allow_medium_removal (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + msc->bbb_datalen = 0U; + + return 0; +} + +/*! + \brief process read10 command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_read10 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + if (BBB_IDLE == msc->bbb_state) { + /* direction is from device to host */ + if (0x80U != (msc->bbb_cbw.bmCBWFlags & 0x80U)) { + scsi_sense_code (udev, msc->bbb_cbw.bCBWLUN, ILLEGAL_REQUEST, INVALID_CDB); + + return -1; + } + + if (0 != usbd_mem_fops->mem_ready(lun)) { + scsi_sense_code (udev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + + return -1; + } + + msc->scsi_blk_addr = (params[2] << 24U) | (params[3] << 16U) | \ + (params[4] << 8U) | params[5]; + + msc->scsi_blk_len = (params[7] << 8U) | params[8]; + + if (scsi_check_address_range (udev, lun, msc->scsi_blk_addr, (uint16_t)msc->scsi_blk_len) < 0) { + return -1; /* error */ + } + + msc->bbb_state = BBB_DATA_IN; + + msc->scsi_blk_addr *= msc->scsi_blk_size[lun]; + msc->scsi_blk_len *= msc->scsi_blk_size[lun]; + + /* cases 4,5 : Hi <> Dn */ + if (msc->bbb_cbw.dCBWDataTransferLength != msc->scsi_blk_len) { + scsi_sense_code (udev, msc->bbb_cbw.bCBWLUN, ILLEGAL_REQUEST, INVALID_CDB); + + return -1; + } + } + + msc->bbb_datalen = MSC_MEDIA_PACKET_SIZE; + + return scsi_process_read (udev, lun); +} + +/*! + \brief process write10 command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_write10 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + if (BBB_IDLE == msc->bbb_state) { + /* case 8 : Hi <> Do */ + if (0x80U == (msc->bbb_cbw.bmCBWFlags & 0x80U)) { + scsi_sense_code (udev, msc->bbb_cbw.bCBWLUN, ILLEGAL_REQUEST, INVALID_CDB); + + return -1; + } + + /* check whether media is ready */ + if (0 != usbd_mem_fops->mem_ready(lun)) { + scsi_sense_code (udev, lun, NOT_READY, MEDIUM_NOT_PRESENT); + + return -1; + } + + /* check if media is write-protected */ + if (0 != usbd_mem_fops->mem_protected(lun)) { + scsi_sense_code (udev, lun, NOT_READY, WRITE_PROTECTED); + + return -1; + } + + msc->scsi_blk_addr = (params[2] << 24U) | (params[3] << 16U) | \ + (params[4] << 8U) | params[5]; + + msc->scsi_blk_len = (params[7] << 8U) | params[8]; + + /* check if LBA address is in the right range */ + if (scsi_check_address_range (udev, lun, msc->scsi_blk_addr, (uint16_t)msc->scsi_blk_len) < 0) { + return -1; /* error */ + } + + msc->scsi_blk_addr *= msc->scsi_blk_size[lun]; + msc->scsi_blk_len *= msc->scsi_blk_size[lun]; + + /* cases 3,11,13 : Hn,Ho <> D0 */ + if (msc->bbb_cbw.dCBWDataTransferLength != msc->scsi_blk_len) { + scsi_sense_code (udev, msc->bbb_cbw.bCBWLUN, ILLEGAL_REQUEST, INVALID_CDB); + + return -1; + } + + /* prepare endpoint to receive first data packet */ + msc->bbb_state = BBB_DATA_OUT; + + usbd_ep_recev (udev, + MSC_OUT_EP, + msc->bbb_data, + USB_MIN (msc->scsi_blk_len, MSC_MEDIA_PACKET_SIZE)); + } else { /* write process ongoing */ + return scsi_process_write (udev, lun); + } + + return 0; +} + +/*! + \brief process verify10 command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_verify10 (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + if (0x02U == (params[1] & 0x02U)) { + scsi_sense_code (udev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); + + return -1; /* error, verify mode not supported*/ + } + + if (scsi_check_address_range (udev, lun, msc->scsi_blk_addr, (uint16_t)msc->scsi_blk_len) < 0) { + return -1; /* error */ + } + + msc->bbb_datalen = 0U; + + return 0; +} + +/*! + \brief check address range + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] blk_offset: block offset + \param[in] blk_nbr: number of block to be processed + \param[out] none + \retval status +*/ +static inline int8_t scsi_check_address_range (usb_core_driver *udev, uint8_t lun, uint32_t blk_offset, uint16_t blk_nbr) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + if ((blk_offset + blk_nbr) > msc->scsi_blk_nbr[lun]) { + scsi_sense_code (udev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); + + return -1; + } + + return 0; +} + +/*! + \brief handle read process + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[out] none + \retval status +*/ +static int8_t scsi_process_read (usb_core_driver *udev, uint8_t lun) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + uint32_t len = USB_MIN(msc->scsi_blk_len, MSC_MEDIA_PACKET_SIZE); + + if (usbd_mem_fops->mem_read(lun, + msc->bbb_data, + msc->scsi_blk_addr, + (uint16_t)(len / msc->scsi_blk_size[lun])) < 0) { + scsi_sense_code(udev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR); + + return -1; + } + + usbd_ep_send (udev, MSC_IN_EP, msc->bbb_data, len); + + msc->scsi_blk_addr += len; + msc->scsi_blk_len -= len; + + /* case 6 : Hi = Di */ + msc->bbb_csw.dCSWDataResidue -= len; + + if (0U == msc->scsi_blk_len) { + msc->bbb_state = BBB_LAST_DATA_IN; + } + + return 0; +} + +/*! + \brief handle write process + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[out] none + \retval status +*/ +static int8_t scsi_process_write (usb_core_driver *udev, uint8_t lun) +{ + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + uint32_t len = USB_MIN(msc->scsi_blk_len, MSC_MEDIA_PACKET_SIZE); + + if (usbd_mem_fops->mem_write (lun, + msc->bbb_data, + msc->scsi_blk_addr, + (uint16_t)(len / msc->scsi_blk_size[lun])) < 0) { + scsi_sense_code(udev, lun, HARDWARE_ERROR, WRITE_FAULT); + + return -1; + } + + msc->scsi_blk_addr += len; + msc->scsi_blk_len -= len; + + /* case 12 : Ho = Do */ + msc->bbb_csw.dCSWDataResidue -= len; + + if (0U == msc->scsi_blk_len) { + msc_bbb_csw_send (udev, CSW_CMD_PASSED); + } else { + /* prepare endpoint to receive next packet */ + usbd_ep_recev (udev, + MSC_OUT_EP, + msc->bbb_data, + USB_MIN (msc->scsi_blk_len, MSC_MEDIA_PACKET_SIZE)); + } + + return 0; +} + +/*! + \brief process format unit command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[out] none + \retval status +*/ +static inline int8_t scsi_format_cmd (usb_core_driver *udev, uint8_t lun) +{ + return 0; +} + +/*! + \brief process Read_Toc command + \param[in] udev: pointer to USB device instance + \param[in] lun: logical unit number + \param[in] params: command parameters + \param[out] none + \retval status +*/ +static int8_t scsi_toc_cmd_read (usb_core_driver *udev, uint8_t lun, uint8_t *params) +{ + uint8_t* pPage; + uint16_t len; + + usbd_msc_handler *msc = (usbd_msc_handler *)udev->dev.class_data[USBD_MSC_INTERFACE]; + + pPage = (uint8_t *)&usbd_mem_fops->mem_toc_data[lun * READ_TOC_CMD_LEN]; + len = (uint16_t)pPage[1] + 2U; + + msc->bbb_datalen = len; + + while (len) { + len--; + msc->bbb_data[len] = pPage[len]; + } + + return 0; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Include/printer_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Include/printer_core.h new file mode 100644 index 0000000000..47a88edcde --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Include/printer_core.h @@ -0,0 +1,78 @@ +/*! + \file printer_core.h + \brief the header file of USB printer device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __PRINTER_CORE_H +#define __PRINTER_CORE_H + +#include "usbd_enum.h" +#include "usb_ch9_std.h" + +/* USB printing device class code */ +#define USB_CLASS_PRINTER 0x07U + +/* printing device subclass code */ +#define USB_SUBCLASS_PRINTER 0x01U + +/* printing device protocol code */ +#define PROTOCOL_UNIDIRECTIONAL_ITF 0x01U +#define PROTOCOL_BI_DIRECTIONAL_ITF 0x02U +#define PROTOCOL_1284_4_ITF 0x03U +#define PROTOCOL_VENDOR 0xFFU + +#define DEVICE_ID_LEN 103U + +#define USB_PRINTER_CONFIG_DESC_LEN 32U + +/* printing device specific-class request */ +#define GET_DEVICE_ID 0x00U +#define GET_PORT_STATUS 0x01U +#define SOFT_RESET 0x02U + +#pragma pack(1) + +/* USB configuration descriptor structure */ +typedef struct +{ + usb_desc_config config; + usb_desc_itf printer_itf; + usb_desc_ep printer_epin; + usb_desc_ep printer_epout; +} usb_printer_desc_config_set; + +#pragma pack() + +extern usb_desc printer_desc; +extern usb_class_core usbd_printer_cb; + +#endif /* __PRINTER_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Source/printer_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Source/printer_core.c new file mode 100644 index 0000000000..c24cf4f8e1 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/class/printer/Source/printer_core.c @@ -0,0 +1,302 @@ +/*! + \file printer_core.c + \brief USB printer device class core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "printer_core.h" + +#define USBD_VID 0x28E9U +#define USBD_PID 0x028DU + +/* printer port status: paper not empty/selected/no error */ +static uint8_t g_port_status = 0x18U; + +uint8_t g_printer_data_buf[PRINTER_OUT_PACKET]; + +__ALIGN_BEGIN uint8_t PRINTER_DEVICE_ID[DEVICE_ID_LEN] __ALIGN_END = { + 0x00, 0x67, + 'M', 'A', 'N', 'U', 'F', 'A', 'C', 'T', 'U', 'R', 'E', 'R', ':', + 'G', 'I', 'G', 'A', ' ', 'D', 'E', 'V', 'I', 'C', 'E', '-', ';', + 'C', 'O', 'M', 'M', 'A', 'N', 'D', ' ', 'S', 'E', 'T', ':', + 'P', 'C', 'L', ',', 'M', 'P', 'L', ';', + 'M', 'O', 'D', 'E', 'L', ':', + 'L', 'a', 's', 'e', 'r', 'B', 'e', 'a', 'm', '?', ';', + 'C', 'O', 'M', 'M', 'E', 'N', 'T', ':', + 'G', 'o', 'o', 'd', ' ', '!', ';', + 'A', 'C', 'T', 'I', 'V', 'E', ' ', 'C', 'O', 'M', 'M', 'A', 'N', 'D', ' ', 'S', 'E', 'T', ':', + 'P', 'C', 'L', ';' +}; + +/* USB standard device descriptor */ +__ALIGN_BEGIN const usb_desc_dev printer_dev_desc __ALIGN_END = { + .header = + { + .bLength = USB_DEV_DESC_LEN, + .bDescriptorType = USB_DESCTYPE_DEV, + }, + .bcdUSB = 0x0200U, + .bDeviceClass = 0x00U, + .bDeviceSubClass = 0x00U, + .bDeviceProtocol = 0x00U, + .bMaxPacketSize0 = USB_FS_EP0_MAX_LEN, + .idVendor = USBD_VID, + .idProduct = USBD_PID, + .bcdDevice = 0x0100U, + .iManufacturer = STR_IDX_MFC, + .iProduct = STR_IDX_PRODUCT, + .iSerialNumber = STR_IDX_SERIAL, + .bNumberConfigurations = USBD_CFG_MAX_NUM, +}; + +/* USB device configuration descriptor */ +__ALIGN_BEGIN const usb_printer_desc_config_set printer_config_desc __ALIGN_END = { + .config = + { + .header = + { + .bLength = sizeof(usb_desc_config), + .bDescriptorType = USB_DESCTYPE_CONFIG + }, + .wTotalLength = sizeof(usb_printer_desc_config_set), + .bNumInterfaces = 0x01U, + .bConfigurationValue = 0x01U, + .iConfiguration = 0x00U, + .bmAttributes = 0xA0U, + .bMaxPower = 0x32U + }, + + .printer_itf = + { + .header = + { + .bLength = sizeof(usb_desc_itf), + .bDescriptorType = USB_DESCTYPE_ITF + }, + .bInterfaceNumber = 0x00U, + .bAlternateSetting = 0x00U, + .bNumEndpoints = 0x02U, + .bInterfaceClass = USB_CLASS_PRINTER, + .bInterfaceSubClass = USB_SUBCLASS_PRINTER, + .bInterfaceProtocol = PROTOCOL_BI_DIRECTIONAL_ITF, + .iInterface = 0x00U + }, + + .printer_epin = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = PRINTER_IN_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = PRINTER_IN_PACKET, + .bInterval = 0x00U + }, + + .printer_epout = + { + .header = + { + .bLength = sizeof(usb_desc_ep), + .bDescriptorType = USB_DESCTYPE_EP + }, + .bEndpointAddress = PRINTER_OUT_EP, + .bmAttributes = USB_EP_ATTR_BULK, + .wMaxPacketSize = PRINTER_OUT_PACKET, + .bInterval = 0x00U + }, +}; + +/* USB language ID Descriptor */ +__ALIGN_BEGIN static const usb_desc_LANGID usbd_language_id_desc __ALIGN_END = { + .header = + { + .bLength = sizeof(usb_desc_LANGID), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .wLANGID = ENG_LANGID +}; + +/* USB manufacture string */ +__ALIGN_BEGIN static const usb_desc_str manufacturer_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(10U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'i', 'g', 'a', 'D', 'e', 'v', 'i', 'c', 'e'} +}; + +/* USB product string */ +__ALIGN_BEGIN static const usb_desc_str product_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(16U), + .bDescriptorType = USB_DESCTYPE_STR, + }, + .unicode_string = {'G', 'D', '3', '2', '-', 'U', 'S', 'B', '_', 'P', 'r', 'i', 'n', 't', 'e', 'r'} +}; + +/* USBD serial string */ +__ALIGN_BEGIN static usb_desc_str serial_string __ALIGN_END = { + .header = + { + .bLength = USB_STRING_LEN(12U), + .bDescriptorType = USB_DESCTYPE_STR, + } +}; + +/* USB string descriptor */ +static void *const usbd_strings[] = { + [STR_IDX_LANGID] = (uint8_t *) &usbd_language_id_desc, + [STR_IDX_MFC] = (uint8_t *) &manufacturer_string, + [STR_IDX_PRODUCT] = (uint8_t *) &product_string, + [STR_IDX_SERIAL] = (uint8_t *) &serial_string +}; + +usb_desc printer_desc = { + .dev_desc = (uint8_t *) &printer_dev_desc, + .config_desc = (uint8_t *) &printer_config_desc, + .strings = usbd_strings +}; + +/* local function prototypes ('static') */ +static uint8_t printer_init(usb_dev *udev, uint8_t config_index); +static uint8_t printer_deinit(usb_dev *udev, uint8_t config_index); +static uint8_t printer_req(usb_dev *udev, usb_req *req); +static uint8_t printer_in(usb_dev *udev, uint8_t ep_num); +static uint8_t printer_out(usb_dev *udev, uint8_t ep_num); + +usb_class_core usbd_printer_cb = { + .init = printer_init, + .deinit = printer_deinit, + + .req_proc = printer_req, + + .data_in = printer_in, + .data_out = printer_out +}; + +/*! + \brief initialize the printer device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t printer_init(usb_dev *udev, uint8_t config_index) +{ + /* initialize the data TX endpoint */ + usbd_ep_setup(udev, &(printer_config_desc.printer_epin)); + + /* initialize the data RX endpoint */ + usbd_ep_setup(udev, &(printer_config_desc.printer_epout)); + + /* prepare to receive data */ + usbd_ep_recev(udev, PRINTER_OUT_EP, g_printer_data_buf, PRINTER_OUT_PACKET); + + return USBD_OK; +} + +/*! + \brief deinitialize the printer device + \param[in] udev: pointer to USB device instance + \param[in] config_index: configuration index + \param[out] none + \retval USB device operation status +*/ +static uint8_t printer_deinit(usb_dev *udev, uint8_t config_index) +{ + /* deinitialize the data TX/RX endpoint */ + usbd_ep_clear(udev, PRINTER_IN_EP); + usbd_ep_clear(udev, PRINTER_OUT_EP); + + return USBD_OK; +} + +/*! + \brief handle the printer class-specific requests + \param[in] udev: pointer to USB device instance + \param[in] req: device class-specific request + \param[out] none + \retval USB device operation status +*/ +static uint8_t printer_req(usb_dev *udev, usb_req *req) +{ + usb_transc *transc = &udev->dev.transc_in[0]; + + switch(req->bRequest) { + case GET_DEVICE_ID: + transc->xfer_buf = (uint8_t *)PRINTER_DEVICE_ID; + transc->remain_len = DEVICE_ID_LEN; + break; + + case GET_PORT_STATUS: + transc->xfer_buf = (uint8_t *)&g_port_status; + transc->remain_len = 1U; + break; + + case SOFT_RESET: + usbd_ep_recev(udev, PRINTER_OUT_EP, g_printer_data_buf, PRINTER_OUT_PACKET); + break; + + default: + return USBD_FAIL; + } + + return USBD_OK; +} + +/*! + \brief handle printer data + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval USB device operation status +*/ +static uint8_t printer_in(usb_dev *udev, uint8_t ep_num) +{ + return USBD_OK; +} + +/*! + \brief handle printer data + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval USB device operation status +*/ +static uint8_t printer_out(usb_dev *udev, uint8_t ep_num) +{ + return USBD_OK; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_core.h new file mode 100644 index 0000000000..c88fe927a0 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_core.h @@ -0,0 +1,103 @@ +/*! + \file usbd_core.h + \brief USB device mode core functions protype + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_CORE_H +#define __USBD_CORE_H + +#include "drv_usb_core.h" +#include "drv_usb_dev.h" + +typedef enum +{ + USBD_OK = 0U, /*!< status OK */ + USBD_BUSY, /*!< status busy */ + USBD_FAIL, /*!< status fail */ +} usbd_status; + +enum _usbd_status { + USBD_DEFAULT = 1U, /*!< default status */ + USBD_ADDRESSED = 2U, /*!< address send status */ + USBD_CONFIGURED = 3U, /*!< configured status */ + USBD_SUSPENDED = 4U /*!< suspended status */ +}; + +/* static inline function definitions */ + +/*! + \brief set USB device address + \param[in] udev: pointer to USB core instance + \param[in] addr: device address to set + \param[out] none + \retval none +*/ +__STATIC_INLINE void usbd_addr_set (usb_core_driver *udev, uint8_t addr) +{ + usb_devaddr_set(udev, addr); +} + +/*! + \brief get the received data length + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint number + \param[out] none + \retval USB device operation cur_status +*/ +__STATIC_INLINE uint16_t usbd_rxcount_get (usb_core_driver *udev, uint8_t ep_num) +{ + return (uint16_t)udev->dev.transc_out[ep_num].xfer_count; +} + +/* function declarations */ +/* initializes the USB device-mode stack and load the class driver */ +void usbd_init (usb_core_driver *udev, usb_desc *desc, usb_class_core *class_core); +/* endpoint initialization */ +uint32_t usbd_ep_setup (usb_core_driver *udev, const usb_desc_ep *ep_desc); +/* configure the endpoint when it is disabled */ +uint32_t usbd_ep_clear (usb_core_driver *udev, uint8_t ep_addr); +/* endpoint prepare to receive data */ +uint32_t usbd_ep_recev (usb_core_driver *udev, uint8_t ep_addr, uint8_t *pbuf, uint32_t len); +/* endpoint prepare to transmit data */ +uint32_t usbd_ep_send (usb_core_driver *udev, uint8_t ep_addr, uint8_t *pbuf, uint32_t len); +/* set an endpoint to STALL status */ +uint32_t usbd_ep_stall (usb_core_driver *udev, uint8_t ep_addr); +/* clear endpoint STALLed status */ +uint32_t usbd_ep_stall_clear (usb_core_driver *udev, uint8_t ep_addr); +/* flush the endpoint FIFOs */ +uint32_t usbd_fifo_flush (usb_core_driver *udev, uint8_t ep_addr); +/* device connect */ +void usbd_connect (usb_core_driver *udev); +/* device disconnect */ +void usbd_disconnect (usb_core_driver *udev); + +#endif /* __USBD_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_enum.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_enum.h new file mode 100644 index 0000000000..43cdc250e6 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_enum.h @@ -0,0 +1,105 @@ +/*! + \file usbd_enum.h + \brief USB enumeration definitions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_ENUM_H +#define __USBD_ENUM_H + +#include "usbd_core.h" +#include "usbd_conf.h" +#include + +#ifndef NULL + #define NULL 0U +#endif + +typedef enum _usb_reqsta { + REQ_SUPP = 0x0U, /* request support */ + REQ_NOTSUPP = 0x1U, /* request not support */ +} usb_reqsta; + +/* string descriptor index */ +enum _str_index +{ + STR_IDX_LANGID = 0x0U, /* language ID string index */ + STR_IDX_MFC = 0x1U, /* manufacturer string index */ + STR_IDX_PRODUCT = 0x2U, /* product string index */ + STR_IDX_SERIAL = 0x3U, /* serial string index */ + STR_IDX_CONFIG = 0x4U, /* configuration string index */ + STR_IDX_ITF = 0x5U, /* interface string index */ +#ifndef WINUSB_EXEMPT_DRIVER + STR_IDX_MAX = 0x6U, /* string maximum index */ +#else + STR_IDX_MAX = 0xEFU, /* string maximum index */ +#endif /* WINUSB_EXEMPT_DRIVER */ +}; + +typedef enum _usb_pwrsta { + USB_PWRSTA_SELF_POWERED = 0x1U, /* USB is in self powered status */ + USB_PWRSTA_REMOTE_WAKEUP = 0x2U, /* USB is in remote wakeup status */ +} usb_pwrsta; + +typedef enum _usb_feature +{ + USB_FEATURE_EP_HALT = 0x0U, /* USB has endpoint halt feature */ + USB_FEATURE_REMOTE_WAKEUP = 0x1U, /* USB has endpoint remote wakeup feature */ + USB_FEATURE_TEST_MODE = 0x2U, /* USB has endpoint test mode feature */ +} usb_feature; + +#define ENG_LANGID 0x0409U /* english language ID */ +#define CHN_LANGID 0x0804U /* chinese language ID */ + +/* USB device exported macros */ +#define CTL_EP(ep) (((ep) == 0x00U) || ((ep) == 0x80U)) + +#define DEVICE_ID1 (0x1FF0F7E8U) /* device ID1 */ +#define DEVICE_ID2 (0x1FF0F7ECU) /* device ID2 */ +#define DEVICE_ID3 (0x1FF0F7F0U) /* device ID3 */ + +#define DEVICE_ID (0x52002100U) + +/* function declarations */ +/* handle USB standard device request */ +usb_reqsta usbd_standard_request (usb_core_driver *udev, usb_req *req); +/* handle USB device class request */ +usb_reqsta usbd_class_request (usb_core_driver *udev, usb_req *req); +/* handle USB vendor request */ +usb_reqsta usbd_vendor_request (usb_core_driver *udev, usb_req *req); +/* handle USB enumeration error */ +void usbd_enum_error (usb_core_driver *udev, usb_req *req); +/* convert hex 32bits value into unicode char */ +void int_to_unicode (uint32_t value, uint8_t *pbuf, uint8_t len); +/* get serial string */ +void serial_string_get (uint16_t *unicode_str); + +#endif /* __USBD_ENUM_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_transc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_transc.h new file mode 100644 index 0000000000..bc4255fab1 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Include/usbd_transc.h @@ -0,0 +1,56 @@ +/*! + \file usbd_transc.h + \brief USB transaction core functions prototype + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBD_TRANSC_H +#define __USBD_TRANSC_H + +#include "usbd_core.h" + +/* function declarations */ +/* USB send data in the control transaction */ +usbd_status usbd_ctl_send (usb_core_driver *udev); +/* USB receive data in control transaction */ +usbd_status usbd_ctl_recev (usb_core_driver *udev); +/* USB send control transaction status */ +usbd_status usbd_ctl_status_send (usb_core_driver *udev); +/* USB control receive status */ +usbd_status usbd_ctl_status_recev (usb_core_driver *udev); +/* USB setup stage processing */ +uint8_t usbd_setup_transc (usb_core_driver *udev); +/* data out stage processing */ +uint8_t usbd_out_transc (usb_core_driver *udev, uint8_t ep_num); +/* data in stage processing */ +uint8_t usbd_in_transc (usb_core_driver *udev, uint8_t ep_num); + +#endif /* __USBD_TRANSC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_core.c new file mode 100644 index 0000000000..d414baa7d2 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_core.c @@ -0,0 +1,311 @@ +/*! + \file usbd_core.c + \brief USB device mode core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_core.h" +#include "usbd_enum.h" +#include "drv_usb_hw.h" + +/* endpoint type */ +const uint32_t ep_type[] = { + [USB_EP_ATTR_CTL] = (uint32_t)USB_EPTYPE_CTRL, + [USB_EP_ATTR_BULK] = (uint32_t)USB_EPTYPE_BULK, + [USB_EP_ATTR_INT] = (uint32_t)USB_EPTYPE_INTR, + [USB_EP_ATTR_ISO] = (uint32_t)USB_EPTYPE_ISOC +}; + +/*! + \brief initializes the USB device-mode stack and load the class driver + \param[in] udev: pointer to USB core instance + \param[in] desc: pointer to USB descriptor + \param[in] class_core: class driver + \param[out] none + \retval none +*/ +void usbd_init(usb_core_driver *udev, usb_desc *desc, usb_class_core *class_core) +{ + udev->dev.desc = desc; + + /* class callbacks */ + udev->dev.class_core = class_core; + + /* create serial string */ + serial_string_get(udev->dev.desc->strings[STR_IDX_SERIAL]); + + /* configure USB capabilities */ + (void)usb_basic_init(&udev->bp, &udev->regs); + + /* initializes the USB core*/ + (void)usb_core_init(udev->bp, &udev->regs); + + /* set device disconnect */ + usbd_disconnect(udev); + + /* initializes device mode */ + (void)usb_devcore_init(udev); + + /* set device connect */ + usbd_connect(udev); + + udev->dev.cur_status = (uint8_t)USBD_DEFAULT; +} + +/*! + \brief endpoint initialization + \param[in] udev: pointer to USB core instance + \param[in] ep_desc: pointer to endpoint descriptor + \param[out] none + \retval none +*/ +uint32_t usbd_ep_setup(usb_core_driver *udev, const usb_desc_ep *ep_desc) +{ + usb_transc *transc; + + uint8_t ep_addr = ep_desc->bEndpointAddress; + uint16_t max_len = ep_desc->wMaxPacketSize; + + /* set endpoint direction */ + if(EP_DIR(ep_addr)) { + transc = &udev->dev.transc_in[EP_ID(ep_addr)]; + + transc->ep_addr.dir = 1U; + } else { + transc = &udev->dev.transc_out[ep_addr]; + + transc->ep_addr.dir = 0U; + } + + transc->ep_addr.num = EP_ID(ep_addr); + transc->max_len = max_len; + transc->ep_type = (uint8_t)ep_type[ep_desc->bmAttributes & (uint8_t)USB_EPTYPE_MASK]; + + /* active USB endpoint function */ + (void)usb_transc_active(udev, transc); + + return 0U; +} + +/*! + \brief configure the endpoint when it is disabled + \param[in] udev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval none +*/ +uint32_t usbd_ep_clear(usb_core_driver *udev, uint8_t ep_addr) +{ + usb_transc *transc; + + if(EP_DIR(ep_addr)) { + transc = &udev->dev.transc_in[EP_ID(ep_addr)]; + } else { + transc = &udev->dev.transc_out[ep_addr]; + } + + /* deactivate USB endpoint function */ + (void)usb_transc_deactivate(udev, transc); + + return 0U; +} + +/*! + \brief endpoint prepare to receive data + \param[in] udev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[in] pbuf: user buffer address pointer + \param[in] len: buffer length + \param[out] none + \retval none +*/ +uint32_t usbd_ep_recev(usb_core_driver *udev, uint8_t ep_addr, uint8_t *pbuf, uint32_t len) +{ + usb_transc *transc = &udev->dev.transc_out[EP_ID(ep_addr)]; + + /* setup the transfer */ + transc->xfer_buf = pbuf; + transc->xfer_len = len; + transc->xfer_count = 0U; + + if((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + transc->dma_addr = (uint32_t)pbuf; + } + + /* start the transfer */ + (void)usb_transc_outxfer(udev, transc); + + return 0U; +} + +/*! + \brief endpoint prepare to transmit data + \param[in] udev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[in] pbuf: transmit buffer address pointer + \param[in] len: buffer length + \param[out] none + \retval none +*/ +uint32_t usbd_ep_send(usb_core_driver *udev, uint8_t ep_addr, uint8_t *pbuf, uint32_t len) +{ + usb_transc *transc = &udev->dev.transc_in[EP_ID(ep_addr)]; + + /* setup the transfer */ + transc->xfer_buf = pbuf; + transc->xfer_len = len; + transc->xfer_count = 0U; + + if((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + transc->dma_addr = (uint32_t)pbuf; + } + + /* start the transfer */ + (void)usb_transc_inxfer(udev, transc); + + return 0U; +} + +/*! + \brief set an endpoint to STALL status + \param[in] udev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval none +*/ +uint32_t usbd_ep_stall(usb_core_driver *udev, uint8_t ep_addr) +{ + usb_transc *transc = NULL; + + if(EP_DIR(ep_addr)) { + transc = &udev->dev.transc_in[EP_ID(ep_addr)]; + } else { + transc = &udev->dev.transc_out[ep_addr]; + } + + transc->ep_stall = 1U; + + (void)usb_transc_stall(udev, transc); + + return (0U); +} + +/*! + \brief clear endpoint STALLed status + \param[in] udev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval none +*/ +uint32_t usbd_ep_stall_clear(usb_core_driver *udev, uint8_t ep_addr) +{ + usb_transc *transc = NULL; + + if(EP_DIR(ep_addr)) { + transc = &udev->dev.transc_in[EP_ID(ep_addr)]; + } else { + transc = &udev->dev.transc_out[ep_addr]; + } + + transc->ep_stall = 0U; + + (void)usb_transc_clrstall(udev, transc); + + return (0U); +} + +/*! + \brief flush the endpoint FIFOs + \param[in] udev: pointer to USB core instance + \param[in] ep_addr: endpoint address + in this parameter: + bit0..bit6: endpoint number (0..7) + bit7: endpoint direction which can be IN(1) or OUT(0) + \param[out] none + \retval none +*/ +uint32_t usbd_fifo_flush(usb_core_driver *udev, uint8_t ep_addr) +{ + if(EP_DIR(ep_addr)) { + (void)usb_txfifo_flush(&udev->regs, EP_ID(ep_addr)); + } else { + (void)usb_rxfifo_flush(&udev->regs); + } + + return (0U); +} + +/*! + \brief device connect + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +void usbd_connect(usb_core_driver *udev) +{ +#ifndef USE_OTG_MODE + /* connect device */ + usb_dev_connect(udev); + + usb_mdelay(3U); +#endif /* USE_OTG_MODE */ +} + +/*! + \brief device disconnect + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +void usbd_disconnect(usb_core_driver *udev) +{ +#ifndef USE_OTG_MODE + /* disconnect device for 3ms */ + usb_dev_disconnect(udev); + + usb_mdelay(3U); +#endif /* USE_OTG_MODE */ +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_enum.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_enum.c new file mode 100644 index 0000000000..c324c003da --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_enum.c @@ -0,0 +1,817 @@ +/*! + \file usbd_enum.c + \brief USB enumeration function + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_enum.h" +#include "usb_ch9_std.h" + +#ifdef WINUSB_EXEMPT_DRIVER + +extern usbd_status usbd_OEM_req(usb_dev *udev, usb_req *req); + +#endif /* WINUSB_EXEMPT_DRIVER */ + +/* local function prototypes ('static') */ +static usb_reqsta _usb_std_reserved(usb_core_driver *udev, usb_req *req); +static uint8_t *_usb_dev_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len); +static uint8_t *_usb_config_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len); +static uint8_t *_usb_bos_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len); +static uint8_t *_usb_str_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len); +static usb_reqsta _usb_std_getstatus(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_clearfeature(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_setfeature(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_setaddress(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_getdescriptor(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_setdescriptor(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_getconfiguration(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_setconfiguration(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_getinterface(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_setinterface(usb_core_driver *udev, usb_req *req); +static usb_reqsta _usb_std_synchframe(usb_core_driver *udev, usb_req *req); + +#ifdef USE_USB_HS +static uint8_t *_usb_other_speed_config_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len); +static uint8_t *_usb_qualifier_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len); +#endif + +static usb_reqsta(*_std_dev_req[])(usb_core_driver *udev, usb_req *req) = { + [USB_GET_STATUS] = _usb_std_getstatus, + [USB_CLEAR_FEATURE] = _usb_std_clearfeature, + [USB_RESERVED2] = _usb_std_reserved, + [USB_SET_FEATURE] = _usb_std_setfeature, + [USB_RESERVED4] = _usb_std_reserved, + [USB_SET_ADDRESS] = _usb_std_setaddress, + [USB_GET_DESCRIPTOR] = _usb_std_getdescriptor, + [USB_SET_DESCRIPTOR] = _usb_std_setdescriptor, + [USB_GET_CONFIGURATION] = _usb_std_getconfiguration, + [USB_SET_CONFIGURATION] = _usb_std_setconfiguration, + [USB_GET_INTERFACE] = _usb_std_getinterface, + [USB_SET_INTERFACE] = _usb_std_setinterface, + [USB_SYNCH_FRAME] = _usb_std_synchframe, +}; + +/* get standard descriptor handler */ +static uint8_t *(*std_desc_get[])(usb_core_driver *udev, uint8_t index, uint16_t *len) = { + [(uint8_t)USB_DESCTYPE_DEV - 1U] = _usb_dev_desc_get, + [(uint8_t)USB_DESCTYPE_CONFIG - 1U] = _usb_config_desc_get, + [(uint8_t)USB_DESCTYPE_STR - 1U] = _usb_str_desc_get, +#ifdef USE_USB_HS + [(uint8_t)USB_DESCTYPE_DEV_QUALIFIER - 3U] = _usb_qualifier_desc_get, + [(uint8_t)USB_DESCTYPE_OTHER_SPD_CONFIG - 3U] = _usb_other_speed_config_desc_get, +#endif +}; + +/*! + \brief handle USB standard device request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +usb_reqsta usbd_standard_request(usb_core_driver *udev, usb_req *req) +{ + return (*_std_dev_req[req->bRequest])(udev, req); +} + +/*! + \brief handle USB device class request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device class request + \param[out] none + \retval USB device request status +*/ +usb_reqsta usbd_class_request(usb_core_driver *udev, usb_req *req) +{ + if((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) { + if(BYTE_LOW(req->wIndex) <= USBD_ITF_MAX_NUM) { + /* call device class handle function */ + return (usb_reqsta)udev->dev.class_core->req_proc(udev, req); + } + } + + return REQ_NOTSUPP; +} + +/*! + \brief handle USB vendor request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB vendor request + \param[out] none + \retval USB device request status +*/ +usb_reqsta usbd_vendor_request(usb_core_driver *udev, usb_req *req) +{ + (void)udev; + (void)req; + + /* added by user... */ +#ifdef WINUSB_EXEMPT_DRIVER + usbd_OEM_req(udev, req); +#endif + + return REQ_SUPP; +} + +/*! + \brief handle USB enumeration error + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval none +*/ +void usbd_enum_error(usb_core_driver *udev, usb_req *req) +{ + (void)req; + + (void)usbd_ep_stall(udev, 0x80U); + (void)usbd_ep_stall(udev, 0x00U); + + usb_ctlep_startout(udev); +} + +/*! + \brief convert hex 32bits value into unicode char + \param[in] value: hex 32bits value + \param[in] pbuf: buffer pointer to store unicode char + \param[in] len: value length + \param[out] none + \retval none +*/ +void int_to_unicode(uint32_t value, uint8_t *pbuf, uint8_t len) +{ + uint8_t index; + + for(index = 0U; index < len; index++) { + if((value >> 28U) < 0x0AU) { + pbuf[2U * index] = (uint8_t)((value >> 28U) + '0'); + } else { + pbuf[2U * index] = (uint8_t)((value >> 28U) + 'A' - 10U); + } + + value = value << 4U; + + pbuf[2U * index + 1U] = 0U; + } +} + +/*! + \brief convert hex 32bits value into unicode char + \param[in] unicode_str: pointer to unicode string + \param[out] none + \retval none +*/ +void serial_string_get(uint16_t *unicode_str) +{ + if((unicode_str[0] & 0x00FFU) != 6U) { + uint32_t DeviceSerial0, DeviceSerial1, DeviceSerial2; + + DeviceSerial0 = *(uint32_t *)DEVICE_ID1; + DeviceSerial1 = *(uint32_t *)DEVICE_ID2; + DeviceSerial2 = *(uint32_t *)DEVICE_ID3; + + DeviceSerial0 += DeviceSerial2; + + if(0U != DeviceSerial0) { + int_to_unicode(DeviceSerial0, (uint8_t *) & (unicode_str[1]), 8U); + int_to_unicode(DeviceSerial1, (uint8_t *) & (unicode_str[9]), 4U); + } + } else { + uint32_t device_serial = *(uint32_t *)DEVICE_ID; + + if(0U != device_serial) { + unicode_str[1] = (uint16_t)(device_serial & 0x0000FFFFU); + unicode_str[2] = (uint16_t)((device_serial & 0xFFFF0000U) >> 16U); + + } + } +} + +/*! + \brief no operation, just for reserved + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB vendor request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_reserved(usb_core_driver *udev, usb_req *req) +{ + (void)udev; + (void)req; + + /* no operation... */ + + return REQ_NOTSUPP; +} + +/*! + \brief get the device descriptor + \param[in] udev: pointer to USB device instance + \param[in] index: no use + \param[out] len: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t *_usb_dev_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len) +{ + (void)index; + + *len = udev->dev.desc->dev_desc[0]; + + return udev->dev.desc->dev_desc; +} + +/*! + \brief get the configuration descriptor + \brief[in] udev: pointer to USB device instance + \brief[in] index: no use + \param[out] len: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t *_usb_config_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len) +{ + (void)index; + + *len = udev->dev.desc->config_desc[2] | (udev->dev.desc->config_desc[3] << 8); + + return udev->dev.desc->config_desc; +} + +#ifdef USE_USB_HS +/*! + \brief get the other speed configuration descriptor + \brief[in] udev: pointer to USB device instance + \brief[in] index: no use + \param[out] len: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t *_usb_other_speed_config_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len) +{ + (void)index; + + *len = udev->dev.desc->other_speed_config_desc[2]; + + return udev->dev.desc->other_speed_config_desc; +} + +/*! + \brief get the other speed configuration descriptor + \brief[in] udev: pointer to USB device instance + \brief[in] index: no use + \param[out] len: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t *_usb_qualifier_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len) +{ + (void)index; + + *len = udev->dev.desc->qualifier_desc[0]; + + return udev->dev.desc->qualifier_desc; +} +#endif + +/*! + \brief get the BOS descriptor + \brief[in] udev: pointer to USB device instance + \brief[in] index: no use + \param[out] len: data length pointer + \retval descriptor buffer pointer +*/ +static uint8_t *_usb_bos_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len) +{ + (void)index; + + *len = udev->dev.desc->bos_desc[2]; + + return udev->dev.desc->bos_desc; +} + +/*! + \brief get string descriptor + \param[in] udev: pointer to USB device instance + \param[in] index: string descriptor index + \param[out] len: pointer to string length + \retval descriptor buffer pointer +*/ +static uint8_t *_usb_str_desc_get(usb_core_driver *udev, uint8_t index, uint16_t *len) +{ + uint8_t *desc = udev->dev.desc->strings[index]; + + *len = desc[0]; + + return desc; +} + +/*! + \brief handle Get_Status request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_getstatus(usb_core_driver *udev, usb_req *req) +{ + uint8_t recp = BYTE_LOW(req->wIndex); + usb_reqsta req_status = REQ_NOTSUPP; + usb_transc *transc = &udev->dev.transc_in[0]; + + static uint8_t status[2] = {0}; + + switch(req->bmRequestType & (uint8_t)USB_RECPTYPE_MASK) { + case USB_RECPTYPE_DEV: + if(((uint8_t)USBD_ADDRESSED == udev->dev.cur_status) || \ + ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status)) { + + if(udev->dev.pm.power_mode) { + status[0] = USB_STATUS_SELF_POWERED; + } else { + status[0] = 0U; + } + + if(udev->dev.pm.dev_remote_wakeup) { + status[0] |= USB_STATUS_REMOTE_WAKEUP; + } else { + status[0] = 0U; + } + + req_status = REQ_SUPP; + } + break; + + case USB_RECPTYPE_ITF: + if(((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) && (recp <= USBD_ITF_MAX_NUM)) { + req_status = REQ_SUPP; + } + break; + + case USB_RECPTYPE_EP: + if((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) { + if(0x80U == (recp & 0x80U)) { + status[0] = udev->dev.transc_in[EP_ID(recp)].ep_stall; + } else { + status[0] = udev->dev.transc_out[recp].ep_stall; + } + + req_status = REQ_SUPP; + } + break; + + default: + break; + } + + if(REQ_SUPP == req_status) { + transc->xfer_buf = status; + transc->remain_len = 2U; + } + + return req_status; +} + +/*! + \brief handle USB Clear_Feature request + \param[in] udev: pointer to USB device instance + \param[in] req: USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_clearfeature(usb_core_driver *udev, usb_req *req) +{ + uint8_t ep = 0U; + + switch(req->bmRequestType & (uint8_t)USB_RECPTYPE_MASK) { + case USB_RECPTYPE_DEV: + if(((uint8_t)USBD_ADDRESSED == udev->dev.cur_status) || \ + ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status)) { + + /* clear device remote wakeup feature */ + if((uint16_t)USB_FEATURE_REMOTE_WAKEUP == req->wValue) { + udev->dev.pm.dev_remote_wakeup = 0U; + + return REQ_SUPP; + } + } + break; + + case USB_RECPTYPE_ITF: + break; + + case USB_RECPTYPE_EP: + /* get endpoint address */ + ep = BYTE_LOW(req->wIndex); + + if((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) { + /* clear endpoint halt feature */ + if(((uint16_t)USB_FEATURE_EP_HALT == req->wValue) && (!CTL_EP(ep))) { + (void)usbd_ep_stall_clear(udev, ep); + + (void)udev->dev.class_core->req_proc(udev, req); + } + + return REQ_SUPP; + } + break; + + default: + break; + } + + return REQ_NOTSUPP; +} + +/*! + \brief handle USB Set_Feature request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_setfeature(usb_core_driver *udev, usb_req *req) +{ + uint8_t ep = 0U; + + switch(req->bmRequestType & (uint8_t)USB_RECPTYPE_MASK) { + case USB_RECPTYPE_DEV: + if(((uint8_t)USBD_ADDRESSED == udev->dev.cur_status) || \ + ((uint8_t)USBD_CONFIGURED == udev->dev.cur_status)) { + /* set device remote wakeup feature */ + if((uint16_t)USB_FEATURE_REMOTE_WAKEUP == req->wValue) { + udev->dev.pm.dev_remote_wakeup = 1U; + } + + return REQ_SUPP; + } + break; + + case USB_RECPTYPE_ITF: + break; + + case USB_RECPTYPE_EP: + /* get endpoint address */ + ep = BYTE_LOW(req->wIndex); + + if((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) { + /* set endpoint halt feature */ + if(((uint16_t)USB_FEATURE_EP_HALT == req->wValue) && (!CTL_EP(ep))) { + (void)usbd_ep_stall(udev, ep); + } + + return REQ_SUPP; + } + break; + + default: + break; + } + + return REQ_NOTSUPP; +} + +/*! + \brief handle USB Set_Address request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_setaddress(usb_core_driver *udev, usb_req *req) +{ + if((0U == req->wIndex) && (0U == req->wLength)) { + udev->dev.dev_addr = (uint8_t)(req->wValue) & 0x7FU; + + if(udev->dev.cur_status != (uint8_t)USBD_CONFIGURED) { + usbd_addr_set(udev, udev->dev.dev_addr); + + if(udev->dev.dev_addr) { + udev->dev.cur_status = (uint8_t)USBD_ADDRESSED; + } else { + udev->dev.cur_status = (uint8_t)USBD_DEFAULT; + } + + return REQ_SUPP; + } + } + + return REQ_NOTSUPP; +} + +/*! + \brief handle USB Get_Descriptor request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_getdescriptor(usb_core_driver *udev, usb_req *req) +{ + uint8_t desc_type = 0U; + uint8_t desc_index = 0U; + + usb_reqsta status = REQ_NOTSUPP; + + usb_transc *transc = &udev->dev.transc_in[0]; + + /* get device standard descriptor */ + switch(req->bmRequestType & USB_RECPTYPE_MASK) { + case USB_RECPTYPE_DEV: + desc_type = BYTE_HIGH(req->wValue); + desc_index = BYTE_LOW(req->wValue); + + switch(desc_type) { + case USB_DESCTYPE_DEV: + transc->xfer_buf = std_desc_get[desc_type - 1U](udev, desc_index, (uint16_t *) & (transc->remain_len)); + + if(64U == req->wLength) { + transc->remain_len = 8U; + } + break; + + case USB_DESCTYPE_CONFIG: + transc->xfer_buf = std_desc_get[desc_type - 1U](udev, desc_index, (uint16_t *) & (transc->remain_len)); + break; + + case USB_DESCTYPE_STR: + if(desc_index < (uint8_t)STR_IDX_MAX) { + transc->xfer_buf = std_desc_get[desc_type - 1U](udev, desc_index, (uint16_t *) & (transc->remain_len)); + } + break; + + case USB_DESCTYPE_ITF: + case USB_DESCTYPE_EP: + break; + +#ifdef USE_USB_HS + + case USB_DESCTYPE_DEV_QUALIFIER: + transc->xfer_buf = std_desc_get[desc_type - 3U](udev, desc_index, (uint16_t *) & (transc->remain_len)); + break; + + case USB_DESCTYPE_OTHER_SPD_CONFIG: + transc->xfer_buf = std_desc_get[desc_type - 3U](udev, desc_index, (uint16_t *) & (transc->remain_len)); + break; +#endif + + case USB_DESCTYPE_ITF_POWER: + break; + + case USB_DESCTYPE_BOS: + transc->xfer_buf = _usb_bos_desc_get(udev, desc_index, (uint16_t *) & (transc->remain_len)); + break; + + default: + break; + } + break; + + case USB_RECPTYPE_ITF: + /* get device class special descriptor */ + status = (usb_reqsta)(udev->dev.class_core->req_proc(udev, req)); + break; + + case USB_RECPTYPE_EP: + break; + + default: + break; + } + + if((0U != transc->remain_len) && (0U != req->wLength)) { + if(transc->remain_len < req->wLength) { + if((transc->remain_len >= transc->max_len) && (0U == (transc->remain_len % transc->max_len))) { + udev->dev.control.ctl_zlp = 1U; + } + } else { + transc->remain_len = req->wLength; + } + + status = REQ_SUPP; + } + + return status; +} + +/*! + \brief handle USB Set_Descriptor request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_setdescriptor(usb_core_driver *udev, usb_req *req) +{ + (void)udev; + (void)req; + + /* no handle... */ + return REQ_SUPP; +} + +/*! + \brief handle USB Get_Configuration request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_getconfiguration(usb_core_driver *udev, usb_req *req) +{ + (void)req; + + usb_reqsta req_status = REQ_NOTSUPP; + usb_transc *transc = &udev->dev.transc_in[0]; + + switch(udev->dev.cur_status) { + case USBD_ADDRESSED: + if(USB_DEFAULT_CONFIG == udev->dev.config) { + req_status = REQ_SUPP; + } + break; + + case USBD_CONFIGURED: + if(udev->dev.config != USB_DEFAULT_CONFIG) { + req_status = REQ_SUPP; + } + break; + + default: + break; + } + + if(REQ_SUPP == req_status) { + transc->xfer_buf = &(udev->dev.config); + transc->remain_len = 1U; + } + + return req_status; +} + +/*! + \brief handle USB Set_Configuration request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_setconfiguration(usb_core_driver *udev, usb_req *req) +{ + static uint8_t config; + usb_reqsta status = REQ_NOTSUPP; + + config = (uint8_t)(req->wValue); + + if(config <= USBD_CFG_MAX_NUM) { + switch(udev->dev.cur_status) { + case USBD_ADDRESSED: + if(config) { + (void)udev->dev.class_core->init(udev, config); + + udev->dev.config = config; + udev->dev.cur_status = (uint8_t)USBD_CONFIGURED; + } + + status = REQ_SUPP; + break; + + case USBD_CONFIGURED: + if(USB_DEFAULT_CONFIG == config) { + (void)udev->dev.class_core->deinit(udev, config); + + udev->dev.config = config; + udev->dev.cur_status = (uint8_t)USBD_ADDRESSED; + } else if(config != udev->dev.config) { + /* clear old configuration */ + (void)udev->dev.class_core->deinit(udev, config); + + /* set new configuration */ + udev->dev.config = config; + + (void)udev->dev.class_core->init(udev, config); + } else { + /* no operation */ + } + + status = REQ_SUPP; + break; + + case USBD_DEFAULT: + break; + + default: + break; + } + } + + return status; +} + +/*! + \brief handle USB Get_Interface request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_getinterface(usb_core_driver *udev, usb_req *req) +{ + switch(udev->dev.cur_status) { + case USBD_DEFAULT: + break; + + case USBD_ADDRESSED: + break; + + case USBD_CONFIGURED: + if(BYTE_LOW(req->wIndex) <= USBD_ITF_MAX_NUM) { + usb_transc *transc = &udev->dev.transc_in[0]; + + transc->xfer_buf = &(udev->dev.class_core->alter_set); + transc->remain_len = 1U; + + return REQ_SUPP; + } + break; + + default: + break; + } + + return REQ_NOTSUPP; +} + +/*! + \brief handle USB Set_Interface request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_setinterface(usb_core_driver *udev, usb_req *req) +{ + switch(udev->dev.cur_status) { + case USBD_DEFAULT: + break; + + case USBD_ADDRESSED: + break; + + case USBD_CONFIGURED: + if(BYTE_LOW(req->wIndex) <= USBD_ITF_MAX_NUM) { + if(NULL != udev->dev.class_core->set_intf) { + (void)udev->dev.class_core->set_intf(udev, req); + } + + return REQ_SUPP; + } + break; + + default: + break; + } + + return REQ_NOTSUPP; +} + +/*! + \brief handle USB SynchFrame request + \param[in] udev: pointer to USB device instance + \param[in] req: pointer to USB device request + \param[out] none + \retval USB device request status +*/ +static usb_reqsta _usb_std_synchframe(usb_core_driver *udev, usb_req *req) +{ + (void)udev; + (void)req; + + /* no handle */ + return REQ_SUPP; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_transc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_transc.c new file mode 100644 index 0000000000..c113e7c20e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/device/core/Source/usbd_transc.c @@ -0,0 +1,270 @@ +/*! + \file usbd_transc.c + \brief USB transaction core functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_enum.h" +#include "usbd_transc.h" + +/*! + \brief USB send data in the control transaction + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation cur_status +*/ +usbd_status usbd_ctl_send(usb_core_driver *udev) +{ + usb_transc *transc = &udev->dev.transc_in[0]; + + (void)usbd_ep_send(udev, 0U, transc->xfer_buf, transc->remain_len); + + if(transc->remain_len > transc->max_len) { + udev->dev.control.ctl_state = (uint8_t)USB_CTL_DATA_IN; + } else { + udev->dev.control.ctl_state = (uint8_t)USB_CTL_LAST_DATA_IN; + } + + return USBD_OK; +} + +/*! + \brief USB receive data in control transaction + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation cur_status +*/ +usbd_status usbd_ctl_recev(usb_core_driver *udev) +{ + usb_transc *transc = &udev->dev.transc_out[0]; + + (void)usbd_ep_recev(udev, 0U, transc->xfer_buf, transc->remain_len); + + if(transc->remain_len > transc->max_len) { + udev->dev.control.ctl_state = (uint8_t)USB_CTL_DATA_OUT; + } else { + udev->dev.control.ctl_state = (uint8_t)USB_CTL_LAST_DATA_OUT; + } + + return USBD_OK; +} + +/*! + \brief USB send control transaction status + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation cur_status +*/ +usbd_status usbd_ctl_status_send(usb_core_driver *udev) +{ + udev->dev.control.ctl_state = (uint8_t)USB_CTL_STATUS_IN; + + (void)usbd_ep_send(udev, 0U, NULL, 0U); + + usb_ctlep_startout(udev); + + return USBD_OK; +} + +/*! + \brief USB control receive status + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation cur_status +*/ +usbd_status usbd_ctl_status_recev(usb_core_driver *udev) +{ + udev->dev.control.ctl_state = (uint8_t)USB_CTL_STATUS_OUT; + + (void)usbd_ep_recev(udev, 0U, NULL, 0U); + + usb_ctlep_startout(udev); + + return USBD_OK; +} + +/*! + \brief USB setup stage processing + \param[in] udev: pointer to USB device instance + \param[out] none + \retval USB device operation cur_status +*/ +uint8_t usbd_setup_transc(usb_core_driver *udev) +{ + usb_reqsta reqstat = REQ_NOTSUPP; + + usb_req req = udev->dev.control.req; + + switch(req.bmRequestType & USB_REQTYPE_MASK) { + /* standard device request */ + case USB_REQTYPE_STRD: + reqstat = usbd_standard_request(udev, &req); + break; + + /* device class request */ + case USB_REQTYPE_CLASS: + reqstat = usbd_class_request(udev, &req); + break; + + /* vendor defined request */ + case USB_REQTYPE_VENDOR: + reqstat = usbd_vendor_request(udev, &req); + break; + + default: + break; + } + + if(REQ_SUPP == reqstat) { + if(0U == req.wLength) { + (void)usbd_ctl_status_send(udev); + } else { + if(req.bmRequestType & 0x80U) { + (void)usbd_ctl_send(udev); + } else { + (void)usbd_ctl_recev(udev); + } + } + } else { + if(req.bmRequestType & 0x80U) { + usbd_ep_stall(udev, 0x80U); + usb_ctlep_startout(udev); + } else { + usbd_ep_stall(udev, 0x00U); + usb_ctlep_startout(udev); + } + } + + return (uint8_t)USBD_OK; +} + +/*! + \brief data out stage processing + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier(0..7) + \param[out] none + \retval USB device operation cur_status +*/ +uint8_t usbd_out_transc(usb_core_driver *udev, uint8_t ep_num) +{ + if(0U == ep_num) { + usb_transc *transc = &udev->dev.transc_out[0]; + + switch(udev->dev.control.ctl_state) { + case USB_CTL_DATA_OUT: + /* update transfer length */ + transc->remain_len -= transc->max_len; + + if((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + transc->xfer_buf += transc->max_len; + } + + (void)usbd_ctl_recev(udev); + break; + + case USB_CTL_LAST_DATA_OUT: + if(udev->dev.cur_status == (uint8_t)USBD_CONFIGURED) { + if(udev->dev.class_core->ctlx_out != NULL) { + (void)udev->dev.class_core->ctlx_out(udev); + } + } + + transc->remain_len = 0U; + + (void)usbd_ctl_status_send(udev); + break; + + default: + break; + } + } else if((udev->dev.class_core->data_out != NULL) && (udev->dev.cur_status == (uint8_t)USBD_CONFIGURED)) { + (void)udev->dev.class_core->data_out(udev, ep_num); + } else { + /* no operation */ + } + + return (uint8_t)USBD_OK; +} + +/*! + \brief data in stage processing + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier(0..7) + \param[out] none + \retval USB device operation cur_status +*/ +uint8_t usbd_in_transc(usb_core_driver *udev, uint8_t ep_num) +{ + if(0U == ep_num) { + usb_transc *transc = &udev->dev.transc_in[0]; + + switch(udev->dev.control.ctl_state) { + case USB_CTL_DATA_IN: + /* update transfer length */ + transc->remain_len -= transc->max_len; + + if((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + transc->xfer_buf += transc->max_len; + } + + (void)usbd_ctl_send(udev); + break; + + case USB_CTL_LAST_DATA_IN: + /* last packet is MPS multiple, so send ZLP packet */ + if(udev->dev.control.ctl_zlp) { + (void)usbd_ep_send(udev, 0U, NULL, 0U); + + udev->dev.control.ctl_zlp = 0U; + } else { + if(udev->dev.cur_status == (uint8_t)USBD_CONFIGURED) { + if(udev->dev.class_core->ctlx_in != NULL) { + (void)udev->dev.class_core->ctlx_in(udev); + } + } + + transc->remain_len = 0U; + + (void)usbd_ctl_status_recev(udev); + } + break; + + default: + break; + } + } else { + if(((uint8_t)USBD_CONFIGURED == udev->dev.cur_status) && (NULL != udev->dev.class_core->data_in)) { + (void)udev->dev.class_core->data_in(udev, ep_num); + } + } + + return (uint8_t)USBD_OK; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_core.h new file mode 100644 index 0000000000..9c4a7c07b9 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_core.h @@ -0,0 +1,355 @@ +/*! + \file drv_usb_core.h + \brief USB core low level driver header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DRV_USB_CORE_H +#define __DRV_USB_CORE_H + +#include "drv_usb_regs.h" +#include "usb_ch9_std.h" + +#define USB_FS_EP0_MAX_LEN 64U /*!< maximum packet size of endpoint 0 */ +#define HC_MAX_PACKET_COUNT 140U /*!< maximum packet count */ + +#define EP_ID(x) ((uint8_t)((x) & 0x7FU)) /*!< endpoint number */ +#define EP_DIR(x) ((uint8_t)((x) >> 7)) /*!< endpoint direction */ + +enum _usb_eptype { + USB_EPTYPE_CTRL = 0U, /*!< control endpoint type */ + USB_EPTYPE_ISOC = 1U, /*!< isochronous endpoint type */ + USB_EPTYPE_BULK = 2U, /*!< bulk endpoint type */ + USB_EPTYPE_INTR = 3U, /*!< interrupt endpoint type */ + USB_EPTYPE_MASK = 3U /*!< endpoint type mask */ +}; + +typedef enum +{ + USB_OTG_OK = 0U, /*!< USB OTG status OK*/ + USB_OTG_FAIL /*!< USB OTG status fail*/ +} usb_otg_status; + +typedef enum +{ + USB_OK = 0U, /*!< USB status OK*/ + USB_FAIL /*!< USB status fail*/ +} usb_status; + +typedef enum +{ + USB_USE_FIFO, /*!< USB use FIFO transfer mode */ + USB_USE_DMA /*!< USB use DMA transfer mode */ +} usb_transfer_mode; + +typedef struct +{ + uint8_t core_enum; /*!< USB core type */ + uint8_t core_speed; /*!< USB core speed */ + uint8_t num_pipe; /*!< USB host channel numbers */ + uint8_t num_ep; /*!< USB device endpoint numbers */ + uint8_t transfer_mode; /*!< USB transfer mode */ + uint8_t phy_itf; /*!< USB core PHY interface */ + uint8_t sof_enable; /*!< USB SOF output */ + uint8_t low_power; /*!< USB low power */ + uint8_t lpm_enable; /*!< USB link power mode(LPM) */ + uint8_t vbus_sensing_enable; /*!< USB VBUS sensing feature */ + uint8_t use_dedicated_ep1; /*!< USB dedicated endpoint1 interrupt */ + uint8_t use_external_vbus; /*!< enable or disable the use of the external VBUS */ + uint32_t base_reg; /*!< base register address */ +} usb_core_basic; + +enum usb_ctl_status { + USB_CTL_IDLE = 0U, /*!< USB control transfer idle state */ + USB_CTL_DATA_IN, /*!< USB control transfer data in state */ + USB_CTL_LAST_DATA_IN, /*!< USB control transfer last data in state */ + USB_CTL_DATA_OUT, /*!< USB control transfer data out state */ + USB_CTL_LAST_DATA_OUT, /*!< USB control transfer last data out state */ + USB_CTL_STATUS_IN, /*!< USB control transfer status in state*/ + USB_CTL_STATUS_OUT /*!< USB control transfer status out state */ +}; + +typedef enum { + LPM_L0 = 0U, /*!< on */ + LPM_L1, /*!< LPM L1 sleep */ + LPM_L2, /*!< suspend */ + LPM_L3, /*!< off */ +}usb_lpm_state; + +typedef enum { + LPM_L0_ACTIVE = 0U, /*!< on */ + LPM_L1_ACTIVE, /*!< LPM L1 sleep */ +}usb_lpm_type; + +#ifdef USE_DEVICE_MODE + +/* USB descriptor */ +typedef struct _usb_desc { + uint8_t *dev_desc; /*!< device descriptor */ + uint8_t *config_desc; /*!< config descriptor */ + uint8_t *bos_desc; /*!< BOS descriptor */ + +#ifdef USE_USB_HS + uint8_t *other_speed_config_desc; /*!< other speed configuration descriptor */ + uint8_t *qualifier_desc; /*!< qualifier descriptor */ +#endif + + void* const *strings; /*!< string descriptor */ +} usb_desc; + +/* USB power management */ +typedef struct _usb_pm { + uint8_t power_mode; /*!< power mode */ + uint8_t power_low; /*!< power low */ + uint8_t dev_remote_wakeup; /*!< remote wakeup */ + uint8_t remote_wakeup_on; /*!< remote wakeup on */ + usb_lpm_state lpm_state; /*!< LPM state */ + uint32_t BESL; /*!< BESL value */ +} usb_pm; + +/* USB control information */ +typedef struct _usb_control { + usb_req req; /*!< USB standard device request */ + + uint8_t ctl_state; /*!< USB control transfer state */ + uint8_t ctl_zlp; /*!< zero length package */ +} usb_control; + +typedef struct +{ + struct { + uint8_t num: 4; /*!< the endpoint number.it can be from 0 to 6 */ + uint8_t pad: 3; /*!< padding between number and direction */ + uint8_t dir: 1; /*!< the endpoint direction */ + } ep_addr; + + uint8_t ep_type; /*!< USB endpoint type */ + uint8_t ep_stall; /*!< USB endpoint stall status */ + + uint8_t frame_num; /*!< number of frame */ + uint16_t max_len; /*!< Maximum packet length */ + + /* transaction level variables */ + uint8_t *xfer_buf; /*!< transmit buffer */ + uint32_t xfer_len; /*!< transmit buffer length */ + uint32_t xfer_count; /*!< transmit buffer count */ + + uint32_t remain_len; /*!< remain packet length */ + + uint32_t dma_addr; /*!< DMA address */ +} usb_transc; + +typedef struct _usb_core_driver usb_dev; + +typedef struct _usb_class_core +{ + uint8_t alter_set; /*!< alternative set */ + uint8_t command; /*!< device class request command */ + + uint8_t (*init) (usb_dev *udev, uint8_t config_index); /*!< initialize handler */ + uint8_t (*deinit) (usb_dev *udev, uint8_t config_index); /*!< de-initialize handler */ + uint8_t (*req_proc) (usb_dev *udev, usb_req *req); /*!< device request handler */ + uint8_t (*set_intf) (usb_dev *udev, usb_req *req); /*!< device set interface callback */ + uint8_t (*ctlx_in) (usb_dev *udev); /*!< device contrl in callback */ + uint8_t (*ctlx_out) (usb_dev *udev); /*!< device contrl out callback */ + uint8_t (*data_in) (usb_dev *udev, uint8_t ep_num); /*!< device data in handler */ + uint8_t (*data_out) (usb_dev *udev, uint8_t ep_num); /*!< device data out handler */ + uint8_t (*SOF) (usb_dev *udev); /*!< Start of frame handler */ + uint8_t (*incomplete_isoc_in) (usb_dev *udev); /*!< Incomplete synchronization IN transfer handler */ + uint8_t (*incomplete_isoc_out) (usb_dev *udev); /*!< Incomplete synchronization OUT transfer handler */ +} usb_class_core; + +typedef struct _usb_perp_dev +{ + uint8_t config; /*!< configuration */ + uint8_t dev_addr; /*!< device address */ + + __IO uint8_t cur_status; /*!< current status */ + __IO uint8_t backup_status; /*!< backup status */ + + usb_transc transc_in[USBHS_MAX_TX_FIFOS]; /*!< endpoint IN transaction */ + usb_transc transc_out[USBHS_MAX_TX_FIFOS]; /*!< endpoint OUT transaction */ + + usb_pm pm; /*!< power management */ + usb_control control; /*!< USB control information */ + usb_desc *desc; /*!< USB descriptors pointer */ + usb_class_core *class_core; /*!< class driver */ + void *class_data[4]; /*!< class data pointer */ + void *user_data; /*!< user data pointer */ + void *pdata; /*!< reserved data pointer */ +} usb_perp_dev; + +#endif /* USE_DEVICE_MODE */ + +#ifdef USE_HOST_MODE + +typedef enum _usb_pipe_status +{ + PIPE_IDLE = 0U, + PIPE_XF, + PIPE_HALTED, + PIPE_NAK, + PIPE_NYET, + PIPE_STALL, + PIPE_TRACERR, + PIPE_BBERR, + PIPE_REQOVR, + PIPE_DTGERR, +} usb_pipe_staus; + +typedef enum _usb_pipe_mode +{ + PIPE_PERIOD = 0U, + PIPE_NON_PERIOD = 1U +} usb_pipe_mode; + +typedef enum _usb_urb_state +{ + URB_IDLE = 0U, + URB_DONE, + URB_NOTREADY, + URB_ERROR, + URB_STALL, + URB_PING +} usb_urb_state; + +typedef struct _usb_pipe +{ + uint8_t in_used; + uint8_t dev_addr; + uint32_t dev_speed; + + struct { + uint8_t num; + uint8_t dir; + uint8_t type; + uint16_t mps; + } ep; + + __IO uint8_t supp_ping; + __IO uint8_t do_ping; + __IO uint32_t DPID; + + uint8_t *xfer_buf; + uint32_t xfer_len; + uint32_t xfer_count; + + uint8_t data_toggle_in; + uint8_t data_toggle_out; + + __IO uint32_t err_count; + __IO usb_pipe_staus pp_status; + __IO usb_urb_state urb_state; +} usb_pipe; + +typedef struct _usb_host_drv +{ + __IO uint32_t connect_status; + __IO uint32_t port_enabled; + __IO uint32_t backup_xfercount[USBHS_MAX_TX_FIFOS]; + + usb_pipe pipe[USBHS_MAX_TX_FIFOS]; + void *data; +} usb_host_drv; + +#endif /* USE_HOST_MODE */ + +typedef struct _usb_core_driver +{ + usb_core_basic bp; /*!< USB basic parameters */ + usb_core_regs regs; /*!< USB registers */ + +#ifdef USE_DEVICE_MODE + usb_perp_dev dev; /*!< USB peripheral device */ +#endif /* USE_DEVICE_MODE */ + +#ifdef USE_HOST_MODE + usb_host_drv host; /*!< USB peripheral host */ +#endif /* USE_HOST_MODE */ +} usb_core_driver; + +typedef enum { + BCD_NONE = 0, + BCD_SDP, + BCD_DCP, + BCD_CDP, + BCD_PS2, + BCD_ERROR +} bcd_type; + +/* static inline function definitions */ + +/*! + \brief get the global interrupts + \param[in] usb_regs: pointer to USB core registers + \param[out] none + \retval interrupt status +*/ +__STATIC_INLINE uint32_t usb_coreintr_get(usb_core_regs *usb_regs) +{ + uint32_t reg_data = usb_regs->gr->GINTEN; + + reg_data &= usb_regs->gr->GINTF; + + return reg_data; +} + +/*! + \brief set USB RX FIFO size + \param[in] usb_regs: pointer to USB core registers + \param[in] size: assigned FIFO size + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_set_rxfifo(usb_core_regs *usb_regs, uint16_t size) +{ + usb_regs->gr->GRFLEN = size; +} + +/* function declarations */ +/* configures USB parameters */ +void usb_para_init(usb_core_driver *core, uint32_t usb_periph, uint32_t usb_speed); +/* configure core capabilities */ +usb_status usb_basic_init (usb_core_basic *usb_basic, usb_core_regs *usb_regs); +/*initializes the USB controller registers and prepares the core device mode or host mode operation*/ +usb_status usb_core_init (usb_core_basic usb_basic, usb_core_regs *usb_regs); +/* write a packet into the TX FIFO associated with the endpoint */ +usb_status usb_txfifo_write (usb_core_regs *usb_regs, uint8_t *src_buf, uint8_t fifo_num, uint16_t byte_count); +/* read a packet from the RX FIFO associated with the endpoint */ +void *usb_rxfifo_read (usb_core_regs *usb_regs, uint8_t *dest_buf, uint16_t byte_count); +/* flush a TX FIFO or all TX FIFOs */ +usb_status usb_txfifo_flush (usb_core_regs *usb_regs, uint8_t fifo_num); +/* flush the entire RX FIFO */ +usb_status usb_rxfifo_flush (usb_core_regs *usb_regs); +/* set endpoint or channel TX FIFO size */ +void usb_set_txfifo(usb_core_regs *usb_regs, uint8_t fifo, uint16_t size); + +#endif /* __DRV_USB_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_dev.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_dev.h new file mode 100644 index 0000000000..d8635ec9c7 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_dev.h @@ -0,0 +1,211 @@ +/*! + \file drv_usb_dev.h + \brief USB device low level driver header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DRV_USB_DEV_H +#define __DRV_USB_DEV_H + +#include "usbd_conf.h" +#include "drv_usb_core.h" + +#define EP_IN(x) ((uint8_t)(0x80U | (x))) /*!< device IN endpoint */ +#define EP_OUT(x) ((uint8_t)(x)) /*!< device OUT endpoint */ + +/* static inline function definitions */ + +/*! + \brief configure the USB device to be disconnected + \param[in] udev: pointer to USB device + \param[out] none + \retval operation status +*/ +__STATIC_INLINE void usb_dev_disconnect (usb_core_driver *udev) +{ + udev->regs.dr->DCTL |= DCTL_SD; +} + +/*! + \brief configure the USB device to be connected + \param[in] udev: pointer to USB device + \param[out] none + \retval operation status +*/ +__STATIC_INLINE void usb_dev_connect (usb_core_driver *udev) +{ + udev->regs.dr->DCTL &= ~DCTL_SD; +} + +/*! + \brief set the USB device address + \param[in] udev: pointer to USB device + \param[in] dev_addr: device address for setting + \param[out] none + \retval operation status +*/ +__STATIC_INLINE void usb_devaddr_set (usb_core_driver *udev, uint8_t dev_addr) +{ + udev->regs.dr->DCFG &= ~DCFG_DAR; + udev->regs.dr->DCFG |= (uint32_t)dev_addr << 4U; +} + +/*! + \brief read device all OUT endpoint interrupt register + \param[in] udev: pointer to USB device + \param[out] none + \retval interrupt status +*/ +__STATIC_INLINE uint32_t usb_oepintnum_read (usb_core_driver *udev) +{ + uint32_t value = udev->regs.dr->DAEPINT; + + value &= udev->regs.dr->DAEPINTEN; + + return (value & DAEPINT_OEPITB) >> 16U; +} + +/*! + \brief read device OUT endpoint interrupt flag register + \param[in] udev: pointer to USB device + \param[in] ep_num: endpoint number + \param[out] none + \retval interrupt status +*/ +__STATIC_INLINE uint32_t usb_oepintr_read (usb_core_driver *udev, uint8_t ep_num) +{ + uint32_t value = udev->regs.er_out[ep_num]->DOEPINTF; + + value &= udev->regs.dr->DOEPINTEN; + + return value; +} + +/*! + \brief read device all IN endpoint interrupt register + \param[in] udev: pointer to USB device + \param[out] none + \retval interrupt status +*/ +__STATIC_INLINE uint32_t usb_iepintnum_read (usb_core_driver *udev) +{ + uint32_t value = udev->regs.dr->DAEPINT; + + value &= udev->regs.dr->DAEPINTEN; + + return value & DAEPINT_IEPITB; +} + +/*! + \brief set remote wakeup signaling + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_rwkup_set (usb_core_driver *udev) +{ + if (udev->dev.pm.dev_remote_wakeup) { + /* enable remote wakeup signaling */ + udev->regs.dr->DCTL |= DCTL_RWKUP; + } +} + +/*! + \brief reset remote wakeup signaling + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_rwkup_reset (usb_core_driver *udev) +{ + if (udev->dev.pm.dev_remote_wakeup) { + /* disable remote wakeup signaling */ + udev->regs.dr->DCTL &= ~DCTL_RWKUP; + } +} + +/*! + \brief enable USB BCD function + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_bcd_enable (usb_core_driver *udev) +{ + udev->regs.gr->GCCFG |= GCCFG_BCDEN; +} + +/*! + \brief disable USB BCD function + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_bcd_disable (usb_core_driver *udev) +{ + udev->regs.gr->GCCFG &= ~GCCFG_BCDEN; +} + +/* function declarations */ +/* initialize USB core registers for device mode */ +usb_status usb_devcore_init (usb_core_driver *udev); +/* enable the USB device mode interrupts */ +usb_status usb_devint_enable (usb_core_driver *udev); +/* active the USB endpoint 0 transaction */ +usb_status usb_transc0_active (usb_core_driver *udev, usb_transc *transc); +/* active the USB transaction */ +usb_status usb_transc_active (usb_core_driver *udev, usb_transc *transc); +/* deactivate the USB transaction */ +usb_status usb_transc_deactivate (usb_core_driver *udev, usb_transc *transc); +/* configure USB transaction to start IN transfer */ +usb_status usb_transc_inxfer (usb_core_driver *udev, usb_transc *transc); +/* configure USB transaction to start OUT transfer */ +usb_status usb_transc_outxfer (usb_core_driver *udev, usb_transc *transc); +/* set the USB transaction STALL status */ +usb_status usb_transc_stall (usb_core_driver *udev, usb_transc *transc); +/* clear the USB transaction STALL status */ +usb_status usb_transc_clrstall (usb_core_driver *udev, usb_transc *transc); +/* read device IN endpoint interrupt flag register */ +uint32_t usb_iepintr_read (usb_core_driver *udev, uint8_t ep_num); +/* configures OUT endpoint 0 to receive SETUP packets */ +void usb_ctlep_startout (usb_core_driver *udev); +/* active remote wakeup signaling */ +void usb_rwkup_active (usb_core_driver *udev); +/* active USB core clock */ +void usb_clock_active (usb_core_driver *udev); +/* USB device suspend */ +void usb_dev_suspend (usb_core_driver *udev); +/* stop the device and clean up FIFOs */ +void usb_dev_stop (usb_core_driver *udev); +/* usb battery charging detect operation */ +bcd_type usbd_bcd_detect (usb_core_driver *udev); + +#endif /* __DRV_USB_DEV_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_host.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_host.h new file mode 100644 index 0000000000..e5293564aa --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_host.h @@ -0,0 +1,117 @@ +/*! + \file drv_usb_host.h + \brief USB host mode low level driver header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DRV_USB_HOST_H +#define __DRV_USB_HOST_H + +#include "drv_usb_regs.h" +#include "usb_ch9_std.h" +#include "drv_usb_core.h" + +/*! + \brief get USB even frame + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +__STATIC_INLINE uint8_t usb_frame_even (usb_core_driver *udev) +{ + return (uint8_t)!(udev->regs.hr->HFINFR & 0x01U); +} + +/*! + \brief configure USB clock of PHY + \param[in] udev: pointer to USB device + \param[in] clock: PHY clock + \param[out] none + \retval none +*/ +__STATIC_INLINE void usb_phyclock_config (usb_core_driver *udev, uint8_t clock) +{ +// udev->regs.hr->HCTL &= ~HCTL_CLKSEL; +// udev->regs.hr->HCTL |= clock; +} + +/*! + \brief read USB port + \param[in] udev: pointer to USB device + \param[out] none + \retval port status +*/ +__STATIC_INLINE uint32_t usb_port_read (usb_core_driver *udev) +{ + return *udev->regs.HPCS & ~(HPCS_PE | HPCS_PCD | HPCS_PEDC); +} + +/*! + \brief get USB current speed + \param[in] udev: pointer to USB device + \param[out] none + \retval USB current speed +*/ +__STATIC_INLINE uint32_t usb_curspeed_get (usb_core_driver *udev) +{ + return *udev->regs.HPCS & HPCS_PS; +} + +/*! + \brief get USB current frame + \param[in] udev: pointer to USB device + \param[out] none + \retval USB current frame +*/ +__STATIC_INLINE uint32_t usb_curframe_get (usb_core_driver *udev) +{ + return (udev->regs.hr->HFINFR & 0xFFFFU); +} + +/* function declarations */ +/* initializes USB core for host mode */ +usb_status usb_host_init (usb_core_driver *udev); +/* control the VBUS to power */ +void usb_portvbus_switch (usb_core_driver *udev, uint8_t state); +/* reset host port */ +uint32_t usb_port_reset (usb_core_driver *udev); +/* initialize host pipe */ +usb_status usb_pipe_init (usb_core_driver *udev, uint8_t pipe_num); +/* prepare host pipe for transferring packets */ +usb_status usb_pipe_xfer (usb_core_driver *udev, uint8_t pipe_num); +/* halt host pipe */ +usb_status usb_pipe_halt (usb_core_driver *udev, uint8_t pipe_num); +/* configure host pipe to do ping operation */ +usb_status usb_pipe_ping (usb_core_driver *udev, uint8_t pipe_num); +/* stop the USB host and clean up FIFO */ +void usb_host_stop (usb_core_driver *udev); + +#endif /* __DRV_USB_HOST_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_hw.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_hw.h new file mode 100644 index 0000000000..9e6f73f3e4 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_hw.h @@ -0,0 +1,65 @@ +/*! + \file drv_usb_hw.h + \brief USB hardware configuration header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DRV_USB_HW_H +#define __DRV_USB_HW_H + +#include "drv_usb_core.h" + +/* function declarations */ +/* configure USB clock */ +void usb_rcu_config (void); +/* configure USB data line GPIO */ +void usb_gpio_config (void); +/* configure USB interrupt */ +void usb_intr_config (void); +/* initializes delay unit using Timer2 */ +void usb_timer_init (void); +/* delay in micro seconds */ +void usb_udelay (const uint32_t usec); +/* delay in milli seconds */ +void usb_mdelay (const uint32_t msec); + +void pllusb_rcu_config(uint32_t usb_periph); + +#ifdef USE_HOST_MODE +/* configure systick */ +void systick_config(void); +/* configure USB VBus */ +void usb_vbus_config (void); +/* drive USB VBus */ +void usb_vbus_drive (uint8_t State); +#endif /* USE_HOST_MODE */ + +#endif /* __DRV_USB_HW_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_regs.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_regs.h new file mode 100644 index 0000000000..7627ab6d22 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usb_regs.h @@ -0,0 +1,748 @@ +/*! + \file drv_usb_regs.h + \brief USB cell registers definition and handle macros + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DRV_USB_REGS_H +#define __DRV_USB_REGS_H + +#include "usb_conf.h" + +#define USBHS0 USBHS_BASE +#define USBHS1 (USBHS_BASE+0x00040000U) + +#define USBHS0_REG_BASE USBHS0 /*!< base address of USBHS0 registers */ +#define USBHS1_REG_BASE USBHS1 /*!< base address of USBHS1 registers */ + +#define USBHS_MAX_TX_FIFOS 16U /*!< FIFO number */ + +#define USBHS_MAX_PACKET_SIZE 512U /*!< USBHS max packet size */ +#define USBHS_MAX_CHANNEL_COUNT 16U /*!< USBHS host channel count */ +#define USBHS_MAX_EP_COUNT 8U /*!< USBHS device endpoint count */ +#define USBHS_MAX_FIFO_WORDLEN 1280U /*!< USBHS max fifo size in words */ + +#define USB_DATA_FIFO_OFFSET 0x1000U /*!< USB data fifo offset */ +#define USB_DATA_FIFO_SIZE 0x1000U /*!< USB data fifo size */ + +typedef enum +{ + USB_EMBEDDED_PHY_FS = 0U, /*!< USB embedded FS PHY */ + USB_EMBEDDED_PHY_HS, /*!< USB embedded HS PHY */ + USB_ULPI_PHY_EXTERNAL /*!< USB external ULPI PHY */ +} usb_phy_enum; + +enum usb_reg_offset { + USB_REG_OFFSET_CORE = 0x0000U, /*!< global OTG control and status register */ + USB_REG_OFFSET_DEV = 0x0800U, /*!< device mode control and status registers */ + USB_REG_OFFSET_EP = 0x0020U, + USB_REG_OFFSET_EP_IN = 0x0900U, /*!< device IN endpoint 0 control register */ + USB_REG_OFFSET_EP_OUT = 0x0B00U, /*!< device OUT endpoint 0 control register */ + USB_REG_OFFSET_HOST = 0x0400U, /*!< host control register */ + USB_REG_OFFSET_CH = 0x0020U, + USB_REG_OFFSET_PORT = 0x0440U, /*!< host port control and status register */ + USB_REG_OFFSET_CH_INOUT = 0x0500U, /*!< host channel-x control registers */ + USB_REG_OFFSET_PWRCLKCTL = 0x0E00U, /*!< power and clock register */ +}; + +typedef struct +{ + __IO uint32_t GOTGCS; /*!< USB global OTG control and status register 000h */ + __IO uint32_t GOTGINTF; /*!< USB global OTG interrupt flag register 004h */ + __IO uint32_t GAHBCS; /*!< USB global AHB control and status register 008h */ + __IO uint32_t GUSBCS; /*!< USB global USB control and status register 00Ch */ + __IO uint32_t GRSTCTL; /*!< USB global reset control register 010h */ + __IO uint32_t GINTF; /*!< USB global interrupt flag register 014h */ + __IO uint32_t GINTEN; /*!< USB global interrupt enable register 018h */ + __IO uint32_t GRSTATR; /*!< USB receive status debug read register 01Ch */ + __IO uint32_t GRSTATP; /*!< USB receive status and pop register 020h */ + __IO uint32_t GRFLEN; /*!< USB global receive FIFO length register 024h */ + __IO uint32_t DIEP0TFLEN_HNPTFLEN; /*!< USB device IN endpoint 0/host non-periodic transmit FIFO length register 028h */ + __IO uint32_t HNPTFQSTAT; /*!< USB host non-periodic FIFO/queue status register 02Ch */ + uint32_t Reserved30[2]; /*!< Reserved 030h */ + __IO uint32_t GCCFG; /*!< USB global core configuration register 038h */ + __IO uint32_t CID; /*!< USB core ID register 03Ch */ + uint32_t Reserved40[5]; /*!< Reserved 040h-053h */ + __IO uint32_t GLPMCFG; /*!< LPM configuration register 54h */ + __IO uint32_t PWRD; /*!< power down register 58h */ + uint32_t Reserved5C; /*!< Reserved 5Ch */ + __IO uint32_t ADPCTL; /*!< ADP control and status register 60h */ + uint32_t Reserved64[3]; /*!< Reserved 64h-6Fh */ + __IO uint32_t PHYCTL; /*!< USBHS PHY control register 70h */ + uint32_t Reserved74[35]; /*!< Reserved 74h-FFh */ + __IO uint32_t HPTFLEN; /*!< USB host periodic transmit FIFO length register 100h */ + __IO uint32_t DIEPTFLEN[15]; /*!< USB device IN endpoint transmit FIFO length register 104h */ +} usb_gr; + +typedef struct +{ + __IO uint32_t HCTL; /*!< USB host control register 400h */ + __IO uint32_t HFT; /*!< USB host frame interval register 404h */ + __IO uint32_t HFINFR; /*!< USB host frame information remaining register 408h */ + uint32_t Reserved40C; /*!< Reserved 40Ch */ + __IO uint32_t HPTFQSTAT; /*!< USB host periodic transmit FIFO/queue status register 410h */ + __IO uint32_t HACHINT; /*!< USB host all channels interrupt register 414h */ + __IO uint32_t HACHINTEN; /*!< USB host all channels interrupt enable register 418h */ +} usb_hr; + +typedef struct +{ + __IO uint32_t HCHCTL; /*!< USB host channel control register 500h */ + __IO uint32_t HCHSTCTL; /*!< Reserved 504h */ + __IO uint32_t HCHINTF; /*!< USB host channel interrupt flag register 508h */ + __IO uint32_t HCHINTEN; /*!< USB host channel interrupt enable register 50Ch */ + __IO uint32_t HCHLEN; /*!< USB host channel transfer length register 510h */ + __IO uint32_t HCHDMAADDR; /*!< USB host channel-x DMA address register 514h*/ + uint32_t Reserved[2]; +} usb_pr; + +typedef struct +{ + __IO uint32_t DCFG; /*!< USB device configuration register 800h */ + __IO uint32_t DCTL; /*!< USB device control register 804h */ + __IO uint32_t DSTAT; /*!< USB device status register 808h */ + uint32_t Reserved0C; /*!< Reserved 80Ch */ + __IO uint32_t DIEPINTEN; /*!< USB device IN endpoint common interrupt enable register 810h */ + __IO uint32_t DOEPINTEN; /*!< USB device OUT endpoint common interrupt enable register 814h */ + __IO uint32_t DAEPINT; /*!< USB device all endpoints interrupt register 818h */ + __IO uint32_t DAEPINTEN; /*!< USB device all endpoints interrupt enable register 81Ch */ + uint32_t Reserved20; /*!< Reserved 820h */ + uint32_t Reserved24; /*!< Reserved 824h */ + __IO uint32_t DVBUSDT; /*!< USB device VBUS discharge time register 828h */ + __IO uint32_t DVBUSPT; /*!< USB device VBUS pulsing time register 82Ch */ + uint32_t Reserved30; /*!< Reserved 830h */ + __IO uint32_t DIEPFEINTEN; /*!< USB Device IN endpoint FIFO empty interrupt enable register 834h */ + __IO uint32_t DEP1INT; /*!< USB device endpoint 1 interrupt register 838h */ + __IO uint32_t DEP1INTEN; /*!< USB device endpoint 1 interrupt enable register 83Ch */ + uint32_t Reserved40; /*!< Reserved 840h */ + __IO uint32_t DIEP1INTEN; /*!< USB device IN endpoint-1 interrupt enable register 844h */ + uint32_t Reserved48[15]; /*!< Reserved 848-880h */ + __IO uint32_t DOEP1INTEN; /*!< USB device OUT endpoint-1 interrupt enable register 884h */ +} usb_dr; + +typedef struct +{ + __IO uint32_t DIEPCTL; /*!< USB device IN endpoint control register 900h + (EpNum * 20h) + 00h */ + uint32_t Reserved04; /*!< Reserved 900h + (EpNum * 20h) + 04h */ + __IO uint32_t DIEPINTF; /*!< USB device IN endpoint interrupt flag register 900h + (EpNum * 20h) + 08h */ + uint32_t Reserved0C; /*!< Reserved 900h + (EpNum * 20h) + 0Ch */ + __IO uint32_t DIEPLEN; /*!< USB device IN endpoint transfer length register 900h + (EpNum * 20h) + 10h */ + __IO uint32_t DIEPDMAADDR; /*!< Device IN endpoint-x DMA address register 900h + (EpNum * 20h) + 14h */ + __IO uint32_t DIEPTFSTAT; /*!< USB device IN endpoint transmit FIFO status register 900h + (EpNum * 20h) + 18h */ +} usb_erin; + +typedef struct +{ + __IO uint32_t DOEPCTL; /*!< USB device IN endpoint control register B00h + (EpNum * 20h) + 00h */ + uint32_t Reserved04; /*!< Reserved B00h + (EpNum * 20h) + 04h */ + __IO uint32_t DOEPINTF; /*!< USB device IN endpoint interrupt flag register B00h + (EpNum * 20h) + 08h */ + uint32_t Reserved0C; /*!< Reserved B00h + (EpNum * 20h) + 0Ch */ + __IO uint32_t DOEPLEN; /*!< USB device IN endpoint transfer length register B00h + (EpNum * 20h) + 10h */ + __IO uint32_t DOEPDMAADDR; /*!< Device OUT endpoint-x DMA address register B00h + (EpNum * 20h) + 0Ch */ +} usb_erout; + +typedef struct _usb_regs +{ + usb_gr *gr; /*!< USBHS global registers */ + usb_dr *dr; /*!< device control and status registers */ + usb_hr *hr; /*!< host control and status registers */ + usb_erin *er_in[8]; /*!< USB device IN endpoint register */ + usb_erout *er_out[8]; /*!< USB device OUT endpoint register */ + usb_pr *pr[16]; /*!< USB Host channel-x control register */ + + __IO uint32_t *HPCS; /*!< USB host port control and status register */ + __IO uint32_t *DFIFO[USBHS_MAX_TX_FIFOS]; + __IO uint32_t *PWRCLKCTL; /*!< USB power and clock control register */ +} usb_core_regs; + +/* global OTG control and status register bits definitions */ +#define GOTGCS_OV BIT(20) /*!< select OTG version */ +#define GOTGCS_BSV BIT(19) /*!< B-Session Valid */ +#define GOTGCS_ASV BIT(18) /*!< A-session valid */ +#define GOTGCS_DI BIT(17) /*!< debounce interval */ +#define GOTGCS_IDPS BIT(16) /*!< id pin status */ +#define GOTGCS_EHE BIT(12) /*!< embedded host enable */ +#define GOTGCS_DHNPEN BIT(11) /*!< device HNP enable */ +#define GOTGCS_HHNPEN BIT(10) /*!< host HNP enable */ +#define GOTGCS_HNPREQ BIT(9) /*!< HNP request */ +#define GOTGCS_HNPS BIT(8) /*!< HNP successes */ +#define GOTGCS_BVOV BIT(7) /*!< override value of B-peripheral session valid */ +#define GOTGCS_BVOE BIT(6) /*!< override enable of B-peripheral session valid */ +#define GOTGCS_AVOV BIT(5) /*!< override value of A-peripheral session valid */ +#define GOTGCS_AVOE BIT(4) /*!< override enable of A-peripheral session valid */ +#define GOTGCS_VOV BIT(3) /*!< override value of VBUS valid */ +#define GOTGCS_VOE BIT(2) /*!< override enable of VBUS valid */ +#define GOTGCS_SRPREQ BIT(1) /*!< SRP request */ +#define GOTGCS_SRPS BIT(0) /*!< SRP successes */ + +/* global OTG interrupt flag register bits definitions */ +#define GOTGINTF_IDCHG BIT(20) /*!< ID input change */ +#define GOTGINTF_DF BIT(19) /*!< debounce finish */ +#define GOTGINTF_ADTO BIT(18) /*!< A-device timeout */ +#define GOTGINTF_HNPDET BIT(17) /*!< host negotiation request detected */ +#define GOTGINTF_HNPEND BIT(9) /*!< HNP end */ +#define GOTGINTF_SRPEND BIT(8) /*!< SRP end */ +#define GOTGINTF_SESEND BIT(2) /*!< session end */ + +/* global AHB control and status register bits definitions */ +#define GAHBCS_PTXFTH BIT(8) /*!< periodic Tx FIFO threshold */ +#define GAHBCS_TXFTH BIT(7) /*!< tx FIFO threshold */ +#define GAHBCS_DMAEN BIT(5) /*!< DMA function Enable */ +#define GAHBCS_BURST BITS(1, 4) /*!< the AHB burst type used by DMA */ +#define GAHBCS_GINTEN BIT(0) /*!< global interrupt enable */ + +/* global USB control and status register bits definitions */ +#define GUSBCS_FDM BIT(30) /*!< force device mode */ +#define GUSBCS_FHM BIT(29) /*!< force host mode */ +#define GUSBCS_ULPIEOI BIT(21) /*!< ULPI external over-current indicator */ +#define GUSBCS_ULPIEVD BIT(20) /*!< ULPI external VBUS driver */ +#define GUSBCS_UTT BITS(10, 13) /*!< USB turnaround time */ +#define GUSBCS_HNPCEN BIT(9) /*!< HNP capability enable */ +#define GUSBCS_SRPCEN BIT(8) /*!< SRP capability enable */ +#define GUSBCS_EMBPHY_FS BIT(6) /*!< embedded FS PHY selected */ +#define GUSBCS_EMBPHY_HS BIT(5) /*!< embedded HS PHY selected */ +#define GUSBCS_HS_CUR_FE BIT(4) /*!< HS current software enable */ +#define GUSBCS_TOC BITS(0, 2) /*!< timeout calibration */ + +/* global reset control register bits definitions */ +#define GRSTCTL_DMAIDL BIT(31) /*!< DMA idle state */ +#define GRSTCTL_DMABSY BIT(30) /*!< DMA busy */ +#define GRSTCTL_TXFNUM BITS(6, 10) /*!< tx FIFO number */ +#define GRSTCTL_TXFF BIT(5) /*!< tx FIFO flush */ +#define GRSTCTL_RXFF BIT(4) /*!< rx FIFO flush */ +#define GRSTCTL_HFCRST BIT(2) /*!< host frame counter reset */ +#define GRSTCTL_HCSRST BIT(1) /*!< HCLK soft reset */ +#define GRSTCTL_CSRST BIT(0) /*!< core soft reset */ + +/* global interrupt flag register bits definitions */ +#define GINTF_WKUPIF BIT(31) /*!< wakeup interrupt flag */ +#define GINTF_SESIF BIT(30) /*!< session interrupt flag */ +#define GINTF_DISCIF BIT(29) /*!< disconnect interrupt flag */ +#define GINTF_IDPSC BIT(28) /*!< id pin status change */ +#define GINTF_LPMIF BIT(27) /*!< LPM interrupt flag */ +#define GINTF_PTXFEIF BIT(26) /*!< periodic tx FIFO empty interrupt flag */ +#define GINTF_HCIF BIT(25) /*!< host channels interrupt flag */ +#define GINTF_HPIF BIT(24) /*!< host port interrupt flag */ +#define GINTF_PXNCIF BIT(21) /*!< periodic transfer not complete interrupt flag */ +#define GINTF_ISOONCIF BIT(21) /*!< isochronous OUT transfer not complete interrupt flag */ +#define GINTF_ISOINCIF BIT(20) /*!< isochronous IN transfer not complete interrupt flag */ +#define GINTF_OEPIF BIT(19) /*!< OUT endpoint interrupt flag */ +#define GINTF_IEPIF BIT(18) /*!< IN endpoint interrupt flag */ +#define GINTF_EOPFIF BIT(15) /*!< end of periodic frame interrupt flag */ +#define GINTF_ISOOPDIF BIT(14) /*!< isochronous OUT packet dropped interrupt flag */ +#define GINTF_ENUMFIF BIT(13) /*!< enumeration finished */ +#define GINTF_RST BIT(12) /*!< USB reset */ +#define GINTF_SP BIT(11) /*!< USB suspend */ +#define GINTF_ESP BIT(10) /*!< early suspend */ +#define GINTF_GONAK BIT(7) /*!< global OUT NAK effective */ +#define GINTF_GNPINAK BIT(6) /*!< global IN non-periodic NAK effective */ +#define GINTF_NPTXFEIF BIT(5) /*!< non-periodic tx FIFO empty interrupt flag */ +#define GINTF_RXFNEIF BIT(4) /*!< rx FIFO non-empty interrupt flag */ +#define GINTF_SOF BIT(3) /*!< start of frame */ +#define GINTF_OTGIF BIT(2) /*!< OTG interrupt flag */ +#define GINTF_MFIF BIT(1) /*!< mode fault interrupt flag */ +#define GINTF_COPM BIT(0) /*!< current operation mode */ + +/* global interrupt enable register bits definitions */ +#define GINTEN_WKUPIE BIT(31) /*!< wakeup interrupt enable */ +#define GINTEN_SESIE BIT(30) /*!< session interrupt enable */ +#define GINTEN_DISCIE BIT(29) /*!< disconnect interrupt enable */ +#define GINTEN_IDPSCIE BIT(28) /*!< id pin status change interrupt enable */ +#define GINTEN_LPMIE BIT(27) /*!< LPM interrupt enable */ +#define GINTEN_PTXFEIE BIT(26) /*!< periodic tx FIFO empty interrupt enable */ +#define GINTEN_HCIE BIT(25) /*!< host channels interrupt enable */ +#define GINTEN_HPIE BIT(24) /*!< host port interrupt enable */ +#define GINTEN_IPXIE BIT(21) /*!< periodic transfer not complete interrupt enable */ +#define GINTEN_ISOONCIE BIT(21) /*!< isochronous OUT transfer not complete interrupt enable */ +#define GINTEN_ISOINCIE BIT(20) /*!< isochronous IN transfer not complete interrupt enable */ +#define GINTEN_OEPIE BIT(19) /*!< OUT endpoints interrupt enable */ +#define GINTEN_IEPIE BIT(18) /*!< IN endpoints interrupt enable */ +#define GINTEN_EOPFIE BIT(15) /*!< end of periodic frame interrupt enable */ +#define GINTEN_ISOOPDIE BIT(14) /*!< isochronous OUT packet dropped interrupt enable */ +#define GINTEN_ENUMFIE BIT(13) /*!< enumeration finish enable */ +#define GINTEN_RSTIE BIT(12) /*!< USB reset interrupt enable */ +#define GINTEN_SPIE BIT(11) /*!< USB suspend interrupt enable */ +#define GINTEN_ESPIE BIT(10) /*!< early suspend interrupt enable */ +#define GINTEN_GONAKIE BIT(7) /*!< global OUT NAK effective interrupt enable */ +#define GINTEN_GNPINAKIE BIT(6) /*!< global non-periodic IN NAK effective interrupt enable */ +#define GINTEN_NPTXFEIE BIT(5) /*!< non-periodic Tx FIFO empty interrupt enable */ +#define GINTEN_RXFNEIE BIT(4) /*!< receive FIFO non-empty interrupt enable */ +#define GINTEN_SOFIE BIT(3) /*!< start of frame interrupt enable */ +#define GINTEN_OTGIE BIT(2) /*!< OTG interrupt enable */ +#define GINTEN_MFIE BIT(1) /*!< mode fault interrupt enable */ + +/* global receive status read and pop register bits definitions */ +#define GRSTATRP_RPCKST BITS(17, 20) /*!< received packet status */ +#define GRSTATRP_DPID BITS(15, 16) /*!< data PID */ +#define GRSTATRP_BCOUNT BITS(4, 14) /*!< byte count */ +#define GRSTATRP_CNUM BITS(0, 3) /*!< channel number */ +#define GRSTATRP_EPNUM BITS(0, 3) /*!< endpoint number */ + +/* global receive FIFO length register bits definitions */ +#define GRFLEN_RXFD BITS(0, 15) /*!< rx FIFO depth */ + +/* host non-periodic transmit FIFO length register bits definitions */ +#define HNPTFLEN_HNPTXFD BITS(16, 31) /*!< non-periodic Tx FIFO depth */ +#define HNPTFLEN_HNPTXRSAR BITS(0, 15) /*!< non-periodic Tx RAM start address */ + +/* USB IN endpoint 0 transmit FIFO length register bits definitions */ +#define DIEP0TFLEN_IEP0TXFD BITS(16, 31) /*!< IN Endpoint 0 Tx FIFO depth */ +#define DIEP0TFLEN_IEP0TXRSAR BITS(0, 15) /*!< IN Endpoint 0 TX RAM start address */ + +/* host non-periodic transmit FIFO/queue status register bits definitions */ +#define HNPTFQSTAT_NPTXRQTOP BITS(24, 30) /*!< top entry of the non-periodic Tx request queue */ +#define HNPTFQSTAT_NPTXRQS BITS(16, 23) /*!< non-periodic Tx request queue space */ +#define HNPTFQSTAT_NPTXFS BITS(0, 15) /*!< non-periodic Tx FIFO space */ +#define HNPTFQSTAT_CNUM BITS(27, 30) /*!< channel number*/ +#define HNPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */ +#define HNPTFQSTAT_TYPE BITS(25, 26) /*!< token type */ +#define HNPTFQSTAT_TMF BIT(24) /*!< terminate flag */ + +/* global core configuration register bits definitions */ +#define GCCFG_VDEN BIT(21) /*!< enable of VBUS sensing comparator to detect VBUS valid */ +#define GCCFG_SOFOEN BIT(20) /*!< SOF output enable */ +#define GCCFG_PWRON BIT(16) /*!< power on */ +#define GCCFG_SDMEN BIT(15) /*!< secondary detection mode enable */ +#define GCCFG_PEMEN BIT(14) /*!< primary detection mode enable */ +#define GCCFG_DCDEN BIT(13) /*!< data connect detection mode enable */ +#define GCCFG_BCDEN BIT(12) /*!< battery charging detection enable */ +#define GCCFG_PS2F BIT(3) /*!< PS2 detection status */ +#define GCCFG_SDF BIT(2) /*!< secondary detection status */ +#define GCCFG_PDF BIT(1) /*!< primary detection status */ +#define GCCFG_DCDF BIT(0) /*!< battery connect detection status */ + +/* core ID register bits definitions */ +#define CID_CID BITS(0, 31) /*!< core ID */ + +/* global core LPM configuration register bits definitions */ +#define GLPMCFG_BESLEN BIT(28) /*!< LPM Errata selection enable */ +#define GLPMCFG_LPMRCS BITS(25, 27) /*!< LPM retry count status */ +#define GLPMCFG_LPMSND BIT(24) /*!< send LPM transaction */ +#define GLPMCFG_LPMRC BITS(21, 23) /*!< LPM retry count */ +#define GLPMCFG_LPMCHI BITS(17, 20) /*!< channel number index */ +#define GLPMCFG_RSOK BIT(16) /*!< Resume can be sent after sleep state */ +#define GLPMCFG_LPMSLPS BIT(15) /*!< sleep status */ +#define GLPMCFG_LPMRSP BITS(13, 14) /*!< response of LPM */ +#define GLPMCFG_DSEN BIT(12) /*!< deep sleep enable */ +#define GLPMCFG_BESLTH BITS(8, 11) /*!< BESL threshold */ +#define GLPMCFG_SSEN BIT(7) /*!< shallow sleep enable */ +#define GLPMCFG_REW BIT(6) /*!< bRemoteWake value */ +#define GLPMCFG_BESL BITS(2, 5) /*!< best effort service latency */ +#define GLPMCFG_ACKLPM BIT(1) /*!< ACK in LPM transaction enable */ +#define GLPMCFG_LPMEN BIT(0) /*!< LPM enable */ + +/* power down register bits definition */ +#define PWRD_ADPF BIT(23) /*!< ADP event interrupt flag */ +#define PWRD_ADPMEN BIT(0) /*!< ADP module enable */ + +/* ADP control and status register bits definition */ +#define ADPCTL_RWR BITS(27, 28) /*!< read and write request */ +#define ADPCTL_ADPTFM BIT(26) /*!< the mask of ADP timeout interrupt flag */ +#define ADPCTL_ADPSNFM BIT(25) /*!< the mask of ADP sense interrupt flag */ +#define ADPCTL_ADPPRFM BIT(24) /*!< the mask of ADP probe interrupt flag */ +#define ADPCTL_ADPTF BIT(23) /*!< ADP timeout interrupt flag */ +#define ADPCTL_ADPSNF BIT(22) /*!< ADP sense interrupt flag */ +#define ADPCTL_ADPPRF BIT(21) /*!< ADP probe interrupt flag */ +#define ADPCTL_ADPEN BIT(20) /*!< ADP enable */ +#define ADPCTL_ADPRST BIT(19) /*!< ADP reset */ +#define ADPCTL_SNEN BIT(18) /*!< ADP sense enable */ +#define ADPCTL_PREN BIT(17) /*!< ADP probe enable */ +#define ADPCTL_CHGT BITS(6, 16) /*!< the latest time that VBUS ramps from VADPSINK to VADPPRB */ +#define ADPCTL_PERPR BITS(4, 5) /*!< period of probe */ +#define ADPCTL_RESOPR BITS(2, 3) /*!< the resolution of CHGT value */ +#define ADPCTL_DSCHGPR BITS(0, 1) /*!< Time of probe discharge */ + +/* USBHS PHY control register bits definitions */ +#define PHYCTL_HS_CALEN BIT(31) /*!< HS PHY calibration enable */ +#define PHYCTL_HS_CALR BITS(25, 30) /*!< HS PHY calibration value */ +#define PHYCTL_HS_RCALR BITS(21, 24) /*!< HS PHY R calibration value */ +#define PHYCTL_SQUECH BIT(16) /*!< HS PHY squech flag */ +#define PHYCTL_HS_BIST_DONE BIT(15) /*!< HS PHY bist finished flag */ +#define PHYCTL_HS_BIST_SUCCESS BIT(14) /*!< HS PHY bist success flag */ +#define PHYCTL_HS_BIST_FAIL BIT(13) /*!< HS PHY bist fail flag */ +#define PHYCTL_HS_BIST_PKT_SEL BITS(11, 12) /*!< HS PHY bist packet select */ +#define PHYCTL_HS_BIST_SEED BITS(3, 10) /*!< HS PHY bist seed */ +#define PHYCTL_HS_BIST_EN BIT(2) /*!< HS PHY bist enable */ +#define PHYCTL_HS_BIST_RESET BIT(1) /*!< HS PHY bist logic reset */ +#define PHYCTL_HS_BIST_START BIT(0) /*!< HS PHY bist start */ + +/* host periodic transmit FIFO length register bits definitions */ +#define HPTFLEN_HPTXFD BITS(16, 31) /*!< host periodic Tx FIFO depth */ +#define HPTFLEN_HPTXFSAR BITS(0, 15) /*!< host periodic Tx RAM start address */ + +/* device IN endpoint transmit FIFO length register bits definitions */ +#define DIEPTFLEN_IEPTXFD BITS(16, 31) /*!< IN endpoint Tx FIFO x depth */ +#define DIEPTFLEN_IEPTXRSAR BITS(0, 15) /*!< IN endpoint FIFOx Tx x RAM start address */ + +/* host control register bits definitions */ +#define HCTL_SPDFSLS BIT(2) /*!< speed limited to FS and LS */ + +/* host frame interval register bits definitions */ +#define HFT_FRI BITS(0, 15) /*!< frame interval */ + +/* host frame information remaining register bits definitions */ +#define HFINFR_FRT BITS(16, 31) /*!< frame remaining time */ +#define HFINFR_FRNUM BITS(0, 15) /*!< frame number */ + +/* host periodic transmit FIFO/queue status register bits definitions */ +#define HPTFQSTAT_PTXREQT BITS(24, 31) /*!< top entry of the periodic Tx request queue */ +#define HPTFQSTAT_PTXREQS BITS(16, 23) /*!< periodic Tx request queue space */ +#define HPTFQSTAT_PTXFS BITS(0, 15) /*!< periodic Tx FIFO space */ +#define HPTFQSTAT_OEFRM BIT(31) /*!< odd/eveb frame */ +#define HPTFQSTAT_CNUM BITS(27, 30) /*!< channel number */ +#define HPTFQSTAT_EPNUM BITS(27, 30) /*!< endpoint number */ +#define HPTFQSTAT_TYPE BITS(25, 26) /*!< token type */ +#define HPTFQSTAT_TMF BIT(24) /*!< terminate flag */ + +#define TFQSTAT_TXFS BITS(0, 15) +#define TFQSTAT_CNUM BITS(27, 30) + +/* host all channels interrupt register bits definitions */ +#define HACHINT_HACHINT BITS(0, 15) /*!< host all channel interrupts */ + +/* host all channels interrupt enable register bits definitions */ +#define HACHINTEN_CINTEN BITS(0, 15) /*!< channel interrupt enable */ + +/* host port control and status register bits definitions */ +#define HPCS_PS BITS(17, 18) /*!< port speed */ +#define HPCS_PTEST BITS(13, 16) /*!< port test control */ +#define HPCS_PP BIT(12) /*!< port power */ +#define HPCS_PLST BITS(10, 11) /*!< port line status */ +#define HPCS_PRST BIT(8) /*!< port reset */ +#define HPCS_PSP BIT(7) /*!< port suspend */ +#define HPCS_PREM BIT(6) /*!< port resume */ +#define HPCS_PEDC BIT(3) /*!< port enable/disable change */ +#define HPCS_PE BIT(2) /*!< port enable */ +#define HPCS_PCD BIT(1) /*!< port connect detected */ +#define HPCS_PCST BIT(0) /*!< port connect status */ + +/* host channel-x control register bits definitions */ +#define HCHCTL_CEN BIT(31) /*!< channel enable */ +#define HCHCTL_CDIS BIT(30) /*!< channel disable */ +#define HCHCTL_ODDFRM BIT(29) /*!< odd frame */ +#define HCHCTL_DAR BITS(22, 28) /*!< device address */ +#define HCHCTL_MPC BITS(20, 21) /*!< multiple packet count */ +#define HCHCTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define HCHCTL_LSD BIT(17) /*!< low-speed device */ +#define HCHCTL_EPDIR BIT(15) /*!< endpoint direction */ +#define HCHCTL_EPNUM BITS(11, 14) /*!< endpoint number */ +#define HCHCTL_MPL BITS(0, 10) /*!< maximum packet length */ + +/* host channel-x split transaction register bits definitions */ +#define HCHSTCTL_SPLEN BIT(31) /*!< enable high-speed split transaction */ +#define HCHSTCTL_CSPLT BIT(16) /*!< complete-split enable */ +#define HCHSTCTL_ISOPCE BITS(14, 15) /*!< isochronous OUT payload continuation encoding */ +#define HCHSTCTL_HADDR BITS(7, 13) /*!< HUB address */ +#define HCHSTCTL_PADDR BITS(0, 6) /*!< port address */ + +/* host channel-x interrupt flag register bits definitions */ +#define HCHINTF_DTER BIT(10) /*!< data toggle error */ +#define HCHINTF_REQOVR BIT(9) /*!< request queue overrun */ +#define HCHINTF_BBER BIT(8) /*!< babble error */ +#define HCHINTF_USBER BIT(7) /*!< USB bus Error */ +#define HCHINTF_NYET BIT(6) /*!< NYET */ +#define HCHINTF_ACK BIT(5) /*!< ACK */ +#define HCHINTF_NAK BIT(4) /*!< NAK */ +#define HCHINTF_STALL BIT(3) /*!< STALL */ +#define HCHINTF_DMAER BIT(2) /*!< DMA error */ +#define HCHINTF_CH BIT(1) /*!< channel halted */ +#define HCHINTF_TF BIT(0) /*!< transfer finished */ + +/* host channel-x interrupt enable register bits definitions */ +#define HCHINTEN_DTERIE BIT(10) /*!< data toggle error interrupt enable */ +#define HCHINTEN_REQOVRIE BIT(9) /*!< request queue overrun interrupt enable */ +#define HCHINTEN_BBERIE BIT(8) /*!< babble error interrupt enable */ +#define HCHINTEN_USBERIE BIT(7) /*!< USB bus error interrupt enable */ +#define HCHINTEN_NYETIE BIT(6) /*!< NYET interrupt enable */ +#define HCHINTEN_ACKIE BIT(5) /*!< ACK interrupt enable */ +#define HCHINTEN_NAKIE BIT(4) /*!< NAK interrupt enable */ +#define HCHINTEN_STALLIE BIT(3) /*!< STALL interrupt enable */ +#define HCHINTEN_DMAERIE BIT(2) /*!< DMA error interrupt enable */ +#define HCHINTEN_CHIE BIT(1) /*!< channel halted interrupt enable */ +#define HCHINTEN_TFIE BIT(0) /*!< transfer finished interrupt enable */ + +/* host channel-x transfer length register bits definitions */ +#define HCHLEN_PING BIT(31) /*!< PING token request */ +#define HCHLEN_DPID BITS(29, 30) /*!< data PID */ +#define HCHLEN_PCNT BITS(19, 28) /*!< packet count */ +#define HCHLEN_TLEN BITS(0, 18) /*!< transfer length */ + +/* host channel-x DMA address register bits definitions */ +#define HCHDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ + +#define PORT_SPEED(x) (((uint32_t)(x) << 17U) & HPCS_PS) /*!< Port speed */ + +#define PORT_SPEED_HIGH PORT_SPEED(0U) /*!< high speed */ +#define PORT_SPEED_FULL PORT_SPEED(1U) /*!< full speed */ +#define PORT_SPEED_LOW PORT_SPEED(2U) /*!< low speed */ + +#define PIPE_CTL_DAR(x) (((uint32_t)(x) << 22U) & HCHCTL_DAR) /*!< device address */ +#define PIPE_CTL_EPTYPE(x) (((uint32_t)(x) << 18U) & HCHCTL_EPTYPE) /*!< endpoint type */ +#define PIPE_CTL_EPNUM(x) (((uint32_t)(x) << 11U) & HCHCTL_EPNUM) /*!< endpoint number */ +#define PIPE_CTL_EPDIR(x) (((uint32_t)(x) << 15U) & HCHCTL_EPDIR) /*!< endpoint direction */ +#define PIPE_CTL_EPMPL(x) (((uint32_t)(x) << 0U) & HCHCTL_MPL) /*!< maximum packet length */ +#define PIPE_CTL_LSD(x) (((uint32_t)(x) << 17U) & HCHCTL_LSD) /*!< low-Speed device */ + +#define PIPE_XFER_PCNT(x) (((uint32_t)(x) << 19U) & HCHLEN_PCNT) /*!< packet count */ +#define PIPE_XFER_DPID(x) (((uint32_t)(x) << 29U) & HCHLEN_DPID) /*!< data PID */ + +#define PIPE_DPID_DATA0 PIPE_XFER_DPID(0) /*!< DATA0 */ +#define PIPE_DPID_DATA1 PIPE_XFER_DPID(2) /*!< DATA1 */ +#define PIPE_DPID_DATA2 PIPE_XFER_DPID(1) /*!< DATA2 */ +#define PIPE_DPID_SETUP PIPE_XFER_DPID(3) /*!< MDATA (non-control)/SETUP (control) */ + +extern const uint32_t PIPE_DPID[2]; + +/* device configuration registers bits definitions */ +#define DCFG_EOPFT BITS(11, 12) /*!< end of periodic frame time */ +#define DCFG_DAR BITS(4, 10) /*!< device address */ +#define DCFG_NZLSOH BIT(2) /*!< non-zero-length status OUT handshake */ +#define DCFG_DS BITS(0, 1) /*!< device speed */ + +/* device control registers bits definitions */ +#define DCTL_L1RJCT BIT(18) /*!< deep sleep reject */ +#define DCTL_POIF BIT(11) /*!< power-on initialization finished */ +#define DCTL_CGONAK BIT(10) /*!< clear global OUT NAK */ +#define DCTL_SGONAK BIT(9) /*!< set global OUT NAK */ +#define DCTL_CGINAK BIT(8) /*!< clear global IN NAK */ +#define DCTL_SGINAK BIT(7) /*!< set global IN NAK */ +#define DCTL_DTEST BITS(4, 6) /*!< device test control */ +#define DCTL_GONS BIT(3) /*!< global OUT NAK status */ +#define DCTL_GINS BIT(2) /*!< global IN NAK status */ +#define DCTL_SD BIT(1) /*!< soft disconnect */ +#define DCTL_RWKUP BIT(0) /*!< remote wakeup */ + +/* device status registers bits definitions */ +#define DSTAT_FNRSOF BITS(8, 21) /*!< the frame number of the received SOF. */ +#define DSTAT_ES BITS(1, 2) /*!< enumerated speed */ +#define DSTAT_SPST BIT(0) /*!< suspend status */ + +/* device IN endpoint common interrupt enable registers bits definitions */ +#define DIEPINTEN_NAKEN BIT(13) /*!< NAK handshake sent by USBHS interrupt enable bit */ +#define DIEPINTEN_TXFEEN BIT(7) /*!< transmit FIFO empty interrupt enable bit */ +#define DIEPINTEN_IEPNEEN BIT(6) /*!< IN endpoint NAK effective interrupt enable bit */ +#define DIEPINTEN_EPTXFUDEN BIT(4) /*!< endpoint Tx FIFO underrun interrupt enable bit */ +#define DIEPINTEN_CITOEN BIT(3) /*!< control In Timeout interrupt enable bit */ +#define DIEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ +#define DIEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */ + +/* device OUT endpoint common interrupt enable registers bits definitions */ +#define DOEPINTEN_NYETEN BIT(14) /*!< NYET handshake is sent interrupt enable bit */ +#define DOEPINTEN_BTBSTPEN BIT(6) /*!< back-to-back SETUP packets interrupt enable bit */ +#define DOEPINTEN_EPRXFOVREN BIT(4) /*!< endpoint Rx FIFO overrun interrupt enable bit */ +#define DOEPINTEN_STPFEN BIT(3) /*!< SETUP phase finished interrupt enable bit */ +#define DOEPINTEN_EPDISEN BIT(1) /*!< endpoint disabled interrupt enable bit */ +#define DOEPINTEN_TFEN BIT(0) /*!< transfer finished interrupt enable bit */ + +/* device all endpoints interrupt registers bits definitions */ +#define DAEPINT_OEPITB BITS(16, 23) /*!< device all OUT endpoint interrupt bits */ +#define DAEPINT_IEPITB BITS(0, 7) /*!< device all IN endpoint interrupt bits */ + +/* device all endpoints interrupt enable registers bits definitions */ +#define DAEPINTEN_OEPIE BITS(16, 23) /*!< OUT endpoint interrupt enable */ +#define DAEPINTEN_IEPIE BITS(0, 7) /*!< IN endpoint interrupt enable */ + +/* device VBUS discharge time registers bits definitions */ +#define DVBUSDT_DVBUSDT BITS(0, 15) /*!< device VBUS discharge time */ + +/* device VBUS pulsing time registers bits definitions */ +#define DVBUSPT_DVBUSPT BITS(0, 11) /*!< device VBUS pulsing time */ + +/* device IN endpoint FIFO empty interrupt enable register bits definitions */ +#define DIEPFEINTEN_IEPTXFEIE BITS(0, 5) /*!< IN endpoint Tx FIFO empty interrupt enable bits */ + +/* device endpoint 0 control register bits definitions */ +#define DEP0CTL_EPEN BIT(31) /*!< endpoint enable */ +#define DEP0CTL_EPD BIT(30) /*!< endpoint disable */ +#define DEP0CTL_SNAK BIT(27) /*!< set NAK */ +#define DEP0CTL_CNAK BIT(26) /*!< clear NAK */ +#define DIEP0CTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */ +#define DEP0CTL_STALL BIT(21) /*!< STALL handshake */ +#define DOEP0CTL_SNOOP BIT(20) /*!< snoop mode */ +#define DEP0CTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define DEP0CTL_NAKS BIT(17) /*!< NAK status */ +#define DEP0CTL_EPACT BIT(15) /*!< endpoint active */ +#define DEP0CTL_MPL BITS(0, 1) /*!< maximum packet length */ + +/* device endpoint x control register bits definitions */ +#define DEPCTL_EPEN BIT(31) /*!< endpoint enable */ +#define DEPCTL_EPD BIT(30) /*!< endpoint disable */ +#define DEPCTL_SODDFRM BIT(29) /*!< set odd frame */ +#define DEPCTL_SD1PID BIT(29) /*!< set DATA1 PID */ +#define DEPCTL_SEVNFRM BIT(28) /*!< set even frame */ +#define DEPCTL_SD0PID BIT(28) /*!< set DATA0 PID */ +#define DEPCTL_SNAK BIT(27) /*!< set NAK */ +#define DEPCTL_CNAK BIT(26) /*!< clear NAK */ +#define DIEPCTL_TXFNUM BITS(22, 25) /*!< tx FIFO number */ +#define DEPCTL_STALL BIT(21) /*!< STALL handshake */ +#define DOEPCTL_SNOOP BIT(20) /*!< snoop mode */ +#define DEPCTL_EPTYPE BITS(18, 19) /*!< endpoint type */ +#define DEPCTL_NAKS BIT(17) /*!< NAK status */ +#define DEPCTL_EOFRM BIT(16) /*!< even/odd frame */ +#define DEPCTL_DPID BIT(16) /*!< endpoint data PID */ +#define DEPCTL_EPACT BIT(15) /*!< endpoint active */ +#define DEPCTL_MPL BITS(0, 10) /*!< maximum packet length */ + +/* device IN endpoint-x interrupt flag register bits definitions */ +#define DIEPINTF_NAK BIT(13) /*!< NAK handshake sent by USBHS */ +#define DIEPINTF_TXFE BIT(7) /*!< transmit FIFO empty */ +#define DIEPINTF_IEPNE BIT(6) /*!< IN endpoint NAK effective */ +#define DIEPINTF_EPTXFUD BIT(4) /*!< endpoint Tx FIFO underrun */ +#define DIEPINTF_CITO BIT(3) /*!< control In Timeout interrupt */ +#define DIEPINTF_EPDIS BIT(1) /*!< endpoint disabled */ +#define DIEPINTF_TF BIT(0) /*!< transfer finished */ + +/* device OUT endpoint-x interrupt flag register bits definitions */ +#define DOEPINTF_NYET BIT(14) /*!< NYET handshake is sent */ +#define DOEPINTF_BTBSTP BIT(6) /*!< back-to-back SETUP packets */ +#define DOEPINTF_EPRXFOVR BIT(4) /*!< endpoint Rx FIFO overrun */ +#define DOEPINTF_STPF BIT(3) /*!< SETUP phase finished */ +#define DOEPINTF_EPDIS BIT(1) /*!< endpoint disabled */ +#define DOEPINTF_TF BIT(0) /*!< transfer finished */ + +/* device IN endpoint 0 transfer length register bits definitions */ +#define DIEP0LEN_PCNT BITS(19, 20) /*!< packet count */ +#define DIEP0LEN_TLEN BITS(0, 6) /*!< transfer length */ + +/* device OUT endpoint 0 transfer length register bits definitions */ +#define DOEP0LEN_STPCNT BITS(29, 30) /*!< SETUP packet count */ +#define DOEP0LEN_PCNT BIT(19) /*!< packet count */ +#define DOEP0LEN_TLEN BITS(0, 6) /*!< transfer length */ + +/* device OUT endpoint-x transfer length register bits definitions */ +#define DOEPLEN_RXDPID BITS(29, 30) /*!< received data PID */ +#define DOEPLEN_STPCNT BITS(29, 30) /*!< SETUP packet count */ +#define DIEPLEN_MCNT BITS(29, 30) /*!< multi count */ +#define DEPLEN_PCNT BITS(19, 28) /*!< packet count */ +#define DEPLEN_TLEN BITS(0, 18) /*!< transfer length */ + +/* device IN endpoint-x DMA address register bits definitions */ +#define DIEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ + +/* device OUT endpoint-x DMA address register bits definitions */ +#define DOEPDMAADDR_DMAADDR BITS(0, 31) /*!< DMA address */ + +/* device IN endpoint-x transmit FIFO status register bits definitions */ +#define DIEPTFSTAT_IEPTFS BITS(0, 15) /*!< IN endpoint Tx FIFO space remaining */ + +/* USB power and clock registers bits definition */ +#define PWRCLKCTL_DSLEEP BIT(7) /*!< PHY is in deep sleep status */ +#define PWRCLKCTL_SSLEEP BIT(6) /*!< PHY is in shallow sleep status */ +#define PWRCLKCTL_SCGEN BIT(5) /*!< When this bit is set, the internal clock gating is enabled */ +#define PWRCLKCTL_SUSP BIT(4) /*!< PHY is in suspend status */ +#define PWRCLKCTL_SHCLK BIT(1) /*!< stop HCLK */ +#define PWRCLKCTL_SUCLK BIT(0) /*!< stop the USB clock */ + +#define RSTAT_GOUT_NAK 1U /*!< global OUT NAK (triggers an interrupt) */ +#define RSTAT_DATA_UPDT 2U /*!< OUT data packet received */ +#define RSTAT_XFER_COMP 3U /*!< OUT transfer completed (triggers an interrupt) */ +#define RSTAT_SETUP_COMP 4U /*!< SETUP transaction completed (triggers an interrupt) */ +#define RSTAT_SETUP_UPDT 6U /*!< SETUP data packet received */ + +#define DSTAT_EM_HS_PHY_30MHZ_60MHZ 0U /*!< USB enumerate speed use high-speed PHY clock in 30MHz or 60MHz */ +#define DSTAT_EM_FS_PHY_30MHZ_60MHZ 1U /*!< USB enumerate speed use full-speed PHY clock in 30MHz or 60MHz */ +#define DSTAT_EM_LS_PHY_6MHZ 2U /*!< USB enumerate speed use low-speed PHY clock in 6MHz */ +#define DSTAT_EM_FS_PHY_48MHZ 3U /*!< USB enumerate speed use full-speed PHY clock in 48MHz */ + +#define DPID_DATA0 0U /*!< device endpoint data PID is DATA0 */ +#define DPID_DATA1 2U /*!< device endpoint data PID is DATA1 */ +#define DPID_DATA2 1U /*!< device endpoint data PID is DATA2 */ +#define DPID_MDATA 3U /*!< device endpoint data PID is MDATA */ + +#define GAHBCS_DMAINCR(regval) (GAHBCS_BURST & ((regval) << 1U)) /*!< AHB burst type used by DMA*/ + +#define DMA_INCR0 GAHBCS_DMAINCR(0U) /*!< single burst type used by DMA*/ +#define DMA_INCR1 GAHBCS_DMAINCR(1U) /*!< 4-beat incrementing burst type used by DMA*/ +#define DMA_INCR4 GAHBCS_DMAINCR(3U) /*!< 8-beat incrementing burst type used by DMA*/ +#define DMA_INCR8 GAHBCS_DMAINCR(5U) /*!< 16-beat incrementing burst type used by DMA*/ +#define DMA_INCR16 GAHBCS_DMAINCR(7U) /*!< 32-beat incrementing burst type used by DMA*/ + +#define DCFG_PFRI(regval) (DCFG_EOPFT & ((regval) << 11U)) /*!< end of periodic frame time configuration */ + +#define FRAME_INTERVAL_80 DCFG_PFRI(0U) /*!< 80% of the frame time */ +#define FRAME_INTERVAL_85 DCFG_PFRI(1U) /*!< 85% of the frame time */ +#define FRAME_INTERVAL_90 DCFG_PFRI(2U) /*!< 90% of the frame time */ +#define FRAME_INTERVAL_95 DCFG_PFRI(3U) /*!< 95% of the frame time */ + +#define DCFG_DEVSPEED(regval) (DCFG_DS & ((regval) << 0U)) /*!< device speed configuration */ + +#define USB_SPEED_INP_HIGH DCFG_DEVSPEED(0U) /*!< device internal PHY high speed */ +#define USB_SPEED_INP_FULL DCFG_DEVSPEED(1U) /*!< device internal PHY full speed */ + +#define DEP0_MPL(regval) (DEP0CTL_MPL & ((regval) << 0U)) /*!< maximum packet length configuration */ + +#define EP0MPL_64 DEP0_MPL(0U) /*!< maximum packet length 64 bytes */ +#define EP0MPL_32 DEP0_MPL(1U) /*!< maximum packet length 32 bytes */ +#define EP0MPL_16 DEP0_MPL(2U) /*!< maximum packet length 16 bytes */ +#define EP0MPL_8 DEP0_MPL(3U) /*!< maximum packet length 8 bytes */ + +#define DOEP0_TLEN(regval) (DOEP0LEN_TLEN & ((regval) << 0U)) /*!< Transfer length */ +#define DOEP0_PCNT(regval) (DOEP0LEN_PCNT & ((regval) << 19U)) /*!< Packet count */ +#define DOEP0_STPCNT(regval) (DOEP0LEN_STPCNT & ((regval) << 29U)) /*!< SETUP packet count */ + +#define GRXSTS_PKTSTS_IN 2U +#define GRXSTS_PKTSTS_IN_XFER_COMP 3U +#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U +#define GRXSTS_PKTSTS_CH_HALTED 7U + +#define DEVICE_MODE 0U /*!< device mode */ +#define HOST_MODE 1U /*!< host mode */ +#define OTG_MODE 2U /*!< OTG mode */ + +#define HCTL_30_60MHZ 0U /*!< USB clock 30-60MHZ */ +#define HCTL_48MHZ 1U /*!< USB clock 48MHZ */ +#define HCTL_6MHZ 2U /*!< USB clock 6MHZ */ + +enum USB_SPEED { + USB_SPEED_UNKNOWN = 0, /*!< USB speed unknown */ + USB_SPEED_LOW, /*!< USB speed low */ + USB_SPEED_FULL, /*!< USB speed full */ + USB_SPEED_HIGH /*!< USB speed high */ +}; + +#define EP0_OUT ((uint8_t)0x00U) /*!< endpoint out 0 */ +#define EP0_IN ((uint8_t)0x80U) /*!< endpoint in 0 */ +#define EP1_OUT ((uint8_t)0x01U) /*!< endpoint out 1 */ +#define EP1_IN ((uint8_t)0x81U) /*!< endpoint in 1 */ +#define EP2_OUT ((uint8_t)0x02U) /*!< endpoint out 2 */ +#define EP2_IN ((uint8_t)0x82U) /*!< endpoint in 2 */ +#define EP3_OUT ((uint8_t)0x03U) /*!< endpoint out 3 */ +#define EP3_IN ((uint8_t)0x83U) /*!< endpoint in 3 */ +#define EP4_OUT ((uint8_t)0x04U) /*!< endpoint out 4 */ +#define EP4_IN ((uint8_t)0x84U) /*!< endpoint in 4 */ +#define EP5_OUT ((uint8_t)0x05U) /*!< endpoint out 5 */ +#define EP5_IN ((uint8_t)0x85U) /*!< endpoint in 5 */ +#define EP6_OUT ((uint8_t)0x06U) /*!< endpoint out 6 */ +#define EP6_IN ((uint8_t)0x86U) /*!< endpoint in 6 */ +#define EP7_OUT ((uint8_t)0x06U) /*!< endpoint out 7 */ +#define EP7_IN ((uint8_t)0x86U) /*!< endpoint in 7 */ + +#endif /* __DRV_USB_REGS_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbd_int.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbd_int.h new file mode 100644 index 0000000000..910b3f4ebc --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbd_int.h @@ -0,0 +1,52 @@ +/*! + \file drv_usbd_int.h + \brief USB device mode interrupt header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DRV_USBD_INT_H +#define __DRV_USBD_INT_H + +#include "drv_usb_core.h" +#include "drv_usb_dev.h" + +/* function declarations */ +#ifdef USB_DEDICATED_EP1_ENABLED +/* USB dedicated OUT endpoint 1 interrupt service routine handler */ +uint32_t usbd_int_dedicated_ep1out (usb_core_driver *udev); +/* USB dedicated IN endpoint 1 interrupt service routine handler */ +uint32_t usbd_int_dedicated_ep1in (usb_core_driver *udev); +#endif + +/* USB device-mode interrupts global service routine handler */ +void usbd_isr (usb_core_driver *udev); + +#endif /* __DRV_USBD_INT_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbh_int.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbh_int.h new file mode 100644 index 0000000000..37d4447e83 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Include/drv_usbh_int.h @@ -0,0 +1,56 @@ +/*! + \file drv_usbh_int.h.h + \brief USB host mode interrupt management header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __DRV_USBH_INT_H +#define __DRV_USBH_INT_H + +#include "drv_usb_host.h" +#include "usbh_core.h" + +typedef struct _usbh_int_cb +{ + uint8_t (*connect) (usbh_host *uhost); + uint8_t (*disconnect) (usbh_host *uhost); + uint8_t (*port_enabled) (usbh_host *uhost); + uint8_t (*port_disabled) (usbh_host *uhost); + uint8_t (*SOF) (usbh_host *uhost); +} usbh_int_cb; + +extern usbh_int_cb *usbh_int_fop; + +/* function declarations */ +/* handle global host interrupt */ +uint32_t usbh_isr (usb_core_driver *udev); + +#endif /* __DRV_USBH_INT_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_core.c new file mode 100644 index 0000000000..3494abb9f9 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_core.c @@ -0,0 +1,396 @@ +/*! + \file drv_usb_core.c + \brief USB core driver which can operate in host and device mode + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "drv_usb_core.h" +#include "drv_usb_hw.h" + +/* local function prototypes ('static') */ +static void usb_core_reset (usb_core_regs *usb_regs); + +/*! + \brief configures USB parameters + \param[in] udev: pointer to USB core instance + \param[in] usb_periph: USBHSx(x=0,1) + \param[in] usb_speed: USB speed type (full-speed or high-speed) + \param[out] none + \retval none +*/ +void usb_para_init(usb_core_driver *udev, uint32_t usb_periph, uint32_t usb_speed) +{ + usb_core_basic *usb_basic = &udev->bp; + + /* configure USB default transfer mode as FIFO mode */ + usb_basic->transfer_mode = (uint8_t)USB_USE_FIFO; + + /* USB default speed is full-speed */ + usb_basic->core_speed = (uint8_t)USB_SPEED_FULL; + + /* USB basic register address setting */ + switch(usb_periph){ + case USBHS0: + usb_basic->base_reg = (uint32_t)USBHS0_REG_BASE; + break; + case USBHS1: + usb_basic->base_reg = (uint32_t)USBHS1_REG_BASE; + break; + default: + break; + } + + /* set the host channel numbers */ + usb_basic->num_pipe = USBHS_MAX_CHANNEL_COUNT; + + /* set the device endpoint numbers */ + usb_basic->num_ep = USBHS_MAX_EP_COUNT; + + if (USB_SPEED_HIGH == usb_speed) { +#ifdef USB_EXTERNAL_ULPI_PHY_ENABLED + usb_basic->phy_itf = USB_ULPI_PHY_EXTERNAL; +#endif /* USB_EXTERNAL_ULPI_PHY_ENABLED */ + +#ifdef USB_EMBEDDED_HS_PHY_ENABLED + usb_basic->phy_itf = USB_EMBEDDED_PHY_HS; +#endif /* USB_EMBEDDED_HS_PHY_ENABLED */ + } else if (USB_SPEED_FULL == usb_speed) { +#ifdef USB_EMBEDDED_FS_PHY_ENABLED + usb_basic->phy_itf = USB_EMBEDDED_PHY_FS; +#endif /* USB_EMBEDDED_FS_PHY_ENABLED */ + } else { + /* no operation */ + } + +#ifdef USB_INTERNAL_DMA_ENABLED + usb_basic->transfer_mode = USB_USE_DMA; +#endif /* USB_INTERNAL_DMA_ENABLED */ + + usb_basic->sof_enable = (uint8_t)USB_SOF_OUTPUT; + usb_basic->low_power = (uint8_t)USB_LOW_POWER; + +#if (1U == LPM_ENABLED) + usb_basic->lpm_enable = 1U; +#endif /* LPM_ENABLED */ +} +/*! + \brief configure USB core basic + \param[in] usb_basic: pointer to USB capabilities + \param[in] usb_regs: pointer to USB core registers + \param[out] none + \retval operation status +*/ +usb_status usb_basic_init (usb_core_basic *usb_basic, usb_core_regs *usb_regs) +{ + /* assign main registers address */ + *usb_regs = (usb_core_regs) { + .gr = (usb_gr*) (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_CORE), + .hr = (usb_hr*) (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_HOST), + .dr = (usb_dr*) (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_DEV), + + .HPCS = (uint32_t*) (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_PORT), + .PWRCLKCTL = (uint32_t*) (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_PWRCLKCTL) + }; + + /* assign device endpoint registers address */ + for (uint8_t i = 0U; i < usb_basic->num_ep; i++) { + usb_regs->er_in[i] = (usb_erin *) \ + (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_EP_IN + (i * (uint32_t)USB_REG_OFFSET_EP)); + + usb_regs->er_out[i] = (usb_erout *)\ + (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_EP_OUT + (i * (uint32_t)USB_REG_OFFSET_EP)); + } + + /* assign host pipe registers address */ + for (uint8_t i = 0U; i < usb_basic->num_pipe; i++) { + usb_regs->pr[i] = (usb_pr *) \ + (usb_basic->base_reg + (uint32_t)USB_REG_OFFSET_CH_INOUT + (i * (uint32_t)USB_REG_OFFSET_CH)); + + usb_regs->DFIFO[i] = (uint32_t *) \ + (usb_basic->base_reg + (uint32_t)USB_DATA_FIFO_OFFSET + (i * (uint32_t)USB_DATA_FIFO_SIZE)); + } + + return USB_OK; +} + +/*! + \brief initializes the USB controller registers and + prepares the core device mode or host mode operation + \param[in] usb_basic: pointer to USB capabilities + \param[in] usb_regs: pointer to USB core registers + \param[out] none + \retval operation status +*/ +usb_status usb_core_init (usb_core_basic usb_basic, usb_core_regs *usb_regs) +{ + /* disable USB global interrupt */ + usb_regs->gr->GAHBCS &= ~GAHBCS_GINTEN; + + if (USB_ULPI_PHY_EXTERNAL == usb_basic.phy_itf) { + usb_regs->gr->GCCFG &= ~GCCFG_PWRON; + + usb_regs->gr->GUSBCS &= ~(GUSBCS_EMBPHY_HS | GUSBCS_EMBPHY_FS); + + if (usb_basic.sof_enable) { + usb_regs->gr->GCCFG |= GCCFG_SOFOEN; + } + + /* initialize the ULPI interface */ + usb_regs->gr->GUSBCS &= ~GUSBCS_ULPIEOI; + +#ifdef USBHS_EXTERNAL_VBUS_ENABLED + /* use external VBUS driver */ + usb_regs->gr->GUSBCS |= GUSBCS_ULPIEVD; +#else + /* use internal VBUS driver */ + usb_regs->gr->GUSBCS &= ~GUSBCS_ULPIEVD; +#endif /* USBHS_EXTERNAL_VBUS_ENABLED */ + + /* soft reset the core */ + usb_core_reset (usb_regs); + } else if (USB_EMBEDDED_PHY_HS == usb_basic.phy_itf) { + usb_regs->gr->GUSBCS |= GUSBCS_EMBPHY_HS; + + /* soft reset the core */ + usb_core_reset (usb_regs); + + usb_regs->gr->GCCFG = 0U; + +#ifdef VBUS_SENSING_ENABLED + /* active the transceiver and enable VBUS sensing */ + usb_regs->gr->GCCFG |= GCCFG_VDEN | GCCFG_PWRON; +#else + #ifdef USE_HOST_MODE + usb_regs->gr->GOTGCS |= GOTGCS_AVOV | GOTGCS_AVOE; + #endif /* USE_HOST_MODE */ + + #ifdef USE_DEVICE_MODE + usb_regs->gr->GOTGCS |= GOTGCS_BVOV | GOTGCS_BVOE; + #endif /* USE_DEVICE_MODE */ + + /* active the transceiver */ + usb_regs->gr->GCCFG |= GCCFG_PWRON; +#endif /* VBUS_SENSING_ENABLED */ + + if (usb_basic.sof_enable) { + usb_regs->gr->GCCFG |= GCCFG_SOFOEN; + } + + usb_mdelay(20U); + } else if (USB_EMBEDDED_PHY_FS == usb_basic.phy_itf) { + usb_regs->gr->GUSBCS |= GUSBCS_EMBPHY_FS; + + /* soft reset the core */ + usb_core_reset (usb_regs); + +#ifdef VBUS_SENSING_ENABLED + /* active the transceiver and enable vbus sensing */ + usb_regs->gr->GCCFG |= GCCFG_VDEN | GCCFG_PWRON; +#else + #ifdef USE_HOST_MODE + usb_regs->gr->GOTGCS |= GOTGCS_AVOV | GOTGCS_AVOE; + #endif /* USE_HOST_MODE */ + + #ifdef USE_DEVICE_MODE + usb_regs->gr->GOTGCS |= GOTGCS_BVOV | GOTGCS_BVOE; + #endif /* USE_DEVICE_MODE */ + + /* active the transceiver */ + usb_regs->gr->GCCFG |= GCCFG_PWRON; +#endif /* VBUS_SENSING_ENABLED */ + + /* enable SOF output */ + if (usb_basic.sof_enable) { + usb_regs->gr->GCCFG |= GCCFG_SOFOEN; + } + + usb_mdelay(20U); + } else { + /* no operation */ + } + + if ((uint8_t)USB_USE_DMA == usb_basic.transfer_mode) { + usb_regs->gr->GAHBCS &= ~GAHBCS_BURST; + usb_regs->gr->GAHBCS |= DMA_INCR8 | GAHBCS_DMAEN; + } + +#ifdef USE_OTG_MODE + + /* enable USB OTG features */ + usb_regs->gr->GUSBCS |= GUSBCS_HNPCEN | GUSBCS_SRPCEN; + + /* enable the USB wakeup and suspend interrupts */ + usb_regs->gr->GINTF = 0xBFFFFFFFU; + + usb_regs->gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE | \ + GINTEN_OTGIE | GINTEN_SESIE | GINTEN_IDPSCIE; + +#endif /* USE_OTG_MODE */ + + return USB_OK; +} + +/*! + \brief write a packet into the TX FIFO associated with the endpoint + \param[in] usb_regs: pointer to USB core registers + \param[in] src_buf: pointer to source buffer + \param[in] fifo_num: FIFO number which is in (0..5) + \param[in] byte_count: packet byte count + \param[out] none + \retval operation status +*/ +usb_status usb_txfifo_write (usb_core_regs *usb_regs, + uint8_t *src_buf, + uint8_t fifo_num, + uint16_t byte_count) +{ + uint32_t word_count = (byte_count + 3U) / 4U; + __IO uint32_t *fifo = usb_regs->DFIFO[fifo_num]; + + while (word_count-- > 0U) { + *fifo = *((__IO uint32_t *)src_buf); + + src_buf += 4U; + } + + return USB_OK; +} + +/*! + \brief read a packet from the Rx FIFO associated with the endpoint + \param[in] usb_regs: pointer to USB core registers + \param[in] dest_buf: pointer to destination buffer + \param[in] byte_count: packet byte count + \param[out] none + \retval void type pointer +*/ +void *usb_rxfifo_read (usb_core_regs *usb_regs, uint8_t *dest_buf, uint16_t byte_count) +{ + __IO uint32_t word_count = (byte_count + 3U) / 4U; + __IO uint32_t *fifo = usb_regs->DFIFO[0]; + + while (word_count-- > 0U) { + *(__IO uint32_t *)dest_buf = *fifo; + + dest_buf += 4U; + } + + return ((void *)dest_buf); +} + +/*! + \brief flush a TX FIFO or all TX FIFOs + \param[in] usb_regs: pointer to USB core registers + \param[in] fifo_num: FIFO number which is in (0..5) + \param[out] none + \retval operation status +*/ +usb_status usb_txfifo_flush (usb_core_regs *usb_regs, uint8_t fifo_num) +{ + usb_regs->gr->GRSTCTL = ((uint32_t)fifo_num << 6U) | GRSTCTL_TXFF; + + /* wait for Tx FIFO flush bit is set */ + while (usb_regs->gr->GRSTCTL & GRSTCTL_TXFF) { + /* no operation */ + } + + /* wait for 3 PHY clocks*/ + usb_udelay(3U); + + return USB_OK; +} + +/*! + \brief flush the entire Rx FIFO + \param[in] usb_regs: pointer to USB core registers + \param[out] none + \retval operation status +*/ +usb_status usb_rxfifo_flush (usb_core_regs *usb_regs) +{ + usb_regs->gr->GRSTCTL = GRSTCTL_RXFF; + + /* wait for RX FIFO flush bit is set */ + while (usb_regs->gr->GRSTCTL & GRSTCTL_RXFF) { + /* no operation */ + } + + /* wait for 3 PHY clocks */ + usb_udelay(3U); + + return USB_OK; +} + +/*! + \brief set endpoint or channel TX FIFO size + \param[in] usb_regs: pointer to USB core registers + \param[in] fifo: TX FIFO number + \param[in] size: assigned TX FIFO size + \param[out] none + \retval none +*/ +void usb_set_txfifo(usb_core_regs *usb_regs, uint8_t fifo, uint16_t size) +{ + uint32_t tx_offset = usb_regs->gr->GRFLEN; + + if (0U == fifo) { + usb_regs->gr->DIEP0TFLEN_HNPTFLEN = ((uint32_t)size << 16U) | tx_offset; + } else { + tx_offset += (usb_regs->gr->DIEP0TFLEN_HNPTFLEN) >> 16U; + + for (uint8_t i = 0U; i < (fifo - 1U); i++) { + tx_offset += (usb_regs->gr->DIEPTFLEN[i] >> 16U); + } + + usb_regs->gr->DIEPTFLEN[fifo - 1U] = ((uint32_t)size << 16U) | tx_offset; + } +} + +/*! + \brief configure USB core to soft reset + \param[in] usb_regs: pointer to USB core registers + \param[out] none + \retval none +*/ +static void usb_core_reset (usb_core_regs *usb_regs) +{ + /* enable core soft reset */ + usb_regs->gr->GRSTCTL |= GRSTCTL_CSRST; + + /* wait for the core to be soft reset */ + while (usb_regs->gr->GRSTCTL & GRSTCTL_CSRST) { + /* no operation */ + } + + /* wait for additional 3 PHY clocks */ + usb_udelay(3U); +} + diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_dev.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_dev.c new file mode 100644 index 0000000000..bec9c4686b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_dev.c @@ -0,0 +1,697 @@ +/*! + \file drv_usb_dev.c + \brief USB device mode low level driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "drv_usb_hw.h" +#include "drv_usb_core.h" +#include "drv_usb_dev.h" + +/* endpoint 0 max packet length */ +static const uint8_t EP0_MAXLEN[4] = { + [DSTAT_EM_HS_PHY_30MHZ_60MHZ] = EP0MPL_64, + [DSTAT_EM_FS_PHY_30MHZ_60MHZ] = EP0MPL_64, + [DSTAT_EM_FS_PHY_48MHZ] = EP0MPL_64, + [DSTAT_EM_LS_PHY_6MHZ] = EP0MPL_8 +}; + +/* USB endpoint Tx FIFO size */ +uint16_t USBHS_TX_FIFO_SIZE[USBHS_MAX_EP_COUNT] = +{ + (uint16_t)TX0_FIFO_SIZE, + (uint16_t)TX1_FIFO_SIZE, + (uint16_t)TX2_FIFO_SIZE, + (uint16_t)TX3_FIFO_SIZE, + (uint16_t)TX4_FIFO_SIZE, + (uint16_t)TX5_FIFO_SIZE, + (uint16_t)TX6_FIFO_SIZE, + (uint16_t)TX7_FIFO_SIZE, +}; + +/*! + \brief initialize USB core registers for device mode + \param[in] udev: pointer to USB device + \param[out] none + \retval operation status +*/ +usb_status usb_devcore_init (usb_core_driver *udev) +{ + uint8_t i; + + /* force to peripheral mode */ + udev->regs.gr->GUSBCS &= ~(GUSBCS_FDM | GUSBCS_FHM); + udev->regs.gr->GUSBCS |= GUSBCS_FDM; + + /* restart the PHY clock (maybe don't need to...) */ + *udev->regs.PWRCLKCTL = 0U; + + /* configure periodic frame interval to default value */ + udev->regs.dr->DCFG &= ~DCFG_EOPFT; + udev->regs.dr->DCFG |= FRAME_INTERVAL_80; + + udev->regs.dr->DCFG &= ~DCFG_DS; + + if (USB_EMBEDDED_PHY_HS == udev->bp.phy_itf) { + udev->regs.dr->DCFG |= USB_SPEED_INP_HIGH; + } else if (USB_EMBEDDED_PHY_FS == udev->bp.phy_itf) { + udev->regs.dr->DCFG |= USB_SPEED_INP_FULL; + } else { + /* no operation */ + } + + /* set RX FIFO size */ + usb_set_rxfifo(&udev->regs, (uint16_t)RX_FIFO_SIZE); + + /* set endpoint 0 to 3's TX FIFO length and RAM address */ + for (i = 0U; i < USBHS_MAX_EP_COUNT; i++) { + usb_set_txfifo(&udev->regs, i, USBHS_TX_FIFO_SIZE[i]); + } + + /* make sure all FIFOs are flushed */ + + /* flush all TX FIFOs */ + (void)usb_txfifo_flush (&udev->regs, 0x10U); + + /* flush entire RX FIFO */ + (void)usb_rxfifo_flush (&udev->regs); + + /* clear all pending device interrupts */ + udev->regs.dr->DIEPINTEN = 0U; + udev->regs.dr->DOEPINTEN = 0U; + udev->regs.dr->DAEPINT = 0xFFFFFFFFU; + udev->regs.dr->DAEPINTEN = 0U; + + /* configure all IN/OUT endpoints */ + for (i = 0U; i < udev->bp.num_ep; i++) { + if (udev->regs.er_in[i]->DIEPCTL & DEPCTL_EPEN) { + udev->regs.er_in[i]->DIEPCTL |= DEPCTL_EPD | DEPCTL_SNAK; + } else { + udev->regs.er_in[i]->DIEPCTL = 0U; + } + + /* set IN endpoint transfer length to 0 */ + udev->regs.er_in[i]->DIEPLEN = 0U; + + /* clear all pending IN endpoint interrupts */ + udev->regs.er_in[i]->DIEPINTF = 0xFFU; + + if (udev->regs.er_out[i]->DOEPCTL & DEPCTL_EPEN) { + udev->regs.er_out[i]->DOEPCTL |= DEPCTL_EPD | DEPCTL_SNAK; + } else { + udev->regs.er_out[i]->DOEPCTL = 0U; + } + + /* set OUT endpoint transfer length to 0 */ + udev->regs.er_out[i]->DOEPLEN = 0U; + + /* clear all pending OUT endpoint interrupts */ + udev->regs.er_out[i]->DOEPINTF = 0xFFU; + } + + udev->regs.dr->DIEPINTEN |= DIEPINTEN_EPTXFUDEN; + + (void)usb_devint_enable (udev); + + /* configure LPM function */ + if(1U == udev->bp.lpm_enable){ + udev->dev.pm.lpm_state = LPM_L0; + udev->regs.gr->GLPMCFG = GLPMCFG_LPMEN | GLPMCFG_ACKLPM | GLPMCFG_BESLEN; + } + + return USB_OK; +} + +/*! + \brief enable the USB device mode interrupts + \param[in] udev: pointer to USB device + \param[out] none + \retval operation status +*/ +usb_status usb_devint_enable (usb_core_driver *udev) +{ + /* clear any pending USB OTG interrupts */ + udev->regs.gr->GOTGINTF = 0xFFFFFFFFU; + + /* clear any pending interrupts */ + udev->regs.gr->GINTF = 0xBFFFFFFFU; + + /* enable the USB wakeup and suspend interrupts */ + udev->regs.gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE; + + /* enable device_mode-related interrupts */ + if ((uint8_t)USB_USE_FIFO == udev->bp.transfer_mode) { + udev->regs.gr->GINTEN |= GINTEN_RXFNEIE; + } + + udev->regs.gr->GINTEN |= GINTEN_RSTIE | GINTEN_ENUMFIE | GINTEN_IEPIE |\ + GINTEN_OEPIE | GINTEN_SOFIE | GINTEN_ISOONCIE | GINTEN_ISOINCIE; + +#ifdef VBUS_SENSING_ENABLED + udev->regs.gr->GINTEN |= GINTEN_SESIE | GINTEN_OTGIE; +#endif /* VBUS_SENSING_ENABLED */ + + if(1U == udev->bp.lpm_enable){ + udev->regs.gr->GINTEN |= GINTEN_LPMIE; + } + + /* enable USB global interrupt */ + udev->regs.gr->GAHBCS |= GAHBCS_GINTEN; + + return USB_OK; +} + +/*! + \brief active the USB endpoint0 transaction + \param[in] udev: pointer to USB device + \param[in] transc: the USB endpoint0 transaction + \param[out] none + \retval operation status +*/ +usb_status usb_transc0_active (usb_core_driver *udev, usb_transc *transc) +{ + __IO uint32_t *reg_addr = NULL; + uint8_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES; + + /* get the endpoint number */ + uint8_t ep_num = transc->ep_addr.num; + + if (ep_num) { + /* not endpoint 0 */ + return USB_FAIL; + } + + if (transc->ep_addr.dir) { + reg_addr = &udev->regs.er_in[0]->DIEPCTL; + } else { + reg_addr = &udev->regs.er_out[0]->DOEPCTL; + } + + /* endpoint 0 is activated after USB clock is enabled */ + + *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM); + + /* set endpoint 0 maximum packet length */ + *reg_addr |= EP0_MAXLEN[enum_speed]; + + /* activate endpoint */ + *reg_addr |= ((uint32_t)transc->ep_type << 18U) | ((uint32_t)ep_num << 22U) | DEPCTL_SD0PID | DEPCTL_EPACT; + + return USB_OK; +} + +/*! + \brief active the USB transaction + \param[in] udev: pointer to USB device + \param[in] transc: the USB transaction + \param[out] none + \retval status +*/ +usb_status usb_transc_active (usb_core_driver *udev, usb_transc *transc) +{ + __IO uint32_t *reg_addr = NULL; + uint32_t epinten = 0U; + uint8_t enum_speed = udev->regs.dr->DSTAT & DSTAT_ES; + + /* get the endpoint number */ + uint8_t ep_num = transc->ep_addr.num; + + /* enable endpoint interrupt number */ + if (transc->ep_addr.dir) { + reg_addr = &udev->regs.er_in[ep_num]->DIEPCTL; + + epinten = 1U << ep_num; + } else { + reg_addr = &udev->regs.er_out[ep_num]->DOEPCTL; + + epinten = 1U << (16U + ep_num); + } + + /* if the endpoint is not active, need change the endpoint control register */ + if (!(*reg_addr & DEPCTL_EPACT)) { + *reg_addr &= ~(DEPCTL_MPL | DEPCTL_EPTYPE | DIEPCTL_TXFNUM); + + /* set endpoint maximum packet length */ + if (0U == ep_num) { + *reg_addr |= EP0_MAXLEN[enum_speed]; + } else { + *reg_addr |= transc->max_len; + } + + /* activate endpoint */ + *reg_addr |= ((uint32_t)transc->ep_type << 18U) | ((uint32_t)ep_num << 22U) | DEPCTL_SD0PID | DEPCTL_EPACT; + } + +#ifdef USB_DEDICATED_EP1_ENABLED + if (1U == ep_num) { + udev->regs.dr->DEP1INTEN |= epinten; + } + else +#endif + { + /* enable the interrupts for this endpoint */ + udev->regs.dr->DAEPINTEN |= epinten; + } + + return USB_OK; +} + +/*! + \brief deactivate the USB transaction + \param[in] udev: pointer to USB device + \param[in] transc: the USB transaction + \param[out] none + \retval status +*/ +usb_status usb_transc_deactivate(usb_core_driver *udev, usb_transc *transc) +{ + uint32_t epinten = 0U; + + uint8_t ep_num = transc->ep_addr.num; + + /* disable endpoint interrupt number */ + if (transc->ep_addr.dir) { + epinten = 1U << ep_num; + + udev->regs.er_in[ep_num]->DIEPCTL &= ~DEPCTL_EPACT; + } else { + epinten = 1U << (ep_num + 16U); + + udev->regs.er_out[ep_num]->DOEPCTL &= ~DEPCTL_EPACT; + } + +#ifdef USB_DEDICATED_EP1_ENABLED + if (1U == ep_num) { + udev->regs.dr->DEP1INTEN &= ~epinten; + } + else +#endif + { + /* disable the interrupts for this endpoint */ + udev->regs.dr->DAEPINTEN &= ~epinten; + } + + return USB_OK; +} + +/*! + \brief configure USB transaction to start IN transfer + \param[in] udev: pointer to USB device + \param[in] transc: the USB IN transaction + \param[out] none + \retval operation status +*/ +usb_status usb_transc_inxfer (usb_core_driver *udev, usb_transc *transc) +{ + usb_status status = USB_OK; + uint8_t ep_num = transc->ep_addr.num; + + uint32_t epctl = udev->regs.er_in[ep_num]->DIEPCTL; + uint32_t eplen = udev->regs.er_in[ep_num]->DIEPLEN; + + eplen &= ~(DEPLEN_TLEN | DEPLEN_PCNT); + + /* zero length packet or endpoint 0 */ + if (0U == transc->xfer_len) { + /* set transfer packet count to 1 */ + eplen |= 1U << 19U; + } else { + /* set transfer packet count */ + if (0U == ep_num) { + transc->xfer_len = USB_MIN(transc->xfer_len, transc->max_len); + + eplen |= 1U << 19U; + } else { + eplen |= (((transc->xfer_len - 1U) + transc->max_len) / transc->max_len) << 19U; + } + + /* set endpoint transfer length */ + eplen |= transc->xfer_len; + + if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type) { + eplen |= DIEPLEN_MCNT & (1U << 29U); + } + } + + udev->regs.er_in[ep_num]->DIEPLEN = eplen; + + if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type) { + if (((udev->regs.dr->DSTAT & DSTAT_FNRSOF) >> 8U) & 0x01U) { + epctl |= DEPCTL_SEVNFRM; + } else { + epctl |= DEPCTL_SODDFRM; + } + } + + if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + udev->regs.er_in[ep_num]->DIEPDMAADDR = transc->dma_addr; + } + + /* enable the endpoint and clear the NAK */ + epctl |= DEPCTL_CNAK | DEPCTL_EPEN; + + udev->regs.er_in[ep_num]->DIEPCTL = epctl; + + if ((uint8_t)USB_USE_FIFO == udev->bp.transfer_mode) { + if (transc->ep_type != (uint8_t)USB_EPTYPE_ISOC) { + /* enable the TX FIFO empty interrupt for this endpoint */ + if (transc->xfer_len > 0U) { + udev->regs.dr->DIEPFEINTEN |= 1U << ep_num; + } + } else { + (void)usb_txfifo_write (&udev->regs, transc->xfer_buf, ep_num, (uint16_t)transc->xfer_len); + } + } + + return status; +} + +/*! + \brief configure USB transaction to start OUT transfer + \param[in] udev: pointer to USB device + \param[in] transc: the USB OUT transaction + \param[out] none + \retval status +*/ +usb_status usb_transc_outxfer (usb_core_driver *udev, usb_transc *transc) +{ + usb_status status = USB_OK; + + __IO uint8_t ep_num = transc->ep_addr.num; + + uint32_t epctl = udev->regs.er_out[ep_num]->DOEPCTL; + uint32_t eplen = udev->regs.er_out[ep_num]->DOEPLEN; + + eplen &= ~(DEPLEN_TLEN | DEPLEN_PCNT); + + /* zero length packet or endpoint 0 */ + if ((0U == transc->xfer_len) || (0U == ep_num)) { + /* set the transfer length to max packet size */ + eplen |= transc->max_len; + + /* set the transfer packet count to 1 */ + eplen |= 1U << 19U; + } else { + /* configure the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + uint32_t packet_count = (transc->xfer_len + transc->max_len - 1U) / transc->max_len; + + eplen |= packet_count << 19U; + eplen |= packet_count * transc->max_len; + } + + udev->regs.er_out[ep_num]->DOEPLEN = eplen; + + if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + udev->regs.er_out[ep_num]->DOEPDMAADDR = transc->dma_addr; + } + + if ((uint8_t)USB_EPTYPE_ISOC == transc->ep_type) { + if (transc->frame_num) { + epctl |= DEPCTL_SD1PID; + } else { + epctl |= DEPCTL_SD0PID; + } + } + + /* enable the endpoint and clear the NAK */ + epctl |= DEPCTL_EPEN | DEPCTL_CNAK; + + udev->regs.er_out[ep_num]->DOEPCTL = epctl; + + return status; +} + +/*! + \brief set the USB transaction STALL status + \param[in] udev: pointer to USB device + \param[in] transc: the USB transaction + \param[out] none + \retval status +*/ +usb_status usb_transc_stall (usb_core_driver *udev, usb_transc *transc) +{ + __IO uint32_t *reg_addr = NULL; + + uint8_t ep_num = transc->ep_addr.num; + + if (transc->ep_addr.dir) { + reg_addr = &(udev->regs.er_in[ep_num]->DIEPCTL); + + /* set the endpoint disable bit */ + if (*reg_addr & DEPCTL_EPEN) { + *reg_addr |= DEPCTL_EPD; + } + } else { + /* set the endpoint stall bit */ + reg_addr = &(udev->regs.er_out[ep_num]->DOEPCTL); + } + + /* set the endpoint stall bit */ + *reg_addr |= DEPCTL_STALL; + + return USB_OK; +} + +/*! + \brief clear the USB transaction STALL status + \param[in] udev: pointer to USB device + \param[in] transc: the USB transaction + \param[out] none + \retval operation status +*/ +usb_status usb_transc_clrstall(usb_core_driver *udev, usb_transc *transc) +{ + __IO uint32_t *reg_addr = NULL; + + uint8_t ep_num = transc->ep_addr.num; + + if (transc->ep_addr.dir) { + reg_addr = &(udev->regs.er_in[ep_num]->DIEPCTL); + } else { + reg_addr = &(udev->regs.er_out[ep_num]->DOEPCTL); + } + + /* clear the endpoint stall bits */ + *reg_addr &= ~DEPCTL_STALL; + + /* reset data PID of the periodic endpoints */ + if (((uint8_t)USB_EPTYPE_INTR == transc->ep_type) || ((uint8_t)USB_EPTYPE_BULK == transc->ep_type)) { + *reg_addr |= DEPCTL_SD0PID; + } + + return USB_OK; +} + +/*! + \brief read device IN endpoint interrupt flag register + \param[in] udev: pointer to USB device + \param[in] ep_num: endpoint number + \param[out] none + \retval interrupt value +*/ +uint32_t usb_iepintr_read (usb_core_driver *udev, uint8_t ep_num) +{ + __IO uint32_t value = 0U; + uint32_t fifoemptymask, commonintmask; + + commonintmask = udev->regs.dr->DIEPINTEN; + fifoemptymask = udev->regs.dr->DIEPFEINTEN; + + /* check FIFO empty interrupt enable bit */ + commonintmask |= ((fifoemptymask >> ep_num) & 0x1U) << 7U; + + value = udev->regs.er_in[ep_num]->DIEPINTF & commonintmask; + + return value; +} + +/*! + \brief configures OUT endpoint 0 to receive SETUP packets + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +void usb_ctlep_startout (usb_core_driver *udev) +{ + /* set OUT endpoint 0 receive length to 24 bytes, 1 packet and 3 setup packets */ + udev->regs.er_out[0]->DOEPLEN = DOEP0_TLEN(8U * 3U) | DOEP0_PCNT(1U) | DOEP0_STPCNT(3U); + + if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + udev->regs.er_out[0]->DOEPDMAADDR = (uint32_t)&udev->dev.control.req; + + /* endpoint enable */ + udev->regs.er_out[0]->DOEPCTL |= DEPCTL_EPACT | DEPCTL_EPEN; + } +} + +/*! + \brief active remote wakeup signaling + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +void usb_rwkup_active (usb_core_driver *udev) +{ + if (udev->dev.pm.dev_remote_wakeup) { + if (udev->regs.dr->DSTAT & DSTAT_SPST) { + if (udev->bp.low_power) { + /* ungate USB core clock */ + *udev->regs.PWRCLKCTL &= ~(PWRCLKCTL_SHCLK | PWRCLKCTL_SUCLK); + } + + /* active remote wakeup signaling */ + udev->regs.dr->DCTL |= DCTL_RWKUP; + + usb_mdelay(5U); + + udev->regs.dr->DCTL &= ~DCTL_RWKUP; + } + } +} + +/*! + \brief active USB core clock + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +void usb_clock_active (usb_core_driver *udev) +{ + if (udev->bp.low_power) { + if (udev->regs.dr->DSTAT & DSTAT_SPST) { + /* un-gate USB Core clock */ + *udev->regs.PWRCLKCTL &= ~(PWRCLKCTL_SHCLK | PWRCLKCTL_SUCLK); + } + } +} + +/*! + \brief USB device suspend + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +void usb_dev_suspend (usb_core_driver *udev) +{ + __IO uint32_t devstat = udev->regs.dr->DSTAT; + + if ((devstat & DSTAT_SPST) && (udev->bp.low_power)) { + /* switch-off the USB clocks */ + *udev->regs.PWRCLKCTL |= PWRCLKCTL_SHCLK; + + /* enter DEEP_SLEEP mode with LDO in low power mode */ + pmu_to_deepsleepmode(WFI_CMD); + } +} + +/*! + \brief stop the device and clean up FIFOs + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +void usb_dev_stop (usb_core_driver *udev) +{ + uint32_t i; + + udev->dev.cur_status = 1U; + + /* clear all interrupt flag and enable bits */ + for (i = 0U; i < udev->bp.num_ep; i++) { + udev->regs.er_in[i]->DIEPINTF = 0xFFU; + udev->regs.er_out[i]->DOEPINTF = 0xFFU; + } + + udev->regs.dr->DIEPINTEN = 0U; + udev->regs.dr->DOEPINTEN = 0U; + udev->regs.dr->DAEPINTEN = 0U; + udev->regs.dr->DAEPINT = 0xFFFFFFFFU; + + /* flush the FIFO */ + (void)usb_rxfifo_flush (&udev->regs); + (void)usb_txfifo_flush (&udev->regs, 0x10U); +} + +/*! + \brief usb battery charging detect operation + \param[in] udev: pointer to USB device instance + \param[out] none + \retval bcd type +*/ +bcd_type usbd_bcd_detect (usb_core_driver *udev) +{ + udev->regs.gr->GCCFG |= GCCFG_DCDEN; + + usb_mdelay(1000); + + if (0U == (udev->regs.gr->GCCFG & GCCFG_DCDF)) { + udev->regs.gr->GCCFG &= ~GCCFG_DCDEN; + + return BCD_ERROR; + } + + udev->regs.gr->GCCFG &= ~GCCFG_DCDEN; + usb_mdelay(20); + udev->regs.gr->GCCFG |= GCCFG_PEMEN; + usb_mdelay(50); + + if (udev->regs.gr->GCCFG & GCCFG_PDF) { + udev->regs.gr->GCCFG &= ~GCCFG_PEMEN; + usb_mdelay(20); + udev->regs.gr->GCCFG |= GCCFG_SDMEN; + usb_mdelay(50); + + if (udev->regs.gr->GCCFG & GCCFG_SDF) { + udev->regs.gr->GCCFG &= ~GCCFG_SDMEN; + usb_mdelay(20); + + return BCD_DCP; + } else { + udev->regs.gr->GCCFG &= ~GCCFG_SDMEN; + usb_mdelay(20); + + return BCD_CDP; + } + } else if (udev->regs.gr->GCCFG & GCCFG_PS2F) { + udev->regs.gr->GCCFG &= ~GCCFG_PEMEN; + usb_mdelay(20); + + return BCD_PS2; + } else { + udev->regs.gr->GCCFG &= ~GCCFG_PEMEN; + usb_mdelay(20); + + return BCD_SDP; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_host.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_host.c new file mode 100644 index 0000000000..e4a8c20f87 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usb_host.c @@ -0,0 +1,451 @@ +/*! + \file drv_usb_host.c + \brief USB host mode low level driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "drv_usb_hw.h" +#include "drv_usb_core.h" +#include "drv_usb_host.h" + +const uint32_t PIPE_DPID[2] = { + PIPE_DPID_DATA0, + PIPE_DPID_DATA1 +}; + +/*! + \brief initializes USB core for host mode + \param[in] udev: pointer to selected USB host + \param[out] none + \retval operation status +*/ +usb_status usb_host_init (usb_core_driver *udev) +{ + uint32_t i = 0U, inten = 0U; + + uint32_t nptxfifolen = 0U; + uint32_t ptxfifolen = 0U; + + udev->regs.gr->GUSBCS &= ~GUSBCS_FDM; + udev->regs.gr->GUSBCS |= GUSBCS_FHM; + + /* restart the PHY Clock */ + *udev->regs.PWRCLKCTL = 0U; + +// usb_port_reset (udev); + + /* support HS, FS and LS */ + udev->regs.hr->HCTL &= ~HCTL_SPDFSLS; + + /* set RX FIFO size */ + udev->regs.gr->GRFLEN = USB_RX_FIFO_SIZE; + + /* set non-periodic TX FIFO size and address */ + nptxfifolen |= USB_RX_FIFO_SIZE; + nptxfifolen |= USB_HTX_NPFIFO_SIZE << 16U; + udev->regs.gr->DIEP0TFLEN_HNPTFLEN = nptxfifolen; + + /* set periodic TX FIFO size and address */ + ptxfifolen |= USB_RX_FIFO_SIZE + USB_HTX_PFIFO_SIZE; + ptxfifolen |= USB_HTX_PFIFO_SIZE << 16U; + udev->regs.gr->HPTFLEN = ptxfifolen; + + +#ifdef USE_OTG_MODE + /* clear host set HNP enable in the usb_otg control register */ + udev->regs.gr->GOTGCS &= ~GOTGCS_HHNPEN; +#endif /* USE_OTG_MODE */ + + /* make sure the FIFOs are flushed */ + + /* flush all TX FIFOs in device or host mode */ + usb_txfifo_flush (&udev->regs, 0x10U); + + /* flush the entire Rx FIFO */ + usb_rxfifo_flush (&udev->regs); + + /* disable all interrupts */ + udev->regs.gr->GINTEN = 0U; + + /* clear any pending USB OTG interrupts */ + udev->regs.gr->GOTGINTF = 0xFFFFFFFFU; + + /* enable the USB wakeup and suspend interrupts */ + udev->regs.gr->GINTF = 0xBFFFFFFFU; + + /* clear all pending host channel interrupts */ + for (i = 0U; i < udev->bp.num_pipe; i++) { + udev->regs.pr[i]->HCHINTF = 0xFFFFFFFFU; + udev->regs.pr[i]->HCHINTEN = 0U; + } + +#ifndef USE_OTG_MODE + usb_portvbus_switch (udev, 1U); +#endif /* USE_OTG_MODE */ + + udev->regs.gr->GINTEN = GINTEN_WKUPIE | GINTEN_SPIE; + + /* enable host_mode-related interrupts */ + if (USB_USE_FIFO == udev->bp.transfer_mode) { + inten = GINTEN_RXFNEIE; + } + + /* configure USBHS interrupts */ + inten |= GINTEN_HPIE | GINTEN_HCIE | GINTEN_ISOINCIE; + udev->regs.gr->GINTEN |= inten; + + inten = GINTEN_DISCIE | GINTEN_SOFIE; + udev->regs.gr->GINTEN &= ~inten; + + udev->regs.gr->GAHBCS |= GAHBCS_GINTEN; + + return USB_OK; +} + +/*! + \brief control the VBUS to power + \param[in] udev: pointer to selected USB host + \param[in] state: VBUS state + \param[out] none + \retval none +*/ +void usb_portvbus_switch (usb_core_driver *udev, uint8_t state) +{ + uint32_t port = 0U; + + /* enable or disable the external charge pump */ + usb_vbus_drive (state); + + /* turn on the host port power. */ + port = usb_port_read (udev); + + if ((!(port & HPCS_PP)) && (1U == state)) { + port |= HPCS_PP; + } + + if ((port & HPCS_PP) && (0U == state)) { + port &= ~HPCS_PP; + } + + *udev->regs.HPCS = port; + + usb_mdelay (200U); +} + +/*! + \brief reset host port + \param[in] udev: pointer to USB device + \param[out] none + \retval operation status +*/ +uint32_t usb_port_reset (usb_core_driver *udev) +{ + __IO uint32_t port = usb_port_read (udev); + + *udev->regs.HPCS = port | HPCS_PRST; + + usb_mdelay(20U); /* see note */ + + *udev->regs.HPCS = port & ~HPCS_PRST; + + usb_mdelay(20U); + + return 1U; +} + +/*! + \brief initialize host pipe + \param[in] udev: pointer to USB device + \param[in] pipe_num: host pipe number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status usb_pipe_init (usb_core_driver *udev, uint8_t pipe_num) +{ + usb_status status = USB_OK; + + __IO uint32_t pp_ctl = 0U; + __IO uint32_t pp_inten = HCHINTEN_TFIE; + + usb_pipe *pp = &udev->host.pipe[pipe_num]; + + /* clear old interrupt conditions for this host channel */ + udev->regs.pr[pipe_num]->HCHINTF = 0xFFFFFFFFU; + + if (USB_USE_DMA == udev->bp.transfer_mode) { + pp_inten |= HCHINTEN_DMAERIE; + } + + if (pp->ep.dir) { + pp_inten |= HCHINTEN_BBERIE; + } + + /* enable channel interrupts required for this transfer */ + switch (pp->ep.type) { + case USB_EPTYPE_CTRL: + case USB_EPTYPE_BULK: + pp_inten |= HCHINTEN_STALLIE | HCHINTEN_USBERIE \ + | HCHINTEN_DTERIE | HCHINTEN_NAKIE; + + if (!pp->ep.dir) { + if (PORT_SPEED_HIGH == pp->dev_speed) { + pp_inten |= HCHINTEN_NYETIE; + pp_inten |= HCHINTEN_ACKIE; + } + } + break; + + case USB_EPTYPE_INTR: + pp_inten |= HCHINTEN_STALLIE | HCHINTEN_USBERIE | HCHINTEN_DTERIE \ + | HCHINTEN_NAKIE | HCHINTEN_REQOVRIE; + break; + + case USB_EPTYPE_ISOC: + pp_inten |= HCHINTEN_REQOVRIE | HCHINTEN_ACKIE; + + if (pp->ep.dir) { + pp_inten |= HCHINTEN_USBERIE; + } + break; + + default: + break; + } + + udev->regs.pr[pipe_num]->HCHINTEN = pp_inten; + + /* enable the top level host channel interrupt */ + udev->regs.hr->HACHINTEN |= 1U << pipe_num; + + /* make sure host channel interrupts are enabled */ + udev->regs.gr->GINTEN |= GINTEN_HCIE; + + /* program the host channel control register */ + pp_ctl |= PIPE_CTL_DAR(pp->dev_addr); + pp_ctl |= PIPE_CTL_EPNUM(pp->ep.num); + pp_ctl |= PIPE_CTL_EPDIR(pp->ep.dir); + pp_ctl |= PIPE_CTL_EPTYPE(pp->ep.type); + pp_ctl |= PIPE_CTL_LSD(pp->dev_speed == PORT_SPEED_LOW); + + pp_ctl |= pp->ep.mps; + pp_ctl |= ((uint32_t)(pp->ep.type == USB_EPTYPE_INTR) << 29U) & HCHCTL_ODDFRM; + + udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; + + return status; +} + +/*! + \brief prepare host channel for transferring packets + \param[in] udev: pointer to USB device + \param[in] pipe_num: host pipe number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status usb_pipe_xfer (usb_core_driver *udev, uint8_t pipe_num) +{ + usb_status status = USB_OK; + + uint16_t dword_len = 0U; + uint16_t packet_count = 0U; + + __IO uint32_t pp_ctl = 0U; + + usb_pipe *pp = &udev->host.pipe[pipe_num]; + + uint16_t max_packet_len = pp->ep.mps; + + /* compute the expected number of packets associated to the transfer */ + if (pp->xfer_len > 0U) { + packet_count = (uint16_t)((pp->xfer_len + max_packet_len - 1U) / max_packet_len); + + if (packet_count > HC_MAX_PACKET_COUNT) { + packet_count = HC_MAX_PACKET_COUNT; + pp->xfer_len = (uint16_t)(packet_count * max_packet_len); + } + } else { + packet_count = 1U; + } + + if (pp->ep.dir) { + pp->xfer_len = (uint16_t)(packet_count * max_packet_len); + } + + /* initialize the host channel transfer information */ + udev->regs.pr[pipe_num]->HCHLEN = pp->xfer_len | pp->DPID | PIPE_XFER_PCNT(packet_count); + + if (USB_USE_DMA == udev->bp.transfer_mode) { + udev->regs.pr[pipe_num]->HCHDMAADDR = (unsigned int)pp->xfer_buf; + } + + pp_ctl = udev->regs.pr[pipe_num]->HCHCTL; + + if (usb_frame_even(udev)) { + pp_ctl |= HCHCTL_ODDFRM; + } else { + pp_ctl &= ~HCHCTL_ODDFRM; + } + + /* set host channel enabled */ + pp_ctl |= HCHCTL_CEN; + pp_ctl &= ~HCHCTL_CDIS; + + udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; + + if (USB_USE_FIFO == udev->bp.transfer_mode) { + if ((0U == pp->ep.dir) && (pp->xfer_len > 0U)) { + switch (pp->ep.type) { + /* non-periodic transfer */ + case USB_EPTYPE_CTRL: + case USB_EPTYPE_BULK: + dword_len = (uint16_t)((pp->xfer_len + 3U) / 4U); + + /* check if there is enough space in FIFO space */ + if (dword_len > (udev->regs.gr->HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) { + /* need to process data in nptxfempty interrupt */ + udev->regs.gr->GINTEN |= GINTEN_NPTXFEIE; + } + break; + + /* periodic transfer */ + case USB_EPTYPE_INTR: + case USB_EPTYPE_ISOC: + dword_len = (uint16_t)((pp->xfer_len + 3U) / 4U); + + /* check if there is enough space in FIFO space */ + if (dword_len > (udev->regs.hr->HPTFQSTAT & HPTFQSTAT_PTXFS)) { + /* need to process data in ptxfempty interrupt */ + udev->regs.gr->GINTEN |= GINTEN_PTXFEIE; + } + break; + + default: + break; + } + + /* write packet into the TX FIFO. */ + usb_txfifo_write (&udev->regs, pp->xfer_buf, pipe_num, (uint16_t)pp->xfer_len); + } + } + + return status; +} + +/*! + \brief halt pipe + \param[in] udev: pointer to USB device + \param[in] pipe_num: host pipe number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status usb_pipe_halt (usb_core_driver *udev, uint8_t pipe_num) +{ + __IO uint32_t pp_ctl = udev->regs.pr[pipe_num]->HCHCTL; + + uint8_t ep_type = (uint8_t)((pp_ctl & HCHCTL_EPTYPE) >> 18U); + + pp_ctl |= HCHCTL_CEN | HCHCTL_CDIS; + + switch (ep_type) { + case USB_EPTYPE_CTRL: + case USB_EPTYPE_BULK: + if (0U == (udev->regs.gr->HNPTFQSTAT & HNPTFQSTAT_NPTXFS)) { + pp_ctl &= ~HCHCTL_CEN; + } + break; + + case USB_EPTYPE_INTR: + case USB_EPTYPE_ISOC: + if (0U == (udev->regs.hr->HPTFQSTAT & HPTFQSTAT_PTXFS)) { + pp_ctl &= ~HCHCTL_CEN; + } + break; + + default: + break; + } + + udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; + + return USB_OK; +} + +/*! + \brief configure host pipe to do ping operation + \param[in] udev: pointer to USB device + \param[in] pipe_num: host pipe number which is in (0..7) + \param[out] none + \retval operation status +*/ +usb_status usb_pipe_ping (usb_core_driver *udev, uint8_t pipe_num) +{ + uint32_t pp_ctl = 0U; + + udev->regs.pr[pipe_num]->HCHLEN = HCHLEN_PING; + + pp_ctl = udev->regs.pr[pipe_num]->HCHCTL; + + pp_ctl |= HCHCTL_CEN; + pp_ctl &= ~HCHCTL_CDIS; + + udev->regs.pr[pipe_num]->HCHCTL = pp_ctl; + + return USB_OK; +} + +/*! + \brief stop the USB host and clean up FIFO + \param[in] udev: pointer to USB device + \param[out] none + \retval none +*/ +void usb_host_stop (usb_core_driver *udev) +{ + uint32_t i; + __IO uint32_t pp_ctl = 0U; + + udev->regs.hr->HACHINTEN = 0x0U; + udev->regs.hr->HACHINT = 0xFFFFFFFFU; + + /* flush out any leftover queued requests. */ + for (i = 0U; i < udev->bp.num_pipe; i++) { + pp_ctl = udev->regs.pr[i]->HCHCTL; + + pp_ctl &= ~(HCHCTL_CEN | HCHCTL_EPDIR); + pp_ctl |= HCHCTL_CDIS; + + udev->regs.pr[i]->HCHCTL = pp_ctl; + } + + /* flush the FIFO */ + usb_rxfifo_flush (&udev->regs); + usb_txfifo_flush (&udev->regs, 0x10U); +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbd_int.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbd_int.c new file mode 100644 index 0000000000..0649021ee9 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbd_int.c @@ -0,0 +1,692 @@ +/*! + \file drv_usbd_int.c + \brief USB device mode interrupt routines + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbd_conf.h" +#include "drv_usbd_int.h" +#include "usbd_transc.h" +#include "drv_usb_hw.h" + +/* local function prototypes ('static') */ +static uint32_t usbd_int_epout (usb_core_driver *udev); +static uint32_t usbd_int_epin (usb_core_driver *udev); +static uint32_t usbd_int_rxfifo (usb_core_driver *udev); +static uint32_t usbd_int_reset (usb_core_driver *udev); +static uint32_t usbd_int_enumfinish (usb_core_driver *udev); +static uint32_t usbd_int_suspend (usb_core_driver *udev); +static uint32_t usbd_int_wakeup (usb_core_driver *udev); +#if (1U == LPM_ENABLED) +static uint32_t usbd_int_lpm (usb_core_driver *udev, usb_lpm_type active_type); +#endif /* LPM_ENABLED */ +static uint32_t usbd_emptytxfifo_write (usb_core_driver *udev, uint32_t ep_num); + +static const uint8_t USB_SPEED[4] = { + [DSTAT_EM_HS_PHY_30MHZ_60MHZ] = (uint8_t)USB_SPEED_HIGH, + [DSTAT_EM_FS_PHY_30MHZ_60MHZ] = (uint8_t)USB_SPEED_FULL, + [DSTAT_EM_FS_PHY_48MHZ] = (uint8_t)USB_SPEED_FULL, + [DSTAT_EM_LS_PHY_6MHZ] = (uint8_t)USB_SPEED_LOW +}; + +#ifdef USB_DEDICATED_EP1_ENABLED + +/*! + \brief USB dedicated OUT endpoint 1 interrupt service routine handler + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +uint32_t usbd_int_dedicated_ep1out (usb_core_driver *udev) +{ + uint32_t oepintr = 0U; + uint32_t oeplen = 0U; + + oepintr = udev->regs.er_out[1]->DOEPINTF; + oepintr &= udev->regs.dr->DOEP1INTEN; + + /* transfer complete */ + if (oepintr & DOEPINTF_TF) { + /* clear the bit in DOEPINTn for this interrupt */ + udev->regs.er_out[1]->DOEPINTF = DOEPINTF_TF; + + if (USB_USE_DMA == udev->bp.transfer_mode) { + oeplen = udev->regs.er_out[1]->DOEPLEN; + + /* ToDo : handle more than one single MPS size packet */ + udev->dev.transc_out[1].xfer_count = udev->dev.transc_out[1].max_len - \ + (oeplen & DEPLEN_TLEN); + } + + /* RX COMPLETE */ + usbd_out_transc (udev, 1U); + } + + return 1U; +} + +/*! + \brief USB dedicated IN endpoint 1 interrupt service routine handler + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +uint32_t usbd_int_dedicated_ep1in (usb_core_driver *udev) +{ + uint32_t inten, intr, emptyen; + + inten = udev->regs.dr->DIEP1INTEN; + emptyen = udev->regs.dr->DIEPFEINTEN; + + inten |= ((emptyen >> 1U ) & 0x1U) << 7U; + + intr = udev->regs.er_in[1]->DIEPINTF & inten; + + if (intr & DIEPINTF_TF) { + udev->regs.dr->DIEPFEINTEN &= ~(0x1U << 1U); + + udev->regs.er_in[1]->DIEPINTF = DIEPINTF_TF; + + /* TX COMPLETE */ + usbd_in_transc (udev, 1U); + } + + if (intr & DIEPINTF_TXFE) { + usbd_emptytxfifo_write(udev, 1U); + + udev->regs.er_in[1]->DIEPINTF = DIEPINTF_TXFE; + } + + return 1U; +} + +#endif + +/*! + \brief USB device-mode interrupts global service routine handler + \param[in] udev: pointer to USB device instance + \param[out] none + \retval none +*/ +void usbd_isr (usb_core_driver *udev) +{ + if (HOST_MODE != (udev->regs.gr->GINTF & GINTF_COPM)) { + uint32_t intr = udev->regs.gr->GINTF; + intr &= udev->regs.gr->GINTEN; + + /* there are no interrupts, avoid spurious interrupt */ + if (!intr) { + return; + } + + /* OUT endpoints interrupts */ + if (intr & GINTF_OEPIF) { + (void)usbd_int_epout (udev); + } + + /* IN endpoints interrupts */ + if (intr & GINTF_IEPIF) { + (void)usbd_int_epin (udev); + } + + /* suspend interrupt */ + if (intr & GINTF_SP) { + (void)usbd_int_suspend (udev); + } + + /* wakeup interrupt */ + if (intr & GINTF_WKUPIF) { + (void)usbd_int_wakeup (udev); + } + + /* start of frame interrupt */ + if (intr & GINTF_SOF) { + if (udev->dev.class_core->SOF) { + (void)udev->dev.class_core->SOF(udev); + } + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_SOF; + } + + /* receive FIFO not empty interrupt */ + if (intr & GINTF_RXFNEIF) { + (void)usbd_int_rxfifo (udev); + } + + /* USB reset interrupt */ + if (intr & GINTF_RST) { + (void)usbd_int_reset (udev); + } + + /* enumeration has been done interrupt */ + if (intr & GINTF_ENUMFIF) { + (void)usbd_int_enumfinish (udev); + } + + /* incomplete synchronization IN transfer interrupt*/ + if (intr & GINTF_ISOINCIF) { + if (NULL != udev->dev.class_core->incomplete_isoc_in) { + (void)udev->dev.class_core->incomplete_isoc_in(udev); + } + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_ISOINCIF; + } + + /* incomplete synchronization OUT transfer interrupt*/ + if (intr & GINTF_ISOONCIF) { + if (NULL != udev->dev.class_core->incomplete_isoc_out) { + (void)udev->dev.class_core->incomplete_isoc_out(udev); + } + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_ISOONCIF; + } + +#if (1U == LPM_ENABLED) + if(intr & GINTF_LPMIF) { + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_LPMIF; + + udev->dev.pm.BESL = (udev->regs.gr->GLPMCFG & GLPMCFG_BESL) >> 2U; + udev->dev.pm.dev_remote_wakeup = (udev->regs.gr->GLPMCFG & GLPMCFG_REW) >> 6U; + + if(LPM_L0 == udev->dev.pm.lpm_state){ + udev->dev.pm.lpm_state = LPM_L1; + usbd_int_lpm(udev, LPM_L1_ACTIVE); + }else{ + udev->dev.pm.lpm_state = LPM_L0; + usbd_int_lpm(udev, LPM_L0_ACTIVE); + } + } +#endif /* LPM_ENABLED */ + +#ifdef VBUS_SENSING_ENABLED + + /* session request interrupt */ + if (intr & GINTF_SESIF) { + udev->regs.gr->GINTF = GINTF_SESIF; + } + + /* OTG mode interrupt */ + if (intr & GINTF_OTGIF) { + if(udev->regs.gr->GOTGINTF & GOTGINTF_SESEND) { + + } + + /* clear OTG interrupt */ + udev->regs.gr->GINTF = GINTF_OTGIF; + } +#endif /* VBUS_SENSING_ENABLED */ + } +} + +/*! + \brief indicates that an OUT endpoint has a pending interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_int_epout (usb_core_driver *udev) +{ + uint32_t epintnum = 0U; + uint8_t ep_num = 0U; + + for (epintnum = usb_oepintnum_read (udev); epintnum; epintnum >>= 1U) { + if (epintnum & 0x01U) { + __IO uint32_t oepintr = usb_oepintr_read (udev, ep_num); + + /* transfer complete interrupt */ + if (oepintr & DOEPINTF_TF) { + /* clear the bit in DOEPINTF for this interrupt */ + udev->regs.er_out[ep_num]->DOEPINTF = DOEPINTF_TF; + + if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + __IO uint32_t eplen = udev->regs.er_out[ep_num]->DOEPLEN; + + udev->dev.transc_out[ep_num].xfer_count = udev->dev.transc_out[ep_num].max_len - \ + (eplen & DEPLEN_TLEN); + } + + /* inform upper layer: data ready */ + (void)usbd_out_transc (udev, ep_num); + + if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + if ((0U == ep_num) && ((uint8_t)USB_CTL_STATUS_OUT == udev->dev.control.ctl_state)) { + usb_ctlep_startout (udev); + } + } + } + + /* setup phase finished interrupt (control endpoints) */ + if (oepintr & DOEPINTF_STPF) { + /* inform the upper layer that a setup packet is available */ + (void)usbd_setup_transc (udev); + + udev->regs.er_out[ep_num]->DOEPINTF = DOEPINTF_STPF; + } + } + + ep_num++; + } + + return 1U; +} + +/*! + \brief indicates that an IN endpoint has a pending interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_int_epin (usb_core_driver *udev) +{ + uint32_t epintnum = 0U; + uint8_t ep_num = 0U; + + for (epintnum = usb_iepintnum_read (udev); epintnum; epintnum >>= 1U) { + if (epintnum & 0x1U) { + __IO uint32_t iepintr = usb_iepintr_read (udev, ep_num); + + if (iepintr & DIEPINTF_TF) { + udev->regs.er_in[ep_num]->DIEPINTF = DIEPINTF_TF; + + /* data transmission is completed */ + (void)usbd_in_transc (udev, ep_num); + + if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + if ((0U == ep_num) && ((uint8_t)USB_CTL_STATUS_IN == udev->dev.control.ctl_state)) { + usb_ctlep_startout (udev); + } + } + } + + if (iepintr & DIEPINTF_TXFE) { + usbd_emptytxfifo_write (udev, (uint32_t)ep_num); + + udev->regs.er_in[ep_num]->DIEPINTF = DIEPINTF_TXFE; + } + } + + ep_num++; + } + + return 1U; +} + +/*! + \brief handle the RX status queue level interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_int_rxfifo (usb_core_driver *udev) +{ + usb_transc *transc = NULL; + + uint8_t data_PID = 0U; + uint32_t bcount = 0U; + + __IO uint32_t devrxstat = 0U; + + /* disable the Rx status queue non-empty interrupt */ + udev->regs.gr->GINTEN &= ~GINTEN_RXFNEIE; + + /* get the status from the top of the FIFO */ + devrxstat = udev->regs.gr->GRSTATP; + + uint8_t ep_num = (uint8_t)(devrxstat & GRSTATRP_EPNUM); + + transc = &udev->dev.transc_out[ep_num]; + + bcount = (devrxstat & GRSTATRP_BCOUNT) >> 4U; + data_PID = (uint8_t)((devrxstat & GRSTATRP_DPID) >> 15U); + + switch ((devrxstat & GRSTATRP_RPCKST) >> 17U) { + case RSTAT_GOUT_NAK: + break; + + case RSTAT_DATA_UPDT: + if (bcount > 0U) { + (void)usb_rxfifo_read (&udev->regs, transc->xfer_buf, (uint16_t)bcount); + + transc->xfer_buf += bcount; + transc->xfer_count += bcount; + } + break; + + case RSTAT_XFER_COMP: + /* trigger the OUT endpoint interrupt */ + break; + + case RSTAT_SETUP_COMP: + /* trigger the OUT endpoint interrupt */ + break; + + case RSTAT_SETUP_UPDT: + if ((0U == transc->ep_addr.num) && (8U == bcount) && (DPID_DATA0 == data_PID)) { + /* copy the setup packet received in FIFO into the setup buffer in RAM */ + (void)usb_rxfifo_read (&udev->regs, (uint8_t *)&udev->dev.control.req, (uint16_t)bcount); + + transc->xfer_count += bcount; + } + break; + + default: + break; + } + + /* enable the Rx status queue level interrupt */ + udev->regs.gr->GINTEN |= GINTEN_RXFNEIE; + + return 1U; +} + +/*! + \brief handle USB reset interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_int_reset (usb_core_driver *udev) +{ + uint32_t i; + + /* clear the remote wakeup signaling */ + udev->regs.dr->DCTL &= ~DCTL_RWKUP; + + /* flush the TX FIFO */ + (void)usb_txfifo_flush (&udev->regs, 0U); + + for (i = 0U; i < udev->bp.num_ep; i++) { + udev->regs.er_in[i]->DIEPINTF = 0xFFU; + udev->regs.er_out[i]->DOEPINTF = 0xFFU; + } + + /* clear all pending device endpoint interrupts */ + udev->regs.dr->DAEPINT = 0xFFFFFFFFU; + + /* enable endpoint 0 interrupts */ + udev->regs.dr->DAEPINTEN = 1U | (1U << 16U); + + /* enable OUT endpoint interrupts */ + udev->regs.dr->DOEPINTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN; + +#ifdef USB_DEDICATED_EP1_ENABLED + udev->regs.dr->DOEP1INTEN = DOEPINTEN_STPFEN | DOEPINTEN_TFEN; +#endif + + /* enable IN endpoint interrupts */ + udev->regs.dr->DIEPINTEN = DIEPINTEN_TFEN; + +#ifdef USB_DEDICATED_EP1_ENABLED + udev->regs.dr->DIEP1INTEN = DIEPINTEN_TFEN; +#endif + + /* reset device address */ + udev->regs.dr->DCFG &= ~DCFG_DAR; + + /* configure endpoint 0 to receive SETUP packets */ + usb_ctlep_startout (udev); + + /* clear USB reset interrupt */ + udev->regs.gr->GINTF = GINTF_RST; + + udev->dev.transc_out[0] = (usb_transc) { + .ep_type = USB_EPTYPE_CTRL, + .max_len = USB_FS_EP0_MAX_LEN + }; + + (void)usb_transc_active (udev, &udev->dev.transc_out[0]); + + udev->dev.transc_in[0] = (usb_transc) { + .ep_addr = { + .dir = 1U + }, + + .ep_type = USB_EPTYPE_CTRL, + .max_len = USB_FS_EP0_MAX_LEN + }; + + (void)usb_transc_active (udev, &udev->dev.transc_in[0]); + + /* upon reset call user call back */ + udev->dev.cur_status = (uint8_t)USBD_DEFAULT; + + return 1U; +} + +/*! + \brief handle USB speed enumeration finish interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval status +*/ +static uint32_t usbd_int_enumfinish (usb_core_driver *udev) +{ + uint8_t enum_speed = (uint8_t)((udev->regs.dr->DSTAT & DSTAT_ES) >> 1U); + + udev->regs.dr->DCTL &= ~DCTL_CGINAK; + udev->regs.dr->DCTL |= DCTL_CGINAK; + + udev->regs.gr->GUSBCS &= ~GUSBCS_UTT; + + /* set USB turn-around time based on device speed and PHY interface */ + if ((uint8_t)USB_SPEED_HIGH == USB_SPEED[enum_speed]) { + udev->bp.core_speed = (uint8_t)USB_SPEED_HIGH; + + udev->regs.gr->GUSBCS |= 0x09U << 10U; + } else { + udev->bp.core_speed = (uint8_t)USB_SPEED_FULL; + + udev->regs.gr->GUSBCS |= 0x05U << 10U; + } + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_ENUMFIF; + + return 1U; +} + +/*! + \brief USB suspend interrupt handler + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_int_suspend (usb_core_driver *udev) +{ + __IO uint8_t low_power = udev->bp.low_power; + __IO uint8_t suspend = (uint8_t)(udev->regs.dr->DSTAT & DSTAT_SPST); + __IO uint8_t is_configured = (udev->dev.cur_status == (uint8_t)USBD_CONFIGURED)? 1U : 0U; + + udev->dev.backup_status = udev->dev.cur_status; + udev->dev.cur_status = (uint8_t)USBD_SUSPENDED; + + if (low_power && suspend && is_configured) { + /* switch-off the OTG clocks */ + *udev->regs.PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK; + + /* enter DEEP_SLEEP mode with LDO in low power mode */ + pmu_to_deepsleepmode(WFI_CMD); + } + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_SP; + + return 1U; +} + +/*! + \brief USB wakeup interrupt handler + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbd_int_wakeup(usb_core_driver *udev) +{ + __IO uint8_t low_power = udev->bp.low_power; + __IO uint8_t remote_wakeup = udev->dev.pm.dev_remote_wakeup; + +#if (1U == LPM_ENABLED) + if(LPM_L1 == udev->dev.pm.lpm_state){ + udev->dev.pm.lpm_state = LPM_L0; + usbd_int_lpm(udev, LPM_L0_ACTIVE); + }else +#endif /* LPM_ENABLED */ + { + if(remote_wakeup && low_power){ + /* resume MCU CLK */ + + /* reset SLEEPDEEP bit of Cortex-M33 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + } + + usb_clock_active(udev); + + if (USBD_SUSPENDED == udev->dev.cur_status) { + /* inform upper layer by the resume event */ + udev->dev.cur_status = udev->dev.backup_status; + } + + udev->dev.cur_status = USBD_CONFIGURED; + } + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_WKUPIF; + + return 1U; +} + +#if (1U == LPM_ENABLED) + +/*! + \brief USB LPM interrupt handler + \param[in] udev: pointer to USB device instance + \param[in] active_type: active type + only one parameter can be selected which is shown as below: + \arg LPM_L0_ACTIVE: select L0 to active + \arg LPM_L1_ACTIVE: select L1 to active + \param[out] none + \retval operation status +*/ +static uint32_t usbd_int_lpm (usb_core_driver *udev, usb_lpm_type active_type) +{ + __IO uint8_t low_power = udev->bp.low_power; + __IO uint8_t suspend = (uint8_t)(udev->regs.dr->DSTAT & DSTAT_SPST); + __IO uint8_t is_configured = (udev->dev.cur_status == (uint8_t)USBD_CONFIGURED)? 1U : 0U; + + switch(active_type){ + case LPM_L0_ACTIVE: + udev->dev.cur_status = udev->dev.backup_status; + + /* switch-on the OTG clocks */ + usb_clock_active(udev); + + if(low_power){ + /* resume MCU CLK */ + + /* reset SLEEPDEEP bit of Cortex-M7 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + } + break; + + case LPM_L1_ACTIVE: + udev->dev.backup_status = udev->dev.cur_status; + udev->dev.cur_status = (uint8_t)USBD_SUSPENDED; + + /* add delay */ + usb_mdelay(300); + + /* switch-off the OTG clocks */ + *udev->regs.PWRCLKCTL |= PWRCLKCTL_SUCLK | PWRCLKCTL_SHCLK; + + if(low_power){ + /* enter DEEP_SLEEP mode with LDO in low power mode */ + pmu_to_deepsleepmode(WFI_CMD); + } + break; + } + + return 1U; +} + +#endif /* LPM_ENABLED */ + +/*! + \brief check FIFO for the next packet to be loaded + \param[in] udev: pointer to USB device instance + \param[in] ep_num: endpoint identifier which is in (0..5) + \param[out] none + \retval status +*/ +static uint32_t usbd_emptytxfifo_write (usb_core_driver *udev, uint32_t ep_num) +{ + uint32_t len; + uint32_t word_count; + + usb_transc *transc = &udev->dev.transc_in[ep_num]; + + len = transc->xfer_len - transc->xfer_count; + + /* get the data length to write */ + if (len > transc->max_len) { + len = transc->max_len; + } + + word_count = (len + 3U) / 4U; + + while (((udev->regs.er_in[ep_num]->DIEPTFSTAT & DIEPTFSTAT_IEPTFS) >= word_count) && \ + (transc->xfer_count < transc->xfer_len)) { + len = transc->xfer_len - transc->xfer_count; + + if (len > transc->max_len) { + len = transc->max_len; + } + + /* write FIFO in word(4bytes) */ + word_count = (len + 3U) / 4U; + + /* write the FIFO */ + (void)usb_txfifo_write (&udev->regs, transc->xfer_buf, (uint8_t)ep_num, (uint16_t)len); + + transc->xfer_buf += len; + transc->xfer_count += len; + + if (transc->xfer_count == transc->xfer_len) { + /* disable the device endpoint FIFO empty interrupt */ + udev->regs.dr->DIEPFEINTEN &= ~(0x01U << ep_num); + } + } + + return 1U; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbh_int.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbh_int.c new file mode 100644 index 0000000000..b5c9cff232 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/driver/Source/drv_usbh_int.c @@ -0,0 +1,617 @@ +/*! + \file drv_usbh_int.c + \brief USB host mode interrupt handler file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "drv_usbh_int.h" + +#if defined (__CC_ARM) /*!< ARM compiler */ + #pragma O0 +#elif defined (__GNUC__) /*!< GNU compiler */ + #pragma GCC optimize ("O0") +#elif defined (__TASKING__) /*!< TASKING compiler */ + #pragma optimize=0 +#endif /* __CC_ARM */ + +/* local function prototypes ('static') */ +static uint32_t usbh_int_port (usb_core_driver *udev); +static uint32_t usbh_int_pipe (usb_core_driver *udev); +static uint32_t usbh_int_pipe_in (usb_core_driver *udev, uint32_t pp_num); +static uint32_t usbh_int_pipe_out (usb_core_driver *udev, uint32_t pp_num); +static uint32_t usbh_int_rxfifonoempty (usb_core_driver *udev); +static uint32_t usbh_int_txfifoempty (usb_core_driver *udev, usb_pipe_mode pp_mode); + +/*! + \brief handle global host interrupt + \param[in] udev: pointer to USB core instance + \param[out] none + \retval operation status +*/ +uint32_t usbh_isr (usb_core_driver *udev) +{ + uint32_t retval = 0U; + + __IO uint32_t intr = 0U; + + /* check if host mode */ + if (HOST_MODE == (udev->regs.gr->GINTF & GINTF_COPM)) { + intr = usb_coreintr_get(&udev->regs); + + if (!intr) { + return 0U; + } + + if (intr & GINTF_SOF) { + usbh_int_fop->SOF(udev->host.data); + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_SOF; + } + + if (intr & GINTF_RXFNEIF) { + retval |= usbh_int_rxfifonoempty (udev); + } + + if (intr & GINTF_NPTXFEIF) { + retval |= usbh_int_txfifoempty (udev, PIPE_NON_PERIOD); + } + + if (intr & GINTF_PTXFEIF) { + retval |= usbh_int_txfifoempty (udev, PIPE_PERIOD); + } + + if (intr & GINTF_HCIF) { + retval |= usbh_int_pipe (udev); + } + + if (intr & GINTF_HPIF) { + retval |= usbh_int_port (udev); + } + + if (intr & GINTF_DISCIF) { + usbh_int_fop->disconnect(udev->host.data); + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_DISCIF; + } + + if (intr & GINTF_ISOONCIF) { + udev->regs.pr[0]->HCHCTL |= HCHCTL_CEN | HCHCTL_CDIS; + + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_ISOONCIF; + } + + if (intr & GINTF_WKUPIF) { + /* clear interrupt */ + udev->regs.gr->GINTF = GINTF_WKUPIF; + } + } + + return retval; +} + +/*! + \brief handle USB pipe halt + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pp_num: host channel number which is in (0..7) + \param[in] pp_int: pipe interrupt + \param[in] pp_status: pipe status + \param[out] none + \retval none +*/ +static inline void usb_pp_halt (usb_core_driver *udev, + uint8_t pp_num, + uint32_t pp_int, + usb_pipe_staus pp_status) +{ + udev->regs.pr[pp_num]->HCHINTEN |= HCHINTEN_CHIE; + + usb_pipe_halt(udev, pp_num); + + udev->regs.pr[pp_num]->HCHINTF = pp_int; + + udev->host.pipe[pp_num].pp_status = pp_status; +} + +/*! + \brief handle the host port interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +#if defined (__ICCARM__) /*!< IAR compiler */ + #pragma optimize = none +#endif /* __ICCARM */ +static uint32_t usbh_int_port (usb_core_driver *udev) +{ + uint32_t retval = 0U; + + __IO uint32_t port_state = *udev->regs.HPCS; + + __IO uint32_t port_reset = 0U; + + /* clear the interrupt bits in GINTSTS */ + port_state &= ~(HPCS_PE | HPCS_PCD | HPCS_PEDC); + + /* port connect detected */ + if (*udev->regs.HPCS & HPCS_PCD) { + port_state |= HPCS_PCD; + + usbh_int_fop->connect(udev->host.data); + + retval |= 1U; + } + + /* port enable changed */ + if (*udev->regs.HPCS & HPCS_PEDC) { + port_state |= HPCS_PEDC; + + if (*udev->regs.HPCS & HPCS_PE) { + uint32_t port_speed = usb_curspeed_get(udev); + + udev->host.connect_status = 1U; + + if (PORT_SPEED_LOW == port_speed) { + udev->regs.hr->HFT = 6000U; + } else if (PORT_SPEED_FULL == port_speed) { + udev->regs.hr->HFT = 48000U; + } else { + } + + port_reset = 1U; + + usbh_int_fop->port_enabled(udev->host.data); + + udev->regs.gr->GINTEN |= GINTEN_DISCIE | GINTEN_SOFIE; + } else { + usbh_int_fop->port_disabled(udev->host.data); + } + } + + if (1U == port_reset) { + usb_port_reset(udev); + } + + /* clear port interrupts */ + *udev->regs.HPCS = port_state; + + return retval; +} + +/*! + \brief handle all host channels interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +static uint32_t usbh_int_pipe (usb_core_driver *udev) +{ + uint32_t pp_num = 0U; + uint32_t retval = 0U; + + for (pp_num = 0U; pp_num < udev->bp.num_pipe; pp_num++) { + if ((udev->regs.hr->HACHINT & HACHINT_HACHINT) & (1U << pp_num)) { + if (udev->regs.pr[pp_num]->HCHCTL & HCHCTL_EPDIR) { + retval |= usbh_int_pipe_in (udev, pp_num); + } else { + retval |= usbh_int_pipe_out (udev, pp_num); + } + } + } + + return retval; +} + +/*! + \brief handle the IN channel interrupt + \param[in] udev: pointer to USB device instance + \param[in] pp_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +#if defined (__ICCARM__) /*!< IAR compiler */ + #pragma optimize = none +#endif /* __ICCARM */ +static uint32_t usbh_int_pipe_in (usb_core_driver *udev, uint32_t pp_num) +{ + usb_pr *pp_reg = udev->regs.pr[pp_num]; + + usb_pipe *pp = &udev->host.pipe[pp_num]; + + uint32_t intr_pp = pp_reg->HCHINTF; + intr_pp &= pp_reg->HCHINTEN; + + uint8_t ep_type = (uint8_t)((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18U); + + if (intr_pp & HCHINTF_ACK) { + pp_reg->HCHINTF = HCHINTF_ACK; + } else if (intr_pp & HCHINTF_STALL) { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_STALL, PIPE_STALL); + pp_reg->HCHINTF = HCHINTF_NAK; + + /* note: When there is a 'STALL', reset also NAK, + else, the udev->host.pp_status = HC_STALL + will be overwritten by 'NAK' in code below */ + intr_pp &= ~HCHINTF_NAK; + } else if (intr_pp & HCHINTF_DTER) { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_DTER, PIPE_DTGERR); + pp_reg->HCHINTF = HCHINTF_NAK; + } else { + /* no operation */ + } + + if (intr_pp & HCHINTF_REQOVR) { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_REQOVR, PIPE_REQOVR); + } else if (intr_pp & HCHINTF_TF) { + if ((uint8_t)USB_USE_DMA == udev->bp.transfer_mode) { + udev->host.backup_xfercount[pp_num] = pp->xfer_len - (pp_reg->HCHLEN & HCHLEN_TLEN); + } + + pp->pp_status = PIPE_XF; + pp->err_count = 0U; + + pp_reg->HCHINTF = HCHINTF_TF; + + switch (ep_type) { + case USB_EPTYPE_CTRL: + case USB_EPTYPE_BULK: + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_XF); + + pp->data_toggle_in ^= 1U; + break; + + case USB_EPTYPE_INTR: + case USB_EPTYPE_ISOC: + pp_reg->HCHCTL |= HCHCTL_ODDFRM; + pp->urb_state = URB_DONE; + break; + + default: + break; + } + } else if (intr_pp & HCHINTF_CH) { + pp_reg->HCHINTEN &= ~HCHINTEN_CHIE; + + switch (pp->pp_status) { + case PIPE_XF: + pp->urb_state = URB_DONE; + break; + + case PIPE_STALL: + pp->urb_state = URB_STALL; + break; + + case PIPE_TRACERR: + case PIPE_DTGERR: + pp->err_count = 0U; + pp->urb_state = URB_ERROR; + + pp->data_toggle_in ^= 1U; + break; + + case PIPE_IDLE: + case PIPE_HALTED: + case PIPE_NAK: + case PIPE_NYET: + case PIPE_BBERR: + case PIPE_REQOVR: + default: + if((uint8_t)USB_EPTYPE_INTR == ep_type) { + pp->data_toggle_in ^= 1U; + } + break; + } + + pp_reg->HCHINTF = HCHINTF_CH; + } else if (intr_pp & HCHINTF_USBER) { + pp->err_count++; + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_USBER, PIPE_TRACERR); + } else if (intr_pp & HCHINTF_NAK) { + pp_reg->HCHINTF = HCHINTF_NAK; + switch (ep_type) { + case USB_EPTYPE_CTRL: + case USB_EPTYPE_BULK: + /* re-activate the channel */ + pp_reg->HCHCTL = (pp_reg->HCHCTL | HCHCTL_CEN) & ~HCHCTL_CDIS; + break; + + case USB_EPTYPE_INTR: + pp_reg->HCHINTEN |= HCHINTEN_CHIE; + + (void)usb_pipe_halt(udev, (uint8_t)pp_num); + break; + + default: + break; + } + + pp->pp_status = PIPE_NAK; + } else { + /* no operation */ + } + + return 1U; +} + +/*! + \brief handle the OUT channel interrupt + \param[in] udev: pointer to USB device instance + \param[in] pp_num: host channel number which is in (0..7) + \param[out] none + \retval operation status +*/ +#if defined (__ICCARM__) /*!< IAR compiler */ + #pragma optimize = none +#endif /* __ICCARM */ +static uint32_t usbh_int_pipe_out (usb_core_driver *udev, uint32_t pp_num) +{ + usbh_host *uhost = udev->host.data; + usb_pr *pp_reg = udev->regs.pr[pp_num]; + + usb_pipe *pp = &udev->host.pipe[pp_num]; + + uint32_t intr_pp = pp_reg->HCHINTF; + intr_pp &= pp_reg->HCHINTEN; + + if (intr_pp & HCHINTF_ACK) { + if (1U == udev->host.pipe[pp_num].do_ping) { + udev->host.pipe[pp_num].do_ping = 0; + pp->err_count = 0U; + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_ACK, PIPE_NAK); + } + + pp_reg->HCHINTF = HCHINTF_ACK; + } else if (intr_pp & HCHINTF_STALL) { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_STALL, PIPE_STALL); + } else if (intr_pp & HCHINTF_DTER) { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_DTER, PIPE_DTGERR); + pp_reg->HCHINTF = HCHINTF_NAK; + } else if (intr_pp & HCHINTF_REQOVR) { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_REQOVR, PIPE_REQOVR); + } else if (intr_pp & HCHINTF_TF) { + pp->err_count = 0U; + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_TF, PIPE_XF); + } else if (intr_pp & HCHINTF_NAK) { + if (0U == udev->host.pipe[pp_num].do_ping) { + if (1U == udev->host.pipe[pp_num].supp_ping) { + udev->host.pipe[pp_num].do_ping = 1; + } + } + + pp->err_count = 0U; + if(USB_USE_FIFO == udev->bp.transfer_mode) { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_NAK); + } else { + pp_reg->HCHINTF = HCHINTF_NAK; + } + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_NAK, PIPE_NAK); + } else if (intr_pp & HCHINTF_USBER) { + pp->err_count++; + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_USBER, PIPE_TRACERR); + } else if (intr_pp & HCHINTF_NYET) { + if (CTL_STATUS_OUT != uhost->control.ctl_state) { + if (0U == udev->host.pipe[pp_num].do_ping) { + if (1U == udev->host.pipe[pp_num].supp_ping) { + udev->host.pipe[pp_num].do_ping = 1; + } + } + + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_NYET, PIPE_NYET); + } else { + usb_pp_halt (udev, (uint8_t)pp_num, HCHINTF_NYET, PIPE_XF); + } + + pp->err_count = 0U; + } else if (intr_pp & HCHINTF_CH) { + udev->regs.pr[pp_num]->HCHINTEN &= ~HCHINTEN_CHIE; + + switch (pp->pp_status) { + case PIPE_XF: + pp->urb_state = URB_DONE; + + if ((uint8_t)USB_EPTYPE_BULK == ((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18U)) { + pp->data_toggle_out ^= 1U; + } + break; + + case PIPE_NAK: + pp->urb_state = URB_NOTREADY; + break; + + case PIPE_NYET: + pp->urb_state = URB_DONE; + + if ((uint8_t)USB_EPTYPE_BULK == ((pp_reg->HCHCTL & HCHCTL_EPTYPE) >> 18U)) { + pp->data_toggle_out ^= 1U; + } + break; + + case PIPE_STALL: + pp->urb_state = URB_STALL; + break; + + case PIPE_TRACERR: + if (3U == pp->err_count) { + pp->urb_state = URB_ERROR; + pp->err_count = 0U; + } + break; + + case PIPE_IDLE: + case PIPE_HALTED: + case PIPE_BBERR: + case PIPE_REQOVR: + case PIPE_DTGERR: + default: + break; + } + + pp_reg->HCHINTF = HCHINTF_CH; + } else { + /* no operation */ + } + + return 1U; +} + +/*! + \brief handle the RX FIFO non-empty interrupt + \param[in] udev: pointer to USB device instance + \param[out] none + \retval operation status +*/ +#if defined (__ICCARM__) /*!< IAR compiler */ + #pragma optimize = none +#endif /* __ICCARM */ +static uint32_t usbh_int_rxfifonoempty (usb_core_driver *udev) +{ + uint32_t count = 0U, xfer_count = 0; + + __IO uint8_t pp_num = 0U; + __IO uint32_t rx_stat = 0U; + + /* disable the RX status queue level interrupt */ + udev->regs.gr->GINTEN &= ~GINTEN_RXFNEIE; + + rx_stat = udev->regs.gr->GRSTATP; + pp_num = (uint8_t)(rx_stat & GRSTATRP_CNUM); + + switch ((rx_stat & GRSTATRP_RPCKST) >> 17U) { + case GRXSTS_PKTSTS_IN: + count = (rx_stat & GRSTATRP_BCOUNT) >> 4U; + + /* read the data into the host buffer. */ + if ((NULL != udev->host.pipe[pp_num].xfer_buf) && (count > 0U)) { + (void)usb_rxfifo_read (&udev->regs, udev->host.pipe[pp_num].xfer_buf, (uint16_t)count); + + /* manage multiple transfer packet */ + udev->host.pipe[pp_num].xfer_buf += count; + udev->host.pipe[pp_num].xfer_count += count; + + xfer_count = udev->host.pipe[pp_num].xfer_count; + + udev->host.backup_xfercount[pp_num] = xfer_count; + + if (udev->regs.pr[pp_num]->HCHLEN & HCHLEN_PCNT) { + /* re-activate the channel when more packets are expected */ + uint32_t pp_ctl = udev->regs.pr[pp_num]->HCHCTL; + + pp_ctl |= HCHCTL_CEN; + pp_ctl &= ~HCHCTL_CDIS; + + udev->regs.pr[pp_num]->HCHCTL = pp_ctl; + } + } + break; + + case GRXSTS_PKTSTS_IN_XFER_COMP: + break; + + case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: + count = (rx_stat & GRSTATRP_BCOUNT) >> 4U; + + while (count > 0U) { + rx_stat = udev->regs.gr->GRSTATP; + count--; + } + break; + + case GRXSTS_PKTSTS_CH_HALTED: + break; + + default: + break; + } + + /* enable the RX status queue level interrupt */ + udev->regs.gr->GINTEN |= GINTEN_RXFNEIE; + + return 1U; +} + +/*! + \brief handle the TX FIFO empty interrupt + \param[in] udev: pointer to USB device instance + \param[in] pp_mode: pipe mode + \param[out] none + \retval operation status +*/ +#if defined (__ICCARM__) /*!< IAR compiler */ + #pragma optimize = none +#endif /* __ICCARM */ +static uint32_t usbh_int_txfifoempty (usb_core_driver *udev, usb_pipe_mode pp_mode) +{ + uint8_t pp_num = 0U; + uint16_t word_count = 0U, len = 0U; + __IO uint32_t *txfiforeg = 0U, txfifostate = 0U; + + if (PIPE_NON_PERIOD == pp_mode) { + txfiforeg = &udev->regs.gr->HNPTFQSTAT; + } else if (PIPE_PERIOD == pp_mode) { + txfiforeg = &udev->regs.hr->HPTFQSTAT; + } else { + return 0U; + } + + txfifostate = *txfiforeg; + + pp_num = (uint8_t)((txfifostate & TFQSTAT_CNUM) >> 27U); + + word_count = (uint16_t)(udev->host.pipe[pp_num].xfer_len + 3U) / 4U; + + while (((txfifostate & TFQSTAT_TXFS) >= word_count) && (0U != udev->host.pipe[pp_num].xfer_len)) { + len = (uint16_t)(txfifostate & TFQSTAT_TXFS) * 4U; + + if (len > udev->host.pipe[pp_num].xfer_len) { + /* last packet */ + len = (uint16_t)udev->host.pipe[pp_num].xfer_len; + + if (PIPE_NON_PERIOD == pp_mode) { + udev->regs.gr->GINTEN &= ~GINTEN_NPTXFEIE; + } else { + udev->regs.gr->GINTEN &= ~GINTEN_PTXFEIE; + } + } + + word_count = (uint16_t)((udev->host.pipe[pp_num].xfer_len + 3U) / 4U); + usb_txfifo_write (&udev->regs, udev->host.pipe[pp_num].xfer_buf, pp_num, len); + + udev->host.pipe[pp_num].xfer_buf += len; + udev->host.pipe[pp_num].xfer_len -= len; + udev->host.pipe[pp_num].xfer_count += len; + + txfifostate = *txfiforeg; + } + + return 1U; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Include/usbh_cdc_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Include/usbh_cdc_core.h new file mode 100644 index 0000000000..28756b1850 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Include/usbh_cdc_core.h @@ -0,0 +1,152 @@ +/*! + \file usbh_cdc_core.h + \brief header file for the usbh_cdc_core.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_CDC_CORE_H +#define __USBH_CDC_CORE_H + +#include "drv_usb_hw.h" +#include "usb_cdc.h" +#include "usbh_core.h" +#include "usbh_pipe.h" +#include "usbh_enum.h" +#include "usbh_transc.h" + +#define CDC_BUFFER_SIZE 1024U +#define LINE_CODING_STRUCTURE_SIZE 0x07U + +/* states for CDC state machine */ +typedef enum +{ + CDC_IDLE = 0U, + CDC_READ_DATA, + CDC_SEND_DATA, + CDC_DATA_SENT, + CDC_BUSY, + CDC_GET_DATA, + CDC_POLL, + CDC_CTRL_STATE +} cdc_state; + +/* CDC transfer state */ +typedef struct _cdc_xfer +{ + volatile cdc_state cdc_cur_state; + + uint8_t *prxtx_buff; + uint8_t *pfill_buff; + uint8_t *pempty_buff; + uint32_t buffer_len; + uint16_t data_length; +} cdc_xfer; + +typedef struct _cdc_usercb +{ + void (*send) (uint8_t *data_buf); + void (*receive) (uint8_t *data_buf); +} cdc_usercb; + +/* structure for CDC command interface */ +typedef struct _cdc_cmd_itf +{ + uint8_t pipe_notify; + uint8_t ep_notify; + uint8_t buff[8]; + uint16_t ep_size_notify; +} cdc_cmd_itf; + +/* structure for CDC data interface */ +typedef struct _cdc_data_itf +{ + uint8_t pipe_in; + uint8_t pipe_out; + uint8_t ep_in; + uint8_t ep_out; + uint8_t buff[8]; + uint16_t ep_size_in; + uint16_t ep_size_out; +} cdc_data_itf; + +/* states for CDC class state machine */ +typedef enum +{ + CDC_SET_LINE_CODING_RQUEST = 0U, + CDC_GET_LINE_CODING_RQUEST, + CDC_SET_CONTROL_LINE_STATE_REQUEST, + CDC_ERROR_STATE +} cdc_requests; + +/* line coding structure */ +typedef union { + uint8_t array[LINE_CODING_STRUCTURE_SIZE]; + + __ALIGN_BEGIN acm_line __ALIGN_END b; +} cdc_line_coding; + +/* structure for CDC process */ +typedef struct _cdc_process +{ + uint8_t rx_enabled; + cdc_xfer tx_param; + cdc_xfer rx_param; + cdc_line_coding line_code_get; + cdc_line_coding line_code_set; + cdc_cmd_itf cmd_itf; + cdc_data_itf data_itf; + cdc_requests req_state; + cdc_usercb user_cb; +} usbh_cdc_handler; + +extern usbh_class usbh_cdc; + +/* function declarations */ +/* send data to the device */ +void cdc_data_send (usbh_host *uhost, uint8_t *data, uint16_t length); +/* send dummy data to the device */ +void cdc_dummydata_send (usbh_host *uhost); +/* enable CDC receive */ +void cdc_start_reception (usbh_host *uhost); +/* stop CDC receive */ +void cdc_stop_reception (usbh_host *uhost); +/* get currently configured line coding */ +usbh_status cdc_get_line_coding (usbh_host *uhost); +/* specify typical asynchronous line-character formatting properties */ +usbh_status cdc_set_line_coding (usbh_host *uhost); +/* this request generates RS-232/V.24 style control signals */ +usbh_status cdc_set_control_line_state (usbh_host *uhost); +/* this function prepares the state before issuing the class specific commands */ +void cdc_change_state_to_issue_setconfig (usbh_host *uhost); +/* this function prepares the state before issuing the class specific commands */ +void cdc_issue_getconfig (usbh_host *uhost); + +#endif /* __USBH_CDC_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Source/usbh_cdc_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Source/usbh_cdc_core.c new file mode 100644 index 0000000000..6afa83a868 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/cdc/Source/usbh_cdc_core.c @@ -0,0 +1,647 @@ +/*! + \file usbh_cdc_core.c + \brief USB host CDC class driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_cdc_core.h" +#include + +#ifdef USB_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment = 4 + #endif +#endif /* USB_HS_INTERNAL_DMA_ENABLED */ + +__ALIGN_BEGIN uint8_t tx_buf[CDC_BUFFER_SIZE] __ALIGN_END; + +#ifdef USB_HS_INTERNAL_DMA_ENABLED + #if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment = 4 + #endif +#endif /* USB_HS_INTERNAL_DMA_ENABLED */ + +__ALIGN_BEGIN uint8_t rx_buf[CDC_BUFFER_SIZE] __ALIGN_END; + +/* local function prototypes ('static') */ +static usbh_status cdc_interface_init (usbh_host *uhost); +static void cdc_interface_deinit (usbh_host *uhost); +static usbh_status cdc_class_request(usbh_host *uhost); +static usbh_status cdc_handle(usbh_host *uhost); +static void cdc_process_transmission(usbh_host *uhost); +static void cdc_process_reception(usbh_host *uhost); +static void cdc_init_txrxparam(usbh_host *uhost); +static void cdc_receive_data(usbh_host *uhost, cdc_xfer *cdc_data); + +usbh_class usbh_cdc = +{ + USB_CLASS_CDC, + cdc_interface_init, + cdc_interface_deinit, + cdc_class_request, + cdc_handle +}; + +/*! + \brief send data to the device + \param[in] uhost: pointer to USB host + \param[in] data: data pointer + \param[in] length: data length + \param[out] none + \retval none +*/ +void cdc_data_send (usbh_host *uhost, uint8_t *data, uint16_t length) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + if (cdc->tx_param.cdc_cur_state == CDC_IDLE) { + cdc->tx_param.prxtx_buff = data; + cdc->tx_param.data_length = length; + cdc->tx_param.cdc_cur_state = CDC_SEND_DATA; + } +} + +/*! + \brief send dummy data to the device + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void cdc_dummydata_send (usbh_host *uhost) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + static uint8_t cdc_send_buf[17] = {0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x20, 0x6C, 0x69, 0x6E, 0x65}; + + if (cdc->tx_param.cdc_cur_state == CDC_IDLE) { + cdc->tx_param.prxtx_buff = cdc_send_buf; + cdc->tx_param.data_length = sizeof(cdc_send_buf); + cdc->tx_param.cdc_cur_state = CDC_SEND_DATA; + } +} + +/*! + \brief enable CDC receive + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void cdc_start_reception (usbh_host *uhost) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + cdc->rx_enabled = 1U; +} + +/*! + \brief stop CDC receive + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void cdc_stop_reception (usbh_host *uhost) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + cdc->rx_enabled = 0U; + + usb_pipe_halt(uhost->data, cdc->data_itf.pipe_in); + usbh_pipe_free(uhost->data, cdc->data_itf.pipe_in); +} + +/*! + \brief get currently configured line coding + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +usbh_status cdc_get_line_coding (usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + if (CTL_IDLE == uhost->control.ctl_state) { + usbh_control *usb_ctl = &uhost->control; + + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_RECPTYPE_ITF | USB_REQTYPE_CLASS, + .bRequest = GET_LINE_CODING, + .wValue = 0U, + .wIndex = 0U, + .wLength = LINE_CODING_STRUCTURE_SIZE + }; + + usbh_ctlstate_config (uhost, cdc->line_code_get.array, LINE_CODING_STRUCTURE_SIZE); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief specify typical asynchronous line-character formatting properties + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +usbh_status cdc_set_line_coding (usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + if (CTL_IDLE == uhost->control.ctl_state) { + usbh_control *usb_ctl = &uhost->control; + + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_ITF | USB_REQTYPE_CLASS, + .bRequest = SET_LINE_CODING, + .wValue = 0U, + .wIndex = 0U, + .wLength = LINE_CODING_STRUCTURE_SIZE + }; + + usbh_ctlstate_config (uhost, cdc->line_code_set.array, LINE_CODING_STRUCTURE_SIZE); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief this request generates RS-232/V.24 style control signals + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +usbh_status cdc_set_control_line_state (usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + + if (CTL_IDLE == uhost->control.ctl_state) { + usbh_control *usb_ctl = &uhost->control; + + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_ITF | USB_REQTYPE_CLASS, + .bRequest = SET_CONTROL_LINE_STATE, + .wValue = CDC_DEACTIVATE_CARRIER_SIGNAL_RTS | CDC_DEACTIVATE_SIGNAL_DTR, + .wIndex = 0U, + .wLength = 0U + }; + + usbh_ctlstate_config (uhost, NULL, 0U); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief this function prepares the state before issuing the class specific commands + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void cdc_change_state_to_issue_setconfig (usbh_host *uhost) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + uhost->backup_state = uhost->cur_state; + uhost->cur_state = HOST_CLASS_ENUM; + + cdc->req_state = CDC_SET_LINE_CODING_RQUEST; +} + +/*! + \brief this function prepares the state before issuing the class specific commands + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void cdc_issue_getconfig (usbh_host *uhost) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + uhost->backup_state = uhost->cur_state; + uhost->cur_state = HOST_CLASS_ENUM; + + cdc->req_state = CDC_GET_LINE_CODING_RQUEST; +} + +/*! + \brief init the CDC class + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status cdc_interface_init (usbh_host *uhost) +{ + usbh_status status = USBH_OK; + + uint8_t interface = usbh_interface_find(&uhost->dev_prop, USB_CLASS_CDC, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTOCOL_AT); + + if (0xFFU == interface) { + uhost->usr_cb->dev_not_supported(); + + status = USBH_FAIL; + } else { + usbh_interface_select(&uhost->dev_prop, interface); + + static usbh_cdc_handler cdc_handler; + + memset(&cdc_handler, 0U, sizeof(usbh_cdc_handler)); + + uhost->active_class->class_data = (void *)&cdc_handler; + + usb_desc_ep *ep_desc = &uhost->dev_prop.cfg_desc_set.itf_desc_set[interface][0].ep_desc[0]; + + /* collect the notification endpoint address and length */ + if (ep_desc->bEndpointAddress & 0x80U) { + cdc_handler.cmd_itf.ep_notify = ep_desc->bEndpointAddress; + cdc_handler.cmd_itf.ep_size_notify = ep_desc->wMaxPacketSize; + } + + /* allocate the length for host channel number in */ + cdc_handler.cmd_itf.pipe_notify = usbh_pipe_allocate (uhost->data, cdc_handler.cmd_itf.ep_notify); + + /* open channel for in endpoint */ + usbh_pipe_create (uhost->data, + &uhost->dev_prop, + cdc_handler.cmd_itf.pipe_notify, + USB_EPTYPE_INTR, + cdc_handler.cmd_itf.ep_size_notify); + + usbh_pipe_toggle_set(uhost->data, cdc_handler.cmd_itf.pipe_notify, 0U); + + interface = usbh_interface_find(&uhost->dev_prop, USB_CLASS_DATA, USB_CDC_SUBCLASS_RESERVED, USB_CDC_PROTOCOL_NONE); + + ep_desc = &uhost->dev_prop.cfg_desc_set.itf_desc_set[interface][0].ep_desc[0]; + + if (ep_desc->bEndpointAddress & 0x80U) { + cdc_handler.data_itf.ep_in = ep_desc->bEndpointAddress; + cdc_handler.data_itf.ep_size_in = ep_desc->wMaxPacketSize; + } else { + cdc_handler.data_itf.ep_out = ep_desc->bEndpointAddress; + cdc_handler.data_itf.ep_size_out = ep_desc->wMaxPacketSize; + } + + ep_desc = &uhost->dev_prop.cfg_desc_set.itf_desc_set[interface][0].ep_desc[1]; + + if (ep_desc->bEndpointAddress & 0x80U) { + cdc_handler.data_itf.ep_in = ep_desc->bEndpointAddress; + cdc_handler.data_itf.ep_size_in = ep_desc->wMaxPacketSize; + } else { + cdc_handler.data_itf.ep_out = ep_desc->bEndpointAddress; + cdc_handler.data_itf.ep_size_out = ep_desc->wMaxPacketSize; + } + + /* allocate the length for host channel number out */ + cdc_handler.data_itf.pipe_out = usbh_pipe_allocate (uhost->data, cdc_handler.data_itf.ep_out); + + /* allocate the length for host channel number in */ + cdc_handler.data_itf.pipe_in = usbh_pipe_allocate (uhost->data, cdc_handler.data_itf.ep_in); + + /* open channel for OUT endpoint */ + usbh_pipe_create (uhost->data, + &uhost->dev_prop, + cdc_handler.data_itf.pipe_out, + USB_EPTYPE_BULK, + cdc_handler.data_itf.ep_size_out); + + /* open channel for IN endpoint */ + usbh_pipe_create (uhost->data, + &uhost->dev_prop, + cdc_handler.data_itf.pipe_in, + USB_EPTYPE_BULK, + cdc_handler.data_itf.ep_size_in); + + usbh_pipe_toggle_set(uhost->data, cdc_handler.data_itf.ep_out, 0U); + usbh_pipe_toggle_set(uhost->data, cdc_handler.data_itf.pipe_in, 0U); + + cdc_handler.req_state = CDC_GET_LINE_CODING_RQUEST; + + /* initialize the TX/TX parameters */ + cdc_init_txrxparam(uhost); + } + + return status; +} + +/*! + \brief deinit the host channels used for the CDC class + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void cdc_interface_deinit (usbh_host *uhost) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + /* reset the channel as free */ + if (cdc->cmd_itf.pipe_notify) { + usb_pipe_halt (uhost->data, cdc->cmd_itf.pipe_notify); + usbh_pipe_free (uhost->data, cdc->cmd_itf.pipe_notify); + + cdc->cmd_itf.pipe_notify = 0U; + } + + /* reset the channel as free */ + if (cdc->data_itf.pipe_out) { + usb_pipe_halt (uhost->data, cdc->data_itf.pipe_out); + usbh_pipe_free (uhost->data, cdc->data_itf.pipe_out); + + cdc->data_itf.pipe_out = 0U; + } + + /* reset the channel as free */ + if (cdc->data_itf.pipe_in) { + usb_pipe_halt (uhost->data, cdc->data_itf.pipe_in); + usbh_pipe_free (uhost->data, cdc->data_itf.pipe_in); + + cdc->data_itf.pipe_in = 0U; + } + +} + +/*! + \brief handler CDC class requests + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status cdc_class_request (usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + usbh_status class_req_status = USBH_BUSY; + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + switch (cdc->req_state) { + case CDC_GET_LINE_CODING_RQUEST: + /* issue the get line coding request */ + class_req_status = cdc_get_line_coding(uhost); + + if (USBH_OK == class_req_status) { + cdc->req_state = CDC_SET_CONTROL_LINE_STATE_REQUEST; + } + break; + + case CDC_SET_LINE_CODING_RQUEST: + /* issue the set line coding request */ + class_req_status = cdc_set_line_coding(uhost); + + if (USBH_OK == class_req_status) { + cdc->req_state = CDC_GET_LINE_CODING_RQUEST; + } + + if (USBH_NOT_SUPPORTED == class_req_status) { + /* a clear feature should be issued here */ + cdc->req_state = CDC_ERROR_STATE; + } + break; + + case CDC_SET_CONTROL_LINE_STATE_REQUEST: + /* issue the set control line coding */ + class_req_status = cdc_set_control_line_state(uhost); + + if (USBH_OK == class_req_status) { + cdc->req_state = CDC_SET_CONTROL_LINE_STATE_REQUEST; + + /* also set the state of receive CDCRxParam to IDLE */ + cdc->rx_param.cdc_cur_state = CDC_IDLE; + + status = USBH_OK; /* this return from class specific routines request*/ + } + break; + + case CDC_ERROR_STATE: + class_req_status = usbh_clrfeature(uhost, 0x00U, uhost->control.pipe_out_num); + + if (USBH_OK == class_req_status) { + cdc->req_state = CDC_GET_LINE_CODING_RQUEST; + } + break; + + default: + break; + } + + return status; +} + +/*! + \brief managing state machine for CDC data transfers + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status cdc_handle (usbh_host *uhost) +{ + usbh_status status = USBH_OK; + + /* call application process */ + uhost->usr_cb->dev_user_app(); + + /* handle the transmission */ + cdc_process_transmission(uhost); + + /* always send in packet to device */ + cdc_process_reception(uhost); + + return status; +} + +/*! + \brief the function is responsible for sending data to the device + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void cdc_process_transmission(usbh_host *uhost) +{ + static uint32_t len ; + usb_urb_state urb_status_tx = URB_IDLE; + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + urb_status_tx = usbh_urbstate_get(uhost->data, cdc->data_itf.pipe_out); + + switch (cdc->tx_param.cdc_cur_state) { + case CDC_IDLE: + break; + + case CDC_SEND_DATA: + if ((urb_status_tx == URB_DONE) || (urb_status_tx == URB_IDLE)) { + /* check the data length is more then the usbh_cdc_handler.data_itf.length */ + if (cdc->tx_param.data_length > cdc->data_itf.ep_size_out) { + len = cdc->data_itf.ep_size_out; + + /* send the data */ + usbh_data_send (uhost->data, + cdc->tx_param.prxtx_buff, + cdc->data_itf.pipe_out, + len); + } else { + len = cdc->tx_param.data_length; + + /* send the remaining data */ + usbh_data_send (uhost->data, + cdc->tx_param.prxtx_buff, + cdc->data_itf.pipe_out, + len); + } + + cdc->tx_param.cdc_cur_state = CDC_DATA_SENT; + } + break; + + case CDC_DATA_SENT: + /* check the status done for transmission */ + if (urb_status_tx == URB_DONE) { + /* point to next chunk of data */ + cdc->tx_param.prxtx_buff += len; + + /* decrease the data length */ + cdc->tx_param.data_length -= len; + + if (cdc->tx_param.data_length == 0U) { + cdc->tx_param.cdc_cur_state = CDC_IDLE; + } else { + cdc->tx_param.cdc_cur_state = CDC_SEND_DATA; + } + } else if (urb_status_tx == URB_NOTREADY) { + /* send the same data */ + usbh_data_send (uhost->data, + (cdc->tx_param.prxtx_buff), + cdc->data_itf.pipe_out, + len); + } + break; + + default: + break; + } +} + +/*! + \brief the function is responsible for reception of data from the device + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void cdc_process_reception(usbh_host *uhost) +{ + usb_core_driver *udev = (usb_core_driver *)uhost->data; + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + if (cdc->rx_enabled == 1) { + usb_urb_state urb_status_rx = usbh_urbstate_get(udev, cdc->data_itf.pipe_in); + + switch (cdc->rx_param.cdc_cur_state) { + case CDC_IDLE: + /* check the received length lesser then the remaining space available in the buffer */ + if (cdc->rx_param.data_length < (cdc->rx_param.buffer_len - cdc->data_itf.ep_size_in)) { + /* receive the data */ + usbh_data_recev(udev, + cdc->rx_param.pfill_buff, + cdc->data_itf.pipe_in, + cdc->data_itf.ep_size_in); + + /* change the CDC state to USBH_CDC_GET_DATA*/ + cdc->rx_param.cdc_cur_state = CDC_GET_DATA; + } + break; + + case CDC_GET_DATA: + /* check the last state of the device is URB_DONE */ + if (urb_status_rx == URB_DONE) { + /* move the pointer as well as data length */ + cdc->rx_param.data_length += udev->host.pipe[cdc->data_itf.pipe_in].xfer_count; + cdc->rx_param.pfill_buff += udev->host.pipe[cdc->data_itf.pipe_in].xfer_count; + + /* Process the received data */ + cdc_receive_data(uhost, &cdc->rx_param); + + /*change the state OD the CDC state*/ + cdc->rx_param.cdc_cur_state = CDC_IDLE; + } + break; + + default: + break; + } + } +} + +/*! + \brief initialize the transmit and receive buffer and its parameter + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void cdc_init_txrxparam(usbh_host *uhost) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + /* initialize the transmit buffer and its parameter */ + cdc->tx_param.cdc_cur_state = CDC_IDLE; + cdc->tx_param.data_length = 0U; + cdc->tx_param.prxtx_buff = tx_buf; + + /* initialize the receive buffer and its parameter */ + cdc->rx_param.cdc_cur_state = CDC_IDLE; + cdc->rx_param.data_length = 0U; + cdc->rx_param.pfill_buff = rx_buf; + cdc->rx_param.pempty_buff = rx_buf; + cdc->rx_param.buffer_len = sizeof(rx_buf); +} + +/*! + \brief call back function from CDC core layer to redirect the received data on the user out put system + \param[in] uhost: pointer to USB host + \param[in] cdc_data: data structure + \param[out] none + \retval none +*/ +static void cdc_receive_data(usbh_host *uhost, cdc_xfer *cdc_data) +{ + usbh_cdc_handler *cdc = (usbh_cdc_handler *)uhost->active_class->class_data; + + if (cdc_data->pempty_buff < cdc_data->pfill_buff) { + /* redirect the received data on the user out put system */ + cdc->user_cb.receive(cdc_data->pempty_buff); + + cdc_data->pfill_buff = cdc_data->pempty_buff; + + /* reset the data length to zero */ + cdc_data->data_length = 0U; + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_core.h new file mode 100644 index 0000000000..4978df12ee --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_core.h @@ -0,0 +1,223 @@ +/*! + \file usbh_hid_core.h + \brief header file for the usbh_hid_core.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_HID_CORE_H +#define __USBH_HID_CORE_H + +#include "usb_hid.h" +#include "usbh_enum.h" +#include "usbh_transc.h" + +#define HID_MIN_POLL 10U +#define HID_REPORT_SIZE 16U +#define HID_MAX_USAGE 10U +#define HID_MAX_NBR_REPORT_FMT 10U +#define HID_QUEUE_SIZE 10U + +#define HID_ITEM_LONG 0xFEU + +#define HID_ITEM_TYPE_MAIN 0x00U +#define HID_ITEM_TYPE_GLOBAL 0x01U +#define HID_ITEM_TYPE_LOCAL 0x02U +#define HID_ITEM_TYPE_RESERVED 0x03U + +#define HID_MAIN_ITEM_TAG_INPUT 0x08U +#define HID_MAIN_ITEM_TAG_OUTPUT 0x09U +#define HID_MAIN_ITEM_TAG_COLLECTION 0x0AU +#define HID_MAIN_ITEM_TAG_FEATURE 0x0BU +#define HID_MAIN_ITEM_TAG_ENDCOLLECTION 0x0CU + +#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0x00U +#define HID_GLOBAL_ITEM_TAG_LOG_MIN 0x01U +#define HID_GLOBAL_ITEM_TAG_LOG_MAX 0x02U +#define HID_GLOBAL_ITEM_TAG_PHY_MIN 0x03U +#define HID_GLOBAL_ITEM_TAG_PHY_MAX 0x04U +#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 0x05U +#define HID_GLOBAL_ITEM_TAG_UNIT 0x06U +#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 0x07U +#define HID_GLOBAL_ITEM_TAG_REPORT_ID 0x08U +#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 0x09U +#define HID_GLOBAL_ITEM_TAG_PUSH 0x0AU +#define HID_GLOBAL_ITEM_TAG_POP 0x0BU + +#define HID_LOCAL_ITEM_TAG_USAGE 0x00U +#define HID_LOCAL_ITEM_TAG_USAGE_MIN 0x01U +#define HID_LOCAL_ITEM_TAG_USAGE_MAX 0x02U +#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 0x03U +#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MIN 0x04U +#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAX 0x05U +#define HID_LOCAL_ITEM_TAG_STRING_INDEX 0x07U +#define HID_LOCAL_ITEM_TAG_STRING_MIN 0x08U +#define HID_LOCAL_ITEM_TAG_STRING_MAX 0x09U +#define HID_LOCAL_ITEM_TAG_DELIMITER 0x0AU + +#define USB_HID_DESC_SIZE 9U + +/* states for HID state machine */ +typedef enum { + HID_INIT = 0U, + HID_IDLE, + HID_SEND_DATA, + HID_BUSY, + HID_GET_DATA, + HID_SYNC, + HID_POLL, + HID_ERROR, +} hid_state; + +typedef enum { + HID_REQ_INIT = 0U, + HID_REQ_IDLE, + HID_REQ_GET_REPORT_DESC, + HID_REQ_GET_HID_DESC, + HID_REQ_SET_IDLE, + HID_REQ_SET_PROTOCOL, + HID_REQ_SET_REPORT, +} hid_ctlstate; + +typedef enum +{ + HID_MOUSE = 0x01U, + HID_KEYBOARD = 0x02U, + HID_UNKNOWN = 0xFFU, +} hid_type; + +typedef struct _hid_report_data +{ + uint8_t ReportID; + uint8_t ReportType; + uint16_t UsagePage; + uint32_t Usage[HID_MAX_USAGE]; + uint32_t NbrUsage; + uint32_t UsageMin; + uint32_t UsageMax; + int32_t LogMin; + int32_t LogMax; + int32_t PhyMin; + int32_t PhyMax; + int32_t UnitExp; + uint32_t Unit; + uint32_t ReportSize; + uint32_t ReportCnt; + uint32_t Flag; + uint32_t PhyUsage; + uint32_t AppUsage; + uint32_t LogUsage; +} hid_report_data; + +typedef struct _hid_report_ID +{ + uint8_t size; /*!< report size return by the device ID */ + uint8_t reportID; /*!< report ID */ + uint8_t type; /*!< report type (INPUT/OUTPUT/FEATURE) */ +} hid_report_ID; + +typedef struct _hid_collection +{ + uint32_t usage; + uint8_t type; + struct _hid_collection *next_ptr; +} hid_collection; + +typedef struct _hid_appcollection +{ + uint32_t usage; + uint8_t type; + uint8_t nbr_report_fmt; + hid_report_data report_data[HID_MAX_NBR_REPORT_FMT]; +} hid_appcollection; + +typedef struct +{ + uint8_t *buf; + uint16_t head; + uint16_t tail; + uint16_t size; + uint8_t lock; +} data_fifo; + +/* structure for HID process */ +typedef struct _hid_process +{ + uint8_t pipe_in; + uint8_t pipe_out; + uint8_t ep_addr; + uint8_t ep_in; + uint8_t ep_out; +__IO uint8_t data_ready; + uint8_t *pdata; + uint16_t len; + uint16_t poll; + + __IO uint32_t timer; + + data_fifo fifo; + usb_desc_hid hid_desc; + hid_report_data hid_report; + + hid_state state; + hid_ctlstate ctl_state; + usbh_status (*init)(usb_core_driver *udev, usbh_host *uhost); + void (*machine)(usb_core_driver *udev, usbh_host *uhost); +} usbh_hid_handler; + +extern usbh_class usbh_hid; + + +/* function declarations */ +/* get HID report */ +usbh_status usbh_get_report (usbh_host *uhost, + uint8_t report_type, + uint8_t report_ID, + uint8_t report_len, + uint8_t *report_buf); +/* set HID report */ +usbh_status usbh_set_report (usb_core_driver *udev, + usbh_host *uhost, + uint8_t report_type, + uint8_t report_ID, + uint8_t report_len, + uint8_t *report_buf); +/* get device function */ +hid_type usbh_hid_device_type_get(usb_core_driver *udev, usbh_host *uhost); +/* get HID device poll time */ +uint8_t usbh_hid_poll_interval_get (usb_core_driver *udev, usbh_host *uhost); +/* read data from FIFO */ +uint16_t usbh_hid_fifo_read (data_fifo *fifo, void *buf, uint16_t nbytes); +/* write data to FIFO */ +uint16_t usbh_hid_fifo_write (data_fifo *fifo, void *buf, uint16_t nbytes); +/* initialize FIFO */ +void usbh_hid_fifo_init (data_fifo *fifo, uint8_t *buf, uint16_t size); + +#endif /* __USBH_HID_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_keybd.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_keybd.h new file mode 100644 index 0000000000..d9ede1d1da --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_keybd.h @@ -0,0 +1,304 @@ +/*! + \file usbh_hid_keybd.h + \brief header file for usbh_hid_keybd.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_HID_KEYBD_H +#define __USBH_HID_KEYBD_H + +#include "usb_conf.h" +#include "usbh_hid_core.h" + +//#define AZERTY_KEYBOARD +#define QWERTY_KEYBOARD + +#define KBD_LEFT_CTRL 0x01U +#define KBD_LEFT_SHIFT 0x02U +#define KBD_LEFT_ALT 0x04U +#define KBD_LEFT_GUI 0x08U +#define KBD_RIGHT_CTRL 0x10U +#define KBD_RIGHT_SHIFT 0x20U +#define KBD_RIGHT_ALT 0x40U +#define KBD_RIGHT_GUI 0x80U + +#define KEY_NONE 0x00U +#define KEY_ERRORROLLOVER 0x01U +#define KEY_POSTFAIL 0x02U +#define KEY_ERRORUNDEFINED 0x03U +#define KEY_A 0x04U +#define KEY_B 0x05U +#define KEY_C 0x06U +#define KEY_D 0x07U +#define KEY_E 0x08U +#define KEY_F 0x09U +#define KEY_G 0x0AU +#define KEY_H 0x0BU +#define KEY_I 0x0CU +#define KEY_J 0x0DU +#define KEY_K 0x0EU +#define KEY_L 0x0FU +#define KEY_M 0x10U +#define KEY_N 0x11U +#define KEY_O 0x12U +#define KEY_P 0x13U +#define KEY_Q 0x14U +#define KEY_R 0x15U +#define KEY_S 0x16U +#define KEY_T 0x17U +#define KEY_U 0x18U +#define KEY_V 0x19U +#define KEY_W 0x1AU +#define KEY_X 0x1BU +#define KEY_Y 0x1CU +#define KEY_Z 0x1DU +#define KEY_1_EXCLAMATION_MARK 0x1EU +#define KEY_2_AT 0x1FU +#define KEY_3_NUMBER_SIGN 0x20U +#define KEY_4_DOLLAR 0x21U +#define KEY_5_PERCENT 0x22U +#define KEY_6_CARET 0x23U +#define KEY_7_AMPERSAND 0x24U +#define KEY_8_ASTERISK 0x25U +#define KEY_9_OPARENTHESIS 0x26U +#define KEY_0_CPARENTHESIS 0x27U +#define KEY_ENTER 0x28U +#define KEY_ESCAPE 0x29U +#define KEY_BACKSPACE 0x2AU +#define KEY_TAB 0x2BU +#define KEY_SPACEBAR 0x2CU +#define KEY_MINUS_UNDERSCORE 0x2DU +#define KEY_EQUAL_PLUS 0x2EU +#define KEY_OBRACKET_AND_OBRACE 0x2FU +#define KEY_CBRACKET_AND_CBRACE 0x30U +#define KEY_BACKSLASH_VERTICAL_BAR 0x31U +#define KEY_NONUS_NUMBER_SIGN_TILDE 0x32U +#define KEY_SEMICOLON_COLON 0x33U +#define KEY_SINGLE_AND_DOUBLE_QUOTE 0x34U +#define KEY_GRAVE ACCENT AND TILDE 0x35U +#define KEY_COMMA_AND_LESS 0x36U +#define KEY_DOT_GREATER 0x37U +#define KEY_SLASH_QUESTION 0x38U +#define KEY_CAPS LOCK 0x39U +#define KEY_F1 0x3AU +#define KEY_F2 0x3BU +#define KEY_F3 0x3CU +#define KEY_F4 0x3DU +#define KEY_F5 0x3EU +#define KEY_F6 0x3FU +#define KEY_F7 0x40U +#define KEY_F8 0x41U +#define KEY_F9 0x42U +#define KEY_F10 0x43U +#define KEY_F11 0x44U +#define KEY_F12 0x45U +#define KEY_PRINTSCREEN 0x46U +#define KEY_SCROLL LOCK 0x47U +#define KEY_PAUSE 0x48U +#define KEY_INSERT 0x49U +#define KEY_HOME 0x4AU +#define KEY_PAGEUP 0x4BU +#define KEY_DELETE 0x4CU +#define KEY_END1 0x4DU +#define KEY_PAGEDOWN 0x4EU +#define KEY_RIGHTARROW 0x4FU +#define KEY_LEFTARROW 0x50U +#define KEY_DOWNARROW 0x51U +#define KEY_UPARROW 0x52U +#define KEY_KEYPAD_NUM_LOCK_AND_CLEAR 0x53U +#define KEY_KEYPAD_SLASH 0x54U +#define KEY_KEYPAD_ASTERIKS 0x55U +#define KEY_KEYPAD_MINUS 0x56U +#define KEY_KEYPAD_PLUS 0x57U +#define KEY_KEYPAD_ENTER 0x58U +#define KEY_KEYPAD_1_END 0x59U +#define KEY_KEYPAD_2_DOWN_ARROW 0x5AU +#define KEY_KEYPAD_3_PAGEDN 0x5BU +#define KEY_KEYPAD_4_LEFT_ARROW 0x5CU +#define KEY_KEYPAD_5 0x5DU +#define KEY_KEYPAD_6_RIGHT_ARROW 0x5EU +#define KEY_KEYPAD_7_HOME 0x5FU +#define KEY_KEYPAD_8_UP_ARROW 0x60U +#define KEY_KEYPAD_9_PAGEUP 0x61U +#define KEY_KEYPAD_0_INSERT 0x62U +#define KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE 0x63U +#define KEY_NONUS_BACK_SLASH_VERTICAL_BAR 0x64U +#define KEY_APPLICATION 0x65U +#define KEY_POWER 0x66U +#define KEY_KEYPAD_EQUAL 0x67U +#define KEY_F13 0x68U +#define KEY_F14 0x69U +#define KEY_F15 0x6AU +#define KEY_F16 0x6BU +#define KEY_F17 0x6CU +#define KEY_F18 0x6DU +#define KEY_F19 0x6EU +#define KEY_F20 0x6FU +#define KEY_F21 0x70U +#define KEY_F22 0x71U +#define KEY_F23 0x72U +#define KEY_F24 0x73U +#define KEY_EXECUTE 0x74U +#define KEY_HELP 0x75U +#define KEY_MENU 0x76U +#define KEY_SELECT 0x77U +#define KEY_STOP 0x78U +#define KEY_AGAIN 0x79U +#define KEY_UNDO 0x7AU +#define KEY_CUT 0x7BU +#define KEY_COPY 0x7CU +#define KEY_PASTE 0x7DU +#define KEY_FIND 0x7EU +#define KEY_MUTE 0x7FU +#define KEY_VOLUME_UP 0x80U +#define KEY_VOLUME_DOWN 0x81U +#define KEY_LOCKING_CAPS_LOCK 0x82U +#define KEY_LOCKING_NUM_LOCK 0x83U +#define KEY_LOCKING_SCROLL_LOCK 0x84U +#define KEY_KEYPAD_COMMA 0x85U +#define KEY_KEYPAD_EQUAL_SIGN 0x86U +#define KEY_INTERNATIONAL1 0x87U +#define KEY_INTERNATIONAL2 0x88U +#define KEY_INTERNATIONAL3 0x89U +#define KEY_INTERNATIONAL4 0x8AU +#define KEY_INTERNATIONAL5 0x8BU +#define KEY_INTERNATIONAL6 0x8CU +#define KEY_INTERNATIONAL7 0x8DU +#define KEY_INTERNATIONAL8 0x8EU +#define KEY_INTERNATIONAL9 0x8FU +#define KEY_LANG1 0x90U +#define KEY_LANG2 0x91U +#define KEY_LANG3 0x92U +#define KEY_LANG4 0x93U +#define KEY_LANG5 0x94U +#define KEY_LANG6 0x95U +#define KEY_LANG7 0x96U +#define KEY_LANG8 0x97U +#define KEY_LANG9 0x98U +#define KEY_ALTERNATE_ERASE 0x99U +#define KEY_SYSREQ 0x9AU +#define KEY_CANCEL 0x9BU +#define KEY_CLEAR 0x9CU +#define KEY_PRIOR 0x9DU +#define KEY_RETURN 0x9EU +#define KEY_SEPARATOR 0x9FU +#define KEY_OUT 0xA0U +#define KEY_OPER 0xA1U +#define KEY_CLEAR_AGAIN 0xA2U +#define KEY_CRSEL 0xA3U +#define KEY_EXSEL 0xA4U +#define KEY_KEYPAD_00 0xB0U +#define KEY_KEYPAD_000 0xB1U +#define KEY_THOUSANDS_SEPARATOR 0xB2U +#define KEY_DECIMAL_SEPARATOR 0xB3U +#define KEY_CURRENCY_UNIT 0xB4U +#define KEY_CURRENCY_SUB_UNIT 0xB5U +#define KEY_KEYPAD_OPARENTHESIS 0xB6U +#define KEY_KEYPAD_CPARENTHESIS 0xB7U +#define KEY_KEYPAD_OBRACE 0xB8U +#define KEY_KEYPAD_CBRACE 0xB9U +#define KEY_KEYPAD_TAB 0xBAU +#define KEY_KEYPAD_BACKSPACE 0xBBU +#define KEY_KEYPAD_A 0xBCU +#define KEY_KEYPAD_B 0xBDU +#define KEY_KEYPAD_C 0xBEU +#define KEY_KEYPAD_D 0xBFU +#define KEY_KEYPAD_E 0xC0U +#define KEY_KEYPAD_F 0xC1U +#define KEY_KEYPAD_XOR 0xC2U +#define KEY_KEYPAD_CARET 0xC3U +#define KEY_KEYPAD_PERCENT 0xC4U +#define KEY_KEYPAD_LESS 0xC5U +#define KEY_KEYPAD_GREATER 0xC6U +#define KEY_KEYPAD_AMPERSAND 0xC7U +#define KEY_KEYPAD_LOGICAL_AND 0xC8U +#define KEY_KEYPAD_VERTICAL_BAR 0xC9U +#define KEY_KEYPAD_LOGIACL_OR 0xCAU +#define KEY_KEYPAD_COLON 0xCBU +#define KEY_KEYPAD_NUMBER_SIGN 0xCCU +#define KEY_KEYPAD_SPACE 0xCDU +#define KEY_KEYPAD_AT 0xCEU +#define KEY_KEYPAD_EXCLAMATION_MARK 0xCFU +#define KEY_KEYPAD_MEMORY_STORE 0xD0U +#define KEY_KEYPAD_MEMORY_RECALL 0xD1U +#define KEY_KEYPAD_MEMORY_CLEAR 0xD2U +#define KEY_KEYPAD_MEMORY_ADD 0xD3U +#define KEY_KEYPAD_MEMORY_SUBTRACT 0xD4U +#define KEY_KEYPAD_MEMORY_MULTIPLY 0xD5U +#define KEY_KEYPAD_MEMORY_DIVIDE 0xD6U +#define KEY_KEYPAD_PLUSMINUS 0xD7U +#define KEY_KEYPAD_CLEAR 0xD8U +#define KEY_KEYPAD_CLEAR_ENTRY 0xD9U +#define KEY_KEYPAD_BINARY 0xDAU +#define KEY_KEYPAD_OCTAL 0xDBU +#define KEY_KEYPAD_DECIMAL 0xDCU +#define KEY_KEYPAD_HEXADECIMAL 0xDDU +#define KEY_LEFTCONTROL 0xE0U +#define KEY_LEFTSHIFT 0xE1U +#define KEY_LEFTALT 0xE2U +#define KEY_LEFT_GUI 0xE3U +#define KEY_RIGHTCONTROL 0xE4U +#define KEY_RIGHTSHIFT 0xE5U +#define KEY_RIGHTALT 0xE6U +#define KEY_RIGHT_GUI 0xE7U + +#define KBR_MAX_NBR_PRESSED 6U + +typedef struct +{ + uint8_t state; + uint8_t lctrl; + uint8_t lshift; + uint8_t lalt; + uint8_t lgui; + uint8_t rctrl; + uint8_t rshift; + uint8_t ralt; + uint8_t rgui; + uint8_t keys[6]; +} hid_keybd_info; + +/* function declarations */ +/* initialize the keyboard function */ +usbh_status usbh_hid_keybd_init (usb_core_driver *udev, usbh_host *uhost); +/* get keyboard information */ +hid_keybd_info *usbh_hid_keybd_info_get (usb_core_driver *udev, usbh_host *uhost); +/* get the ASCII code of hid */ +uint8_t usbh_hid_ascii_code_get (hid_keybd_info *info); +/* keyboard machine */ +void usbh_hid_keybrd_machine (usb_core_driver *udev, usbh_host *uhost); + +/* initialize keyboard */ +void usr_keybrd_init (void); +/* process keyboard data */ +void usr_keybrd_process_data (uint8_t data); + +#endif /* __USBH_HID_KEYBD_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_mouse.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_mouse.h new file mode 100644 index 0000000000..aae0e0f9b5 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_mouse.h @@ -0,0 +1,60 @@ +/*! + \file usbh_hid_mouse.h + \brief header file for the usbh_hid_mouse.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_HID_MOUSE_H +#define __USBH_HID_MOUSE_H + +#include "usbh_hid_core.h" + +typedef struct _hid_mouse_info +{ + uint8_t x; + uint8_t y; + uint8_t buttons[3]; +} hid_mouse_info; + +/* function declarations */ +/* initialize mouse function */ +usbh_status usbh_hid_mouse_init (usb_core_driver *udev, usbh_host *uhost); +/* get mouse information */ +hid_mouse_info *usbh_hid_mouse_info_get (usb_core_driver *udev, usbh_host *uhost); +/* mouse machine */ +void usbh_hid_mouse_machine (usb_core_driver *udev, usbh_host *uhost); + +/* initialize mouse window */ +void usr_mouse_init (void); +/* process mouse data */ +void usr_mouse_process_data (hid_mouse_info *data); + +#endif /* __USBH_HID_MOUSE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_parser.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_parser.h new file mode 100644 index 0000000000..971f53caa1 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_parser.h @@ -0,0 +1,61 @@ +/*! + \file usbh_hid_parser.h + \brief header file for the usbh_hid_parser.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_HID_PARSER_H +#define __USBH_HID_PARSER_H + +#include "usbh_hid_core.h" +#include "usbh_hid_usage.h" + +typedef struct +{ + uint8_t *data; + uint32_t size; + uint8_t shift; + uint8_t count; + uint8_t sign; + uint32_t logical_min; /* min value device can return */ + uint32_t logical_max; /* max value device can return */ + uint32_t physical_min; /* min vale read can report */ + uint32_t physical_max; /* max value read can report */ + uint32_t resolution; +} hid_report_item; + +/* function declarations */ +/* read a hid report item */ +uint32_t hid_item_read (hid_report_item *ri, uint8_t ndx); +/* write a hid report item */ +uint32_t hid_item_write (hid_report_item *ri, uint32_t value, uint8_t ndx); + +#endif /* __USBH_HID_PARSER_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_usage.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_usage.h new file mode 100644 index 0000000000..03f6b14fa3 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Include/usbh_hid_usage.h @@ -0,0 +1,138 @@ +/*! + \file usbh_hid_usage.h + \brief header file for the usbh_hid_usage.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USDH_HID_USAGE_H +#define __USDH_HID_USAGE_H + +/* HID 1.11 usage pages */ +#define HID_USAGE_PAGE_UNDEFINED uint16_t (0x00) /* Undefined */ + +/* top level pages */ +#define HID_USAGE_PAGE_GEN_DES uint16_t (0x01) /* Generic Desktop Controls*/ +#define HID_USAGE_PAGE_SIM_CTR uint16_t (0x02) /* Simulation Controls */ +#define HID_USAGE_PAGE_VR_CTR uint16_t (0x03) /* VR Controls */ +#define HID_USAGE_PAGE_SPORT_CTR uint16_t (0x04) /* Sport Controls */ +#define HID_USAGE_PAGE_GAME_CTR uint16_t (0x05) /* Game Controls */ +#define HID_USAGE_PAGE_GEN_DEV uint16_t (0x06) /* Generic Device Controls */ +#define HID_USAGE_PAGE_KEYB uint16_t (0x07) /* Keyboard/Keypad */ +#define HID_USAGE_PAGE_LED uint16_t (0x08) /* LEDs */ +#define HID_USAGE_PAGE_BUTTON uint16_t (0x09) /* Button */ +#define HID_USAGE_PAGE_ORDINAL uint16_t (0x0A) /* Ordinal */ +#define HID_USAGE_PAGE_PHONE uint16_t (0x0B) /* Telephony */ +#define HID_USAGE_PAGE_CONSUMER uint16_t (0x0C) /* Consumer */ +#define HID_USAGE_PAGE_DIGITIZER uint16_t (0x0D) /* Digitizer*/ +#define HID_USAGE_PAGE_PID uint16_t (0x0F) /* PID Page (force feedback and related devices) */ +#define HID_USAGE_PAGE_UNICODE uint16_t (0x10) /* Unicode */ +#define HID_USAGE_PAGE_ALNUM_DISP uint16_t (0x14) /* Alphanumeric Display */ +/* end of top level pages */ + +#define HID_USAGE_PAGE_MEDICAL uint16_t (0x40) /* Medical Instruments */ +#define HID_USAGE_PAGE_BARCODE uint16_t (0x8C) /* Bar Code Scanner page */ +#define HID_USAGE_PAGE_SCALE uint16_t (0x8D) /* Scale page */ +#define HID_USAGE_PAGE_MSR uint16_t (0x8E) /* Magnetic Stripe Reading (MSR) Devices */ +#define HID_USAGE_PAGE_POS uint16_t (0x8F) /* Reserved Point of Sale pages */ +#define HID_USAGE_PAGE_CAMERA_CTR uint16_t (0x90) /* Camera Control Page */ +#define HID_USAGE_PAGE_ARCADE uint16_t (0x91) /* Arcade Page */ + +/* usage definitions for the "generic desktop" page */ +#define HID_USAGE_UNDEFINED uint16_t (0x00) /* Undefined */ +#define HID_USAGE_POINTER uint16_t (0x01) /* Pointer (Physical Collection) */ +#define HID_USAGE_MOUSE uint16_t (0x02) /* Mouse (Application Collection) */ +#define HID_USAGE_JOYSTICK uint16_t (0x04) /* Joystick (Application Collection) */ +#define HID_USAGE_GAMEPAD uint16_t (0x05) /* Game Pad (Application Collection) */ +#define HID_USAGE_KBD uint16_t (0x06) /* Keyboard (Application Collection) */ +#define HID_USAGE_KEYPAD uint16_t (0x07) /* Keypad (Application Collection) */ +#define HID_USAGE_MAX_CTR uint16_t (0x08) /* Multi-axis Controller (Application Collection) */ +#define HID_USAGE_X uint16_t (0x30) /* X (Dynamic Value) */ +#define HID_USAGE_Y uint16_t (0x31) /* Y (Dynamic Value) */ +#define HID_USAGE_Z uint16_t (0x32) /* Z (Dynamic Value) */ +#define HID_USAGE_RX uint16_t (0x33) /* Rx (Dynamic Value) */ +#define HID_USAGE_RY uint16_t (0x34) /* Ry (Dynamic Value) */ +#define HID_USAGE_RZ uint16_t (0x35) /* Rz (Dynamic Value) */ +#define HID_USAGE_SLIDER uint16_t (0x36) /* Slider (Dynamic Value) */ +#define HID_USAGE_DIAL uint16_t (0x37) /* Dial (Dynamic Value) */ +#define HID_USAGE_WHEEL uint16_t (0x38) /* Wheel (Dynamic Value) */ +#define HID_USAGE_HATSW uint16_t (0x39) /* Hat switch (Dynamic Value) */ +#define HID_USAGE_COUNTEDBUF uint16_t (0x3A) /* Counted Buffer (Logical Collection) */ +#define HID_USAGE_BYTECOUNT uint16_t (0x3B) /* Byte Count (Dynamic Value) */ +#define HID_USAGE_MOTIONWAKE uint16_t (0x3C) /* Motion Wakeup (One Shot Control) */ +#define HID_USAGE_START uint16_t (0x3D) /* Start (On/Off Control) */ +#define HID_USAGE_SELECT uint16_t (0x3E) /* Select (On/Off Control) */ +#define HID_USAGE_VX uint16_t (0x40) /* Vx (Dynamic Value) */ +#define HID_USAGE_VY uint16_t (0x41) /* Vy (Dynamic Value) */ +#define HID_USAGE_VZ uint16_t (0x42) /* Vz (Dynamic Value) */ +#define HID_USAGE_VBRX uint16_t (0x43) /* Vbrx (Dynamic Value) */ +#define HID_USAGE_VBRY uint16_t (0x44) /* Vbry (Dynamic Value) */ +#define HID_USAGE_VBRZ uint16_t (0x45) /* Vbrz (Dynamic Value) */ +#define HID_USAGE_VNO uint16_t (0x46) /* Vno (Dynamic Value) */ +#define HID_USAGE_FEATNOTIF uint16_t (0x47) /* Feature Notification (Dynamic Value),(Dynamic Flag) */ +#define HID_USAGE_SYSCTL uint16_t (0x80) /* System Control (Application Collection) */ +#define HID_USAGE_PWDOWN uint16_t (0x81) /* System Power Down (One Shot Control) */ +#define HID_USAGE_SLEEP uint16_t (0x82) /* System Sleep (One Shot Control) */ +#define HID_USAGE_WAKEUP uint16_t (0x83) /* System Wake Up (One Shot Control) */ +#define HID_USAGE_CONTEXTM uint16_t (0x84) /* System Context Menu (One Shot Control) */ +#define HID_USAGE_MAINM uint16_t (0x85) /* System Main Menu (One Shot Control) */ +#define HID_USAGE_APPM uint16_t (0x86) /* System App Menu (One Shot Control) */ +#define HID_USAGE_MENUHELP uint16_t (0x87) /* System Menu Help (One Shot Control) */ +#define HID_USAGE_MENUEXIT uint16_t (0x88) /* System Menu Exit (One Shot Control) */ +#define HID_USAGE_MENUSELECT uint16_t (0x89) /* System Menu Select (One Shot Control) */ +#define HID_USAGE_SYSM_RIGHT uint16_t (0x8A) /* System Menu Right (Re-Trigger Control) */ +#define HID_USAGE_SYSM_LEFT uint16_t (0x8B) /* System Menu Left (Re-Trigger Control) */ +#define HID_USAGE_SYSM_UP uint16_t (0x8C) /* System Menu Up (Re-Trigger Control) */ +#define HID_USAGE_SYSM_DOWN uint16_t (0x8D) /* System Menu Down (Re-Trigger Control) */ +#define HID_USAGE_COLDRESET uint16_t (0x8E) /* System Cold Restart (One Shot Control) */ +#define HID_USAGE_WARMRESET uint16_t (0x8F) /* System Warm Restart (One Shot Control) */ +#define HID_USAGE_DUP uint16_t (0x90) /* D-pad Up (On/Off Control) */ +#define HID_USAGE_DDOWN uint16_t (0x91) /* D-pad Down (On/Off Control) */ +#define HID_USAGE_DRIGHT uint16_t (0x92) /* D-pad Right (On/Off Control) */ +#define HID_USAGE_DLEFT uint16_t (0x93) /* D-pad Left (On/Off Control) */ +#define HID_USAGE_SYS_DOCK uint16_t (0xA0) /* System Dock (One Shot Control) */ +#define HID_USAGE_SYS_UNDOCK uint16_t (0xA1) /* System Undock (One Shot Control) */ +#define HID_USAGE_SYS_SETUP uint16_t (0xA2) /* System Setup (One Shot Control) */ +#define HID_USAGE_SYS_BREAK uint16_t (0xA3) /* System Break (One Shot Control) */ +#define HID_USAGE_SYS_DBGBRK uint16_t (0xA4) /* System Debugger Break (One Shot Control) */ +#define HID_USAGE_APP_BRK uint16_t (0xA5) /* Application Break (One Shot Control) */ +#define HID_USAGE_APP_DBGBRK uint16_t (0xA6) /* Application Debugger Break (One Shot Control) */ +#define HID_USAGE_SYS_SPKMUTE uint16_t (0xA7) /* System Speaker Mute (One Shot Control) */ +#define HID_USAGE_SYS_HIBERN uint16_t (0xA8) /* System Hibernate (One Shot Control) */ +#define HID_USAGE_SYS_SIDPINV uint16_t (0xB0) /* System Display Invert (One Shot Control) */ +#define HID_USAGE_SYS_DISPINT uint16_t (0xB1) /* System Display Internal (One Shot Control) */ +#define HID_USAGE_SYS_DISPEXT uint16_t (0xB2) /* System Display External (One Shot Control) */ +#define HID_USAGE_SYS_DISPBOTH uint16_t (0xB3) /* System Display Both (One Shot Control) */ +#define HID_USAGE_SYS_DISPDUAL uint16_t (0xB4) /* System Display Dual (One Shot Control) */ +#define HID_USAGE_SYS_DISPTGLIE uint16_t (0xB5) /* System Display Toggle Int/Ext (One Shot Control) */ +#define HID_USAGE_SYS_DISP_SWAP uint16_t (0xB6) /* System Display Swap Primary/Secondary (One Shot Control) */ +#define HID_USAGE_SYS_DIPS_LCDA uint16_t (0xB7) /* System Display LCD Autoscale (One Shot Control) */ + +#endif /* __USDH_HID_USAGE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_core.c new file mode 100644 index 0000000000..88311ce308 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_core.c @@ -0,0 +1,675 @@ +/*! + \file usbh_hid_core.c + \brief USB host HID class driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_pipe.h" +#include "usbh_hid_core.h" +#include "usbh_hid_mouse.h" +#include "usbh_hid_keybd.h" +#include +#include + +static void usbh_hiddesc_parse (usb_desc_hid *hid_desc, uint8_t *buf); +static void usbh_hid_itf_deinit (usbh_host *uhost); +static usbh_status usbh_hid_itf_init (usbh_host *uhost); +static usbh_status usbh_hid_class_req (usbh_host *uhost); +static usbh_status usbh_hid_handle (usbh_host *uhost); +static usbh_status usbh_hid_reportdesc_get (usbh_host *uhost, uint16_t len); +static usbh_status usbh_hid_sof(usbh_host *uhost); +static usbh_status usbh_hid_desc_get (usbh_host *uhost, uint16_t len); +static usbh_status usbh_set_idle (usbh_host *uhost, uint8_t duration, uint8_t report_ID); +static usbh_status usbh_set_protocol (usbh_host *uhost, uint8_t protocol); + +usbh_class usbh_hid = +{ + USB_HID_CLASS, + usbh_hid_itf_init, + usbh_hid_itf_deinit, + usbh_hid_class_req, + usbh_hid_handle, + usbh_hid_sof +}; + +/*! + \brief get report + \param[in] uhost: pointer to USB host + \param[in] report_type: duration for HID set idle request + \param[in] report_ID: targeted report ID for HID set idle request + \param[in] report_len: length of data report to be send + \param[in] report_buf: report buffer + \param[out] none + \retval operation status +*/ +usbh_status usbh_get_report (usbh_host *uhost, + uint8_t report_type, + uint8_t report_ID, + uint8_t report_len, + uint8_t *report_buf) +{ + usbh_status status = USBH_BUSY; + + if (CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_RECPTYPE_ITF | USB_REQTYPE_CLASS, + .bRequest = GET_REPORT, + .wValue = (report_type << 8U) | report_ID, + .wIndex = 0U, + .wLength = report_len + }; + + usbh_ctlstate_config (uhost, report_buf, report_len); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief set report + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[in] report_type: duration for HID set idle request + \param[in] report_ID: targeted report ID for HID set idle request + \param[in] report_len: length of data report to be send + \param[in] report_buf: report buffer + \param[out] none + \retval operation status +*/ +usbh_status usbh_set_report (usb_core_driver *udev, + usbh_host *uhost, + uint8_t report_type, + uint8_t report_ID, + uint8_t report_len, + uint8_t *report_buf) +{ + usbh_status status = USBH_BUSY; + + if (CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_ITF | USB_REQTYPE_CLASS, + .bRequest = SET_REPORT, + .wValue = (report_type << 8U) | report_ID, + .wIndex = 0U, + .wLength = report_len + }; + + usbh_ctlstate_config (uhost, report_buf, report_len); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief get device type + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval hid_type +*/ +hid_type usbh_hid_device_type_get(usb_core_driver *udev, usbh_host *uhost) +{ + hid_type type = HID_UNKNOWN; + uint8_t interface_protocol; + + if (HOST_CLASS_HANDLER == uhost->cur_state) { + interface_protocol = uhost->dev_prop.cfg_desc_set.itf_desc_set[uhost->dev_prop.cur_itf][0].itf_desc.bInterfaceProtocol; + + if (USB_HID_PROTOCOL_KEYBOARD == interface_protocol) { + type = HID_KEYBOARD; + } else { + if (USB_HID_PROTOCOL_MOUSE == interface_protocol) { + type = HID_MOUSE; + } + } + } + + return type; +} + +/*! + \brief get HID device poll time + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval poll time (ms) +*/ +uint8_t usbh_hid_poll_interval_get (usb_core_driver *udev, usbh_host *uhost) +{ + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + if ((HOST_CLASS_ENUM == uhost->cur_state) || + (HOST_USER_INPUT == uhost->cur_state) || + (HOST_CHECK_CLASS == uhost->cur_state) || + (HOST_CLASS_HANDLER == uhost->cur_state)) { + return (uint8_t)(hid->poll); + } else { + return 0U; + } +} + +/*! + \brief read from FIFO + \param[in] fifo: FIFO address + \param[in] buf: read buffer + \param[in] nbytes: number of item to read + \param[out] none + \retval number of read items +*/ +uint16_t usbh_hid_fifo_read (data_fifo *fifo, void *buf, uint16_t nbytes) +{ + uint16_t i = 0U; + uint8_t *p = (uint8_t*) buf; + + if (0U == fifo->lock) { + fifo->lock = 1U; + + for (i = 0U; i < nbytes; i++) { + if (fifo->tail != fifo->head) { + *p++ = fifo->buf[fifo->tail]; + fifo->tail++; + + if (fifo->tail == fifo->size) { + fifo->tail = 0U; + } + } else { + fifo->lock = 0U; + + return i; + } + } + } + + fifo->lock = 0U; + + return nbytes; +} + +/*! + \brief write to FIFO + \param[in] fifo: FIFO address + \param[in] buf: read buffer + \param[in] nbytes: number of item to read + \param[out] none + \retval number of write items +*/ +uint16_t usbh_hid_fifo_write (data_fifo *fifo, void *buf, uint16_t nbytes) +{ + uint16_t i = 0U; + uint8_t *p = (uint8_t*) buf; + + if (0U == fifo->lock) { + fifo->lock = 1U; + + for (i = 0U; i < nbytes; i++) { + if ((fifo->head + 1U == fifo->tail) || + ((fifo->head + 1U == fifo->size) && (0U == fifo->tail))) { + fifo->lock = 0U; + + return i; + } else { + fifo->buf[fifo->head] = *p++; + fifo->head++; + + if (fifo->head == fifo->size) { + fifo->head = 0U; + } + } + } + } + + fifo->lock = 0U; + + return nbytes; +} + +/*! + \brief initialize FIFO + \param[in] fifo: FIFO address + \param[in] buf: read buffer + \param[in] size: size of FIFO + \param[out] none + \retval none +*/ +void usbh_hid_fifo_init (data_fifo *fifo, uint8_t *buf, uint16_t size) +{ + fifo->head = 0U; + fifo->tail = 0U; + fifo->lock = 0U; + fifo->size = size; + fifo->buf = buf; +} + +/*! + \brief parse the HID descriptor + \param[in] hid_desc: pointer to HID descriptor + \param[in] buf: pointer to buffer where the source descriptor is available + \param[out] none + \retval none +*/ +static void usbh_hiddesc_parse (usb_desc_hid *hid_desc, uint8_t *buf) +{ + hid_desc->header.bLength = *(uint8_t *)(buf + 0U); + hid_desc->header.bDescriptorType = *(uint8_t *)(buf + 1U); + hid_desc->bcdHID = BYTE_SWAP(buf + 2U); + hid_desc->bCountryCode = *(uint8_t *)(buf + 4U); + hid_desc->bNumDescriptors = *(uint8_t *)(buf + 5U); + hid_desc->bDescriptorType = *(uint8_t *)(buf + 6U); + hid_desc->wDescriptorLength = BYTE_SWAP(buf + 7U); +} + +/*! + \brief de-initialize the host pipes used for the HID class + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void usbh_hid_itf_deinit (usbh_host *uhost) +{ + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + if (0x00U != hid->pipe_in) { + usb_pipe_halt (uhost->data, hid->pipe_in); + + usbh_pipe_free (uhost->data, hid->pipe_in); + + /* reset the pipe as free */ + hid->pipe_in = 0U; + } + + if (0x00U != hid->pipe_out) { + usb_pipe_halt (uhost->data, hid->pipe_out); + + usbh_pipe_free (uhost->data, hid->pipe_out); + + /* reset the pipe as free */ + hid->pipe_out = 0U; + } +} + +/*! + \brief initialize the hid class + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_itf_init (usbh_host *uhost) +{ + uint8_t num = 0U, ep_num = 0U, interface = 0U; + usbh_status status = USBH_BUSY; + + interface = usbh_interface_find(&uhost->dev_prop, USB_HID_CLASS, USB_HID_SUBCLASS_BOOT_ITF, 0xFFU); + + if (0xFFU == interface) { + uhost->usr_cb->dev_not_supported(); + + status = USBH_FAIL; + } else { + usbh_interface_select(&uhost->dev_prop, interface); + + static usbh_hid_handler hid_handler; + + memset((void*)&hid_handler, 0, sizeof(usbh_hid_handler)); + + hid_handler.state = HID_ERROR; + + uint8_t itf_protocol = uhost->dev_prop.cfg_desc_set.itf_desc_set[uhost->dev_prop.cur_itf][0].itf_desc.bInterfaceProtocol; + if (USB_HID_PROTOCOL_KEYBOARD == itf_protocol) { + hid_handler.init = usbh_hid_keybd_init; + hid_handler.machine = usbh_hid_keybrd_machine; + } else if (USB_HID_PROTOCOL_MOUSE == itf_protocol) { + hid_handler.init = usbh_hid_mouse_init; + hid_handler.machine = usbh_hid_mouse_machine; + } else { + status = USBH_FAIL; + } + + hid_handler.state = HID_INIT; + hid_handler.ctl_state = HID_REQ_INIT; + hid_handler.ep_addr = uhost->dev_prop.cfg_desc_set.itf_desc_set[uhost->dev_prop.cur_itf][0].ep_desc[0].bEndpointAddress; + hid_handler.len = uhost->dev_prop.cfg_desc_set.itf_desc_set[uhost->dev_prop.cur_itf][0].ep_desc[0].wMaxPacketSize; + hid_handler.poll = uhost->dev_prop.cfg_desc_set.itf_desc_set[uhost->dev_prop.cur_itf][0].ep_desc[0].bInterval; + + if (hid_handler.poll < HID_MIN_POLL) { + hid_handler.poll = HID_MIN_POLL; + } + + /* check FIFO available number of endpoints */ + /* find the number of endpoints in the interface descriptor */ + /* choose the lower number in order not to overrun the buffer allocated */ + ep_num = USB_MIN(uhost->dev_prop.cfg_desc_set.itf_desc_set[uhost->dev_prop.cur_itf][0].itf_desc.bNumEndpoints, USBH_MAX_EP_NUM); + + /* decode endpoint IN and OUT address from interface descriptor */ + for (num = 0U; num < ep_num; num++) { + usb_desc_ep *ep_desc = &uhost->dev_prop.cfg_desc_set.itf_desc_set[uhost->dev_prop.cur_itf][0].ep_desc[num]; + + uint8_t ep_addr = ep_desc->bEndpointAddress; + + if (ep_addr & 0x80U) { + hid_handler.ep_in = ep_addr; + hid_handler.pipe_in = usbh_pipe_allocate (uhost->data, ep_addr); + + /* open channel for IN endpoint */ + usbh_pipe_create (uhost->data, + &uhost->dev_prop, + hid_handler.pipe_in, + USB_EPTYPE_INTR, + hid_handler.len); + + usbh_pipe_toggle_set(uhost->data, hid_handler.pipe_in, 0U); + } else { + hid_handler.ep_out = ep_addr; + hid_handler.pipe_out = usbh_pipe_allocate (uhost->data, ep_addr); + + /* open channel for OUT endpoint */ + usbh_pipe_create (uhost->data, + &uhost->dev_prop, + hid_handler.pipe_out, + USB_EPTYPE_INTR, + hid_handler.len); + + usbh_pipe_toggle_set(uhost->data, hid_handler.pipe_out, 0U); + } + } + + uhost->active_class->class_data = (void *)&hid_handler; + + status = USBH_OK; + } + + return status; +} + +/*! + \brief handle HID class requests for HID class + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_class_req (usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + usbh_status class_req_status = USBH_BUSY; + + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + /* handle HID control state machine */ + switch (hid->ctl_state) { + case HID_REQ_INIT: + case HID_REQ_GET_HID_DESC: + /* get HID descriptor */ + if (USBH_OK == usbh_hid_desc_get (uhost, USB_HID_DESC_SIZE)) { + usbh_hiddesc_parse(&hid->hid_desc, uhost->dev_prop.data); + + hid->ctl_state = HID_REQ_GET_REPORT_DESC; + } + break; + + case HID_REQ_GET_REPORT_DESC: + /* get report descriptor */ + if (USBH_OK == usbh_hid_reportdesc_get(uhost, hid->hid_desc.wDescriptorLength)) { + hid->ctl_state = HID_REQ_SET_IDLE; + } + break; + + case HID_REQ_SET_IDLE: + class_req_status = usbh_set_idle (uhost, 0U, 0U); + + /* set idle */ + if (USBH_OK == class_req_status) { + hid->ctl_state = HID_REQ_SET_PROTOCOL; + } else { + if(USBH_NOT_SUPPORTED == class_req_status) { + hid->ctl_state = HID_REQ_SET_PROTOCOL; + } + } + break; + + case HID_REQ_SET_PROTOCOL: + /* set protocol */ + if (USBH_OK == usbh_set_protocol (uhost, 0U)) { + hid->ctl_state = HID_REQ_IDLE; + + /* all requests performed */ + status = USBH_OK; + } + break; + + case HID_REQ_IDLE: + default: + break; + } + + return status; +} + +/*! + \brief manage state machine for HID data transfers + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_handle (usbh_host *uhost) +{ + usbh_status status = USBH_OK; + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + switch (hid->state) { + case HID_INIT: + hid->init(uhost->data, uhost); + hid->state = HID_IDLE; + break; + + case HID_IDLE: + hid->state = HID_SYNC; + status = USBH_OK; + break; + + case HID_SYNC: + /* sync with start of even frame */ + if (true == usb_frame_even(uhost->data)) { + hid->state = HID_GET_DATA; + } + break; + + case HID_GET_DATA: + usbh_data_recev (uhost->data, hid->pdata, hid->pipe_in, hid->len); + + hid->state = HID_POLL; + hid->timer = usb_curframe_get (uhost->data); + hid->data_ready = 0U; + break; + + case HID_POLL: + if (URB_DONE == usbh_urbstate_get (uhost->data, hid->pipe_in)) { + if (0U == hid->data_ready) { /* handle data once */ + usbh_hid_fifo_write(&hid->fifo, hid->pdata, hid->len); + hid->data_ready = 1U; + hid->machine(uhost->data, uhost); + } + } else { + if (URB_STALL == usbh_urbstate_get (uhost->data, hid->pipe_in)) { /* IN endpoint stalled */ + /* issue clear feature on interrupt in endpoint */ + if (USBH_OK == (usbh_clrfeature (uhost, hid->ep_addr, hid->pipe_in))) { + /* change state to issue next in token */ + hid->state = HID_GET_DATA; + } + } + } + break; + + default: + break; + } + return status; +} + +/*! + \brief send get report descriptor command to the device + \param[in] uhost: pointer to USB host + \param[in] len: HID report descriptor length + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_reportdesc_get (usbh_host *uhost, uint16_t len) +{ + usbh_status status = USBH_BUSY; + + if (CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_RECPTYPE_ITF | USB_REQTYPE_STRD, + .bRequest = USB_GET_DESCRIPTOR, + .wValue = USBH_DESC(USB_DESCTYPE_REPORT), + .wIndex = 0U, + .wLength = len + }; + + usbh_ctlstate_config (uhost, uhost->dev_prop.data, len); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief managing the SOF process + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_sof(usbh_host *uhost) +{ + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + if (HID_POLL == hid->state) { + uint32_t frame_count = usb_curframe_get (uhost->data); + + if ((frame_count > hid->timer) && ((frame_count - hid->timer) >= hid->poll)) { + hid->state = HID_GET_DATA; + } else if ((frame_count < hid->timer) && ((frame_count + 0x3FFFU - hid->timer) >= hid->poll)) { + hid->state = HID_GET_DATA; + } else { + /* no operation */ + } + } + + return USBH_OK; +} + +/*! + \brief send the command of get HID descriptor to the device + \param[in] uhost: pointer to USB host + \param[in] len: HID descriptor length + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_desc_get (usbh_host *uhost, uint16_t len) +{ + usbh_status status = USBH_BUSY; + + if (CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_RECPTYPE_ITF | USB_REQTYPE_STRD, + .bRequest = USB_GET_DESCRIPTOR, + .wValue = USBH_DESC(USB_DESCTYPE_HID), + .wIndex = 0U, + .wLength = len + }; + + usbh_ctlstate_config (uhost, uhost->dev_prop.data, len); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief set idle state + \param[in] uhost: pointer to USB host + \param[in] duration: duration for HID set idle request + \param[in] report_ID: targeted report ID for HID set idle request + \param[out] none + \retval operation status +*/ +static usbh_status usbh_set_idle (usbh_host *uhost, uint8_t duration, uint8_t report_ID) +{ + usbh_status status = USBH_BUSY; + + if (CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_ITF | USB_REQTYPE_CLASS, + .bRequest = SET_IDLE, + .wValue = (duration << 8U) | report_ID, + .wIndex = 0U, + .wLength = 0U + }; + + usbh_ctlstate_config (uhost, NULL, 0U); + } + + status = usbh_ctl_handler (uhost); + + return status; +} + +/*! + \brief set protocol state + \param[in] uhost: pointer to USB host + \param[in] protocol: boot/report protocol + \param[out] none + \retval operation status +*/ +static usbh_status usbh_set_protocol (usbh_host *uhost, uint8_t protocol) +{ + usbh_status status = USBH_BUSY; + + if (CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_ITF | USB_REQTYPE_CLASS, + .bRequest = SET_PROTOCOL, + .wValue = !protocol, + .wIndex = 0U, + .wLength = 0U + }; + + usbh_ctlstate_config (uhost, NULL, 0U); + } + + status = usbh_ctl_handler (uhost); + + return status; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_keybd.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_keybd.c new file mode 100644 index 0000000000..2dfca3ce86 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_keybd.c @@ -0,0 +1,398 @@ +/*! + \file usbh_hid_keybd.c + \brief USB host HID keyboard driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_hid_keybd.h" +#include "usbh_hid_parser.h" +#include + +hid_keybd_info keybd_info; +uint32_t keybd_report_data[2]; + +static const hid_report_item imp_0_lctrl = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 0, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_lshift = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 1, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_lalt = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 2, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_lgui = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 3, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_rctrl = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 4, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_rshift = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 5, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_ralt = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 6, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_rgui = +{ + (uint8_t*)(void *)keybd_report_data + 0, /* data */ + 1, /* size */ + 7, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +static const hid_report_item imp_0_key_array = +{ + (uint8_t*)(void *)keybd_report_data + 2, /* data */ + 8, /* size */ + 0, /* shift */ + 6, /* count (only for array items) */ + 0, /* signed */ + 0, /* min value read can return */ + 101, /* max value read can return */ + 0, /* min vale device can report */ + 101, /* max value device can report */ + 1 /* resolution */ +}; + +/* local constants */ +static const uint8_t hid_keybrd_codes[] = +{ + 0, 0, 0, 0, 31, 50, 48, 33, + 19, 34, 35, 36, 24, 37, 38, 39, /* 0x00 - 0x0F */ + 52, 51, 25, 26, 17, 20, 32, 21, + 23, 49, 18, 47, 22, 46, 2, 3, /* 0x10 - 0x1F */ + 4, 5, 6, 7, 8, 9, 10, 11, + 43, 110, 15, 16, 61, 12, 13, 27, /* 0x20 - 0x2F */ + 28, 29, 42, 40, 41, 1, 53, 54, + 55, 30, 112, 113, 114, 115, 116, 117, /* 0x30 - 0x3F */ + 118, 119, 120, 121, 122, 123, 124, 125, + 126, 75, 80, 85, 76, 81, 86, 89, /* 0x40 - 0x4F */ + 79, 84, 83, 90, 95, 100, 105, 106, + 108, 93, 98, 103, 92, 97, 102, 91, /* 0x50 - 0x5F */ + 96, 101, 99, 104, 45, 129, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6F */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */ + 0, 0, 0, 0, 0, 107, 0, 56, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9F */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xAF */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 - 0xBF */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 - 0xCF */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 - 0xDF */ + 58, 44, 60, 127, 64, 57, 62, 128 /* 0xE0 - 0xE7 */ +}; + +#ifdef QWERTY_KEYBOARD + +static const int8_t hid_keybrd_key[] = +{ + '\0', '`', '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '\0', '\r', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', + 'i', 'o', 'p', '[', ']', '\\', + '\0', 'a', 's', 'd', 'f', 'g', 'h', 'j', + 'k', 'l', ';', '\'', '\0', '\n', + '\0', '\0', 'z', 'x', 'c', 'v', 'b', 'n', + 'm', ',', '.', '/', '\0', '\0', + '\0', '\0', '\0', ' ', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '7', '4', '1', + '\0', '/', '8', '5', '2', + '0', '*', '9', '6', '3', + '.', '-', '+', '\0', '\n', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0' +}; + +static const int8_t hid_keybrd_shiftkey[] = { + '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + '_', '+', '\0', '\0', '\0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', + 'I', 'O', 'P', '{', '}', '|', '\0', 'A', 'S', 'D', 'F', 'G', + 'H', 'J', 'K', 'L', ':', '"', '\0', '\n', '\0', '\0', 'Z', 'X', + 'C', 'V', 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}; + +#else + +static const int8_t hid_keybrd_key[] = { + '\0', '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + '-', '=', '\0', '\r', '\t', 'a', 'z', 'e', 'r', 't', 'y', 'u', + 'i', 'o', 'p', '[', ']', '\\', '\0', 'q', 's', 'd', 'f', 'g', + 'h', 'j', 'k', 'l', 'm', '\0', '\0', '\n', '\0', '\0', 'w', 'x', + 'c', 'v', 'b', 'n', ',', ';', ':', '!', '\0', '\0', '\0', '\0', + '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\r', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '7', '4', '1', '\0', '/', + '8', '5', '2', '0', '*', '9', '6', '3', '.', '-', '+', '\0', + '\n', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}; + +static const int8_t hid_keybrd_shiftkey[] = { + '\0', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', + '+', '\0', '\0', '\0', 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', + 'P', '{', '}', '*', '\0', 'Q', 'S', 'D', 'F', 'G', 'H', 'J', 'K', + 'L', 'M', '%', '\0', '\n', '\0', '\0', 'W', 'X', 'C', 'V', 'B', 'N', + '?', '.', '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' +}; + +#endif + +/* local function prototypes ('static') */ +static usbh_status usbh_hid_keybrd_decode (usb_core_driver *udev, usbh_host *uhost); + +/*! + \brief initialize the keyboard function + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +usbh_status usbh_hid_keybd_init (usb_core_driver *udev, usbh_host *uhost) +{ + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + keybd_info.lctrl = keybd_info.lshift = 0U; + keybd_info.lalt = keybd_info.lgui = 0U; + keybd_info.rctrl = keybd_info.rshift = 0U; + keybd_info.ralt = keybd_info.rgui = 0U; + + for (uint32_t x = 0U; x < (sizeof(keybd_report_data) / sizeof(uint32_t)); x++) { + keybd_report_data[x] = 0U; + } + + if (hid->len > (sizeof(keybd_report_data) / sizeof(uint32_t))) { + hid->len = (sizeof(keybd_report_data) / sizeof(uint32_t)); + } + + hid->pdata = (uint8_t*)(void *)keybd_report_data; + + usbh_hid_fifo_init (&hid->fifo, uhost->dev_prop.data, HID_QUEUE_SIZE * sizeof(keybd_report_data)); + + /* call user initialization*/ + usr_keybrd_init(); + + return USBH_OK; +} + +/*! + \brief get keyboard information + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host handler + \param[out] none + \retval keyboard information +*/ +hid_keybd_info *usbh_hid_keybd_info_get (usb_core_driver *udev, usbh_host *uhost) +{ + if (USBH_OK == usbh_hid_keybrd_decode(udev, uhost)) { + return &keybd_info; + } else { + return NULL; + } +} + +/*! + \brief get ASCII code + \param[in] info: keyboard information + \param[out] none + \retval output +*/ +uint8_t usbh_hid_ascii_code_get (hid_keybd_info *info) +{ + uint8_t output; + if ((1U == info->lshift) || (info->rshift)) { + output = hid_keybrd_shiftkey[hid_keybrd_codes[info->keys[0]]]; + } else { + output = hid_keybrd_key[hid_keybrd_codes[info->keys[0]]]; + } + + return output; +} + +/*! + \brief decode the pressed keys + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void usbh_hid_keybrd_machine (usb_core_driver *udev, usbh_host *uhost) +{ + hid_keybd_info *k_pinfo; + + k_pinfo = usbh_hid_keybd_info_get(udev, uhost); + + if (k_pinfo != NULL) { + char c = usbh_hid_ascii_code_get(k_pinfo); + + if (c != 0U) { + usr_keybrd_process_data(c); + } + } +} + +/*! + \brief decode keyboard information + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_keybrd_decode (usb_core_driver *udev, usbh_host *uhost) +{ + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + if (0U == hid->len) { + return USBH_FAIL; + } + + /* fill report */ + if (usbh_hid_fifo_read (&hid->fifo, &keybd_report_data, hid->len) == hid->len) { + keybd_info.lctrl = (uint8_t)hid_item_read((hid_report_item *)&imp_0_lctrl, 0U); + keybd_info.lshift = (uint8_t)hid_item_read((hid_report_item *)&imp_0_lshift, 0U); + keybd_info.lalt = (uint8_t)hid_item_read((hid_report_item *)&imp_0_lalt, 0U); + keybd_info.lgui = (uint8_t)hid_item_read((hid_report_item *)&imp_0_lgui, 0U); + keybd_info.rctrl = (uint8_t)hid_item_read((hid_report_item *)&imp_0_rctrl, 0U); + keybd_info.rshift = (uint8_t)hid_item_read((hid_report_item *)&imp_0_rshift, 0U); + keybd_info.ralt = (uint8_t)hid_item_read((hid_report_item *)&imp_0_ralt, 0U); + keybd_info.rgui = (uint8_t)hid_item_read((hid_report_item *)&imp_0_rgui, 0U); + + for (uint8_t x = 0U; x < sizeof(keybd_info.keys); x++) { + keybd_info.keys[x] = (uint8_t)hid_item_read((hid_report_item *)&imp_0_key_array, x); + } + + return USBH_OK; + } + + return USBH_FAIL; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_mouse.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_mouse.c new file mode 100644 index 0000000000..6ba27a5e03 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_mouse.c @@ -0,0 +1,217 @@ +/*! + \file usbh_hid_mouse.c + \brief USB host HID mouse driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_hid_mouse.h" +#include "usbh_hid_parser.h" +//#include "usbh_hid_usr.h" + +hid_mouse_info mouse_info; +uint32_t mouse_report_data[2]; + +/* structures defining how to access items in a hid mouse report */ +/* access button 1 state. */ +static const hid_report_item prop_b1 = +{ + (uint8_t *)(void *)mouse_report_data + 0, /* data */ + 1, /* size */ + 0, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed? */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min value device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +/* access button 2 state. */ +static const hid_report_item prop_b2 = +{ + (uint8_t *)(void *)mouse_report_data + 0, /* data */ + 1, /* size */ + 1, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed? */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min value device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +/* access button 3 state. */ +static const hid_report_item prop_b3 = +{ + (uint8_t *)(void *)mouse_report_data + 0, /* data */ + 1, /* size */ + 2, /* shift */ + 0, /* count (only for array items) */ + 0, /* signed? */ + 0, /* min value read can return */ + 1, /* max value read can return */ + 0, /* min vale device can report */ + 1, /* max value device can report */ + 1 /* resolution */ +}; + +/* access x coordinate change. */ +static const hid_report_item prop_x = +{ + (uint8_t *)(void *)mouse_report_data + 1, /* data */ + 8, /* size */ + 0, /* shift */ + 0, /* count (only for array items) */ + 1, /* signed? */ + 0, /* min value read can return */ + 0xFFFF,/* max value read can return */ + 0, /* min vale device can report */ + 0xFFFF,/* max value device can report */ + 1 /* resolution */ +}; + +/* access y coordinate change. */ +static const hid_report_item prop_y = +{ + (uint8_t *)(void *)mouse_report_data + 2, /* data */ + 8, /* size */ + 0, /* shift */ + 0, /* count (only for array items) */ + 1, /* signed? */ + 0, /* min value read can return */ + 0xFFFF,/* max value read can return */ + 0, /* min vale device can report */ + 0xFFFF,/* max value device can report */ + 1 /* resolution */ +}; + +/* local function prototypes ('static') */ +static usbh_status usbh_hid_mouse_decode(usb_core_driver *udev, usbh_host *uhost); + +/*! + \brief initialize the mouse function + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +usbh_status usbh_hid_mouse_init (usb_core_driver *udev, usbh_host *uhost) +{ + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + mouse_info.x = 0U; + mouse_info.y = 0U; + mouse_info.buttons[0] = 0U; + mouse_info.buttons[1] = 0U; + mouse_info.buttons[2] = 0U; + + mouse_report_data[0] = 0U; + + if(hid->len > sizeof(mouse_report_data)) { + hid->len = sizeof(mouse_report_data); + } + + hid->pdata = (uint8_t *)(void *)mouse_report_data; + + usbh_hid_fifo_init(&hid->fifo, uhost->dev_prop.data, HID_QUEUE_SIZE * sizeof(mouse_report_data)); + + usr_mouse_init(); + + return USBH_OK; +} + +/*! + \brief get mouse information + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval mouse information +*/ +hid_mouse_info *usbh_hid_mouse_info_get (usb_core_driver *udev, usbh_host *uhost) +{ + if(usbh_hid_mouse_decode(udev, uhost)== USBH_OK) { + return &mouse_info; + } else { + return NULL; + } +} + +/*! + \brief decode mouse data + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void usbh_hid_mouse_machine (usb_core_driver *udev, usbh_host *uhost) +{ + hid_mouse_info *m_pinfo = NULL; + + m_pinfo = usbh_hid_mouse_info_get(udev, uhost); + + if (NULL != m_pinfo) { + /* handle mouse data position */ + usr_mouse_process_data(&mouse_info); + } +} + +/*! + \brief decode mouse information + \param[in] udev: pointer to USB core instance + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_hid_mouse_decode(usb_core_driver *udev, usbh_host *uhost) +{ + usbh_hid_handler *hid = (usbh_hid_handler *)uhost->active_class->class_data; + + if (0U == hid->len) { + return USBH_FAIL; + } + + /* fill report */ + if (usbh_hid_fifo_read(&hid->fifo, &mouse_report_data, hid->len) == hid->len) { + /* decode report */ + mouse_info.x = (uint8_t)hid_item_read((hid_report_item *)&prop_x, 0U); + mouse_info.y = (uint8_t)hid_item_read((hid_report_item *)&prop_y, 0U); + + mouse_info.buttons[0] = (uint8_t)hid_item_read((hid_report_item *)&prop_b1, 0U); + mouse_info.buttons[1] = (uint8_t)hid_item_read((hid_report_item *)&prop_b2, 0U); + mouse_info.buttons[2] = (uint8_t)hid_item_read((hid_report_item *)&prop_b3, 0U); + + return USBH_OK; + } + + return USBH_FAIL; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_parser.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_parser.c new file mode 100644 index 0000000000..cfc78aff20 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/hid/Source/usbh_hid_parser.c @@ -0,0 +1,148 @@ +/*! + \file usbh_hid_parser.c + \brief HID layer handlers for USB host HID class + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_hid_parser.h" + +/*! + \brief read a hid report item + \param[in] ri: pointer to report item + \param[in] ndx: report index + \param[out] none + \retval operation status (0: fail otherwise: item value) +*/ +uint32_t hid_item_read (hid_report_item *ri, uint8_t ndx) +{ + uint32_t val = 0U; + uint32_t bofs = 0U; + uint8_t *data = ri->data; + uint8_t shift = ri->shift; + + /* get the logical value of the item */ + + /* if this is an array, wee may need to offset ri->data.*/ + if (ri->count > 0U) { + /* if APP tries to read outside of the array. */ + if (ri->count <= ndx) { + return(0U); + } + + /* calculate bit offset */ + bofs = ndx * ri->size; + bofs += shift; + + /* calculate byte offset + shift pair from bit offset. */ + data += bofs / 8U; + shift = (uint8_t)(bofs % 8U); + } + + /* read data bytes in little endian order */ + for (uint32_t x = 0U; x < ((ri->size & 0x7U) ? (ri->size / 8U) + 1U : (ri->size / 8U)); x++) { + val=(uint32_t)((uint32_t)(*data) << (x * 8U)); + } + + val=(val >> shift) & ((1U << ri->size) - 1U); + + if ((val < ri->logical_min) || (val > ri->logical_max)) { + return(0U); + } + + /* convert logical value to physical value */ + /* see if the number is negative or not. */ + if ((ri->sign) && (val & (1U << (ri->size - 1U)))) { + /* yes, so sign extend value to 32 bits. */ + uint32_t vs = (uint32_t)((0xffffffffU & ~((1U << (ri->size)) - 1U)) | val); + + if (1U == ri->resolution) { + return((uint32_t)vs); + } + return((uint32_t)(vs * ri->resolution)); + } else { + if (1U == ri->resolution) { + return(val); + } + + return (val * ri->resolution); + } +} + +/*! + \brief write a hid report item + \param[in] ri: pointer to report item + \param[in] value: the value to be write + \param[in] ndx: report index + \param[out] none + \retval operation status (1: fail 0: OK) +*/ +uint32_t hid_item_write(hid_report_item *ri, uint32_t value, uint8_t ndx) +{ + uint32_t mask; + uint32_t bofs; + uint8_t *data = ri->data; + uint8_t shift = ri->shift; + + if ((value < ri->physical_min) || (value > ri->physical_max)) { + return(1U); + } + + /* if this is an array, wee may need to offset ri->data.*/ + if (ri->count > 0U) { + /* if APP tries to read outside of the array. */ + if (ri->count >= ndx) { + return(0U); + } + + /* calculate bit offset */ + bofs = ndx * ri->size; + bofs += shift; + + /* calculate byte offset + shift pair from bit offset. */ + data += bofs / 8U; + shift = (uint8_t)(bofs % 8U); + } + + /* convert physical value to logical value. */ + if (1U != ri->resolution) { + value = value / ri->resolution; + } + + /* write logical value to report in little endian order. */ + mask = (1U << ri->size) - 1U; + value = (value & mask) << shift; + + for (uint32_t x = 0U; x < ((ri->size & 0x7U) ? (ri->size / 8U) + 1U : (ri->size / 8U)); x++) { + *(ri->data + x) = (uint8_t)((*(ri->data+x) & ~(mask>>(x* 8U))) | ((value >> (x * 8U)) & (mask >> (x * 8U)))); + } + + return 0U; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_bbb.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_bbb.h new file mode 100644 index 0000000000..5fe4e1bf6b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_bbb.h @@ -0,0 +1,150 @@ +/*! + \file usbh_msc_bbb.h + \brief header file for usbh_msc_bbb.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_MSC_BBB_H +#define __USBH_MSC_BBB_H + +#include "usbh_enum.h" +#include "msc_bbb.h" + +typedef union { + msc_bbb_cbw field; + + uint8_t CBWArray[31]; +}usbh_cbw_pkt; + +typedef union { + msc_bbb_csw field; + + uint8_t CSWArray[13]; +}usbh_csw_pkt; + +enum usbh_msc_state { + USBH_MSC_BOT_INIT_STATE = 0U, + USBH_MSC_BOT_RESET, + USBH_MSC_GET_MAX_LUN, + USBH_MSC_TEST_UNIT_READY, + USBH_MSC_READ_CAPACITY10, + USBH_MSC_MODE_SENSE6, + USBH_MSC_REQUEST_SENSE, + USBH_MSC_BOT_USB_TRANSFERS, + USBH_MSC_DEFAULT_APPLI_STATE, + USBH_MSC_CTRL_ERROR_STATE, + USBH_MSC_UNRECOVERED_STATE +}; + +typedef enum +{ + BOT_OK = 0U, + BOT_FAIL, + BOT_PHASE_ERROR, + BOT_BUSY +} bot_status; + +typedef enum +{ + BOT_CMD_IDLE = 0U, + BOT_CMD_SEND, + BOT_CMD_WAIT, +} bot_cmd_state; + +/* csw status definitions */ +typedef enum +{ + BOT_CSW_CMD_PASSED = 0U, + BOT_CSW_CMD_FAILED, + BOT_CSW_PHASE_ERROR, +} bot_csw_status; + +typedef enum +{ + BOT_SEND_CBW = 1U, + BOT_SEND_CBW_WAIT, + BOT_DATA_IN, + BOT_DATA_IN_WAIT, + BOT_DATA_OUT, + BOT_DATA_OUT_WAIT, + BOT_RECEIVE_CSW, + BOT_RECEIVE_CSW_WAIT, + BOT_ERROR_IN, + BOT_ERROR_OUT, + BOT_UNRECOVERED_ERROR +} bot_state; + +typedef struct +{ + uint8_t *pbuf; + uint32_t data[16]; + bot_state state; + bot_state prev_state; + bot_cmd_state cmd_state; + usbh_cbw_pkt cbw; + usbh_csw_pkt csw; +} bot_handle; + +#define USBH_MSC_BOT_CBW_TAG 0x20304050U + +#define USBH_MSC_CSW_MAX_LENGTH 63U + +#define USBH_MSC_SEND_CSW_DISABLE 0U +#define USBH_MSC_SEND_CSW_ENABLE 1U + +#define USBH_MSC_DIR_IN 0U +#define USBH_MSC_DIR_OUT 1U +#define USBH_MSC_BOTH_DIR 2U + +#define USBH_MSC_PAGE_LENGTH 512U + +#define CBW_CB_LENGTH 16U +#define CBW_LENGTH 10U +#define CBW_LENGTH_TEST_UNIT_READY 0U + +#define MAX_BULK_STALL_COUNT_LIMIT 0x04U /*!< if STALL is seen on bulk + endpoint continously, this means + that device and host has phase error + hence a reset is needed */ + +/* function declarations */ +/* initialize the mass storage parameters */ +void usbh_msc_bot_init (usbh_host *uhost); +/* manage the different states of BOT transfer and updates the status to upper layer */ +usbh_status usbh_msc_bot_process (usbh_host *uhost, uint8_t lun); +/* manages the different error handling for stall */ +usbh_status usbh_msc_bot_abort (usbh_host *uhost, uint8_t direction); +/* reset MSC bot request structure */ +usbh_status usbh_msc_bot_reset (usbh_host *uhost); +/* decode the CSW received by the device and updates the same to upper layer */ +bot_csw_status usbh_msc_csw_decode (usbh_host *uhost); + +#endif /* __USBH_MSC_BBB_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_core.h new file mode 100644 index 0000000000..55497189f1 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_core.h @@ -0,0 +1,124 @@ +/*! + \file usbh_core.h + \brief header file for the usbh_core.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_MSC_CORE_H +#define __USBH_MSC_CORE_H + +#include "usb_msc.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bbb.h" + +#define MSC_MAX_SUPPORTED_LUN 2U + +typedef enum +{ + MSC_INIT = 0U, + MSC_IDLE, + MSC_TEST_UNIT_READY, + MSC_READ_CAPACITY10, + MSC_READ_INQUIRY, + MSC_REQUEST_SENSE, + MSC_READ, + MSC_WRITE, + MSC_UNRECOVERED_ERROR, + MSC_PERIODIC_CHECK, +} msc_state; + +typedef enum +{ + MSC_OK, + MSC_NOT_READY, + MSC_ERROR, +} msc_error; + +typedef enum +{ + MSC_REQ_IDLE = 0U, + MSC_REQ_RESET, + MSC_REQ_GET_MAX_LUN, + MSC_REQ_ERROR, +} msc_req_state; + +/* structure for LUN */ +typedef struct +{ + msc_state state; + msc_error error; + msc_scsi_sense sense; + scsi_capacity capacity; + scsi_std_inquiry_data inquiry; + usbh_status prev_ready_state; + uint8_t state_changed; +} msc_lun; + +/* structure for MSC process */ +typedef struct _msc_process +{ + uint8_t pipe_in; + uint8_t pipe_out; + uint8_t ep_in; + uint8_t ep_out; + uint16_t ep_size_in; + uint16_t ep_size_out; + uint8_t cur_lun; + uint16_t rw_lun; + uint32_t max_lun; + msc_state state; + msc_error error; + msc_req_state req_state; + msc_req_state prev_req_state; + bot_handle bot; + msc_lun unit[MSC_MAX_SUPPORTED_LUN]; + uint32_t timer; +} usbh_msc_handler; + +extern usbh_class usbh_msc; + +/* function declarations */ +/* get MSC logic unit information */ +usbh_status usbh_msc_lun_info_get (usbh_host *uhost, uint8_t lun, msc_lun *info); +/* MSC read interface */ +usbh_status usbh_msc_read (usbh_host *uhost, + uint8_t lun, + uint32_t address, + uint8_t *pbuf, + uint32_t length); +/* MSC write interface */ +usbh_status usbh_msc_write (usbh_host *uhost, + uint8_t lun, + uint32_t address, + uint8_t *pbuf, + uint32_t length); + +#endif /* __USBH_MSC_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_scsi.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_scsi.h new file mode 100644 index 0000000000..a8bdf43595 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Include/usbh_msc_scsi.h @@ -0,0 +1,100 @@ +/*! + \file usbh_msc_scsi.h + \brief header file for usbh_msc_scsi.c + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_MSC_SCSI_H +#define __USBH_MSC_SCSI_H + +#include "msc_scsi.h" +#include "usbh_enum.h" + +/* capacity data */ +typedef struct +{ + uint32_t block_nbr; + uint16_t block_size; +} scsi_capacity; + +/* inquiry data */ +typedef struct +{ + uint8_t peripheral_qualifier; + uint8_t device_type; + uint8_t removable_media; + uint8_t vendor_id[9]; + uint8_t product_id[17]; + uint8_t revision_id[5]; +} scsi_std_inquiry_data; + +typedef struct +{ + uint32_t msc_capacity; + uint32_t msc_sense_key; + uint16_t msc_page_len; + uint8_t msc_write_protect; +}usbh_msc_parameter; + +#define DESC_REQUEST_SENSE 0x00U +#define ALLOCATION_LENGTH_REQUEST_SENSE 63U +#define XFER_LEN_MODE_SENSE6 63U + +#define MASK_MODE_SENSE_WRITE_PROTECT 0x80U +#define MODE_SENSE_PAGE_CONTROL_FIELD 0x00U +#define MODE_SENSE_PAGE_CODE 0x3FU +#define DISK_WRITE_PROTECTED 0x01U + +/* function declarations */ +/* send 'inquiry' command to the device */ +usbh_status usbh_msc_scsi_inquiry (usbh_host *uhost, uint8_t lun, scsi_std_inquiry_data *inquiry); +/* send 'test unit ready' command to the device */ +usbh_status usbh_msc_test_unitready (usbh_host *uhost, uint8_t lun); +/* send the read capacity command to the device */ +usbh_status usbh_msc_read_capacity10 (usbh_host *uhost, uint8_t lun, scsi_capacity *capacity); +/* send the mode sense6 command to the device */ +usbh_status usbh_msc_mode_sense6 (usbh_host *uhost, uint8_t lun); +/* send the request sense command to the device */ +usbh_status usbh_msc_request_sense (usbh_host *uhost, uint8_t lun, msc_scsi_sense *sense_data); +/* send the write10 command to the device */ +usbh_status usbh_msc_write10 (usbh_host *uhost, + uint8_t lun, + uint8_t *data_buf, + uint32_t addr, + uint32_t byte_num); +/* send the read10 command to the device */ +usbh_status usbh_msc_read10 (usbh_host *uhost, + uint8_t lun, + uint8_t *data_buf, + uint32_t addr, + uint32_t byte_num); + +#endif /* __USBH_MSC_SCSI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_bbb.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_bbb.c new file mode 100644 index 0000000000..27b4ddb368 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_bbb.c @@ -0,0 +1,355 @@ +/*! + \file usbh_msc_bbb.c + \brief USB MSC BBB protocol related functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_pipe.h" +#include "usbh_msc_core.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bbb.h" +#include "usbh_transc.h" +#include "drv_usbh_int.h" + +/*! + \brief initialize the mass storage parameters + \param[in] uhost: pointer to USB host handler + \param[out] none + \retval none +*/ +void usbh_msc_bot_init(usbh_host *uhost) +{ + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + msc->bot.cbw.field.dCBWSignature = BBB_CBW_SIGNATURE; + msc->bot.cbw.field.dCBWTag = USBH_MSC_BOT_CBW_TAG; + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_SEND; +} + +/*! + \brief manage the different states of BOT transfer and updates the status to upper layer + \param[in] uhost: pointer to USB host + \param[in] lun: logic unit number + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_bot_process(usbh_host *uhost, uint8_t lun) +{ + bot_csw_status csw_status = BOT_CSW_CMD_FAILED; + usbh_status status = USBH_BUSY; + usbh_status error = USBH_BUSY; + usb_urb_state urb_status = URB_IDLE; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(msc->bot.state) { + case BOT_SEND_CBW: + msc->bot.cbw.field.bCBWLUN = lun; + msc->bot.state = BOT_SEND_CBW_WAIT; + /* send CBW */ + usbh_data_send(uhost->data, + msc->bot.cbw.CBWArray, + msc->pipe_out, + BBB_CBW_LENGTH); + break; + + case BOT_SEND_CBW_WAIT: + urb_status = usbh_urbstate_get(uhost->data, msc->pipe_out); + + if(URB_DONE == urb_status) { + if(0U != msc->bot.cbw.field.dCBWDataTransferLength) { + if(USB_TRX_IN == (msc->bot.cbw.field.bmCBWFlags & USB_TRX_MASK)) { + msc->bot.state = BOT_DATA_IN; + } else { + msc->bot.state = BOT_DATA_OUT; + } + } else { + msc->bot.state = BOT_RECEIVE_CSW; + } + + } else if(URB_NOTREADY == urb_status) { + msc->bot.state = BOT_SEND_CBW; + } else { + if(URB_STALL == urb_status) { + msc->bot.state = BOT_ERROR_OUT; + } + } + break; + + case BOT_DATA_IN: + usbh_data_recev(uhost->data, + msc->bot.pbuf, + msc->pipe_in, + msc->ep_size_in); + + msc->bot.state = BOT_DATA_IN_WAIT; + break; + + case BOT_DATA_IN_WAIT: + urb_status = usbh_urbstate_get(uhost->data, msc->pipe_in); + + /* BOT DATA IN stage */ + if(URB_DONE == urb_status) { + if(msc->bot.cbw.field.dCBWDataTransferLength > msc->ep_size_in) { + msc->bot.pbuf += msc->ep_size_in; + msc->bot.cbw.field.dCBWDataTransferLength -= msc->ep_size_in; + } else { + msc->bot.cbw.field.dCBWDataTransferLength = 0U; + } + + if(msc->bot.cbw.field.dCBWDataTransferLength > 0U) { + usbh_data_recev(uhost->data, + msc->bot.pbuf, + msc->pipe_in, + msc->ep_size_in); + } else { + msc->bot.state = BOT_RECEIVE_CSW; + } + } else if(URB_STALL == urb_status) { + /* this is data stage stall condition */ + msc->bot.state = BOT_ERROR_IN; + } else { + /* no operation */ + } + break; + + case BOT_DATA_OUT: + usbh_data_send(uhost->data, + msc->bot.pbuf, + msc->pipe_out, + msc->ep_size_out); + + msc->bot.state = BOT_DATA_OUT_WAIT; + break; + + case BOT_DATA_OUT_WAIT: + /* BOT DATA OUT stage */ + urb_status = usbh_urbstate_get(uhost->data, msc->pipe_out); + if(URB_DONE == urb_status) { + if(msc->bot.cbw.field.dCBWDataTransferLength > msc->ep_size_out) { + msc->bot.pbuf += msc->ep_size_out; + msc->bot.cbw.field.dCBWDataTransferLength -= msc->ep_size_out; + } else { + msc->bot.cbw.field.dCBWDataTransferLength = 0; /* reset this value and keep in same state */ + } + + if(msc->bot.cbw.field.dCBWDataTransferLength > 0) { + usbh_data_send(uhost->data, + msc->bot.pbuf, + msc->pipe_out, + msc->ep_size_out); + } else { + msc->bot.state = BOT_RECEIVE_CSW; + } + } else if(URB_NOTREADY == urb_status) { + msc->bot.state = BOT_DATA_OUT; + } else if(URB_STALL == urb_status) { + msc->bot.state = BOT_ERROR_OUT; + } else { + /* no operation */ + } + break; + + case BOT_RECEIVE_CSW: + /* BOT CSW stage */ + usbh_data_recev(uhost->data, + msc->bot.csw.CSWArray, + msc->pipe_in, + BBB_CSW_LENGTH); + + msc->bot.state = BOT_RECEIVE_CSW_WAIT; + break; + + case BOT_RECEIVE_CSW_WAIT: + urb_status = usbh_urbstate_get(uhost->data, msc->pipe_in); + + /* decode CSW */ + if(URB_DONE == urb_status) { + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_SEND; + + csw_status = usbh_msc_csw_decode(uhost); + if(BOT_CSW_CMD_PASSED == csw_status) { + status = USBH_OK; + } else { + status = USBH_FAIL; + } + } else if(URB_STALL == urb_status) { + msc->bot.state = BOT_ERROR_IN; + } else { + /* no operation */ + } + break; + + case BOT_ERROR_IN: + error = usbh_msc_bot_abort(uhost, USBH_MSC_DIR_IN); + + if(USBH_OK == error) { + msc->bot.state = BOT_RECEIVE_CSW; + } else if(USBH_UNRECOVERED_ERROR == status) { + /* this means that there is a stall error limit, do reset recovery */ + msc->bot.state = BOT_UNRECOVERED_ERROR; + } else { + /* no operation */ + } + break; + + case BOT_ERROR_OUT: + status = usbh_msc_bot_abort(uhost, USBH_MSC_DIR_OUT); + + if(USBH_OK == status) { + uint8_t toggle = usbh_pipe_toggle_get(uhost->data, msc->pipe_out); + usbh_pipe_toggle_set(uhost->data, msc->pipe_out, 1U - toggle); + usbh_pipe_toggle_set(uhost->data, msc->pipe_in, 0U); + msc->bot.state = BOT_ERROR_IN; + } else { + if(USBH_UNRECOVERED_ERROR == status) { + msc->bot.state = BOT_UNRECOVERED_ERROR; + } + } + break; + + case BOT_UNRECOVERED_ERROR: + status = usbh_msc_bot_reset(uhost); + if(USBH_OK == status) { + msc->bot.state = BOT_SEND_CBW; + } + break; + + default: + break; + } + + return status; +} + +/*! + \brief manages the different error handling for stall + \param[in] uhost: pointer to USB host handler + \param[in] direction: data IN or OUT + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_bot_abort(usbh_host *uhost, uint8_t direction) +{ + usbh_status status = USBH_BUSY; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(direction) { + case USBH_MSC_DIR_IN : + /* send clrfeture command on bulk IN endpoint */ + status = usbh_clrfeature(uhost, + msc->ep_in, + msc->pipe_in); + break; + + case USBH_MSC_DIR_OUT : + /*send clrfeature command on bulk OUT endpoint */ + status = usbh_clrfeature(uhost, + msc->ep_out, + msc->pipe_out); + break; + + default: + break; + } + + return status; +} + +/*! + \brief reset MSC bot transfer + \param[in] uhost: pointer to USB host handler + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_bot_reset(usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + + if(CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_REQTYPE_CLASS | USB_RECPTYPE_ITF, + .bRequest = BBB_RESET, + .wValue = 0U, + .wIndex = 0U, + .wLength = 0U + }; + + usbh_ctlstate_config(uhost, NULL, 0U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief decode the CSW received by the device and updates the same to upper layer + \param[in] uhost: pointer to USB host + \param[out] none + \retval on success USBH_MSC_OK, on failure USBH_MSC_FAIL +*/ +bot_csw_status usbh_msc_csw_decode(usbh_host *uhost) +{ + bot_csw_status status = BOT_CSW_CMD_FAILED; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + /* checking if the transfer length is different than 13 */ + if(BBB_CSW_LENGTH != usbh_xfercount_get(uhost->data, msc->pipe_in)) { + status = BOT_CSW_PHASE_ERROR; + } else { + /* CSW length is correct */ + + /* check validity of the CSW Signature and CSWStatus */ + if(BBB_CSW_SIGNATURE == msc->bot.csw.field.dCSWSignature) { + /* check condition 1. dCSWSignature is equal to 53425355h */ + if(msc->bot.csw.field.dCSWTag == msc->bot.cbw.field.dCBWTag) { + /* check condition 3. dCSWTag matches the dCBWTag from the corresponding CBW */ + if(0U == msc->bot.csw.field.bCSWStatus) { + status = BOT_CSW_CMD_PASSED; + } else if(1U == msc->bot.csw.field.bCSWStatus) { + status = BOT_CSW_CMD_FAILED; + } else if(2U == msc->bot.csw.field.bCSWStatus) { + status = BOT_CSW_PHASE_ERROR; + } else { + /* no operation */ + } + } + } else { + /* if the CSW signature is not valid, we shall return the phase error to + upper layers for reset recovery */ + status = BOT_CSW_PHASE_ERROR; + } + } + + return status; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_core.c new file mode 100644 index 0000000000..cd65087b95 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_core.c @@ -0,0 +1,555 @@ +/*! + \file usbh_core.c + \brief USB MSC(mass storage device) class driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_msc_core.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bbb.h" +#include "usbh_pipe.h" +#include "usbh_transc.h" +#include +#include + +/* local function prototypes ('static') */ +static void usbh_msc_itf_deinit(usbh_host *uhost); +static usbh_status usbh_msc_itf_init(usbh_host *uhost); +static usbh_status usbh_msc_req(usbh_host *uhost); +static usbh_status usbh_msc_handle(usbh_host *uhost); +static usbh_status usbh_msc_maxlun_get(usbh_host *uhost, uint8_t *maxlun); +static usbh_status usbh_msc_rdwr_process(usbh_host *uhost, uint8_t lun); + +usbh_class usbh_msc = { + USB_CLASS_MSC, + usbh_msc_itf_init, + usbh_msc_itf_deinit, + usbh_msc_req, + usbh_msc_handle, +}; + +/*! + \brief get MSC logic unit information + \param[in] uhost: pointer to USB host + \param[in] lun: logic unit number + \param[in] info: pointer to logic unit information + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_lun_info_get(usbh_host *uhost, uint8_t lun, msc_lun *info) +{ + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + if(HOST_CLASS_HANDLER == uhost->cur_state) { + memcpy(info, &msc->unit[lun], sizeof(msc_lun)); + + return USBH_OK; + } else { + return USBH_FAIL; + } +} + +/*! + \brief MSC read interface + \param[in] uhost: pointer to USB host + \param[in] lun: logic unit number + \param[in] address: address to be read + \param[in] pbuf: pointer to user buffer + \param[in] length: length to be read + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_read(usbh_host *uhost, + uint8_t lun, + uint32_t address, + uint8_t *pbuf, + uint32_t length) +{ + uint32_t timeout = 0U; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + usb_core_driver *udev = (usb_core_driver *)uhost->data; + + if((0U == udev->host.connect_status) || + (HOST_CLASS_HANDLER != uhost->cur_state) || + (MSC_IDLE != msc->unit[lun].state)) { + return USBH_FAIL; + } + + msc->state = MSC_READ; + msc->unit[lun].state = MSC_READ; + msc->rw_lun = lun; + + usbh_msc_read10(uhost, lun, pbuf, address, length); + + timeout = uhost->control.timer; + + while(USBH_BUSY == usbh_msc_rdwr_process(uhost, lun)) { + if(((uhost->control.timer - timeout) > (1000U * length)) || (0U == udev->host.connect_status)) { + msc->state = MSC_IDLE; + return USBH_FAIL; + } + } + + msc->state = MSC_IDLE; + + return USBH_OK; +} + +/*! + \brief MSC write interface + \param[in] uhost: pointer to USB host + \param[in] lun: logic unit number + \param[in] address: address to be written + \param[in] pbuf: pointer to user buffer + \param[in] length: length to be written + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_write(usbh_host *uhost, + uint8_t lun, + uint32_t address, + uint8_t *pbuf, + uint32_t length) +{ + uint32_t timeout = 0U; + usb_core_driver *udev = (usb_core_driver *)uhost->data; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + if((0U == udev->host.connect_status) || + (HOST_CLASS_HANDLER != uhost->cur_state) || + (MSC_IDLE != msc->unit[lun].state)) { + return USBH_FAIL; + } + + msc->state = MSC_WRITE; + msc->unit[lun].state = MSC_WRITE; + msc->rw_lun = lun; + + usbh_msc_write10(uhost, lun, pbuf, address, length); + + timeout = uhost->control.timer; + + while(USBH_BUSY == usbh_msc_rdwr_process(uhost, lun)) { + if(((uhost->control.timer - timeout) > (1000U * length)) || (0U == udev->host.connect_status)) { + msc->state = MSC_IDLE; + return USBH_FAIL; + } + } + + msc->state = MSC_IDLE; + + return USBH_OK; +} + +/*! + \brief de-initialize interface by freeing host channels allocated to interface + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static void usbh_msc_itf_deinit(usbh_host *uhost) +{ + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + if(msc->pipe_out) { + usb_pipe_halt(uhost->data, msc->pipe_out); + usbh_pipe_free(uhost->data, msc->pipe_out); + + msc->pipe_out = 0U; + } + + if(msc->pipe_in) { + usb_pipe_halt(uhost->data, msc->pipe_in); + usbh_pipe_free(uhost->data, msc->pipe_in); + + msc->pipe_in = 0U; + } +} + +/*! + \brief interface initialization for MSC class + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_msc_itf_init(usbh_host *uhost) +{ + usbh_status status = USBH_OK; + + uint8_t interface = usbh_interface_find(&uhost->dev_prop, MSC_CLASS, USB_MSC_SUBCLASS_SCSI, MSC_PROTOCOL); + + if(0xFFU == interface) { + uhost->usr_cb->dev_not_supported(); + + status = USBH_FAIL; + } else { + static usbh_msc_handler msc_handler; + + memset((void *)&msc_handler, 0, sizeof(usbh_msc_handler)); + + uhost->active_class->class_data = (void *)&msc_handler; + + usbh_interface_select(&uhost->dev_prop, interface); + + usb_desc_ep *ep_desc = &uhost->dev_prop.cfg_desc_set.itf_desc_set[interface][0].ep_desc[0]; + + if(ep_desc->bEndpointAddress & 0x80) { + msc_handler.ep_in = ep_desc->bEndpointAddress; + msc_handler.ep_size_in = ep_desc->wMaxPacketSize; + } else { + msc_handler.ep_out = ep_desc->bEndpointAddress; + msc_handler.ep_size_out = ep_desc->wMaxPacketSize; + } + + ep_desc = &uhost->dev_prop.cfg_desc_set.itf_desc_set[interface][0].ep_desc[1]; + + if(ep_desc->bEndpointAddress & 0x80) { + msc_handler.ep_in = ep_desc->bEndpointAddress; + msc_handler.ep_size_in = ep_desc->wMaxPacketSize; + } else { + msc_handler.ep_out = ep_desc->bEndpointAddress; + msc_handler.ep_size_out = ep_desc->wMaxPacketSize; + } + + msc_handler.state = MSC_INIT; + msc_handler.error = MSC_OK; + msc_handler.req_state = MSC_REQ_IDLE; + msc_handler.pipe_out = usbh_pipe_allocate(uhost->data, msc_handler.ep_out); + msc_handler.pipe_in = usbh_pipe_allocate(uhost->data, msc_handler.ep_in); + + usbh_msc_bot_init(uhost); + + /* open the new channels */ + usbh_pipe_create(uhost->data, + &uhost->dev_prop, + msc_handler.pipe_out, + USB_EPTYPE_BULK, + msc_handler.ep_size_out); + + usbh_pipe_create(uhost->data, + &uhost->dev_prop, + msc_handler.pipe_in, + USB_EPTYPE_BULK, + msc_handler.ep_size_in); + + usbh_pipe_toggle_set(uhost->data, msc_handler.pipe_out, 0U); + usbh_pipe_toggle_set(uhost->data, msc_handler.pipe_in, 0U); + } + + return status; +} + +/*! + \brief initialize the MSC state machine + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_msc_req(usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(msc->req_state) { + case MSC_REQ_IDLE: + case MSC_REQ_GET_MAX_LUN: + /* issue Get_MaxLun request */ + status = usbh_msc_maxlun_get(uhost, (uint8_t *)&msc->max_lun); + + if(USBH_OK == status) { + msc->max_lun = ((uint8_t)msc->max_lun > MSC_MAX_SUPPORTED_LUN) ? MSC_MAX_SUPPORTED_LUN : (uint8_t)msc->max_lun + 1U; + + for(uint8_t i = 0U; i < msc->max_lun; i++) { + msc->unit[i].prev_ready_state = USBH_FAIL; + msc->unit[i].state_changed = 0U; + } + } else { + if(USBH_NOT_SUPPORTED == status) { + msc->max_lun = 0U; + status = USBH_OK; + } + } + break; + + case MSC_REQ_ERROR: + /* issue clear feature request */ + if(USBH_OK == usbh_clrfeature(uhost, 0x00U, uhost->control.pipe_out_num)) { + msc->req_state = msc->prev_req_state; + } + break; + + default: + break; + } + + return status; +} + +/*! + \brief MSC state machine handler + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static usbh_status usbh_msc_handle(usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + uint8_t scsi_status = USBH_BUSY; + uint8_t ready_status = USBH_BUSY; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + + switch(msc->state) { + case MSC_INIT: + if(msc->cur_lun < msc->max_lun) { + msc->unit[msc->cur_lun].error = MSC_NOT_READY; + + switch(msc->unit[msc->cur_lun].state) { + case MSC_INIT: + msc->unit[msc->cur_lun].state = MSC_READ_INQUIRY; + msc->timer = uhost->control.timer; + break; + + case MSC_READ_INQUIRY: + scsi_status = usbh_msc_scsi_inquiry(uhost, msc->cur_lun, &msc->unit[msc->cur_lun].inquiry); + + if(USBH_OK == scsi_status) { + msc->unit[msc->cur_lun].state = MSC_TEST_UNIT_READY; + } else if(scsi_status == USBH_FAIL) { + msc->unit[msc->cur_lun].state = MSC_REQUEST_SENSE; + } else { + if(scsi_status == USBH_UNRECOVERED_ERROR) { + msc->unit[msc->cur_lun].state = MSC_IDLE; + msc->unit[msc->cur_lun].error = MSC_ERROR; + } + } + break; + + case MSC_TEST_UNIT_READY: + /* issue SCSI command TestUnitReady */ + ready_status = usbh_msc_test_unitready(uhost, msc->cur_lun); + + if(USBH_OK == ready_status) { + if(USBH_OK != msc->unit[msc->cur_lun].prev_ready_state) { + msc->unit[msc->cur_lun].state_changed = 1U; + } else { + msc->unit[msc->cur_lun].state_changed = 0U; + } + + msc->unit[msc->cur_lun].state = MSC_READ_CAPACITY10; + msc->unit[msc->cur_lun].error = MSC_OK; + msc->unit[msc->cur_lun].prev_ready_state = USBH_OK; + } else if(USBH_FAIL == ready_status) { + if(USBH_FAIL != msc->unit[msc->cur_lun].prev_ready_state) { + msc->unit[msc->cur_lun].state_changed = 1U; + } else { + msc->unit[msc->cur_lun].state_changed = 0U; + } + + msc->unit[msc->cur_lun].state = MSC_REQUEST_SENSE; + msc->unit[msc->cur_lun].error = MSC_NOT_READY; + msc->unit[msc->cur_lun].prev_ready_state = USBH_FAIL; + } else { + if(USBH_UNRECOVERED_ERROR == ready_status) { + msc->unit[msc->cur_lun].state = MSC_IDLE; + msc->unit[msc->cur_lun].error = MSC_ERROR; + } + } + break; + + case MSC_READ_CAPACITY10: + /* issue READ_CAPACITY10 SCSI command */ + scsi_status = usbh_msc_read_capacity10(uhost, msc->cur_lun, &msc->unit[msc->cur_lun].capacity); + + if(USBH_OK == scsi_status) { + if(1U == msc->unit[msc->cur_lun].state_changed) { + } + msc->unit[msc->cur_lun].state = MSC_IDLE; + msc->unit[msc->cur_lun].error = MSC_OK; + msc->cur_lun ++; + } else if(USBH_FAIL == scsi_status) { + msc->unit[msc->cur_lun].state = MSC_REQUEST_SENSE; + } else { + if(USBH_UNRECOVERED_ERROR == scsi_status) { + msc->unit[msc->cur_lun].state = MSC_IDLE; + msc->unit[msc->cur_lun].error = MSC_ERROR; + } + } + break; + + case MSC_REQUEST_SENSE: + /* issue RequestSense SCSI command for receive error code */ + scsi_status = usbh_msc_request_sense(uhost, msc->cur_lun, &msc->unit[msc->cur_lun].sense); + if(USBH_OK == scsi_status) { + if((UNIT_ATTENTION == msc->unit[msc->cur_lun].sense.SenseKey) || (NOT_READY == msc->unit[msc->cur_lun].sense.SenseKey)) { + if((uhost->control.timer - msc->timer) < 10000U) { + msc->unit[msc->cur_lun].state = MSC_TEST_UNIT_READY; + break; + } + } + + msc->unit[msc->cur_lun].state = MSC_IDLE; + msc->cur_lun++; + } else if(USBH_FAIL == scsi_status) { + msc->unit[msc->cur_lun].state = MSC_UNRECOVERED_ERROR; + } else { + if(MSC_UNRECOVERED_ERROR == scsi_status) { + msc->unit[msc->cur_lun].state = MSC_IDLE; + msc->unit[msc->cur_lun].error = MSC_ERROR; + } + } + break; + + case MSC_UNRECOVERED_ERROR: + msc->cur_lun ++; + break; + + default: + break; + } + } else { + msc->cur_lun = 0U; + msc->state = MSC_IDLE; + } + break; + + case MSC_IDLE: + uhost->usr_cb->dev_user_app(); + status = USBH_OK; + break; + + default: + break; + } + + return status; +} + +/*! + \brief get max lun of the mass storage device + \param[in] uhost: pointer to USB host + \param[in] maxlun: pointer to max lun + \param[out] none + \retval operation status +*/ +static usbh_status usbh_msc_maxlun_get(usbh_host *uhost, uint8_t *maxlun) +{ + usbh_status status = USBH_BUSY; + + if(CTL_IDLE == uhost->control.ctl_state) { + uhost->control.setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_REQTYPE_CLASS | USB_RECPTYPE_ITF, + .bRequest = BBB_GET_MAX_LUN, + .wValue = 0U, + .wIndex = 0U, + .wLength = 1U + }; + + usbh_ctlstate_config(uhost, maxlun, 1U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief get max lun of the mass storage device + \param[in] uhost: pointer to USB host + \param[in] lun: logic unit number + \param[out] none + \retval operation status +*/ +static usbh_status usbh_msc_rdwr_process(usbh_host *uhost, uint8_t lun) +{ + usbh_status error = USBH_BUSY; + usbh_status scsi_status = USBH_BUSY; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + /* switch MSC REQ state machine */ + switch(msc->unit[lun].state) { + case MSC_READ: + scsi_status = usbh_msc_read10(uhost, lun, NULL, 0U, 0U); + + if(USBH_OK == scsi_status) { + msc->unit[lun].state = MSC_IDLE; + error = USBH_OK; + } else if(USBH_FAIL == scsi_status) { + msc->unit[lun].state = MSC_REQUEST_SENSE; + } else { + if(USBH_UNRECOVERED_ERROR == scsi_status) { + msc->unit[lun].state = MSC_UNRECOVERED_ERROR; + error = USBH_FAIL; + } + } + break; + + case MSC_WRITE: + scsi_status = usbh_msc_write10(uhost, lun, NULL, 0U, 0U); + + if(USBH_OK == scsi_status) { + msc->unit[lun].state = MSC_IDLE; + error = USBH_OK; + } else if(USBH_FAIL == scsi_status) { + msc->unit[lun].state = MSC_REQUEST_SENSE; + } else { + if(USBH_UNRECOVERED_ERROR == scsi_status) { + msc->unit[lun].state = MSC_UNRECOVERED_ERROR; + error = USBH_FAIL; + } + } + break; + + case MSC_REQUEST_SENSE: + scsi_status = usbh_msc_request_sense(uhost, lun, &msc->unit[lun].sense); + + if(USBH_OK == scsi_status) { + msc->unit[lun].state = MSC_IDLE; + msc->unit[lun].error = MSC_ERROR; + + error = USBH_FAIL; + } + + if(USBH_FAIL == scsi_status) { + } else { + if(USBH_UNRECOVERED_ERROR == scsi_status) { + msc->unit[lun].state = MSC_UNRECOVERED_ERROR; + error = USBH_FAIL; + } + } + break; + + default: + break; + } + + return error; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_fatfs.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_fatfs.c new file mode 100644 index 0000000000..f98bc050a6 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_fatfs.c @@ -0,0 +1,234 @@ +/*! + \file usbh_msc_fatfs.c + \brief USB MSC host FATFS related functions + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usb_conf.h" +#include "diskio.h" +#include "usbh_msc_core.h" + +static volatile DSTATUS state = STA_NOINIT; /* disk status */ + +extern usbh_host usb_host_msc; + +/*! + \brief initialize the disk drive + \param[in] drv: physical drive number (0) + \param[out] none + \retval operation status +*/ +DSTATUS disk_initialize(BYTE drv) +{ + usb_core_driver *udev = (usb_core_driver *)usb_host_msc.data; + + if(udev->host.connect_status) { + state &= ~STA_NOINIT; + } + + return state; +} + +/*! + \brief get disk status + \param[in] drv: physical drive number (0) + \param[out] none + \retval operation status +*/ +DSTATUS disk_status(BYTE drv) +{ + if(drv) { + return STA_NOINIT; /* supports only single drive */ + } + + return state; +} + +/*! + \brief read sectors + \param[in] drv: physical drive number (0) + \param[in] buff: pointer to the data buffer to store read data + \param[in] sector: start sector number (LBA) + \param[in] count: sector count (1..255) + \param[out] none + \retval operation status +*/ +DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, UINT count) +{ + BYTE status = USBH_OK; + usb_core_driver *udev = (usb_core_driver *)usb_host_msc.data; + + if(drv || (!count)) { + return RES_PARERR; + } + + if(state & STA_NOINIT) { + return RES_NOTRDY; + } + + if(udev->host.connect_status) { + do { + status = usbh_msc_read(&usb_host_msc, drv, sector, buff, count); + + if(!udev->host.connect_status) { + return RES_ERROR; + } + } while(status == USBH_BUSY); + } + + if(status == USBH_OK) { + return RES_OK; + } + + return RES_ERROR; +} + +#if _READONLY == 0U + +/*! + \brief write sectors + \param[in] drv: physical drive number (0) + \param[in] buff: pointer to the data buffer to store read data + \param[in] sector: start sector number (LBA) + \param[in] count: sector count (1..255) + \param[out] none + \retval operation status +*/ +DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, UINT count) +{ + BYTE status = USBH_OK; + usb_core_driver *udev = (usb_core_driver *)usb_host_msc.data; + + if((!count) || drv) { + return RES_PARERR; + } + + if(state & STA_NOINIT) { + return RES_NOTRDY; + } + + if(state & STA_PROTECT) { + return RES_WRPRT; + } + + if(udev->host.connect_status) { + do { + status = usbh_msc_write(&usb_host_msc, drv, sector, (BYTE *)buff, count); + + if(!udev->host.connect_status) { + return RES_ERROR; + } + } while(status == USBH_BUSY); + } + + if(status == USBH_OK) { + return RES_OK; + } + + return RES_ERROR; +} + +#endif /* _READONLY == 0 */ + +/*! + \brief I/O control function + \param[in] drv: physical drive number (0) + \param[in] ctrl: control code + \param[in] buff: pointer to the data buffer to store read data + \param[out] none + \retval operation status +*/ +DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff) +{ + DRESULT res = RES_OK; + msc_lun info; + + if(drv) { + return RES_PARERR; + } + + res = RES_ERROR; + + if(state & STA_NOINIT) { + return RES_NOTRDY; + } + + switch(ctrl) { + /* make sure that no pending write process */ + case CTRL_SYNC: + res = RES_OK; + break; + + /* get number of sectors on the disk (dword) */ + case GET_SECTOR_COUNT: + if(USBH_OK == usbh_msc_lun_info_get(&usb_host_msc, drv, &info)) { + *(DWORD *)buff = (DWORD)info.capacity.block_nbr; + res = RES_OK; + } + break; + + /* get r/w sector size (word) */ + case GET_SECTOR_SIZE: + if(USBH_OK == usbh_msc_lun_info_get(&usb_host_msc, drv, &info)) { + *(WORD *)buff = (DWORD)info.capacity.block_size; + res = RES_OK; + } + break; + + /* get erase block size in unit of sector (dword) */ + case GET_BLOCK_SIZE: + *(DWORD *)buff = 512U; + break; + + default: + res = RES_PARERR; + break; + } + + return res; +} + +/*! + \brief get fat time + \param[in] none + \param[out] none + \retval time value +*/ +DWORD get_fattime(void) +{ + + return ((DWORD)(2019U - 1980U) << 25U) /* year 2019 */ + | ((DWORD)1U << 21U) /* month 1 */ + | ((DWORD)1U << 16U) /* day 1 */ + | ((DWORD)0U << 11U) /* hour 0 */ + | ((DWORD)0U << 5U) /* min 0 */ + | ((DWORD)0U >> 1U); /* sec 0 */ +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_scsi.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_scsi.c new file mode 100644 index 0000000000..df9c14a90e --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/class/msc/Source/usbh_msc_scsi.c @@ -0,0 +1,399 @@ +/*! + \file usbh_msc_scsi.c + \brief USB MSC SCSI commands implemention + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_msc_core.h" +#include "usbh_msc_scsi.h" +#include "usbh_msc_bbb.h" +#include + +/*! + \brief send 'Inquiry' command to the device + \param[in] uhost: pointer to USB host handler + \param[in] lun: logic unit number + \param[in] inquiry: pointer to the inquiry structure + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_scsi_inquiry(usbh_host *uhost, uint8_t lun, scsi_std_inquiry_data *inquiry) +{ + usbh_status error = USBH_FAIL; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(msc->bot.cmd_state) { + case BOT_CMD_SEND: + /* prepare the CBW and relevant field*/ + msc->bot.cbw.field.dCBWDataTransferLength = STANDARD_INQUIRY_DATA_LEN; + msc->bot.cbw.field.bmCBWFlags = USB_TRX_IN; + msc->bot.cbw.field.bCBWCBLength = CBW_LENGTH; + + memset(msc->bot.cbw.field.CBWCB, 0U, CBW_LENGTH); + + msc->bot.cbw.field.CBWCB[0] = SCSI_INQUIRY; + msc->bot.cbw.field.CBWCB[1] = (lun << 5U); + msc->bot.cbw.field.CBWCB[4] = 0x24U; + + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_WAIT; + msc->bot.pbuf = (uint8_t *)(void *)msc->bot.data; + error = USBH_BUSY; + break; + + case BOT_CMD_WAIT: + error = usbh_msc_bot_process(uhost, lun); + + if(USBH_OK == error) { + memset(inquiry, 0U, sizeof(scsi_std_inquiry_data)); + + /* assign inquiry data */ + inquiry->device_type = msc->bot.pbuf[0] & 0x1FU; + inquiry->peripheral_qualifier = msc->bot.pbuf[0] >> 5U; + + if(0x80U == ((uint32_t)msc->bot.pbuf[1] & 0x80U)) { + inquiry->removable_media = 1U; + } else { + inquiry->removable_media = 0U; + } + + memcpy(inquiry->vendor_id, &msc->bot.pbuf[8], 8U); + memcpy(inquiry->product_id, &msc->bot.pbuf[16], 16U); + memcpy(inquiry->revision_id, &msc->bot.pbuf[32], 4U); + } + break; + + default: + break; + } + + return error; +} + +/*! + \brief send 'Test unit ready' command to the device + \param[in] uhost: pointer to USB host handler + \param[in] lun: logic unit number + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_test_unitready(usbh_host *uhost, uint8_t lun) +{ + usbh_status status = USBH_FAIL; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + + switch(msc->bot.cmd_state) { + case BOT_CMD_SEND: + /* prepare the CBW and relevant field */ + msc->bot.cbw.field.dCBWDataTransferLength = CBW_LENGTH_TEST_UNIT_READY; + msc->bot.cbw.field.bmCBWFlags = USB_TRX_OUT; + msc->bot.cbw.field.bCBWCBLength = CBW_LENGTH; + + memset(msc->bot.cbw.field.CBWCB, 0U, CBW_CB_LENGTH); + + msc->bot.cbw.field.CBWCB[0] = SCSI_TEST_UNIT_READY; + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_WAIT; + + status = USBH_BUSY; + break; + + case BOT_CMD_WAIT: + status = usbh_msc_bot_process(uhost, lun); + break; + + default: + break; + } + + return status; +} + +/*! + \brief send the read capacity command to the device + \param[in] uhost: pointer to USB host handler + \param[in] lun: logic unit number + \param[in] capacity: pointer to SCSI capacity + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_read_capacity10(usbh_host *uhost, uint8_t lun, scsi_capacity *capacity) +{ + usbh_status status = USBH_FAIL; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(msc->bot.cmd_state) { + case BOT_CMD_SEND: + /* prepare the CBW and relevant field */ + msc->bot.cbw.field.dCBWDataTransferLength = READ_CAPACITY10_DATA_LEN; + msc->bot.cbw.field.bmCBWFlags = USB_TRX_IN; + msc->bot.cbw.field.bCBWCBLength = CBW_LENGTH; + + memset(msc->bot.cbw.field.CBWCB, 0U, CBW_CB_LENGTH); + + msc->bot.cbw.field.CBWCB[0] = SCSI_READ_CAPACITY10; + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_WAIT; + msc->bot.pbuf = (uint8_t *)(void *)msc->bot.data; + + status = USBH_BUSY; + break; + + case BOT_CMD_WAIT: + status = usbh_msc_bot_process(uhost, lun); + + if(USBH_OK == status) { + capacity->block_nbr = msc->bot.pbuf[3] | \ + ((uint32_t)msc->bot.pbuf[2] << 8U) | \ + ((uint32_t)msc->bot.pbuf[1] << 16U) | \ + ((uint32_t)msc->bot.pbuf[0] << 24U); + + capacity->block_size = (uint16_t)(msc->bot.pbuf[7] | ((uint32_t)msc->bot.pbuf[6] << 8U)); + } + break; + + default: + break; + } + + return status; +} + +/*! + \brief send the mode sense6 command to the device + \param[in] uhost: pointer to USB host handler + \param[in] lun: logic unit number + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_mode_sense6(usbh_host *uhost, uint8_t lun) +{ + usbh_status status = USBH_FAIL; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + + switch(msc->bot.cmd_state) { + case BOT_CMD_SEND: + /* prepare the CBW and relevant field */ + msc->bot.cbw.field.dCBWDataTransferLength = XFER_LEN_MODE_SENSE6; + msc->bot.cbw.field.bmCBWFlags = USB_TRX_IN; + msc->bot.cbw.field.bCBWCBLength = CBW_LENGTH; + + memset(msc->bot.cbw.field.CBWCB, 0U, CBW_CB_LENGTH); + + msc->bot.cbw.field.CBWCB[0] = SCSI_MODE_SENSE6; + msc->bot.cbw.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | MODE_SENSE_PAGE_CODE; + msc->bot.cbw.field.CBWCB[4] = XFER_LEN_MODE_SENSE6; + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_WAIT; + msc->bot.pbuf = (uint8_t *)(void *)msc->bot.data; + + status = USBH_BUSY; + break; + + case BOT_CMD_WAIT: + status = usbh_msc_bot_process(uhost, lun); + + if(USBH_OK == status) { + if(msc->bot.data[2] & MASK_MODE_SENSE_WRITE_PROTECT) { + + } else { + + } + } + break; + + default: + break; + } + + + return status; +} + +/*! + \brief send the request sense command to the device + \param[in] uhost: pointer to USB host handler + \param[in] lun: logic unit number + \param[in] sense_data: pointer to sense data + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_request_sense(usbh_host *uhost, uint8_t lun, msc_scsi_sense *sense_data) +{ + usbh_status status = USBH_FAIL; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(msc->bot.cmd_state) { + case BOT_CMD_SEND: + /* prepare the CBW and relevant field */ + msc->bot.cbw.field.dCBWDataTransferLength = ALLOCATION_LENGTH_REQUEST_SENSE; + msc->bot.cbw.field.bmCBWFlags = USB_TRX_IN; + msc->bot.cbw.field.bCBWCBLength = CBW_LENGTH; + + memset(msc->bot.cbw.field.CBWCB, 0U, CBW_CB_LENGTH); + + msc->bot.cbw.field.CBWCB[0] = SCSI_REQUEST_SENSE; + msc->bot.cbw.field.CBWCB[1] = (lun << 5U); + msc->bot.cbw.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE; + + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_WAIT; + msc->bot.pbuf = (uint8_t *)(void *)msc->bot.data; + + status = USBH_BUSY; + break; + + case BOT_CMD_WAIT: + status = usbh_msc_bot_process(uhost, lun); + + if(USBH_OK == status) { + /* get sense data */ + sense_data->SenseKey = msc->bot.pbuf[2] & 0x0FU; + sense_data->ASC = msc->bot.pbuf[12]; + sense_data->ASCQ = msc->bot.pbuf[13]; + } + break; + + default: + break; + } + + return status; +} + +/*! + \brief send the write10 command to the device + \param[in] uhost: pointer to USB host handler + \param[in] lun: logic unit number + \param[in] data_buf: data buffer contains the data to write + \param[in] addr: address to which the data will be written + \param[in] sector_num: number of sector to be written + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_write10(usbh_host *uhost, uint8_t lun, uint8_t *data_buf, uint32_t addr, uint32_t sector_num) +{ + usbh_status status = USBH_FAIL; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(msc->bot.cmd_state) { + case BOT_CMD_SEND: + msc->bot.cbw.field.dCBWDataTransferLength = sector_num * msc->unit[lun].capacity.block_size; + msc->bot.cbw.field.bmCBWFlags = USB_TRX_OUT; + msc->bot.cbw.field.bCBWCBLength = CBW_LENGTH; + + memset(msc->bot.cbw.field.CBWCB, 0U, CBW_CB_LENGTH); + + msc->bot.cbw.field.CBWCB[0] = SCSI_WRITE10; + + /* logical block address */ + msc->bot.cbw.field.CBWCB[2] = (((uint8_t *)&addr)[3]); + msc->bot.cbw.field.CBWCB[3] = (((uint8_t *)&addr)[2]); + msc->bot.cbw.field.CBWCB[4] = (((uint8_t *)&addr)[1]); + msc->bot.cbw.field.CBWCB[5] = (((uint8_t *)&addr)[0]); + + /* transfer length */ + msc->bot.cbw.field.CBWCB[7] = (((uint8_t *)§or_num)[1]); + msc->bot.cbw.field.CBWCB[8] = (((uint8_t *)§or_num)[0]); + + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_WAIT; + msc->bot.pbuf = data_buf; + + status = USBH_BUSY; + break; + + case BOT_CMD_WAIT: + status = usbh_msc_bot_process(uhost, lun); + break; + + default: + break; + } + + return status; +} + +/*! + \brief send the read10 command to the device + \param[in] uhost: pointer to USB host handler + \param[in] lun: logic unit number + \param[in] data_buf: data buffer contains the data to write + \param[in] addr: address to which the data will be read + \param[in] sector_num: number of sector to be read + \param[out] none + \retval operation status +*/ +usbh_status usbh_msc_read10(usbh_host *uhost, uint8_t lun, uint8_t *data_buf, uint32_t addr, uint32_t sector_num) +{ + usbh_status status = USBH_FAIL; + usbh_msc_handler *msc = (usbh_msc_handler *)uhost->active_class->class_data; + + switch(msc->bot.cmd_state) { + case BOT_CMD_SEND: + /* prepare the CBW and relevant field */ + msc->bot.cbw.field.dCBWDataTransferLength = sector_num * msc->unit[lun].capacity.block_size; + msc->bot.cbw.field.bmCBWFlags = USB_TRX_IN; + msc->bot.cbw.field.bCBWCBLength = CBW_LENGTH; + + memset(msc->bot.cbw.field.CBWCB, 0U, CBW_CB_LENGTH); + + msc->bot.cbw.field.CBWCB[0] = SCSI_READ10; + + /* logical block address */ + msc->bot.cbw.field.CBWCB[2] = (((uint8_t *)&addr)[3]); + msc->bot.cbw.field.CBWCB[3] = (((uint8_t *)&addr)[2]); + msc->bot.cbw.field.CBWCB[4] = (((uint8_t *)&addr)[1]); + msc->bot.cbw.field.CBWCB[5] = (((uint8_t *)&addr)[0]); + + /* transfer length */ + msc->bot.cbw.field.CBWCB[7] = (((uint8_t *)§or_num)[1]); + msc->bot.cbw.field.CBWCB[8] = (((uint8_t *)§or_num)[0]); + + msc->bot.state = BOT_SEND_CBW; + msc->bot.cmd_state = BOT_CMD_WAIT; + msc->bot.pbuf = data_buf; + + status = USBH_BUSY; + break; + + case BOT_CMD_WAIT: + status = usbh_msc_bot_process(uhost, lun); + break; + + default: + break; + } + + return status; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_core.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_core.h new file mode 100644 index 0000000000..4d7e97cada --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_core.h @@ -0,0 +1,280 @@ +/*! + \file usbh_core.h + \brief USB host core state machine header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_CORE_H +#define __USBH_CORE_H + +#include "usbh_conf.h" +#include "drv_usb_host.h" + +#define MSC_CLASS 0x08U +#define HID_CLASS 0x03U +#define MSC_PROTOCOL 0x50U +#define CBI_PROTOCOL 0x01U + +#define USBH_MAX_ERROR_COUNT 3U + +#define USBH_DEV_ADDR_DEFAULT 0U +#define USBH_DEV_ADDR 1U + +typedef enum +{ + USBH_OK = 0U, + USBH_BUSY, + USBH_FAIL, + USBH_NOT_SUPPORTED, + USBH_UNRECOVERED_ERROR, + USBH_SPEED_UNKNOWN_ERROR, + USBH_APPLY_DEINIT +} usbh_status; + +/* USB host global operation state */ +typedef enum +{ + HOST_DEFAULT = 0U, + HOST_DETECT_DEV_SPEED, + HOST_DEV_ATTACHED, + HOST_DEV_DETACHED, + HOST_ENUM, + HOST_SET_WAKEUP_FEATURE, + HOST_CHECK_CLASS, + HOST_CLASS_ENUM, + HOST_CLASS_HANDLER, + HOST_USER_INPUT, + HOST_SUSPENDED, + HOST_WAKEUP, + HOST_ERROR +} usb_host_state; + +/* USB host enumeration state */ +typedef enum +{ + ENUM_DEFAULT = 0U, + ENUM_GET_DEV_DESC, + ENUM_SET_ADDR, + ENUM_GET_CFG_DESC, + ENUM_GET_CFG_DESC_SET, + ENUM_GET_STR_DESC, +#ifdef USB_MTP + ENUM_GET_MTP_STR, +#endif + ENUM_SET_CONFIGURATION, + ENUM_DEV_CONFIGURED +} usbh_enum_state; + +/* USB host control transfer state */ +typedef enum +{ + CTL_IDLE = 0U, + CTL_SETUP, + CTL_SETUP_WAIT, + CTL_DATA_IN, + CTL_DATA_IN_WAIT, + CTL_DATA_OUT, + CTL_DATA_OUT_WAIT, + CTL_STATUS_IN, + CTL_STATUS_IN_WAIT, + CTL_STATUS_OUT, + CTL_STATUS_OUT_WAIT, + CTL_ERROR, + CTL_FINISH +} usbh_ctl_state; + +/* user action state */ +typedef enum +{ + USBH_USER_NO_RESP = 0U, + USBH_USER_RESP_OK = 1U, +} usbh_user_status; + +typedef enum +{ + USBH_PORT_EVENT = 1U, + USBH_URB_EVENT, + USBH_CONTROL_EVENT, + USBH_CLASS_EVENT, + USBH_STATE_CHANGED_EVENT, +}usbh_os_event; + +/* control transfer information */ +typedef struct _usbh_control +{ + uint8_t pipe_in_num; + uint8_t pipe_out_num; + uint8_t max_len; + uint8_t error_count; + + uint8_t *buf; + uint16_t ctl_len; + __IO uint32_t timer; + + usb_setup setup; + usbh_ctl_state ctl_state; +} usbh_control; + +/* USB interface descriptor set */ +typedef struct _usb_desc_itf_set +{ + usb_desc_itf itf_desc; + usb_desc_ep ep_desc[USBH_MAX_EP_NUM]; +} usb_desc_itf_set; + +/* USB configure descriptor set */ +typedef struct _usb_desc_cfg_set +{ + usb_desc_config cfg_desc; + usb_desc_itf_set itf_desc_set[USBH_MAX_INTERFACES_NUM][USBH_MAX_ALT_SETTING]; +} usb_desc_cfg_set; + +/* USB device property */ +typedef struct +{ + uint8_t data[USBH_DATA_BUF_MAX_LEN]; /* if DMA is used, the data array must be located in the first position */ + uint8_t cur_itf; + uint8_t addr; + + uint32_t speed; + + usb_desc_dev dev_desc; + usb_desc_cfg_set cfg_desc_set; + +#if (USBH_KEEP_CFG_DESCRIPTOR == 1U) + uint8_t cfgdesc_rawdata[USBH_CFGSET_MAX_LEN]; +#endif /* (USBH_KEEP_CFG_DESCRIPTOR == 1U) */ +} usb_dev_prop; + +struct _usbh_host; + +/* device class callbacks */ +typedef struct +{ + uint8_t class_code; /*!< USB class type */ + + usbh_status (*class_init) (struct _usbh_host *phost); + void (*class_deinit) (struct _usbh_host *phost); + usbh_status (*class_requests) (struct _usbh_host *phost); + usbh_status (*class_machine) (struct _usbh_host *phost); + usbh_status (*class_sof) (struct _usbh_host *uhost); + + void *class_data; +} usbh_class; + +/* user callbacks */ +typedef struct +{ + void (*dev_init) (void); + void (*dev_deinit) (void); + void (*dev_attach) (void); + void (*dev_reset) (void); + void (*dev_detach) (void); + void (*dev_over_currented) (void); + void (*dev_speed_detected) (uint32_t dev_speed); + void (*dev_devdesc_assigned) (void *dev_desc); + void (*dev_address_set) (void); + + void (*dev_cfgdesc_assigned) (usb_desc_config *cfg_desc, + usb_desc_itf *itf_desc, + usb_desc_ep *ep_desc); + + void (*dev_mfc_str) (void *mfc_str); + void (*dev_prod_str) (void *prod_str); + void (*dev_seral_str) (void *serial_str); + void (*dev_enumerated) (void); + usbh_user_status (*dev_user_input) (void); + int (*dev_user_app) (void); + void (*dev_not_supported) (void); + void (*dev_error) (void); +} usbh_user_cb; + +/* host information */ +typedef struct _usbh_host +{ + usb_host_state cur_state; /*!< host state machine value */ + usb_host_state backup_state; /*!< backup of previous state machine value */ + usbh_enum_state enum_state; /*!< enumeration state machine */ + usbh_control control; /*!< USB host control state machine */ + usb_dev_prop dev_prop; /*!< USB device property */ + + usbh_class *uclass[USBH_MAX_SUPPORTED_CLASS]; /*!< USB host supported class */ + usbh_class *active_class; /*!< USB active class */ + usbh_user_cb *usr_cb; /*!< USB user callback */ + + uint8_t class_num; /*!< USB class number */ + + void *data; /*!< used for... */ + +//#if USB_LOW_POWER + uint8_t suspend_flag; /*!< host suspend flag */ + uint8_t dev_supp_remote_wkup; /*!< record device remote wakeup function */ + uint8_t wakeup_mode; /*!< record wakeup mode */ +//#endif /* USB_LOW_POWER*/ +} usbh_host; + +/*! + \brief get USB URB state + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pipe number + \param[out] none + \retval none +*/ +static inline usb_urb_state usbh_urbstate_get (usb_core_driver *udev, uint8_t pp_num) +{ + return udev->host.pipe[pp_num].urb_state; +} + +/*! + \brief get USB transfer data count + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pipe number + \param[out] none + \retval none +*/ +static inline uint32_t usbh_xfercount_get (usb_core_driver *udev, uint8_t pp_num) +{ + return udev->host.backup_xfercount[pp_num]; +} + +/* function declarations */ +/* USB host stack initializations */ +void usbh_init (usbh_host *uhost, usb_core_driver *udev, usbh_user_cb *user_cb); +/* USB host register device class */ +usbh_status usbh_class_register (usbh_host *uhost, usbh_class *puclass); +/* de-initialize USB host */ +usbh_status usbh_deinit (usbh_host *uhost); +/* USB host core main state machine process */ +void usbh_core_task (usbh_host *uhost); +/* handle the error on USB host side */ +void usbh_error_handler (usbh_host *uhost, usbh_status err_type); + +#endif /* __USBH_CORE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_enum.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_enum.h new file mode 100644 index 0000000000..ad6b8af908 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_enum.h @@ -0,0 +1,71 @@ +/*! + \file usbh_enum.h + \brief USB host mode USB enumeration header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_ENUM_H +#define __USBH_ENUM_H + +#include "usb_conf.h" +#include "usbh_core.h" + +/* function declarations */ +/* configure USB control status parameters */ +void usbh_ctlstate_config (usbh_host *uhost, uint8_t *buf, uint16_t len); +/* get device descriptor from the USB device */ +usbh_status usbh_devdesc_get (usbh_host *uhost, uint8_t len); +/* get configuration descriptor from the USB device */ +usbh_status usbh_cfgdesc_get (usbh_host *uhost, uint16_t len); +/* get string descriptor from the USB device */ +usbh_status usbh_strdesc_get (usbh_host *uhost,uint8_t str_index, uint8_t *buf, uint16_t len); +/* set the address to the connected device */ +usbh_status usbh_setaddress (usbh_host *uhost, uint8_t dev_addr); +/* set the configuration value to the connected device */ +usbh_status usbh_setcfg (usbh_host *uhost, uint16_t config); +/* set the interface value to the connected device */ +usbh_status usbh_setinterface (usbh_host *uhost, uint8_t itf_num, uint8_t alter_setting); +/* set or enable a specific device feature */ +usbh_status usbh_setdevfeature (usbh_host *uhost, uint8_t feature_selector, uint16_t windex); +/* clear or disable a specific device feature */ +usbh_status usbh_clrdevfeature (usbh_host *uhost, uint8_t feature_selector, uint16_t windex); +/* clear or disable a specific feature */ +usbh_status usbh_clrfeature (usbh_host *uhost, uint8_t ep_addr, uint8_t pp_num); +/* get the next descriptor header */ +usb_desc_header *usbh_nextdesc_get (uint8_t *pbuf, uint16_t *ptr); +/* select an interface */ +usbh_status usbh_interface_select (usb_dev_prop *udev, uint8_t interface); +/* find the interface index for a specific class */ +uint8_t usbh_interface_find (usb_dev_prop *udev, uint8_t main_class, uint8_t sub_class, uint8_t protocol); +/* find the interface index for a specific class interface and alternate setting number */ +uint8_t usbh_interfaceindex_find (usb_dev_prop *udev, uint8_t interface_number, uint8_t alt_settings); + +#endif /* __USBH_ENUM_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_pipe.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_pipe.h new file mode 100644 index 0000000000..ddf8318930 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_pipe.h @@ -0,0 +1,99 @@ +/*! + \file usbh_pipe.h + \brief USB host mode pipe header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_PIPE_H +#define __USBH_PIPE_H + +#include "usbh_core.h" + +#define HC_MAX 16U +#define HC_OK 0x0000U +#define HC_USED 0x8000U +#define HC_ERROR 0xFFFFU +#define HC_USED_MASK 0x7FFFU + +/*! + \brief set toggle for a pipe + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pipe number + \param[in] toggle: toggle (0/1) + \param[out] none + \retval operation status +*/ +__STATIC_INLINE void usbh_pipe_toggle_set (usb_core_driver *udev, uint8_t pp_num, uint8_t toggle) +{ + if (udev->host.pipe[pp_num].ep.dir) { + udev->host.pipe[pp_num].data_toggle_in = toggle; + } else { + udev->host.pipe[pp_num].data_toggle_out = toggle; + } +} + +/*! + \brief get toggle flag of pipe + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pipe number + \param[out] none + \retval operation status +*/ +__STATIC_INLINE uint8_t usbh_pipe_toggle_get (usb_core_driver *udev, uint8_t pp_num) +{ + if (udev->host.pipe[pp_num].ep.dir) { + return udev->host.pipe[pp_num].data_toggle_in; + } else { + return udev->host.pipe[pp_num].data_toggle_out; + } +} + +/* function declarations */ +/* create a pipe */ +uint8_t usbh_pipe_create (usb_core_driver *udev, + usb_dev_prop *dev, + uint8_t pp_num, + uint8_t ep_type, + uint16_t ep_mpl); +/* modify a pipe */ +uint8_t usbh_pipe_update (usb_core_driver *udev, + uint8_t pp_num, + uint8_t dev_addr, + uint32_t dev_speed, + uint16_t ep_mpl); +/* allocate a new pipe */ +uint8_t usbh_pipe_allocate (usb_core_driver *udev, uint8_t ep_addr); +/* free a pipe */ +uint8_t usbh_pipe_free (usb_core_driver *udev, uint8_t pp_num); +/* delete all USB host pipe */ +uint8_t usbh_pipe_delete (usb_core_driver *udev); + +#endif /* __USBH_PIPE_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_transc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_transc.h new file mode 100644 index 0000000000..b1b120a596 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Include/usbh_transc.h @@ -0,0 +1,51 @@ +/*! + \file usbh_transc.h + \brief USB host mode transactions header file + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USBH_TRANSC_H +#define __USBH_TRANSC_H + +#include "usb_conf.h" +#include "usbh_core.h" + +/* function declarations */ +/* send the setup packet to the USB device */ +usbh_status usbh_ctlsetup_send (usb_core_driver *udev, uint8_t *buf, uint8_t pp_num); +/* send a data packet to the USB device */ +usbh_status usbh_data_send (usb_core_driver *udev, uint8_t *buf, uint8_t pp_num, uint16_t len); +/* receive a data packet from the USB device */ +usbh_status usbh_data_recev (usb_core_driver *udev, uint8_t *buf, uint8_t pp_num, uint16_t len); +/* USB control transfer handler */ +usbh_status usbh_ctl_handler (usbh_host *uhost); + +#endif /* __USBH_TRANSC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_core.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_core.c new file mode 100644 index 0000000000..8f77869b31 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_core.c @@ -0,0 +1,722 @@ +/*! + \file usbh_core.c + \brief USB host core state machine driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "drv_usb_hw.h" +#include "usbh_pipe.h" +#include "usbh_enum.h" +#include "usbh_core.h" +#include "drv_usbh_int.h" +#include + +/* local function prototypes ('static') */ +static uint8_t usbh_sof(usbh_host *uhost); +static uint8_t usbh_connect(usbh_host *uhost); +static uint8_t usbh_disconnect(usbh_host *uhost); +static uint8_t usbh_port_enabled(usbh_host *uhost); +static uint8_t usbh_port_disabled(usbh_host *uhost); +static usbh_status usbh_enum_task(usbh_host *uhost); + +#if USB_LOW_POWER +static void usb_hwp_suspend(usb_core_driver *udev); +static void usb_hwp_resume(usb_core_driver *udev); +#endif + +usbh_int_cb usbh_int_op = { + usbh_connect, + usbh_disconnect, + usbh_port_enabled, + usbh_port_disabled, + usbh_sof +}; + +usbh_int_cb *usbh_int_fop = &usbh_int_op; + +/*! + \brief USB host stack initializations + \param[in] uhost: pointer to USB host + \param[in] udev: pointer to USB core instance + \param[in] user_cb: pointer to user callback + \param[out] none + \retval none +*/ +void usbh_init(usbh_host *uhost, usb_core_driver *udev, usbh_user_cb *user_cb) +{ + /* host de-initializations */ + usbh_deinit(uhost); + + uhost->usr_cb = user_cb; + + udev->host.connect_status = 0U; + + for(uint8_t i = 0U; i < USBHS_MAX_TX_FIFOS; i++) { + udev->host.pipe[i].err_count = 0U; + udev->host.pipe[i].pp_status = PIPE_IDLE; + udev->host.backup_xfercount[i] = 0U; + } + + udev->host.pipe[0].ep.mps = 8U; + + usb_basic_init(&udev->bp, &udev->regs); + +#ifndef DUAL_ROLE_MODE_ENABLED + + usb_core_init(udev->bp, &udev->regs); + + usb_host_init(udev); + +#endif /* DUAL_ROLE_MODE_ENABLED */ + + /* link driver to the stack */ + udev->host.data = (void *)uhost; + uhost->data = (void *)udev; + + /* upon initialize call USR call back */ + uhost->usr_cb->dev_init(); +} + +/*! + \brief USB host register device class + \param[in] uhost: pointer to USB host instance + \param[in] puclass: pointer to USB device class + \param[out] none + \retval operation status +*/ +usbh_status usbh_class_register(usbh_host *uhost, usbh_class *puclass) +{ + usbh_status status = USBH_OK; + + if(NULL != puclass) { + if(uhost->class_num < USBH_MAX_SUPPORTED_CLASS) { + uhost->uclass[uhost->class_num++] = puclass; + } else { + status = USBH_FAIL; + } + } else { + status = USBH_FAIL; + } + + return status; +} + +/*! + \brief de-initialize USB host + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +usbh_status usbh_deinit(usbh_host *uhost) +{ + usb_core_driver *udev = (usb_core_driver *)uhost->data; + + /* software initialize */ + uhost->cur_state = HOST_DEFAULT; + uhost->backup_state = HOST_DEFAULT; + uhost->enum_state = ENUM_DEFAULT; + + uhost->control.ctl_state = CTL_IDLE; + uhost->control.max_len = USB_FS_EP0_MAX_LEN; + + uhost->dev_prop.addr = USBH_DEV_ADDR_DEFAULT; + uhost->dev_prop.speed = PORT_SPEED_FULL; + uhost->dev_prop.cur_itf = 0xFFU; + + usbh_pipe_free(udev, uhost->control.pipe_in_num); + usbh_pipe_free(udev, uhost->control.pipe_out_num); + + return USBH_OK; +} + +/*! + \brief USB host core main state machine process + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +void usbh_core_task(usbh_host *uhost) +{ + volatile usbh_status status = USBH_FAIL; + usb_core_driver *udev = (usb_core_driver *)uhost->data; + + /* check for host port events */ + if(((0U == udev->host.connect_status) || (0U == udev->host.port_enabled)) && (HOST_DEFAULT != uhost->cur_state)) { + if(uhost->cur_state != HOST_DEV_DETACHED) { + uhost->cur_state = HOST_DEV_DETACHED; + } + } + + switch(uhost->cur_state) { + case HOST_DEFAULT: + if(udev->host.connect_status) { + uhost->cur_state = HOST_DETECT_DEV_SPEED; + + usb_mdelay(100U); + + usb_port_reset(udev); + + uhost->usr_cb->dev_reset(); + } + break; + + case HOST_DETECT_DEV_SPEED: + if(udev->host.port_enabled) { + uhost->cur_state = HOST_DEV_ATTACHED; + + uhost->dev_prop.speed = usb_curspeed_get(udev); + + uhost->usr_cb->dev_speed_detected(uhost->dev_prop.speed); + + usb_mdelay(50U); + } + break; + + case HOST_DEV_ATTACHED: + uhost->usr_cb->dev_attach(); + uhost->control.pipe_out_num = usbh_pipe_allocate(udev, 0x00U); + uhost->control.pipe_in_num = usbh_pipe_allocate(udev, 0x80U); + + /* open IN control pipe */ + usbh_pipe_create(udev, + &uhost->dev_prop, + uhost->control.pipe_in_num, + USB_EPTYPE_CTRL, + (uint16_t)uhost->control.max_len); + + /* open OUT control pipe */ + usbh_pipe_create(udev, + &uhost->dev_prop, + uhost->control.pipe_out_num, + USB_EPTYPE_CTRL, + (uint16_t)uhost->control.max_len); + + uhost->cur_state = HOST_ENUM; + break; + + case HOST_ENUM: + /* check for enumeration status */ + if(USBH_OK == usbh_enum_task(uhost)) { + /* the function shall return USBH_OK when full enumeration is complete */ + + /* user callback for end of device basic enumeration */ + uhost->usr_cb->dev_enumerated(); + +#if USB_LOW_POWER + uhost->cur_state = HOST_SUSPENDED; + + /* judge device remote wakup function */ + if((uhost->dev_prop.cfg_desc_set.cfg_desc.bmAttributes) & (1U << 5)) { + uhost->dev_supp_remote_wkup = 1; + } else { + uhost->dev_supp_remote_wkup = 0; + } +#else + uhost->cur_state = HOST_SET_WAKEUP_FEATURE; +#endif + } + break; + + case HOST_SET_WAKEUP_FEATURE: + if((uhost->dev_prop.cfg_desc_set.cfg_desc.bmAttributes) & (1U << 5)) { + if(usbh_setdevfeature(uhost, FEATURE_SELECTOR_REMOTEWAKEUP, 0U) == USBH_OK) { + uhost->cur_state = HOST_CHECK_CLASS; + } + } else { + uhost->cur_state = HOST_CHECK_CLASS; + } + break; + + case HOST_CHECK_CLASS: + if(0U == uhost->class_num) { + uhost->cur_state = HOST_ERROR; + } else { + uhost->active_class = NULL; + + uint8_t itf_class = uhost->dev_prop.cfg_desc_set.itf_desc_set[0][0].itf_desc.bInterfaceClass; + + for(uint8_t index = 0U; index < uhost->class_num; index++) { + if((uhost->uclass[index]->class_code == itf_class) || (0xFFU == itf_class)) { + uhost->active_class = uhost->uclass[index]; + } + } + + if(uhost->active_class != NULL) { + uhost->cur_state = HOST_USER_INPUT; + } else { + uhost->cur_state = HOST_ERROR; + } + } + break; + + case HOST_USER_INPUT: + /* the function should return user response true to move to class state */ + if(USBH_USER_RESP_OK == uhost->usr_cb->dev_user_input()) { + if((USBH_OK == uhost->active_class->class_init(uhost))) { + uhost->cur_state = HOST_CLASS_ENUM; + } + } + break; + +#if USB_LOW_POWER + case HOST_SUSPENDED: + if(uhost->dev_supp_remote_wkup) { + /* send set feature command*/ + if(USBH_OK == usbh_setdevfeature(uhost, FEATURE_SELECTOR_REMOTEWAKEUP, 0U)) { + + usb_hwp_suspend(udev); + + usb_mdelay(20U); + uhost->suspend_flag = 1; + uhost->usr_cb->dev_user_input(); + + /* MCU enter deep-sleep*/ + pmu_to_deepsleepmode(WFI_CMD); + uhost->cur_state = HOST_WAKEUP; + } + } else { + /* host suspend */ + usb_hwp_suspend(udev); + + usb_mdelay(20U); + uhost->suspend_flag = 1U; + uhost->usr_cb->dev_user_input(); + + /* MCU enter deep-sleep */ + pmu_to_deepsleepmode(WFI_CMD); + uhost->cur_state = HOST_WAKEUP; + } + break; + + case HOST_WAKEUP: + /* judge suspend status */ + if(0 == uhost->suspend_flag) { + usb_hwp_resume(udev); + usb_mdelay(500U); + + if(uhost->dev_supp_remote_wkup) { + if(USBH_OK == usbh_clrdevfeature(uhost, FEATURE_SELECTOR_DEV, 0U)) { + /* user callback for initialization */ + uhost->usr_cb->dev_init(); + uhost->cur_state = HOST_CHECK_CLASS; + } + } else { + uhost->cur_state = HOST_CHECK_CLASS; + } + } + break; +#endif + + case HOST_CLASS_ENUM: + /* process class standard control requests state machine */ + status = uhost->active_class->class_requests(uhost); + + if(USBH_OK == status) { + uhost->cur_state = HOST_CLASS_HANDLER; + } else { + usbh_error_handler(uhost, status); + } + break; + + case HOST_CLASS_HANDLER: + /* process class state machine */ + status = uhost->active_class->class_machine(uhost); + + usbh_error_handler(uhost, status); + break; + + case HOST_ERROR: + /* initialize host for new enumeration */ + usbh_deinit(uhost); + uhost->usr_cb->dev_deinit(); + uhost->active_class->class_deinit(uhost); + break; + + case HOST_DEV_DETACHED: + /* manage user disconnect operations*/ + uhost->usr_cb->dev_detach(); + + /* re-initialize host for new enumeration */ + usbh_deinit(uhost); + uhost->usr_cb->dev_deinit(); + uhost->active_class->class_deinit(uhost); + usbh_pipe_delete(udev); + uhost->cur_state = HOST_DEFAULT; + break; + + default: + break; + } +} + +/*! + \brief handle the error on USB host side + \param[in] uhost: pointer to USB host + \param[in] err_type: type of error or busy/OK state + \param[out] none + \retval none +*/ +void usbh_error_handler(usbh_host *uhost, usbh_status err_type) +{ + /* error unrecovered or not supported device speed */ + if((USBH_SPEED_UNKNOWN_ERROR == err_type) || (USBH_UNRECOVERED_ERROR == err_type)) { + uhost->usr_cb->dev_error(); + + uhost->cur_state = HOST_ERROR; + } else if(USBH_APPLY_DEINIT == err_type) { + uhost->cur_state = HOST_ERROR; + + /* user callback for initialization */ + uhost->usr_cb->dev_init(); + } else { + /* no operation */ + } +} + +/*! + \brief USB SOF callback function from the interrupt + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static uint8_t usbh_sof(usbh_host *uhost) +{ + usb_core_driver *udev = (usb_core_driver *)uhost->data; + + /* update timer variable */ + uhost->control.timer++; + + if(NULL != uhost->active_class) { + if(NULL != uhost->active_class->class_sof) { + uhost->active_class->class_sof(uhost); + } + } + + return 0U; +} + +/*! + \brief USB connect callback function from the interrupt + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static uint8_t usbh_connect(usbh_host *uhost) +{ + usb_core_driver *udev = (usb_core_driver *)uhost->data; + udev->host.connect_status = 1U; + + return 0U; +} + +/*! + \brief USB disconnect callback function from the interrupt + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static uint8_t usbh_disconnect(usbh_host *uhost) +{ + usb_core_driver *udev = (usb_core_driver *)uhost->data; + udev->host.connect_status = 0U; + + return 0U; +} + +/*! + \brief USB port enable callback function from the interrupt + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static uint8_t usbh_port_enabled(usbh_host *uhost) +{ + usb_core_driver *udev = (usb_core_driver *)uhost->data; + udev->host.port_enabled = 1U; + + return 0U; +} + +/*! + \brief USB port disabled callback function from the interrupt + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +static uint8_t usbh_port_disabled(usbh_host *uhost) +{ + usb_core_driver *udev = (usb_core_driver *)uhost->data; + udev->host.port_enabled = 0U; + + return 0U; +} + +/*! + \brief handle the USB enumeration task + \param[in] uhost: pointer to host + \param[out] none + \retval none +*/ +static usbh_status usbh_enum_task(usbh_host *uhost) +{ + uint8_t str_buf[512]; + usbh_status status = USBH_BUSY; + usb_core_driver *udev = (usb_core_driver *)uhost->data; + +#ifdef USB_MTP + static uint8_t interface = 0U, index_itf_str = 0U; +#endif /* USB_MTP */ + + static uint8_t index_mfc_str = 0U, index_prod_str = 0U, index_serial_str = 0U; + + switch(uhost->enum_state) { + case ENUM_DEFAULT: + /* get device descriptor for only 1st 8 bytes : to get ep0 maxpacketsize */ + if(USBH_OK == usbh_devdesc_get(uhost, 8U)) { + uhost->control.max_len = uhost->dev_prop.dev_desc.bMaxPacketSize0; + + /* modify control channels configuration for maximum packet size */ + usbh_pipe_update(udev, + uhost->control.pipe_out_num, + 0U, 0U, + (uint16_t)uhost->control.max_len); + + usbh_pipe_update(udev, + uhost->control.pipe_in_num, + 0U, 0U, + (uint16_t)uhost->control.max_len); + + uhost->enum_state = ENUM_GET_DEV_DESC; + } + break; + + case ENUM_GET_DEV_DESC: + /* get full device descriptor */ + if(USBH_OK == usbh_devdesc_get(uhost, USB_DEV_DESC_LEN)) { + uhost->usr_cb->dev_devdesc_assigned(&uhost->dev_prop.dev_desc); + + index_mfc_str = uhost->dev_prop.dev_desc.iManufacturer; + index_prod_str = uhost->dev_prop.dev_desc.iProduct; + index_serial_str = uhost->dev_prop.dev_desc.iSerialNumber; + + uhost->enum_state = ENUM_SET_ADDR; + } + break; + + case ENUM_SET_ADDR: + /* set address */ + if(USBH_OK == usbh_setaddress(uhost, USBH_DEV_ADDR)) { + usb_mdelay(2U); + + uhost->dev_prop.addr = USBH_DEV_ADDR; + + /* user callback for device address assigned */ + uhost->usr_cb->dev_address_set(); + + /* modify control channels to update device address */ + usbh_pipe_update(udev, + uhost->control.pipe_in_num, + uhost->dev_prop.addr, + 0U, 0U); + + usbh_pipe_update(udev, + uhost->control.pipe_out_num, + uhost->dev_prop.addr, + 0U, 0U); + + uhost->enum_state = ENUM_GET_CFG_DESC; + } + break; + + case ENUM_GET_CFG_DESC: + /* get standard configuration descriptor */ + if(USBH_OK == usbh_cfgdesc_get(uhost, USB_CFG_DESC_LEN)) { + uhost->enum_state = ENUM_GET_CFG_DESC_SET; + } + break; + + case ENUM_GET_CFG_DESC_SET: + /* get full configure descriptor (config, interface, endpoints) */ + if(USBH_OK == usbh_cfgdesc_get(uhost, uhost->dev_prop.cfg_desc_set.cfg_desc.wTotalLength)) { + /* user callback for configuration descriptors available */ + uhost->usr_cb->dev_cfgdesc_assigned(&uhost->dev_prop.cfg_desc_set.cfg_desc, + &uhost->dev_prop.cfg_desc_set.itf_desc_set[0][0].itf_desc, + &uhost->dev_prop.cfg_desc_set.itf_desc_set[0][0].ep_desc[0]); + + uhost->enum_state = ENUM_GET_STR_DESC; + } + break; + + case ENUM_GET_STR_DESC: + if(index_mfc_str) { + if(USBH_OK == usbh_strdesc_get(uhost, + uhost->dev_prop.dev_desc.iManufacturer, + str_buf, + 0xFFU)) { + /* user callback for manufacturing string */ + uhost->usr_cb->dev_mfc_str(str_buf); + + index_mfc_str = 0U; + } + } else { + if(index_prod_str) { + /* check that product string is available */ + if(USBH_OK == usbh_strdesc_get(uhost, + uhost->dev_prop.dev_desc.iProduct, + str_buf, + 0xFFU)) { + uhost->usr_cb->dev_prod_str(str_buf); + + index_prod_str = 0U; + } + } else { + if(index_serial_str) { + if(USBH_OK == usbh_strdesc_get(uhost, + uhost->dev_prop.dev_desc.iSerialNumber, + str_buf, + 0xFFU)) { + uhost->usr_cb->dev_seral_str(str_buf); +#ifndef USB_MTP + uhost->enum_state = ENUM_SET_CONFIGURATION; +#else + uhost->enum_state = ENUM_GET_MTP_STR; +#endif + + index_serial_str = 0U; + } + } else { +#ifndef USB_MTP + uhost->enum_state = ENUM_SET_CONFIGURATION; +#else + uhost->enum_state = ENUM_GET_MTP_STR; +#endif + } + } + } + break; + +#ifdef USB_MTP + case ENUM_GET_MTP_STR: + if(interface < uhost->dev_prop.cfg_desc_set.cfg_desc.bNumInterfaces) { + index_itf_str = uhost->dev_prop.cfg_desc_set.itf_desc_set[interface][0].itf_desc.iInterface; + + if(index_itf_str != 0U) { + if(USBH_OK == usbh_strdesc_get(uhost, index_itf_str, str_buf, 0xFFU)) { + if(0U == strcmp((const char *)str_buf, "MTP")) { + uhost->dev_prop.cur_itf = interface; + + uhost->enum_state = ENUM_SET_CONFIGURATION; + interface = 0U; + } else { + interface ++; + } + } + } else { + interface ++; + } + } else { + interface = 0U; + uhost->enum_state = ENUM_SET_CONFIGURATION; + } + break; +#endif + + case ENUM_SET_CONFIGURATION: + if(USBH_OK == usbh_setcfg(uhost, (uint16_t)uhost->dev_prop.cfg_desc_set.cfg_desc.bConfigurationValue)) { + uhost->enum_state = ENUM_DEV_CONFIGURED; + } + break; + + case ENUM_DEV_CONFIGURED: + status = USBH_OK; + break; + + default: + break; + } + + return status; +} + +#if USB_LOW_POWER + +/*! + \brief handles the USB resume from suspend mode + \param[in] udev: pointer to USB core instance + \param[out] none + \retval none +*/ +static void usb_hwp_resume(usb_core_driver *udev) +{ + __IO uint32_t hprt = 0U; + + /* switch-on the clocks */ + *udev->regs.PWRCLKCTL &= ~PWRCLKCTL_SUCLK; + + *udev->regs.PWRCLKCTL &= ~PWRCLKCTL_SHCLK; + + hprt = usb_port_read(udev); + + hprt &= ~HPCS_PSP; + hprt |= HPCS_PREM; + + *udev->regs.HPCS = hprt; + + usb_mdelay(20U); + + hprt &= ~HPCS_PREM; + + *udev->regs.HPCS = hprt; +} + +/*! + \brief handles the USB enter to suspend mode + \param[in] udev: pointer to USB core instance + \param[out] none + \retval none +*/ +static void usb_hwp_suspend(usb_core_driver *udev) +{ + __IO uint32_t hprt = 0U; + + hprt = usb_port_read(udev); + + hprt |= HPCS_PSP; + + *udev->regs.HPCS = hprt; + + /* switch-off the clocks */ + *udev->regs.PWRCLKCTL |= PWRCLKCTL_SUCLK; + + *udev->regs.PWRCLKCTL |= PWRCLKCTL_SHCLK; +} + +#endif diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_enum.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_enum.c new file mode 100644 index 0000000000..a981cdcd9f --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_enum.c @@ -0,0 +1,691 @@ +/*! + \file usbh_enum.c + \brief USB host mode enumeration driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_pipe.h" +#include "usbh_transc.h" +#include "usbh_enum.h" + +/* local function prototypes ('static') */ +static void usbh_devdesc_parse(usb_desc_dev *dev_desc, uint8_t *buf, uint16_t len); +static void usbh_cfgdesc_parse(usb_desc_config *cfg_desc, uint8_t *buf); +static void usbh_cfgset_parse(usb_dev_prop *udev, uint8_t *buf); +static void usbh_itfdesc_parse(usb_desc_itf *itf_desc, uint8_t *buf); +static void usbh_epdesc_parse(usb_desc_ep *ep_desc, uint8_t *buf); +static void usbh_strdesc_parse(uint8_t *psrc, uint8_t *pdest, uint16_t len); + +/*! + \brief configure USB control status parameters + \param[in] uhost: pointer to USB host + \param[in] buf: control transfer data buffer pointer + \param[in] len: length of the data buffer + \param[out] none + \retval none +*/ +void usbh_ctlstate_config(usbh_host *uhost, uint8_t *buf, uint16_t len) +{ + /* prepare the transactions */ + uhost->control.buf = buf; + uhost->control.ctl_len = len; + + uhost->control.ctl_state = CTL_SETUP; +} + +/*! + \brief get device descriptor from the USB device + \param[in] uhost: pointer to USB host + \param[in] len: length of the descriptor + \param[out] none + \retval operation status +*/ +usbh_status usbh_devdesc_get(usbh_host *uhost, uint8_t len) +{ + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, + .bRequest = USB_GET_DESCRIPTOR, + .wValue = USBH_DESC(USB_DESCTYPE_DEV), + .wIndex = 0U, + .wLength = len + }; + + usbh_ctlstate_config(uhost, uhost->dev_prop.data, (uint16_t)len); + } + + status = usbh_ctl_handler(uhost); + + if(USBH_OK == status) { + /* commands successfully sent and response received */ + usbh_devdesc_parse(&uhost->dev_prop.dev_desc, uhost->dev_prop.data, (uint16_t)len); + } + + return status; +} + +/*! + \brief get configuration descriptor from the USB device + \param[in] uhost: pointer to USB host + \param[in] len: length of the descriptor + \param[out] none + \retval operation status +*/ +usbh_status usbh_cfgdesc_get(usbh_host *uhost, uint16_t len) +{ + uint8_t *pdata = NULL; + + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + +#if (USBH_KEEP_CFG_DESCRIPTOR == 1U) + pdata = uhost->dev_prop.cfgdesc_rawdata; +#else + pdata = uhost->dev_prop.data; +#endif + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, + .bRequest = USB_GET_DESCRIPTOR, + .wValue = USBH_DESC(USB_DESCTYPE_CONFIG), + .wIndex = 0U, + .wLength = len + }; + + usbh_ctlstate_config(uhost, pdata, len); + } + + status = usbh_ctl_handler(uhost); + + if(USBH_OK == status) { + if(len <= USB_CFG_DESC_LEN) { + usbh_cfgdesc_parse(&uhost->dev_prop.cfg_desc_set.cfg_desc, pdata); + } else { + usbh_cfgset_parse(&uhost->dev_prop, pdata); + } + } + + return status; +} + +/*! + \brief get string descriptor from the USB device + \param[in] uhost: pointer to USB host + \param[in] str_index: index for the string descriptor + \param[in] buf: buffer pointer to the string descriptor + \param[in] len: length of the descriptor + \param[out] none + \retval operation status +*/ +usbh_status usbh_strdesc_get(usbh_host *uhost, + uint8_t str_index, + uint8_t *buf, + uint16_t len) +{ + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_IN | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, + .bRequest = USB_GET_DESCRIPTOR, + .wValue = USBH_DESC(USB_DESCTYPE_STR) | str_index, + .wIndex = 0x0409U, + .wLength = len + }; + + usbh_ctlstate_config(uhost, uhost->dev_prop.data, len); + } + + status = usbh_ctl_handler(uhost); + + if(USBH_OK == status) { + /* commands successfully sent and response received */ + usbh_strdesc_parse(uhost->dev_prop.data, buf, len); + } + + return status; +} + +/*! + \brief set the address to the connected device + \param[in] uhost: pointer to USB host + \param[in] dev_addr: device address to assign + \param[out] none + \retval operation status +*/ +usbh_status usbh_setaddress(usbh_host *uhost, uint8_t dev_addr) +{ + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, + .bRequest = USB_SET_ADDRESS, + .wValue = (uint16_t)dev_addr, + .wIndex = 0U, + .wLength = 0U + }; + + usbh_ctlstate_config(uhost, NULL, 0U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief set the configuration value to the connected device + \param[in] uhost: pointer to USB host + \param[in] config_index: configuration value + \param[out] none + \retval operation status +*/ +usbh_status usbh_setcfg(usbh_host *uhost, uint16_t config_index) +{ + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, + .bRequest = USB_SET_CONFIGURATION, + .wValue = config_index, + .wIndex = 0U, + .wLength = 0U + }; + + usbh_ctlstate_config(uhost, NULL, 0U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief set the interface value to the connected device + \param[in] uhost: pointer to USB host + \param[in] itf_num: interface number + \param[in] set: alternated setting value + \param[out] none + \retval operation status +*/ +usbh_status usbh_setinterface(usbh_host *uhost, uint8_t itf_num, uint8_t set) +{ + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_ITF | USB_REQTYPE_STRD, + .bRequest = USB_SET_INTERFACE, + .wValue = set, + .wIndex = itf_num, + .wLength = 0U + }; + + usbh_ctlstate_config(uhost, NULL, 0U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief set the interface value to the connected device + \param[in] uhost: pointer to USB host + \param[in] feature_selector: feature selector + \param[in] windex: index value + \param[out] none + \retval operation status +*/ +usbh_status usbh_setdevfeature(usbh_host *uhost, uint8_t feature_selector, uint16_t windex) +{ + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, + .bRequest = USB_SET_FEATURE, + .wValue = feature_selector, + .wIndex = windex, + .wLength = 0U + }; + + usbh_ctlstate_config(uhost, NULL, 0U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief clear the interface value to the connected device + \param[in] uhost: pointer to USB host + \param[in] feature_selector: feature selector + \param[in] windex: index value + \param[out] none + \retval operation status +*/ +usbh_status usbh_clrdevfeature(usbh_host *uhost, uint8_t feature_selector, uint16_t windex) +{ + usbh_status status = USBH_BUSY; + + usbh_control *usb_ctl = &uhost->control; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, + .bRequest = USB_CLEAR_FEATURE, + .wValue = feature_selector, + .wIndex = windex, + .wLength = 0U + }; + + usbh_ctlstate_config(uhost, NULL, 0U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief clear or disable a specific feature + \param[in] uhost: pointer to USB host + \param[in] ep_addr: endpoint address + \param[in] pp_num: pipe number + \param[out] none + \retval operation status +*/ +usbh_status usbh_clrfeature(usbh_host *uhost, uint8_t ep_addr, uint8_t pp_num) +{ + usbh_status status = USBH_BUSY; + usbh_control *usb_ctl = &uhost->control; + usb_core_driver *udev = (usb_core_driver *)uhost->data; + + if(CTL_IDLE == usb_ctl->ctl_state) { + usb_ctl->setup.req = (usb_req) { + .bmRequestType = USB_TRX_OUT | USB_RECPTYPE_EP | USB_REQTYPE_STRD, + .bRequest = USB_CLEAR_FEATURE, + .wValue = FEATURE_SELECTOR_EP, + .wIndex = ep_addr, + .wLength = 0U + }; + + if(EP_ID(ep_addr) == udev->host.pipe[pp_num].ep.num) { + usbh_pipe_toggle_set(udev, pp_num, 0U); + } else { + return USBH_FAIL; + } + + usbh_ctlstate_config(uhost, NULL, 0U); + } + + status = usbh_ctl_handler(uhost); + + return status; +} + +/*! + \brief get the next descriptor header + \param[in] pbuf: pointer to buffer where the configuration descriptor set is available + \param[in] ptr: data pointer inside the configuration descriptor set + \param[out] none + \retval return descriptor header +*/ +usb_desc_header *usbh_nextdesc_get(uint8_t *pbuf, uint16_t *ptr) +{ + usb_desc_header *pnext; + + *ptr += ((usb_desc_header *)pbuf)->bLength; + + pnext = (usb_desc_header *)((uint8_t *)pbuf + ((usb_desc_header *)pbuf)->bLength); + + return (pnext); +} + +/*! + \brief get the next descriptor header + \param[in] udev: pointer to device property + \param[in] interface: interface number + \param[out] none + \retval operation status +*/ +usbh_status usbh_interface_select(usb_dev_prop *udev, uint8_t interface) +{ + usbh_status status = USBH_OK; + + if(interface < udev->cfg_desc_set.cfg_desc.bNumInterfaces) { + udev->cur_itf = interface; + } else { + status = USBH_FAIL; + } + + return status; +} + +/*! + \brief find the interface index for a specific class + \param[in] udev: pointer to device property + \param[in] main_class: class code + \param[in] sub_class: subclass code + \param[in] protocol: Protocol code + \param[out] none + \retval interface index in the configuration structure +*/ +uint8_t usbh_interface_find(usb_dev_prop *udev, uint8_t main_class, uint8_t sub_class, uint8_t protocol) +{ + usb_desc_itf *pif; + + uint8_t if_ix = 0U; + + pif = (usb_desc_itf *)0; + + while(if_ix < udev->cfg_desc_set.cfg_desc.bNumInterfaces) { + pif = &udev->cfg_desc_set.itf_desc_set[if_ix][0].itf_desc; + + if(((pif->bInterfaceClass == main_class) || (0xFFU == main_class)) && + ((pif->bInterfaceSubClass == sub_class) || (0xFFU == sub_class)) && + ((pif->bInterfaceProtocol == protocol) || (0xFFU == protocol))) { + return if_ix; + } + + if_ix++; + } + + return 0xFFU; +} + +/*! + \brief find the interface index for a specific class interface and alternate setting number + \param[in] udev: pointer to device property + \param[in] interface_number: interface number + \param[in] alt_settings: alternate setting number + \param[out] none + \retval interface index in the configuration structure +*/ +uint8_t usbh_interfaceindex_find(usb_dev_prop *udev, uint8_t interface_number, uint8_t alt_settings) +{ + usb_desc_itf *pif; + + uint8_t if_ix = 0U; + + pif = (usb_desc_itf *)0; + + while(if_ix < USBH_MAX_INTERFACES_NUM) { + pif = &udev->cfg_desc_set.itf_desc_set[if_ix][alt_settings].itf_desc; + + if((pif->bInterfaceNumber == interface_number) && (pif->bAlternateSetting == alt_settings)) { + return if_ix; + } + + if_ix++; + } + + return 0xFFU; +} + +/*! + \brief parse the device descriptor + \param[in] dev_desc: pointer to USB device descriptor buffer + \param[in] buf: pointer to the source descriptor buffer + \param[in] len: length of the descriptor + \param[out] none + \retval none +*/ +static void usbh_devdesc_parse(usb_desc_dev *dev_desc, uint8_t *buf, uint16_t len) +{ + *dev_desc = (usb_desc_dev) { + .header = { + .bLength = *(uint8_t *)(buf + 0U), + .bDescriptorType = *(uint8_t *)(buf + 1U) + }, + + .bcdUSB = BYTE_SWAP(buf + 2U), + .bDeviceClass = *(uint8_t *)(buf + 4U), + .bDeviceSubClass = *(uint8_t *)(buf + 5U), + .bDeviceProtocol = *(uint8_t *)(buf + 6U), + .bMaxPacketSize0 = *(uint8_t *)(buf + 7U) + }; + + if(len > 8U) { + /* for 1st time after device connection, host may issue only 8 bytes for device descriptor length */ + dev_desc->idVendor = BYTE_SWAP(buf + 8U); + dev_desc->idProduct = BYTE_SWAP(buf + 10U); + dev_desc->bcdDevice = BYTE_SWAP(buf + 12U); + dev_desc->iManufacturer = *(uint8_t *)(buf + 14U); + dev_desc->iProduct = *(uint8_t *)(buf + 15U); + dev_desc->iSerialNumber = *(uint8_t *)(buf + 16U); + dev_desc->bNumberConfigurations = *(uint8_t *)(buf + 17U); + } +} + +/*! + \brief parse the configuration descriptor + \param[in] cfg_desc: pointer to USB configuration descriptor buffer + \param[in] buf: pointer to the source descriptor buffer + \param[out] none + \retval none +*/ +static void usbh_cfgdesc_parse(usb_desc_config *cfg_desc, uint8_t *buf) +{ + /* parse configuration descriptor */ + *cfg_desc = (usb_desc_config) { + .header = { + .bLength = *(uint8_t *)(buf + 0U), + .bDescriptorType = *(uint8_t *)(buf + 1U), + }, + + .wTotalLength = BYTE_SWAP(buf + 2U), + .bNumInterfaces = *(uint8_t *)(buf + 4U), + .bConfigurationValue = *(uint8_t *)(buf + 5U), + .iConfiguration = *(uint8_t *)(buf + 6U), + .bmAttributes = *(uint8_t *)(buf + 7U), + .bMaxPower = *(uint8_t *)(buf + 8U) + }; +} + +/*! + \brief parse the configuration descriptor set + \param[in] udev: pointer to device property + \param[in] buf: pointer to the source descriptor buffer + \param[out] none + \retval none +*/ +static void usbh_cfgset_parse(usb_dev_prop *udev, uint8_t *buf) +{ + usb_desc_ep *ep = NULL; + usb_desc_itf_set *itf = NULL; + usb_desc_itf itf_value; + usb_desc_config *cfg = NULL; + + usb_desc_header *pdesc = (usb_desc_header *)buf; + + uint8_t itf_index = 0U, ep_index = 0U, alt_setting = 0U; + uint8_t pre_itf_index = 0U; + uint16_t ptr; + + /* parse configuration descriptor */ + usbh_cfgdesc_parse(&udev->cfg_desc_set.cfg_desc, buf); + cfg = &udev->cfg_desc_set.cfg_desc; + ptr = USB_CFG_DESC_LEN; + + if(cfg->bNumInterfaces > USBH_MAX_INTERFACES_NUM) { + return; + } + + while(ptr < cfg->wTotalLength) { + pdesc = usbh_nextdesc_get((uint8_t *)pdesc, &ptr); + + if(pdesc->bDescriptorType == USB_DESCTYPE_ITF) { + itf_index = *(((uint8_t *)pdesc) + 2U); + + if(pre_itf_index != itf_index) { + alt_setting = 0U; + } + + itf = &udev->cfg_desc_set.itf_desc_set[itf_index][alt_setting]; + + alt_setting++; + + if((*((uint8_t *)pdesc + 3U)) < 3U) { + usbh_itfdesc_parse(&itf_value, (uint8_t *)pdesc); + + /* parse endpoint descriptors relative to the current interface */ + if(itf_value.bNumEndpoints > USBH_MAX_EP_NUM) { + return; + } + + usbh_itfdesc_parse(&itf->itf_desc, (uint8_t *)&itf_value); + + /* store the previous interface index */ + pre_itf_index = itf_index; + + if(0U == itf_value.bNumEndpoints) { + continue; + } + + for(ep_index = 0U; ep_index < itf_value.bNumEndpoints;) { + pdesc = usbh_nextdesc_get((void *)pdesc, &ptr); + + if(pdesc->bDescriptorType == USB_DESCTYPE_EP) { + ep = &itf->ep_desc[ep_index]; + + usbh_epdesc_parse(ep, (uint8_t *)pdesc); + + ep_index++; + } + } + } + } + } +} + +/*! + \brief parse the interface descriptor + \param[in] itf_desc: pointer to USB interface descriptor buffer + \param[in] buf: pointer to the source descriptor buffer + \param[out] none + \retval none +*/ +static void usbh_itfdesc_parse(usb_desc_itf *itf_desc, uint8_t *buf) +{ + *itf_desc = (usb_desc_itf) { + .header = { + .bLength = *(uint8_t *)(buf + 0U), + .bDescriptorType = *(uint8_t *)(buf + 1U), + }, + + .bInterfaceNumber = *(uint8_t *)(buf + 2U), + .bAlternateSetting = *(uint8_t *)(buf + 3U), + .bNumEndpoints = *(uint8_t *)(buf + 4U), + .bInterfaceClass = *(uint8_t *)(buf + 5U), + .bInterfaceSubClass = *(uint8_t *)(buf + 6U), + .bInterfaceProtocol = *(uint8_t *)(buf + 7U), + .iInterface = *(uint8_t *)(buf + 8U) + }; +} + +/*! + \brief parse the endpoint descriptor + \param[in] ep_desc: pointer to USB endpoint descriptor buffer + \param[in] buf: pointer to the source descriptor buffer + \param[out] none + \retval none +*/ +static void usbh_epdesc_parse(usb_desc_ep *ep_desc, uint8_t *buf) +{ + *ep_desc = (usb_desc_ep) { + .header = { + .bLength = *(uint8_t *)(buf + 0U), + .bDescriptorType = *(uint8_t *)(buf + 1U) + }, + + .bEndpointAddress = *(uint8_t *)(buf + 2U), + .bmAttributes = *(uint8_t *)(buf + 3U), + .wMaxPacketSize = BYTE_SWAP(buf + 4U), + .bInterval = *(uint8_t *)(buf + 6U) + }; +} + +/*! + \brief parse the string descriptor + \param[in] psrc: source pointer containing the descriptor data + \param[in] pdest: destination address pointer + \param[in] len: length of the descriptor + \param[out] none + \retval none +*/ +static void usbh_strdesc_parse(uint8_t *psrc, uint8_t *pdest, uint16_t len) +{ + uint16_t str_len = 0U, index = 0U; + + /* the unicode string descriptor is not NULL-terminated. The string length is + * computed by substracting two from the value of the first byte of the descriptor. + */ + + /* check which is lower size, the size of string or the length of bytes read from the device */ + if(USB_DESCTYPE_STR == psrc[1]) { + /* make sure the descriptor is string type */ + + /* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */ + str_len = USB_MIN((uint16_t)psrc[0] - 2U, len); + + psrc += 2U; /* adjust the offset ignoring the string len and descriptor type */ + + for(index = 0U; index < str_len; index += 2U) { + /* copy only the string and ignore the unicode id, hence add the src */ + *pdest = psrc[index]; + + pdest++; + } + + *pdest = 0U; /* mark end of string */ + } +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_pipe.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_pipe.c new file mode 100644 index 0000000000..e4a0b36c1d --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_pipe.c @@ -0,0 +1,183 @@ +/*! + \file usbh_pipe.c + \brief USB host mode pipe operation driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "usbh_pipe.h" + +/* local function prototypes ('static') */ +static uint16_t usbh_freepipe_get(usb_core_driver *udev); + +/*! + \brief create a pipe + \param[in] udev: pointer to USB core instance + \param[in] dev: USB device + \param[in] pp_num: pipe number + \param[in] ep_type: endpoint type + \param[in] ep_mpl: endpoint max packet length + \param[out] none + \retval operation status +*/ +uint8_t usbh_pipe_create(usb_core_driver *udev, + usb_dev_prop *dev, + uint8_t pp_num, + uint8_t ep_type, + uint16_t ep_mpl) +{ + usb_pipe *pp = &udev->host.pipe[pp_num]; + + pp->dev_addr = dev->addr; + pp->dev_speed = dev->speed; + pp->ep.type = ep_type; + pp->ep.mps = ep_mpl; + + if (((USB_EPTYPE_BULK == pp->ep.type) || (USB_EPTYPE_CTRL == pp->ep.type))) { + pp->supp_ping = (uint8_t)(pp->dev_speed == PORT_SPEED_HIGH); + } + + usb_pipe_init(udev, pp_num); + + return HC_OK; +} + +/*! + \brief modify a pipe + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pipe number + \param[in] dev_addr: device address + \param[in] dev_speed: device speed + \param[in] ep_mpl: endpoint max packet length + \param[out] none + \retval operation status +*/ +uint8_t usbh_pipe_update(usb_core_driver *udev, + uint8_t pp_num, + uint8_t dev_addr, + uint32_t dev_speed, + uint16_t ep_mpl) +{ + usb_pipe *pp = &udev->host.pipe[pp_num]; + + if((pp->dev_addr != dev_addr) && (dev_addr)) { + pp->dev_addr = dev_addr; + } + + if((pp->dev_speed != dev_speed) && (dev_speed)) { + pp->dev_speed = dev_speed; + + if (((USB_EPTYPE_BULK == pp->ep.type) || (USB_EPTYPE_CTRL == pp->ep.type))) { + pp->supp_ping = (uint8_t)(pp->dev_speed == PORT_SPEED_HIGH); + } + } + + if((pp->ep.mps != ep_mpl) && (ep_mpl)) { + pp->ep.mps = ep_mpl; + } + + usb_pipe_init(udev, pp_num); + + return HC_OK; +} + +/*! + \brief allocate a new pipe + \param[in] udev: pointer to USB core instance + \param[in] ep_addr: endpoint address + \param[out] none + \retval operation status +*/ +uint8_t usbh_pipe_allocate(usb_core_driver *udev, uint8_t ep_addr) +{ + uint16_t pp_num = usbh_freepipe_get(udev); + + if(HC_ERROR != pp_num) { + udev->host.pipe[pp_num].in_used = 1U; + udev->host.pipe[pp_num].ep.dir = EP_DIR(ep_addr); + udev->host.pipe[pp_num].ep.num = EP_ID(ep_addr); + } + + return (uint8_t)pp_num; +} + +/*! + \brief free a pipe + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pipe number + \param[out] none + \retval operation status +*/ +uint8_t usbh_pipe_free(usb_core_driver *udev, uint8_t pp_num) +{ + if(pp_num < HC_MAX) { + udev->host.pipe[pp_num].in_used = 0U; + } + + return USBH_OK; +} + +/*! + \brief delete all USB host pipe + \param[in] udev: pointer to USB core instance + \param[out] none + \retval operation status +*/ +uint8_t usbh_pipe_delete(usb_core_driver *udev) +{ + uint8_t pp_num = 0U; + + for(pp_num = 2U; pp_num < HC_MAX; pp_num++) { + udev->host.pipe[pp_num] = (usb_pipe) { + 0 + }; + } + + return USBH_OK; +} + +/*! + \brief get a free pipe number for allocation + \param[in] udev: pointer to USB core instance + \param[out] none + \retval operation status +*/ +static uint16_t usbh_freepipe_get(usb_core_driver *udev) +{ + uint8_t pp_num = 0U; + + for(pp_num = 0U; pp_num < HC_MAX; pp_num++) { + if(0U == udev->host.pipe[pp_num].in_used) { + return (uint16_t)pp_num; + } + } + + return HC_ERROR; +} diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_transc.c b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_transc.c new file mode 100644 index 0000000000..dab9897469 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/host/core/Source/usbh_transc.c @@ -0,0 +1,371 @@ +/*! + \file usbh_transc.c + \brief USB host mode transactions driver + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "drv_usb_hw.h" +#include "usbh_pipe.h" +#include "usbh_transc.h" + +/* local function prototypes ('static') */ +static usb_urb_state usbh_urb_wait(usbh_host *uhost, uint8_t pp_num, uint32_t wait_time); +static void usbh_setup_transc(usbh_host *uhost); +static void usbh_data_in_transc(usbh_host *uhost); +static void usbh_data_out_transc(usbh_host *uhost); +static void usbh_status_in_transc(usbh_host *uhost); +static void usbh_status_out_transc(usbh_host *uhost); +static uint32_t usbh_request_submit(usb_core_driver *udev, uint8_t pp_num); + +/*! + \brief send the setup packet to the USB device + \param[in] udev: pointer to USB core instance + \param[in] buf: data buffer which will be sent to USB device + \param[in] pp_num: pipe number + \param[out] none + \retval operation status +*/ +usbh_status usbh_ctlsetup_send(usb_core_driver *udev, uint8_t *buf, uint8_t pp_num) +{ + usb_pipe *pp = &udev->host.pipe[pp_num]; + + pp->DPID = PIPE_DPID_SETUP; + pp->xfer_buf = buf; + pp->xfer_len = USB_SETUP_PACKET_LEN; + + return (usbh_status)usbh_request_submit(udev, pp_num); +} + +/*! + \brief send a data packet to the USB device + \param[in] udev: pointer to USB core instance + \param[in] buf: data buffer which will be sent to USB device + \param[in] pp_num: pipe number + \param[in] len: length of the data to be sent + \param[out] none + \retval operation status +*/ +usbh_status usbh_data_send(usb_core_driver *udev, uint8_t *buf, uint8_t pp_num, uint16_t len) +{ + usb_pipe *pp = &udev->host.pipe[pp_num]; + + pp->xfer_buf = buf; + pp->xfer_len = len; + + switch(pp->ep.type) { + case USB_EPTYPE_CTRL: + if(0U == len) { + pp->data_toggle_out = 1U; + } + + pp->DPID = PIPE_DPID[pp->data_toggle_out]; + break; + + case USB_EPTYPE_INTR: + pp->DPID = PIPE_DPID[pp->data_toggle_out]; + + pp->data_toggle_out ^= 1U; + break; + + case USB_EPTYPE_BULK: + pp->DPID = PIPE_DPID[pp->data_toggle_out]; + break; + + case USB_EPTYPE_ISOC: + pp->DPID = PIPE_DPID[0]; + break; + + default: + break; + } + + usbh_request_submit(udev, pp_num); + + return USBH_OK; +} + +/*! + \brief receive a data packet from the USB device + \param[in] udev: pointer to USB core instance + \param[in] buf: data buffer which will be received from USB device + \param[in] pp_num: pipe number + \param[in] len: length of the data to be received + \param[out] none + \retval operation status +*/ +usbh_status usbh_data_recev(usb_core_driver *udev, uint8_t *buf, uint8_t pp_num, uint16_t len) +{ + usb_pipe *pp = &udev->host.pipe[pp_num]; + + pp->xfer_buf = buf; + pp->xfer_len = len; + + switch(pp->ep.type) { + case USB_EPTYPE_CTRL: + pp->DPID = PIPE_DPID[1]; + break; + + case USB_EPTYPE_INTR: + pp->DPID = PIPE_DPID[pp->data_toggle_in]; + + /* toggle DATA PID */ + pp->data_toggle_in ^= 1U; + break; + + case USB_EPTYPE_BULK: + pp->DPID = PIPE_DPID[pp->data_toggle_in]; + break; + + case USB_EPTYPE_ISOC: + pp->DPID = PIPE_DPID[0]; + break; + + default: + break; + } + + usbh_request_submit(udev, pp_num); + + return USBH_OK; +} + +/*! + \brief USB control transfer handler + \param[in] uhost: pointer to USB host + \param[out] none + \retval operation status +*/ +usbh_status usbh_ctl_handler(usbh_host *uhost) +{ + usbh_status status = USBH_BUSY; + + switch(uhost->control.ctl_state) { + case CTL_SETUP: + usbh_setup_transc(uhost); + break; + + case CTL_DATA_IN: + usbh_data_in_transc(uhost); + break; + + case CTL_DATA_OUT: + usbh_data_out_transc(uhost); + break; + + case CTL_STATUS_IN: + usbh_status_in_transc(uhost); + break; + + case CTL_STATUS_OUT: + usbh_status_out_transc(uhost); + break; + + case CTL_FINISH: + uhost->control.ctl_state = CTL_IDLE; + + status = USBH_OK; + break; + + case CTL_ERROR: + if(++uhost->control.error_count <= USBH_MAX_ERROR_COUNT) { + /* do the transmission again, starting from SETUP packet */ + uhost->control.ctl_state = CTL_SETUP; + } else { + status = USBH_FAIL; + } + break; + + default: + break; + } + + return status; +} + +/*! + \brief wait for USB URB(USB request block) state + \param[in] uhost: pointer to USB host + \param[in] pp_num: pipe number + \param[in] wait_time: wait time + \param[out] none + \retval USB URB state +*/ +static usb_urb_state usbh_urb_wait(usbh_host *uhost, uint8_t pp_num, uint32_t wait_time) +{ + uint32_t timeout = 0U; + usb_urb_state urb_status = URB_IDLE; + timeout = uhost ->control.timer; + + while(URB_DONE != (urb_status = usbh_urbstate_get(uhost->data, pp_num))) { + if(URB_NOTREADY == urb_status) { + break; + } else if(URB_STALL == urb_status) { + uhost->control.ctl_state = CTL_SETUP; + break; + } else if(URB_ERROR == urb_status) { + uhost->control.ctl_state = CTL_ERROR; + break; + } else if((wait_time > 0U) && ((uhost->control.timer - timeout) > wait_time)) { + /* timeout for in transfer */ + uhost->control.ctl_state = CTL_ERROR; + break; + } else { + /* no operation, just wait */ + } + } + + return urb_status; +} + +/*! + \brief USB setup transaction + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void usbh_setup_transc(usbh_host *uhost) +{ + /* send a SETUP packet */ + usbh_ctlsetup_send(uhost->data, + uhost->control.setup.data, + uhost->control.pipe_out_num); + + if (URB_DONE == usbh_urb_wait(uhost, uhost->control.pipe_out_num, 0U)) { + uint8_t dir = (uhost->control.setup.req.bmRequestType & USB_TRX_MASK); + + if(uhost->control.setup.req.wLength) { + if(USB_TRX_IN == dir) { + uhost->control.ctl_state = CTL_DATA_IN; + } else { + uhost->control.ctl_state = CTL_DATA_OUT; + } + } else { + if(USB_TRX_IN == dir) { + uhost->control.ctl_state = CTL_STATUS_OUT; + } else { + uhost->control.ctl_state = CTL_STATUS_IN; + } + } + } +} + +/*! + \brief USB data IN transaction + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void usbh_data_in_transc(usbh_host *uhost) +{ + usbh_data_recev(uhost->data, + uhost->control.buf, + uhost->control.pipe_in_num, + uhost->control.ctl_len); + + if(URB_DONE == usbh_urb_wait(uhost, uhost->control.pipe_in_num, DATA_STAGE_TIMEOUT)) { + uhost->control.ctl_state = CTL_STATUS_OUT; + } +} + +/*! + \brief USB data OUT transaction + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void usbh_data_out_transc(usbh_host *uhost) +{ + usbh_pipe_toggle_set(uhost->data, uhost->control.pipe_out_num, 1U); + + usbh_data_send(uhost->data, + uhost->control.buf, + uhost->control.pipe_out_num, + uhost->control.ctl_len); + + if(URB_DONE == usbh_urb_wait(uhost, uhost->control.pipe_out_num, DATA_STAGE_TIMEOUT)) { + uhost->control.ctl_state = CTL_STATUS_IN; + } +} + +/*! + \brief USB status IN transaction + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void usbh_status_in_transc(usbh_host *uhost) +{ + uint8_t pp_num = uhost->control.pipe_in_num; + + usbh_data_recev(uhost->data, NULL, pp_num, 0U); + + if(URB_DONE == usbh_urb_wait(uhost, pp_num, NODATA_STAGE_TIMEOUT)) { + uhost->control.ctl_state = CTL_FINISH; + } +} + +/*! + \brief USB status OUT transaction + \param[in] uhost: pointer to USB host + \param[out] none + \retval none +*/ +static void usbh_status_out_transc(usbh_host *uhost) +{ + uint8_t pp_num = uhost->control.pipe_out_num; + + usbh_data_send(uhost->data, NULL, pp_num, 0U); + + if(URB_DONE == usbh_urb_wait(uhost, pp_num, NODATA_STAGE_TIMEOUT)) { + uhost->control.ctl_state = CTL_FINISH; + } +} + +/*! + \brief prepare a pipe and start a transfer + \param[in] udev: pointer to USB core instance + \param[in] pp_num: pipe number + \param[out] none + \retval operation status +*/ +static uint32_t usbh_request_submit(usb_core_driver *udev, uint8_t pp_num) +{ + udev->host.pipe[pp_num].urb_state = URB_IDLE; + udev->host.pipe[pp_num].xfer_count = 0U; + + if (1U == udev->host.pipe[pp_num].do_ping) { + (void)usb_pipe_ping (udev, (uint8_t)pp_num); + return USB_OK; + } + + return (uint32_t)usb_pipe_xfer (udev, pp_num); +} + diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/cdc/usb_cdc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/cdc/usb_cdc.h new file mode 100644 index 0000000000..e2f4f5a505 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/cdc/usb_cdc.h @@ -0,0 +1,180 @@ +/*! + \file usb_cdc.h + \brief the header file of communication device class standard + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USB_CDC_H +#define __USB_CDC_H + +#include "usb_ch9_std.h" + +/* communications device class code */ +#define USB_CLASS_CDC 0x02U + +/* communications interface class control protocol codes */ +#define USB_CDC_PROTOCOL_NONE 0x00U +#define USB_CDC_PROTOCOL_AT 0x01U +#define USB_CDC_PROTOCOL_VENDOR 0xFFU + +/* data interface class code */ +#define USB_CLASS_DATA 0x0AU + +#define USB_DESCTYPE_CDC_ACM 0x21U +#define USB_DESCTYPE_CS_INTERFACE 0x24U + +#define USB_CDC_ACM_CONFIG_DESC_SIZE 0x43U + +/* class-specific notification codes for pstn subclasses */ +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20U + +/* class-specific request codes */ +#define SEND_ENCAPSULATED_COMMAND 0x00U +#define GET_ENCAPSULATED_RESPONSE 0x01U +#define SET_COMM_FEATURE 0x02U +#define GET_COMM_FEATURE 0x03U +#define CLEAR_COMM_FEATURE 0x04U + +#define SET_AUX_LINE_STATE 0x10U +#define SET_HOOK_STATE 0x11U +#define PULSE_SETUP 0x12U +#define SEND_PULSE 0x13U +#define SET_PULSE_TIME 0x14U +#define RING_AUX_JACK 0x15U + +#define SET_LINE_CODING 0x20U +#define GET_LINE_CODING 0x21U +#define SET_CONTROL_LINE_STATE 0x22U +#define SEND_BREAK 0x23U +#define NO_CMD 0xFFU + +#define SET_RINGER_PARMS 0x30U +#define GET_RINGER_PARMS 0x31U +#define SET_OPERATION_PARMS 0x32U +#define GET_OPERATION_PARMS 0x33U +#define SET_LINE_PARMS 0x34U +#define GET_LINE_PARMS 0x35U +#define DIAL_DIGITS 0x36U +#define SET_UNIT_PARAMETER 0x37U +#define GET_UNIT_PARAMETER 0x38U +#define CLEAR_UNIT_PARAMETER 0x39U +#define GET_PROFILE 0x3AU + +#define SET_ETHERNET_MULTICAST_FILTERS 0x40U +#define SET_ETHERNET_POWER_MANAGEMENT_PATTERN FILTER 0x41U +#define GET_ETHERNET_POWER_MANAGEMENT_PATTERN FILTER 0x42U +#define SET_ETHERNET_PACKET_FILTER 0x43U +#define GET_ETHERNET_STATISTIC 0x44U + +#define SET_ATM_DATA_FORMAT 0x50U +#define GET_ATM_DEVICE_STATISTICS 0x51U +#define SET_ATM_DEFAULT_VC 0x52U +#define GET_ATM_VC_STATISTICS 0x53U + +/* wValue for set control line state */ +#define CDC_ACTIVATE_CARRIER_SIGNAL_RTS 0x0002U +#define CDC_DEACTIVATE_CARRIER_SIGNAL_RTS 0x0000U +#define CDC_ACTIVATE_SIGNAL_DTR 0x0001U +#define CDC_DEACTIVATE_SIGNAL_DTR 0x0000U + +/* CDC subclass code */ +enum usb_cdc_subclass { + USB_CDC_SUBCLASS_RESERVED = 0U, /*!< reserved */ + USB_CDC_SUBCLASS_DLCM, /*!< direct line control mode */ + USB_CDC_SUBCLASS_ACM, /*!< abstract control mode */ + USB_CDC_SUBCLASS_TCM, /*!< telephone control mode */ + USB_CDC_SUBCLASS_MCM, /*!< multichannel control model */ + USB_CDC_SUBCLASS_CCM, /*!< CAPI control model */ + USB_CDC_SUBCLASS_ENCM, /*!< ethernet networking control model */ + USB_CDC_SUBCLASS_ANCM /*!< ATM networking control model */ +}; + +#pragma pack(1) + +/* cdc acm line coding structure */ +typedef struct { + uint32_t dwDTERate; /*!< data terminal rate */ + uint8_t bCharFormat; /*!< stop bits */ + uint8_t bParityType; /*!< parity */ + uint8_t bDataBits; /*!< data bits */ +} acm_line; + +/* notification structure */ +typedef struct { + uint8_t bmRequestType; /*!< type of request */ + uint8_t bNotification; /*!< communication interface class notifications */ + uint16_t wValue; /*!< value of notification */ + uint16_t wIndex; /*!< index of interface */ + uint16_t wLength; /*!< length of notification data */ +} acm_notification; + +typedef struct { + usb_desc_header header; /*!< descriptor header, including type and size. */ + uint8_t bDescriptorSubtype; /*!< bDescriptorSubtype: header function descriptor */ + uint16_t bcdCDC; /*!< bcdCDC: low byte of spec release number (CDC1.10) */ +} usb_desc_header_func; + +typedef struct { + usb_desc_header header; /*!< descriptor header, including type and size. */ + uint8_t bDescriptorSubtype; /*!< bDescriptorSubtype: call management function descriptor */ + uint8_t bmCapabilities; /*!< bmCapabilities: D0 is reset, D1 is ignored */ + uint8_t bDataInterface; /*!< bDataInterface: 1 interface used for call management */ +} usb_desc_call_managment_func; + +typedef struct { + usb_desc_header header; /*!< descriptor header, including type and size. */ + uint8_t bDescriptorSubtype; /*!< bDescriptorSubtype: abstract control management descriptor */ + uint8_t bmCapabilities; /*!< bmCapabilities: D1 */ +} usb_desc_acm_func; + +typedef struct { + usb_desc_header header; /*!< descriptor header, including type and size. */ + uint8_t bDescriptorSubtype; /*!< bDescriptorSubtype: union function descriptor */ + uint8_t bMasterInterface; /*!< bMasterInterface: communication class interface */ + uint8_t bSlaveInterface0; /*!< bSlaveInterface0: data class interface */ +} usb_desc_union_func; + +#pragma pack() + +typedef struct { + usb_desc_config config; + usb_desc_itf cmd_itf; + usb_desc_header_func cdc_header; + usb_desc_call_managment_func cdc_call_managment; + usb_desc_acm_func cdc_acm; + usb_desc_union_func cdc_union; + usb_desc_ep cdc_cmd_endpoint; + usb_desc_itf cdc_data_interface; + usb_desc_ep cdc_out_endpoint; + usb_desc_ep cdc_in_endpoint; +} usb_cdc_desc_config_set; + +#endif /* __USB_CDC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/hid/usb_hid.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/hid/usb_hid.h new file mode 100644 index 0000000000..17c025c93c --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/hid/usb_hid.h @@ -0,0 +1,83 @@ +/*! + \file usb_hid.h + \brief definitions for the USB HID class + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USB_HID_H +#define __USB_HID_H + +#include "usb_ch9_std.h" + +#define USB_HID_CLASS 0x03U + +#define USB_DESCTYPE_HID 0x21U +#define USB_DESCTYPE_REPORT 0x22U + +/* HID subclass code */ +#define USB_HID_SUBCLASS_BOOT_ITF 0x01U + +/* HID protocol codes */ +#define USB_HID_PROTOCOL_KEYBOARD 0x01U +#define USB_HID_PROTOCOL_MOUSE 0x02U + +#define GET_REPORT 0x01U +#define GET_IDLE 0x02U +#define GET_PROTOCOL 0x03U +#define SET_REPORT 0x09U +#define SET_IDLE 0x0AU +#define SET_PROTOCOL 0x0BU + +#pragma pack(1) + +typedef struct +{ + usb_desc_header header; /*!< regular descriptor header containing the descriptor's type and length */ + + uint16_t bcdHID; /*!< BCD encoded version that the HID descriptor and device complies to */ + uint8_t bCountryCode; /*!< country code of the localized device, or zero if universal */ + uint8_t bNumDescriptors; /*!< total number of HID report descriptors for the interface */ + uint8_t bDescriptorType; /*!< type of HID report */ + uint16_t wDescriptorLength; /*!< length of the associated HID report descriptor, in bytes */ +} usb_desc_hid; + +#pragma pack() + +typedef struct +{ + usb_desc_config config; + usb_desc_itf hid_itf; + usb_desc_hid hid_vendor; + usb_desc_ep hid_epin; + usb_desc_ep hid_epout; +}usb_hid_desc_config_set; + +#endif /* __USB_HID_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_bbb.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_bbb.h new file mode 100644 index 0000000000..78ca6b8e05 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_bbb.h @@ -0,0 +1,69 @@ +/*! + \file msc_bbb.h + \brief definitions for the USB MSC BBB(bulk/bulk/bulk) protocol + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __MSC_BBB_H +#define __MSC_BBB_H + +#include "usb_ch9_std.h" + +#define BBB_CBW_SIGNATURE 0x43425355U +#define BBB_CSW_SIGNATURE 0x53425355U +#define BBB_CBW_LENGTH 31U +#define BBB_CSW_LENGTH 13U + +typedef struct { + uint32_t dCBWSignature; + uint32_t dCBWTag; + uint32_t dCBWDataTransferLength; + uint8_t bmCBWFlags; + uint8_t bCBWLUN; + uint8_t bCBWCBLength; + uint8_t CBWCB[16]; +}msc_bbb_cbw; + +typedef struct { + uint32_t dCSWSignature; + uint32_t dCSWTag; + uint32_t dCSWDataResidue; + uint8_t bCSWStatus; +}msc_bbb_csw; + +/* CSW command status */ +enum msc_csw_status { + CSW_CMD_PASSED = 0, + CSW_CMD_FAILED, + CSW_PHASE_ERROR +}; + +#endif /* __MSC_BBB_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_scsi.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_scsi.h new file mode 100644 index 0000000000..6a23aeac2b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/msc_scsi.h @@ -0,0 +1,117 @@ +/*! + \file msc_scsi.h + \brief definitions for the USB MSC SCSI commands + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __MSC_SCSI_H +#define __MSC_SCSI_H + +#include "usb_ch9_std.h" + +/* SCSI commands */ +#define SCSI_FORMAT_UNIT 0x04U +#define SCSI_INQUIRY 0x12U +#define SCSI_MODE_SELECT6 0x15U +#define SCSI_MODE_SELECT10 0x55U +#define SCSI_MODE_SENSE6 0x1AU +#define SCSI_READ_TOC_DATA 0x43U +#define SCSI_MODE_SENSE10 0x5AU +#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1EU +#define SCSI_READ6 0x08U +#define SCSI_READ10 0x28U +#define SCSI_READ12 0xA8U +#define SCSI_READ16 0x88U + +#define SCSI_READ_CAPACITY10 0x25U +#define SCSI_READ_CAPACITY16 0x9EU + +#define SCSI_REQUEST_SENSE 0x03U +#define SCSI_START_STOP_UNIT 0x1BU +#define SCSI_TEST_UNIT_READY 0x00U +#define SCSI_WRITE6 0x0AU +#define SCSI_WRITE10 0x2AU +#define SCSI_WRITE12 0xAAU +#define SCSI_WRITE16 0x8AU + +#define SCSI_VERIFY10 0x2FU +#define SCSI_VERIFY12 0xAFU +#define SCSI_VERIFY16 0x8FU + +#define SCSI_SEND_DIAGNOSTIC 0x1DU +#define SCSI_READ_FORMAT_CAPACITIES 0x23U + +#define INVALID_CDB 0x20U +#define INVALID_FIELED_IN_COMMAND 0x24U +#define PARAMETER_LIST_LENGTH_ERROR 0x1AU +#define INVALID_FIELD_IN_PARAMETER_LIST 0x26U +#define ADDRESS_OUT_OF_RANGE 0x21U +#define MEDIUM_NOT_PRESENT 0x3AU +#define MEDIUM_HAVE_CHANGED 0x28U +#define WRITE_PROTECTED 0x27U +#define UNRECOVERED_READ_ERROR 0x11U +#define WRITE_FAULT 0x03U + +#define READ_FORMAT_CAPACITY_DATA_LEN 0x0CU +#define READ_CAPACITY10_DATA_LEN 0x08U +#define MODE_SENSE10_DATA_LEN 0x08U +#define MODE_SENSE6_DATA_LEN 0x04U +#define READ_TOC_CMD_LEN 0x14U +#define REQUEST_SENSE_DATA_LEN 0x12U +#define STANDARD_INQUIRY_DATA_LEN 0x24U +#define BLKVFY 0x04U + +enum sense_state { + NO_SENSE = 0U, + RECOVERED_ERROR, + NOT_READY, + MEDIUM_ERROR, + HARDWARE_ERROR, + ILLEGAL_REQUEST, + UNIT_ATTENTION, + DATA_PROTECT, + BLANK_CHECK, + VENDOR_SPECIFIC, + COPY_ABORTED, + ABORTED_COMMAND, + RESERVED, + VOLUME_OVERFLOW, + MISCOMPARE +}; + +typedef struct { + uint8_t SenseKey; + uint32_t Information; + uint8_t ASC; + uint8_t ASCQ; +} msc_scsi_sense; + +#endif /* __MSC_SCSI_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/usb_msc.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/usb_msc.h new file mode 100644 index 0000000000..e13955d44b --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/class/msc/usb_msc.h @@ -0,0 +1,68 @@ +/*! + \file usb_msc.h + \brief definitions for the USB MSC class + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USB_MSC_H +#define __USB_MSC_H + +#include "usb_ch9_std.h" + +/* mass storage device class code */ +#define USB_CLASS_MSC 0x08U + +/* mass storage subclass code */ +#define USB_MSC_SUBCLASS_RBC 0x01U +#define USB_MSC_SUBCLASS_ATAPI 0x02U +#define USB_MSC_SUBCLASS_UFI 0x04U +#define USB_MSC_SUBCLASS_SCSI 0x06U +#define USB_MSC_SUBCLASS_LOCKABLE 0x07U +#define USB_MSC_SUBCLASS_IEEE1667 0x08U + +/* mass storage interface class control protocol codes */ +#define USB_MSC_PROTOCOL_CBI 0x00U +#define USB_MSC_PROTOCOL_CBI_ALT 0x01U +#define USB_MSC_PROTOCOL_BBB 0x50U + +/* mass storage request codes */ +#define USB_MSC_REQ_CODES_ADSC 0x00U +#define USB_MSC_REQ_CODES_GET 0xFCU +#define USB_MSC_REQ_CODES_PUT 0xFDU +#define USB_MSC_REQ_CODES_GML 0xFEU +#define USB_MSC_REQ_CODES_BOMSR 0xFFU + +#define BBB_GET_MAX_LUN 0xFEU +#define BBB_RESET 0xFFU + +#define SCSI_CMD_LENGTH 16U + +#endif /* __USB_MSC_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/common/usb_ch9_std.h b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/common/usb_ch9_std.h new file mode 100644 index 0000000000..d947141200 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/GD32H7xx_usbhs_library/ustd/common/usb_ch9_std.h @@ -0,0 +1,243 @@ +/*! + \file usb_ch9_std.h + \brief USB 2.0 standard defines + + \version 2024-01-05, V1.2.0, firmware for GD32H7xx +*/ + +/* + Copyright (c) 2024, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef __USB_CH9_STD_H +#define __USB_CH9_STD_H + +#include "usb_conf.h" + +#define USB_DEV_QUALIFIER_DESC_LEN 0x0AU /*!< USB device qualifier descriptor length */ +#define USB_DEV_DESC_LEN 0x12U /*!< USB device descriptor length */ +#define USB_CFG_DESC_LEN 0x09U /*!< USB configuration descriptor length */ +#define USB_ITF_DESC_LEN 0x09U /*!< USB interface descriptor length */ +#define USB_EP_DESC_LEN 0x07U /*!< USB endpoint descriptor length */ +#define USB_IAD_DESC_LEN 0x08U /*!< USB IAD descriptor length */ +#define USB_OTG_DESC_LEN 0x03U /*!< USB device OTG descriptor length */ + +#define USB_SETUP_PACKET_LEN 0x08U /*!< USB setup packet length */ + +/* bit 7 of bmRequestType: data phase transfer direction */ +#define USB_TRX_MASK 0x80U /*!< USB transfer direction mask */ +#define USB_TRX_OUT 0x00U /*!< USB transfer OUT direction */ +#define USB_TRX_IN 0x80U /*!< USB transfer IN direction */ + +/* bit 6..5 of bmRequestType: request type */ +#define USB_REQTYPE_STRD 0x00U /*!< USB standard request */ +#define USB_REQTYPE_CLASS 0x20U /*!< USB class request */ +#define USB_REQTYPE_VENDOR 0x40U /*!< USB vendor request */ +#define USB_REQTYPE_MASK 0x60U /*!< USB request mask */ + +#define USBD_BUS_POWERED 0x00U /*!< USB bus power supply */ +#define USBD_SELF_POWERED 0x01U /*!< USB self power supply */ + +#define USB_STATUS_REMOTE_WAKEUP 2U /*!< USB is in remote wakeup status */ +#define USB_STATUS_SELF_POWERED 1U /*!< USB is in self powered status */ + +/* bit 4..0 of bmRequestType: recipient type */ +enum _usb_recp_type { + USB_RECPTYPE_DEV = 0x0U, /*!< USB device request type */ + USB_RECPTYPE_ITF = 0x1U, /*!< USB interface request type */ + USB_RECPTYPE_EP = 0x2U, /*!< USB endpoint request type */ + USB_RECPTYPE_MASK = 0x3U /*!< USB request type mask */ +}; + +/* bRequest value */ +enum _usb_request { + USB_GET_STATUS = 0x0U, /*!< USB get status request */ + USB_CLEAR_FEATURE = 0x1U, /*!< USB clear feature request */ + USB_RESERVED2 = 0x2U, + USB_SET_FEATURE = 0x3U, /*!< USB set feature request */ + USB_RESERVED4 = 0x4U, + USB_SET_ADDRESS = 0x5U, /*!< USB set address request */ + USB_GET_DESCRIPTOR = 0x6U, /*!< USB get descriptor request */ + USB_SET_DESCRIPTOR = 0x7U, /*!< USB set descriptor request */ + USB_GET_CONFIGURATION = 0x8U, /*!< USB get configuration request */ + USB_SET_CONFIGURATION = 0x9U, /*!< USB set configuration request */ + USB_GET_INTERFACE = 0xAU, /*!< USB get interface request */ + USB_SET_INTERFACE = 0xBU, /*!< USB set interface request */ + USB_SYNCH_FRAME = 0xCU /*!< USB synchronize frame request */ +}; + +/* descriptor types of USB specifications */ +enum _usb_desctype { + USB_DESCTYPE_DEV = 0x1U, /*!< USB device descriptor type */ + USB_DESCTYPE_CONFIG = 0x2U, /*!< USB configuration descriptor type */ + USB_DESCTYPE_STR = 0x3U, /*!< USB string descriptor type */ + USB_DESCTYPE_ITF = 0x4U, /*!< USB interface descriptor type */ + USB_DESCTYPE_EP = 0x5U, /*!< USB endpoint descriptor type */ + USB_DESCTYPE_DEV_QUALIFIER = 0x6U, /*!< USB device qualifier descriptor type */ + USB_DESCTYPE_OTHER_SPD_CONFIG = 0x7U, /*!< USB other speed configuration descriptor type */ + USB_DESCTYPE_ITF_POWER = 0x8U, /*!< USB interface power descriptor type */ + USB_DESCTYPE_IAD = 0xBU, /*!< USB interface association descriptor type */ + USB_DESCTYPE_BOS = 0xFU /*!< USB BOS descriptor type */ +}; + +/* USB Endpoint Descriptor bmAttributes bit definitions */ +/* bits 1..0 : transfer type */ +enum _usbx_type { + USB_EP_ATTR_CTL = 0x0U, /*!< USB control transfer type */ + USB_EP_ATTR_ISO = 0x1U, /*!< USB isochronous transfer type */ + USB_EP_ATTR_BULK = 0x2U, /*!< USB bulk transfer type */ + USB_EP_ATTR_INT = 0x3U /*!< USB interrupt transfer type */ +}; + +/* bits 3..2 : Sync type (only if ISOCHRONOUS) */ +#define USB_EP_ATTR_NOSYNC 0x00U /*!< no synchronization */ +#define USB_EP_ATTR_ASYNC 0x04U /*!< asynchronous */ +#define USB_EP_ATTR_ADAPTIVE 0x08U /*!< adaptive */ +#define USB_EP_ATTR_SYNC 0x0CU /*!< synchronous */ +#define USB_EP_ATTR_SYNCTYPE 0x0CU /*!< synchronous type */ + +/* bits 5..4 : usage type (only if ISOCHRONOUS) */ +#define USB_EP_ATTR_DATA 0x00U /*!< data endpoint */ +#define USB_EP_ATTR_FEEDBACK 0x10U /*!< feedback endpoint */ +#define USB_EP_ATTR_IMPLICIT_FEEDBACK_DATA 0x20U /*!< implicit feedback data endpoint */ +#define USB_EP_ATTR_USAGETYPE 0x30U /*!< usage type */ + +#define FEATURE_SELECTOR_EP 0x00U /*!< USB endpoint feature selector */ +#define FEATURE_SELECTOR_DEV 0x01U /*!< USB device feature selector */ +#define FEATURE_SELECTOR_REMOTEWAKEUP 0x01U /*!< USB feature selector remote wakeup */ + +#define BYTE_SWAP(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (uint16_t)(((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) + +#define BYTE_LOW(x) ((uint8_t)((x) & 0x00FFU)) +#define BYTE_HIGH(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) + +#define USB_MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#define USB_DEFAULT_CONFIG 0U + +/* USB classes */ +#define USB_CLASS_HID 0x03U /*!< USB HID class */ +#define USB_CLASS_MSC 0x08U /*!< USB MSC class */ + +/* use the following values when USB host need to get descriptor */ +#define USBH_DESC(x) (((x)<< 8U) & 0xFF00U) + +/* as per USB specs 9.2.6.4 :standard request with data request timeout: 5sec + standard request with no data stage timeout : 50ms */ +#define DATA_STAGE_TIMEOUT 5000U /*!< USB data stage timeout*/ +#define NODATA_STAGE_TIMEOUT 50U /*!< USB no data stage timeout*/ + +#pragma pack(1) + +/* USB standard device request structure */ +typedef struct _usb_req { + uint8_t bmRequestType; /*!< type of request */ + uint8_t bRequest; /*!< request of setup packet */ + uint16_t wValue; /*!< value of setup packet */ + uint16_t wIndex; /*!< index of setup packet */ + uint16_t wLength; /*!< length of setup packet */ +} usb_req; + +/* USB setup packet define */ +typedef union _usb_setup { + uint8_t data[8]; + + usb_req req; +} usb_setup; + +/* USB descriptor defines */ + +typedef struct _usb_desc_header { + uint8_t bLength; /*!< size of the descriptor */ + uint8_t bDescriptorType; /*!< type of the descriptor */ +} usb_desc_header; + +typedef struct _usb_desc_dev { + usb_desc_header header; /*!< descriptor header, including type and size */ + + uint16_t bcdUSB; /*!< BCD of the supported USB specification */ + uint8_t bDeviceClass; /*!< USB device class */ + uint8_t bDeviceSubClass; /*!< USB device subclass */ + uint8_t bDeviceProtocol; /*!< USB device protocol */ + uint8_t bMaxPacketSize0; /*!< size of the control (address 0) endpoint's bank in bytes */ + uint16_t idVendor; /*!< vendor ID for the USB product */ + uint16_t idProduct; /*!< unique product ID for the USB product */ + uint16_t bcdDevice; /*!< product release (version) number */ + uint8_t iManufacturer; /*!< string index for the manufacturer's name */ + uint8_t iProduct; /*!< string index for the product name/details */ + uint8_t iSerialNumber; /*!< string index for the product's globally unique hexadecimal serial number */ + uint8_t bNumberConfigurations; /*!< total number of configurations supported by the device */ +} usb_desc_dev; + +typedef struct _usb_desc_config { + usb_desc_header header; /*!< descriptor header, including type and size */ + + uint16_t wTotalLength; /*!< size of the configuration descriptor header,and all sub descriptors inside the configuration */ + uint8_t bNumInterfaces; /*!< total number of interfaces in the configuration */ + uint8_t bConfigurationValue; /*!< configuration index of the current configuration */ + uint8_t iConfiguration; /*!< index of a string descriptor describing the configuration */ + uint8_t bmAttributes; /*!< configuration attributes */ + uint8_t bMaxPower; /*!< maximum power consumption of the device while in the current configuration */ +} usb_desc_config; + +typedef struct _usb_desc_itf { + usb_desc_header header; /*!< descriptor header, including type and size */ + + uint8_t bInterfaceNumber; /*!< index of the interface in the current configuration */ + uint8_t bAlternateSetting; /*!< alternate setting for the interface number */ + uint8_t bNumEndpoints; /*!< total number of endpoints in the interface */ + uint8_t bInterfaceClass; /*!< interface class ID */ + uint8_t bInterfaceSubClass; /*!< interface subclass ID */ + uint8_t bInterfaceProtocol; /*!< interface protocol ID */ + uint8_t iInterface; /*!< index of the string descriptor describing the interface */ +} usb_desc_itf; + +typedef struct _usb_desc_ep { + usb_desc_header header; /*!< descriptor header, including type and size. */ + + uint8_t bEndpointAddress; /*!< logical address of the endpoint */ + uint8_t bmAttributes; /*!< endpoint attributes */ + uint16_t wMaxPacketSize; /*!< size of the endpoint bank, in bytes */ + uint8_t bInterval; /*!< polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type */ +} usb_desc_ep; + +typedef struct _usb_desc_LANGID { + usb_desc_header header; /*!< descriptor header, including type and size. */ + uint16_t wLANGID; /*!< LANGID code */ +} usb_desc_LANGID; + +typedef struct _usb_desc_str { + usb_desc_header header; /*!< descriptor header, including type and size. */ + uint16_t unicode_string[64]; /*!< unicode string data */ +} usb_desc_str; + +#pragma pack() + +/* compute string descriptor length */ +#define USB_STRING_LEN(unicode_chars) (sizeof(usb_desc_header) + ((unicode_chars) << 1U)) + +#endif /* __USB_CH9_STD_H */ diff --git a/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/SConscript b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/SConscript new file mode 100644 index 0000000000..9f10c2a9d7 --- /dev/null +++ b/bsp/gd32/arm/libraries/GD32H7xx_Firmware_Library/SConscript @@ -0,0 +1,69 @@ +import rtconfig +from building import * + +# get current directory +cwd = GetCurrentDir() + +# The set of source files associated with this SConscript file. + +src = Split(''' +CMSIS/GD/GD32H7xx/Source/system_gd32h7xx.c +GD32H7xx_standard_peripheral/Source/gd32h7xx_gpio.c +GD32H7xx_standard_peripheral/Source/gd32h7xx_rcu.c +GD32H7xx_standard_peripheral/Source/gd32h7xx_exti.c +GD32H7xx_standard_peripheral/Source/gd32h7xx_misc.c +GD32H7xx_standard_peripheral/Source/gd32h7xx_syscfg.c +GD32H7xx_standard_peripheral/Source/gd32h7xx_pmu.c +''') + +if GetDepend(['RT_USING_SERIAL']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_usart.c'] + +if GetDepend(['RT_USING_I2C']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_i2c.c'] + +if GetDepend(['RT_USING_SPI']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_spi.c'] + +if GetDepend(['RT_USING_CAN']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_can.c'] + +if GetDepend(['BSP_USING_ETH']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_enet.c'] + +if GetDepend(['RT_USING_ADC']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_adc.c'] + +if GetDepend(['RT_USING_DAC']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_dac.c'] + +if GetDepend(['RT_USING_RTC']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_rtc.c'] + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_pmu.c'] + +if GetDepend(['RT_USING_WDT']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_wwdgt.c'] + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_fwdgt.c'] + +if GetDepend(['RT_USING_SDIO']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_sdio.c'] + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_dma.c'] + +if GetDepend(['BSP_USING_SDRAM']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_fmc.c'] + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_exmc.c'] + +if GetDepend(['BSP_USING_TLI']): + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_tli.c'] + src += ['GD32H7xx_standard_peripheral/Source/gd32h7xx_ipa.c'] + +path = [ + cwd + '/CMSIS/GD/GD32H7xx/Include', + cwd + '/CMSIS', + cwd + '/GD32H7xx_standard_peripheral/Include',] + +CPPDEFINES = ['USE_STDPERIPH_DRIVER'] + +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/gd32/arm/libraries/Kconfig b/bsp/gd32/arm/libraries/Kconfig index 100c320ab1..cb92bb8ddb 100644 --- a/bsp/gd32/arm/libraries/Kconfig +++ b/bsp/gd32/arm/libraries/Kconfig @@ -20,3 +20,8 @@ config SOC_SERIES_GD32F4 bool select ARCH_ARM_CORTEX_M4 select SOC_FAMILY_GD32 + +config SOC_SERIES_GD32H7 + bool + select ARCH_ARM_CORTEX_M7 + select SOC_FAMILY_GD32