From 0da346d568adb5cba19f047c97e996d966bbde78 Mon Sep 17 00:00:00 2001 From: Zheng Wu Date: Thu, 27 Feb 2025 15:08:31 +0000 Subject: [PATCH] support the GD32F415 microcontroller with a polling - only UART driver. --- Ubiquitous/XiZi_IIoT/Makefile | 2 +- Ubiquitous/XiZi_IIoT/arch/arm/Makefile | 5 + .../XiZi_IIoT/arch/arm/cortex-m4/Makefile | 4 + .../arch/arm/cortex-m4/gd32f415/Makefile | 3 + .../arch/arm/cortex-m4/gd32f415/boot.S | 112 + .../arch/arm/cortex-m4/gd32f415/interrupt.c | 75 + .../arm/cortex-m4/gd32f415/interrupt_vector.S | 171 + .../XiZi_IIoT/board/gd32f415rgo6/.defconfig | 275 ++ .../XiZi_IIoT/board/gd32f415rgo6/Kconfig | 44 + .../XiZi_IIoT/board/gd32f415rgo6/Makefile | 5 + .../XiZi_IIoT/board/gd32f415rgo6/README.md | 221 ++ .../XiZi_IIoT/board/gd32f415rgo6/board.c | 78 + .../XiZi_IIoT/board/gd32f415rgo6/board.h | 76 + .../XiZi_IIoT/board/gd32f415rgo6/config.mk | 27 + .../XiZi_IIoT/board/gd32f415rgo6/img/main.png | Bin 0 -> 13668 bytes .../board/gd32f415rgo6/img/menuconfig1.png | Bin 0 -> 90615 bytes .../board/gd32f415rgo6/img/menuconfig2.jpg | Bin 0 -> 28566 bytes .../board/gd32f415rgo6/img/putty.png | Bin 0 -> 99679 bytes .../board/gd32f415rgo6/img/st-link.png | Bin 0 -> 59814 bytes .../img/stm32f407-st-discovery.png | Bin 0 -> 293377 bytes .../board/gd32f415rgo6/img/terminal.png | Bin 0 -> 182459 bytes .../board/gd32f415rgo6/img/vscode.jpg | Bin 0 -> 57472 bytes .../board/gd32f415rgo6/include/core_cm4.h | 1790 +++++++++ .../gd32f415rgo6/include/core_cm4_simd.h | 697 ++++ .../board/gd32f415rgo6/include/core_cmFunc.h | 616 +++ .../board/gd32f415rgo6/include/core_cmInstr.h | 618 +++ .../board/gd32f415rgo6/include/gd32f4xx.h | 368 ++ .../gd32f415rgo6/include/gd32f4xx_libopt.h | 78 + .../gd32f415rgo6/include/system_gd32f4xx.h | 58 + .../XiZi_IIoT/board/gd32f415rgo6/link.lds | 110 + .../board/gd32f415rgo6/link_userspace.lds | 72 + .../gd32f415rgo6/third_party_driver/Kconfig | 8 + .../gd32f415rgo6/third_party_driver/Makefile | 7 + .../third_party_driver/include/connect_uart.h | 51 + .../third_party_driver/include/gd32f4xx_adc.h | 516 +++ .../third_party_driver/include/gd32f4xx_can.h | 750 ++++ .../third_party_driver/include/gd32f4xx_crc.h | 81 + .../third_party_driver/include/gd32f4xx_ctc.h | 185 + .../third_party_driver/include/gd32f4xx_dac.h | 271 ++ .../third_party_driver/include/gd32f4xx_dbg.h | 153 + .../third_party_driver/include/gd32f4xx_dci.h | 239 ++ .../third_party_driver/include/gd32f4xx_dma.h | 428 ++ .../include/gd32f4xx_enet.h | 1681 ++++++++ .../include/gd32f4xx_exmc.h | 814 ++++ .../include/gd32f4xx_exti.h | 274 ++ .../third_party_driver/include/gd32f4xx_fmc.h | 415 ++ .../include/gd32f4xx_fwdgt.h | 114 + .../include/gd32f4xx_gpio.h | 409 ++ .../third_party_driver/include/gd32f4xx_i2c.h | 413 ++ .../third_party_driver/include/gd32f4xx_ipa.h | 381 ++ .../include/gd32f4xx_iref.h | 187 + .../third_party_driver/include/gd32f4xx_it.h | 50 + .../include/gd32f4xx_misc.h | 93 + .../third_party_driver/include/gd32f4xx_pmu.h | 206 + .../third_party_driver/include/gd32f4xx_rcu.h | 1183 ++++++ .../third_party_driver/include/gd32f4xx_rtc.h | 641 +++ .../include/gd32f4xx_sdio.h | 434 ++ .../third_party_driver/include/gd32f4xx_spi.h | 380 ++ .../include/gd32f4xx_syscfg.h | 182 + .../include/gd32f4xx_timer.h | 779 ++++ .../third_party_driver/include/gd32f4xx_tli.h | 373 ++ .../include/gd32f4xx_trng.h | 103 + .../include/gd32f4xx_usart.h | 492 +++ .../include/gd32f4xx_wwdgt.h | 94 + .../third_party_driver/src/Makefile | 3 + .../third_party_driver/src/gd32f4xx_adc.c | 1203 ++++++ .../third_party_driver/src/gd32f4xx_can.c | 1026 +++++ .../third_party_driver/src/gd32f4xx_crc.c | 130 + .../third_party_driver/src/gd32f4xx_ctc.c | 391 ++ .../third_party_driver/src/gd32f4xx_dac.c | 678 ++++ .../third_party_driver/src/gd32f4xx_dbg.c | 183 + .../third_party_driver/src/gd32f4xx_dci.c | 346 ++ .../third_party_driver/src/gd32f4xx_dma.c | 904 +++++ .../third_party_driver/src/gd32f4xx_enet.c | 3510 +++++++++++++++++ .../third_party_driver/src/gd32f4xx_exmc.c | 1252 ++++++ .../third_party_driver/src/gd32f4xx_exti.c | 253 ++ .../third_party_driver/src/gd32f4xx_fmc.c | 1048 +++++ .../third_party_driver/src/gd32f4xx_fwdgt.c | 218 + .../third_party_driver/src/gd32f4xx_gpio.c | 434 ++ .../third_party_driver/src/gd32f4xx_i2c.c | 840 ++++ .../third_party_driver/src/gd32f4xx_ipa.c | 639 +++ .../third_party_driver/src/gd32f4xx_iref.c | 127 + .../third_party_driver/src/gd32f4xx_it.c | 81 + .../third_party_driver/src/gd32f4xx_misc.c | 175 + .../third_party_driver/src/gd32f4xx_pmu.c | 412 ++ .../third_party_driver/src/gd32f4xx_rcu.c | 1332 +++++++ .../third_party_driver/src/gd32f4xx_rtc.c | 1294 ++++++ .../third_party_driver/src/gd32f4xx_sdio.c | 804 ++++ .../third_party_driver/src/gd32f4xx_spi.c | 893 +++++ .../third_party_driver/src/gd32f4xx_syscfg.c | 205 + .../third_party_driver/src/gd32f4xx_timer.c | 2064 ++++++++++ .../third_party_driver/src/gd32f4xx_tli.c | 598 +++ .../third_party_driver/src/gd32f4xx_trng.c | 156 + .../third_party_driver/src/gd32f4xx_usart.c | 981 +++++ .../third_party_driver/src/gd32f4xx_wwdgt.c | 129 + .../third_party_driver/src/system_gd32f4xx.c | 1153 ++++++ .../third_party_driver/uart/Kconfig | 15 + .../third_party_driver/uart/Makefile | 3 + .../third_party_driver/uart/connect_uart.c | 271 ++ Ubiquitous/XiZi_IIoT/path_kernel.mk | 10 + 100 files changed, 41652 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/boot.S create mode 100644 Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt.c create mode 100644 Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt_vector.S create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/.defconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/README.md create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/config.mk create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/main.png create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/menuconfig1.png create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/menuconfig2.jpg create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/putty.png create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/st-link.png create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/stm32f407-st-discovery.png create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/terminal.png create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/vscode.jpg create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cm4.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cm4_simd.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmFunc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmInstr.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx_libopt.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/system_gd32f4xx.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link.lds create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link_userspace.lds create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/connect_uart.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_adc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_can.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_crc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ctc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dac.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dbg.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dci.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dma.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_enet.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exmc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exti.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fmc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fwdgt.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_gpio.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_i2c.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ipa.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_iref.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_it.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_misc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_pmu.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rcu.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rtc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_sdio.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_spi.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_syscfg.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_timer.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_tli.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_trng.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_usart.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_wwdgt.h create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_adc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_can.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_crc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ctc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dac.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dbg.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dci.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dma.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_enet.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exmc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exti.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fmc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fwdgt.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_gpio.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_i2c.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ipa.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_iref.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_it.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_misc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_pmu.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rcu.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rtc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_sdio.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_spi.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_syscfg.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_timer.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_tli.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_trng.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_usart.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_wwdgt.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/system_gd32f4xx.c create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/connect_uart.c diff --git a/Ubiquitous/XiZi_IIoT/Makefile b/Ubiquitous/XiZi_IIoT/Makefile index c20451f80..f2d8f8dfb 100755 --- a/Ubiquitous/XiZi_IIoT/Makefile +++ b/Ubiquitous/XiZi_IIoT/Makefile @@ -6,7 +6,7 @@ MAKEFLAGS += --no-print-directory riscv_support := kd233 maix-go hifive1-rev-B gapuino gd32vf103-rvstar rv32m1-vega aiit-riscv64-board xidatong-riscv64 edu-riscv64 ch32v307vct6 ch32v208rbt6 ch569w -arm_support += stm32f407-st-discovery stm32f407zgt6 stm32f103-nano nuvoton-m2354 ok1052-c imxrt1176-sbc aiit-arm32-board xidatong-arm32 xiwangtong-arm32 edu-arm32 xishutong-arm32 rzv2l-m33 rzg2ul-m33 imx8mp +arm_support += stm32f407-st-discovery stm32f407zgt6 stm32f103-nano nuvoton-m2354 ok1052-c imxrt1176-sbc aiit-arm32-board xidatong-arm32 xiwangtong-arm32 edu-arm32 xishutong-arm32 rzv2l-m33 rzg2ul-m33 imx8mp gd32f415rgo6 emulator_support += hifive1-emulator k210-emulator cortex-m0-emulator cortex-m3-emulator cortex-m4-emulator cortex-m7-emulator support := $(riscv_support) $(arm_support) $(emulator_support) diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/Makefile b/Ubiquitous/XiZi_IIoT/arch/arm/Makefile index 6211694dd..993fd059b 100644 --- a/Ubiquitous/XiZi_IIoT/arch/arm/Makefile +++ b/Ubiquitous/XiZi_IIoT/arch/arm/Makefile @@ -35,6 +35,11 @@ SRC_DIR := shared SRC_DIR += cortex-m4 endif +ifeq ($(CONFIG_BOARD_GD32F415RG),y) +SRC_DIR := shared +SRC_DIR += cortex-m4 +endif + ifeq ($(CONFIG_BOARD_CORTEX_M7_EVB),y) SRC_DIR := shared SRC_DIR += cortex-m7 diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/Makefile b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/Makefile index de858a0f4..84fcddd7c 100644 --- a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/Makefile +++ b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/Makefile @@ -22,4 +22,8 @@ ifeq ($(CONFIG_BOARD_XISHUTONG_ARM32),y) SRC_DIR += hc32f4a0 endif +ifeq ($(CONFIG_BOARD_GD32F415RG), y) +SRC_DIR += gd32f415 +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/Makefile b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/Makefile new file mode 100644 index 000000000..111e2ee09 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := interrupt.c boot.S interrupt_vector.S + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/boot.S b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/boot.S new file mode 100644 index 000000000..419b6fb47 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/boot.S @@ -0,0 +1,112 @@ +/** + ****************************************************************************** + * @file startup_stm32f407xx.s + * @author MCD Application Team + * @brief STM32F407xx Devices vector table for GCC based toolchains. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2017 STMicroelectronics

+ * + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/** +* @file boot.S +* @brief derived from ST standard peripheral library +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: boot.S +Description: Reset and init function +Others: +History: +1. Date: 2021-04-29 +Author: AIIT XUOS Lab +Modification: +1. take startup_stm32f407xx.s for XiZi kernel +2. gd32f4xx is compatible with stm32f4xx for startup file +*************************************************/ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.word _sidata +.word _sdata +.word _edata +.word __bss_start +.word __bss_end + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =__stack_tp + movs r1, #0 + +/* Copy the data segment initializers from flash to SRAM */ +DataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcs DataInitEnd + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + b DataInit + +DataInitEnd: + ldr r2, =__bss_start + +/* Zero fill the bss segment. */ +BSSInit: + ldr r3, = __bss_end + cmp r2, r3 + bcs BSSInitEnd + movs r3, #0 + str r3, [r2], #4 + b BSSInit + +BSSInitEnd: + bl SystemInit + + bl entry + bx lr +.size Reset_Handler, .-Reset_Handler \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt.c b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt.c new file mode 100644 index 000000000..e4e6786d4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt.c @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file interrupt.c +* @brief support arm cortex-m4 interrupt function +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-29 +*/ + +#include +#include +#include +#include "gd32f4xx_exti.h" + + +x_base __attribute__((naked)) DisableLocalInterrupt() +{ + asm volatile ("MRS r0, PRIMASK"); + asm volatile ("CPSID I"); + asm volatile ("BX LR "); +} + +void __attribute__((naked)) EnableLocalInterrupt(x_base level) +{ + asm volatile ("MSR PRIMASK, r0"); + asm volatile ("BX LR"); +} + +int32 ArchEnableHwIrq(uint32 irq_num) { + if (irq_num >= EXTI_0 && irq_num <= EXTI_22) { + exti_interrupt_enable((exti_line_enum)irq_num); + } + return EOK; +} + +int32 ArchDisableHwIrq(uint32 irq_num) { + if (irq_num >= EXTI_0 && irq_num <= EXTI_22) { + exti_interrupt_disable((exti_line_enum)irq_num); + } + return EOK; +} + +extern void KTaskOsAssignAfterIrq(void *context); + +void IsrEntry() +{ + uint32 ipsr; + + __asm__ volatile("MRS %0, IPSR" : "=r"(ipsr)); + + isrManager.done->incCounter(); + isrManager.done->handleIrq(ipsr); + KTaskOsAssignAfterIrq(NONE); + isrManager.done->decCounter(); + +} + +uintptr_t *Svcall(unsigned int ipsr , uintptr_t* contex ) +{ +#ifdef TASK_ISOLATION + _svcall(contex); +#endif + return contex; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt_vector.S b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt_vector.S new file mode 100644 index 000000000..8e02008e9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m4/gd32f415/interrupt_vector.S @@ -0,0 +1,171 @@ +/** + ****************************************************************************** + * @file startup_stm32f407xx.s + * @author MCD Application Team + * @brief STM32F407xx Devices vector table for GCC based toolchains. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2017 STMicroelectronics

+ * + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/** +* @file interrupt_vector.S +* @brief derived from ST standard peripheral library +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: interrupt_vector.S +Description: Interrupt Vectors +Others: +History: +1. Date: 2021-04-29 +Author: AIIT XUOS Lab +Modification: +1. take startup_stm32f407xx.s for XiZi kernel +*************************************************/ + +.globl InterruptVectors + +/****************************************************************************** +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type InterruptVectors, %object + .size InterruptVectors, .-InterruptVectors + +InterruptVectors: + .word __stack_end__ + + .word Reset_Handler + .word NMI_Handler + .word HardFaultHandler + .word MemFaultHandler + .word BusFault_Handler + .word UsageFault_Handler + .word IsrEntry + .word IsrEntry + .word IsrEntry + .word IsrEntry + .word SVC_Handler /* SVC */ + .word IsrEntry /* DebugMon */ + .word IsrEntry + .word PendSV_Handler + .word SysTick_Handler /* SysTick */ + + .word IsrEntry /* Window WatchDog */ + .word IsrEntry /* PVD through EXTI Line detection */ + .word IsrEntry /* Tamper and TimeStamps through the EXTI line */ + .word IsrEntry /* RTC Wakeup through the EXTI line */ + .word IsrEntry /* FLASH */ + .word IsrEntry /* RCC */ + .word IsrEntry /* EXTI Line0 */ + .word IsrEntry /* EXTI Line1 */ + .word IsrEntry /* EXTI Line2 */ + .word IsrEntry /* EXTI Line3 */ + .word IsrEntry /* EXTI Line4 */ + .word IsrEntry /* DMA1 Stream 0 */ + .word IsrEntry /* DMA1 Stream 1 */ + .word IsrEntry /* DMA1 Stream 2 */ + .word IsrEntry /* DMA1 Stream 3 */ + .word IsrEntry /* DMA1 Stream 4 */ + .word IsrEntry /* DMA1 Stream 5 */ + .word IsrEntry /* DMA1 Stream 6 */ + .word IsrEntry /* ADC1, ADC2 and ADC3s */ + .word IsrEntry /* CAN1 TX */ + .word IsrEntry /* CAN1 RX0 */ + .word IsrEntry /* CAN1 RX1 */ + .word IsrEntry /* CAN1 SCE */ + .word IsrEntry /* External Line[9:5]s */ + .word IsrEntry /* TIM1 Break and TIM9 */ + .word IsrEntry /* TIM1 Update and TIM10 */ + .word IsrEntry /* TIM1 Trigger and Commutation and TIM11 */ + .word IsrEntry /* TIM1 Capture Compare */ + .word IsrEntry /* TIM2 */ + .word IsrEntry /* TIM3 */ + .word IsrEntry /* TIM4 */ + .word IsrEntry /* I2C1 Event */ + .word IsrEntry /* I2C1 Error */ + .word IsrEntry /* I2C2 Event */ + .word IsrEntry /* I2C2 Error */ + .word IsrEntry /* SPI1 */ + .word IsrEntry /* SPI2 */ + .word IsrEntry /* USART1 */ + .word IsrEntry /* USART2 */ + .word IsrEntry /* USART3 */ + .word IsrEntry /* External Line[15:10]s */ + .word IsrEntry /* RTC Alarm (A and B) through EXTI Line */ + .word IsrEntry /* USB OTG FS Wakeup through EXTI line */ + .word IsrEntry /* TIM8 Break and TIM12 */ + .word IsrEntry /* TIM8 Update and TIM13 */ + .word IsrEntry /* TIM8 Trigger and Commutation and TIM14 */ + .word IsrEntry /* TIM8 Capture Compare */ + .word IsrEntry /* DMA1 Stream7 */ + .word IsrEntry /* FSMC */ + .word IsrEntry /* SDIO */ + .word IsrEntry /* TIM5 */ + .word IsrEntry /* SPI3 */ + .word IsrEntry /* UART4 */ + .word IsrEntry /* UART5 */ + .word IsrEntry /* TIM6 and DAC1&2 underrun errors */ + .word IsrEntry /* TIM7 */ + .word IsrEntry /* DMA2 Stream 0 */ + .word IsrEntry /* DMA2 Stream 1 */ + .word IsrEntry /* DMA2 Stream 2 */ + .word IsrEntry /* DMA2 Stream 3 */ + .word IsrEntry /* DMA2 Stream 4 */ + .word IsrEntry /* Ethernet */ + .word IsrEntry /* Ethernet Wakeup through EXTI line */ + .word IsrEntry /* CAN2 TX */ + .word IsrEntry /* CAN2 RX0 */ + .word IsrEntry /* CAN2 RX1 */ + .word IsrEntry /* CAN2 SCE */ + .word IsrEntry /* USB OTG FS */ + .word IsrEntry /* DMA2 Stream 5 */ + .word IsrEntry /* DMA2 Stream 6 */ + .word IsrEntry /* DMA2 Stream 7 */ + .word IsrEntry /* USART6 */ + .word IsrEntry /* I2C3 event */ + .word IsrEntry /* I2C3 error */ + .word IsrEntry /* USB OTG HS End Point 1 Out */ + .word IsrEntry /* USB OTG HS End Point 1 In */ + .word IsrEntry /* USB OTG HS Wakeup through EXTI */ + .word IsrEntry /* USB OTG HS */ + .word IsrEntry /* DCMI */ + .word IsrEntry /* CRYP crypto */ + .word IsrEntry /* Hash and Rng */ + .word IsrEntry /* FPU */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/.defconfig b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/.defconfig new file mode 100644 index 000000000..16066cb19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/.defconfig @@ -0,0 +1,275 @@ +# +# XiZi_IIoT Project Default Configuration +# +CONFIG_BOARD_GD32F415RG=y +CONFIG_ARCH_ARM=y + +# +# gd32f415rgo6 feature +# +# CONFIG_BSP_USING_UART is not set + +# +# config default board resources +# + +# +# config board app name +# +CONFIG_BOARD_APP_NAME="/XiUOS_gd32f415rgo6_app.bin" + +# +# config board service table +# +CONFIG_SERVICE_TABLE_ADDRESS=0x20000000 + +# +# Hardware feature +# +CONFIG_RESOURCES_SERIAL=y +# CONFIG_SERIAL_USING_DMA is not set +CONFIG_SERIAL_RB_BUFSZ=128 + +# +# Kernel feature +# + +# +# separate compile(choose none for compile once) +# +# CONFIG_SEPARATE_COMPILE is not set +# CONFIG_COMPILER_APP is not set +# CONFIG_APP_STARTUP_FROM_SDCARD is not set +CONFIG_APP_STARTUP_FROM_FLASH=y +# CONFIG_COMPILER_KERNEL is not set + +# +# Memory Management +# +# CONFIG_KERNEL_MEMBLOCK is not set +CONFIG_MEM_ALIGN_SIZE=8 +# CONFIG_MEM_EXTERN_SRAM is not set +CONFIG_MM_PAGE_SIZE=4096 + +# +# Using small memory allocator +# +CONFIG_KERNEL_SMALL_MEM_ALLOC=y +CONFIG_SMALL_NUMBER_32B=64 +CONFIG_SMALL_NUMBER_64B=32 + +# +# Task feature +# +CONFIG_USER_APPLICATION=y +# CONFIG_TASK_ISOLATION is not set +# CONFIG_KERNEL_CAPABILITY is not set + +# +# Inter-Task communication +# +CONFIG_KERNEL_SEMAPHORE=y +CONFIG_KERNEL_MUTEX=y +CONFIG_KERNEL_EVENT=y +CONFIG_KERNEL_MESSAGEQUEUE=y +CONFIG_KERNEL_SOFTTIMER=y +CONFIG_SCHED_POLICY_RR_REMAINSLICE=y +# CONFIG_SCHED_POLICY_RR is not set +# CONFIG_SCHED_POLICY_FIFO is not set +# CONFIG_KTASK_PRIORITY_8 is not set +CONFIG_KTASK_PRIORITY_32=y +# CONFIG_KTASK_PRIORITY_256 is not set +CONFIG_KTASK_PRIORITY_MAX=32 +CONFIG_TICK_PER_SECOND=100 +CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y +CONFIG_IDLE_KTASK_STACKSIZE=1024 +CONFIG_ZOMBIE_KTASK_STACKSIZE=2048 + +# +# Kernel Console +# +# CONFIG_KERNEL_CONSOLE is not set + +# +# Kernel Hook +# +# CONFIG_KERNEL_HOOK is not set + +# +# Command shell +# +# CONFIG_TOOL_SHELL is not set + +# +# Kernel data structure Manage +# +CONFIG_KERNEL_QUEUEMANAGE=y +CONFIG_KERNEL_WORKQUEUE=y +CONFIG_WORKQUEUE_KTASK_STACKSIZE=2048 +CONFIG_WORKQUEUE_KTASK_PRIORITY=23 +CONFIG_QUEUE_MAX=16 +CONFIG_KERNEL_WAITQUEUE=y +CONFIG_KERNEL_DATAQUEUE=y +# CONFIG_KERNEL_CIRCULAR_AREA is not set +# CONFIG_KERNEL_AVL_TREE is not set + +# +# Kernel components init +# +CONFIG_KERNEL_COMPONENTS_INIT=y +CONFIG_ENV_INIT_KTASK_STACK_SIZE=8192 +CONFIG_KERNEL_USER_MAIN=y +CONFIG_NAME_NUM_MAX=32 +# CONFIG_KERNEL_DEBUG is not set +# CONFIG_ARCH_SMP is not set + +# +# hash table config +# +CONFIG_ID_HTABLE_SIZE=16 +CONFIG_ID_NUM_MAX=128 +# CONFIG_KERNEL_TEST is not set + +# +# Kernel Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set +# CONFIG_LIB_OTHER is not set + +# +# C++ features +# +# CONFIG_LIB_CPLUSPLUS is not set + +# +# File system +# +CONFIG_FS_VFS=y +CONFIG_VFS_USING_WORKDIR=y +CONFIG_FS_VFS_DEVFS=y +CONFIG_FS_VFS_FATFS=y +# CONFIG_FS_CH376 is not set +# CONFIG_FS_LWEXT4 is not set + +# +# Tool feature +# + +# +# OTA function +# +# CONFIG_TOOL_USING_OTA is not set + +# +# APP_Framework +# + +# +# Framework +# +CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y +CONFIG_ADD_XIZI_FEATURES=y +# CONFIG_ADD_NUTTX_FEATURES is not set +# CONFIG_ADD_RTTHREAD_FEATURES is not set +# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set +# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set +# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set +# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set + +# +# Security +# +# CONFIG_CRYPTO is not set +# CONFIG_MBEDTLS is not set + +# +# Applications +# + +# +# config stack size and priority of main task +# +CONFIG_MAIN_KTASK_STACK_SIZE=1024 +CONFIG_MAIN_KTASK_PRIORITY=16 + +# +# test app +# +# CONFIG_USER_TEST is not set + +# +# connection app +# +# CONFIG_APPLICATION_CONNECTION is not set + +# +# control app +# + +# +# knowing app +# +# CONFIG_APPLICATION_KNOWING is not set + +# +# sensor app +# +# CONFIG_APPLICATION_SENSOR is not set +# CONFIG_USING_EMBEDDED_DATABASE_APP is not set +# CONFIG_APP_USING_WEBNET is not set +# CONFIG_APPLICATION_WEBSERVER is not set + +# +# app lib +# +CONFIG_APP_SELECT_NEWLIB=y +# CONFIG_APP_SELECT_OTHER_LIB is not set + +# +# lib using cJSON +# +# CONFIG_LIB_USING_CJSON is not set + +# +# lib using queue +# +# CONFIG_LIB_USING_QUEUE is not set + +# +# lib using LVGL +# +# CONFIG_LIB_LV is not set + +# +# lvgl image display parameter settings +# +CONFIG_LVGL_WIDTH=320 +CONFIG_LVGL_HEIGHT=320 + +# +# lib using embedded_database +# +# CONFIG_USING_EMBEDDED_DATABASE is not set + +# +# lib using LoRaWan +# +# CONFIG_LIB_USING_LORAWAN is not set + +# +# lib using MQTT +# +# CONFIG_LIB_USING_MQTT is not set + +# +# lib using JerryScript +# +# CONFIG_LIB_USING_JERRYSCRIPT is not set + +# +# lib using SQLite +# +# CONFIG_LIB_USING_SQLITE is not set diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Kconfig b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Kconfig new file mode 100644 index 000000000..40ad59b51 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Kconfig @@ -0,0 +1,44 @@ +mainmenu "XiZi_IIoT Project Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config KERNEL_DIR + string + option env="KERNEL_ROOT" + default "../.." + +config BOARD_GD32F415RG + bool + select ARCH_ARM + default y + +source "$KERNEL_DIR/arch/Kconfig" + +menu "gd32f415rgo6 feature" + source "$BSP_DIR/third_party_driver/Kconfig" + + menu "config default board resources" + menu "config board app name" + config BOARD_APP_NAME + string "config board app name" + default "/XiUOS_gd32f415rgo6_app.bin" + endmenu + endmenu + + menu "config board service table" + config SERVICE_TABLE_ADDRESS + hex "board service table address" + default 0x20000000 + endmenu + +endmenu + + +menu "Hardware feature" +source "$KERNEL_DIR/resources/Kconfig" +endmenu + +source "$KERNEL_DIR/Kconfig" diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Makefile b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Makefile new file mode 100644 index 000000000..5f5cd51d7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/Makefile @@ -0,0 +1,5 @@ +SRC_FILES := board.c + +SRC_DIR := third_party_driver + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/README.md b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/README.md new file mode 100644 index 000000000..8cb542314 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/README.md @@ -0,0 +1,221 @@ +# 从零开始构建矽璓工业物联操作系统:使用ARM架构的STM32F407-discovery开发板 + +[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓工业物联操作系统是一款面向工业物联场景的泛在操作系统,来自泛在操作系统研究计划。所谓泛在操作系统(UOS: Ubiquitous Operating Systems),是支持互联网时代人机物融合泛在计算应用模式的新型操作系统,是传统操作系统概念的泛化与延伸。在泛在操作系统技术体系中,不同的泛在计算设备和泛在应用场景需要符合各自特性的不同UOS,XiUOS即是面向工业物联场景的一种UOS,主要由一个极简的微型实时操作系统(RTOS)内核和其上的智能工业物联框架构成,支持工业物联网(IIoT: Industrial Internet of Things)应用。 + +>注:最新版README请访问[从零开始构建矽璓工业物联操作系统:使用ARM架构的STM32F407-discovery开发板](https://blog.csdn.net/AIIT_Ubiquitous/article/details/116209686),如博客内容与本地文档有差异,以网站内容为准。 + +## 开发环境搭建 + +### 推荐使用: + +**操作系统:** ubuntu18.04 [https://ubuntu.com/download/desktop](https://ubuntu.com/download/desktop) + +更新`ubuntu 18.04`源的方法:(根据自身情况而定,可以不更改) + +第一步:打开sources.list文件 + +```c +sudo vim /etc/apt/sources.list +``` + +第二步:将以下内容复制到sources.list文件 + +```c +deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +``` + +第三步:更新源和系统软件 + +```c +sudo apt-get update +sudo apt-get upgrade +``` + +**开发工具推荐使用 VSCode ,VScode下载地址为:** VSCode [https://code.visualstudio.com/](https://code.visualstudio.com/),推荐下载地址为 [http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb](http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb) + +### 依赖包安装: + +``` +$ sudo apt install build-essential pkg-config git +$ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev +``` + +**XiUOS操作系统源码下载:** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos) + +新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下: + +```c +mkdir test && cd test +git clone https://gitlink.org.cn/xuos/xiuos.git +``` + +1、打开XiUOS源码文件包可以看到以下目录: +| 名称 | 说明 | +| -- | -- | +| APP_Framework | 应用代码 | +| Ubiquitous | 板级支持包,支持NuttX、RT-Thread和XiZi内核 | + +2、打开XiZi内核源码文件包可以看到以下目录: +| 名称 | 说明 | +| -- | -- | +| arch | 架构代码 | +| board | 板级支持包 | +| fs | 文件系统 | +| kernel | 内核源码 | +| lib | 第三方库源码 | +| resources | 驱动文件 | +| tool | 系统工具 | + +使用VScode打开代码,具体操作步骤为:在源码文件夹下打开系统终端,输入`code .`即可打开VScode开发环境,如下图所示: + +
+ +
+ +### 裁减配置工具的下载 + +裁减配置工具: + +**工具地址:** kconfig-frontends [https://www.gitlink.org.cn/xuos/kconfig-frontends](https://www.gitlink.org.cn/xuos/kconfig-frontends),下载与安装的具体命令如下: + +```c +mkdir kfrontends && cd kfrontends +git clone https://gitlink.org.cn/xuos/kconfig-frontends.git +``` + +下载源码后按以下步骤执行软件安装: + +```c +cd kconfig-frontends +./xs_build.sh +``` + +### 编译工具链: + +ARM: arm-none-eabi(`gcc version 6.3.1`),默认安装到Ubuntu的/usr/bin/arm-none-eabi-,使用如下命令行下载和安装。 + +```shell +$ sudo apt install gcc-arm-none-eabi +``` + +# 在STM32F407-DISCOVERY上创建第一个应用 --helloworld + +## 1. 简介 + +| 硬件 | 描述 | +| -- | -- | +|芯片型号| Stm32F407VGT6| +|CPU|arm cortex-m| +|主频| 168MHz | +|片内SRAM| 192KB | +|片上FLASH| 1MB | +| 外设 | -- | +| | ADC、DAC、USB、GPIO、UART、SPI、SDIO、RTC、CAN、DMA、MAC、I²C、WDT、Timer等 | + +XiUOS板级驱动当前支持使用GPIO、I2C、LCD、USB、RTC、SPI、Timer、UART和WDT等。 + +## 2. 编译说明 + +### 编辑环境:`Ubuntu18.04` + +### 编译工具链:`arm-none-eabi-gcc` +使用`VScode`打开工程的方法有多种,本文介绍一种快捷键,在项目目录下将`code .`输入linux系统命令终端即可打开目标项目 + +修改`APP_Framework/Applications`文件夹下`main.c` +在输出函数中写入 `Hello, world!!! \n Running on stm32f407-st-discovery`完成代码编辑。 + +![main](img/main.png) + +编译步骤: + +1.在VScode命令终端中执行以下命令,生成配置文件 + +```c +cd ./Ubiquitous/XiZi +make BOARD=stm32f407-st-discovery distclean +make BOARD=stm32f407-st-discovery menuconfig +``` + +2.在menuconfig界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后保存并退出(本例旨在演示简单的输出例程,所以没有需要配置的选项,双击快捷键ESC退出配置) + +![menuconfig1](img/menuconfig1.png) + +退出时选择`yes`保存上面所配置的内容,如下图所示: + +![menuconfig2](img/menuconfig2.jpg) + +3.继续执行以下命令,进行编译 + +```c +make BOARD=stm32f407-st-discovery +``` + +4.如果编译正确无误,会产生XiZi-stm32f407-st-discovery.elf、XiZi-stm32f407-st-discovery.bin文件。其中XiZi-stm32f407-st-discovery.bin需要烧写到设备中进行运行。 + +## 3. 烧写及执行 + +将 BOARD=stm32f407-st-discovery开发板SWD经 st-link 转接到USB接口,然后使用st-flash工具进行烧写bin文件。 + +![stm32f407-st-discovery](img/stm32f407-st-discovery.png) + +### 烧写工具 + +ARM:ST-LINK(ST-LINK V2实物如图,可在购物网站搜索关键字购买) + +![st-link](img/st-link.png) + +下载并以下执行命令以下命令安装st-link工具(本文使用v1.5.1版本),下载地址为:[http://101.36.126.201:8011/stlink.zip](http://101.36.126.201:8011/stlink.zip) + +``` +sudo apt install libusb-dev +sudo apt install libusb-1.0-0-dev +sudo apt install cmake +cd stlink +make +cd build/Release && make install DESTDIR=_install +``` + +将生成的st-flash(在stlink/build/Release/bin文件夹下)复制到/usr/bin下就可使用了 + +代码根目录下执行st-flash工具烧录 + +``` +sudo st-flash write build/XiZi-stm32f407-st-discovery.bin 0x8000000 +``` + +此外,推荐用户使用putty作为终端工具,安装命令如下: + +```c +sudo apt install putty +``` + +打开putty配置串口信息 + +```c +sudo puty +``` + +选择ttyUSB0(这个端口号根据具体情况而定),配置波特率为115200。 + +![putty](img/putty.png) + +注意:选择正确的终端端口号,最后可以执行以下命令,清除配置文件和编译生成的文件 + +```c +make BOARD=stm32f407-st-discovery distclean +``` + +### 3.1 运行结果 + +如果编译 & 烧写无误,将会在串口终端上看到信息打印输出,(终端串口引脚为PB6、PB7)。 + +![terminal](img/terminal.png) diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.c new file mode 100644 index 000000000..368873a61 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.c @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file board.c +* @brief support stm32f407-st-discovery-board init configure and start-up +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: board.c +Description: support stm32f407-st-discovery-board init configure and driver/task/... init +Others: +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. support stm32f407-st-discovery-board InitBoardHardware +*************************************************/ + +#include +#include +#include +#include "connect_uart.h" + +void SysTickConfiguration(void) +{ + /* setup systick timer for 1000Hz interrupts */ + if(SysTick_Config(SystemCoreClock / 1000U)) { + /* capture error */ + while(1) { + } + } + /* configure the systick handler priority */ + NVIC_SetPriority(SysTick_IRQn, 0x00U); +} + + +void SysTick_Handler(int irqn, void *arg) +{ + + TickAndTaskTimesliceUpdate(); + +} + +void InitBoardHardware() +{ + // system_clock_config() is called from SystemInit (void) + SysTickConfiguration(); + +#ifdef BSP_USING_UART + Gd32HwUsartInit(); +#endif + + InitBoardMemory((void *)MEMORY_START_ADDRESS, (void *)MEMORY_END_ADDRESS); + +#ifdef KERNEL_CONSOLE + InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); + + KPrintf("\nconsole init completed.\n"); + KPrintf("board initialization......\n"); +#endif + + KPrintf("board init done.\n"); + KPrintf("start kernel...\n"); + +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.h new file mode 100644 index 000000000..16bca629e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/board.h @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file board.h +* @brief define stm32f407zgt6-board init configure and start-up function +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: board.h +Description: define stm32f407zgt6-board board init function and struct +Others: +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. define stm32f407zgt6-board InitBoardHardware +2. define stm32f407zgt6-board data and bss struct +*************************************************/ + +#ifndef BOARD_H +#define BOARD_H + +#include + +extern int __stack_end__; +extern unsigned int g_service_table_start; +extern unsigned int g_service_table_end; + +#define MEMORY_START_ADDRESS (&__stack_end__) +#define SRAM_SIZE 112 +#define MEMORY_END_ADDRESS (0x20000000 + SRAM_SIZE * 1024) + +#ifdef SEPARATE_COMPILE +typedef int (*main_t)(int argc, char *argv[]); +typedef void (*exit_t)(void); +struct userspace_s +{ + main_t us_entrypoint; + exit_t us_taskquit; + uintptr_t us_textstart; + uintptr_t us_textend; + uintptr_t us_datasource; + uintptr_t us_datastart; + uintptr_t us_dataend; + uintptr_t us_bssstart; + uintptr_t us_bssend; + uintptr_t us_heapend; +}; +#define USERSPACE (( struct userspace_s *)(0x08040000)) + +#ifndef SERVICE_TABLE_ADDRESS +#define SERVICE_TABLE_ADDRESS (0x20000000) +#endif + +#define USER_SRAM_SIZE 64 +#define USER_MEMORY_START_ADDRESS (USERSPACE->us_bssend) +#define USER_MEMORY_END_ADDRESS (0x10000000 + USER_SRAM_SIZE * 1024) +#endif + +void InitBoardHardware(void); +int Gd32HwUsartInit(void); + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/config.mk b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/config.mk new file mode 100644 index 000000000..256e789e4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/config.mk @@ -0,0 +1,27 @@ +export CROSS_COMPILE ?=/usr/bin/arm-none-eabi- + +export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror +export AFLAGS := -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2 +export LFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds +export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -Werror + +ifeq ($(CONFIG_LIB_MUSLLIB), y) +export LFLAGS += -nostdlib -nostdinc -fno-builtin -nodefaultlibs +export LIBCC := -lgcc +export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a +endif + +ifeq ($(CONFIG_RESOURCES_LWIP), y) +export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a +endif + +export APPLFLAGS := -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds + + +export DEFINES := -DHAVE_CCONFIG_H -DGD32F407 -DHAVE_SIGINFO + +export USING_NEWLIB =1 +export USING_VFS = 1 +export USING_SPI = 1 +export ARCH = arm +export USING_LORA = 1 diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/main.png b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/main.png new file mode 100644 index 0000000000000000000000000000000000000000..d19d92c16441c00eef85cba9cdf6e1da7740d710 GIT binary patch literal 13668 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 B$h80f literal 0 HcmV?d00001 diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/menuconfig1.png b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/menuconfig1.png new file mode 100644 index 0000000000000000000000000000000000000000..d150ebc9669e5266e5bf3ef0f56423ce6b0c1481 GIT binary patch literal 90615 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 z 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 literal 0 HcmV?d00001 diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/menuconfig2.jpg b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/menuconfig2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5529e40b26874ed0138bdfd1a8e4c22d19ba504 GIT binary patch literal 28566 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 z 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 oN(7km_hNZeZgXgFbngSdJ^%n907*naRCt_} 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 literal 0 HcmV?d00001 diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/stm32f407-st-discovery.png b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/stm32f407-st-discovery.png new file mode 100644 index 0000000000000000000000000000000000000000..473bf779b30813e4765cb38d935c60d664c268ff GIT binary patch literal 293377 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 z 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%0A`n%f{>CQfgP=^u~`CCP&rH*}OaW50{9x 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%0ALCY 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

W=&p0P^LNPb1Il|K& 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 P@Bjzna29RwAgl5JOUn$J literal 0 HcmV?d00001 diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/terminal.png b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..a1bd89aa3f53e0f999b71fcecc1414099874fd47 GIT binary patch literal 182459 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 ePrvjCv|LbS`pKFhP&go7g=KUWw`}Lau literal 0 HcmV?d00001 diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/vscode.jpg b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/img/vscode.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b9bacff78e4b635984f01459c6c41720bcd7f3c6 GIT binary patch literal 57472 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 + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) /* Cosmic */ + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __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 (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +#include /* Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #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 */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + 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 */ +#endif + 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; + + +/** \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; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \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; + +/*@} 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 +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< 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 +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< 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 7 /*!< 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 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< 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 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< 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 4 /*!< 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 3 /*!< 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 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< 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 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< 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 8 /*!< 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 0 /*!< 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 */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< 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 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< 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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_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 +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< 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 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< 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 +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 0 /*!< 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 0 /*!< 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 0 /*!< 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 0 /*!< 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 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< 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 +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< 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 0 /*!< 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 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< 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 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< 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 0 /*!< 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 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< 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 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< 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 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< 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_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< 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 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< 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 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< 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_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< 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 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \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 +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< 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 28 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 8 /*!< 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 1 /*!< 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 0 /*!< 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 + + +#if (__FPU_PRESENT == 1) +/** \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[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< 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 1 /*!< 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 0 /*!< 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 */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< 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 24 /*!< 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 20 /*!< 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 16 /*!< 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 12 /*!< 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 8 /*!< 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 4 /*!< 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 0 /*!< 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 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< 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 24 /*!< 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 4 /*!< 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 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< 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 25 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 5 /*!< 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 3 /*!< 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 2 /*!< 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 1 /*!< 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 0 /*!< 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 */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 10 /*!< 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 9 /*!< 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 8 /*!< 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 7 /*!< 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 6 /*!< 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 5 /*!< 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 4 /*!< 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 0 /*!< 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_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 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 (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function 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)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function 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 ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \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(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function 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 samllest 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 & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function 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 samllest 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* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function 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 - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* 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 (0); /* 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 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function 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) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function 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 + + The function 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 */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cm4_simd.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cm4_simd.h new file mode 100644 index 000000000..bee997ed6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cm4_simd.h @@ -0,0 +1,697 @@ +/**************************************************************************//** + * @file core_cm4_simd.h + * @brief CMSIS Cortex-M4 SIMD Header File + * @version V3.30 + * @date 17. February 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM4_SIMD_H +#define __CORE_CM4_SIMD_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ +#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) << 32) ) >> 32)) + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* not yet supported */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_SIMD_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmFunc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmFunc.h new file mode 100644 index 000000000..adb07b5d3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmFunc.h @@ -0,0 +1,616 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V3.01 + * @date 06. March 2012 + * + * @note + * Copyright (C) 2009-2012 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function 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 + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 + + This function 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 (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function 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 + + This function 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 & 0xff); +} + + +/** \brief Get Fault Mask + + This function 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 + + This function 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)1); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function 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 (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function 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 (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) ); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmInstr.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmInstr.h new file mode 100644 index 000000000..624c175fd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/core_cmInstr.h @@ -0,0 +1,618 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V3.01 + * @date 06. March 2012 + * + * @note + * Copyright (C) 2009-2012 ARM Limited. All rights reserved. + * + * @par + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + ******************************************************************************/ + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + 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 + + 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 + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + 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 + + This function 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 + + This function 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) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command 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(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command 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(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command 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(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function 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 + + This function 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 Count leading zeros + + This function 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 + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + 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. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + 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. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + uint32_t result; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + + __ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) ); + return(op1); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint8_t result; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint16_t result; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function 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 + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint8_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * 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. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx.h new file mode 100644 index 000000000..8045ec46e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx.h @@ -0,0 +1,368 @@ +/*! + \file gd32f4xx.h + \brief general definitions for GD32F4xx + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2020, 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 GD32F4XX_H +#define GD32F4XX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* define GD32F4xx */ +#if !defined (GD32F450) && !defined (GD32F405) && !defined (GD32F407) && !defined (GD32F470) && !defined (GD32F425) && !defined (GD32F427) + /* #define GD32F450 */ + /* #define GD32F405 */ + /* #define GD32F407 */ + /* #define GD32F470 */ + /* #define GD32F425 */ + /* #define GD32F427 */ +#endif /* define GD32F4xx */ + +#if !defined (GD32F450) && !defined (GD32F405) && !defined (GD32F407) && !defined (GD32F470) && !defined (GD32F425) && !defined (GD32F427) + #error "Please select the target GD32F4xx device in gd32f4xx.h file" +#endif /* undefine GD32F4xx 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)0xFFFF) +#endif /* high speed crystal oscillator startup timeout */ + +/* define value of internal 16MHz RC oscillator (IRC16M) in Hz */ +#if !defined (IRC16M_VALUE) +#define IRC16M_VALUE ((uint32_t)16000000) +#endif /* internal 16MHz RC oscillator value */ + +/* define startup timeout value of internal 16MHz RC oscillator (IRC16M) */ +#if !defined (IRC16M_STARTUP_TIMEOUT) +#define IRC16M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 16MHz 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 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 */ + +/* I2S external clock in selection */ +//#define I2S_EXTERNAL_CLOCK_IN (uint32_t)12288000U + +/* GD32F4xx firmware library version number V1.0 */ +#define __GD32F4xx_STDPERIPH_VERSION_MAIN (0x03) /*!< [31:24] main version */ +#define __GD32F4xx_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32F4xx_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32F4xx_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32F4xx_STDPERIPH_VERSION ((__GD32F4xx_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32F4xx_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32F4xx_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32F4xx_STDPERIPH_VERSION_RC)) + +/* configuration of the cortex-M4 processor and core peripherals */ +#define __CM4_REV 0x0001 /*!< core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< GD32F4xx provide MPU */ +#define __NVIC_PRIO_BITS 4 /*!< GD32F4xx 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 interrupt number */ +typedef enum IRQn +{ + /* cortex-M4 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 cortex-M4 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 cortex-M4 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 cortex-M4 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 cortex-M4 SV call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 cortex-M4 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 cortex-M4 pend SV interrupt */ + SysTick_IRQn = -1, /*!< 15 cortex-M4 system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ + TAMPER_STAMP_IRQn = 2, /*!< tamper and timestamp through EXTI line detect */ + RTC_WKUP_IRQn = 3, /*!< RTC wakeup through EXTI line interrupt */ + FMC_IRQn = 4, /*!< FMC interrupt */ + RCU_CTC_IRQn = 5, /*!< RCU and CTC interrupt */ + EXTI0_IRQn = 6, /*!< EXTI line 0 interrupts */ + EXTI1_IRQn = 7, /*!< EXTI line 1 interrupts */ + EXTI2_IRQn = 8, /*!< EXTI line 2 interrupts */ + EXTI3_IRQn = 9, /*!< EXTI line 3 interrupts */ + EXTI4_IRQn = 10, /*!< EXTI line 4 interrupts */ + DMA0_Channel0_IRQn = 11, /*!< DMA0 channel0 Interrupt */ + DMA0_Channel1_IRQn = 12, /*!< DMA0 channel1 Interrupt */ + DMA0_Channel2_IRQn = 13, /*!< DMA0 channel2 interrupt */ + DMA0_Channel3_IRQn = 14, /*!< DMA0 channel3 interrupt */ + DMA0_Channel4_IRQn = 15, /*!< DMA0 channel4 interrupt */ + DMA0_Channel5_IRQn = 16, /*!< DMA0 channel5 interrupt */ + DMA0_Channel6_IRQn = 17, /*!< DMA0 channel6 interrupt */ + ADC_IRQn = 18, /*!< ADC interrupt */ + CAN0_TX_IRQn = 19, /*!< CAN0 TX interrupt */ + CAN0_RX0_IRQn = 20, /*!< CAN0 RX0 interrupt */ + CAN0_RX1_IRQn = 21, /*!< CAN0 RX1 interrupt */ + CAN0_EWMC_IRQn = 22, /*!< CAN0 EWMC interrupt */ + EXTI5_9_IRQn = 23, /*!< EXTI[9:5] interrupts */ + TIMER0_BRK_TIMER8_IRQn = 24, /*!< TIMER0 break and TIMER8 interrupts */ + TIMER0_UP_TIMER9_IRQn = 25, /*!< TIMER0 update and TIMER9 interrupts */ + TIMER0_TRG_CMT_TIMER10_IRQn = 26, /*!< TIMER0 trigger and commutation and TIMER10 interrupts */ + TIMER0_Channel_IRQn = 27, /*!< TIMER0 channel capture compare interrupt */ + TIMER1_IRQn = 28, /*!< TIMER1 interrupt */ + TIMER2_IRQn = 29, /*!< TIMER2 interrupt */ + TIMER3_IRQn = 30, /*!< TIMER3 interrupts */ + 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 interrupt */ + USART1_IRQn = 38, /*!< USART1 interrupt */ + USART2_IRQn = 39, /*!< USART2 interrupt */ + EXTI10_15_IRQn = 40, /*!< EXTI[15:10] interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC alarm interrupt */ + USBFS_WKUP_IRQn = 42, /*!< USBFS wakeup interrupt */ + TIMER7_BRK_TIMER11_IRQn = 43, /*!< TIMER7 break and TIMER11 interrupts */ + TIMER7_UP_TIMER12_IRQn = 44, /*!< TIMER7 update and TIMER12 interrupts */ + TIMER7_TRG_CMT_TIMER13_IRQn = 45, /*!< TIMER7 trigger and commutation and TIMER13 interrupts */ + TIMER7_Channel_IRQn = 46, /*!< TIMER7 channel capture compare interrupt */ + DMA0_Channel7_IRQn = 47, /*!< DMA0 channel7 interrupt */ + +#if defined (GD32F450) || defined (GD32F470) + EXMC_IRQn = 48, /*!< EXMC interrupt */ + SDIO_IRQn = 49, /*!< SDIO interrupt */ + TIMER4_IRQn = 50, /*!< TIMER4 interrupt */ + SPI2_IRQn = 51, /*!< SPI2 interrupt */ + UART3_IRQn = 52, /*!< UART3 interrupt */ + UART4_IRQn = 53, /*!< UART4 interrupt */ + TIMER5_DAC_IRQn = 54, /*!< TIMER5 and DAC0 DAC1 underrun error interrupts */ + 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 */ + ENET_IRQn = 61, /*!< ENET interrupt */ + ENET_WKUP_IRQn = 62, /*!< ENET wakeup through EXTI line interrupt */ + CAN1_TX_IRQn = 63, /*!< CAN1 TX interrupt */ + CAN1_RX0_IRQn = 64, /*!< CAN1 RX0 interrupt */ + CAN1_RX1_IRQn = 65, /*!< CAN1 RX1 interrupt */ + CAN1_EWMC_IRQn = 66, /*!< CAN1 EWMC interrupt */ + USBFS_IRQn = 67, /*!< USBFS interrupt */ + DMA1_Channel5_IRQn = 68, /*!< DMA1 channel5 interrupt */ + DMA1_Channel6_IRQn = 69, /*!< DMA1 channel6 interrupt */ + DMA1_Channel7_IRQn = 70, /*!< DMA1 channel7 interrupt */ + USART5_IRQn = 71, /*!< USART5 interrupt */ + I2C2_EV_IRQn = 72, /*!< I2C2 event interrupt */ + I2C2_ER_IRQn = 73, /*!< I2C2 error interrupt */ + USBHS_EP1_Out_IRQn = 74, /*!< USBHS endpoint 1 out interrupt */ + USBHS_EP1_In_IRQn = 75, /*!< USBHS endpoint 1 in interrupt */ + USBHS_WKUP_IRQn = 76, /*!< USBHS wakeup through EXTI line interrupt */ + USBHS_IRQn = 77, /*!< USBHS interrupt */ + DCI_IRQn = 78, /*!< DCI interrupt */ + TRNG_IRQn = 80, /*!< 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 */ + TLI_IRQn = 88, /*!< TLI interrupt */ + TLI_ER_IRQn = 89, /*!< TLI error interrupt */ + IPA_IRQn = 90, /*!< IPA interrupt */ +#endif /* GD32F450 and GD32F470 */ + +#if defined (GD32F405) || defined (GD32F425) + SDIO_IRQn = 49, /*!< SDIO interrupt */ + TIMER4_IRQn = 50, /*!< TIMER4 interrupt */ + SPI2_IRQn = 51, /*!< SPI2 interrupt */ + UART3_IRQn = 52, /*!< UART3 interrupt */ + UART4_IRQn = 53, /*!< UART4 interrupt */ + TIMER5_DAC_IRQn = 54, /*!< TIMER5 and DAC0 DAC1 underrun error interrupts */ + 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 */ + CAN1_TX_IRQn = 63, /*!< CAN1 TX interrupt */ + CAN1_RX0_IRQn = 64, /*!< CAN1 RX0 interrupt */ + CAN1_RX1_IRQn = 65, /*!< CAN1 RX1 interrupt */ + CAN1_EWMC_IRQn = 66, /*!< CAN1 EWMC interrupt */ + USBFS_IRQn = 67, /*!< USBFS interrupt */ + DMA1_Channel5_IRQn = 68, /*!< DMA1 channel5 interrupt */ + DMA1_Channel6_IRQn = 69, /*!< DMA1 channel6 interrupt */ + DMA1_Channel7_IRQn = 70, /*!< DMA1 channel7 interrupt */ + USART5_IRQn = 71, /*!< USART5 interrupt */ + I2C2_EV_IRQn = 72, /*!< I2C2 event interrupt */ + I2C2_ER_IRQn = 73, /*!< I2C2 error interrupt */ + USBHS_EP1_Out_IRQn = 74, /*!< USBHS endpoint 1 Out interrupt */ + USBHS_EP1_In_IRQn = 75, /*!< USBHS endpoint 1 in interrupt */ + USBHS_WKUP_IRQn = 76, /*!< USBHS wakeup through EXTI line interrupt */ + USBHS_IRQn = 77, /*!< USBHS interrupt */ + DCI_IRQn = 78, /*!< DCI interrupt */ + TRNG_IRQn = 80, /*!< TRNG interrupt */ + FPU_IRQn = 81, /*!< FPU interrupt */ +#endif /* GD32F405 and GD32F425 */ + +#if defined (GD32F407) || defined (GD32F427) + EXMC_IRQn = 48, /*!< EXMC interrupt */ + SDIO_IRQn = 49, /*!< SDIO interrupt */ + TIMER4_IRQn = 50, /*!< TIMER4 interrupt */ + SPI2_IRQn = 51, /*!< SPI2 interrupt */ + UART3_IRQn = 52, /*!< UART3 interrupt */ + UART4_IRQn = 53, /*!< UART4 interrupt */ + TIMER5_DAC_IRQn = 54, /*!< TIMER5 and DAC0 DAC1 underrun error interrupts */ + 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 */ + ENET_IRQn = 61, /*!< ENET interrupt */ + ENET_WKUP_IRQn = 62, /*!< ENET wakeup through EXTI line interrupt */ + CAN1_TX_IRQn = 63, /*!< CAN1 TX interrupt */ + CAN1_RX0_IRQn = 64, /*!< CAN1 RX0 interrupt */ + CAN1_RX1_IRQn = 65, /*!< CAN1 RX1 interrupt */ + CAN1_EWMC_IRQn = 66, /*!< CAN1 EWMC interrupt */ + USBFS_IRQn = 67, /*!< USBFS interrupt */ + DMA1_Channel5_IRQn = 68, /*!< DMA1 channel5 interrupt */ + DMA1_Channel6_IRQn = 69, /*!< DMA1 channel6 interrupt */ + DMA1_Channel7_IRQn = 70, /*!< DMA1 channel7 interrupt */ + USART5_IRQn = 71, /*!< USART5 interrupt */ + I2C2_EV_IRQn = 72, /*!< I2C2 event interrupt */ + I2C2_ER_IRQn = 73, /*!< I2C2 error interrupt */ + USBHS_EP1_Out_IRQn = 74, /*!< USBHS endpoint 1 out interrupt */ + USBHS_EP1_In_IRQn = 75, /*!< USBHS endpoint 1 in interrupt */ + USBHS_WKUP_IRQn = 76, /*!< USBHS wakeup through EXTI line interrupt */ + USBHS_IRQn = 77, /*!< USBHS interrupt */ + DCI_IRQn = 78, /*!< DCI interrupt */ + TRNG_IRQn = 80, /*!< TRNG interrupt */ + FPU_IRQn = 81, /*!< FPU interrupt */ +#endif /* GD32F407 and GD32F427 */ + +} IRQn_Type; + +/* includes */ +#include "core_cm4.h" +#include "system_gd32f4xx.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {GD_ERROR = 0, GD_SUCCESS = !GD_ERROR} ErrStatus; + +/* bit operations */ +#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 TCMSRAM_BASE ((uint32_t)0x10000000U) /*!< TCMSRAM(64KB) base address */ +#define OPTION_BASE ((uint32_t)0x1FFEC000U) /*!< Option bytes base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM0 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 AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x50000000U) /*!< ahb2 base address */ + +/* EXMC memory map */ +#define EXMC_BASE ((uint32_t)0xA0000000U) /*!< EXMC register base address */ + +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define RTC_BASE (APB1_BUS_BASE + 0x00002800U) /*!< RTC base address */ +#define WWDGT_BASE (APB1_BUS_BASE + 0x00002C00U) /*!< WWDGT base address */ +#define FWDGT_BASE (APB1_BUS_BASE + 0x00003000U) /*!< FWDGT base address */ +#define I2S_ADD_BASE (APB1_BUS_BASE + 0x00003400U) /*!< I2S1_add base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define CAN_BASE (APB1_BUS_BASE + 0x00006400U) /*!< CAN base address */ +#define CTC_BASE (APB1_BUS_BASE + 0x00006C00U) /*!< CTC base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ +#define IREF_BASE (APB1_BUS_BASE + 0x0000C400U) /*!< IREF base address */ + +/* advanced peripheral bus 2 memory map */ +#define TLI_BASE (APB2_BUS_BASE + 0x00006800U) /*!< TLI base address */ +#define SYSCFG_BASE (APB2_BUS_BASE + 0x00003800U) /*!< SYSCFG base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00003C00U) /*!< EXTI base address */ +#define SDIO_BASE (APB2_BUS_BASE + 0x00002C00U) /*!< SDIO base address */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002000U) /*!< ADC base address */ +/* advanced high performance bus 1 memory map */ +#define GPIO_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< GPIO base address */ +#define CRC_BASE (AHB1_BUS_BASE + 0x00003000U) /*!< CRC base address */ +#define RCU_BASE (AHB1_BUS_BASE + 0x00003800U) /*!< RCU base address */ +#define FMC_BASE (AHB1_BUS_BASE + 0x00003C00U) /*!< FMC base address */ +#define BKPSRAM_BASE (AHB1_BUS_BASE + 0x00004000U) /*!< BKPSRAM base address */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00006000U) /*!< DMA base address */ +#define ENET_BASE (AHB1_BUS_BASE + 0x00008000U) /*!< ENET base address */ +#define IPA_BASE (AHB1_BUS_BASE + 0x0000B000U) /*!< IPA base address */ +#define USBHS_BASE (AHB1_BUS_BASE + 0x00020000U) /*!< USBHS base address */ + +/* advanced high performance bus 2 memory map */ +#define USBFS_BASE (AHB2_BUS_BASE + 0x00000000U) /*!< USBFS base address */ +#define DCI_BASE (AHB2_BUS_BASE + 0x00050000U) /*!< DCI base address */ +#define TRNG_BASE (AHB2_BUS_BASE + 0x00060800U) /*!< TRNG base address */ +/* option byte and debug memory map */ +#define OB_BASE ((uint32_t)0x1FFEC000U) /*!< OB base address */ +#define DBG_BASE ((uint32_t)0xE0042000U) /*!< DBG_DEVICE base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32f4xx_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx_libopt.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx_libopt.h new file mode 100644 index 000000000..dd6af6573 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/gd32f4xx_libopt.h @@ -0,0 +1,78 @@ +/*! + \file gd32f4xx_libopt.h + \brief library optional for gd32f4xx + + \version 2022-04-18, V2.0.0, demo for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_LIBOPT_H +#define GD32F4XX_LIBOPT_H + +#if defined (GD32F450) || defined (GD32F405) || defined (GD32F407) || defined (GD32F470) || defined (GD32F425) || defined (GD32F427) + #include "gd32f4xx_rcu.h" + #include "gd32f4xx_adc.h" + #include "gd32f4xx_can.h" + #include "gd32f4xx_crc.h" + #include "gd32f4xx_ctc.h" + #include "gd32f4xx_dac.h" + #include "gd32f4xx_dbg.h" + #include "gd32f4xx_dci.h" + #include "gd32f4xx_dma.h" + #include "gd32f4xx_exti.h" + #include "gd32f4xx_fmc.h" + #include "gd32f4xx_fwdgt.h" + #include "gd32f4xx_gpio.h" + #include "gd32f4xx_syscfg.h" + #include "gd32f4xx_i2c.h" + #include "gd32f4xx_iref.h" + #include "gd32f4xx_pmu.h" + #include "gd32f4xx_rtc.h" + #include "gd32f4xx_sdio.h" + #include "gd32f4xx_spi.h" + #include "gd32f4xx_timer.h" + #include "gd32f4xx_trng.h" + #include "gd32f4xx_usart.h" + #include "gd32f4xx_wwdgt.h" + #include "gd32f4xx_misc.h" +#endif + +#if defined (GD32F450) || defined (GD32F470) + #include "gd32f4xx_enet.h" + #include "gd32f4xx_exmc.h" + #include "gd32f4xx_ipa.h" + #include "gd32f4xx_tli.h" +#endif + +#if defined (GD32F407) || defined (GD32F427) + #include "gd32f4xx_enet.h" + #include "gd32f4xx_exmc.h" +#endif + +#endif /* GD32F4XX_LIBOPT_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/system_gd32f4xx.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/system_gd32f4xx.h new file mode 100644 index 000000000..56f64bfaa --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/include/system_gd32f4xx.h @@ -0,0 +1,58 @@ +/*! + \file system_gd32f4xx.h + \brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for + GD32F4xx Device Series +*/ + +/* Copyright (c) 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#ifndef SYSTEM_GD32F4XX_H +#define SYSTEM_GD32F4XX_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_GD32F4XX_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link.lds b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link.lds new file mode 100644 index 000000000..6214749a8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link.lds @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +__SYSTEM_STACKSIZE__ = 0x400; + +OUTPUT_ARCH(arm) + +MEMORY +{ + flash (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */ + sram (rw) : ORIGIN = 0x20000000, LENGTH = 112k /* 124k sram */ +} + +ENTRY(Reset_Handler) +SECTIONS +{ + .text : + { + . = ALIGN(4); + PROVIDE(_stext = ABSOLUTE(.)); + KEEP(*(.isr_vector)) /* Startup code */ + + + . = ALIGN(4); + *(.text .text.*) /* Normal code */ + *(.rodata .rodata*) /* read-only data (constants) */ + + *(.glue_7) + *(.glue_7t) + + /* section information for shell */ + . = ALIGN(4); + _shell_command_start = .; + KEEP (*(shellCommand)) + _shell_command_end = .; + . = ALIGN(4); + + PROVIDE(__ctors_start__ = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(4); + + __isrtbl_idx_start = .; + KEEP(*(.isrtbl.idx)) + __isrtbl_start = .; + KEEP(*(.isrtbl)) + __isrtbl_end = .; + . = ALIGN(4); + + PROVIDE(g_service_table_start = ABSOLUTE(.)); + KEEP(*(.g_service_table)) + PROVIDE(g_service_table_end = ABSOLUTE(.)); + + PROVIDE(_etext = ABSOLUTE(.)); + _exit = .; + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + PROVIDE(__exidx_start = ABSOLUTE(.)); + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + _sidata = .; + PROVIDE(__exidx_end = ABSOLUTE(.)); + } > flash + + .data : AT(__exidx_end) + { + . = ALIGN(4); + PROVIDE(_sdata = ABSOLUTE(.)); + *(.data .data.*) + PROVIDE(_edata = ABSOLUTE(.)); + } > sram + + .bss : + { + . = ALIGN(4); + __bss_start = ABSOLUTE(.); + + *(.bss .bss.*) + *(COMMON) + + . = ALIGN(4); + __bss_end = ABSOLUTE(.); + } > sram + + .stack : + { + . = ALIGN(4); + PROVIDE(__stack_start__ = ABSOLUTE(.)); + /* cpu stack */ + . = . + __SYSTEM_STACKSIZE__; + __stack_tp = .; + PROVIDE(__stack_end__ = ABSOLUTE(.)); + } > sram + + _end = ABSOLUTE(.); +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link_userspace.lds b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link_userspace.lds new file mode 100644 index 000000000..a60db4c58 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/link_userspace.lds @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +OUTPUT_ARCH(arm) + +MEMORY +{ + uflash (rx) : ORIGIN = 0x08080000, LENGTH = 512k /* 512KB uflash */ + usram (rw) : ORIGIN = 0x2001C000, LENGTH = 80k /* 80K usram */ +} + +SECTIONS +{ + .userspace : + { + _ustext = ABSOLUTE(.); + . = ALIGN(4); + KEEP(*(.userspace)) + } > uflash + + .text : + { + *(.text .text.*) + *(.rodata .rodata*) + *(.glue_7) + *(.glue_7t) + PROVIDE(_uetext = ABSOLUTE(.)); + } > uflash + + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > uflash + + __uexidx_start = ABSOLUTE(.); + + .ARM.exidx : + { + PROVIDE(__uexidx_start = ABSOLUTE(.)); + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + PROVIDE(__uexidx_end = ABSOLUTE(.)); + } > uflash + + _ueronly = ABSOLUTE(.); + + .data : AT(_ueronly) + { + _usdata = ABSOLUTE(.); + *(.data .data.*) + . = ALIGN(4); + _uedata = ABSOLUTE(.); + } > usram + + .bss : { + . = ALIGN(4); + _usbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + . = ALIGN(4); + _uebss = ABSOLUTE(.); + } > usram +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Kconfig new file mode 100644 index 000000000..4a600e247 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Kconfig @@ -0,0 +1,8 @@ + +menuconfig BSP_USING_UART +bool "Using UART device" +default y +select RESOURCES_SERIAL +if BSP_USING_UART +source "$BSP_DIR/third_party_driver/uart/Kconfig" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Makefile new file mode 100644 index 000000000..fa01b25a9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/Makefile @@ -0,0 +1,7 @@ +SRC_DIR := src + +ifeq ($(CONFIG_BSP_USING_UART),y) + SRC_DIR += uart +endif + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/connect_uart.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/connect_uart.h new file mode 100644 index 000000000..828962feb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/connect_uart.h @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_usart.h +* @brief define stm32f407zgt6-board usart function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_USART_H +#define CONNECT_USART_H + +#include +#include "gd32f4xx_usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define KERNEL_CONSOLE_BUS_NAME SERIAL_BUS_NAME_5 +#define KERNEL_CONSOLE_DRV_NAME SERIAL_DRV_NAME_5 +#define KERNEL_CONSOLE_DEVICE_NAME SERIAL_5_DEVICE_NAME_0 + +struct UsartHwCfg +{ + uint32_t uart_device; +}; + +struct Gd32Usart +{ + struct SerialBus serial_bus; +}; + +int Gd32HwUsartInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_adc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_adc.h new file mode 100644 index 000000000..359692483 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_adc.h @@ -0,0 +1,516 @@ +/*! + \file gd32f4xx_adc.h + \brief definitions for the ADC + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_ADC_H +#define GD32F4XX_ADC_H + +#include "gd32f4xx.h" + +/* ADC definitions */ +#define ADC0 ADC_BASE +#define ADC1 (ADC_BASE + 0x100U) +#define ADC2 (ADC_BASE + 0x200U) + +/* registers definitions */ +#define ADC_STAT(adcx) REG32((adcx) + 0x00U) /*!< ADC status register */ +#define ADC_CTL0(adcx) REG32((adcx) + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1(adcx) REG32((adcx) + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1(adcx) REG32((adcx) + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0(adcx) REG32((adcx) + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1(adcx) REG32((adcx) + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2(adcx) REG32((adcx) + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3(adcx) REG32((adcx) + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT(adcx) REG32((adcx) + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT(adcx) REG32((adcx) + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0(adcx) REG32((adcx) + 0x2CU) /*!< ADC routine sequence register 0 */ +#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC routine sequence register 1 */ +#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC routine sequence register 2 */ +#define ADC_ISQ(adcx) REG32((adcx) + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0(adcx) REG32((adcx) + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1(adcx) REG32((adcx) + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2(adcx) REG32((adcx) + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3(adcx) REG32((adcx) + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA(adcx) REG32((adcx) + 0x4CU) /*!< ADC routine data register */ +#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x80U) /*!< ADC oversampling control register */ +#define ADC_SSTAT REG32((ADC_BASE) + 0x300U) /*!< ADC summary status register */ +#define ADC_SYNCCTL REG32((ADC_BASE) + 0x304U) /*!< ADC synchronization control register */ +#define ADC_SYNCDATA REG32((ADC_BASE) + 0x308U) /*!< ADC synchronization routine data register */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of conversion */ +#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion */ +#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */ +#define ADC_STAT_STRC BIT(4) /*!< routine channel start flag */ +#define ADC_STAT_ROVF BIT(5) /*!< routine data register overflow */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted sequence conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on routine channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ +#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on routine channels */ +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ +#define ADC_CTL0_ROVFIE BIT(26) /*!< interrupt enable for ROVF */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ +#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_ETSIC BITS(16,19) /*!< external event select for inserted sequence */ +#define ADC_CTL1_ETMIC BITS(20,21) /*!< external trigger conversion mode for inserted channels */ +#define ADC_CTL1_SWICST BIT(22) /*!< start conversion of inserted channels */ +#define ADC_CTL1_ETSRC BITS(24,27) /*!< external event select for routine sequence */ +#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger conversion mode for routine channels */ +#define ADC_CTL1_SWRCST BIT(30) /*!< start conversion of routine channels */ + +/* ADC_SAMPTx x=0..1 */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel x sample time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for inserted channel x */ + +/* ADC_WDHT */ +#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ + +/* ADC_WDLT */ +#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ + +/* ADC_RSQx */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< x conversion in routine sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< routine channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< x conversion in inserted sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< inserted sequence length */ + +/* ADC_IDATAx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< inserted data x */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< routine data */ + +/* ADC_OVSAMPCTL */ +#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSAMPCTL_OVSR BITS(2,4) /*!< oversampling ratio */ +#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ +#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ + +/* ADC_SSTAT */ +#define ADC_SSTAT_WDE0 BIT(0) /*!< the mirror image of the WDE bit of ADC0 */ +#define ADC_SSTAT_EOC0 BIT(1) /*!< the mirror image of the EOC bit of ADC0 */ +#define ADC_SSTAT_EOIC0 BIT(2) /*!< the mirror image of the EOIC bit of ADC0 */ +#define ADC_SSTAT_STIC0 BIT(3) /*!< the mirror image of the STIC bit of ADC0 */ +#define ADC_SSTAT_STRC0 BIT(4) /*!< the mirror image of the STRC bit of ADC0 */ +#define ADC_SSTAT_ROVF0 BIT(5) /*!< the mirror image of the ROVF bit of ADC0 */ +#define ADC_SSTAT_WDE1 BIT(8) /*!< the mirror image of the WDE bit of ADC1 */ +#define ADC_SSTAT_EOC1 BIT(9) /*!< the mirror image of the EOC bit of ADC1 */ +#define ADC_SSTAT_EOIC1 BIT(10) /*!< the mirror image of the EOIC bit of ADC1 */ +#define ADC_SSTAT_STIC1 BIT(11) /*!< the mirror image of the STIC bit of ADC1 */ +#define ADC_SSTAT_STRC1 BIT(12) /*!< the mirror image of the STRC bit of ADC1 */ +#define ADC_SSTAT_ROVF1 BIT(13) /*!< the mirror image of the ROVF bit of ADC1 */ +#define ADC_SSTAT_WDE2 BIT(16) /*!< the mirror image of the WDE bit of ADC2 */ +#define ADC_SSTAT_EOC2 BIT(17) /*!< the mirror image of the EOC bit of ADC2 */ +#define ADC_SSTAT_EOIC2 BIT(18) /*!< the mirror image of the EOIC bit of ADC2 */ +#define ADC_SSTAT_STIC2 BIT(19) /*!< the mirror image of the STIC bit of ADC2 */ +#define ADC_SSTAT_STRC2 BIT(20) /*!< the mirror image of the STRC bit of ADC2 */ +#define ADC_SSTAT_ROVF2 BIT(21) /*!< the mirror image of the ROVF bit of ADC2 */ + +/* ADC_SYNCCTL */ +#define ADC_SYNCCTL_SYNCM BITS(0,4) /*!< ADC synchronization mode */ +#define ADC_SYNCCTL_SYNCDLY BITS(8,11) /*!< ADC synchronization delay */ +#define ADC_SYNCCTL_SYNCDDM BIT(13) /*!< ADC synchronization DMA disable mode */ +#define ADC_SYNCCTL_SYNCDMA BITS(14,15) /*!< ADC synchronization DMA mode selection */ +#define ADC_SYNCCTL_ADCCK BITS(16,18) /*!< ADC clock */ +#define ADC_SYNCCTL_VBATEN BIT(22) /*!< channel 18 (1/4 voltate of external battery) enable of ADC0 */ +#define ADC_SYNCCTL_TSVREN BIT(23) /*!< channel 16 (temperature sensor) and 17 (internal reference voltage) enable of ADC0 */ + +/* ADC_SYNCDATA */ +#define ADC_SYNCDATA_SYNCDATA0 BITS(0,15) /*!< routine data1 in ADC synchronization mode */ +#define ADC_SYNCDATA_SYNCDATA1 BITS(16,31) /*!< routine data2 in ADC synchronization mode */ + +/* constants definitions */ +/* ADC status flag */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< routine channel start flag */ +#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow */ + +/* adc_ctl0 register value */ +#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< 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 sequence convert automatically */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ + +/* temperature sensor channel, internal reference voltage channel, VBAT channel */ +#define ADC_VBAT_CHANNEL_SWITCH ADC_SYNCCTL_VBATEN /*!< VBAT channel */ +#define ADC_TEMP_VREF_CHANNEL_SWITCH ADC_SYNCCTL_TSVREN /*!< Vref and Vtemp channel */ + +/* ADC synchronization mode */ +#define SYNCCTL_SYNCM(regval) (BITS(0,4) & ((uint32_t)(regval))) /*!< write value to ADC_CTL0_SYNCM bit field */ +#define ADC_SYNC_MODE_INDEPENDENT SYNCCTL_SYNCM(0) /*!< ADC synchronization mode disabled.All the ADCs work independently */ +#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(1) /*!< ADC0 and ADC1 work in combined routine parallel & inserted parallel mode. ADC2 works independently */ +#define ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(2) /*!< ADC0 and ADC1 work in combined routine parallel & trigger rotation mode. ADC2 works independently */ +#define ADC_DAUL_INSERTED_PARALLEL SYNCCTL_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode. ADC2 works independently */ +#define ADC_DAUL_ROUTINE_PARALLEL SYNCCTL_SYNCM(6) /*!< ADC0 and ADC1 work in routine parallel mode. ADC2 works independently */ +#define ADC_DAUL_ROUTINE_FOLLOW_UP SYNCCTL_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up mode. ADC2 works independently */ +#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION SYNCCTL_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode. ADC2 works independently */ +#define ADC_ALL_ROUTINE_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(17) /*!< all ADCs work in combined routine parallel & inserted parallel mode */ +#define ADC_ALL_ROUTINE_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(18) /*!< all ADCs work in combined routine parallel & trigger rotation mode */ +#define ADC_ALL_INSERTED_PARALLEL SYNCCTL_SYNCM(21) /*!< all ADCs work in inserted parallel mode */ +#define ADC_ALL_ROUTINE_PARALLEL SYNCCTL_SYNCM(22) /*!< all ADCs work in routine parallel mode */ +#define ADC_ALL_ROUTINE_FOLLOW_UP SYNCCTL_SYNCM(23) /*!< all ADCs work in follow-up mode */ +#define ADC_ALL_INSERTED_TRRIGGER_ROTATION SYNCCTL_SYNCM(25) /*!< all ADCs work in trigger rotation mode */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ + +/* external trigger mode for routine 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 external trigger select for routine channel */ +#define CTL1_ETSRC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) +#define ADC_EXTTRIG_ROUTINE_T0_CH0 CTL1_ETSRC(0) /*!< timer 0 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH1 CTL1_ETSRC(1) /*!< timer 0 CC1 event select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH2 CTL1_ETSRC(2) /*!< timer 0 CC2 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_CH1 CTL1_ETSRC(3) /*!< timer 1 CC1 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_CH2 CTL1_ETSRC(4) /*!< timer 1 CC2 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_CH3 CTL1_ETSRC(5) /*!< timer 1 CC3 event select */ +#define ADC_EXTTRIG_ROUTINE_T1_TRGO CTL1_ETSRC(6) /*!< timer 1 TRGO event select */ +#define ADC_EXTTRIG_ROUTINE_T2_CH0 CTL1_ETSRC(7) /*!< timer 2 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T2_TRGO CTL1_ETSRC(8) /*!< timer 2 TRGO event select */ +#define ADC_EXTTRIG_ROUTINE_T3_CH3 CTL1_ETSRC(9) /*!< timer 3 CC3 event select */ +#define ADC_EXTTRIG_ROUTINE_T4_CH0 CTL1_ETSRC(10) /*!< timer 4 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T4_CH1 CTL1_ETSRC(11) /*!< timer 4 CC1 event select */ +#define ADC_EXTTRIG_ROUTINE_T4_CH2 CTL1_ETSRC(12) /*!< timer 4 CC2 event select */ +#define ADC_EXTTRIG_ROUTINE_T7_CH0 CTL1_ETSRC(13) /*!< timer 7 CC0 event select */ +#define ADC_EXTTRIG_ROUTINE_T7_TRGO CTL1_ETSRC(14) /*!< timer 7 TRGO event select */ +#define ADC_EXTTRIG_ROUTINE_EXTI_11 CTL1_ETSRC(15) /*!< extiline 11 select */ + +/* ADC external trigger select for inserted channel */ +#define CTL1_ETSIC(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(0) /*!< timer0 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(1) /*!< timer0 TRGO event */ +#define ADC_EXTTRIG_INSERTED_T1_CH0 CTL1_ETSIC(2) /*!< timer1 capture compare 0 */ +#define ADC_EXTTRIG_INSERTED_T1_TRGO CTL1_ETSIC(3) /*!< timer1 TRGO event */ +#define ADC_EXTTRIG_INSERTED_T2_CH1 CTL1_ETSIC(4) /*!< timer2 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(5) /*!< timer2 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T3_CH0 CTL1_ETSIC(6) /*!< timer3 capture compare 0 */ +#define ADC_EXTTRIG_INSERTED_T3_CH1 CTL1_ETSIC(7) /*!< timer3 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T3_CH2 CTL1_ETSIC(8) /*!< timer3 capture compare 2 */ +#define ADC_EXTTRIG_INSERTED_T3_TRGO CTL1_ETSIC(9) /*!< timer3 capture compare TRGO */ +#define ADC_EXTTRIG_INSERTED_T4_CH3 CTL1_ETSIC(10) /*!< timer4 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_T4_TRGO CTL1_ETSIC(11) /*!< timer4 capture compare TRGO */ +#define ADC_EXTTRIG_INSERTED_T7_CH1 CTL1_ETSIC(12) /*!< timer7 capture compare 1 */ +#define ADC_EXTTRIG_INSERTED_T7_CH2 CTL1_ETSIC(13) /*!< timer7 capture compare 2 */ +#define ADC_EXTTRIG_INSERTED_T7_CH3 CTL1_ETSIC(14) /*!< timer7 capture compare 3 */ +#define ADC_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(15) /*!< external interrupt line 15 */ + +/* ADC channel sample time */ +#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_SAMPTX_SPT bit field */ +#define ADC_SAMPLETIME_3 SAMPTX_SPT(0) /*!< 3 sampling cycles */ +#define ADC_SAMPLETIME_15 SAMPTX_SPT(1) /*!< 15 sampling cycles */ +#define ADC_SAMPLETIME_28 SAMPTX_SPT(2) /*!< 28 sampling cycles */ +#define ADC_SAMPLETIME_56 SAMPTX_SPT(3) /*!< 56 sampling cycles */ +#define ADC_SAMPLETIME_84 SAMPTX_SPT(4) /*!< 84 sampling cycles */ +#define ADC_SAMPLETIME_112 SAMPTX_SPT(5) /*!< 112 sampling cycles */ +#define ADC_SAMPLETIME_144 SAMPTX_SPT(6) /*!< 144 sampling cycles */ +#define ADC_SAMPLETIME_480 SAMPTX_SPT(7) /*!< 480 sampling cycles */ + +/* adc_ioffx register value */ +#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_IOFFX_IOFF bit field */ + +/* adc_wdht register value */ +#define WDHT_WDHT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDHT_WDHT bit field */ + +/* adc_wdlt register value */ +#define WDLT_WDLT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) /*!< write value to ADC_WDLT_WDLT bit field */ + +/* adc_rsqx register value */ +#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_RSQ0_RL bit field */ + +/* adc_isq register value */ +#define ISQ_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) /*!< write value to ADC_ISQ_IL bit field */ + +/* adc_ovsampctl register value */ +/* ADC resolution */ +#define CTL0_DRES(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) /*!< write value to ADC_CTL0_DRES bit field */ +#define ADC_RESOLUTION_12B CTL0_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B CTL0_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B CTL0_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B CTL0_DRES(3) /*!< 6-bit ADC resolution */ + +/* oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */ +#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */ + +/* oversampling ratio */ +#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */ +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ + +/* 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 */ + +/* ADC channel sequence definitions */ +#define ADC_ROUTINE_CHANNEL ((uint8_t)0x01U) /*!< adc routine sequence */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc inserted sequence */ +#define ADC_ROUTINE_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both routine and inserted sequence */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of routine & inserted sequence */ + +/* 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 */ + +/* ADC interrupt flag */ +#define ADC_INT_WDE ADC_CTL0_WDEIE /*!< analog watchdog event interrupt */ +#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< end of sequence conversion interrupt */ +#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< end of inserted sequence conversion interrupt */ +#define ADC_INT_ROVF ADC_CTL0_ROVFIE /*!< routine data register overflow */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */ +#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion interrupt */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion interrupt */ +#define ADC_INT_FLAG_ROVF ADC_STAT_ROVF /*!< routine data register overflow */ + +/* configure the ADC clock for all the ADCs */ +#define SYNCCTL_ADCCK(regval) (BITS(16,18) & ((uint32_t)(regval) << 16)) +#define ADC_ADCCK_PCLK2_DIV2 SYNCCTL_ADCCK(0) /*!< PCLK2 div2 */ +#define ADC_ADCCK_PCLK2_DIV4 SYNCCTL_ADCCK(1) /*!< PCLK2 div4 */ +#define ADC_ADCCK_PCLK2_DIV6 SYNCCTL_ADCCK(2) /*!< PCLK2 div6 */ +#define ADC_ADCCK_PCLK2_DIV8 SYNCCTL_ADCCK(3) /*!< PCLK2 div8 */ +#define ADC_ADCCK_HCLK_DIV5 SYNCCTL_ADCCK(4) /*!< HCLK div5 */ +#define ADC_ADCCK_HCLK_DIV6 SYNCCTL_ADCCK(5) /*!< HCLK div6 */ +#define ADC_ADCCK_HCLK_DIV10 SYNCCTL_ADCCK(6) /*!< HCLK div10 */ +#define ADC_ADCCK_HCLK_DIV20 SYNCCTL_ADCCK(7) /*!< HCLK div20 */ + +/* ADC synchronization delay */ +#define ADC_SYNC_DELAY_5CYCLE ((uint32_t)0x00000000U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 5 ADC clock cycles. */ +#define ADC_SYNC_DELAY_6CYCLE ((uint32_t)0x00000100U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 6 ADC clock cycles. */ +#define ADC_SYNC_DELAY_7CYCLE ((uint32_t)0x00000200U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 7 ADC clock cycles. */ +#define ADC_SYNC_DELAY_8CYCLE ((uint32_t)0x00000300U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 8 ADC clock cycles. */ +#define ADC_SYNC_DELAY_9CYCLE ((uint32_t)0x00000400U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 9 ADC clock cycles. */ +#define ADC_SYNC_DELAY_10CYCLE ((uint32_t)0x00000500U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 10 ADC clock cycles. */ +#define ADC_SYNC_DELAY_11CYCLE ((uint32_t)0x00000600U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 11 ADC clock cycles. */ +#define ADC_SYNC_DELAY_12CYCLE ((uint32_t)0x00000700U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 12 ADC clock cycles. */ +#define ADC_SYNC_DELAY_13CYCLE ((uint32_t)0x00000800U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 13 ADC clock cycles. */ +#define ADC_SYNC_DELAY_14CYCLE ((uint32_t)0x00000900U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 14 ADC clock cycles. */ +#define ADC_SYNC_DELAY_15CYCLE ((uint32_t)0x00000A00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 15 ADC clock cycles. */ +#define ADC_SYNC_DELAY_16CYCLE ((uint32_t)0x00000B00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 16 ADC clock cycles. */ +#define ADC_SYNC_DELAY_17CYCLE ((uint32_t)0x00000C00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 17 ADC clock cycles. */ +#define ADC_SYNC_DELAY_18CYCLE ((uint32_t)0x00000D00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 18 ADC clock cycles. */ +#define ADC_SYNC_DELAY_19CYCLE ((uint32_t)0x00000E00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 19 ADC clock cycles. */ +#define ADC_SYNC_DELAY_20CYCLE ((uint32_t)0x00000F00U) /*!< the delay between 2 sampling phases in ADC synchronization modes to 20 ADC clock cycles. */ + +/* ADC synchronization DMA mode selection */ +#define ADC_SYNC_DMA_DISABLE ((uint32_t)0x00000000U) /*!< ADC synchronization DMA disabled */ +#define ADC_SYNC_DMA_MODE0 ((uint32_t)0x00004000U) /*!< ADC synchronization DMA mode 0 */ +#define ADC_SYNC_DMA_MODE1 ((uint32_t)0x00008000U) /*!< ADC synchronization DMA mode 1 */ + +/* end of conversion mode */ +#define ADC_EOC_SET_SEQUENCE ((uint8_t)0x00U) /*!< only at the end of a sequence of routine conversions, the EOC bit is set */ +#define ADC_EOC_SET_CONVERSION ((uint8_t)0x01U) /*!< at the end of each routine conversion, the EOC bit is set */ + +/* function declarations */ +/* initialization config */ +/* reset ADC */ +void adc_deinit(void); +/* configure the ADC clock for all the ADCs */ +void adc_clock_config(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); +/* ADC calibration and reset calibration */ +void adc_calibration_enable(uint32_t adc_periph); +/* configure temperature sensor and internal reference voltage channel or VBAT channel function */ +void adc_channel_16_to_18(uint32_t function, ControlStatus newvalue); +/* configure ADC resolution */ +void adc_resolution_config(uint32_t adc_periph, uint32_t resolution); +/* configure ADC oversample mode */ +void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint8_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); + +/* 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 routine 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); + +/* routine sequence and inserted sequence config */ +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_sequence , uint8_t length); +/* configure the length of routine sequence or inserted sequence */ +void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_sequence , uint32_t length); +/* configure ADC routine channel */ +void adc_routine_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 , uint16_t offset); +/* configure ADC external trigger source */ +void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_sequence , uint32_t external_trigger_source); +/* enable ADC external trigger */ +void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_sequence , uint32_t trigger_mode); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_sequence); +/* configure end of conversion mode */ +void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection); + +/* get channel data */ +/* read ADC routine data register */ +uint16_t adc_routine_data_read(uint32_t adc_periph); +/* read ADC inserted data register */ +uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel); + +/* watchdog config */ +/* disable ADC analog watchdog single channel */ +void adc_watchdog_single_channel_disable(uint32_t adc_periph ); +/* enable ADC analog watchdog single channel */ +void adc_watchdog_single_channel_enable(uint32_t adc_periph , uint8_t adc_channel); +/* configure ADC analog watchdog sequence */ +void adc_watchdog_sequence_channel_enable(uint32_t adc_periph , uint8_t adc_sequence); +/* disable ADC analog watchdog */ +void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_sequence); +/* configure ADC analog watchdog threshold */ +void adc_watchdog_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold); + +/* interrupt & flag functions */ +/* get the ADC flag bits */ +FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t adc_flag); +/* clear the ADC flag bits */ +void adc_flag_clear(uint32_t adc_periph , uint32_t adc_flag); +/* get the bit state of ADCx software start conversion */ +FlagStatus adc_routine_software_startconv_flag_get(uint32_t adc_periph); +/* get the bit state of ADCx software inserted channel start conversion */ +FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph); +/* get the ADC interrupt bits */ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t adc_interrupt); +/* clear the ADC flag */ +void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t adc_interrupt); +/* enable ADC interrupt */ +void adc_interrupt_enable(uint32_t adc_periph , uint32_t adc_interrupt); +/* disable ADC interrupt */ +void adc_interrupt_disable(uint32_t adc_periph , uint32_t adc_interrupt); + +/* 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 is disabled after the end of transfer signal from DMA controller is detected */ +void adc_sync_dma_request_after_last_enable(void); +/* configure ADC sync DMA engine issues requests according to the SYNCDMA bits */ +void adc_sync_dma_request_after_last_disable(void); +/* read ADC sync routine data register */ +uint32_t adc_sync_routine_data_read(void); + +#endif /* GD32F4XX_ADC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_can.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_can.h new file mode 100644 index 000000000..192950f3d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_can.h @@ -0,0 +1,750 @@ +/*! + \file gd32f4xx_can.h + \brief definitions for the CAN + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2019-11-27, V2.0.1, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_CAN_H +#define GD32F4XX_CAN_H + +#include "gd32f4xx.h" + +/* CAN definitions */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN0 + 0x00000400U) /*!< CAN1 base address */ + +/* registers definitions */ +#define CAN_CTL(canx) REG32((canx) + 0x00000000U) /*!< CAN control register */ +#define CAN_STAT(canx) REG32((canx) + 0x00000004U) /*!< CAN status register */ +#define CAN_TSTAT(canx) REG32((canx) + 0x00000008U) /*!< CAN transmit status register*/ +#define CAN_RFIFO0(canx) REG32((canx) + 0x0000000CU) /*!< CAN receive FIFO0 register */ +#define CAN_RFIFO1(canx) REG32((canx) + 0x00000010U) /*!< CAN receive FIFO1 register */ +#define CAN_INTEN(canx) REG32((canx) + 0x00000014U) /*!< CAN interrupt enable register */ +#define CAN_ERR(canx) REG32((canx) + 0x00000018U) /*!< CAN error register */ +#define CAN_BT(canx) REG32((canx) + 0x0000001CU) /*!< CAN bit timing register */ +#define CAN_TMI0(canx) REG32((canx) + 0x00000180U) /*!< CAN transmit mailbox0 identifier register */ +#define CAN_TMP0(canx) REG32((canx) + 0x00000184U) /*!< CAN transmit mailbox0 property register */ +#define CAN_TMDATA00(canx) REG32((canx) + 0x00000188U) /*!< CAN transmit mailbox0 data0 register */ +#define CAN_TMDATA10(canx) REG32((canx) + 0x0000018CU) /*!< CAN transmit mailbox0 data1 register */ +#define CAN_TMI1(canx) REG32((canx) + 0x00000190U) /*!< CAN transmit mailbox1 identifier register */ +#define CAN_TMP1(canx) REG32((canx) + 0x00000194U) /*!< CAN transmit mailbox1 property register */ +#define CAN_TMDATA01(canx) REG32((canx) + 0x00000198U) /*!< CAN transmit mailbox1 data0 register */ +#define CAN_TMDATA11(canx) REG32((canx) + 0x0000019CU) /*!< CAN transmit mailbox1 data1 register */ +#define CAN_TMI2(canx) REG32((canx) + 0x000001A0U) /*!< CAN transmit mailbox2 identifier register */ +#define CAN_TMP2(canx) REG32((canx) + 0x000001A4U) /*!< CAN transmit mailbox2 property register */ +#define CAN_TMDATA02(canx) REG32((canx) + 0x000001A8U) /*!< CAN transmit mailbox2 data0 register */ +#define CAN_TMDATA12(canx) REG32((canx) + 0x000001ACU) /*!< CAN transmit mailbox2 data1 register */ +#define CAN_RFIFOMI0(canx) REG32((canx) + 0x000001B0U) /*!< CAN receive FIFO0 mailbox identifier register */ +#define CAN_RFIFOMP0(canx) REG32((canx) + 0x000001B4U) /*!< CAN receive FIFO0 mailbox property register */ +#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x000001B8U) /*!< CAN receive FIFO0 mailbox data0 register */ +#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x000001BCU) /*!< CAN receive FIFO0 mailbox data1 register */ +#define CAN_RFIFOMI1(canx) REG32((canx) + 0x000001C0U) /*!< CAN receive FIFO1 mailbox identifier register */ +#define CAN_RFIFOMP1(canx) REG32((canx) + 0x000001C4U) /*!< CAN receive FIFO1 mailbox property register */ +#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x000001C8U) /*!< CAN receive FIFO1 mailbox data0 register */ +#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x000001CCU) /*!< CAN receive FIFO1 mailbox data1 register */ +#define CAN_FCTL(canx) REG32((canx) + 0x00000200U) /*!< CAN filter control register */ +#define CAN_FMCFG(canx) REG32((canx) + 0x00000204U) /*!< CAN filter mode register */ +#define CAN_FSCFG(canx) REG32((canx) + 0x0000020CU) /*!< CAN filter scale register */ +#define CAN_FAFIFO(canx) REG32((canx) + 0x00000214U) /*!< CAN filter associated FIFO register */ +#define CAN_FW(canx) REG32((canx) + 0x0000021CU) /*!< CAN filter working register */ +#define CAN_F0DATA0(canx) REG32((canx) + 0x00000240U) /*!< CAN filter 0 data 0 register */ +#define CAN_F1DATA0(canx) REG32((canx) + 0x00000248U) /*!< CAN filter 1 data 0 register */ +#define CAN_F2DATA0(canx) REG32((canx) + 0x00000250U) /*!< CAN filter 2 data 0 register */ +#define CAN_F3DATA0(canx) REG32((canx) + 0x00000258U) /*!< CAN filter 3 data 0 register */ +#define CAN_F4DATA0(canx) REG32((canx) + 0x00000260U) /*!< CAN filter 4 data 0 register */ +#define CAN_F5DATA0(canx) REG32((canx) + 0x00000268U) /*!< CAN filter 5 data 0 register */ +#define CAN_F6DATA0(canx) REG32((canx) + 0x00000270U) /*!< CAN filter 6 data 0 register */ +#define CAN_F7DATA0(canx) REG32((canx) + 0x00000278U) /*!< CAN filter 7 data 0 register */ +#define CAN_F8DATA0(canx) REG32((canx) + 0x00000280U) /*!< CAN filter 8 data 0 register */ +#define CAN_F9DATA0(canx) REG32((canx) + 0x00000288U) /*!< CAN filter 9 data 0 register */ +#define CAN_F10DATA0(canx) REG32((canx) + 0x00000290U) /*!< CAN filter 10 data 0 register */ +#define CAN_F11DATA0(canx) REG32((canx) + 0x00000298U) /*!< CAN filter 11 data 0 register */ +#define CAN_F12DATA0(canx) REG32((canx) + 0x000002A0U) /*!< CAN filter 12 data 0 register */ +#define CAN_F13DATA0(canx) REG32((canx) + 0x000002A8U) /*!< CAN filter 13 data 0 register */ +#define CAN_F14DATA0(canx) REG32((canx) + 0x000002B0U) /*!< CAN filter 14 data 0 register */ +#define CAN_F15DATA0(canx) REG32((canx) + 0x000002B8U) /*!< CAN filter 15 data 0 register */ +#define CAN_F16DATA0(canx) REG32((canx) + 0x000002C0U) /*!< CAN filter 16 data 0 register */ +#define CAN_F17DATA0(canx) REG32((canx) + 0x000002C8U) /*!< CAN filter 17 data 0 register */ +#define CAN_F18DATA0(canx) REG32((canx) + 0x000002D0U) /*!< CAN filter 18 data 0 register */ +#define CAN_F19DATA0(canx) REG32((canx) + 0x000002D8U) /*!< CAN filter 19 data 0 register */ +#define CAN_F20DATA0(canx) REG32((canx) + 0x000002E0U) /*!< CAN filter 20 data 0 register */ +#define CAN_F21DATA0(canx) REG32((canx) + 0x000002E8U) /*!< CAN filter 21 data 0 register */ +#define CAN_F22DATA0(canx) REG32((canx) + 0x000002F0U) /*!< CAN filter 22 data 0 register */ +#define CAN_F23DATA0(canx) REG32((canx) + 0x000003F8U) /*!< CAN filter 23 data 0 register */ +#define CAN_F24DATA0(canx) REG32((canx) + 0x00000300U) /*!< CAN filter 24 data 0 register */ +#define CAN_F25DATA0(canx) REG32((canx) + 0x00000308U) /*!< CAN filter 25 data 0 register */ +#define CAN_F26DATA0(canx) REG32((canx) + 0x00000310U) /*!< CAN filter 26 data 0 register */ +#define CAN_F27DATA0(canx) REG32((canx) + 0x00000318U) /*!< CAN filter 27 data 0 register */ +#define CAN_F0DATA1(canx) REG32((canx) + 0x00000244U) /*!< CAN filter 0 data 1 register */ +#define CAN_F1DATA1(canx) REG32((canx) + 0x0000024CU) /*!< CAN filter 1 data 1 register */ +#define CAN_F2DATA1(canx) REG32((canx) + 0x00000254U) /*!< CAN filter 2 data 1 register */ +#define CAN_F3DATA1(canx) REG32((canx) + 0x0000025CU) /*!< CAN filter 3 data 1 register */ +#define CAN_F4DATA1(canx) REG32((canx) + 0x00000264U) /*!< CAN filter 4 data 1 register */ +#define CAN_F5DATA1(canx) REG32((canx) + 0x0000026CU) /*!< CAN filter 5 data 1 register */ +#define CAN_F6DATA1(canx) REG32((canx) + 0x00000274U) /*!< CAN filter 6 data 1 register */ +#define CAN_F7DATA1(canx) REG32((canx) + 0x0000027CU) /*!< CAN filter 7 data 1 register */ +#define CAN_F8DATA1(canx) REG32((canx) + 0x00000284U) /*!< CAN filter 8 data 1 register */ +#define CAN_F9DATA1(canx) REG32((canx) + 0x0000028CU) /*!< CAN filter 9 data 1 register */ +#define CAN_F10DATA1(canx) REG32((canx) + 0x00000294U) /*!< CAN filter 10 data 1 register */ +#define CAN_F11DATA1(canx) REG32((canx) + 0x0000029CU) /*!< CAN filter 11 data 1 register */ +#define CAN_F12DATA1(canx) REG32((canx) + 0x000002A4U) /*!< CAN filter 12 data 1 register */ +#define CAN_F13DATA1(canx) REG32((canx) + 0x000002ACU) /*!< CAN filter 13 data 1 register */ +#define CAN_F14DATA1(canx) REG32((canx) + 0x000002B4U) /*!< CAN filter 14 data 1 register */ +#define CAN_F15DATA1(canx) REG32((canx) + 0x000002BCU) /*!< CAN filter 15 data 1 register */ +#define CAN_F16DATA1(canx) REG32((canx) + 0x000002C4U) /*!< CAN filter 16 data 1 register */ +#define CAN_F17DATA1(canx) REG32((canx) + 0x0000024CU) /*!< CAN filter 17 data 1 register */ +#define CAN_F18DATA1(canx) REG32((canx) + 0x000002D4U) /*!< CAN filter 18 data 1 register */ +#define CAN_F19DATA1(canx) REG32((canx) + 0x000002DCU) /*!< CAN filter 19 data 1 register */ +#define CAN_F20DATA1(canx) REG32((canx) + 0x000002E4U) /*!< CAN filter 20 data 1 register */ +#define CAN_F21DATA1(canx) REG32((canx) + 0x000002ECU) /*!< CAN filter 21 data 1 register */ +#define CAN_F22DATA1(canx) REG32((canx) + 0x000002F4U) /*!< CAN filter 22 data 1 register */ +#define CAN_F23DATA1(canx) REG32((canx) + 0x000002FCU) /*!< CAN filter 23 data 1 register */ +#define CAN_F24DATA1(canx) REG32((canx) + 0x00000304U) /*!< CAN filter 24 data 1 register */ +#define CAN_F25DATA1(canx) REG32((canx) + 0x0000030CU) /*!< CAN filter 25 data 1 register */ +#define CAN_F26DATA1(canx) REG32((canx) + 0x00000314U) /*!< CAN filter 26 data 1 register */ +#define CAN_F27DATA1(canx) REG32((canx) + 0x0000031CU) /*!< CAN filter 27 data 1 register */ + +/* CAN transmit mailbox bank */ +#define CAN_TMI(canx, bank) REG32((canx) + 0x180U + ((bank) * 0x10U)) /*!< CAN transmit mailbox identifier register */ +#define CAN_TMP(canx, bank) REG32((canx) + 0x184U + ((bank) * 0x10U)) /*!< CAN transmit mailbox property register */ +#define CAN_TMDATA0(canx, bank) REG32((canx) + 0x188U + ((bank) * 0x10U)) /*!< CAN transmit mailbox data0 register */ +#define CAN_TMDATA1(canx, bank) REG32((canx) + 0x18CU + ((bank) * 0x10U)) /*!< CAN transmit mailbox data1 register */ + +/* CAN filter bank */ +#define CAN_FDATA0(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x0U) /*!< CAN filter data 0 register */ +#define CAN_FDATA1(canx, bank) REG32((canx) + 0x240U + ((bank) * 0x8U) + 0x4U) /*!< CAN filter data 1 register */ + +/* CAN receive FIFO mailbox bank */ +#define CAN_RFIFOMI(canx, bank) REG32((canx) + 0x1B0U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox identifier register */ +#define CAN_RFIFOMP(canx, bank) REG32((canx) + 0x1B4U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox property register */ +#define CAN_RFIFOMDATA0(canx, bank) REG32((canx) + 0x1B8U + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data0 register */ +#define CAN_RFIFOMDATA1(canx, bank) REG32((canx) + 0x1BCU + ((bank) * 0x10U)) /*!< CAN receive FIFO mailbox data1 register */ + +/* bits definitions */ +/* CAN_CTL */ +#define CAN_CTL_IWMOD BIT(0) /*!< initial working mode */ +#define CAN_CTL_SLPWMOD BIT(1) /*!< sleep working mode */ +#define CAN_CTL_TFO BIT(2) /*!< transmit FIFO order */ +#define CAN_CTL_RFOD BIT(3) /*!< receive FIFO overwrite disable */ +#define CAN_CTL_ARD BIT(4) /*!< automatic retransmission disable */ +#define CAN_CTL_AWU BIT(5) /*!< automatic wakeup */ +#define CAN_CTL_ABOR BIT(6) /*!< automatic bus-off recovery */ +#define CAN_CTL_TTC BIT(7) /*!< time triggered communication */ +#define CAN_CTL_SWRST BIT(15) /*!< CAN software reset */ +#define CAN_CTL_DFZ BIT(16) /*!< CAN debug freeze */ + +/* CAN_STAT */ +#define CAN_STAT_IWS BIT(0) /*!< initial working state */ +#define CAN_STAT_SLPWS BIT(1) /*!< sleep working state */ +#define CAN_STAT_ERRIF BIT(2) /*!< error interrupt flag*/ +#define CAN_STAT_WUIF BIT(3) /*!< status change interrupt flag of wakeup from sleep working mode */ +#define CAN_STAT_SLPIF BIT(4) /*!< status change interrupt flag of sleep working mode entering */ +#define CAN_STAT_TS BIT(8) /*!< transmitting state */ +#define CAN_STAT_RS BIT(9) /*!< receiving state */ +#define CAN_STAT_LASTRX BIT(10) /*!< last sample value of rx pin */ +#define CAN_STAT_RXL BIT(11) /*!< CAN rx signal */ + +/* CAN_TSTAT */ +#define CAN_TSTAT_MTF0 BIT(0) /*!< mailbox0 transmit finished */ +#define CAN_TSTAT_MTFNERR0 BIT(1) /*!< mailbox0 transmit finished and no error */ +#define CAN_TSTAT_MAL0 BIT(2) /*!< mailbox0 arbitration lost */ +#define CAN_TSTAT_MTE0 BIT(3) /*!< mailbox0 transmit error */ +#define CAN_TSTAT_MST0 BIT(7) /*!< mailbox0 stop transmitting */ +#define CAN_TSTAT_MTF1 BIT(8) /*!< mailbox1 transmit finished */ +#define CAN_TSTAT_MTFNERR1 BIT(9) /*!< mailbox1 transmit finished and no error */ +#define CAN_TSTAT_MAL1 BIT(10) /*!< mailbox1 arbitration lost */ +#define CAN_TSTAT_MTE1 BIT(11) /*!< mailbox1 transmit error */ +#define CAN_TSTAT_MST1 BIT(15) /*!< mailbox1 stop transmitting */ +#define CAN_TSTAT_MTF2 BIT(16) /*!< mailbox2 transmit finished */ +#define CAN_TSTAT_MTFNERR2 BIT(17) /*!< mailbox2 transmit finished and no error */ +#define CAN_TSTAT_MAL2 BIT(18) /*!< mailbox2 arbitration lost */ +#define CAN_TSTAT_MTE2 BIT(19) /*!< mailbox2 transmit error */ +#define CAN_TSTAT_MST2 BIT(23) /*!< mailbox2 stop transmitting */ +#define CAN_TSTAT_NUM BITS(24,25) /*!< mailbox number */ +#define CAN_TSTAT_TME0 BIT(26) /*!< transmit mailbox0 empty */ +#define CAN_TSTAT_TME1 BIT(27) /*!< transmit mailbox1 empty */ +#define CAN_TSTAT_TME2 BIT(28) /*!< transmit mailbox2 empty */ +#define CAN_TSTAT_TMLS0 BIT(29) /*!< last sending priority flag for mailbox0 */ +#define CAN_TSTAT_TMLS1 BIT(30) /*!< last sending priority flag for mailbox1 */ +#define CAN_TSTAT_TMLS2 BIT(31) /*!< last sending priority flag for mailbox2 */ + +/* CAN_RFIFO0 */ +#define CAN_RFIFO0_RFL0 BITS(0,1) /*!< receive FIFO0 length */ +#define CAN_RFIFO0_RFF0 BIT(3) /*!< receive FIFO0 full */ +#define CAN_RFIFO0_RFO0 BIT(4) /*!< receive FIFO0 overfull */ +#define CAN_RFIFO0_RFD0 BIT(5) /*!< receive FIFO0 dequeue */ + +/* CAN_RFIFO1 */ +#define CAN_RFIFO1_RFL1 BITS(0,1) /*!< receive FIFO1 length */ +#define CAN_RFIFO1_RFF1 BIT(3) /*!< receive FIFO1 full */ +#define CAN_RFIFO1_RFO1 BIT(4) /*!< receive FIFO1 overfull */ +#define CAN_RFIFO1_RFD1 BIT(5) /*!< receive FIFO1 dequeue */ + +/* CAN_INTEN */ +#define CAN_INTEN_TMEIE BIT(0) /*!< transmit mailbox empty interrupt enable */ +#define CAN_INTEN_RFNEIE0 BIT(1) /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INTEN_RFFIE0 BIT(2) /*!< receive FIFO0 full interrupt enable */ +#define CAN_INTEN_RFOIE0 BIT(3) /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INTEN_RFNEIE1 BIT(4) /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INTEN_RFFIE1 BIT(5) /*!< receive FIFO1 full interrupt enable */ +#define CAN_INTEN_RFOIE1 BIT(6) /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INTEN_WERRIE BIT(8) /*!< warning error interrupt enable */ +#define CAN_INTEN_PERRIE BIT(9) /*!< passive error interrupt enable */ +#define CAN_INTEN_BOIE BIT(10) /*!< bus-off interrupt enable */ +#define CAN_INTEN_ERRNIE BIT(11) /*!< error number interrupt enable */ +#define CAN_INTEN_ERRIE BIT(15) /*!< error interrupt enable */ +#define CAN_INTEN_WIE BIT(16) /*!< wakeup interrupt enable */ +#define CAN_INTEN_SLPWIE BIT(17) /*!< sleep working interrupt enable */ + +/* CAN_ERR */ +#define CAN_ERR_WERR BIT(0) /*!< warning error */ +#define CAN_ERR_PERR BIT(1) /*!< passive error */ +#define CAN_ERR_BOERR BIT(2) /*!< bus-off error */ +#define CAN_ERR_ERRN BITS(4,6) /*!< error number */ +#define CAN_ERR_TECNT BITS(16,23) /*!< transmit error count */ +#define CAN_ERR_RECNT BITS(24,31) /*!< receive error count */ + +/* CAN_BT */ +#define CAN_BT_BAUDPSC BITS(0,9) /*!< baudrate prescaler */ +#define CAN_BT_BS1 BITS(16,19) /*!< bit segment 1 */ +#define CAN_BT_BS2 BITS(20,22) /*!< bit segment 2 */ +#define CAN_BT_SJW BITS(24,25) /*!< resynchronization jump width */ +#define CAN_BT_LCMOD BIT(30) /*!< loopback communication mode */ +#define CAN_BT_SCMOD BIT(31) /*!< silent communication mode */ + +/* CAN_TMIx */ +#define CAN_TMI_TEN BIT(0) /*!< transmit enable */ +#define CAN_TMI_FT BIT(1) /*!< frame type */ +#define CAN_TMI_FF BIT(2) /*!< frame format */ +#define CAN_TMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_TMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_TMPx */ +#define CAN_TMP_DLENC BITS(0,3) /*!< data length code */ +#define CAN_TMP_TSEN BIT(8) /*!< time stamp enable */ +#define CAN_TMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_TMDATA0x */ +#define CAN_TMDATA0_DB0 BITS(0,7) /*!< transmit data byte 0 */ +#define CAN_TMDATA0_DB1 BITS(8,15) /*!< transmit data byte 1 */ +#define CAN_TMDATA0_DB2 BITS(16,23) /*!< transmit data byte 2 */ +#define CAN_TMDATA0_DB3 BITS(24,31) /*!< transmit data byte 3 */ + +/* CAN_TMDATA1x */ +#define CAN_TMDATA1_DB4 BITS(0,7) /*!< transmit data byte 4 */ +#define CAN_TMDATA1_DB5 BITS(8,15) /*!< transmit data byte 5 */ +#define CAN_TMDATA1_DB6 BITS(16,23) /*!< transmit data byte 6 */ +#define CAN_TMDATA1_DB7 BITS(24,31) /*!< transmit data byte 7 */ + +/* CAN_RFIFOMIx */ +#define CAN_RFIFOMI_FT BIT(1) /*!< frame type */ +#define CAN_RFIFOMI_FF BIT(2) /*!< frame format */ +#define CAN_RFIFOMI_EFID BITS(3,31) /*!< the frame identifier */ +#define CAN_RFIFOMI_SFID BITS(21,31) /*!< the frame identifier */ + +/* CAN_RFIFOMPx */ +#define CAN_RFIFOMP_DLENC BITS(0,3) /*!< receive data length code */ +#define CAN_RFIFOMP_FI BITS(8,15) /*!< filter index */ +#define CAN_RFIFOMP_TS BITS(16,31) /*!< time stamp */ + +/* CAN_RFIFOMDATA0x */ +#define CAN_RFIFOMDATA0_DB0 BITS(0,7) /*!< receive data byte 0 */ +#define CAN_RFIFOMDATA0_DB1 BITS(8,15) /*!< receive data byte 1 */ +#define CAN_RFIFOMDATA0_DB2 BITS(16,23) /*!< receive data byte 2 */ +#define CAN_RFIFOMDATA0_DB3 BITS(24,31) /*!< receive data byte 3 */ + +/* CAN_RFIFOMDATA1x */ +#define CAN_RFIFOMDATA1_DB4 BITS(0,7) /*!< receive data byte 4 */ +#define CAN_RFIFOMDATA1_DB5 BITS(8,15) /*!< receive data byte 5 */ +#define CAN_RFIFOMDATA1_DB6 BITS(16,23) /*!< receive data byte 6 */ +#define CAN_RFIFOMDATA1_DB7 BITS(24,31) /*!< receive data byte 7 */ + +/* CAN_FCTL */ +#define CAN_FCTL_FLD BIT(0) /*!< filter lock disable */ +#define CAN_FCTL_HBC1F BITS(8,13) /*!< header bank of CAN1 filter */ + +/* CAN_FMCFG */ +#define CAN_FMCFG_FMOD(regval) BIT(regval) /*!< filter mode, list or mask */ + +/* CAN_FSCFG */ +#define CAN_FSCFG_FS(regval) BIT(regval) /*!< filter scale, 32 bits or 16 bits */ + +/* CAN_FAFIFO */ +#define CAN_FAFIFOR_FAF(regval) BIT(regval) /*!< filter associated with FIFO */ + +/* CAN_FW */ +#define CAN_FW_FW(regval) BIT(regval) /*!< filter working */ + +/* CAN_FxDATAy */ +#define CAN_FDATA_FD(regval) BIT(regval) /*!< filter data */ + +/* constants definitions */ +/* define the CAN bit position and its register index offset */ +#define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define CAN_REG_VAL(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 6))) +#define CAN_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +#define CAN_REGIDX_BITS(regidx, bitpos0, bitpos1) (((uint32_t)(regidx) << 12) | ((uint32_t)(bitpos0) << 6) | (uint32_t)(bitpos1)) +#define CAN_REG_VALS(canx, offset) (REG32((canx) + ((uint32_t)(offset) >> 12))) +#define CAN_BIT_POS0(val) (((uint32_t)(val) >> 6) & 0x1FU) +#define CAN_BIT_POS1(val) ((uint32_t)(val) & 0x1FU) + +/* register offset */ +#define STAT_REG_OFFSET ((uint8_t)0x04U) /*!< STAT register offset */ +#define TSTAT_REG_OFFSET ((uint8_t)0x08U) /*!< TSTAT register offset */ +#define RFIFO0_REG_OFFSET ((uint8_t)0x0CU) /*!< RFIFO0 register offset */ +#define RFIFO1_REG_OFFSET ((uint8_t)0x10U) /*!< RFIFO1 register offset */ +#define ERR_REG_OFFSET ((uint8_t)0x18U) /*!< ERR register offset */ + +/* CAN flags */ +typedef enum { + /* flags in STAT register */ + CAN_FLAG_RXL = CAN_REGIDX_BIT(STAT_REG_OFFSET, 11U), /*!< RX level */ + CAN_FLAG_LASTRX = CAN_REGIDX_BIT(STAT_REG_OFFSET, 10U), /*!< last sample value of RX pin */ + CAN_FLAG_RS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 9U), /*!< receiving state */ + CAN_FLAG_TS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 8U), /*!< transmitting state */ + CAN_FLAG_SLPIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< status change flag of entering sleep working mode */ + CAN_FLAG_WUIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< status change flag of wakeup from sleep working mode */ + CAN_FLAG_ERRIF = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< error flag */ + CAN_FLAG_SLPWS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 1U), /*!< sleep working state */ + CAN_FLAG_IWS = CAN_REGIDX_BIT(STAT_REG_OFFSET, 0U), /*!< initial working state */ + /* flags in TSTAT register */ + CAN_FLAG_TMLS2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 31U), /*!< transmit mailbox 2 last sending in TX FIFO */ + CAN_FLAG_TMLS1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 30U), /*!< transmit mailbox 1 last sending in TX FIFO */ + CAN_FLAG_TMLS0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 29U), /*!< transmit mailbox 0 last sending in TX FIFO */ + CAN_FLAG_TME2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 28U), /*!< transmit mailbox 2 empty */ + CAN_FLAG_TME1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 27U), /*!< transmit mailbox 1 empty */ + CAN_FLAG_TME0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 26U), /*!< transmit mailbox 0 empty */ + CAN_FLAG_MTE2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 19U), /*!< mailbox 2 transmit error */ + CAN_FLAG_MTE1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 11U), /*!< mailbox 1 transmit error */ + CAN_FLAG_MTE0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 3U), /*!< mailbox 0 transmit error */ + CAN_FLAG_MAL2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 18U), /*!< mailbox 2 arbitration lost */ + CAN_FLAG_MAL1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 10U), /*!< mailbox 1 arbitration lost */ + CAN_FLAG_MAL0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 2U), /*!< mailbox 0 arbitration lost */ + CAN_FLAG_MTFNERR2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 17U), /*!< mailbox 2 transmit finished with no error */ + CAN_FLAG_MTFNERR1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 9U), /*!< mailbox 1 transmit finished with no error */ + CAN_FLAG_MTFNERR0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 1U), /*!< mailbox 0 transmit finished with no error */ + CAN_FLAG_MTF2 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 16U), /*!< mailbox 2 transmit finished */ + CAN_FLAG_MTF1 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 8U), /*!< mailbox 1 transmit finished */ + CAN_FLAG_MTF0 = CAN_REGIDX_BIT(TSTAT_REG_OFFSET, 0U), /*!< mailbox 0 transmit finished */ + /* flags in RFIFO0 register */ + CAN_FLAG_RFO0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 4U), /*!< receive FIFO0 overfull */ + CAN_FLAG_RFF0 = CAN_REGIDX_BIT(RFIFO0_REG_OFFSET, 3U), /*!< receive FIFO0 full */ + /* flags in RFIFO1 register */ + CAN_FLAG_RFO1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 4U), /*!< receive FIFO1 overfull */ + CAN_FLAG_RFF1 = CAN_REGIDX_BIT(RFIFO1_REG_OFFSET, 3U), /*!< receive FIFO1 full */ + /* flags in ERR register */ + CAN_FLAG_BOERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 2U), /*!< bus-off error */ + CAN_FLAG_PERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 1U), /*!< passive error */ + CAN_FLAG_WERR = CAN_REGIDX_BIT(ERR_REG_OFFSET, 0U), /*!< warning error */ +} can_flag_enum; + +/* CAN interrupt flags */ +typedef enum { + /* interrupt flags in STAT register */ + CAN_INT_FLAG_SLPIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 4U, 17U), /*!< status change interrupt flag of sleep working mode entering */ + CAN_INT_FLAG_WUIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 3U, 16), /*!< status change interrupt flag of wakeup from sleep working mode */ + CAN_INT_FLAG_ERRIF = CAN_REGIDX_BITS(STAT_REG_OFFSET, 2U, 15), /*!< error interrupt flag */ + /* interrupt flags in TSTAT register */ + CAN_INT_FLAG_MTF2 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 16U, 0U), /*!< mailbox 2 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF1 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 8U, 0U), /*!< mailbox 1 transmit finished interrupt flag */ + CAN_INT_FLAG_MTF0 = CAN_REGIDX_BITS(TSTAT_REG_OFFSET, 0U, 0U), /*!< mailbox 0 transmit finished interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 4U, 3U), /*!< receive FIFO0 overfull interrupt flag */ + CAN_INT_FLAG_RFF0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 3U, 2U), /*!< receive FIFO0 full interrupt flag */ + CAN_INT_FLAG_RFL0 = CAN_REGIDX_BITS(RFIFO0_REG_OFFSET, 2U, 1U), /*!< receive FIFO0 not empty interrupt flag */ + /* interrupt flags in RFIFO0 register */ + CAN_INT_FLAG_RFO1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 4U, 6U), /*!< receive FIFO1 overfull interrupt flag */ + CAN_INT_FLAG_RFF1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 3U, 5U), /*!< receive FIFO1 full interrupt flag */ + CAN_INT_FLAG_RFL1 = CAN_REGIDX_BITS(RFIFO1_REG_OFFSET, 2U, 4U), /*!< receive FIFO1 not empty interrupt flag */ + /* interrupt flags in ERR register */ + CAN_INT_FLAG_ERRN = CAN_REGIDX_BITS(ERR_REG_OFFSET, 3U, 11U), /*!< error number interrupt flag */ + CAN_INT_FLAG_BOERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 2U, 10U), /*!< bus-off error interrupt flag */ + CAN_INT_FLAG_PERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 1U, 9U), /*!< passive error interrupt flag */ + CAN_INT_FLAG_WERR = CAN_REGIDX_BITS(ERR_REG_OFFSET, 0U, 8U), /*!< warning error interrupt flag */ +} can_interrupt_flag_enum; + +/* CAN initiliaze parameters structure */ +typedef struct { + uint8_t working_mode; /*!< CAN working mode */ + uint8_t resync_jump_width; /*!< CAN resynchronization jump width */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ + ControlStatus time_triggered; /*!< time triggered communication mode */ + ControlStatus auto_bus_off_recovery; /*!< automatic bus-off recovery */ + ControlStatus auto_wake_up; /*!< automatic wake-up mode */ + ControlStatus auto_retrans; /*!< automatic retransmission mode */ + ControlStatus rec_fifo_overwrite; /*!< receive FIFO overwrite mode */ + ControlStatus trans_fifo_order; /*!< transmit FIFO order */ + uint16_t prescaler; /*!< baudrate prescaler */ +} can_parameter_struct; + +/* CAN transmit message structure */ +typedef struct { + uint32_t tx_sfid; /*!< standard format frame identifier */ + uint32_t tx_efid; /*!< extended format frame identifier */ + uint8_t tx_ff; /*!< format of frame, standard or extended format */ + uint8_t tx_ft; /*!< type of frame, data or remote */ + uint8_t tx_dlen; /*!< data length */ + uint8_t tx_data[8]; /*!< transmit data */ +} can_trasnmit_message_struct; + +/* CAN receive message structure */ +typedef struct { + uint32_t rx_sfid; /*!< standard format frame identifier */ + uint32_t rx_efid; /*!< extended format frame identifier */ + uint8_t rx_ff; /*!< format of frame, standard or extended format */ + uint8_t rx_ft; /*!< type of frame, data or remote */ + uint8_t rx_dlen; /*!< data length */ + uint8_t rx_data[8]; /*!< receive data */ + uint8_t rx_fi; /*!< filtering index */ +} can_receive_message_struct; + +/* CAN filter parameters structure */ +typedef struct { + uint16_t filter_list_high; /*!< filter list number high bits */ + uint16_t filter_list_low; /*!< filter list number low bits */ + uint16_t filter_mask_high; /*!< filter mask number high bits */ + uint16_t filter_mask_low; /*!< filter mask number low bits */ + uint16_t filter_fifo_number; /*!< receive FIFO associated with the filter */ + uint16_t filter_number; /*!< filter number */ + uint16_t filter_mode; /*!< filter mode, list or mask */ + uint16_t filter_bits; /*!< filter scale */ + ControlStatus filter_enable; /*!< filter work or not */ +} can_filter_parameter_struct; + +/* CAN errors */ +typedef enum { + CAN_ERROR_NONE = 0, /*!< no error */ + CAN_ERROR_FILL, /*!< fill error */ + CAN_ERROR_FORMATE, /*!< format error */ + CAN_ERROR_ACK, /*!< ACK error */ + CAN_ERROR_BITRECESSIVE, /*!< bit recessive error */ + CAN_ERROR_BITDOMINANTER, /*!< bit dominant error */ + CAN_ERROR_CRC, /*!< CRC error */ + CAN_ERROR_SOFTWARECFG, /*!< software configure */ +} can_error_enum; + +/* transmit states */ +typedef enum { + CAN_TRANSMIT_FAILED = 0U, /*!< CAN transmitted failure */ + CAN_TRANSMIT_OK = 1U, /*!< CAN transmitted success */ + CAN_TRANSMIT_PENDING = 2U, /*!< CAN transmitted pending */ + CAN_TRANSMIT_NOMAILBOX = 4U, /*!< no empty mailbox to be used for CAN */ +} can_transmit_state_enum; + +typedef enum { + CAN_INIT_STRUCT = 0, /* CAN initiliaze parameters struct */ + CAN_FILTER_STRUCT, /* CAN filter parameters struct */ + CAN_TX_MESSAGE_STRUCT, /* CAN transmit message struct */ + CAN_RX_MESSAGE_STRUCT, /* CAN receive message struct */ +} can_struct_type_enum; + +/* CAN baudrate prescaler */ +#define BT_BAUDPSC(regval) (BITS(0,9) & ((uint32_t)(regval) << 0)) + +/* CAN bit segment 1 */ +#define BT_BS1(regval) (BITS(16,19) & ((uint32_t)(regval) << 16)) + +/* CAN bit segment 2 */ +#define BT_BS2(regval) (BITS(20,22) & ((uint32_t)(regval) << 20)) + +/* CAN resynchronization jump width */ +#define BT_SJW(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) + +/* CAN communication mode */ +#define BT_MODE(regval) (BITS(30,31) & ((uint32_t)(regval) << 30)) + +/* CAN FDATA high 16 bits */ +#define FDATA_MASK_HIGH(regval) (BITS(16,31) & ((uint32_t)(regval) << 16)) + +/* CAN FDATA low 16 bits */ +#define FDATA_MASK_LOW(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) + +/* CAN1 filter start bank_number */ +#define FCTL_HBC1F(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) + +/* CAN transmit mailbox extended identifier */ +#define TMI_EFID(regval) (BITS(3,31) & ((uint32_t)(regval) << 3)) + +/* CAN transmit mailbox standard identifier */ +#define TMI_SFID(regval) (BITS(21,31) & ((uint32_t)(regval) << 21)) + +/* transmit data byte 0 */ +#define TMDATA0_DB0(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 1 */ +#define TMDATA0_DB1(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 2 */ +#define TMDATA0_DB2(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 3 */ +#define TMDATA0_DB3(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* transmit data byte 4 */ +#define TMDATA1_DB4(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* transmit data byte 5 */ +#define TMDATA1_DB5(regval) (BITS(8,15) & ((uint32_t)(regval) << 8)) + +/* transmit data byte 6 */ +#define TMDATA1_DB6(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) + +/* transmit data byte 7 */ +#define TMDATA1_DB7(regval) (BITS(24,31) & ((uint32_t)(regval) << 24)) + +/* receive mailbox extended identifier */ +#define GET_RFIFOMI_EFID(regval) GET_BITS((uint32_t)(regval), 3U, 31U) + +/* receive mailbox standard identifier */ +#define GET_RFIFOMI_SFID(regval) GET_BITS((uint32_t)(regval), 21U, 31U) + +/* receive data length */ +#define GET_RFIFOMP_DLENC(regval) GET_BITS((uint32_t)(regval), 0U, 3U) + +/* the index of the filter by which the frame is passed */ +#define GET_RFIFOMP_FI(regval) GET_BITS((uint32_t)(regval), 8U, 15U) + +/* receive data byte 0 */ +#define GET_RFIFOMDATA0_DB0(regval) GET_BITS((uint32_t)(regval), 0U, 7U) + +/* receive data byte 1 */ +#define GET_RFIFOMDATA0_DB1(regval) GET_BITS((uint32_t)(regval), 8U, 15U) + +/* receive data byte 2 */ +#define GET_RFIFOMDATA0_DB2(regval) GET_BITS((uint32_t)(regval), 16U, 23U) + +/* receive data byte 3 */ +#define GET_RFIFOMDATA0_DB3(regval) GET_BITS((uint32_t)(regval), 24U, 31U) + +/* receive data byte 4 */ +#define GET_RFIFOMDATA1_DB4(regval) GET_BITS((uint32_t)(regval), 0U, 7U) + +/* receive data byte 5 */ +#define GET_RFIFOMDATA1_DB5(regval) GET_BITS((uint32_t)(regval), 8U, 15U) + +/* receive data byte 6 */ +#define GET_RFIFOMDATA1_DB6(regval) GET_BITS((uint32_t)(regval), 16U, 23U) + +/* receive data byte 7 */ +#define GET_RFIFOMDATA1_DB7(regval) GET_BITS((uint32_t)(regval), 24U, 31U) + +/* error number */ +#define GET_ERR_ERRN(regval) GET_BITS((uint32_t)(regval), 4U, 6U) + +/* transmit error count */ +#define GET_ERR_TECNT(regval) GET_BITS((uint32_t)(regval), 16U, 23U) + +/* receive error count */ +#define GET_ERR_RECNT(regval) GET_BITS((uint32_t)(regval), 24U, 31U) + +/* CAN errors */ +#define ERR_ERRN(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) +#define CAN_ERRN_0 ERR_ERRN(0U) /*!< no error */ +#define CAN_ERRN_1 ERR_ERRN(1U) /*!< fill error */ +#define CAN_ERRN_2 ERR_ERRN(2U) /*!< format error */ +#define CAN_ERRN_3 ERR_ERRN(3U) /*!< ACK error */ +#define CAN_ERRN_4 ERR_ERRN(4U) /*!< bit recessive error */ +#define CAN_ERRN_5 ERR_ERRN(5U) /*!< bit dominant error */ +#define CAN_ERRN_6 ERR_ERRN(6U) /*!< CRC error */ +#define CAN_ERRN_7 ERR_ERRN(7U) /*!< software error */ + +#define CAN_STATE_PENDING ((uint32_t)0x00000000U) /*!< CAN pending */ + +/* CAN communication mode */ +#define CAN_NORMAL_MODE ((uint8_t)0x00U) /*!< normal communication mode */ +#define CAN_LOOPBACK_MODE ((uint8_t)0x01U) /*!< loopback communication mode */ +#define CAN_SILENT_MODE ((uint8_t)0x02U) /*!< silent communication mode */ +#define CAN_SILENT_LOOPBACK_MODE ((uint8_t)0x03U) /*!< loopback and silent communication mode */ + +/* CAN resynchronisation jump width */ +#define CAN_BT_SJW_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_SJW_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_SJW_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_SJW_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ + +/* CAN time segment 1 */ +#define CAN_BT_BS1_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS1_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS1_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS1_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS1_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS1_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS1_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS1_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ +#define CAN_BT_BS1_9TQ ((uint8_t)0x08U) /*!< 9 time quanta */ +#define CAN_BT_BS1_10TQ ((uint8_t)0x09U) /*!< 10 time quanta */ +#define CAN_BT_BS1_11TQ ((uint8_t)0x0AU) /*!< 11 time quanta */ +#define CAN_BT_BS1_12TQ ((uint8_t)0x0BU) /*!< 12 time quanta */ +#define CAN_BT_BS1_13TQ ((uint8_t)0x0CU) /*!< 13 time quanta */ +#define CAN_BT_BS1_14TQ ((uint8_t)0x0DU) /*!< 14 time quanta */ +#define CAN_BT_BS1_15TQ ((uint8_t)0x0EU) /*!< 15 time quanta */ +#define CAN_BT_BS1_16TQ ((uint8_t)0x0FU) /*!< 16 time quanta */ + +/* CAN time segment 2 */ +#define CAN_BT_BS2_1TQ ((uint8_t)0x00U) /*!< 1 time quanta */ +#define CAN_BT_BS2_2TQ ((uint8_t)0x01U) /*!< 2 time quanta */ +#define CAN_BT_BS2_3TQ ((uint8_t)0x02U) /*!< 3 time quanta */ +#define CAN_BT_BS2_4TQ ((uint8_t)0x03U) /*!< 4 time quanta */ +#define CAN_BT_BS2_5TQ ((uint8_t)0x04U) /*!< 5 time quanta */ +#define CAN_BT_BS2_6TQ ((uint8_t)0x05U) /*!< 6 time quanta */ +#define CAN_BT_BS2_7TQ ((uint8_t)0x06U) /*!< 7 time quanta */ +#define CAN_BT_BS2_8TQ ((uint8_t)0x07U) /*!< 8 time quanta */ + +/* CAN mailbox number */ +#define CAN_MAILBOX0 ((uint8_t)0x00U) /*!< mailbox0 */ +#define CAN_MAILBOX1 ((uint8_t)0x01U) /*!< mailbox1 */ +#define CAN_MAILBOX2 ((uint8_t)0x02U) /*!< mailbox2 */ +#define CAN_NOMAILBOX ((uint8_t)0x03U) /*!< no mailbox empty */ + +/* CAN frame format */ +#define CAN_FF_STANDARD ((uint32_t)0x00000000U) /*!< standard frame */ +#define CAN_FF_EXTENDED ((uint32_t)0x00000004U) /*!< extended frame */ + +/* CAN receive FIFO */ +#define CAN_FIFO0 ((uint8_t)0x00U) /*!< receive FIFO0 */ +#define CAN_FIFO1 ((uint8_t)0x01U) /*!< receive FIFO1 */ + +/* frame number of receive FIFO */ +#define CAN_RFIF_RFL_MASK ((uint32_t)0x00000003U) /*!< mask for frame number in receive FIFOx */ + +#define CAN_SFID_MASK ((uint32_t)0x000007FFU) /*!< mask of standard identifier */ +#define CAN_EFID_MASK ((uint32_t)0x1FFFFFFFU) /*!< mask of extended identifier */ + +/* CAN working mode */ +#define CAN_MODE_INITIALIZE ((uint8_t)0x01U) /*!< CAN initialize mode */ +#define CAN_MODE_NORMAL ((uint8_t)0x02U) /*!< CAN normal mode */ +#define CAN_MODE_SLEEP ((uint8_t)0x04U) /*!< CAN sleep mode */ + +/* filter bits */ +#define CAN_FILTERBITS_16BIT ((uint8_t)0x00U) /*!< CAN filter 16 bits */ +#define CAN_FILTERBITS_32BIT ((uint8_t)0x01U) /*!< CAN filter 32 bits */ + +/* filter mode */ +#define CAN_FILTERMODE_MASK ((uint8_t)0x00U) /*!< mask mode */ +#define CAN_FILTERMODE_LIST ((uint8_t)0x01U) /*!< list mode */ + +/* filter 16 bits mask */ +#define CAN_FILTER_MASK_16BITS ((uint32_t)0x0000FFFFU) /*!< can filter 16 bits mask */ + +/* frame type */ +#define CAN_FT_DATA ((uint32_t)0x00000000U) /*!< data frame */ +#define CAN_FT_REMOTE ((uint32_t)0x00000002U) /*!< remote frame */ + +/* CAN timeout */ +#define CAN_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< timeout value */ + +/* interrupt enable bits */ +#define CAN_INT_TME CAN_INTEN_TMEIE /*!< transmit mailbox empty interrupt enable */ +#define CAN_INT_RFNE0 CAN_INTEN_RFNEIE0 /*!< receive FIFO0 not empty interrupt enable */ +#define CAN_INT_RFF0 CAN_INTEN_RFFIE0 /*!< receive FIFO0 full interrupt enable */ +#define CAN_INT_RFO0 CAN_INTEN_RFOIE0 /*!< receive FIFO0 overfull interrupt enable */ +#define CAN_INT_RFNE1 CAN_INTEN_RFNEIE1 /*!< receive FIFO1 not empty interrupt enable */ +#define CAN_INT_RFF1 CAN_INTEN_RFFIE1 /*!< receive FIFO1 full interrupt enable */ +#define CAN_INT_RFO1 CAN_INTEN_RFOIE1 /*!< receive FIFO1 overfull interrupt enable */ +#define CAN_INT_WERR CAN_INTEN_WERRIE /*!< warning error interrupt enable */ +#define CAN_INT_PERR CAN_INTEN_PERRIE /*!< passive error interrupt enable */ +#define CAN_INT_BO CAN_INTEN_BOIE /*!< bus-off interrupt enable */ +#define CAN_INT_ERRN CAN_INTEN_ERRNIE /*!< error number interrupt enable */ +#define CAN_INT_ERR CAN_INTEN_ERRIE /*!< error interrupt enable */ +#define CAN_INT_WAKEUP CAN_INTEN_WIE /*!< wakeup interrupt enable */ +#define CAN_INT_SLPW CAN_INTEN_SLPWIE /*!< sleep working interrupt enable */ + +/* function declarations */ +/* initialization functions */ +/* deinitialize CAN */ +void can_deinit(uint32_t can_periph); +/* initialize CAN structure */ +void can_struct_para_init(can_struct_type_enum type, void *p_struct); +/* initialize CAN */ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init); +/* CAN filter initialization */ +void can_filter_init(can_filter_parameter_struct *can_filter_parameter_init); + +/* function configuration */ +/* set can1 filter start bank number */ +void can1_filter_start_bank(uint8_t start_bank); +/* enable functions */ +/* CAN debug freeze enable */ +void can_debug_freeze_enable(uint32_t can_periph); +/* CAN debug freeze disable */ +void can_debug_freeze_disable(uint32_t can_periph); +/* CAN time trigger mode enable */ +void can_time_trigger_mode_enable(uint32_t can_periph); +/* CAN time trigger mode disable */ +void can_time_trigger_mode_disable(uint32_t can_periph); + +/* transmit functions */ +/* transmit CAN message */ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message); +/* get CAN transmit state */ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number); +/* stop CAN transmission */ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number); +/* CAN receive message */ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct *receive_message); +/* CAN release FIFO */ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number); +/* CAN receive message length */ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number); +/* CAN working mode */ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode); +/* CAN wakeup from sleep mode */ +ErrStatus can_wakeup(uint32_t can_periph); + +/* CAN get error type */ +can_error_enum can_error_get(uint32_t can_periph); +/* get CAN receive error number */ +uint8_t can_receive_error_number_get(uint32_t can_periph); +/* get CAN transmit error number */ +uint8_t can_transmit_error_number_get(uint32_t can_periph); + +/* interrupt & flag functions */ +/* CAN get flag state */ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); +/* CAN clear flag state */ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* CAN interrupt enable */ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt); +/* CAN interrupt disable */ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt); +/* CAN get interrupt flag state */ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag); +/* CAN clear interrupt flag state */ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag); + +#endif /* GD32F4XX_CAN_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_crc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_crc.h new file mode 100644 index 000000000..ef4d3ae58 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_crc.h @@ -0,0 +1,81 @@ +/*! + \file gd32f4xx_crc.h + \brief definitions for the CRC + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_CRC_H +#define GD32F4XX_CRC_H + +#include "gd32f4xx.h" + +/* CRC definitions */ +#define CRC CRC_BASE /*!< CRC base 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 */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0,31) /*!< CRC calculation result bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0,7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset CRC_DATA register bit */ + + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); + +/* reset data register(CRC_DATA) to the value of 0xFFFFFFFF */ +void crc_data_register_reset(void); +/* read the value of the data register */ +uint32_t crc_data_register_read(void); + +/* read the value of the free data register */ +uint8_t crc_free_data_register_read(void); +/* write data to the free data register */ +void crc_free_data_register_write(uint8_t free_data); + +/* calculate the CRC value of a 32-bit data */ +uint32_t crc_single_data_calculate(uint32_t sdata); +/* calculate the CRC value of an array of 32-bit values */ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size); + +#endif /* GD32F4XX_CRC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ctc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ctc.h new file mode 100644 index 000000000..0542676fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ctc.h @@ -0,0 +1,185 @@ +/*! + \file gd32f4xx_ctc.h + \brief definitions for the CTC + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_CTC_H +#define GD32F4XX_CTC_H + +#include "gd32f4xx.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 clock 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 */ +/* 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); +/* get CTC flag */ +FlagStatus ctc_flag_get(uint32_t flag); +/* clear CTC flag */ +void ctc_flag_clear(uint32_t flag); + +#endif /* GD32F4XX_CTC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dac.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dac.h new file mode 100644 index 000000000..cf0d7da90 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dac.h @@ -0,0 +1,271 @@ +/*! + \file gd32f4xx_dac.h + \brief definitions for the DAC + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_DAC_H +#define GD32F4XX_DAC_H + +#include "gd32f4xx.h" + +/* DACx(x=0,1) definitions */ +#define DAC DAC_BASE +#define DAC0 0U +#define DAC1 1U + +/* registers definitions */ +#define DAC_CTL REG32(DAC + 0x00U) /*!< DAC control register */ +#define DAC_SWT REG32(DAC + 0x04U) /*!< DAC software trigger register */ +#define DAC0_R12DH REG32(DAC + 0x08U) /*!< DAC0 12-bit right-aligned data holding register */ +#define DAC0_L12DH REG32(DAC + 0x0CU) /*!< DAC0 12-bit left-aligned data holding register */ +#define DAC0_R8DH REG32(DAC + 0x10U) /*!< DAC0 8-bit right-aligned data holding register */ +#define DAC1_R12DH REG32(DAC + 0x14U) /*!< DAC1 12-bit right-aligned data holding register */ +#define DAC1_L12DH REG32(DAC + 0x18U) /*!< DAC1 12-bit left-aligned data holding register */ +#define DAC1_R8DH REG32(DAC + 0x1CU) /*!< DAC1 8-bit right-aligned data holding register */ +#define DACC_R12DH REG32(DAC + 0x20U) /*!< DAC concurrent mode 12-bit right-aligned data holding register */ +#define DACC_L12DH REG32(DAC + 0x24U) /*!< DAC concurrent mode 12-bit left-aligned data holding register */ +#define DACC_R8DH REG32(DAC + 0x28U) /*!< DAC concurrent mode 8-bit right-aligned data holding register */ +#define DAC0_DO REG32(DAC + 0x2CU) /*!< DAC0 data output register */ +#define DAC1_DO REG32(DAC + 0x30U) /*!< DAC1 data output register */ +#define DAC_STAT REG32(DAC + 0x34U) /*!< DAC status register */ + +/* bits definitions */ +/* DAC_CTL */ +#define DAC_CTL_DEN0 BIT(0) /*!< DAC0 enable/disable bit */ +#define DAC_CTL_DBOFF0 BIT(1) /*!< DAC0 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN0 BIT(2) /*!< DAC0 trigger enable/disable bit */ +#define DAC_CTL_DTSEL0 BITS(3,5) /*!< DAC0 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM0 BITS(6,7) /*!< DAC0 noise wave mode */ +#define DAC_CTL_DWBW0 BITS(8,11) /*!< DAC0 noise wave bit width */ +#define DAC_CTL_DDMAEN0 BIT(12) /*!< DAC0 DMA enable/disable bit */ +#define DAC_CTL_DDUDRIE0 BIT(13) /*!< DAC0 DMA underrun interrupt enable/disable bit */ +#define DAC_CTL_DEN1 BIT(16) /*!< DAC1 enable/disable bit */ +#define DAC_CTL_DBOFF1 BIT(17) /*!< DAC1 output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN1 BIT(18) /*!< DAC1 trigger enable/disable bit */ +#define DAC_CTL_DTSEL1 BITS(19,21) /*!< DAC1 trigger source selection enable/disable bits */ +#define DAC_CTL_DWM1 BITS(22,23) /*!< DAC1 noise wave mode */ +#define DAC_CTL_DWBW1 BITS(24,27) /*!< DAC1 noise wave bit width */ +#define DAC_CTL_DDMAEN1 BIT(28) /*!< DAC1 DMA enable/disable bit */ +#define DAC_CTL_DDUDRIE1 BIT(29) /*!< DAC1 DMA underrun interrupt enable/disable bit */ + +/* DAC_SWT */ +#define DAC_SWT_SWTR0 BIT(0) /*!< DAC0 software trigger bit, cleared by hardware */ +#define DAC_SWT_SWTR1 BIT(1) /*!< DAC1 software trigger bit, cleared by hardware */ + +/* DAC0_R12DH */ +#define DAC0_R12DH_DAC0_DH BITS(0,11) /*!< DAC0 12-bit right-aligned data bits */ + +/* DAC0_L12DH */ +#define DAC0_L12DH_DAC0_DH BITS(4,15) /*!< DAC0 12-bit left-aligned data bits */ + +/* DAC0_R8DH */ +#define DAC0_R8DH_DAC0_DH BITS(0,7) /*!< DAC0 8-bit right-aligned data bits */ + +/* DAC1_R12DH */ +#define DAC1_R12DH_DAC1_DH BITS(0,11) /*!< DAC1 12-bit right-aligned data bits */ + +/* DAC1_L12DH */ +#define DAC1_L12DH_DAC1_DH BITS(4,15) /*!< DAC1 12-bit left-aligned data bits */ + +/* DAC1_R8DH */ +#define DAC1_R8DH_DAC1_DH BITS(0,7) /*!< DAC1 8-bit right-aligned data bits */ + +/* DACC_R12DH */ +#define DACC_R12DH_DAC0_DH BITS(0,11) /*!< DAC concurrent mode DAC0 12-bit right-aligned data bits */ +#define DACC_R12DH_DAC1_DH BITS(16,27) /*!< DAC concurrent mode DAC1 12-bit right-aligned data bits */ + +/* DACC_L12DH */ +#define DACC_L12DH_DAC0_DH BITS(4,15) /*!< DAC concurrent mode DAC0 12-bit left-aligned data bits */ +#define DACC_L12DH_DAC1_DH BITS(20,31) /*!< DAC concurrent mode DAC1 12-bit left-aligned data bits */ + +/* DACC_R8DH */ +#define DACC_R8DH_DAC0_DH BITS(0,7) /*!< DAC concurrent mode DAC0 8-bit right-aligned data bits */ +#define DACC_R8DH_DAC1_DH BITS(8,15) /*!< DAC concurrent mode DAC1 8-bit right-aligned data bits */ + +/* DAC0_DO */ +#define DAC0_DO_DAC0_DO BITS(0,11) /*!< DAC0 12-bit output data bits */ + +/* DAC1_DO */ +#define DAC1_DO_DAC1_DO BITS(0,11) /*!< DAC1 12-bit output data bits */ + +/* DAC_STAT */ +#define DAC_STAT_DDUDR0 BIT(13) /*!< DAC0 DMA underrun flag */ +#define DAC_STAT_DDUDR1 BIT(29) /*!< DAC1 DMA underrun flag */ + +/* constants definitions */ +/* DAC trigger source */ +#define CTL_DTSEL(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define DAC_TRIGGER_T5_TRGO CTL_DTSEL(0) /*!< TIMER5 TRGO */ +#define DAC_TRIGGER_T7_TRGO CTL_DTSEL(1) /*!< TIMER7 TRGO */ +#define DAC_TRIGGER_T6_TRGO CTL_DTSEL(2) /*!< TIMER6 TRGO */ +#define DAC_TRIGGER_T4_TRGO CTL_DTSEL(3) /*!< TIMER4 TRGO */ +#define DAC_TRIGGER_T1_TRGO CTL_DTSEL(4) /*!< TIMER1 TRGO */ +#define DAC_TRIGGER_T3_TRGO CTL_DTSEL(5) /*!< TIMER3 TRGO */ +#define DAC_TRIGGER_EXTI_9 CTL_DTSEL(6) /*!< EXTI interrupt line9 event */ +#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(7) /*!< 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 disable */ +#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] */ + +/* DAC data alignment */ +#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< data right 12 bit alignment */ +#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< data left 12 bit alignment */ +#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< data right 8 bit alignment */ + +/* 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 */ + +/* function declarations */ +/* initialization functions */ +/* deinitialize DAC */ +void dac_deinit(void); +/* enable DAC */ +void dac_enable(uint32_t dac_periph); +/* disable DAC */ +void dac_disable(uint32_t dac_periph); +/* enable DAC DMA */ +void dac_dma_enable(uint32_t dac_periph); +/* disable DAC DMA */ +void dac_dma_disable(uint32_t dac_periph); +/* enable DAC output buffer */ +void dac_output_buffer_enable(uint32_t dac_periph); +/* disable DAC output buffer */ +void dac_output_buffer_disable(uint32_t dac_periph); +/* get the last data output value */ +uint16_t dac_output_value_get(uint32_t dac_periph); +/* set DAC data holding register value */ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data); + +/* DAC trigger configuration */ +/* enable DAC trigger */ +void dac_trigger_enable(uint32_t dac_periph); +/* disable DAC trigger */ +void dac_trigger_disable(uint32_t dac_periph); +/* configure DAC trigger source */ +void dac_trigger_source_config(uint32_t dac_periph, uint32_t triggersource); +/* enable DAC software trigger */ +void dac_software_trigger_enable(uint32_t dac_periph); +/* disable DAC software trigger */ +void dac_software_trigger_disable(uint32_t dac_periph); + +/* DAC wave mode configuration */ +/* configure DAC wave mode */ +void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode); +/* configure DAC wave bit width */ +void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width); +/* configure DAC LFSR noise mode */ +void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits); +/* configure DAC triangle noise mode */ +void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude); + +/* DAC concurrent mode configuration */ +/* enable DAC concurrent mode */ +void dac_concurrent_enable(void); +/* disable DAC concurrent mode */ +void dac_concurrent_disable(void); +/* enable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_enable(void); +/* disable DAC concurrent software trigger */ +void dac_concurrent_software_trigger_disable(void); +/* enable DAC concurrent buffer function */ +void dac_concurrent_output_buffer_enable(void); +/* disable DAC concurrent buffer function */ +void dac_concurrent_output_buffer_disable(void); +/* set DAC concurrent mode data holding register value */ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1); +/* enable DAC concurrent interrupt */ +void dac_concurrent_interrupt_enable(void); +/* disable DAC concurrent interrupt */ +void dac_concurrent_interrupt_disable(void); + +/* DAC interrupt configuration */ +/* get the specified DAC flag(DAC DMA underrun flag) */ +FlagStatus dac_flag_get(uint32_t dac_periph); +/* clear the specified DAC flag(DAC DMA underrun flag) */ +void dac_flag_clear(uint32_t dac_periph); +/* enable DAC interrupt(DAC DMA underrun interrupt) */ +void dac_interrupt_enable(uint32_t dac_periph); +/* disable DAC interrupt(DAC DMA underrun interrupt) */ +void dac_interrupt_disable(uint32_t dac_periph); +/* get the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph); +/* clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag) */ +void dac_interrupt_flag_clear(uint32_t dac_periph); + +#endif /* GD32F4XX_DAC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dbg.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dbg.h new file mode 100644 index 000000000..2e2a00ccb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dbg.h @@ -0,0 +1,153 @@ +/*! + \file gd32f4xx_dbg.h + \brief definitions for the DBG_DEVICE + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_DBG_H +#define GD32F4XX_DBG_H + +#include "gd32f4xx.h" + +/* DBG_DEVICE definitions */ +#define DBG_DEVICE DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG_DEVICE + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG_DEVICE + 0x04U) /*!< DBG_DEVICE control register 0 */ +#define DBG_CTL1 REG32(DBG_DEVICE + 0x08U) /*!< DBG_DEVICE control register 1 */ +#define DBG_CTL2 REG32(DBG_DEVICE + 0x0CU) /*!< DBG_DEVICE control register 2 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG_DEVICE 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_IOEN BIT(5) /*!< enable trace pin assignment */ + +/* DBG_CTL1 */ +#define DBG_CTL1_TIMER1_HOLD BIT(0) /*!< hold TIMER1 counter when core is halted */ +#define DBG_CTL1_TIMER2_HOLD BIT(1) /*!< hold TIMER2 counter when core is halted */ +#define DBG_CTL1_TIMER3_HOLD BIT(2) /*!< hold TIMER3 counter when core is halted */ +#define DBG_CTL1_TIMER4_HOLD BIT(3) /*!< hold TIMER4 counter when core is halted */ +#define DBG_CTL1_TIMER5_HOLD BIT(4) /*!< hold TIMER5 counter when core is halted */ +#define DBG_CTL1_TIMER6_HOLD BIT(5) /*!< hold TIMER6 counter when core is halted */ +#define DBG_CTL1_TIMER11_HOLD BIT(6) /*!< hold TIMER11 counter when core is halted */ +#define DBG_CTL1_TIMER12_HOLD BIT(7) /*!< hold TIMER12 counter when core is halted */ +#define DBG_CTL1_TIMER13_HOLD BIT(8) /*!< hold TIMER13 counter when core is halted */ +#define DBG_CTL1_RTC_HOLD BIT(10) /*!< hold RTC calendar and wakeup counter when core is halted */ +#define DBG_CTL1_WWDGT_HOLD BIT(11) /*!< debug WWDGT kept when core is halted */ +#define DBG_CTL1_FWDGT_HOLD BIT(12) /*!< debug FWDGT kept when core is halted */ +#define DBG_CTL1_I2C0_HOLD BIT(21) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL1_I2C1_HOLD BIT(22) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL1_I2C2_HOLD BIT(23) /*!< hold I2C2 smbus when core is halted */ +#define DBG_CTL1_CAN0_HOLD BIT(25) /*!< debug CAN0 kept when core is halted */ +#define DBG_CTL1_CAN1_HOLD BIT(26) /*!< debug CAN1 kept when core is halted */ + +/* DBG_CTL2 */ +#define DBG_CTL2_TIMER0_HOLD BIT(0) /*!< hold TIMER0 counter when core is halted */ +#define DBG_CTL2_TIMER7_HOLD BIT(1) /*!< hold TIMER7 counter when core is halted */ +#define DBG_CTL2_TIMER8_HOLD BIT(16) /*!< hold TIMER8 counter when core is halted */ +#define DBG_CTL2_TIMER9_HOLD BIT(17) /*!< hold TIMER9 counter when core is halted */ +#define DBG_CTL2_TIMER10_HOLD BIT(18) /*!< hold TIMER10 counter 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_DEVICE + ((uint32_t)(periph) >> 6))) +#define DBG_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register index */ +enum dbg_reg_idx +{ + DBG_IDX_CTL0 = 0x04U, + DBG_IDX_CTL1 = 0x08U, + DBG_IDX_CTL2 = 0x0CU +}; + +typedef enum +{ + DBG_TIMER1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 0U), /*!< hold TIMER1 counter when core is halted */ + DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 1U), /*!< hold TIMER2 counter when core is halted */ + DBG_TIMER3_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 2U), /*!< hold TIMER3 counter when core is halted */ + DBG_TIMER4_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 3U), /*!< hold TIMER4 counter when core is halted */ + DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 4U), /*!< hold TIMER5 counter when core is halted */ + DBG_TIMER6_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 5U), /*!< hold TIMER6 counter when core is halted */ + DBG_TIMER11_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 6U), /*!< hold TIMER11 counter when core is halted */ + DBG_TIMER12_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 7U), /*!< hold TIMER12 counter when core is halted */ + DBG_TIMER13_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 8U), /*!< hold TIMER13 counter when core is halted */ + DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U), /*!< hold RTC calendar and wakeup counter when core is halted */ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 11U), /*!< debug WWDGT kept when core is halted */ + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 12U), /*!< debug FWDGT kept when core is halted */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 21U), /*!< hold I2C0 smbus when core is halted */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 22U), /*!< hold I2C1 smbus when core is halted */ + DBG_I2C2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 23U), /*!< hold I2C2 smbus when core is halted */ + DBG_CAN0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 25U), /*!< debug CAN0 kept when core is halted */ + DBG_CAN1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 26U), /*!< debug CAN1 kept when core is halted */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 0U), /*!< hold TIMER0 counter when core is halted */ + DBG_TIMER7_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 1U), /*!< hold TIMER7 counter when core is halted */ + DBG_TIMER8_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 16U), /*!< hold TIMER8 counter when core is halted */ + DBG_TIMER9_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 17U), /*!< hold TIMER9 counter when core is halted */ + DBG_TIMER10_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL2, 18U) /*!< hold TIMER10 counter when core is halted */ +}dbg_periph_enum; + +/* function declarations */ +/* deinitialize the DBG_DEVICE */ +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 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); + +/* enable trace pin assignment */ +void dbg_trace_pin_enable(void); +/* disable trace pin assignment */ +void dbg_trace_pin_disable(void); + +#endif /* GD32F4XX_DBG_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dci.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dci.h new file mode 100644 index 000000000..4dfc8116a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dci.h @@ -0,0 +1,239 @@ +/*! + \file gd32f4xx_dci.h + \brief definitions for the DCI + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_DCI_H +#define GD32F4XX_DCI_H + +#include "gd32f4xx.h" + +/* DCI definitions */ +#define DCI DCI_BASE + +/* registers definitions */ +#define DCI_CTL REG32(DCI + 0x00U) /*!< DCI control register */ +#define DCI_STAT0 REG32(DCI + 0x04U) /*!< DCI status register 0 */ +#define DCI_STAT1 REG32(DCI + 0x08U) /*!< DCI status register 1 */ +#define DCI_INTEN REG32(DCI + 0x0CU) /*!< DCI interrupt enable register */ +#define DCI_INTF REG32(DCI + 0x10U) /*!< DCI interrupt flag register */ +#define DCI_INTC REG32(DCI + 0x14U) /*!< DCI interrupt clear register */ +#define DCI_SC REG32(DCI + 0x18U) /*!< DCI synchronization codes register */ +#define DCI_SCUMSK REG32(DCI + 0x1CU) /*!< DCI synchronization codes unmask register */ +#define DCI_CWSPOS REG32(DCI + 0x20U) /*!< DCI cropping window start position register */ +#define DCI_CWSZ REG32(DCI + 0x24U) /*!< DCI cropping window size register */ +#define DCI_DATA REG32(DCI + 0x28U) /*!< 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_DCIEN BIT(14) /*!< DCI 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 */ + +/* 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 */ + +/* 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 */ + +/* 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 */ + +/* 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 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) << 8U)) +#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) << 10U)) +#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 */ + +/* 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 */ + +/* 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 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); +/* 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 /* GD32F4XX_DCI_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dma.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dma.h new file mode 100644 index 000000000..cffbbf878 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_dma.h @@ -0,0 +1,428 @@ +/*! + \file gd32f4xx_dma.h + \brief definitions for the DMA + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_DMA_H +#define GD32F4XX_DMA_H + +#include "gd32f4xx.h" + +/* DMA definitions */ +#define DMA0 (DMA_BASE) /*!< DMA0 base address */ +#define DMA1 (DMA_BASE + 0x00000400U) /*!< DMA1 base address */ + +/* 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 */ + +/* 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_TFCS BIT(5) /*!< transfer flow controller select */ +#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 */ +#define DMA_CHXCTL_PERIEN BITS(25,27) /*!< peripheral enable */ + +/* 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_M0ADDR 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 */ + +/* constants definitions */ +/* DMA channel select */ +typedef enum +{ + DMA_CH0 = 0, /*!< 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; + +/* DMA peripheral select */ +typedef enum +{ + DMA_SUBPERI0 = 0, /*!< DMA Peripheral 0 */ + DMA_SUBPERI1, /*!< DMA Peripheral 1 */ + DMA_SUBPERI2, /*!< DMA Peripheral 2 */ + DMA_SUBPERI3, /*!< DMA Peripheral 3 */ + DMA_SUBPERI4, /*!< DMA Peripheral 4 */ + DMA_SUBPERI5, /*!< DMA Peripheral 5 */ + DMA_SUBPERI6, /*!< DMA Peripheral 6 */ + DMA_SUBPERI7 /*!< DMA Peripheral 7 */ +} dma_subperipheral_enum; + +/* DMA multidata mode initialize struct */ +typedef struct +{ + 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; /*!< multi data mode enable */ + uint32_t periph_burst_width; /*!< multi data mode enable */ + 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 singledata mode initialize struct */ +typedef struct +{ + 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; + +#define DMA_FLAG_ADD(flag,channel) ((uint32_t)((flag)<<((((uint32_t)(channel)*6U))+((uint32_t)(((uint32_t)(channel)) >> 1U)&0x01U)*4U))) /*!< DMA channel flag shift */ + +/* DMA_register address */ +#define DMA_CHCTL(dma,channel) REG32(((dma) + 0x10U) + 0x18U*(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(dma,channel) REG32(((dma) + 0x14U) + 0x18U*(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(dma,channel) REG32(((dma) + 0x18U) + 0x18U*(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHM0ADDR(dma,channel) REG32(((dma) + 0x1CU) + 0x18U*(channel)) /*!< the address of DMA channel CHXM0ADDR register */ +#define DMA_CHM1ADDR(dma,channel) REG32(((dma) + 0x20U) + 0x18U*(channel)) /*!< the address of DMA channel CHXM1ADDR register */ +#define DMA_CHFCTL(dma,channel) REG32(((dma) + 0x24U) + 0x18U*(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* peripheral select */ +#define CHCTL_PERIEN(regval) (BITS(25,27) & ((uint32_t)(regval) << 25)) +#define DMA_PERIPH_0_SELECT CHCTL_PERIEN(0) /*!< peripheral 0 select */ +#define DMA_PERIPH_1_SELECT CHCTL_PERIEN(1) /*!< peripheral 1 select */ +#define DMA_PERIPH_2_SELECT CHCTL_PERIEN(2) /*!< peripheral 2 select */ +#define DMA_PERIPH_3_SELECT CHCTL_PERIEN(3) /*!< peripheral 3 select */ +#define DMA_PERIPH_4_SELECT CHCTL_PERIEN(4) /*!< peripheral 4 select */ +#define DMA_PERIPH_5_SELECT CHCTL_PERIEN(5) /*!< peripheral 5 select */ +#define DMA_PERIPH_6_SELECT CHCTL_PERIEN(6) /*!< peripheral 6 select */ +#define DMA_PERIPH_7_SELECT CHCTL_PERIEN(7) /*!< peripheral 7 select */ + +/* burst type of memory */ +#define CHCTL_MBURST(regval) (BITS(23,24) & ((uint32_t)(regval) << 23)) +#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) << 21)) +#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) << 16)) +#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) << 13)) +#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) << 11)) +#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) << 6)) +#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) << 0)) +#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 */ + +/* 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 */ + +/* DMA_INTF register */ +/* 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 */ + +/* 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 */ + + +/* function declarations */ +/* DMA deinitialization and initialization functions */ +/* deinitialize DMA a channel registers */ +void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx); +/* initialize the DMA single data mode parameters struct 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 struct with the default values */ +void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct* init_struct); +/* DMA single data mode initialize */ +void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_single_data_parameter_struct* init_struct); +/* DMA multi data mode initialize */ +void dma_multi_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_multi_data_parameter_struct* init_struct); + +/* DMA configuration functions */ +/* set DMA peripheral base address */ +void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address); +/* set DMA Memory base address */ +void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t memory_flag, uint32_t address); + +/* set 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); + +/* DMA switch buffer mode config */ +void dma_switch_buffer_mode_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t memory1_addr, uint32_t memory_select); +/* DMA using memory get */ +uint32_t dma_using_memory_get(uint32_t dma_periph, dma_channel_enum channelx); + +/* DMA channel peripheral select */ +void dma_channel_subperipheral_select(uint32_t dma_periph, dma_channel_enum channelx, dma_subperipheral_enum sub_periph); +/* DMA flow controller configure */ +void dma_flow_controller_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t controller); +/* DMA flow controller enable */ +void dma_switch_buffer_mode_enable(uint32_t dma_periph, dma_channel_enum channelx, ControlStatus newvalue); +/* DMA FIFO status get */ +uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx); + +/* flag and interrupt functions */ +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel 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 source); +/* disable DMA interrupt */ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source); +/* check DMA flag is set or not */ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); +/* clear DMA a channel flag */ +void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt); + +#endif /* GD32F4XX_DMA_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_enet.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_enet.h new file mode 100644 index 000000000..4363c43ca --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_enet.h @@ -0,0 +1,1681 @@ +/*! + \file gd32f4xx_enet.h + \brief definitions for the ENET + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_ENET_H +#define GD32F4XX_ENET_H + +#include "gd32f4xx.h" +#include + +#define IF_USE_EXTERNPHY_LIB 0 +#if (1 == 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 0 +#define LAN8700 1 +#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)0x8000) /*!< PHY reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< enable phy loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< configure speed to 100 Mbit/s and the full-duplex mode */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< configure speed to 100 Mbit/s and the half-duplex mode */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< configure speed to 10 Mbit/s and the full-duplex mode */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< configure speed to 10 Mbit/s and the half-duplex mode */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< enable the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< isolate PHY from MII */ + +/* PHY basic status register */ +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< auto-negotioation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< jabber condition detected */ + +#if(PHY_TYPE == LAN8700) +#define PHY_SR 31U /*!< tranceiver status register */ +#define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< configured information of speed: 10Mbit/s */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< configured information of duplex: full-duplex */ +#elif(PHY_TYPE == DP83848) +#define PHY_SR 16U /*!< tranceiver status register */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< configured information of speed: 10Mbit/s */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< configured information of duplex: full-duplex */ +#endif /* PHY_TYPE */ + +#endif /* _PHY_H_ */ + + +/* ENET definitions */ +#define ENET ENET_BASE + +/* registers definitions */ +#define ENET_MAC_CFG REG32((ENET) + 0x0000U) /*!< ethernet MAC configuration register */ +#define ENET_MAC_FRMF REG32((ENET) + 0x0004U) /*!< ethernet MAC frame filter register */ +#define ENET_MAC_HLH REG32((ENET) + 0x0008U) /*!< ethernet MAC hash list high register */ +#define ENET_MAC_HLL REG32((ENET) + 0x000CU) /*!< ethernet MAC hash list low register */ +#define ENET_MAC_PHY_CTL REG32((ENET) + 0x0010U) /*!< ethernet MAC PHY control register */ +#define ENET_MAC_PHY_DATA REG32((ENET) + 0x0014U) /*!< ethernet MAC PHY data register */ +#define ENET_MAC_FCTL REG32((ENET) + 0x0018U) /*!< ethernet MAC flow control register */ +#define ENET_MAC_VLT REG32((ENET) + 0x001CU) /*!< ethernet MAC VLAN tag register */ +#define ENET_MAC_RWFF REG32((ENET) + 0x0028U) /*!< ethernet MAC remote wakeup frame filter register */ +#define ENET_MAC_WUM REG32((ENET) + 0x002CU) /*!< ethernet MAC wakeup management register */ +#define ENET_MAC_DBG REG32((ENET) + 0x0034U) /*!< ethernet MAC debug register */ +#define ENET_MAC_INTF REG32((ENET) + 0x0038U) /*!< ethernet MAC interrupt flag register */ +#define ENET_MAC_INTMSK REG32((ENET) + 0x003CU) /*!< ethernet MAC interrupt mask register */ +#define ENET_MAC_ADDR0H REG32((ENET) + 0x0040U) /*!< ethernet MAC address 0 high register */ +#define ENET_MAC_ADDR0L REG32((ENET) + 0x0044U) /*!< ethernet MAC address 0 low register */ +#define ENET_MAC_ADDR1H REG32((ENET) + 0x0048U) /*!< ethernet MAC address 1 high register */ +#define ENET_MAC_ADDR1L REG32((ENET) + 0x004CU) /*!< ethernet MAC address 1 low register */ +#define ENET_MAC_ADDT2H REG32((ENET) + 0x0050U) /*!< ethernet MAC address 2 high register */ +#define ENET_MAC_ADDR2L REG32((ENET) + 0x0054U) /*!< ethernet MAC address 2 low register */ +#define ENET_MAC_ADDR3H REG32((ENET) + 0x0058U) /*!< ethernet MAC address 3 high register */ +#define ENET_MAC_ADDR3L REG32((ENET) + 0x005CU) /*!< ethernet MAC address 3 low register */ +#define ENET_MAC_FCTH REG32((ENET) + 0x1080U) /*!< ethernet MAC flow control threshold register */ + +#define ENET_MSC_CTL REG32((ENET) + 0x0100U) /*!< ethernet MSC control register */ +#define ENET_MSC_RINTF REG32((ENET) + 0x0104U) /*!< ethernet MSC receive interrupt flag register */ +#define ENET_MSC_TINTF REG32((ENET) + 0x0108U) /*!< ethernet MSC transmit interrupt flag register */ +#define ENET_MSC_RINTMSK REG32((ENET) + 0x010CU) /*!< ethernet MSC receive interrupt mask register */ +#define ENET_MSC_TINTMSK REG32((ENET) + 0x0110U) /*!< ethernet MSC transmit interrupt mask register */ +#define ENET_MSC_SCCNT REG32((ENET) + 0x014CU) /*!< ethernet MSC transmitted good frames after a single collision counter register */ +#define ENET_MSC_MSCCNT REG32((ENET) + 0x0150U) /*!< ethernet MSC transmitted good frames after more than a single collision counter register */ +#define ENET_MSC_TGFCNT REG32((ENET) + 0x0168U) /*!< ethernet MSC transmitted good frames counter register */ +#define ENET_MSC_RFCECNT REG32((ENET) + 0x0194U) /*!< ethernet MSC received frames with CRC error counter register */ +#define ENET_MSC_RFAECNT REG32((ENET) + 0x0198U) /*!< ethernet MSC received frames with alignment error counter register */ +#define ENET_MSC_RGUFCNT REG32((ENET) + 0x01C4U) /*!< ethernet MSC received good unicast frames counter register */ + +#define ENET_PTP_TSCTL REG32((ENET) + 0x0700U) /*!< ethernet PTP time stamp control register */ +#define ENET_PTP_SSINC REG32((ENET) + 0x0704U) /*!< ethernet PTP subsecond increment register */ +#define ENET_PTP_TSH REG32((ENET) + 0x0708U) /*!< ethernet PTP time stamp high register */ +#define ENET_PTP_TSL REG32((ENET) + 0x070CU) /*!< ethernet PTP time stamp low register */ +#define ENET_PTP_TSUH REG32((ENET) + 0x0710U) /*!< ethernet PTP time stamp update high register */ +#define ENET_PTP_TSUL REG32((ENET) + 0x0714U) /*!< ethernet PTP time stamp update low register */ +#define ENET_PTP_TSADDEND REG32((ENET) + 0x0718U) /*!< ethernet PTP time stamp addend register */ +#define ENET_PTP_ETH REG32((ENET) + 0x071CU) /*!< ethernet PTP expected time high register */ +#define ENET_PTP_ETL REG32((ENET) + 0x0720U) /*!< ethernet PTP expected time low register */ +#define ENET_PTP_TSF REG32((ENET) + 0x0728U) /*!< ethernet PTP time stamp flag register */ +#define ENET_PTP_PPSCTL REG32((ENET) + 0x072CU) /*!< ethernet PTP PPS control register */ + +#define ENET_DMA_BCTL REG32((ENET) + 0x1000U) /*!< ethernet DMA bus control register */ +#define ENET_DMA_TPEN REG32((ENET) + 0x1004U) /*!< ethernet DMA transmit poll enable register */ +#define ENET_DMA_RPEN REG32((ENET) + 0x1008U) /*!< ethernet DMA receive poll enable register */ +#define ENET_DMA_RDTADDR REG32((ENET) + 0x100CU) /*!< ethernet DMA receive descriptor table address register */ +#define ENET_DMA_TDTADDR REG32((ENET) + 0x1010U) /*!< ethernet DMA transmit descriptor table address register */ +#define ENET_DMA_STAT REG32((ENET) + 0x1014U) /*!< ethernet DMA status register */ +#define ENET_DMA_CTL REG32((ENET) + 0x1018U) /*!< ethernet DMA control register */ +#define ENET_DMA_INTEN REG32((ENET) + 0x101CU) /*!< ethernet DMA interrupt enable register */ +#define ENET_DMA_MFBOCNT REG32((ENET) + 0x1020U) /*!< ethernet DMA missed frame and buffer overflow counter register */ +#define ENET_DMA_RSWDC REG32((ENET) + 0x1024U) /*!< ethernet DMA receive state watchdog counter register */ +#define ENET_DMA_CTDADDR REG32((ENET) + 0x1048U) /*!< ethernet DMA current transmit descriptor address register */ +#define ENET_DMA_CRDADDR REG32((ENET) + 0x104CU) /*!< ethernet DMA current receive descriptor address register */ +#define ENET_DMA_CTBADDR REG32((ENET) + 0x1050U) /*!< ethernet DMA current transmit buffer address register */ +#define ENET_DMA_CRBADDR REG32((ENET) + 0x1054U) /*!< 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 PTP_TSCTL_CKNT(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) /*!< write value to ENET_PTP_TSCTL_CKNT bit field */ + +#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_TSADDAND */ +#define ENET_PTP_TSADDAND_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 */ + +#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) << 6) | (uint32_t)(bitpos)) +#define ENET_REG_VAL(periph) (REG32(ENET + ((uint32_t)(periph) >> 6))) +#define ENET_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* 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] << 8) | (uint32_t)(p)[4]) +#define ENET_SET_MACADDRL(p) (((uint32_t)(p)[3] << 24) | ((uint32_t)(p)[2] << 16) | ((uint32_t)(p)[1] << 8) | (uint32_t)(p)[0]) +#define ENET_ADDRH_BASE ((ENET) + 0x40U) +#define ENET_ADDRL_BASE ((ENET) + 0x44U) +#define ENET_GET_MACADDR(offset, n) ((uint8_t)((REG32((ENET_ADDRL_BASE + (offset)) - (((n) / 4U) * 4U)) >> (8U * ((n) % 4U))) & 0xFFU)) + +/* register offset */ +#define MAC_FCTL_REG_OFFSET ((uint16_t)0x0018U) /*!< MAC flow control register offset */ +#define MAC_WUM_REG_OFFSET ((uint16_t)0x002CU) /*!< MAC wakeup management register offset */ +#define MAC_INTF_REG_OFFSET ((uint16_t)0x0038U) /*!< MAC interrupt flag register offset */ +#define MAC_INTMSK_REG_OFFSET ((uint16_t)0x003CU) /*!< MAC interrupt mask register offset */ + +#define MSC_RINTF_REG_OFFSET ((uint16_t)0x0104U) /*!< MSC receive interrupt flag register offset */ +#define MSC_TINTF_REG_OFFSET ((uint16_t)0x0108U) /*!< MSC transmit interrupt flag register offset */ +#define MSC_RINTMSK_REG_OFFSET ((uint16_t)0x010CU) /*!< MSC receive interrupt mask register offset */ +#define MSC_TINTMSK_REG_OFFSET ((uint16_t)0x0110U) /*!< MSC transmit interrupt mask register offset */ +#define MSC_SCCNT_REG_OFFSET ((uint16_t)0x014CU) /*!< MSC transmitted good frames after a single collision counter register offset */ +#define MSC_MSCCNT_REG_OFFSET ((uint16_t)0x0150U) /*!< MSC transmitted good frames after more than a single collision counter register offset */ +#define MSC_TGFCNT_REG_OFFSET ((uint16_t)0x0168U) /*!< MSC transmitted good frames counter register offset */ +#define MSC_RFCECNT_REG_OFFSET ((uint16_t)0x0194U) /*!< MSC received frames with CRC error counter register offset */ +#define MSC_RFAECNT_REG_OFFSET ((uint16_t)0x0198U) /*!< MSC received frames with alignment error counter register offset */ +#define MSC_RGUFCNT_REG_OFFSET ((uint16_t)0x01C4U) /*!< MSC received good unicast frames counter register offset */ + +#define PTP_TSF_REG_OFFSET ((uint16_t)0x0728U) /*!< PTP time stamp flag register offset */ + +#define DMA_STAT_REG_OFFSET ((uint16_t)0x1014U) /*!< DMA status register offset */ +#define DMA_INTEN_REG_OFFSET ((uint16_t)0x101CU) /*!< DMA interrupt enable register offset */ +#define DMA_TDTADDR_REG_OFFSET ((uint16_t)0x1010U) /*!< DMA transmit descriptor table address register offset */ +#define DMA_CTDADDR_REG_OFFSET ((uint16_t)0x1048U) /*!< DMA current transmit descriptor address register */ +#define DMA_CTBADDR_REG_OFFSET ((uint16_t)0x1050U) /*!< DMA current transmit buffer address register */ +#define DMA_RDTADDR_REG_OFFSET ((uint16_t)0x100CU) /*!< DMA receive descriptor table address register */ +#define DMA_CRDADDR_REG_OFFSET ((uint16_t)0x104CU) /*!< DMA current receive descriptor address register */ +#define DMA_CRBADDR_REG_OFFSET ((uint16_t)0x1054U) /*!< 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)0x00000000, /*!< 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)0x00000000), /*!< MAC address0 */ + ENET_MAC_ADDRESS1 = ((uint32_t)0x00000008), /*!< MAC address1 */ + ENET_MAC_ADDRESS2 = ((uint32_t)0x00000010), /*!< MAC address2 */ + ENET_MAC_ADDRESS3 = ((uint32_t)0x00000018) /*!< 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; + +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; + +/* 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 subsecond; /*!< subsecond 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) << 5)) /*!< 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) << 17)) /*!< 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) << 6)) /*!< 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) << 2)) /*!< 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-240 MHz; MDC clock= HCLK/102 */ + +#define MAC_PHY_CTL_PR(regval) (BITS(6,10) & ((uint32_t)(regval) << 6)) /*!< write value to ENET_MAC_PHY_CTL_PR bit field */ + +#define MAC_PHY_CTL_PA(regval) (BITS(11,15) & ((uint32_t)(regval) << 11)) /*!< 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) << 0)) /*!< 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) << 4)) /*!< 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) << 16)) /*!< write value to ENET_MAC_FCTL_PTM bit field */ +/* mac_vlt register value */ +#define MAC_VLT_VLTI(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< 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),1,2) /*!< get value of ENET_MAC_DBG_RXAFS bit field */ + +#define GET_MAC_DBG_RXFRS(regval) GET_BITS((regval),5,6) /*!< get value of ENET_MAC_DBG_RXFRS bit field */ + +#define GET_MAC_DBG_RXFS(regval) GET_BITS((regval),8,9) /*!< get value of ENET_MAC_DBG_RXFS bit field */ + +#define GET_MAC_DBG_SOMT(regval) GET_BITS((regval),17,18) /*!< get value of ENET_MAC_DBG_SOMT bit field */ + +#define GET_MAC_DBG_TXFRS(regval) GET_BITS((regval),20,21) /*!< get value of ENET_MAC_DBG_TXFRS bit field */ + +/* mac_addr0h register value */ +#define MAC_ADDR0H_ADDR0H(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) /*!< 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) << 0)) /*!< 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)0x00000000) /*!< 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) << 0)) << 8) /*!< 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) << 4)) << 8) /*!< 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 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) << 0)) /*!< write value to ENET_PTP_SSINC_STMSSI bit field */ + +/* ptp_tsl register value */ +#define GET_PTP_TSL_STMSS(regval) GET_BITS((uint32_t)(regval),0,30) /*!< get value of ENET_PTP_TSL_STMSS bit field */ + +#define ENET_PTP_TIME_POSITIVE ((uint32_t)0x00000000) /*!< 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) << 0)) /*!< write value to ENET_PTP_TSUL_TMSUSS bit field */ + +#define ENET_PTP_ADD_TO_TIME ((uint32_t)0x00000000) /*!< 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) << 0)) /*!< 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) << 2)) /*!< 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)0x00000000) /*!< normal mode descriptor */ + +#define DMA_BCTL_PGBL(regval) (BITS(8,13) & ((uint32_t)(regval) << 8)) /*!< 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) << 14)) /*!< 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)0x00000000) /*!< AHB can use SINGLE/INCR burst transfer operations */ + +#define DMA_BCTL_RXDP(regval) (BITS(17,22) & ((uint32_t)(regval) << 17)) /*!< 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)0x00000000) /*!< 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)0x00000000) /*!< 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)0x00000000) /*!< 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),17,19) /*!< get value of ENET_DMA_STAT_RP bit field */ +#define ENET_RX_STATE_STOPPED ((uint32_t)0x00000000) /*!< 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),20,22) /*!< get value of ENET_DMA_STAT_TP bit field */ +#define ENET_TX_STATE_STOPPED ((uint32_t)0x00000000) /*!< 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),23,25) /*!< 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) << 3)) /*!< 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) << 14)) /*!< 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)0x00000000) /*!< 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)0x00000000) /*!< RxFIFO operates in cut-through mode */ + +#define ENET_FLUSH_RXFRAME_ENABLE ((uint32_t)0x00000000) /*!< 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 flushes 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)0x00000000) /*!< TxFIFO operates in cut-through mode */ + +#define ENET_FORWARD_ERRFRAMES_ENABLE (ENET_DMA_CTL_FERF << 2) /*!< all frame received with error except runt error are forwarded to memory */ +#define ENET_FORWARD_ERRFRAMES_DISABLE ((uint32_t)0x00000000) /*!< RxFIFO drop error frame */ +#define ENET_FORWARD_ERRFRAMES (ENET_DMA_CTL_FERF << 2) /*!< 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 << 2) /*!< forward undersized good frames */ +#define ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE ((uint32_t)0x00000000) /*!< RxFIFO drops all frames whose length is less than 64 bytes */ +#define ENET_FORWARD_UNDERSZ_GOODFRAMES (ENET_DMA_CTL_FUF << 2) /*!< 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)0x00000000) /*!< 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),0,15) /*!< get value of ENET_DMA_MFBOCNT_MSFC bit field */ + +#define GET_DMA_MFBOCNT_MSFA(regval) GET_BITS((regval),17,27) /*!< get value of ENET_DMA_MFBOCNT_MSFA bit field */ + +/* dma_rswdc register value */ +#define DMA_RSWDC_WDCFRS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) /*!< 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) << 3)) /*!< write value to ENET DMA TDES0 CONT bit field */ +#define GET_TDES0_COCNT(regval) GET_BITS((regval),3,6) /*!< get value of ENET DMA TDES0 CONT bit field */ + +#define TDES0_CM(regval) (BITS(22,23) & ((uint32_t)(regval) << 22)) /*!< 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) << 0)) /*!< write value to ENET DMA TDES1 TB1S bit field */ + +#define TDES1_TB2S(regval) (BITS(16,28) & ((uint32_t)(regval) << 16)) /*!< 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) << 16)) /*!< write value to ENET DMA RDES0 FRML bit field */ +#define GET_RDES0_FRML(regval) GET_BITS((regval),16,29) /*!< 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),0,12) /*!< get value of ENET DMA RDES1 RB1S bit field */ + +#define GET_RDES1_RB2S(regval) GET_BITS((regval),16,28) /*!< 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) << 0)) /*!< write value to ENET DMA RDES4 IPPLDT bit field */ +#define GET_RDES4_IPPLDT(regval) GET_BITS((regval),0,2) /*!< get value of ENET DMA RDES4 IPPLDT bit field */ + +#define RDES4_PTPMT(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) /*!< write value to ENET DMA RDES4 PTPMT bit field */ +#define GET_RDES4_PTPMT(regval) GET_BITS((regval),8,11) /*!< 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 ((uint32_t)0x00000020U) /*!< TxDMA enhanced descriptor size */ +#define ETH_DMARXDESC_SIZE ((uint32_t)0x00000020U) /*!< RxDMA enhanced descriptor size */ +#else +#define ETH_DMATXDESC_SIZE ((uint32_t)0x00000010U) /*!< TxDMA descriptor size */ +#define ETH_DMARXDESC_SIZE ((uint32_t)0x00000010U) /*!< RxDMA descriptor size */ +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* 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 */ + + + +/* function declarations */ +/* main function */ +/* deinitialize the ENET, and reset structure parameters for ENET initialization */ +void enet_deinit(void); +/* 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(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(void); +/* check receive frame valid and return frame size */ +uint32_t enet_rxframe_size_get(void); +/* initialize the dma tx/rx descriptors's parameters in chain mode */ +void enet_descriptors_chain_init(enet_dmadirection_enum direction); +/* initialize the dma tx/rx descriptors's parameters in ring mode */ +void enet_descriptors_ring_init(enet_dmadirection_enum direction); +/* handle current received frame data to application buffer */ +ErrStatus enet_frame_receive(uint8_t *buffer, uint32_t bufsize); +/* handle current received frame but without data copy to application buffer */ +#define ENET_NOCOPY_FRAME_RECEIVE() enet_frame_receive(NULL, 0U) +/* handle application buffer data to transmit it */ +ErrStatus enet_frame_transmit(uint8_t *buffer, uint32_t length); +/* handle current transmit frame but without data copy from application buffer */ +#define ENET_NOCOPY_FRAME_TRANSMIT(len) enet_frame_transmit(NULL, (len)) +/* configure the transmit IP frame checksum offload calculation and insertion */ +void 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(void); +/* ENET Tx and Rx function disable (include MAC and DMA module) */ +void enet_disable(void); +/* configure MAC address */ +void enet_mac_address_set(enet_macaddress_enum mac_addr, uint8_t paddr[]); +/* get MAC address */ +void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]); + +/* get the ENET MAC/MSC/PTP/DMA status flag */ +FlagStatus enet_flag_get(enet_flag_enum enet_flag); +/* clear the ENET DMA status flag */ +void enet_flag_clear(enet_flag_clear_enum enet_flag); +/* enable ENET MAC/MSC/DMA interrupt */ +void enet_interrupt_enable(enet_int_enum enet_int); +/* disable ENET MAC/MSC/DMA interrupt */ +void enet_interrupt_disable(enet_int_enum enet_int); +/* get ENET MAC/MSC/DMA interrupt flag */ +FlagStatus enet_interrupt_flag_get(enet_int_flag_enum int_flag); +/* clear ENET DMA interrupt flag */ +void enet_interrupt_flag_clear(enet_int_flag_clear_enum int_flag_clear); + +/* MAC function */ +/* ENET Tx function enable (include MAC and DMA module) */ +void enet_tx_enable(void); +/* ENET Tx function disable (include MAC and DMA module) */ +void enet_tx_disable(void); +/* ENET Rx function enable (include MAC and DMA module) */ +void enet_rx_enable(void); +/* ENET Rx function disable (include MAC and DMA module) */ +void enet_rx_disable(void); +/* put registers value into the application buffer */ +void enet_registers_get(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 mac_debug); +/* enable the MAC address filter */ +void enet_address_filter_enable(enet_macaddress_enum mac_addr); +/* disable the MAC address filter */ +void enet_address_filter_disable(enet_macaddress_enum mac_addr); +/* configure the MAC address filter */ +void enet_address_filter_config(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(void); +/* write to/read from a PHY register */ +ErrStatus enet_phy_write_read(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(void); +/* disable the loopback function of phy chip */ +ErrStatus enet_phyloopback_disable(void); +/* enable ENET forward feature */ +void enet_forward_feature_enable(uint32_t feature); +/* disable ENET forward feature */ +void enet_forward_feature_disable(uint32_t feature); +/* enable ENET fliter feature */ +void enet_fliter_feature_enable(uint32_t feature); +/* disable ENET fliter feature */ +void enet_fliter_feature_disable(uint32_t feature); + +/* flow control function */ +/* generate the pause frame, ENET will send pause frame after enable transmit flow control */ +ErrStatus enet_pauseframe_generate(void); +/* configure the pause frame detect type */ +void enet_pauseframe_detect_config(uint32_t detect); +/* configure the pause frame parameters */ +void enet_pauseframe_config(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 deactive, uint32_t active); +/* enable ENET flow control feature */ +void enet_flowcontrol_feature_enable(uint32_t feature); +/* disable ENET flow control feature */ +void enet_flowcontrol_feature_disable(uint32_t feature); + +/* DMA function */ +/* get the dma transmit/receive process state */ +uint32_t enet_dmaprocess_state_get(enet_dmadirection_enum direction); +/* poll the dma transmission/reception enable */ +void enet_dmaprocess_resume(enet_dmadirection_enum direction); +/* check and recover the Rx process */ +void enet_rxprocess_check_recovery(void); +/* flush the ENET transmit fifo, and wait until the flush operation completes */ +ErrStatus enet_txfifo_flush(void); +/* get the transmit/receive address of current descriptor, or current buffer, or descriptor table */ +uint32_t enet_current_desc_address_get(enet_desc_reg_enum addr_get); +/* get the Tx or Rx descriptor information */ +uint32_t enet_desc_information_get(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 *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(enet_descriptors_struct *desc, uint32_t delay_time); +/* drop current receive frame */ +void enet_rxframe_drop(void); +/* enable DMA feature */ +void enet_dma_feature_enable(uint32_t feature); +/* disable DMA feature */ +void enet_dma_feature_disable(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(void); +/* initialize the dma Tx/Rx descriptors's parameters in enhanced chain mode with ptp function */ +void enet_ptp_enhanced_descriptors_chain_init(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(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(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(ptr) enet_ptpframe_receive_enhanced_mode(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(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(len, ptr) enet_ptpframe_transmit_enhanced_mode(NULL, (len), (ptr)) + +#else + +/* configure descriptor to work in normal mode */ +void enet_desc_select_normal_mode(void); +/* initialize the dma Tx/Rx descriptors's parameters in normal chain mode with ptp function */ +void enet_ptp_normal_descriptors_chain_init(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(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(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(ptr) enet_ptpframe_receive_normal_mode(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(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(len, ptr) enet_ptpframe_transmit_normal_mode(NULL, (len), (ptr)) + +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/* WUM function */ +/* wakeup frame filter register pointer reset */ +void enet_wum_filter_register_pointer_reset(void); +/* set the remote wakeup frame registers */ +void enet_wum_filter_config(uint32_t pdata[]); +/* enable wakeup management features */ +void enet_wum_feature_enable(uint32_t feature); +/* disable wakeup management features */ +void enet_wum_feature_disable(uint32_t feature); + +/* MSC function */ +/* reset the MAC statistics counters */ +void enet_msc_counters_reset(void); +/* enable the MAC statistics counter features */ +void enet_msc_feature_enable(uint32_t feature); +/* disable the MAC statistics counter features */ +void enet_msc_feature_disable(uint32_t feature); +/* configure MAC statistics counters preset mode */ +void enet_msc_counters_preset_config(enet_msc_preset_enum mode); +/* get MAC statistics counter */ +uint32_t enet_msc_counters_get(enet_msc_counter_enum counter); + +/* PTP function */ +/* enable the PTP features */ +void enet_ptp_feature_enable(uint32_t feature); +/* disable the PTP features */ +void enet_ptp_feature_disable(uint32_t feature); +/* configure the PTP timestamp function */ +ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func); +/* configure the PTP system time subsecond increment value */ +void enet_ptp_subsecond_increment_config(uint32_t subsecond); +/* adjusting the PTP clock frequency only in fine update mode */ +void enet_ptp_timestamp_addend_config(uint32_t add); +/* initializing or adding/subtracting to second of the PTP system time */ +void enet_ptp_timestamp_update_config(uint32_t sign, uint32_t second, uint32_t subsecond); +/* configure the PTP expected target time */ +void enet_ptp_expected_time_config(uint32_t second, uint32_t nanosecond); +/* get the PTP current system time */ +void enet_ptp_system_time_get(enet_ptp_systime_struct *systime_struct); +/* configure the PPS output frequency */ +void enet_ptp_pps_output_frequency_config(uint32_t freq); + + +/* internal function */ +/* reset the ENET initpara struct, call it before using enet_initpara_config() */ +void enet_initpara_reset(void); + + +#endif /* GD32F4XX_ENET_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exmc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exmc.h new file mode 100644 index 000000000..4b05227fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exmc.h @@ -0,0 +1,814 @@ +/*! + \file gd32f4xx_exmc.h + \brief definitions for the EXMC + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx + \version 2022-06-08, V3.0.1, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_EXMC_H +#define GD32F4XX_EXMC_H + +#include "gd32f4xx.h" + +/* EXMC definitions */ +#define EXMC (EXMC_BASE) /*!< EXMC register base address */ +#define EXMC_NOR_PSRAM (EXMC_BASE - 0x40000000) /*!< EXMC NOR/PSRAM base address */ +#define EXMC_NAND (EXMC_BASE - 0x30000000) /*!< EXMC NAND base address */ +#define EXMC_PCCARD (EXMC_BASE - 0x10000000) /*!< EXMC PC card base address */ +#define EXMC_SDRAM (EXMC_BASE + 0x20000000) /*!< EXMC SDRAM base address */ + +/* registers definitions */ +/* NOR/PSRAM */ +#define EXMC_SNCTL0 REG32(EXMC + 0x00U) /*!< EXMC SRAM/NOR flash control register for region0 */ +#define EXMC_SNTCFG0 REG32(EXMC + 0x04U) /*!< EXMC SRAM/NOR flash timing configuration register for region0 */ +#define EXMC_SNWTCFG0 REG32(EXMC + 0x104U) /*!< EXMC SRAM/NOR flash write timing configuration register for region0 */ + +#define EXMC_SNCTL1 REG32(EXMC + 0x08U) /*!< EXMC SRAM/NOR flash control register for region1 */ +#define EXMC_SNTCFG1 REG32(EXMC + 0x0CU) /*!< EXMC SRAM/NOR flash timing configuration register for region1 */ +#define EXMC_SNWTCFG1 REG32(EXMC + 0x10CU) /*!< EXMC SRAM/NOR flash write timing configuration register for region1 */ + +#define EXMC_SNCTL2 REG32(EXMC + 0x10U) /*!< EXMC SRAM/NOR flash control register for region2 */ +#define EXMC_SNTCFG2 REG32(EXMC + 0x14U) /*!< EXMC SRAM/NOR flash timing configuration register for region2 */ +#define EXMC_SNWTCFG2 REG32(EXMC + 0x114U) /*!< EXMC SRAM/NOR flash write timing configuration register for region2 */ + +#define EXMC_SNCTL3 REG32(EXMC + 0x18U) /*!< EXMC SRAM/NOR flash control register for region3 */ +#define EXMC_SNTCFG3 REG32(EXMC + 0x1CU) /*!< EXMC SRAM/NOR flash timing configuration register for region3 */ +#define EXMC_SNWTCFG3 REG32(EXMC + 0x11CU) /*!< EXMC SRAM/NOR flash write timing configuration register for region3 */ + +/* NAND/PC card */ +#define EXMC_NPCTL1 REG32(EXMC + 0x60U) /*!< EXMC NAND/PC card control register for bank1 */ +#define EXMC_NPINTEN1 REG32(EXMC + 0x64U) /*!< EXMC NAND/PC card interrupt enable register for bank1 */ +#define EXMC_NPCTCFG1 REG32(EXMC + 0x68U) /*!< EXMC NAND/PC card common space timing configuration register for bank1 */ +#define EXMC_NPATCFG1 REG32(EXMC + 0x6CU) /*!< EXMC NAND/PC card attribute space timing configuration register for bank1 */ +#define EXMC_NECC1 REG32(EXMC + 0x74U) /*!< EXMC NAND ECC register */ + +#define EXMC_NPCTL2 REG32(EXMC + 0x80U) /*!< EXMC NAND/PC card control register for bank2 */ +#define EXMC_NPINTEN2 REG32(EXMC + 0x84U) /*!< EXMC NAND/PC card interrupt enable register for bank2 */ +#define EXMC_NPCTCFG2 REG32(EXMC + 0x88U) /*!< EXMC NAND/PC card common space timing configuration register for bank2 */ +#define EXMC_NPATCFG2 REG32(EXMC + 0x8CU) /*!< EXMC NAND/PC card attribute space timing configuration register for bank2 */ +#define EXMC_NECC2 REG32(EXMC + 0x94U) /*!< EXMC NAND ECC register */ + +#define EXMC_NPCTL3 REG32(EXMC + 0xA0U) /*!< EXMC NAND/PC card control register for bank3 */ +#define EXMC_NPINTEN3 REG32(EXMC + 0xA4U) /*!< EXMC NAND/PC card interrupt enable register for bank3 */ +#define EXMC_NPCTCFG3 REG32(EXMC + 0xA8U) /*!< EXMC NAND/PC card common space timing configuration register for bank3 */ +#define EXMC_NPATCFG3 REG32(EXMC + 0xACU) /*!< EXMC NAND/PC card attribute space timing configuration register for bank3 */ +#define EXMC_PIOTCFG3 REG32(EXMC + 0xB0U) /*!< EXMC PC card I/O space timing configuration register for bank3 */ + +/* SDRAM */ +#define EXMC_SDCTL0 REG32(EXMC + 0x140U) /*!< EXMC SDRAM control register for device0 */ +#define EXMC_SDTCFG0 REG32(EXMC + 0x148U) /*!< EXMC SDRAM timing configuration register register for device0 */ + +#define EXMC_SDCTL1 REG32(EXMC + 0x144U) /*!< EXMC SDRAM control register for device1 */ +#define EXMC_SDTCFG1 REG32(EXMC + 0x14CU) /*!< EXMC SDRAM timing configuration register register for device1 */ + +#define EXMC_SDCMD REG32(EXMC + 0x150U) /*!< EXMC SDRAM command register */ +#define EXMC_SDARI REG32(EXMC + 0x154U) /*!< EXMC SDRAM auto-refresh interval register */ +#define EXMC_SDSTAT REG32(EXMC + 0x158U) /*!< EXMC SDRAM status register */ +#define EXMC_SDRSCTL REG32(EXMC + 0x180U) /*!< EXMC SDRAM read sample control register */ + +/* SQPI PSRAM */ +#define EXMC_SINIT REG32(EXMC + 0x310U) /*!< EXMC SPI initialization register */ +#define EXMC_SRCMD REG32(EXMC + 0x320U) /*!< EXMC SPI read command register */ +#define EXMC_SWCMD REG32(EXMC + 0x330U) /*!< EXMC SPI write command register */ +#define EXMC_SIDL REG32(EXMC + 0x340U) /*!< EXMC SPI ID low register */ +#define EXMC_SIDH REG32(EXMC + 0x350U) /*!< EXMC SPI ID high register */ + +/* bits definitions */ +/* EXMC_SNCTLx,x=0..3 */ +#define EXMC_SNCTL_NRBKEN BIT(0) /*!< NOR bank enable */ +#define EXMC_SNCTL_NRMUX BIT(1) /*!< NOR bank memory address/data multiplexing enable */ +#define EXMC_SNCTL_NRTP BITS(2,3) /*!< NOR bank memory type */ +#define EXMC_SNCTL_NRW BITS(4,5) /*!< NOR bank 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_WRAPEN BIT(10) /*!< wrapped burst mode enable */ +#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 */ + +/* 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_NPCTLx,x=1..3 */ +#define EXMC_NPCTL_NDWTEN BIT(1) /*!< wait feature enable */ +#define EXMC_NPCTL_NDBKEN BIT(2) /*!< NAND bank enable */ +#define EXMC_NPCTL_NDTP BIT(3) /*!< NAND bank memory type */ +#define EXMC_NPCTL_NDW BITS(4,5) /*!< NAND bank memory data bus width */ +#define EXMC_NPCTL_ECCEN BIT(6) /*!< ECC enable */ +#define EXMC_NPCTL_CTR BITS(9,12) /*!< CLE to RE delay */ +#define EXMC_NPCTL_ATR BITS(13,16) /*!< ALE to RE delay */ +#define EXMC_NPCTL_ECCSZ BITS(17,19) /*!< ECC size */ + +/* EXMC_NPINTENx,x=1..3 */ +#define EXMC_NPINTEN_INTRS BIT(0) /*!< interrupt rising edge status */ +#define EXMC_NPINTEN_INTHS BIT(1) /*!< interrupt high-level status */ +#define EXMC_NPINTEN_INTFS BIT(2) /*!< interrupt falling edge status */ +#define EXMC_NPINTEN_INTREN BIT(3) /*!< interrupt rising edge detection enable */ +#define EXMC_NPINTEN_INTHEN BIT(4) /*!< interrupt high-level detection enable */ +#define EXMC_NPINTEN_INTFEN BIT(5) /*!< interrupt falling edge detection enable */ +#define EXMC_NPINTEN_FFEPT BIT(6) /*!< FIFO empty flag */ + +/* EXMC_NPCTCFGx,x=1..3 */ +#define EXMC_NPCTCFG_COMSET BITS(0,7) /*!< common memory setup time */ +#define EXMC_NPCTCFG_COMWAIT BITS(8,15) /*!< common memory wait time */ +#define EXMC_NPCTCFG_COMHLD BITS(16,23) /*!< common memory hold time */ +#define EXMC_NPCTCFG_COMHIZ BITS(24,31) /*!< common memory data bus HiZ time */ + +/* EXMC_NPATCFGx,x=1..3 */ +#define EXMC_NPATCFG_ATTSET BITS(0,7) /*!< attribute memory setup time */ +#define EXMC_NPATCFG_ATTWAIT BITS(8,15) /*!< attribute memory wait time */ +#define EXMC_NPATCFG_ATTHLD BITS(16,23) /*!< attribute memory hold time */ +#define EXMC_NPATCFG_ATTHIZ BITS(24,31) /*!< attribute memory data bus HiZ time */ + +/* EXMC_PIOTCFG3 */ +#define EXMC_PIOTCFG3_IOSET BITS(0,7) /*!< IO space setup time */ +#define EXMC_PIOTCFG3_IOWAIT BITS(8,15) /*!< IO space wait time */ +#define EXMC_PIOTCFG3_IOHLD BITS(16,23) /*!< IO space hold time */ +#define EXMC_PIOTCFG3_IOHIZ BITS(24,31) /*!< IO space data bus HiZ time */ + +/* EXMC_NECCx,x=1..2 */ +#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 */ +#define EXMC_SDCTL_PIPED BITS(13,14) /*!< pipeline delay */ + +/* 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 */ + +/* 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 */ +#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 */ + +/* EXMC_SINIT */ +#define EXMC_SINIT_CMDBIT BITS(16,17) /*!< bit number of SPI PSRAM command phase */ +#define EXMC_SINIT_ARDBIT BITS(24,28) /*!< bit number of SPI PSRAM address phase */ +#define EXMC_SINIT_IDL BITS(29,30) /*!< SPI PSRAM ID length */ +#define EXMC_SINIT_POL BIT(31) /*!< read data sample polarity */ + +/* EXMC_SRCMD */ +#define EXMC_SRCMD_RCMD BITS(0,15) /*!< SPI read command for AHB read transfer */ +#define EXMC_SRCMD_RWAITCYCLE BITS(16,19) /*!< SPI read wait cycle number after address phase */ +#define EXMC_SRCMD_RMODE BITS(20,21) /*!< SPI PSRAM read command mode */ +#define EXMC_SRCMD_RDID BIT(31) /*!< send SPI read ID command */ + +/* EXMC_SWCMD */ +#define EXMC_SWCMD_WCMD BITS(0,15) /*!< SPI write command for AHB write transfer */ +#define EXMC_SWCMD_WWAITCYCLE BITS(16,19) /*!< SPI write wait cycle number after address phase */ +#define EXMC_SWCMD_WMODE BITS(20,21) /*!< SPI PSRAM write command mode */ +#define EXMC_SWCMD_SC BIT(31) /*!< send SPI special command */ + +/* EXMC_SIDL */ +#define EXMC_SIDL_SIDL BITS(0,31) /*!< ID low data saved for SPI read ID command */ + +/* EXMC_SIDH */ +#define EXMC_SIDL_SIDH BITS(0,31) /*!< ID high Data saved for SPI read ID command */ + +/* 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/SRAM bank */ + uint32_t write_mode; /*!< the write mode, synchronous mode or asynchronous mode */ + uint32_t extended_mode; /*!< enable or disable the extended mode */ + uint32_t asyn_wait; /*!< enable or disable the asynchronous wait function */ + uint32_t nwait_signal; /*!< enable or disable the NWAIT signal while in synchronous bust mode */ + uint32_t memory_write; /*!< enable or disable the write operation */ + uint32_t nwait_config; /*!< NWAIT signal configuration */ + uint32_t wrap_burst_mode; /*!< enable or disable the wrap burst mode */ + uint32_t nwait_polarity; /*!< specifies the polarity of NWAIT signal from memory */ + uint32_t burst_mode; /*!< enable or disable the burst mode */ + uint32_t databus_width; /*!< specifies the databus width of external memory */ + uint32_t memory_type; /*!< specifies the type of external memory */ + uint32_t address_data_mux; /*!< specifies whether the data bus and address bus are multiplexed */ + 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/PC card 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_pccard_timing_parameter_struct; + +/* EXMC NAND initialize structure */ +typedef struct +{ + uint32_t nand_bank; /*!< select the bank of NAND */ + 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_pccard_timing_parameter_struct* common_space_timing; /*!< the timing parameters for NAND flash common space */ + exmc_nand_pccard_timing_parameter_struct* attribute_space_timing; /*!< the timing parameters for NAND flash attribute space */ +}exmc_nand_parameter_struct; + +/* EXMC PC card initialize structure */ +typedef struct +{ + 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 wait_feature; /*!< enable or disable the wait feature */ + exmc_nand_pccard_timing_parameter_struct* common_space_timing; /*!< the timing parameters for PC card common space */ + exmc_nand_pccard_timing_parameter_struct* attribute_space_timing; /*!< the timing parameters for PC card attribute space */ + exmc_nand_pccard_timing_parameter_struct* io_space_timing; /*!< the timing parameters for PC card IO space */ +}exmc_pccard_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 HCLK clock cycles */ + uint32_t burst_read_switch; /*!< enable or disable the burst read */ + uint32_t sdclock_config; /*!< the SDCLK memory clock for both SDRAM banks */ + uint32_t write_protection; /*!< enable or disable SDRAM bank 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 SQPISRAM initialize structure */ +typedef struct{ + uint32_t sample_polarity; /*!< read data sample polarity */ + uint32_t id_length; /*!< SPI PSRAM ID length */ + uint32_t address_bits; /*!< bit number of SPI PSRAM address phase */ + uint32_t command_bits; /*!< bit number of SPI PSRAM command phase */ +}exmc_sqpipsram_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_NPCTL(bank) REG32(EXMC + 0x40U + 0x20U*((uint32_t)(bank))) /*!< EXMC NAND/PC card control registers, bank = 1,2,3 */ +#define EXMC_NPINTEN(bank) REG32(EXMC + 0x44U + 0x20U*((uint32_t)(bank))) /*!< EXMC NAND/PC card interrupt enable registers, bank = 1,2,3 */ +#define EXMC_NPCTCFG(bank) REG32(EXMC + 0x48U + 0x20U*((uint32_t)(bank))) /*!< EXMC NAND/PC card common space timing configuration registers, bank = 1,2,3 */ +#define EXMC_NPATCFG(bank) REG32(EXMC + 0x4CU + 0x20U*((uint32_t)(bank))) /*!< EXMC NAND/PC card attribute space timing configuration registers, bank = 1,2,3 */ +#define EXMC_NECC(bank) REG32(EXMC + 0x54U + 0x20U*((uint32_t)(bank))) /*!< EXMC NAND ECC registers, bank = 1,2 */ + +#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 */ + +/* 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 bank 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 bank 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) /*!< EXMC_CLK disable */ +#define EXMC_SYN_CLOCK_RATIO_2_CLK SNTCFG_CKDIV(1) /*!< EXMC_CLK = 2*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_3_CLK SNTCFG_CKDIV(2) /*!< EXMC_CLK = 3*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_4_CLK SNTCFG_CKDIV(3) /*!< EXMC_CLK = 4*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_5_CLK SNTCFG_CKDIV(4) /*!< EXMC_CLK = 5*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_6_CLK SNTCFG_CKDIV(5) /*!< EXMC_CLK = 6*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_7_CLK SNTCFG_CKDIV(6) /*!< EXMC_CLK = 7*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_8_CLK SNTCFG_CKDIV(7) /*!< EXMC_CLK = 8*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_9_CLK SNTCFG_CKDIV(8) /*!< EXMC_CLK = 9*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_10_CLK SNTCFG_CKDIV(9) /*!< EXMC_CLK = 10*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_11_CLK SNTCFG_CKDIV(10) /*!< EXMC_CLK = 11*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_12_CLK SNTCFG_CKDIV(11) /*!< EXMC_CLK = 12*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_13_CLK SNTCFG_CKDIV(12) /*!< EXMC_CLK = 13*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_14_CLK SNTCFG_CKDIV(13) /*!< EXMC_CLK = 14*HCLK*/ +#define EXMC_SYN_CLOCK_RATIO_15_CLK SNTCFG_CKDIV(14) /*!< EXMC_CLK = 15*HCLK */ +#define EXMC_SYN_CLOCK_RATIO_16_CLK SNTCFG_CKDIV(15) /*!< EXMC_CLK = 16*HCLK */ + +/* ECC size */ +#define NPCTL_ECCSZ(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) +#define EXMC_ECC_SIZE_256BYTES NPCTL_ECCSZ(0) /* ECC size is 256 bytes */ +#define EXMC_ECC_SIZE_512BYTES NPCTL_ECCSZ(1) /* ECC size is 512 bytes */ +#define EXMC_ECC_SIZE_1024BYTES NPCTL_ECCSZ(2) /* ECC size is 1024 bytes */ +#define EXMC_ECC_SIZE_2048BYTES NPCTL_ECCSZ(3) /* ECC size is 2048 bytes */ +#define EXMC_ECC_SIZE_4096BYTES NPCTL_ECCSZ(4) /* ECC size is 4096 bytes */ +#define EXMC_ECC_SIZE_8192BYTES NPCTL_ECCSZ(5) /* ECC size is 8192 bytes */ + +/* ALE to RE delay */ +#define NPCTL_ATR(regval) (BITS(13,16) & ((uint32_t)(regval) << 13)) +#define EXMC_ALE_RE_DELAY_1_HCLK NPCTL_ATR(0) /* ALE to RE delay = 1*HCLK */ +#define EXMC_ALE_RE_DELAY_2_HCLK NPCTL_ATR(1) /* ALE to RE delay = 2*HCLK */ +#define EXMC_ALE_RE_DELAY_3_HCLK NPCTL_ATR(2) /* ALE to RE delay = 3*HCLK */ +#define EXMC_ALE_RE_DELAY_4_HCLK NPCTL_ATR(3) /* ALE to RE delay = 4*HCLK */ +#define EXMC_ALE_RE_DELAY_5_HCLK NPCTL_ATR(4) /* ALE to RE delay = 5*HCLK */ +#define EXMC_ALE_RE_DELAY_6_HCLK NPCTL_ATR(5) /* ALE to RE delay = 6*HCLK */ +#define EXMC_ALE_RE_DELAY_7_HCLK NPCTL_ATR(6) /* ALE to RE delay = 7*HCLK */ +#define EXMC_ALE_RE_DELAY_8_HCLK NPCTL_ATR(7) /* ALE to RE delay = 8*HCLK */ +#define EXMC_ALE_RE_DELAY_9_HCLK NPCTL_ATR(8) /* ALE to RE delay = 9*HCLK */ +#define EXMC_ALE_RE_DELAY_10_HCLK NPCTL_ATR(9) /* ALE to RE delay = 10*HCLK */ +#define EXMC_ALE_RE_DELAY_11_HCLK NPCTL_ATR(10) /* ALE to RE delay = 11*HCLK */ +#define EXMC_ALE_RE_DELAY_12_HCLK NPCTL_ATR(11) /* ALE to RE delay = 12*HCLK */ +#define EXMC_ALE_RE_DELAY_13_HCLK NPCTL_ATR(12) /* ALE to RE delay = 13*HCLK */ +#define EXMC_ALE_RE_DELAY_14_HCLK NPCTL_ATR(13) /* ALE to RE delay = 14*HCLK */ +#define EXMC_ALE_RE_DELAY_15_HCLK NPCTL_ATR(14) /* ALE to RE delay = 15*HCLK */ +#define EXMC_ALE_RE_DELAY_16_HCLK NPCTL_ATR(15) /* ALE to RE delay = 16*HCLK */ + +/* CLE to RE delay */ +#define NPCTL_CTR(regval) (BITS(9,12) & ((uint32_t)(regval) << 9)) +#define EXMC_CLE_RE_DELAY_1_HCLK NPCTL_CTR(0) /* CLE to RE delay = 1*HCLK */ +#define EXMC_CLE_RE_DELAY_2_HCLK NPCTL_CTR(1) /* CLE to RE delay = 2*HCLK */ +#define EXMC_CLE_RE_DELAY_3_HCLK NPCTL_CTR(2) /* CLE to RE delay = 3*HCLK */ +#define EXMC_CLE_RE_DELAY_4_HCLK NPCTL_CTR(3) /* CLE to RE delay = 4*HCLK */ +#define EXMC_CLE_RE_DELAY_5_HCLK NPCTL_CTR(4) /* CLE to RE delay = 5*HCLK */ +#define EXMC_CLE_RE_DELAY_6_HCLK NPCTL_CTR(5) /* CLE to RE delay = 6*HCLK */ +#define EXMC_CLE_RE_DELAY_7_HCLK NPCTL_CTR(6) /* CLE to RE delay = 7*HCLK */ +#define EXMC_CLE_RE_DELAY_8_HCLK NPCTL_CTR(7) /* CLE to RE delay = 8*HCLK */ +#define EXMC_CLE_RE_DELAY_9_HCLK NPCTL_CTR(8) /* CLE to RE delay = 9*HCLK */ +#define EXMC_CLE_RE_DELAY_10_HCLK NPCTL_CTR(9) /* CLE to RE delay = 10*HCLK */ +#define EXMC_CLE_RE_DELAY_11_HCLK NPCTL_CTR(10) /* CLE to RE delay = 11*HCLK */ +#define EXMC_CLE_RE_DELAY_12_HCLK NPCTL_CTR(11) /* CLE to RE delay = 12*HCLK */ +#define EXMC_CLE_RE_DELAY_13_HCLK NPCTL_CTR(12) /* CLE to RE delay = 13*HCLK */ +#define EXMC_CLE_RE_DELAY_14_HCLK NPCTL_CTR(13) /* CLE to RE delay = 14*HCLK */ +#define EXMC_CLE_RE_DELAY_15_HCLK NPCTL_CTR(14) /* CLE to RE delay = 15*HCLK */ +#define EXMC_CLE_RE_DELAY_16_HCLK NPCTL_CTR(15) /* CLE to RE delay = 16*HCLK */ + +/* NAND bank memory data bus width */ +#define NPCTL_NDW(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define EXMC_NAND_DATABUS_WIDTH_8B NPCTL_NDW(0) /*!< NAND data width is 8 bits */ +#define EXMC_NAND_DATABUS_WIDTH_16B NPCTL_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_HCLK SDCTL_PIPED(0) /*!< 0 HCLK clock cycle delay */ +#define EXMC_PIPELINE_DELAY_1_HCLK SDCTL_PIPED(1) /*!< 1 HCLK clock cycle delay */ +#define EXMC_PIPELINE_DELAY_2_HCLK SDCTL_PIPED(2) /*!< 2 HCLK 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_HCLK SDCTL_SDCLK(2) /*!< SDCLK memory period = 2*HCLK */ +#define EXMC_SDCLK_PERIODS_3_HCLK SDCTL_SDCLK(3) /*!< SDCLK memory period = 3*HCLK */ + +/* 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 */ + +/* SPI PSRAM ID length */ +#define SINIT_IDL(regval) (BITS(29,30) & ((uint32_t)(regval) << 29)) +#define EXMC_SQPIPSRAM_ID_LENGTH_64B SINIT_IDL(0) /*!< SPI PSRAM ID length is 64 bits */ +#define EXMC_SQPIPSRAM_ID_LENGTH_32B SINIT_IDL(1) /*!< SPI PSRAM ID length is 32 bits */ +#define EXMC_SQPIPSRAM_ID_LENGTH_16B SINIT_IDL(2) /*!< SPI PSRAM ID length is 16 bits */ +#define EXMC_SQPIPSRAM_ID_LENGTH_8B SINIT_IDL(3) /*!< SPI PSRAM ID length is 8 bits */ + +/* SPI PSRAM bit number of address phase */ +#define SINIT_ADRBIT(regval) (BITS(24,28) & ((uint32_t)(regval) << 24)) +#define EXMC_SQPIPSRAM_ADDR_LENGTH_1B SINIT_ADRBIT(1) /*!< SPI PSRAM address is 1 bit */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_2B SINIT_ADRBIT(2) /*!< SPI PSRAM address is 2 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_3B SINIT_ADRBIT(3) /*!< SPI PSRAM address is 3 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_4B SINIT_ADRBIT(4) /*!< SPI PSRAM address is 4 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_5B SINIT_ADRBIT(5) /*!< SPI PSRAM address is 5 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_6B SINIT_ADRBIT(6) /*!< SPI PSRAM address is 6 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_7B SINIT_ADRBIT(7) /*!< SPI PSRAM address is 7 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_8B SINIT_ADRBIT(8) /*!< SPI PSRAM address is 8 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_9B SINIT_ADRBIT(9) /*!< SPI PSRAM address is 9 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_10B SINIT_ADRBIT(10) /*!< SPI PSRAM address is 10 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_11B SINIT_ADRBIT(11) /*!< SPI PSRAM address is 11 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_12B SINIT_ADRBIT(12) /*!< SPI PSRAM address is 12 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_13B SINIT_ADRBIT(13) /*!< SPI PSRAM address is 13 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_14B SINIT_ADRBIT(14) /*!< SPI PSRAM address is 14 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_15B SINIT_ADRBIT(15) /*!< SPI PSRAM address is 15 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_16B SINIT_ADRBIT(16) /*!< SPI PSRAM address is 16 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_17B SINIT_ADRBIT(17) /*!< SPI PSRAM address is 17 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_18B SINIT_ADRBIT(18) /*!< SPI PSRAM address is 18 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_19B SINIT_ADRBIT(19) /*!< SPI PSRAM address is 19 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_20B SINIT_ADRBIT(20) /*!< SPI PSRAM address is 20 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_21B SINIT_ADRBIT(21) /*!< SPI PSRAM address is 21 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_22B SINIT_ADRBIT(22) /*!< SPI PSRAM address is 22 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_23B SINIT_ADRBIT(23) /*!< SPI PSRAM address is 23 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_24B SINIT_ADRBIT(24) /*!< SPI PSRAM address is 24 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_25B SINIT_ADRBIT(25) /*!< SPI PSRAM address is 25 bits */ +#define EXMC_SQPIPSRAM_ADDR_LENGTH_26B SINIT_ADRBIT(26) /*!< SPI PSRAM address is 26 bits */ + +/* SPI PSRAM bit number of command phase */ +#define SINIT_CMDBIT(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) +#define EXMC_SQPIPSRAM_COMMAND_LENGTH_4B SINIT_CMDBIT(0) /*!< SPI PSRAM command is 4 bits */ +#define EXMC_SQPIPSRAM_COMMAND_LENGTH_8B SINIT_CMDBIT(1) /*!< SPI PSRAM command is 8 bits */ +#define EXMC_SQPIPSRAM_COMMAND_LENGTH_16B SINIT_CMDBIT(2) /*!< SPI PSRAM command is 16 bits */ + +/* SPI PSRAM read command mode */ +#define SRCMD_RMODE(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define EXMC_SQPIPSRAM_READ_MODE_DISABLE SRCMD_RMODE(0) /*!< not SPI mode */ +#define EXMC_SQPIPSRAM_READ_MODE_SPI SRCMD_RMODE(1) /*!< SPI mode */ +#define EXMC_SQPIPSRAM_READ_MODE_SQPI SRCMD_RMODE(2) /*!< SQPI mode */ +#define EXMC_SQPIPSRAM_READ_MODE_QPI SRCMD_RMODE(3) /*!< QPI mode */ + +/* SPI PSRAM write command mode */ +#define SRCMD_WMODE(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define EXMC_SQPIPSRAM_WRITE_MODE_DISABLE SRCMD_WMODE(0) /*!< not SPI mode */ +#define EXMC_SQPIPSRAM_WRITE_MODE_SPI SRCMD_WMODE(1) /*!< SPI mode */ +#define EXMC_SQPIPSRAM_WRITE_MODE_SQPI SRCMD_WMODE(2) /*!< SQPI mode */ +#define EXMC_SQPIPSRAM_WRITE_MODE_QPI SRCMD_WMODE(3) /*!< QPI mode */ + +/* 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/PC card bank definition */ +#define EXMC_BANK1_NAND ((uint32_t)0x00000001U) /*!< NAND flash bank1 */ +#define EXMC_BANK2_NAND ((uint32_t)0x00000002U) /*!< NAND flash bank2 */ +#define EXMC_BANK3_PCCARD ((uint32_t)0x00000003U) /*!< PC card bank3 */ + +/* 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 selection */ +#define EXMC_SDRAM_DEVICE0_UNSELECT ((uint32_t)0x00000000U) /*!< unselect SDRAM device0 */ +#define EXMC_SDRAM_DEVICE0_SELECT EXMC_SDCMD_DS0 /*!< select SDRAM device0 */ + +/* SDRAM device1 selection */ +#define EXMC_SDRAM_DEVICE1_UNSELECT ((uint32_t)0x00000000U) /*!< unselect SDRAM device1 */ +#define EXMC_SDRAM_DEVICE1_SELECT EXMC_SDCMD_DS1 /*!< select SDRAM device1 */ + +/* 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_EXTRAHCLK ((uint32_t)0x00000000U) /*!< add 0 extra HCLK cycle to the read data sample clock besides the delay chain */ +#define EXMC_SDRAM_READSAMPLE_1_EXTRAHCLK EXMC_SDRSCTL_SSCR /*!< add 1 extra HCLK cycle to the read data sample clock besides the delay chain */ + +/* read data sample polarity */ +#define EXMC_SQPIPSRAM_SAMPLE_RISING_EDGE ((uint32_t)0x00000000U) /*!< sample data at rising edge */ +#define EXMC_SQPIPSRAM_SAMPLE_FALLING_EDGE EXMC_SINIT_POL /*!< sample data at falling edge */ + +/* SQPI SRAM command flag */ +#define EXMC_SEND_COMMAND_FLAG_RDID EXMC_SRCMD_RDID /*!< EXMC_SRCMD_RDID flag bit */ +#define EXMC_SEND_COMMAND_FLAG_SC EXMC_SWCMD_SC /*!< EXMC_SWCMD_SC flag bit */ + +/* EXMC flag bits */ +#define EXMC_NAND_PCCARD_FLAG_RISE EXMC_NPINTEN_INTRS /*!< interrupt rising edge status */ +#define EXMC_NAND_PCCARD_FLAG_LEVEL EXMC_NPINTEN_INTHS /*!< interrupt high-level status */ +#define EXMC_NAND_PCCARD_FLAG_FALL EXMC_NPINTEN_INTFS /*!< interrupt falling edge status */ +#define EXMC_NAND_PCCARD_FLAG_FIFOE EXMC_NPINTEN_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 flag bits */ +#define EXMC_NAND_PCCARD_INT_FLAG_RISE EXMC_NPINTEN_INTREN /*!< rising edge interrupt and flag */ +#define EXMC_NAND_PCCARD_INT_FLAG_LEVEL EXMC_NPINTEN_INTHEN /*!< high-level interrupt and flag */ +#define EXMC_NAND_PCCARD_INT_FLAG_FALL EXMC_NPINTEN_INTFEN /*!< falling edge interrupt and flag */ +#define EXMC_SDRAM_INT_FLAG_REFRESH EXMC_SDARI_REIE /*!< refresh error interrupt and 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(uint32_t exmc_nand_bank); +/* 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(uint32_t exmc_nand_bank); +/* disable EXMC NAND bank */ +void exmc_nand_disable(uint32_t exmc_nand_bank); +/* PC card */ +/* deinitialize EXMC PC card bank */ +void exmc_pccard_deinit(void); +/* initialize exmc_pccard_parameter_struct with the default values */ +void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct); +/* initialize EXMC PC card bank */ +void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct); +/* enable EXMC PC card bank */ +void exmc_pccard_enable(void); +/* disable EXMC PC card bank */ +void exmc_pccard_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); +/* initialize exmc_sdram_command_parameter_struct with the default values */ +void exmc_sdram_struct_command_para_init(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct); +/* SQPIPSRAM */ +/* deinitialize EXMC SQPIPSRAM */ +void exmc_sqpipsram_deinit(void); +/* initialize exmc_sqpipsram_parameter_struct with the default values */ +void exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct); +/* initialize EXMC SQPIPSRAM */ +void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct* exmc_sqpipsram_init_struct); + +/* function configuration */ +/* NOR/SRAM */ +/* configure consecutive clock */ +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(uint32_t exmc_nand_bank, ControlStatus newvalue); +/* get the EXMC ECC value */ +uint32_t exmc_ecc_get(uint32_t exmc_nand_bank); +/* SDRAM */ +/* enable or disable read sample */ +void exmc_sdram_readsample_enable(ControlStatus newvalue); +/* configure the delayed sample clock of read data */ +void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk); +/* 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); +/* SQPIPSRAM */ +/* set the read command */ +void exmc_sqpipsram_read_command_set(uint32_t read_command_mode,uint32_t read_wait_cycle,uint32_t read_command_code); +/* set the write command */ +void exmc_sqpipsram_write_command_set(uint32_t write_command_mode,uint32_t write_wait_cycle,uint32_t write_command_code); +/* send SPI read ID command */ +void exmc_sqpipsram_read_id_command_send(void); +/* send SPI special command which does not have address and data phase */ +void exmc_sqpipsram_write_cmd_send(void); +/* get the EXMC SPI ID low data */ +uint32_t exmc_sqpipsram_low_id_get(void); +/* get the EXMC SPI ID high data */ +uint32_t exmc_sqpipsram_high_id_get(void); +/* get the bit value of EXMC send write command bit or read ID command */ +FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag); + +/* interrupt & flag functions */ +/* 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 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); +/* 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 /* GD32F4XX_EXMC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exti.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exti.h new file mode 100644 index 000000000..abba09dcc --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_exti.h @@ -0,0 +1,274 @@ +/*! + \file gd32f4xx_exti.h + \brief definitions for the EXTI + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_EXTI_H +#define GD32F4XX_EXTI_H + +#include "gd32f4xx.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x04U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x08U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x10U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x14U) /*!< pending register */ + +/* bits definitions */ +/* EXTI_INTEN */ +#define EXTI_INTEN_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN_INTEN18 BIT(18) /*!< interrupt from line 18 */ +#define EXTI_INTEN_INTEN19 BIT(19) /*!< interrupt from line 19 */ +#define EXTI_INTEN_INTEN20 BIT(20) /*!< interrupt from line 20 */ +#define EXTI_INTEN_INTEN21 BIT(21) /*!< interrupt from line 21 */ +#define EXTI_INTEN_INTEN22 BIT(22) /*!< interrupt from line 22 */ + +/* EXTI_EVEN */ +#define EXTI_EVEN_EVEN0 BIT(0) /*!< event from line 0 */ +#define EXTI_EVEN_EVEN1 BIT(1) /*!< event from line 1 */ +#define EXTI_EVEN_EVEN2 BIT(2) /*!< event from line 2 */ +#define EXTI_EVEN_EVEN3 BIT(3) /*!< event from line 3 */ +#define EXTI_EVEN_EVEN4 BIT(4) /*!< event from line 4 */ +#define EXTI_EVEN_EVEN5 BIT(5) /*!< event from line 5 */ +#define EXTI_EVEN_EVEN6 BIT(6) /*!< event from line 6 */ +#define EXTI_EVEN_EVEN7 BIT(7) /*!< event from line 7 */ +#define EXTI_EVEN_EVEN8 BIT(8) /*!< event from line 8 */ +#define EXTI_EVEN_EVEN9 BIT(9) /*!< event from line 9 */ +#define EXTI_EVEN_EVEN10 BIT(10) /*!< event from line 10 */ +#define EXTI_EVEN_EVEN11 BIT(11) /*!< event from line 11 */ +#define EXTI_EVEN_EVEN12 BIT(12) /*!< event from line 12 */ +#define EXTI_EVEN_EVEN13 BIT(13) /*!< event from line 13 */ +#define EXTI_EVEN_EVEN14 BIT(14) /*!< event from line 14 */ +#define EXTI_EVEN_EVEN15 BIT(15) /*!< event from line 15 */ +#define EXTI_EVEN_EVEN16 BIT(16) /*!< event from line 16 */ +#define EXTI_EVEN_EVEN17 BIT(17) /*!< event from line 17 */ +#define EXTI_EVEN_EVEN18 BIT(18) /*!< event from line 18 */ +#define EXTI_EVEN_EVEN19 BIT(19) /*!< event from line 19 */ +#define EXTI_EVEN_EVEN20 BIT(20) /*!< event from line 20 */ +#define EXTI_EVEN_EVEN21 BIT(21) /*!< event from line 21 */ +#define EXTI_EVEN_EVEN22 BIT(22) /*!< event from line 22 */ + +/* EXTI_RTEN */ +#define EXTI_RTEN_RTEN0 BIT(0) /*!< rising edge from line 0 */ +#define EXTI_RTEN_RTEN1 BIT(1) /*!< rising edge from line 1 */ +#define EXTI_RTEN_RTEN2 BIT(2) /*!< rising edge from line 2 */ +#define EXTI_RTEN_RTEN3 BIT(3) /*!< rising edge from line 3 */ +#define EXTI_RTEN_RTEN4 BIT(4) /*!< rising edge from line 4 */ +#define EXTI_RTEN_RTEN5 BIT(5) /*!< rising edge from line 5 */ +#define EXTI_RTEN_RTEN6 BIT(6) /*!< rising edge from line 6 */ +#define EXTI_RTEN_RTEN7 BIT(7) /*!< rising edge from line 7 */ +#define EXTI_RTEN_RTEN8 BIT(8) /*!< rising edge from line 8 */ +#define EXTI_RTEN_RTEN9 BIT(9) /*!< rising edge from line 9 */ +#define EXTI_RTEN_RTEN10 BIT(10) /*!< rising edge from line 10 */ +#define EXTI_RTEN_RTEN11 BIT(11) /*!< rising edge from line 11 */ +#define EXTI_RTEN_RTEN12 BIT(12) /*!< rising edge from line 12 */ +#define EXTI_RTEN_RTEN13 BIT(13) /*!< rising edge from line 13 */ +#define EXTI_RTEN_RTEN14 BIT(14) /*!< rising edge from line 14 */ +#define EXTI_RTEN_RTEN15 BIT(15) /*!< rising edge from line 15 */ +#define EXTI_RTEN_RTEN16 BIT(16) /*!< rising edge from line 16 */ +#define EXTI_RTEN_RTEN17 BIT(17) /*!< rising edge from line 17 */ +#define EXTI_RTEN_RTEN18 BIT(18) /*!< rising edge from line 18 */ +#define EXTI_RTEN_RTEN19 BIT(19) /*!< rising edge from line 19 */ +#define EXTI_RTEN_RTEN20 BIT(20) /*!< rising edge from line 20 */ +#define EXTI_RTEN_RTEN21 BIT(21) /*!< rising edge from line 21 */ +#define EXTI_RTEN_RTEN22 BIT(22) /*!< rising edge from line 22 */ + +/* EXTI_FTEN */ +#define EXTI_FTEN_FTEN0 BIT(0) /*!< falling edge from line 0 */ +#define EXTI_FTEN_FTEN1 BIT(1) /*!< falling edge from line 1 */ +#define EXTI_FTEN_FTEN2 BIT(2) /*!< falling edge from line 2 */ +#define EXTI_FTEN_FTEN3 BIT(3) /*!< falling edge from line 3 */ +#define EXTI_FTEN_FTEN4 BIT(4) /*!< falling edge from line 4 */ +#define EXTI_FTEN_FTEN5 BIT(5) /*!< falling edge from line 5 */ +#define EXTI_FTEN_FTEN6 BIT(6) /*!< falling edge from line 6 */ +#define EXTI_FTEN_FTEN7 BIT(7) /*!< falling edge from line 7 */ +#define EXTI_FTEN_FTEN8 BIT(8) /*!< falling edge from line 8 */ +#define EXTI_FTEN_FTEN9 BIT(9) /*!< falling edge from line 9 */ +#define EXTI_FTEN_FTEN10 BIT(10) /*!< falling edge from line 10 */ +#define EXTI_FTEN_FTEN11 BIT(11) /*!< falling edge from line 11 */ +#define EXTI_FTEN_FTEN12 BIT(12) /*!< falling edge from line 12 */ +#define EXTI_FTEN_FTEN13 BIT(13) /*!< falling edge from line 13 */ +#define EXTI_FTEN_FTEN14 BIT(14) /*!< falling edge from line 14 */ +#define EXTI_FTEN_FTEN15 BIT(15) /*!< falling edge from line 15 */ +#define EXTI_FTEN_FTEN16 BIT(16) /*!< falling edge from line 16 */ +#define EXTI_FTEN_FTEN17 BIT(17) /*!< falling edge from line 17 */ +#define EXTI_FTEN_FTEN18 BIT(18) /*!< falling edge from line 18 */ +#define EXTI_FTEN_FTEN19 BIT(19) /*!< falling edge from line 19 */ +#define EXTI_FTEN_FTEN20 BIT(20) /*!< falling edge from line 20 */ +#define EXTI_FTEN_FTEN21 BIT(21) /*!< falling edge from line 21 */ +#define EXTI_FTEN_FTEN22 BIT(22) /*!< falling edge from line 22 */ + +/* EXTI_SWIEV */ +#define EXTI_SWIEV_SWIEV0 BIT(0) /*!< software interrupt/event request from line 0 */ +#define EXTI_SWIEV_SWIEV1 BIT(1) /*!< software interrupt/event request from line 1 */ +#define EXTI_SWIEV_SWIEV2 BIT(2) /*!< software interrupt/event request from line 2 */ +#define EXTI_SWIEV_SWIEV3 BIT(3) /*!< software interrupt/event request from line 3 */ +#define EXTI_SWIEV_SWIEV4 BIT(4) /*!< software interrupt/event request from line 4 */ +#define EXTI_SWIEV_SWIEV5 BIT(5) /*!< software interrupt/event request from line 5 */ +#define EXTI_SWIEV_SWIEV6 BIT(6) /*!< software interrupt/event request from line 6 */ +#define EXTI_SWIEV_SWIEV7 BIT(7) /*!< software interrupt/event request from line 7 */ +#define EXTI_SWIEV_SWIEV8 BIT(8) /*!< software interrupt/event request from line 8 */ +#define EXTI_SWIEV_SWIEV9 BIT(9) /*!< software interrupt/event request from line 9 */ +#define EXTI_SWIEV_SWIEV10 BIT(10) /*!< software interrupt/event request from line 10 */ +#define EXTI_SWIEV_SWIEV11 BIT(11) /*!< software interrupt/event request from line 11 */ +#define EXTI_SWIEV_SWIEV12 BIT(12) /*!< software interrupt/event request from line 12 */ +#define EXTI_SWIEV_SWIEV13 BIT(13) /*!< software interrupt/event request from line 13 */ +#define EXTI_SWIEV_SWIEV14 BIT(14) /*!< software interrupt/event request from line 14 */ +#define EXTI_SWIEV_SWIEV15 BIT(15) /*!< software interrupt/event request from line 15 */ +#define EXTI_SWIEV_SWIEV16 BIT(16) /*!< software interrupt/event request from line 16 */ +#define EXTI_SWIEV_SWIEV17 BIT(17) /*!< software interrupt/event request from line 17 */ +#define EXTI_SWIEV_SWIEV18 BIT(18) /*!< software interrupt/event request from line 18 */ +#define EXTI_SWIEV_SWIEV19 BIT(19) /*!< software interrupt/event request from line 19 */ +#define EXTI_SWIEV_SWIEV20 BIT(20) /*!< software interrupt/event request from line 20 */ +#define EXTI_SWIEV_SWIEV21 BIT(21) /*!< software interrupt/event request from line 21 */ +#define EXTI_SWIEV_SWIEV22 BIT(22) /*!< software interrupt/event request from line 22 */ + +/* EXTI_PD */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt pending status from line 17 */ +#define EXTI_PD_PD18 BIT(18) /*!< interrupt pending status from line 18 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt pending status from line 19 */ +#define EXTI_PD_PD20 BIT(20) /*!< interrupt pending status from line 20 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt pending status from line 21 */ +#define EXTI_PD_PD22 BIT(22) /*!< interrupt pending status from line 22 */ + +/* constants definitions */ +/* EXTI line number */ +typedef enum { + EXTI_0 = BIT(0), /*!< EXTI line 0 */ + EXTI_1 = BIT(1), /*!< EXTI line 1 */ + EXTI_2 = BIT(2), /*!< EXTI line 2 */ + EXTI_3 = BIT(3), /*!< EXTI line 3 */ + EXTI_4 = BIT(4), /*!< EXTI line 4 */ + EXTI_5 = BIT(5), /*!< EXTI line 5 */ + EXTI_6 = BIT(6), /*!< EXTI line 6 */ + EXTI_7 = BIT(7), /*!< EXTI line 7 */ + EXTI_8 = BIT(8), /*!< EXTI line 8 */ + EXTI_9 = BIT(9), /*!< EXTI line 9 */ + EXTI_10 = BIT(10), /*!< EXTI line 10 */ + EXTI_11 = BIT(11), /*!< EXTI line 11 */ + EXTI_12 = BIT(12), /*!< EXTI line 12 */ + EXTI_13 = BIT(13), /*!< EXTI line 13 */ + EXTI_14 = BIT(14), /*!< EXTI line 14 */ + EXTI_15 = BIT(15), /*!< EXTI line 15 */ + EXTI_16 = BIT(16), /*!< EXTI line 16 */ + EXTI_17 = BIT(17), /*!< EXTI line 17 */ + EXTI_18 = BIT(18), /*!< EXTI line 18 */ + EXTI_19 = BIT(19), /*!< EXTI line 19 */ + EXTI_20 = BIT(20), /*!< EXTI line 20 */ + EXTI_21 = BIT(21), /*!< EXTI line 21 */ + EXTI_22 = BIT(22) /*!< EXTI line 22 */ +} exti_line_enum; + +/* external interrupt and event */ +typedef enum { + EXTI_INTERRUPT = 0, /*!< EXTI interrupt mode */ + EXTI_EVENT /*!< EXTI event mode */ +} exti_mode_enum; + +/* interrupt 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 /*!< none EXTI edge trigger */ +} exti_trig_type_enum; + +/* function declarations */ +/* 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 /* GD32F4XX_EXTI_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fmc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fmc.h new file mode 100644 index 000000000..aca5a7d47 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fmc.h @@ -0,0 +1,415 @@ +/*! + \file gd32f4xx_fmc.h + \brief definitions for the FMC + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2020-12-20, V2.1.1, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_FMC_H +#define GD32F4XX_FMC_H + +#include "gd32f4xx.h" + +/* FMC and option byte definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option byte base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00000000U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x00000004U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x00000008U) /*!< FMC option byte unlock key register */ +#define FMC_STAT REG32((FMC) + 0x0000000CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x00000010U) /*!< FMC control register */ +#define FMC_OBCTL0 REG32((FMC) + 0x00000014U) /*!< FMC option byte control register 0 */ +#define FMC_OBCTL1 REG32((FMC) + 0x00000018U) /*!< FMC option byte control register 1 */ +#define FMC_PECFG REG32((FMC) + 0x00000020U) /*!< FMC page erase configuration register */ +#define FMC_PEKEY REG32((FMC) + 0x00000024U) /*!< FMC unlock page erase key register */ +#define FMC_WSEN REG32((FMC) + 0x000000FCU) /*!< FMC wait state enable register */ +#define FMC_PID REG32((FMC) + 0x00000100U) /*!< FMC product ID register */ + +#define OB_WP1 REG32((OB) + 0x00000008U) /*!< option byte write protection 1 */ +#define OB_USER REG32((OB) + 0x00010000U) /*!< option byte user value*/ +#define OB_SPC REG32((OB) + 0x00010001U) /*!< option byte security protection value */ +#define OB_WP0 REG32((OB) + 0x00010008U) /*!< option byte write protection 0 */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WC_WSCNT BITS(0,3) /*!< wait state counter */ + +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC main flash key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option byte key bits */ + +/* FMC_STAT */ +#define FMC_STAT_END BIT(0) /*!< end of operation flag bit */ +#define FMC_STAT_OPERR BIT(1) /*!< flash operation error flag bit */ +#define FMC_STAT_WPERR BIT(4) /*!< erase/Program protection error flag bit */ +#define FMC_STAT_PGMERR BIT(6) /*!< program size not match error flag bit */ +#define FMC_STAT_PGSERR BIT(7) /*!< program sequence error flag bit */ +#define FMC_STAT_RDDERR BIT(8) /*!< read D-bus protection error flag bit */ +#define FMC_STAT_BUSY BIT(16) /*!< flash busy flag bit */ + +/* FMC_CTL */ +#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */ +#define FMC_CTL_SER BIT(1) /*!< main flash sector erase command bit */ +#define FMC_CTL_MER0 BIT(2) /*!< main flash mass erase for bank0 command bit */ +#define FMC_CTL_SN BITS(3,7) /*!< select which sector number to be erased */ +#define FMC_CTL_PSZ BITS(8,9) /*!< program size bit */ +#define FMC_CTL_MER1 BIT(15) /*!< main flash mass erase for bank1 command bit */ +#define FMC_CTL_START BIT(16) /*!< send erase command to FMC bit */ +#define FMC_CTL_ENDIE BIT(24) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_ERRIE BIT(25) /*!< error interrupt enable bit */ +#define FMC_CTL_LK BIT(31) /*!< FMC_CTL lock bit */ + +/* FMC_OBCTL0 */ +#define FMC_OBCTL0_OB_LK BIT(0) /*!< FMC_OBCTL0 lock bit */ +#define FMC_OBCTL0_OB_START BIT(1) /*!< send option byte change command to FMC bit */ +#define FMC_OBCTL0_BOR_TH BITS(2,3) /*!< option byte BOR threshold value */ +#define FMC_OBCTL0_BB BIT(4) /*!< option byte boot bank value */ +#define FMC_OBCTL0_NWDG_HW BIT(5) /*!< option byte watchdog value */ +#define FMC_OBCTL0_NRST_DPSLP BIT(6) /*!< option byte deepsleep reset value */ +#define FMC_OBCTL0_NRST_STDBY BIT(7) /*!< option byte standby reset value */ +#define FMC_OBCTL0_SPC BITS(8,15) /*!< option byte Security Protection code */ +#define FMC_OBCTL0_WP0 BITS(16,27) /*!< erase/program protection of each sector when DRP is 0 */ +#define FMC_OBCTL0_DBS BIT(30) /*!< double banks or single bank selection when flash size is 1M bytes */ +#define FMC_OBCTL0_DRP BIT(31) /*!< D-bus read protection bit */ + +/* FMC_OBCTL1 */ +#define FMC_OBCTL1_WP1 BITS(16,27) /*!< erase/program protection of each sector when DRP is 0 */ + +/* FMC_PECFG */ +#define FMC_PE_EN BIT(31) /*!< the enable bit of page erase function */ +#define FMC_PE_ADDR BITS(0,28) /*!< page erase address */ + +/* FMC_PEKEY */ +#define FMC_PE_KEY BITS(0,31) /*!< FMC_PECFG unlock key value */ + +/* FMC_WSEN */ +#define FMC_WSEN_WSEN BIT(0) /*!< FMC wait state enable bit */ + +/* FMC_PID */ +#define FMC_PID_PID BITS(0,31) /*!< product ID bits */ + +/* constants definitions */ +/* fmc state */ +typedef enum { + FMC_READY = 0, /*!< the operation has been completed */ + FMC_BUSY, /*!< the operation is in progress */ + FMC_RDDERR, /*!< read D-bus protection error */ + FMC_PGSERR, /*!< program sequence error */ + FMC_PGMERR, /*!< program size not match error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_OPERR, /*!< operation error */ + FMC_TOERR /*!< timeout error */ +} fmc_state_enum; + +/* unlock key */ +#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ +#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ +#define UNLOCK_PE_KEY ((uint32_t)0xA9B8C7D6U) /*!< unlock page erase function key */ + +#define OB_UNLOCK_KEY0 ((uint32_t)0x08192A3BU) /*!< ob unlock key 0 */ +#define OB_UNLOCK_KEY1 ((uint32_t)0x4C5D6E7FU) /*!< ob unlock key 1 */ + +/* option byte write protection */ +#define OB_LWP ((uint32_t)0x000000FFU) /*!< write protection low bits */ +#define OB_HWP ((uint32_t)0x0000FF00U) /*!< write protection high bits */ + +/* FMC wait state counter */ +#define WC_WSCNT(regval) (BITS(0,3) & ((uint32_t)(regval))) +#define WS_WSCNT_0 WC_WSCNT(0) /*!< FMC 0 wait */ +#define WS_WSCNT_1 WC_WSCNT(1) /*!< FMC 1 wait */ +#define WS_WSCNT_2 WC_WSCNT(2) /*!< FMC 2 wait */ +#define WS_WSCNT_3 WC_WSCNT(3) /*!< FMC 3 wait */ +#define WS_WSCNT_4 WC_WSCNT(4) /*!< FMC 4 wait */ +#define WS_WSCNT_5 WC_WSCNT(5) /*!< FMC 5 wait */ +#define WS_WSCNT_6 WC_WSCNT(6) /*!< FMC 6 wait */ +#define WS_WSCNT_7 WC_WSCNT(7) /*!< FMC 7 wait */ +#define WS_WSCNT_8 WC_WSCNT(8) /*!< FMC 8 wait */ +#define WS_WSCNT_9 WC_WSCNT(9) /*!< FMC 9 wait */ +#define WS_WSCNT_10 WC_WSCNT(10) /*!< FMC 10 wait */ +#define WS_WSCNT_11 WC_WSCNT(11) /*!< FMC 11 wait */ +#define WS_WSCNT_12 WC_WSCNT(12) /*!< FMC 12 wait */ +#define WS_WSCNT_13 WC_WSCNT(13) /*!< FMC 13 wait */ +#define WS_WSCNT_14 WC_WSCNT(14) /*!< FMC 14 wait */ +#define WS_WSCNT_15 WC_WSCNT(15) /*!< FMC 15 wait */ + +/* option byte BOR threshold value */ +#define OBCTL0_BOR_TH(regval) (BITS(2,3) & ((uint32_t)(regval))<< 2) +#define OB_BOR_TH_VALUE3 OBCTL0_BOR_TH(0) /*!< BOR threshold value 3 */ +#define OB_BOR_TH_VALUE2 OBCTL0_BOR_TH(1) /*!< BOR threshold value 2 */ +#define OB_BOR_TH_VALUE1 OBCTL0_BOR_TH(2) /*!< BOR threshold value 1 */ +#define OB_BOR_TH_OFF OBCTL0_BOR_TH(3) /*!< no BOR function */ + +/* option byte boot bank value */ +#define OBCTL0_BB(regval) (BIT(4) & ((uint32_t)(regval)<<4)) +#define OB_BB_DISABLE OBCTL0_BB(0) /*!< boot from bank0 */ +#define OB_BB_ENABLE OBCTL0_BB(1) /*!< boot from bank1 or bank0 if bank1 is void */ + +/* option byte software/hardware free watch dog timer */ +#define OBCTL0_NWDG_HW(regval) (BIT(5) & ((uint32_t)(regval))<< 5) +#define OB_FWDGT_SW OBCTL0_NWDG_HW(1) /*!< software free watchdog */ +#define OB_FWDGT_HW OBCTL0_NWDG_HW(0) /*!< hardware free watchdog */ + +/* option byte reset or not entering deep sleep mode */ +#define OBCTL0_NRST_DPSLP(regval) (BIT(6) & ((uint32_t)(regval))<< 6) +#define OB_DEEPSLEEP_NRST OBCTL0_NRST_DPSLP(1) /*!< no reset when entering deepsleep mode */ +#define OB_DEEPSLEEP_RST OBCTL0_NRST_DPSLP(0) /*!< generate a reset instead of entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OBCTL0_NRST_STDBY(regval) (BIT(7) & ((uint32_t)(regval))<< 7) +#define OB_STDBY_NRST OBCTL0_NRST_STDBY(1) /*!< no reset when entering deepsleep mode */ +#define OB_STDBY_RST OBCTL0_NRST_STDBY(0) /*!< generate a reset instead of entering standby mode */ + +/* read protect configure */ +#define FMC_NSPC ((uint8_t)0xAAU) /*!< no security protection */ +#define FMC_LSPC ((uint8_t)0xABU) /*!< low security protection */ +#define FMC_HSPC ((uint8_t)0xCCU) /*!< high security protection */ + +/* option bytes write protection */ +#define OB_WP_0 ((uint32_t)0x00000001U) /*!< erase/program protection of sector 0 */ +#define OB_WP_1 ((uint32_t)0x00000002U) /*!< erase/program protection of sector 1 */ +#define OB_WP_2 ((uint32_t)0x00000004U) /*!< erase/program protection of sector 2 */ +#define OB_WP_3 ((uint32_t)0x00000008U) /*!< erase/program protection of sector 3 */ +#define OB_WP_4 ((uint32_t)0x00000010U) /*!< erase/program protection of sector 4 */ +#define OB_WP_5 ((uint32_t)0x00000020U) /*!< erase/program protection of sector 5 */ +#define OB_WP_6 ((uint32_t)0x00000040U) /*!< erase/program protection of sector 6 */ +#define OB_WP_7 ((uint32_t)0x00000080U) /*!< erase/program protection of sector 7 */ +#define OB_WP_8 ((uint32_t)0x00000100U) /*!< erase/program protection of sector 8 */ +#define OB_WP_9 ((uint32_t)0x00000200U) /*!< erase/program protection of sector 9 */ +#define OB_WP_10 ((uint32_t)0x00000400U) /*!< erase/program protection of sector 10 */ +#define OB_WP_11 ((uint32_t)0x00000800U) /*!< erase/program protection of sector 11 */ +#define OB_WP_12 ((uint32_t)0x00010000U) /*!< erase/program protection of sector 12 */ +#define OB_WP_13 ((uint32_t)0x00020000U) /*!< erase/program protection of sector 13 */ +#define OB_WP_14 ((uint32_t)0x00040000U) /*!< erase/program protection of sector 14 */ +#define OB_WP_15 ((uint32_t)0x00080000U) /*!< erase/program protection of sector 15 */ +#define OB_WP_16 ((uint32_t)0x00100000U) /*!< erase/program protection of sector 16 */ +#define OB_WP_17 ((uint32_t)0x00200000U) /*!< erase/program protection of sector 17 */ +#define OB_WP_18 ((uint32_t)0x00400000U) /*!< erase/program protection of sector 18 */ +#define OB_WP_19 ((uint32_t)0x00800000U) /*!< erase/program protection of sector 19 */ +#define OB_WP_20 ((uint32_t)0x01000000U) /*!< erase/program protection of sector 20 */ +#define OB_WP_21 ((uint32_t)0x02000000U) /*!< erase/program protection of sector 21 */ +#define OB_WP_22 ((uint32_t)0x04000000U) /*!< erase/program protection of sector 22 */ +#define OB_WP_23_27 ((uint32_t)0x08000000U) /*!< erase/program protection of sector 23~27 */ +#define OB_WP_ALL ((uint32_t)0x0FFF0FFFU) /*!< erase/program protection of all sectors */ + +/* option bytes D-bus read protection */ +#define OB_DRP_0 ((uint32_t)0x00000001U) /*!< D-bus read protection protection of sector 0 */ +#define OB_DRP_1 ((uint32_t)0x00000002U) /*!< D-bus read protection protection of sector 1 */ +#define OB_DRP_2 ((uint32_t)0x00000004U) /*!< D-bus read protection protection of sector 2 */ +#define OB_DRP_3 ((uint32_t)0x00000008U) /*!< D-bus read protection protection of sector 3 */ +#define OB_DRP_4 ((uint32_t)0x00000010U) /*!< D-bus read protection protection of sector 4 */ +#define OB_DRP_5 ((uint32_t)0x00000020U) /*!< D-bus read protection protection of sector 5 */ +#define OB_DRP_6 ((uint32_t)0x00000040U) /*!< D-bus read protection protection of sector 6 */ +#define OB_DRP_7 ((uint32_t)0x00000080U) /*!< D-bus read protection protection of sector 7 */ +#define OB_DRP_8 ((uint32_t)0x00000100U) /*!< D-bus read protection protection of sector 8 */ +#define OB_DRP_9 ((uint32_t)0x00000200U) /*!< D-bus read protection protection of sector 9 */ +#define OB_DRP_10 ((uint32_t)0x00000400U) /*!< D-bus read protection protection of sector 10 */ +#define OB_DRP_11 ((uint32_t)0x00000800U) /*!< D-bus read protection protection of sector 11 */ +#define OB_DRP_12 ((uint32_t)0x00010000U) /*!< D-bus read protection protection of sector 12 */ +#define OB_DRP_13 ((uint32_t)0x00020000U) /*!< D-bus read protection protection of sector 13 */ +#define OB_DRP_14 ((uint32_t)0x00040000U) /*!< D-bus read protection protection of sector 14 */ +#define OB_DRP_15 ((uint32_t)0x00080000U) /*!< D-bus read protection protection of sector 15 */ +#define OB_DRP_16 ((uint32_t)0x00100000U) /*!< D-bus read protection protection of sector 16 */ +#define OB_DRP_17 ((uint32_t)0x00200000U) /*!< D-bus read protection protection of sector 17 */ +#define OB_DRP_18 ((uint32_t)0x00400000U) /*!< D-bus read protection protection of sector 18 */ +#define OB_DRP_19 ((uint32_t)0x00800000U) /*!< D-bus read protection protection of sector 19 */ +#define OB_DRP_20 ((uint32_t)0x01000000U) /*!< D-bus read protection protection of sector 20 */ +#define OB_DRP_21 ((uint32_t)0x02000000U) /*!< D-bus read protection protection of sector 21 */ +#define OB_DRP_22 ((uint32_t)0x04000000U) /*!< D-bus read protection protection of sector 22 */ +#define OB_DRP_23_27 ((uint32_t)0x08000000U) /*!< D-bus read protection protection of sector 23~27 */ +#define OB_DRP_ALL ((uint32_t)0x0FFF0FFFU) /*!< D-bus read protection protection of all sectors */ + +/* double banks or single bank selection when flash size is 1M bytes */ +#define OBCTL0_DBS(regval) (BIT(30) & ((uint32_t)(regval) << 30U)) +#define OB_DBS_DISABLE OBCTL0_DBS(0) /*!< single bank when flash size is 1M bytes */ +#define OB_DBS_ENABLE OBCTL0_DBS(1) /*!< double bank when flash size is 1M bytes */ + +/* option bytes D-bus read protection mode */ +#define OBCTL0_DRP(regval) (BIT(31) & ((uint32_t)(regval) << 31U)) +#define OB_DRP_DISABLE OBCTL0_DRP(0) /*!< the WPx bits used as erase/program protection of each sector */ +#define OB_DRP_ENABLE OBCTL0_DRP(1) /*!< the WPx bits used as erase/program protection and D-bus read protection of each sector */ + +/* FMC sectors */ +#define CTL_SN(regval) (BITS(3,7) & ((uint32_t)(regval))<< 3) +#define CTL_SECTOR_NUMBER_0 CTL_SN(0) /*!< sector 0 */ +#define CTL_SECTOR_NUMBER_1 CTL_SN(1) /*!< sector 1 */ +#define CTL_SECTOR_NUMBER_2 CTL_SN(2) /*!< sector 2 */ +#define CTL_SECTOR_NUMBER_3 CTL_SN(3) /*!< sector 3 */ +#define CTL_SECTOR_NUMBER_4 CTL_SN(4) /*!< sector 4 */ +#define CTL_SECTOR_NUMBER_5 CTL_SN(5) /*!< sector 5 */ +#define CTL_SECTOR_NUMBER_6 CTL_SN(6) /*!< sector 6 */ +#define CTL_SECTOR_NUMBER_7 CTL_SN(7) /*!< sector 7 */ +#define CTL_SECTOR_NUMBER_8 CTL_SN(8) /*!< sector 8 */ +#define CTL_SECTOR_NUMBER_9 CTL_SN(9) /*!< sector 9 */ +#define CTL_SECTOR_NUMBER_10 CTL_SN(10) /*!< sector 10 */ +#define CTL_SECTOR_NUMBER_11 CTL_SN(11) /*!< sector 11 */ +#define CTL_SECTOR_NUMBER_24 CTL_SN(12) /*!< sector 24 */ +#define CTL_SECTOR_NUMBER_25 CTL_SN(13) /*!< sector 25 */ +#define CTL_SECTOR_NUMBER_26 CTL_SN(14) /*!< sector 26 */ +#define CTL_SECTOR_NUMBER_27 CTL_SN(15) /*!< sector 27 */ +#define CTL_SECTOR_NUMBER_12 CTL_SN(16) /*!< sector 12 */ +#define CTL_SECTOR_NUMBER_13 CTL_SN(17) /*!< sector 13 */ +#define CTL_SECTOR_NUMBER_14 CTL_SN(18) /*!< sector 14 */ +#define CTL_SECTOR_NUMBER_15 CTL_SN(19) /*!< sector 15 */ +#define CTL_SECTOR_NUMBER_16 CTL_SN(20) /*!< sector 16 */ +#define CTL_SECTOR_NUMBER_17 CTL_SN(21) /*!< sector 17 */ +#define CTL_SECTOR_NUMBER_18 CTL_SN(22) /*!< sector 18 */ +#define CTL_SECTOR_NUMBER_19 CTL_SN(23) /*!< sector 19 */ +#define CTL_SECTOR_NUMBER_20 CTL_SN(24) /*!< sector 20 */ +#define CTL_SECTOR_NUMBER_21 CTL_SN(25) /*!< sector 21 */ +#define CTL_SECTOR_NUMBER_22 CTL_SN(26) /*!< sector 22 */ +#define CTL_SECTOR_NUMBER_23 CTL_SN(27) /*!< sector 23 */ + + +/* FMC program size */ +#define CTL_PSZ(regval) (BITS(8,9) & ((uint32_t)(regval))<< 8U) +#define CTL_PSZ_BYTE CTL_PSZ(0) /*!< FMC program by byte access */ +#define CTL_PSZ_HALF_WORD CTL_PSZ(1) /*!< FMC program by half-word access */ +#define CTL_PSZ_WORD CTL_PSZ(2) /*!< FMC program by word access */ + +/* FMC interrupt enable */ +#define FMC_INT_END ((uint32_t)0x01000000U) /*!< enable FMC end of program interrupt */ +#define FMC_INT_ERR ((uint32_t)0x02000000U) /*!< enable FMC error interrupt */ + +/* FMC flags */ +#define FMC_FLAG_END FMC_STAT_END /*!< FMC end of operation flag bit */ +#define FMC_FLAG_OPERR FMC_STAT_OPERR /*!< FMC operation error flag bit */ +#define FMC_FLAG_WPERR FMC_STAT_WPERR /*!< FMC erase/program protection error flag bit */ +#define FMC_FLAG_PGMERR FMC_STAT_PGMERR /*!< FMC program size not match error flag bit */ +#define FMC_FLAG_PGSERR FMC_STAT_PGSERR /*!< FMC program sequence error flag bit */ +#define FMC_FLAG_RDDERR FMC_STAT_RDDERR /*!< FMC read D-bus protection error flag bit */ +#define FMC_FLAG_BUSY FMC_STAT_BUSY /*!< FMC busy flag */ + +/* FMC interrupt flags */ +#define FMC_INT_FLAG_END FMC_STAT_END /*!< FMC end of operation interrupt flag */ +#define FMC_INT_FLAG_OPERR FMC_STAT_OPERR /*!< FMC operation error interrupt flag */ +#define FMC_INT_FLAG_WPERR FMC_STAT_WPERR /*!< FMC erase/program protection error interrupt flag */ +#define FMC_INT_FLAG_PGMERR FMC_STAT_PGMERR /*!< FMC program size not match error interrupt flag */ +#define FMC_INT_FLAG_PGSERR FMC_STAT_PGSERR /*!< FMC program sequence error interrupt flag */ +#define FMC_INT_FLAG_RDDERR FMC_STAT_RDDERR /*!< FMC read D-bus protection error interrupt flag */ + + +/* FMC time out */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x4FFFFFFFU) /*!< count to judge of FMC timeout */ + +/* function declarations */ +/* FMC main memory programming functions */ +/* set the FMC wait state counter */ +void fmc_wscnt_set(uint32_t wscnt); +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(void); +#if defined (GD32F425) || defined (GD32F427) || defined (GD32F470) +/* FMC erase page */ +fmc_state_enum fmc_page_erase(uint32_t page_addr); +#endif +/* FMC erase sector */ +fmc_state_enum fmc_sector_erase(uint32_t fmc_sector); +/* FMC erase whole chip */ +fmc_state_enum fmc_mass_erase(void); +/* FMC erase whole bank0 */ +fmc_state_enum fmc_bank0_erase(void); +/* FMC erase whole bank1 */ +fmc_state_enum fmc_bank1_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 half word at the corresponding address */ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data); +/* FMC program a byte at the corresponding address */ +fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data); + +/* FMC option bytes programming functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* send option byte change command */ +void ob_start(void); +/* erase option byte */ +void ob_erase(void); +/* enable write protect */ +ErrStatus ob_write_protection_enable(uint32_t ob_wp); +/* disable write protect */ +ErrStatus ob_write_protection_disable(uint32_t ob_wp); +/* enable erase/program protection and D-bus read protection */ +void ob_drp_enable(uint32_t ob_drp); +/* disable erase/program protection and D-bus read protection */ +void ob_drp_disable(void); +/* configure security protection level */ +void ob_security_protection_config(uint8_t ob_spc); +/* program the FMC user option byte */ +void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby); +/* program the option byte BOR threshold value */ +void ob_user_bor_threshold(uint32_t ob_bor_th); +/* configure the boot mode */ +void ob_boot_mode_config(uint32_t boot_mode); +/* get the FMC user option byte */ +uint8_t ob_user_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection0_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection1_get(void); +/* get the FMC erase/program protection and D-bus read protection option bytes value */ +uint16_t ob_drp0_get(void); +/* get the FMC erase/program protection and D-bus read protection option bytes value */ +uint16_t ob_drp1_get(void); +/* get option byte security protection code value */ +FlagStatus ob_spc_get(void); +/* get the FMC option byte BOR threshold value */ +uint8_t ob_user_bor_threshold_get(void); + +/* FMC interrupts and flags management functions */ +/* get flag set or reset */ +FlagStatus fmc_flag_get(uint32_t fmc_flag); +/* clear the FMC pending flag */ +void fmc_flag_clear(uint32_t fmc_flag); +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t fmc_int); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t fmc_int); +/* get FMC interrupt flag set or reset */ +FlagStatus fmc_interrupt_flag_get(uint32_t fmc_int_flag); +/* clear the FMC interrupt flag */ +void fmc_interrupt_flag_clear(uint32_t fmc_int_flag); +/* get the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check whether FMC is ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t timeout); + +#endif /* GD32F4XX_FMC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fwdgt.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fwdgt.h new file mode 100644 index 000000000..af0a89765 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_fwdgt.h @@ -0,0 +1,114 @@ +/*! + \file gd32f4xx_fwdgt.h + \brief definitions for the FWDGT + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_FWDGT_H +#define GD32F4XX_FWDGT_H + +#include "gd32f4xx.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE /*!< FWDGT base address */ + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x04U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x08U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0CU) /*!< FWDGT status 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 */ + +/* constants definitions */ +/* psc register value */ +#define PSC_PSC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#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_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 /*!< FWDGT prescaler divider value update flag */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< FWDGT counter reload value update flag */ + +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/* function declarations */ +/* enable write access to FWDGT_PSC and FWDGT_RLD */ +void fwdgt_write_enable(void); +/* disable write access to FWDGT_PSC and FWDGT_RLD */ +void fwdgt_write_disable(void); +/* start the free watchdog timer counter */ +void fwdgt_enable(void); + +/* configure the free watchdog timer counter prescaler value */ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value); +/* configure the free watchdog timer counter reload value */ +ErrStatus fwdgt_reload_value_config(uint16_t reload_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 /* GD32F4XX_FWDGT_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_gpio.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_gpio.h new file mode 100644 index 000000000..5a693857f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_gpio.h @@ -0,0 +1,409 @@ +/*! + \file gd32f4xx_gpio.h + \brief definitions for the GPIO + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_GPIO_H +#define GD32F4XX_GPIO_H + +#include "gd32f4xx.h" + +/* GPIOx(x=A,B,C,D,E,F,G,H,I) 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 GPIOI (GPIO_BASE + 0x00002000U) + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/pull-down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operate register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x28U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x2CU) /*!< GPIO port bit toggle 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 control bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output control bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output control bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output control bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output control bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output control bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output control bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output control bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output control bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output control bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output control bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output control bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output control bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output control bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output control bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output control 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 lock sequence 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 */ + +/* 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 level */ +#define OSPD_OSPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_LEVEL0 OSPD_OSPD(0) /*!< output max speed level 0 */ +#define GPIO_OSPEED_LEVEL1 OSPD_OSPD(1) /*!< output max speed level 1 */ +#define GPIO_OSPEED_LEVEL2 OSPD_OSPD(2) /*!< output max speed level 2 */ +#define GPIO_OSPEED_LEVEL3 OSPD_OSPD(3) /*!< output max speed level 3 */ + +/* GPIO output max speed value */ +#define GPIO_OSPEED_2MHZ GPIO_OSPEED_LEVEL0 /*!< output max speed 2MHz */ +#define GPIO_OSPEED_25MHZ GPIO_OSPEED_LEVEL1 /*!< output max speed 25MHz */ +#define GPIO_OSPEED_50MHZ GPIO_OSPEED_LEVEL2 /*!< output max speed 50MHz */ +#define GPIO_OSPEED_MAX GPIO_OSPEED_LEVEL3 /*!< GPIO very high output speed, max speed more than 50MHz */ + +/* 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); + +/* 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 /* GD32F4XX_GPIO_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_i2c.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_i2c.h new file mode 100644 index 000000000..2a1a88a4e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_i2c.h @@ -0,0 +1,413 @@ +/*! + \file gd32f4xx_i2c.h + \brief definitions for the I2C + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2019-04-16, V2.0.1, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_I2C_H +#define GD32F4XX_I2C_H + +#include "gd32f4xx.h" + +/* I2Cx(x=0,1,2) definitions */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE + 0x00000400U) /*!< I2C1 base address */ +#define I2C2 (I2C_BASE + 0x00000800U) /*!< I2C2 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_DATA(i2cx) REG32((i2cx) + 0x00000010U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x00000014U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x00000018U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x0000001CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x00000020U) /*!< I2C rise time register */ +#define I2C_FCTL(i2cx) REG32((i2cx) + 0x00000024U) /*!< I2C filter control register */ +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x00000080U) /*!< I2C SAM control and status register */ + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ +#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ +#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ +#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ +#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ +#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ +#define I2C_CTL0_SS BIT(7) /*!< clock stretching disable (slave mode) */ +#define I2C_CTL0_START BIT(8) /*!< start generation */ +#define I2C_CTL0_STOP BIT(9) /*!< stop generation */ +#define I2C_CTL0_ACKEN BIT(10) /*!< acknowledge enable */ +#define I2C_CTL0_POAP BIT(11) /*!< acknowledge/PEC position (for data reception) */ +#define I2C_CTL0_PECTRANS BIT(12) /*!< packet error checking */ +#define I2C_CTL0_SALT BIT(13) /*!< SMBus alert */ +#define I2C_CTL0_SRESET BIT(15) /*!< software reset */ + +/* I2Cx_CTL1 */ +#define I2C_CTL1_I2CCLK BITS(0,5) /*!< I2CCLK[5:0] bits (peripheral clock frequency) */ +#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt enable */ +#define I2C_CTL1_EVIE BIT(9) /*!< event interrupt enable */ +#define I2C_CTL1_BUFIE BIT(10) /*!< buffer interrupt enable */ +#define I2C_CTL1_DMAON BIT(11) /*!< DMA requests enable */ +#define I2C_CTL1_DMALST BIT(12) /*!< DMA last 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(15) /*!< address mode for the I2C slave */ + +/* I2Cx_SADDR1 */ +#define I2C_SADDR1_DUADEN BIT(0) /*!< aual-address mode switch */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave in dual-address mode */ + +/* I2Cx_DATA */ +#define I2C_DATA_TRB BITS(0,7) /*!< 8-bit data register */ + +/* I2Cx_STAT0 */ +#define I2C_STAT0_SBSEND BIT(0) /*!< start bit (master mode) */ +#define I2C_STAT0_ADDSEND BIT(1) /*!< address sent (master mode)/matched (slave mode) */ +#define I2C_STAT0_BTC BIT(2) /*!< byte transfer finished */ +#define I2C_STAT0_ADD10SEND BIT(3) /*!< 10-bit header sent (master mode) */ +#define I2C_STAT0_STPDET BIT(4) /*!< stop detection (slave mode) */ +#define I2C_STAT0_RBNE BIT(6) /*!< data register not empty (receivers) */ +#define I2C_STAT0_TBE BIT(7) /*!< data register empty (transmitters) */ +#define I2C_STAT0_BERR BIT(8) /*!< bus error */ +#define I2C_STAT0_LOSTARB BIT(9) /*!< arbitration lost (master mode) */ +#define I2C_STAT0_AERR BIT(10) /*!< acknowledge failure */ +#define I2C_STAT0_OUERR BIT(11) /*!< overrun/underrun */ +#define I2C_STAT0_PECERR BIT(12) /*!< PEC error in reception */ +#define I2C_STAT0_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_STAT0_SMBALT BIT(15) /*!< SMBus alert status */ + +/* I2Cx_STAT1 */ +#define I2C_STAT1_MASTER BIT(0) /*!< master/slave */ +#define I2C_STAT1_I2CBSY BIT(1) /*!< bus busy */ +#define I2C_STAT1_TR BIT(2) /*!< transmitter/receiver */ +#define I2C_STAT1_RXGC BIT(4) /*!< general call address (slave mode) */ +#define I2C_STAT1_DEFSMB BIT(5) /*!< SMBus device default address (slave mode) */ +#define I2C_STAT1_HSTSMB BIT(6) /*!< SMBus host header (slave mode) */ +#define I2C_STAT1_DUMODF BIT(7) /*!< dual flag (slave mode) */ +#define I2C_STAT1_PECV BITS(8,15) /*!< packet error checking value */ + +/* I2Cx_CKCFG */ +#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode (master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< fast mode duty cycle */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ + +/* I2Cx_RT */ +#define I2C_RT_RISETIME BITS(0,5) /*!< maximum rise time in fast/standard mode (Master mode) */ + +/* I2Cx_FCTL */ +#define I2C_FCTL_DF BITS(0,3) /*!< digital noise filter */ +#define I2C_FCTL_AFD BIT(4) /*!< analog noise filter disable */ + +/* I2Cx_SAMCS */ +#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ +#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ +#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ +#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ +#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ +#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ +#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ +#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ +#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag */ + +/* 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_CTL1_REG_OFFSET ((uint32_t)0x00000004U) /*!< CTL1 register offset */ +#define I2C_STAT0_REG_OFFSET ((uint32_t)0x00000014U) /*!< STAT0 register offset */ +#define I2C_STAT1_REG_OFFSET ((uint32_t)0x00000018U) /*!< STAT1 register offset */ +#define I2C_SAMCS_REG_OFFSET ((uint32_t)0x00000080U) /*!< SAMCS register offset */ + +/* I2C flags */ +typedef enum { + /* flags in STAT0 register */ + I2C_FLAG_SBSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode */ + I2C_FLAG_ADDSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode */ + I2C_FLAG_BTC = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ + I2C_FLAG_ADD10SEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode */ + I2C_FLAG_STPDET = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode */ + I2C_FLAG_RBNE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not empty during receiving */ + I2C_FLAG_TBE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting */ + I2C_FLAG_BERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ + I2C_FLAG_LOSTARB = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode */ + I2C_FLAG_AERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error */ + I2C_FLAG_OUERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode */ + I2C_FLAG_PECERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data */ + I2C_FLAG_SMBTO = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode */ + I2C_FLAG_SMBALT = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status */ + /* flags in STAT1 register */ + I2C_FLAG_MASTER = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 0U), /*!< a flag indicating whether I2C block is in master or slave mode */ + I2C_FLAG_I2CBSY = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 1U), /*!< busy flag */ + I2C_FLAG_TR = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 2U), /*!< whether the I2C is a transmitter or a receiver */ + I2C_FLAG_RXGC = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 4U), /*!< general call address (00h) received */ + I2C_FLAG_DEFSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 5U), /*!< default address of SMBus device */ + I2C_FLAG_HSTSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 6U), /*!< SMBus host header detected in slave mode */ + I2C_FLAG_DUMOD = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 7U), /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ + /* flags in SAMCS register */ + I2C_FLAG_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall flag */ + I2C_FLAG_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise flag */ + I2C_FLAG_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall flag */ + I2C_FLAG_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise flag */ +} i2c_flag_enum; + +/* I2C interrupt flags */ +typedef enum { + /* interrupt flags in CTL1 register */ + I2C_INT_FLAG_SBSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode interrupt flag */ + I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode interrupt flag */ + I2C_INT_FLAG_BTC = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes interrupt flag */ + I2C_INT_FLAG_ADD10SEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode interrupt flag */ + I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode interrupt flag */ + I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving interrupt flag */ + I2C_INT_FLAG_TBE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting interrupt flag */ + I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */ + I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode interrupt flag */ + I2C_INT_FLAG_AERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error interrupt flag */ + I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode interrupt flag */ + I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data interrupt flag */ + I2C_INT_FLAG_SMBTO = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode interrupt flag */ + I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status interrupt flag */ + /* interrupt flags in SAMCS register */ + I2C_INT_FLAG_TFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 4U, I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall interrupt flag */ + I2C_INT_FLAG_TFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 5U, I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise interrupt flag */ + I2C_INT_FLAG_RFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 6U, I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall interrupt flag */ + I2C_INT_FLAG_RFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 7U, I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise interrupt flag */ +} i2c_interrupt_flag_enum; + +/* I2C interrupt */ +typedef enum { + /* interrupt in CTL1 register */ + I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U), /*!< error interrupt */ + I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U), /*!< event interrupt */ + I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U), /*!< buffer interrupt */ + /* interrupt in SAMCS register */ + I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U), /*!< txframe fall interrupt */ + I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U), /*!< txframe rise interrupt */ + I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U), /*!< rxframe fall interrupt */ + I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U) /*!< rxframe rise interrupt */ +} i2c_interrupt_enum; + +/* the digital noise filter can filter spikes's length */ +typedef enum { + I2C_DF_DISABLE = 0, /*!< disable digital noise filter */ + I2C_DF_1PCLK, /*!< enable digital noise filter and the maximum filtered spiker's length 1 PCLK1 */ + I2C_DF_2PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 2 PCLK1 */ + I2C_DF_3PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 3 PCLK1 */ + I2C_DF_4PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 4 PCLK1 */ + I2C_DF_5PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 5 PCLK1 */ + I2C_DF_6PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 6 PCLK1 */ + I2C_DF_7PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 7 PCLK1 */ + I2C_DF_8PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 8 PCLK1 */ + I2C_DF_9PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 9 PCLK1 */ + I2C_DF_10PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 10 PCLK1 */ + I2C_DF_11PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 11 PCLK1 */ + I2C_DF_12PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 12 PCLK1 */ + I2C_DF_13PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 13 PCLK1 */ + I2C_DF_14PCLKS, /*!< enable digital noise filter and the maximum filtered spiker's length 14 PCLK1 */ + I2C_DF_15PCLKS /*!< enable digital noise filter and the maximum filtered spiker's length 15 PCLK1 */ +} i2c_digital_filter_enum; + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_I2CMODE_ENABLE ((uint32_t)0x00000000U) /*!< I2C mode */ +#define I2C_SMBUSMODE_ENABLE I2C_CTL0_SMBEN /*!< SMBus mode */ + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus mode device type */ +#define I2C_SMBUS_HOST I2C_CTL0_SMBSEL /*!< SMBus mode host type */ + +/* I2C transfer direction */ +#define I2C_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */ +#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */ + +/* whether or not to send an ACK */ +#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */ +#define I2C_ACK_ENABLE I2C_CTL0_ACKEN /*!< ACK will be sent */ + +/* I2C POAP position*/ +#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ +#define I2C_ACKPOS_NEXT I2C_CTL0_POAP /*!< ACKEN bit decides whether or not to send ACK for the next byte */ + +/* whether or not to stretch SCL low */ +#define I2C_SCLSTRETCH_ENABLE ((uint32_t)0x00000000U) /*!< enable SCL stretching */ +#define I2C_SCLSTRETCH_DISABLE I2C_CTL0_SS /*!< disable SCL stretching */ + +/* whether or not to response to a general call */ +#define I2C_GCEN_ENABLE I2C_CTL0_GCEN /*!< slave will response to a general call */ +#define I2C_GCEN_DISABLE ((uint32_t)0x00000000U) /*!< slave will not response to a general call */ + +/* software reset I2C */ +#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ +#define I2C_SRESET_SET I2C_CTL0_SRESET /*!< I2C is under reset */ + +/* I2C DMA mode configure */ +/* DMA mode switch */ +#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< disable DMA mode */ +#define I2C_DMA_ON I2C_CTL1_DMAON /*!< enable DMA mode */ + +/* flag indicating DMA last transfer */ +#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ +#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ + +/* I2C PEC configure */ +/* PEC enable */ +#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ +#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ + +/* PEC transfer */ +#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ +#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC value */ + +/* I2C SMBus configure */ +/* issue or not alert through SMBA pin */ +#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ +#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ + +/* ARP protocol in SMBus switch */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< disable ARP */ +#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< enable ARP */ + +/* transmit I2C data */ +#define DATA_TRANS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* receive I2C data */ +#define DATA_RECV(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* I2C duty cycle in fast mode */ +#define I2C_DTCY_2 ((uint32_t)0x00000000U) /*!< T_low/T_high = 2 in fast mode */ +#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< T_low/T_high = 16/9 in fast mode */ + +/* 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 */ + +/* function declarations */ +/* initialization functions */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure I2C clock */ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc); +/* configure I2C address */ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr); + +/* application function declarations */ +/* select SMBus type */ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type); +/* whether or not to send an ACK */ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); +/* configure I2C POAP position */ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos); +/* master sends slave address */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection); +/* enable dual-address mode */ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr); +/* disable dual-address mode */ +void i2c_dualaddr_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 function */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); +/* I2C receive data function */ +uint8_t i2c_data_receive(uint32_t i2c_periph); +/* configure I2C DMA mode */ +void i2c_dma_config(uint32_t i2c_periph, uint32_t dmastate); +/* configure whether next DMA EOT is DMA last transfer or not */ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast); +/* whether to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara); +/* whether or not to response to a general call */ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara); +/* configure software reset of I2C */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); +/* configure I2C PEC calculation */ +void i2c_pec_config(uint32_t i2c_periph, uint32_t pecstate); +/* configure whether to transfer PEC value */ +void i2c_pec_transfer_config(uint32_t i2c_periph, uint32_t pecpara); +/* get packet error checking value */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph); +/* configure I2C alert through SMBA pin */ +void i2c_smbus_alert_config(uint32_t i2c_periph, uint32_t smbuspara); +/* configure I2C ARP protocol in SMBus */ +void i2c_smbus_arp_config(uint32_t i2c_periph, uint32_t arpstate); +/* disable analog noise filter */ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph); +/* enable analog noise filter */ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph); +/* configure digital noise filter */ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, i2c_digital_filter_enum dfilterpara); +/* enable SAM_V interface */ +void i2c_sam_enable(uint32_t i2c_periph); +/* disable SAM_V interface */ +void i2c_sam_disable(uint32_t i2c_periph); +/* enable SAM_V interface timeout detect */ +void i2c_sam_timeout_enable(uint32_t i2c_periph); +/* disable SAM_V interface timeout detect */ +void i2c_sam_timeout_disable(uint32_t i2c_periph); + +/* interrupt & flag functions */ +/* get I2C flag status */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag); +/* clear I2C flag status */ +void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum 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 /* GD32F4XX_I2C_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ipa.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ipa.h new file mode 100644 index 000000000..22e77d1a9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_ipa.h @@ -0,0 +1,381 @@ +/*! + \file gd32f4xx_ipa.h + \brief definitions for the IPA + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_IPA_H +#define GD32F4XX_IPA_H + +#include "gd32f4xx.h" + +/* TLI 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 */ + +/* 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_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 */ + +/* 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 RGB8888 */ +#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 */ + + +/* 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 */ +} 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 */ +} ipa_destination_parameter_struct; + +/* destination pixel format */ +typedef enum { + IPA_DPF_ARGB8888, /*!< 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; + +/* 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) << 16)) +#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) << 16)) +#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) << 16)) +#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_ARG1555 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 */ + +/* 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_ARG1555 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 */ + +/* 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 */ +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); + +/* 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); + +/* 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 /* GD32F4XX_IPA_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_iref.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_iref.h new file mode 100644 index 000000000..1b297a0af --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_iref.h @@ -0,0 +1,187 @@ +/*! + \file gd32f4xx_iref.h + \brief definitions for the IREF + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_IREF_H +#define GD32F4XX_IREF_H + +#include "gd32f4xx.h" + +/* IREF definitions */ +#define IREF IREF_BASE /*!< IREF base address */ + +/* registers definitions */ +#define IREF_CTL REG32(IREF + 0x300U) /*!< IREF control register */ + +/* bits definitions */ +/* IREF_CTL */ +#define IREF_CTL_CSDT BITS(0,5) /*!< current step data */ +#define IREF_CTL_SCMOD BIT(7) /*!< sink current mode */ +#define IREF_CTL_CPT BITS(8,12) /*!< current precision trim */ +#define IREF_CTL_SSEL BIT(14) /*!< step selection */ +#define IREF_CTL_CREN BIT(15) /*!< current reference enable */ + +/* constants definitions */ +/* IREF current precision trim */ +#define CTL_CPT(regval) (BITS(8,12) & ((uint32_t)(regval) << 8)) +#define IREF_CUR_PRECISION_TRIM_0 CTL_CPT(0) /*!< IREF current precision trim 0 */ +#define IREF_CUR_PRECISION_TRIM_1 CTL_CPT(1) /*!< IREF current precision trim 1 */ +#define IREF_CUR_PRECISION_TRIM_2 CTL_CPT(2) /*!< IREF current precision trim 2 */ +#define IREF_CUR_PRECISION_TRIM_3 CTL_CPT(3) /*!< IREF current precision trim 3 */ +#define IREF_CUR_PRECISION_TRIM_4 CTL_CPT(4) /*!< IREF current precision trim 4 */ +#define IREF_CUR_PRECISION_TRIM_5 CTL_CPT(5) /*!< IREF current precision trim 5 */ +#define IREF_CUR_PRECISION_TRIM_6 CTL_CPT(6) /*!< IREF current precision trim 6 */ +#define IREF_CUR_PRECISION_TRIM_7 CTL_CPT(7) /*!< IREF current precision trim 7 */ +#define IREF_CUR_PRECISION_TRIM_8 CTL_CPT(8) /*!< IREF current precision trim 8 */ +#define IREF_CUR_PRECISION_TRIM_9 CTL_CPT(9) /*!< IREF current precision trim 9 */ +#define IREF_CUR_PRECISION_TRIM_10 CTL_CPT(10) /*!< IREF current precision trim 10 */ +#define IREF_CUR_PRECISION_TRIM_11 CTL_CPT(11) /*!< IREF current precision trim 11 */ +#define IREF_CUR_PRECISION_TRIM_12 CTL_CPT(12) /*!< IREF current precision trim 12 */ +#define IREF_CUR_PRECISION_TRIM_13 CTL_CPT(13) /*!< IREF current precision trim 13 */ +#define IREF_CUR_PRECISION_TRIM_14 CTL_CPT(14) /*!< IREF current precision trim 14 */ +#define IREF_CUR_PRECISION_TRIM_15 CTL_CPT(15) /*!< IREF current precision trim 15 */ +#define IREF_CUR_PRECISION_TRIM_16 CTL_CPT(16) /*!< IREF current precision trim 16 */ +#define IREF_CUR_PRECISION_TRIM_17 CTL_CPT(17) /*!< IREF current precision trim 17 */ +#define IREF_CUR_PRECISION_TRIM_18 CTL_CPT(18) /*!< IREF current precision trim 18 */ +#define IREF_CUR_PRECISION_TRIM_19 CTL_CPT(19) /*!< IREF current precision trim 19 */ +#define IREF_CUR_PRECISION_TRIM_20 CTL_CPT(20) /*!< IREF current precision trim 20 */ +#define IREF_CUR_PRECISION_TRIM_21 CTL_CPT(21) /*!< IREF current precision trim 21 */ +#define IREF_CUR_PRECISION_TRIM_22 CTL_CPT(22) /*!< IREF current precision trim 22 */ +#define IREF_CUR_PRECISION_TRIM_23 CTL_CPT(23) /*!< IREF current precision trim 23 */ +#define IREF_CUR_PRECISION_TRIM_24 CTL_CPT(24) /*!< IREF current precision trim 24 */ +#define IREF_CUR_PRECISION_TRIM_25 CTL_CPT(25) /*!< IREF current precision trim 25 */ +#define IREF_CUR_PRECISION_TRIM_26 CTL_CPT(26) /*!< IREF current precision trim 26 */ +#define IREF_CUR_PRECISION_TRIM_27 CTL_CPT(27) /*!< IREF current precision trim 27 */ +#define IREF_CUR_PRECISION_TRIM_28 CTL_CPT(28) /*!< IREF current precision trim 28 */ +#define IREF_CUR_PRECISION_TRIM_29 CTL_CPT(29) /*!< IREF current precision trim 29 */ +#define IREF_CUR_PRECISION_TRIM_30 CTL_CPT(30) /*!< IREF current precision trim 30 */ +#define IREF_CUR_PRECISION_TRIM_31 CTL_CPT(31) /*!< IREF current precision trim 31 */ + +/* IREF current step */ +#define CTL_CSDT(regval) (BITS(0,5) & ((uint32_t)(regval) << 0)) +#define IREF_CUR_STEP_DATA_0 CTL_CSDT(0) /*!< IREF current step data 0 */ +#define IREF_CUR_STEP_DATA_1 CTL_CSDT(1) /*!< IREF current step data 1 */ +#define IREF_CUR_STEP_DATA_2 CTL_CSDT(2) /*!< IREF current step data 2 */ +#define IREF_CUR_STEP_DATA_3 CTL_CSDT(3) /*!< IREF current step data 3 */ +#define IREF_CUR_STEP_DATA_4 CTL_CSDT(4) /*!< IREF current step data 4 */ +#define IREF_CUR_STEP_DATA_5 CTL_CSDT(5) /*!< IREF current step data 5 */ +#define IREF_CUR_STEP_DATA_6 CTL_CSDT(6) /*!< IREF current step data 6 */ +#define IREF_CUR_STEP_DATA_7 CTL_CSDT(7) /*!< IREF current step data 7 */ +#define IREF_CUR_STEP_DATA_8 CTL_CSDT(8) /*!< IREF current step data 8 */ +#define IREF_CUR_STEP_DATA_9 CTL_CSDT(9) /*!< IREF current step data 9 */ +#define IREF_CUR_STEP_DATA_10 CTL_CSDT(10) /*!< IREF current step data 10 */ +#define IREF_CUR_STEP_DATA_11 CTL_CSDT(11) /*!< IREF current step data 11 */ +#define IREF_CUR_STEP_DATA_12 CTL_CSDT(12) /*!< IREF current step data 12 */ +#define IREF_CUR_STEP_DATA_13 CTL_CSDT(13) /*!< IREF current step data 13 */ +#define IREF_CUR_STEP_DATA_14 CTL_CSDT(14) /*!< IREF current step data 14 */ +#define IREF_CUR_STEP_DATA_15 CTL_CSDT(15) /*!< IREF current step data 15 */ +#define IREF_CUR_STEP_DATA_16 CTL_CSDT(16) /*!< IREF current step data 16 */ +#define IREF_CUR_STEP_DATA_17 CTL_CSDT(17) /*!< IREF current step data 17 */ +#define IREF_CUR_STEP_DATA_18 CTL_CSDT(18) /*!< IREF current step data 18 */ +#define IREF_CUR_STEP_DATA_19 CTL_CSDT(19) /*!< IREF current step data 19 */ +#define IREF_CUR_STEP_DATA_20 CTL_CSDT(20) /*!< IREF current step data 20 */ +#define IREF_CUR_STEP_DATA_21 CTL_CSDT(21) /*!< IREF current step data 21 */ +#define IREF_CUR_STEP_DATA_22 CTL_CSDT(22) /*!< IREF current step data 22 */ +#define IREF_CUR_STEP_DATA_23 CTL_CSDT(23) /*!< IREF current step data 23 */ +#define IREF_CUR_STEP_DATA_24 CTL_CSDT(24) /*!< IREF current step data 24 */ +#define IREF_CUR_STEP_DATA_25 CTL_CSDT(25) /*!< IREF current step data 25 */ +#define IREF_CUR_STEP_DATA_26 CTL_CSDT(26) /*!< IREF current step data 26 */ +#define IREF_CUR_STEP_DATA_27 CTL_CSDT(27) /*!< IREF current step data 27 */ +#define IREF_CUR_STEP_DATA_28 CTL_CSDT(28) /*!< IREF current step data 28 */ +#define IREF_CUR_STEP_DATA_29 CTL_CSDT(29) /*!< IREF current step data 29 */ +#define IREF_CUR_STEP_DATA_30 CTL_CSDT(30) /*!< IREF current step data 30 */ +#define IREF_CUR_STEP_DATA_31 CTL_CSDT(31) /*!< IREF current step data 31 */ +#define IREF_CUR_STEP_DATA_32 CTL_CSDT(32) /*!< IREF current step data 32 */ +#define IREF_CUR_STEP_DATA_33 CTL_CSDT(33) /*!< IREF current step data 33 */ +#define IREF_CUR_STEP_DATA_34 CTL_CSDT(34) /*!< IREF current step data 34 */ +#define IREF_CUR_STEP_DATA_35 CTL_CSDT(35) /*!< IREF current step data 35 */ +#define IREF_CUR_STEP_DATA_36 CTL_CSDT(36) /*!< IREF current step data 36 */ +#define IREF_CUR_STEP_DATA_37 CTL_CSDT(37) /*!< IREF current step data 37 */ +#define IREF_CUR_STEP_DATA_38 CTL_CSDT(38) /*!< IREF current step data 38 */ +#define IREF_CUR_STEP_DATA_39 CTL_CSDT(39) /*!< IREF current step data 39 */ +#define IREF_CUR_STEP_DATA_40 CTL_CSDT(40) /*!< IREF current step data 40 */ +#define IREF_CUR_STEP_DATA_41 CTL_CSDT(41) /*!< IREF current step data 41 */ +#define IREF_CUR_STEP_DATA_42 CTL_CSDT(42) /*!< IREF current step data 42 */ +#define IREF_CUR_STEP_DATA_43 CTL_CSDT(43) /*!< IREF current step data 43 */ +#define IREF_CUR_STEP_DATA_44 CTL_CSDT(44) /*!< IREF current step data 44 */ +#define IREF_CUR_STEP_DATA_45 CTL_CSDT(45) /*!< IREF current step data 45 */ +#define IREF_CUR_STEP_DATA_46 CTL_CSDT(46) /*!< IREF current step data 46 */ +#define IREF_CUR_STEP_DATA_47 CTL_CSDT(47) /*!< IREF current step data 47 */ +#define IREF_CUR_STEP_DATA_48 CTL_CSDT(48) /*!< IREF current step data 48 */ +#define IREF_CUR_STEP_DATA_49 CTL_CSDT(49) /*!< IREF current step data 49 */ +#define IREF_CUR_STEP_DATA_50 CTL_CSDT(50) /*!< IREF current step data 50 */ +#define IREF_CUR_STEP_DATA_51 CTL_CSDT(51) /*!< IREF current step data 51 */ +#define IREF_CUR_STEP_DATA_52 CTL_CSDT(52) /*!< IREF current step data 52 */ +#define IREF_CUR_STEP_DATA_53 CTL_CSDT(53) /*!< IREF current step data 53 */ +#define IREF_CUR_STEP_DATA_54 CTL_CSDT(54) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_55 CTL_CSDT(55) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_56 CTL_CSDT(56) /*!< IREF current step data 54 */ +#define IREF_CUR_STEP_DATA_57 CTL_CSDT(57) /*!< IREF current step data 57 */ +#define IREF_CUR_STEP_DATA_58 CTL_CSDT(58) /*!< IREF current step data 58 */ +#define IREF_CUR_STEP_DATA_59 CTL_CSDT(59) /*!< IREF current step data 59 */ +#define IREF_CUR_STEP_DATA_60 CTL_CSDT(60) /*!< IREF current step data 60 */ +#define IREF_CUR_STEP_DATA_61 CTL_CSDT(61) /*!< IREF current step data 61 */ +#define IREF_CUR_STEP_DATA_62 CTL_CSDT(62) /*!< IREF current step data 62 */ +#define IREF_CUR_STEP_DATA_63 CTL_CSDT(63) /*!< IREF current step data 63 */ + +/* IREF mode selection */ +#define IREF_STEP(regval) (BIT(14) & ((uint32_t)(regval) << 14)) +#define IREF_MODE_LOW_POWER IREF_STEP(0) /*!< low power, 1uA step */ +#define IREF_MODE_HIGH_CURRENT IREF_STEP(1) /*!< high current, 8uA step */ + +/* IREF sink current mode*/ +#define IREF_CURRENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define IREF_SOURCE_CURRENT IREF_CURRENT(0) /*!< IREF source current */ +#define IREF_SINK_CURRENT IREF_CURRENT(1) /*!< IREF sink current */ + +/* function declarations */ +/* deinitialize IREF */ +void iref_deinit(void); +/* enable IREF */ +void iref_enable(void); +/* disable IREF */ +void iref_disable(void); + +/* set IREF mode*/ +void iref_mode_set(uint32_t step); +/* set IREF sink current mode*/ +void iref_sink_set(uint32_t sinkmode); +/* set IREF current precision trim value */ +void iref_precision_trim_value_set(uint32_t precisiontrim); +/* set IREF step data*/ +void iref_step_data_config(uint32_t stepdata); + +#endif /* GD32F4XX_IREF_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_it.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_it.h new file mode 100644 index 000000000..10dcf1976 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_it.h @@ -0,0 +1,50 @@ +/*! + \file gd32f4xx_it.h + \brief the header file of the ISR + + \version 2020-12-04, V2.0.0, demo for GD32F4xx +*/ + +/* + Copyright (c) 2020, 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 GD32F4XX_IT_H +#define GD32F4XX_IT_H + +#include "gd32f4xx.h" + +/* function declarations */ +/* this function handles NMI exception */ +void NMI_Handler(void); +/* this function handles BusFault exception */ +void BusFault_Handler(void); +/* this function handles UsageFault exception */ +void UsageFault_Handler(void); +/* this function handles SVC exception */ +void SVC_Handler(void); + +#endif /* GD32F4XX_IT_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_misc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_misc.h new file mode 100644 index 000000000..03dc07486 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_misc.h @@ -0,0 +1,93 @@ +/*! + \file gd32f4xx_misc.h + \brief definitions for the MISC + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_MISC_H +#define GD32F4XX_MISC_H + +#include "gd32f4xx.h" + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80) + +/* 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)0x05FA0000) + +/* priority group - define the pre-emption priority and the subpriority */ +#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ +#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ +#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ +#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ +#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */ + +/* choose the method to enter or exit the lowpower mode */ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ + +/* function declarations */ +/* set the priority group */ +void nvic_priority_group_set(uint32_t nvic_prigroup); + +/* enable NVIC request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority); +/* disable NVIC 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); + +#endif /* GD32F4XX_MISC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_pmu.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_pmu.h new file mode 100644 index 000000000..375dbf08f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_pmu.h @@ -0,0 +1,206 @@ +/*! + \file gd32f4xx_pmu.h + \brief definitions for the PMU + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_PMU_H +#define GD32F4XX_PMU_H + +#include "gd32f4xx.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00000000U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x00000004U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL_LDLP BIT(10) /*!< low-driver mode when use low power LDO */ +#define PMU_CTL_LDNP BIT(11) /*!< low-driver mode when use normal power LDO */ +#define PMU_CTL_LDOVS BITS(14,15) /*!< LDO output voltage select */ +#define PMU_CTL_HDEN BIT(16) /*!< high-driver mode enable */ +#define PMU_CTL_HDS BIT(17) /*!< high-driver mode switch */ +#define PMU_CTL_LDEN BITS(18,19) /*!< low-driver mode enable in deep-sleep mode */ + +/* 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_BLDORF BIT(3) /*!< backup SRAM LDO ready flag */ +#define PMU_CS_WUPEN BIT(8) /*!< wakeup pin enable */ +#define PMU_CS_BLDOON BIT(9) /*!< backup SRAM LDO on */ +#define PMU_CS_LDOVSRF BIT(14) /*!< LDO voltage select ready flag */ +#define PMU_CS_HDRF BIT(16) /*!< high-driver ready flag */ +#define PMU_CS_HDSRF BIT(17) /*!< high-driver switch ready flag */ +#define PMU_CS_LDRF BITS(18,19) /*!< low-driver mode ready flag */ + +/* constants definitions */ +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO normal work when PMU enter deep-sleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deep-sleep mode */ + +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval)<<5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.1V */ +#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 2.3V */ +#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 2.4V */ +#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.9V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 3.0V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 3.1V */ + +/* PMU low-driver mode when use low power LDO */ +#define CTL_LDLP(regval) (BIT(10)&((uint32_t)(regval)<<10)) +#define PMU_NORMALDR_LOWPWR CTL_LDLP(0) /*!< normal driver when use low power LDO */ +#define PMU_LOWDR_LOWPWR CTL_LDLP(1) /*!< low-driver mode enabled when LDEN is 11 and use low power LDO */ + +/* PMU low-driver mode when use normal power LDO */ +#define CTL_LDNP(regval) (BIT(11)&((uint32_t)(regval)<<11)) +#define PMU_NORMALDR_NORMALPWR CTL_LDNP(0) /*!< normal driver when use normal power LDO */ +#define PMU_LOWDR_NORMALPWR CTL_LDNP(1) /*!< low-driver mode enabled when LDEN is 11 and use normal power LDO */ + +/* PMU LDO output voltage select definitions */ +#define CTL_LDOVS(regval) (BITS(14,15)&((uint32_t)(regval)<<14)) +#define PMU_LDOVS_LOW CTL_LDOVS(1) /*!< LDO output voltage low mode */ +#define PMU_LDOVS_MID CTL_LDOVS(2) /*!< LDO output voltage mid mode */ +#define PMU_LDOVS_HIGH CTL_LDOVS(3) /*!< LDO output voltage high mode */ + + +/* PMU high-driver mode switch */ +#define CTL_HDS(regval) (BIT(17)&((uint32_t)(regval)<<17)) +#define PMU_HIGHDR_SWITCH_NONE CTL_HDS(0) /*!< no high-driver mode switch */ +#define PMU_HIGHDR_SWITCH_EN CTL_HDS(1) /*!< high-driver mode switch */ + +/* PMU low-driver mode enable in deep-sleep mode */ +#define CTL_LDEN(regval) (BITS(18,19)&((uint32_t)(regval)<<18)) +#define PMU_LOWDRIVER_DISABLE CTL_LDEN(0) /*!< low-driver mode disable in deep-sleep mode */ +#define PMU_LOWDRIVER_ENABLE CTL_LDEN(3) /*!< low-driver mode enable in deep-sleep mode */ + +/* PMU backup SRAM LDO on or off */ +#define CS_BLDOON(regval) (BIT(9)&((uint32_t)(regval)<<9)) +#define PMU_BLDOON_OFF CS_BLDOON(0) /*!< backup SRAM LDO off */ +#define PMU_BLDOON_ON CS_BLDOON(1) /*!< the backup SRAM LDO on */ + +/* PMU low power mode ready flag definitions */ +#define CS_LDRF(regval) (BITS(18,19)&((uint32_t)(regval)<<18)) +#define PMU_LDRF_NORMAL CS_LDRF(0) /*!< normal driver in deep-sleep mode */ +#define PMU_LDRF_LOWDRIVER CS_LDRF(3) /*!< low-driver mode in deep-sleep mode */ + +/* PMU flag definitions */ +#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ +#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ +#define PMU_FLAG_LVD PMU_CS_LVDF /*!< lvd flag status */ +#define PMU_FLAG_BLDORF PMU_CS_BLDORF /*!< backup SRAM LDO ready flag */ +#define PMU_FLAG_LDOVSRF PMU_CS_LDOVSRF /*!< LDO voltage select ready flag */ +#define PMU_FLAG_HDRF PMU_CS_HDRF /*!< high-driver ready flag */ +#define PMU_FLAG_HDSRF PMU_CS_HDSRF /*!< high-driver switch ready flag */ +#define PMU_FLAG_LDRF PMU_CS_LDRF /*!< low-driver mode ready flag */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00U) /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01U) /*!< standby flag reset */ + +/* 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); + +/* LVD functions */ +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* disable PMU lvd */ +void pmu_lvd_disable(void); + +/* LDO functions */ +/* select LDO output voltage */ +void pmu_ldo_output_select(uint32_t ldo_output); + +/* functions of low-driver mode and high-driver mode */ +/* enable high-driver mode */ +void pmu_highdriver_mode_enable(void); +/* disable high-driver mode */ +void pmu_highdriver_mode_disable(void); +/* switch high-driver mode */ +void pmu_highdriver_switch_select(uint32_t highdr_switch); +/* enable low-driver mode in deep-sleep */ +void pmu_lowdriver_mode_enable(void); +/* disable low-driver mode in deep-sleep */ +void pmu_lowdriver_mode_disable(void); +/* in deep-sleep mode, driver mode when use low power LDO */ +void pmu_lowpower_driver_config(uint32_t mode); +/* in deep-sleep mode, driver mode when use normal power LDO */ +void pmu_normalpower_driver_config(uint32_t mode); + +/* set PMU mode */ +/* PMU work in sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work in deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo, uint32_t lowdrive, uint8_t deepsleepmodecmd); +/* PMU work in standby mode */ +void pmu_to_standbymode(void); +/* enable PMU wakeup pin */ +void pmu_wakeup_pin_enable(void); +/* disable PMU wakeup pin */ +void pmu_wakeup_pin_disable(void); + +/* backup related functions */ +/* backup SRAM LDO on */ +void pmu_backup_ldo_config(uint32_t bkp_ldo); +/* enable write access to the registers in backup domain */ +void pmu_backup_write_enable(void); +/* disable write access to the registers in backup domain */ +void pmu_backup_write_disable(void); + +/* flag functions */ +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag); + +#endif /* GD32F4XX_PMU_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rcu.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rcu.h new file mode 100644 index 000000000..242637464 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rcu.h @@ -0,0 +1,1183 @@ +/*! + \file gd32f4xx_rcu.h + \brief definitions for the RCU + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_RCU_H +#define GD32F4XX_RCU_H + +#include "gd32f4xx.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL REG32(RCU + 0x00U) /*!< control register */ +#define RCU_PLL REG32(RCU + 0x04U) /*!< PLL register */ +#define RCU_CFG0 REG32(RCU + 0x08U) /*!< clock configuration register 0 */ +#define RCU_INT REG32(RCU + 0x0CU) /*!< clock interrupt register */ +#define RCU_AHB1RST REG32(RCU + 0x10U) /*!< AHB1 reset register */ +#define RCU_AHB2RST REG32(RCU + 0x14U) /*!< AHB2 reset register */ +#define RCU_AHB3RST REG32(RCU + 0x18U) /*!< AHB3 reset register */ +#define RCU_APB1RST REG32(RCU + 0x20U) /*!< APB1 reset register */ +#define RCU_APB2RST REG32(RCU + 0x24U) /*!< APB2 reset register */ +#define RCU_AHB1EN REG32(RCU + 0x30U) /*!< AHB1 enable register */ +#define RCU_AHB2EN REG32(RCU + 0x34U) /*!< AHB2 enable register */ +#define RCU_AHB3EN REG32(RCU + 0x38U) /*!< AHB3 enable register */ +#define RCU_APB1EN REG32(RCU + 0x40U) /*!< APB1 enable register */ +#define RCU_APB2EN REG32(RCU + 0x44U) /*!< APB2 enable register */ +#define RCU_AHB1SPEN REG32(RCU + 0x50U) /*!< AHB1 sleep mode enable register */ +#define RCU_AHB2SPEN REG32(RCU + 0x54U) /*!< AHB2 sleep mode enable register */ +#define RCU_AHB3SPEN REG32(RCU + 0x58U) /*!< AHB3 sleep mode enable register */ +#define RCU_APB1SPEN REG32(RCU + 0x60U) /*!< APB1 sleep mode enable register */ +#define RCU_APB2SPEN REG32(RCU + 0x64U) /*!< APB2 sleep mode enable register */ +#define RCU_BDCTL REG32(RCU + 0x70U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x74U) /*!< reset source / clock register */ +#define RCU_PLLSSCTL REG32(RCU + 0x80U) /*!< PLL clock spread spectrum control register */ +#define RCU_PLLI2S REG32(RCU + 0x84U) /*!< PLLI2S register */ +#define RCU_PLLSAI REG32(RCU + 0x88U) /*!< PLLSAI register */ +#define RCU_CFG1 REG32(RCU + 0x8CU) /*!< clock configuration register 1 */ +#define RCU_ADDCTL REG32(RCU + 0xC0U) /*!< Additional clock control register */ +#define RCU_ADDINT REG32(RCU + 0xCCU) /*!< Additional clock interrupt register */ +#define RCU_ADDAPB1RST REG32(RCU + 0xE0U) /*!< APB1 additional reset register */ +#define RCU_ADDAPB1EN REG32(RCU + 0xE4U) /*!< APB1 additional enable register */ +#define RCU_ADDAPB1SPEN REG32(RCU + 0xE8U) /*!< APB1 additional sleep mode enable register */ +#define RCU_VKEY REG32(RCU + 0x100U) /*!< voltage key register */ +#define RCU_DSV REG32(RCU + 0x134U) /*!< deep-sleep mode voltage register */ + +/* bits definitions */ +/* RCU_CTL */ +#define RCU_CTL_IRC16MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL_IRC16MSTB BIT(1) /*!< IRC16M high speed internal oscillator stabilization flag */ +#define RCU_CTL_IRC16MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL_IRC16MCALIB BITS(8,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_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL_PLLSTB BIT(25) /*!< PLL Clock Stabilization Flag */ +#define RCU_CTL_PLLI2SEN BIT(26) /*!< PLLI2S enable */ +#define RCU_CTL_PLLI2SSTB BIT(27) /*!< PLLI2S Clock Stabilization Flag */ +#define RCU_CTL_PLLSAIEN BIT(28) /*!< PLLSAI enable */ +#define RCU_CTL_PLLSAISTB BIT(29) /*!< PLLSAI Clock Stabilization Flag */ + +/* RCU_PLL */ +#define RCU_PLL_PLLPSC BITS(0,5) /*!< The PLL VCO source clock prescaler */ +#define RCU_PLL_PLLN BITS(6,14) /*!< The PLL VCO clock multi factor */ +#define RCU_PLL_PLLP BITS(16,17) /*!< The PLLP output frequency division factor from PLL VCO clock */ +#define RCU_PLL_PLLSEL BIT(22) /*!< PLL Clock Source Selection */ +#define RCU_PLL_PLLQ BITS(24,27) /*!< The PLL Q output frequency division factor from PLL VCO clock */ + +/* 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,20) /*!< RTC clock divider factor */ +#define RCU_CFG0_CKOUT0SEL BITS(21,22) /*!< CKOUT0 Clock Source Selection */ +#define RCU_CFG0_I2SSEL BIT(23) /*!< I2S Clock Source Selection */ +#define RCU_CFG0_CKOUT0DIV BITS(24,26) /*!< The CK_OUT0 divider which the CK_OUT0 frequency can be reduced */ +#define RCU_CFG0_CKOUT1DIV BITS(27,29) /*!< The CK_OUT1 divider which the CK_OUT1 frequency can be reduced */ +#define RCU_CFG0_CKOUT1SEL BITS(30,31) /*!< CKOUT1 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_IRC16MSTBIF BIT(2) /*!< IRC16M stabilization interrupt flag */ +#define RCU_INT_HXTALSTBIF BIT(3) /*!< HXTAL stabilization interrupt flag */ +#define RCU_INT_PLLSTBIF BIT(4) /*!< PLL stabilization interrupt flag */ +#define RCU_INT_PLLI2SSTBIF BIT(5) /*!< PLLI2S stabilization interrupt flag */ +#define RCU_INT_PLLSAISTBIF BIT(6) /*!< PLLSAI 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_IRC16MSTBIE BIT(10) /*!< IRC16M stabilization interrupt enable */ +#define RCU_INT_HXTALSTBIE BIT(11) /*!< HXTAL stabilization interrupt enable */ +#define RCU_INT_PLLSTBIE BIT(12) /*!< PLL stabilization interrupt enable */ +#define RCU_INT_PLLI2SSTBIE BIT(13) /*!< PLLI2S Stabilization Interrupt Enable */ +#define RCU_INT_PLLSAISTBIE BIT(14) /*!< PLLSAI 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_IRC16MSTBIC BIT(18) /*!< IRC16M Stabilization Interrupt Clear */ +#define RCU_INT_HXTALSTBIC BIT(19) /*!< HXTAL Stabilization Interrupt Clear */ +#define RCU_INT_PLLSTBIC BIT(20) /*!< PLL stabilization Interrupt Clear */ +#define RCU_INT_PLLI2SSTBIC BIT(21) /*!< PLLI2S stabilization Interrupt Clear */ +#define RCU_INT_PLLSAISTBIC BIT(22) /*!< PLLSAI stabilization Interrupt Clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL Clock Stuck Interrupt Clear */ + +/* RCU_AHB1RST */ +#define RCU_AHB1RST_PARST BIT(0) /*!< GPIO port A reset */ +#define RCU_AHB1RST_PBRST BIT(1) /*!< GPIO port B reset */ +#define RCU_AHB1RST_PCRST BIT(2) /*!< GPIO port C reset */ +#define RCU_AHB1RST_PDRST BIT(3) /*!< GPIO port D reset */ +#define RCU_AHB1RST_PERST BIT(4) /*!< GPIO port E reset */ +#define RCU_AHB1RST_PFRST BIT(5) /*!< GPIO port F reset */ +#define RCU_AHB1RST_PGRST BIT(6) /*!< GPIO port G reset */ +#define RCU_AHB1RST_PHRST BIT(7) /*!< GPIO port H reset */ +#define RCU_AHB1RST_PIRST BIT(8) /*!< GPIO port I reset */ +#define RCU_AHB1RST_CRCRST BIT(12) /*!< CRC reset */ +#define RCU_AHB1RST_DMA0RST BIT(21) /*!< DMA0 reset */ +#define RCU_AHB1RST_DMA1RST BIT(22) /*!< DMA1 reset */ +#define RCU_AHB1RST_IPARST BIT(23) /*!< IPA reset */ +#define RCU_AHB1RST_ENETRST BIT(25) /*!< ENET reset */ +#define RCU_AHB1RST_USBHSRST BIT(29) /*!< USBHS reset */ + +/* RCU_AHB2RST */ +#define RCU_AHB2RST_DCIRST BIT(0) /*!< DCI reset */ +#define RCU_AHB2RST_TRNGRST BIT(6) /*!< TRNG reset */ +#define RCU_AHB2RST_USBFSRST BIT(7) /*!< USBFS reset */ + +/* RCU_AHB3RST */ +#define RCU_AHB3RST_EXMCRST BIT(0) /*!< EXMC 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_TIMER11RST BIT(6) /*!< TIMER11 reset */ +#define RCU_APB1RST_TIMER12RST BIT(7) /*!< TIMER12 reset */ +#define RCU_APB1RST_TIMER13RST BIT(8) /*!< TIMER13 reset */ +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< WWDGT reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_SPI2RST BIT(15) /*!< SPI2 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_CAN0RST BIT(25) /*!< CAN0 reset */ +#define RCU_APB1RST_CAN1RST BIT(26) /*!< CAN1 reset */ +#define RCU_APB1RST_PMURST BIT(28) /*!< PMU 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_ADCRST BIT(8) /*!< ADC reset */ +#define RCU_APB2RST_SDIORST BIT(11) /*!< SDIO reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_SPI3RST BIT(13) /*!< SPI3 reset */ +#define RCU_APB2RST_SYSCFGRST BIT(14) /*!< SYSCFG reset */ +#define RCU_APB2RST_TIMER8RST BIT(16) /*!< TIMER8 reset */ +#define RCU_APB2RST_TIMER9RST BIT(17) /*!< TIMER9 reset */ +#define RCU_APB2RST_TIMER10RST BIT(18) /*!< TIMER10 reset */ +#define RCU_APB2RST_SPI4RST BIT(20) /*!< SPI4 reset */ +#define RCU_APB2RST_SPI5RST BIT(21) /*!< SPI5 reset */ +#define RCU_APB2RST_TLIRST BIT(26) /*!< TLI reset */ + +/* RCU_AHB1EN */ +#define RCU_AHB1EN_PAEN BIT(0) /*!< GPIO port A clock enable */ +#define RCU_AHB1EN_PBEN BIT(1) /*!< GPIO port B clock enable */ +#define RCU_AHB1EN_PCEN BIT(2) /*!< GPIO port C clock enable */ +#define RCU_AHB1EN_PDEN BIT(3) /*!< GPIO port D clock enable */ +#define RCU_AHB1EN_PEEN BIT(4) /*!< GPIO port E clock enable */ +#define RCU_AHB1EN_PFEN BIT(5) /*!< GPIO port F clock enable */ +#define RCU_AHB1EN_PGEN BIT(6) /*!< GPIO port G clock enable */ +#define RCU_AHB1EN_PHEN BIT(7) /*!< GPIO port H clock enable */ +#define RCU_AHB1EN_PIEN BIT(8) /*!< GPIO port I clock enable */ +#define RCU_AHB1EN_CRCEN BIT(12) /*!< CRC clock enable */ +#define RCU_AHB1EN_BKPSRAMEN BIT(18) /*!< BKPSRAM clock enable */ +#define RCU_AHB1EN_TCMSRAMEN BIT(20) /*!< TCMSRAM clock enable */ +#define RCU_AHB1EN_DMA0EN BIT(21) /*!< DMA0 clock enable */ +#define RCU_AHB1EN_DMA1EN BIT(22) /*!< DMA1 clock enable */ +#define RCU_AHB1EN_IPAEN BIT(23) /*!< IPA clock enable */ +#define RCU_AHB1EN_ENETEN BIT(25) /*!< ENET clock enable */ +#define RCU_AHB1EN_ENETTXEN BIT(26) /*!< Ethernet TX clock enable */ +#define RCU_AHB1EN_ENETRXEN BIT(27) /*!< Ethernet RX clock enable */ +#define RCU_AHB1EN_ENETPTPEN BIT(28) /*!< Ethernet PTP clock enable */ +#define RCU_AHB1EN_USBHSEN BIT(29) /*!< USBHS clock enable */ +#define RCU_AHB1EN_USBHSULPIEN BIT(30) /*!< USBHS ULPI clock enable */ + +/* RCU_AHB2EN */ +#define RCU_AHB2EN_DCIEN BIT(0) /*!< DCI clock enable */ +#define RCU_AHB2EN_TRNGEN BIT(6) /*!< TRNG clock enable */ +#define RCU_AHB2EN_USBFSEN BIT(7) /*!< USBFS clock enable */ + +/* RCU_AHB3EN */ +#define RCU_AHB3EN_EXMCEN BIT(0) /*!< EXMC clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 clock enable */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 clock enable */ +#define RCU_APB1EN_TIMER3EN BIT(2) /*!< TIMER3 clock enable */ +#define RCU_APB1EN_TIMER4EN BIT(3) /*!< TIMER4 clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 clock enable */ +#define RCU_APB1EN_TIMER6EN BIT(5) /*!< TIMER6 clock enable */ +#define RCU_APB1EN_TIMER11EN BIT(6) /*!< TIMER11 clock enable */ +#define RCU_APB1EN_TIMER12EN BIT(7) /*!< TIMER12 clock enable */ +#define RCU_APB1EN_TIMER13EN BIT(8) /*!< TIMER13 clock enable */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< WWDGT clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_SPI2EN BIT(15) /*!< SPI2 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_USART2EN BIT(18) /*!< USART2 clock enable */ +#define RCU_APB1EN_UART3EN BIT(19) /*!< UART3 clock enable */ +#define RCU_APB1EN_UART4EN BIT(20) /*!< UART4 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#define RCU_APB1EN_I2C2EN BIT(23) /*!< I2C2 clock enable */ +#define RCU_APB1EN_CAN0EN BIT(25) /*!< CAN0 clock enable */ +#define RCU_APB1EN_CAN1EN BIT(26) /*!< CAN1 clock enable */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< PMU clock enable */ +#define RCU_APB1EN_DACEN BIT(29) /*!< DAC clock enable */ +#define RCU_APB1EN_UART6EN BIT(30) /*!< UART6 clock enable */ +#define RCU_APB1EN_UART7EN BIT(31) /*!< UART7 clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_TIMER0EN BIT(0) /*!< TIMER0 clock enable */ +#define RCU_APB2EN_TIMER7EN BIT(1) /*!< TIMER7 clock enable */ +#define RCU_APB2EN_USART0EN BIT(4) /*!< USART0 clock enable */ +#define RCU_APB2EN_USART5EN BIT(5) /*!< USART5 clock enable */ +#define RCU_APB2EN_ADC0EN BIT(8) /*!< ADC0 clock enable */ +#define RCU_APB2EN_ADC1EN BIT(9) /*!< ADC1 clock enable */ +#define RCU_APB2EN_ADC2EN BIT(10) /*!< ADC2 clock enable */ +#define RCU_APB2EN_SDIOEN BIT(11) /*!< SDIO clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_SPI3EN BIT(13) /*!< SPI3 clock enable */ +#define RCU_APB2EN_SYSCFGEN BIT(14) /*!< SYSCFG clock enable */ +#define RCU_APB2EN_TIMER8EN BIT(16) /*!< TIMER8 clock enable */ +#define RCU_APB2EN_TIMER9EN BIT(17) /*!< TIMER9 clock enable */ +#define RCU_APB2EN_TIMER10EN BIT(18) /*!< TIMER10 clock enable */ +#define RCU_APB2EN_SPI4EN BIT(20) /*!< SPI4 clock enable */ +#define RCU_APB2EN_SPI5EN BIT(21) /*!< SPI5 clock enable */ +#define RCU_APB2EN_TLIEN BIT(26) /*!< TLI clock enable */ + +/* RCU_AHB1SPEN */ +#define RCU_AHB1SPEN_PASPEN BIT(0) /*!< GPIO port A clock enable when sleep mode */ +#define RCU_AHB1SPEN_PBSPEN BIT(1) /*!< GPIO port B clock enable when sleep mode */ +#define RCU_AHB1SPEN_PCSPEN BIT(2) /*!< GPIO port C clock enable when sleep mode */ +#define RCU_AHB1SPEN_PDSPEN BIT(3) /*!< GPIO port D clock enable when sleep mode */ +#define RCU_AHB1SPEN_PESPEN BIT(4) /*!< GPIO port E clock enable when sleep mode */ +#define RCU_AHB1SPEN_PFSPEN BIT(5) /*!< GPIO port F clock enable when sleep mode */ +#define RCU_AHB1SPEN_PGSPEN BIT(6) /*!< GPIO port G clock enable when sleep mode */ +#define RCU_AHB1SPEN_PHSPEN BIT(7) /*!< GPIO port H clock enable when sleep mode */ +#define RCU_AHB1SPEN_PISPEN BIT(8) /*!< GPIO port I clock enable when sleep mode */ +#define RCU_AHB1SPEN_CRCSPEN BIT(12) /*!< CRC clock enable when sleep mode */ +#define RCU_AHB1SPEN_FMCSPEN BIT(15) /*!< FMC 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_BKPSRAMSPEN BIT(18) /*!< BKPSRAM clock enable when sleep mode */ +#define RCU_AHB1SPEN_SRAM2SPEN BIT(19) /*!< SRAM2 clock enable when sleep mode */ +#define RCU_AHB1SPEN_DMA0SPEN BIT(21) /*!< DMA0 clock when sleep mode enable */ +#define RCU_AHB1SPEN_DMA1SPEN BIT(22) /*!< DMA1 clock when sleep mode enable */ +#define RCU_AHB1SPEN_IPASPEN BIT(23) /*!< IPA clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETSPEN BIT(25) /*!< ENET clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETTXSPEN BIT(26) /*!< Ethernet TX clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETRXSPEN BIT(27) /*!< Ethernet RX clock enable when sleep mode */ +#define RCU_AHB1SPEN_ENETPTPSPEN BIT(28) /*!< Ethernet PTP clock enable when sleep mode */ +#define RCU_AHB1SPEN_USBHSSPEN BIT(29) /*!< USBHS clock enable when sleep mode */ +#define RCU_AHB1SPEN_USBHSULPISPEN BIT(30) /*!< USBHS ULPI clock enable when sleep mode */ + +/* RCU_AHB2SPEN */ +#define RCU_AHB2SPEN_DCISPEN BIT(0) /*!< DCI clock enable when sleep mode */ +#define RCU_AHB2SPEN_TRNGSPEN BIT(6) /*!< TRNG clock enable when sleep mode */ +#define RCU_AHB2SPEN_USBFSSPEN BIT(7) /*!< USBFS clock enable when sleep mode */ + +/* RCU_AHB3SPEN */ +#define RCU_AHB3SPEN_EXMCSPEN BIT(0) /*!< EXMC 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_TIMER11SPEN BIT(6) /*!< TIMER11 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER12SPEN BIT(7) /*!< TIMER12 clock enable when sleep mode */ +#define RCU_APB1SPEN_TIMER13SPEN BIT(8) /*!< TIMER13 clock enable when sleep mode */ +#define RCU_APB1SPEN_WWDGTSPEN BIT(11) /*!< WWDGT 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_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_CAN0SPEN BIT(25) /*!< CAN0 clock enable when sleep mode*/ +#define RCU_APB1SPEN_CAN1SPEN BIT(26) /*!< CAN1 clock enable when sleep mode */ +#define RCU_APB1SPEN_PMUSPEN BIT(28) /*!< PMU 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_SDIOSPEN BIT(11) /*!< SDIO 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_SYSCFGSPEN BIT(14) /*!< SYSCFG clock enable when sleep mode */ +#define RCU_APB2SPEN_TIMER8SPEN BIT(16) /*!< TIMER8 clock enable when sleep mode */ +#define RCU_APB2SPEN_TIMER9SPEN BIT(17) /*!< TIMER9 clock enable when sleep mode */ +#define RCU_APB2SPEN_TIMER10SPEN BIT(18) /*!< TIMER10 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_TLISPEN BIT(26) /*!< TLI 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 BIT(3) /*!< LXTAL drive capability */ +#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_PLLSSCTL */ +#define RCU_PLLSSCTL_MODCNT BITS(0,12) /*!< these bits configure PLL spread spectrum modulation + profile amplitude and frequency. the following criteria + must be met: MODSTEP*MODCNT=215-1 */ +#define RCU_PLLSSCTL_MODSTEP BITS(13,27) /*!< these bits configure PLL spread spectrum modulation + profile amplitude and frequency. the following criteria + must be met: MODSTEP*MODCNT=215-1 */ +#define RCU_PLLSSCTL_SS_TYPE BIT(30) /*!< PLL spread spectrum modulation type select */ +#define RCU_PLLSSCTL_SSCGON BIT(31) /*!< PLL spread spectrum modulation enable */ + +/* RCU_PLLI2S */ +#define RCU_PLLI2S_PLLI2SN BITS(6,14) /*!< the PLLI2S VCO clock multi factor */ +#define RCU_PLLI2S_PLLI2SR BITS(28,30) /*!< the PLLI2S R output frequency division factor from PLLI2S VCO clock */ + +/* RCU_PLLSAI */ +#define RCU_PLLSAI_PLLSAIN BITS(6,14) /*!< the PLLSAI VCO clock multi factor */ +#define RCU_PLLSAI_PLLSAIP BITS(16,17) /*!< the PLLSAI P output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAI_PLLSAIR BITS(28,30) /*!< the PLLSAI R output frequency division factor from PLLSAI VCO clock */ + +/* RCU_CFG1 */ +#define RCU_CFG1_PLLSAIRDIV BITS(16,17) /*!< the divider factor from PLLSAIR clock */ +#define RCU_CFG1_TIMERSEL BIT(24) /*!< TIMER clock selection */ + +/* RCU_ADDCTL */ +#define RCU_ADDCTL_CK48MSEL BIT(0) /*!< 48MHz clock selection */ +#define RCU_ADDCTL_PLL48MSEL BIT(1) /*!< PLL48M clock selection */ +#define RCU_ADDCTL_IRC48MEN BIT(16) /*!< internal 48MHz RC oscillator enable */ +#define RCU_ADDCTL_IRC48MSTB BIT(17) /*!< internal 48MHz RC oscillator clock stabilization flag */ +#define RCU_ADDCTL_IRC48MCAL BITS(24,31) /*!< internal 48MHz RC oscillator calibration value register */ + +/* RCU_ADDINT */ +#define RCU_ADDINT_IRC48MSTBIF BIT(6) /*!< IRC48M stabilization interrupt flag */ +#define RCU_ADDINT_IRC48MSTBIE BIT(14) /*!< internal 48 MHz RC oscillator stabilization interrupt enable */ +#define RCU_ADDINT_IRC48MSTBIC BIT(22) /*!< internal 48 MHz RC oscillator stabilization interrupt clear */ + +/* RCU_ADDAPB1RST */ +#define RCU_ADDAPB1RST_CTCRST BIT(27) /*!< CTC reset */ +#define RCU_ADDAPB1RST_IREFRST BIT(31) /*!< IREF reset */ + +/* RCU_ADDAPB1EN */ +#define RCU_ADDAPB1EN_CTCEN BIT(27) /*!< CTC clock enable */ +#define RCU_ADDAPB1EN_IREFEN BIT(31) /*!< IREF interface clock enable */ + +/* RCU_ADDAPB1SPEN */ +#define RCU_ADDAPB1SPEN_CTCSPEN BIT(27) /*!< CTC clock enable during sleep mode */ +#define RCU_ADDAPB1SPEN_IREFSPEN BIT(31) /*!< IREF interface clock enable during sleep mode */ + +/* RCU_VKEY */ +#define RCU_VKEY_KEY BITS(0,31) /*!< RCU_DSV key register */ + +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,2) /*!< deep-sleep mode voltage select */ + +/* 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) & 0x1FU) +/* define the voltage key unlock value */ +#define RCU_VKEY_UNLOCK ((uint32_t)0x1A2B3C4DU) + +/* register offset */ +/* peripherals enable */ +#define AHB1EN_REG_OFFSET 0x30U /*!< AHB1 enable register offset */ +#define AHB2EN_REG_OFFSET 0x34U /*!< AHB2 enable register offset */ +#define AHB3EN_REG_OFFSET 0x38U /*!< AHB3 enable register offset */ +#define APB1EN_REG_OFFSET 0x40U /*!< APB1 enable register offset */ +#define APB2EN_REG_OFFSET 0x44U /*!< APB2 enable register offset */ +#define AHB1SPEN_REG_OFFSET 0x50U /*!< AHB1 sleep mode enable register offset */ +#define AHB2SPEN_REG_OFFSET 0x54U /*!< AHB2 sleep mode enable register offset */ +#define AHB3SPEN_REG_OFFSET 0x58U /*!< AHB3 sleep mode enable register offset */ +#define APB1SPEN_REG_OFFSET 0x60U /*!< APB1 sleep mode enable register offset */ +#define APB2SPEN_REG_OFFSET 0x64U /*!< APB2 sleep mode enable register offset */ +#define ADD_APB1EN_REG_OFFSET 0xE4U /*!< APB1 additional enable register offset */ +#define ADD_APB1SPEN_REG_OFFSET 0xE8U /*!< APB1 additional sleep mode enable register offset */ + +/* peripherals reset */ +#define AHB1RST_REG_OFFSET 0x10U /*!< AHB1 reset register offset */ +#define AHB2RST_REG_OFFSET 0x14U /*!< AHB2 reset register offset */ +#define AHB3RST_REG_OFFSET 0x18U /*!< AHB3 reset register offset */ +#define APB1RST_REG_OFFSET 0x20U /*!< APB1 reset register offset */ +#define APB2RST_REG_OFFSET 0x24U /*!< APB2 reset register offset */ +#define ADD_APB1RST_REG_OFFSET 0xE0U /*!< APB1 additional reset register offset */ +#define RSTSCK_REG_OFFSET 0x74U /*!< reset source/clock register offset */ + +/* clock control */ +#define CTL_REG_OFFSET 0x00U /*!< control register offset */ +#define BDCTL_REG_OFFSET 0x70U /*!< backup domain control register offset */ +#define ADDCTL_REG_OFFSET 0xC0U /*!< additional clock control register offset */ + +/* clock stabilization and stuck interrupt */ +#define INT_REG_OFFSET 0x0CU /*!< clock interrupt register offset */ +#define ADDINT_REG_OFFSET 0xCCU /*!< additional clock interrupt register offset */ + +/* configuration register */ +#define PLL_REG_OFFSET 0x04U /*!< PLL register offset */ +#define CFG0_REG_OFFSET 0x08U /*!< clock configuration register 0 offset */ +#define PLLSSCTL_REG_OFFSET 0x80U /*!< PLL clock spread spectrum control register offset */ +#define PLLI2S_REG_OFFSET 0x84U /*!< PLLI2S register offset */ +#define PLLSAI_REG_OFFSET 0x88U /*!< PLLSAI register offset */ +#define CFG1_REG_OFFSET 0x8CU /*!< clock configuration register 1 offset */ + +/* peripheral clock enable */ +typedef enum +{ + /* AHB1 peripherals */ + RCU_GPIOA = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 0U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 1U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 2U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 3U), /*!< GPIOD clock */ + RCU_GPIOE = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 4U), /*!< GPIOE clock */ + RCU_GPIOF = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 5U), /*!< GPIOF clock */ + RCU_GPIOG = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 6U), /*!< GPIOG clock */ + RCU_GPIOH = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 7U), /*!< GPIOH clock */ + RCU_GPIOI = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 8U), /*!< GPIOI clock */ + RCU_CRC = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 12U), /*!< CRC clock */ + RCU_BKPSRAM = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 18U), /*!< BKPSRAM clock */ + RCU_TCMSRAM = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 20U), /*!< TCMSRAM clock */ + RCU_DMA0 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 21U), /*!< DMA0 clock */ + RCU_DMA1 = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 22U), /*!< DMA1 clock */ + RCU_IPA = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 23U), /*!< IPA clock */ + RCU_ENET = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 25U), /*!< ENET clock */ + RCU_ENETTX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 26U), /*!< ENETTX clock */ + RCU_ENETRX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 27U), /*!< ENETRX clock */ + RCU_ENETPTP = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 28U), /*!< ENETPTP clock */ + RCU_USBHS = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 29U), /*!< USBHS clock */ + RCU_USBHSULPI = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 30U), /*!< USBHSULPI clock */ + /* AHB2 peripherals */ + RCU_DCI = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 0U), /*!< DCI clock */ + RCU_TRNG = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 6U), /*!< TRNG clock */ + RCU_USBFS = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 7U), /*!< USBFS clock */ + /* AHB3 peripherals */ + RCU_EXMC = RCU_REGIDX_BIT(AHB3EN_REG_OFFSET, 0U), /*!< EXMC 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_TIMER11 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 6U), /*!< TIMER11 clock */ + RCU_TIMER12 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 7U), /*!< TIMER12 clock */ + RCU_TIMER13 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 8U), /*!< TIMER13 clock */ + RCU_WWDGT = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 14U), /*!< SPI1 clock */ + RCU_SPI2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 15U), /*!< SPI2 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_CAN0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 25U), /*!< CAN0 clock */ + RCU_CAN1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 26U), /*!< CAN1 clock */ + RCU_PMU = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 28U), /*!< PMU 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 */ + RCU_RTC = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 15U), /*!< RTC 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_SDIO = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 11U), /*!< SDIO clock */ + RCU_SPI0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI3 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 13U), /*!< SPI3 clock */ + RCU_SYSCFG = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 14U), /*!< SYSCFG clock */ + RCU_TIMER8 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 16U), /*!< TIMER8 clock */ + RCU_TIMER9 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 17U), /*!< TIMER9 clock */ + RCU_TIMER10 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 18U), /*!< TIMER10 clock */ + RCU_SPI4 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 20U), /*!< SPI4 clock */ + RCU_SPI5 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 21U), /*!< SPI5 clock */ + RCU_TLI = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 26U), /*!< TLI clock */ + /* APB1 additional peripherals */ + RCU_CTC = RCU_REGIDX_BIT(ADD_APB1EN_REG_OFFSET, 27U), /*!< CTC clock */ + RCU_IREF = RCU_REGIDX_BIT(ADD_APB1EN_REG_OFFSET, 31U), /*!< IREF clock */ +}rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum +{ + /* AHB1 peripherals */ + RCU_GPIOA_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 0U), /*!< GPIOA clock */ + RCU_GPIOB_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 1U), /*!< GPIOB clock */ + RCU_GPIOC_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 2U), /*!< GPIOC clock */ + RCU_GPIOD_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 3U), /*!< GPIOD clock */ + RCU_GPIOE_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 4U), /*!< GPIOE clock */ + RCU_GPIOF_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 5U), /*!< GPIOF clock */ + RCU_GPIOG_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 6U), /*!< GPIOG clock */ + RCU_GPIOH_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 7U), /*!< GPIOH clock */ + RCU_GPIOI_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 8U), /*!< GPIOI clock */ + RCU_CRC_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 12U), /*!< CRC clock */ + RCU_FMC_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 15U), /*!< FMC clock */ + RCU_SRAM0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 16U), /*!< SRAM0 clock */ + RCU_SRAM1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 17U), /*!< SRAM1 clock */ + RCU_BKPSRAM_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 18U), /*!< BKPSRAM clock */ + RCU_SRAM2_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 19U), /*!< SRAM2 clock */ + RCU_DMA0_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 21U), /*!< DMA0 clock */ + RCU_DMA1_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 22U), /*!< DMA1 clock */ + RCU_IPA_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 23U), /*!< IPA clock */ + RCU_ENET_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 25U), /*!< ENET clock */ + RCU_ENETTX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 26U), /*!< ENETTX clock */ + RCU_ENETRX_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 27U), /*!< ENETRX clock */ + RCU_ENETPTP_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 28U), /*!< ENETPTP clock */ + RCU_USBHS_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 29U), /*!< USBHS clock */ + RCU_USBHSULPI_SLP = RCU_REGIDX_BIT(AHB1SPEN_REG_OFFSET, 30U), /*!< USBHSULPI clock */ + /* AHB2 peripherals */ + RCU_DCI_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 0U), /*!< DCI clock */ + RCU_TRNG_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 6U), /*!< TRNG clock */ + RCU_USBFS_SLP = RCU_REGIDX_BIT(AHB2SPEN_REG_OFFSET, 7U), /*!< USBFS clock */ + /* AHB3 peripherals */ + RCU_EXMC_SLP = RCU_REGIDX_BIT(AHB3SPEN_REG_OFFSET, 0U), /*!< EXMC clock */ + /* APB1 peripherals */ + RCU_TIMER1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 0U), /*!< TIMER1 clock */ + RCU_TIMER2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 1U), /*!< TIMER2 clock */ + RCU_TIMER3_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 2U), /*!< TIMER3 clock */ + RCU_TIMER4_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 3U), /*!< TIMER4 clock */ + RCU_TIMER5_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 4U), /*!< TIMER5 clock */ + RCU_TIMER6_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 5U), /*!< TIMER6 clock */ + RCU_TIMER11_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 6U), /*!< TIMER11 clock */ + RCU_TIMER12_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 7U), /*!< TIMER12 clock */ + RCU_TIMER13_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 8U), /*!< TIMER13 clock */ + RCU_WWDGT_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 11U), /*!< WWDGT clock */ + RCU_SPI1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 14U), /*!< SPI1 clock */ + RCU_SPI2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 15U), /*!< SPI2 clock */ + RCU_USART1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 17U), /*!< USART1 clock */ + RCU_USART2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 18U), /*!< USART2 clock */ + RCU_UART3_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 19U), /*!< UART3 clock */ + RCU_UART4_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 20U), /*!< UART4 clock */ + RCU_I2C0_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_I2C2_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 23U), /*!< I2C2 clock */ + RCU_CAN0_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 25U), /*!< CAN0 clock */ + RCU_CAN1_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 26U), /*!< CAN1 clock */ + RCU_PMU_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 28U), /*!< PMU clock */ + RCU_DAC_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 29U), /*!< DAC clock */ + RCU_UART6_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 30U), /*!< UART6 clock */ + RCU_UART7_SLP = RCU_REGIDX_BIT(APB1SPEN_REG_OFFSET, 31U), /*!< UART7 clock */ + /* APB2 peripherals */ + RCU_TIMER0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 0U), /*!< TIMER0 clock */ + RCU_TIMER7_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 1U), /*!< TIMER7 clock */ + RCU_USART0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 4U), /*!< USART0 clock */ + RCU_USART5_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 5U), /*!< USART5 clock */ + RCU_ADC0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 8U), /*!< ADC0 clock */ + RCU_ADC1_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 9U), /*!< ADC1 clock */ + RCU_ADC2_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 10U), /*!< ADC2 clock */ + RCU_SDIO_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 11U), /*!< SDIO clock */ + RCU_SPI0_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI3_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 13U), /*!< SPI3 clock */ + RCU_SYSCFG_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 14U), /*!< SYSCFG clock */ + RCU_TIMER8_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 16U), /*!< TIMER8 clock */ + RCU_TIMER9_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 17U), /*!< TIMER9 clock */ + RCU_TIMER10_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 18U), /*!< TIMER10 clock */ + RCU_SPI4_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 20U), /*!< SPI4 clock */ + RCU_SPI5_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 21U), /*!< SPI5 clock */ + RCU_TLI_SLP = RCU_REGIDX_BIT(APB2SPEN_REG_OFFSET, 26U), /*!< TLI clock */ + /* APB1 additional peripherals */ + RCU_CTC_SLP = RCU_REGIDX_BIT(ADD_APB1SPEN_REG_OFFSET, 27U), /*!< CTC clock */ + RCU_IREF_SLP = RCU_REGIDX_BIT(ADD_APB1SPEN_REG_OFFSET, 31U), /*!< IREF clock */ +}rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum +{ + /* AHB1 peripherals */ + RCU_GPIOARST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 0U), /*!< GPIOA clock reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 1U), /*!< GPIOB clock reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 2U), /*!< GPIOC clock reset */ + RCU_GPIODRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 3U), /*!< GPIOD clock reset */ + RCU_GPIOERST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 4U), /*!< GPIOE clock reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 5U), /*!< GPIOF clock reset */ + RCU_GPIOGRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 6U), /*!< GPIOG clock reset */ + RCU_GPIOHRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 7U), /*!< GPIOH clock reset */ + RCU_GPIOIRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 8U), /*!< GPIOI clock reset */ + RCU_CRCRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 12U), /*!< CRC 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_IPARST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 23U), /*!< IPA clock reset */ + RCU_ENETRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 25U), /*!< ENET clock reset */ + RCU_USBHSRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 29U), /*!< USBHS clock reset */ + /* AHB2 peripherals */ + RCU_DCIRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 0U), /*!< DCI clock reset */ + RCU_TRNGRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 6U), /*!< TRNG clock reset */ + RCU_USBFSRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 7U), /*!< USBFS clock reset */ + /* AHB3 peripherals */ + RCU_EXMCRST = RCU_REGIDX_BIT(AHB3RST_REG_OFFSET, 0U), /*!< EXMC 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_TIMER11RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 6U), /*!< TIMER11 clock reset */ + RCU_TIMER12RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 7U), /*!< TIMER12 clock reset */ + RCU_TIMER13RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 8U), /*!< TIMER13 clock reset */ + RCU_WWDGTRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 11U), /*!< WWDGT 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_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_CAN0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 25U), /*!< CAN0 clock reset */ + RCU_CAN1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 26U), /*!< CAN1 clock reset */ + RCU_PMURST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 28U), /*!< PMU 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_ADCRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 8U), /*!< ADCs all clock reset */ + RCU_SDIORST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 11U), /*!< SDIO 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_SYSCFGRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 14U), /*!< SYSCFG clock reset */ + RCU_TIMER8RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 16U), /*!< TIMER8 clock reset */ + RCU_TIMER9RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 17U), /*!< TIMER9 clock reset */ + RCU_TIMER10RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 18U), /*!< TIMER10 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_TLIRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 26U), /*!< TLI clock reset */ + /* APB1 additional peripherals */ + RCU_CTCRST = RCU_REGIDX_BIT(ADD_APB1RST_REG_OFFSET, 27U), /*!< CTC clock reset */ + RCU_IREFRST = RCU_REGIDX_BIT(ADD_APB1RST_REG_OFFSET, 31U) /*!< IREF clock reset */ +}rcu_periph_reset_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum +{ + /* clock stabilization flags */ + RCU_FLAG_IRC16MSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 1U), /*!< IRC16M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 25U), /*!< PLL stabilization flags */ + RCU_FLAG_PLLI2SSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 27U), /*!< PLLI2S stabilization flags */ + RCU_FLAG_PLLSAISTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 29U), /*!< PLLSAI 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(ADDCTL_REG_OFFSET, 17U), /*!< IRC48M stabilization 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 ckm 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_IRC16MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 2U), /*!< IRC16M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 4U), /*!< PLL stabilization interrupt flag */ + RCU_INT_FLAG_PLLI2SSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 5U), /*!< PLLI2S stabilization interrupt flag */ + RCU_INT_FLAG_PLLSAISTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U), /*!< PLLSAI stabilization interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 7U), /*!< HXTAL clock stuck interrupt flag */ + RCU_INT_FLAG_IRC48MSTB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 6U), /*!< IRC48M 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_IRC16MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U), /*!< IRC16M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 19U), /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 20U), /*!< PLL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLI2SSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 21U), /*!< PLLI2S stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSAISTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U), /*!< PLLSAI stabilization interrupt flags clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 23U), /*!< CKM interrupt flags clear */ + RCU_INT_FLAG_IRC48MSTB_CLR = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 22U), /*!< internal 48 MHz RC oscillator stabilization interrupt 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_IRC16MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 10U), /*!< IRC16M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 11U), /*!< HXTAL stabilization interrupt */ + RCU_INT_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 12U), /*!< PLL stabilization interrupt */ + RCU_INT_PLLI2SSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 13U), /*!< PLLI2S stabilization interrupt */ + RCU_INT_PLLSAISTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 14U), /*!< PLLSAI stabilization interrupt */ + RCU_INT_IRC48MSTB = RCU_REGIDX_BIT(ADDINT_REG_OFFSET, 14U), /*!< internal 48 MHz RC oscillator 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_IRC16M = RCU_REGIDX_BIT(CTL_REG_OFFSET, 0U), /*!< IRC16M */ + RCU_IRC48M = RCU_REGIDX_BIT(ADDCTL_REG_OFFSET, 16U), /*!< IRC48M */ + RCU_IRC32K = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U), /*!< IRC32K */ + RCU_PLL_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 24U), /*!< PLL */ + RCU_PLLI2S_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 26U), /*!< PLLI2S */ + RCU_PLLSAI_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 28U), /*!< PLLSAI */ +}rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum +{ + CK_SYS = 0, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB1, /*!< APB1 clock */ + CK_APB2, /*!< APB2 clock */ +}rcu_clock_freq_enum; + +/* RCU_CFG0 register bit define */ +/* system clock source select */ +#define CFG0_SCS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_CKSYSSRC_IRC16M CFG0_SCS(0) /*!< system clock source select IRC16M */ +#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */ +#define RCU_CKSYSSRC_PLLP CFG0_SCS(2) /*!< system clock source select PLLP */ + +/* system clock source select status */ +#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define RCU_SCSS_IRC16M CFG0_SCSS(0) /*!< system clock source select IRC16M */ +#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select HXTAL */ +#define RCU_SCSS_PLLP CFG0_SCSS(2) /*!< system clock source select PLLP */ + +/* AHB prescaler selection */ +#define CFG0_AHBPSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#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) << 10)) +#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) << 13)) +#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 */ + +/* RTC clock divider factor from HXTAL clock */ +#define CFG0_RTCDIV(regval) (BITS(16,20) & ((uint32_t)(regval) << 16)) +#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 */ + +/* CKOUT0 Clock source selection */ +#define CFG0_CKOUT0SEL(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define RCU_CKOUT0SRC_IRC16M CFG0_CKOUT0SEL(0) /*!< internal 16M RC oscillator clock selected */ +#define RCU_CKOUT0SRC_LXTAL CFG0_CKOUT0SEL(1) /*!< low speed crystal oscillator clock (LXTAL) selected */ +#define RCU_CKOUT0SRC_HXTAL CFG0_CKOUT0SEL(2) /*!< high speed crystal oscillator clock (HXTAL) selected */ +#define RCU_CKOUT0SRC_PLLP CFG0_CKOUT0SEL(3) /*!< CK_PLLP clock selected */ + +/* I2S Clock source selection */ +#define RCU_I2SSRC_PLLI2S ((uint32_t)0x00000000U) /*!< PLLI2S output clock selected as I2S source clock */ +#define RCU_I2SSRC_I2S_CKIN RCU_CFG0_I2SSEL /*!< external I2S_CKIN pin selected as I2S source clock */ + +/* The CK_OUT0 divider */ +#define CFG0_CKOUT0DIV(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUT0_DIV1 CFG0_CKOUT0DIV(0) /*!< CK_OUT0 is divided by 1 */ +#define RCU_CKOUT0_DIV2 CFG0_CKOUT0DIV(4) /*!< CK_OUT0 is divided by 2 */ +#define RCU_CKOUT0_DIV3 CFG0_CKOUT0DIV(5) /*!< CK_OUT0 is divided by 3 */ +#define RCU_CKOUT0_DIV4 CFG0_CKOUT0DIV(6) /*!< CK_OUT0 is divided by 4 */ +#define RCU_CKOUT0_DIV5 CFG0_CKOUT0DIV(7) /*!< CK_OUT0 is divided by 5 */ + +/* The CK_OUT1 divider */ +#define CFG0_CKOUT1DIV(regval) (BITS(27,29) & ((uint32_t)(regval) << 27)) +#define RCU_CKOUT1_DIV1 CFG0_CKOUT1DIV(0) /*!< CK_OUT1 is divided by 1 */ +#define RCU_CKOUT1_DIV2 CFG0_CKOUT1DIV(4) /*!< CK_OUT1 is divided by 2 */ +#define RCU_CKOUT1_DIV3 CFG0_CKOUT1DIV(5) /*!< CK_OUT1 is divided by 3 */ +#define RCU_CKOUT1_DIV4 CFG0_CKOUT1DIV(6) /*!< CK_OUT1 is divided by 4 */ +#define RCU_CKOUT1_DIV5 CFG0_CKOUT1DIV(7) /*!< CK_OUT1 is divided by 5 */ + +/* CKOUT1 Clock source selection */ +#define CFG0_CKOUT1SEL(regval) (BITS(30,31) & ((uint32_t)(regval) << 30)) +#define RCU_CKOUT1SRC_SYSTEMCLOCK CFG0_CKOUT1SEL(0) /*!< system clock selected */ +#define RCU_CKOUT1SRC_PLLI2SR CFG0_CKOUT1SEL(1) /*!< CK_PLLI2SR clock selected */ +#define RCU_CKOUT1SRC_HXTAL CFG0_CKOUT1SEL(2) /*!< high speed crystal oscillator clock (HXTAL) selected */ +#define RCU_CKOUT1SRC_PLLP CFG0_CKOUT1SEL(3) /*!< CK_PLLP clock selected */ + +/* RCU_CFG1 register bit define */ +/* the divider factor from PLLI2SQ clock */ +#define CFG1_PLLI2SQDIV(regval) (BITS(0,4) & ((uint32_t)(regval) << 0)) +#define RCU_PLLI2SQ_DIV1 CFG1_PLLI2SQDIV(0) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/1 */ +#define RCU_PLLI2SQ_DIV2 CFG1_PLLI2SQDIV(1) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/2 */ +#define RCU_PLLI2SQ_DIV3 CFG1_PLLI2SQDIV(2) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/3 */ +#define RCU_PLLI2SQ_DIV4 CFG1_PLLI2SQDIV(3) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/4 */ +#define RCU_PLLI2SQ_DIV5 CFG1_PLLI2SQDIV(4) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/5 */ +#define RCU_PLLI2SQ_DIV6 CFG1_PLLI2SQDIV(5) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/6 */ +#define RCU_PLLI2SQ_DIV7 CFG1_PLLI2SQDIV(6) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/7 */ +#define RCU_PLLI2SQ_DIV8 CFG1_PLLI2SQDIV(7) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/8 */ +#define RCU_PLLI2SQ_DIV9 CFG1_PLLI2SQDIV(8) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/9 */ +#define RCU_PLLI2SQ_DIV10 CFG1_PLLI2SQDIV(9) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/10 */ +#define RCU_PLLI2SQ_DIV11 CFG1_PLLI2SQDIV(10) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/11 */ +#define RCU_PLLI2SQ_DIV12 CFG1_PLLI2SQDIV(11) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/12 */ +#define RCU_PLLI2SQ_DIV13 CFG1_PLLI2SQDIV(12) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/13 */ +#define RCU_PLLI2SQ_DIV14 CFG1_PLLI2SQDIV(13) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/14 */ +#define RCU_PLLI2SQ_DIV15 CFG1_PLLI2SQDIV(14) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/15 */ +#define RCU_PLLI2SQ_DIV16 CFG1_PLLI2SQDIV(15) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/16 */ +#define RCU_PLLI2SQ_DIV17 CFG1_PLLI2SQDIV(16) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/17 */ +#define RCU_PLLI2SQ_DIV18 CFG1_PLLI2SQDIV(17) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/18 */ +#define RCU_PLLI2SQ_DIV19 CFG1_PLLI2SQDIV(18) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/19 */ +#define RCU_PLLI2SQ_DIV20 CFG1_PLLI2SQDIV(19) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/20 */ +#define RCU_PLLI2SQ_DIV21 CFG1_PLLI2SQDIV(20) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/21 */ +#define RCU_PLLI2SQ_DIV22 CFG1_PLLI2SQDIV(21) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/22 */ +#define RCU_PLLI2SQ_DIV23 CFG1_PLLI2SQDIV(22) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/23 */ +#define RCU_PLLI2SQ_DIV24 CFG1_PLLI2SQDIV(23) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/24 */ +#define RCU_PLLI2SQ_DIV25 CFG1_PLLI2SQDIV(24) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/25 */ +#define RCU_PLLI2SQ_DIV26 CFG1_PLLI2SQDIV(25) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/26 */ +#define RCU_PLLI2SQ_DIV27 CFG1_PLLI2SQDIV(26) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/27 */ +#define RCU_PLLI2SQ_DIV28 CFG1_PLLI2SQDIV(27) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/28 */ +#define RCU_PLLI2SQ_DIV29 CFG1_PLLI2SQDIV(28) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/29 */ +#define RCU_PLLI2SQ_DIV30 CFG1_PLLI2SQDIV(29) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/30 */ +#define RCU_PLLI2SQ_DIV31 CFG1_PLLI2SQDIV(30) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/31 */ +#define RCU_PLLI2SQ_DIV32 CFG1_PLLI2SQDIV(31) /*!< CK_PLLI2SQDIV clock select CK_PLLI2SQ/32 */ + +/* the divider factor from PLLSAIR clock */ +#define CFG1_PLLSAIRDIV(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) +#define RCU_PLLSAIR_DIV2 CFG1_PLLSAIRDIV(0) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/2 */ +#define RCU_PLLSAIR_DIV4 CFG1_PLLSAIRDIV(1) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/4 */ +#define RCU_PLLSAIR_DIV8 CFG1_PLLSAIRDIV(2) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/8 */ +#define RCU_PLLSAIR_DIV16 CFG1_PLLSAIRDIV(3) /*!< CK_PLLSAIRDIV clock select CK_PLLSAIR/16 */ + +/* TIMER clock selection */ +#define RCU_TIMER_PSC_MUL2 ~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_PLLSSCTL register bit define */ +/* PLL spread spectrum modulation type select */ +#define RCU_SS_TYPE_CENTER ((uint32_t)0x00000000U) /*!< center type is selected */ +#define RCU_SS_TYPE_DOWN RCU_PLLSSCTL_SS_TYPE /*!< down type is selected */ + +/* RCU_PLL register bit define */ +/* The PLL VCO source clock prescaler */ +#define RCU_PLLPSC_DIV_MIN ((uint32_t)2U) /*!< PLLPSC_DIV min value */ +#define RCU_PLLPSC_DIV_MAX ((uint32_t)63U) /*!< PLLPSC_DIV max value */ + +/* The PLL VCO clock multi factor */ +#define RCU_PLLN_MUL_MIN ((uint32_t)64U) /*!< PLLN_MUL min value */ +#define RCU_PLLN_MUL_MAX ((uint32_t)500U) /*!< PLLN_MUL max value */ +#define RCU_SS_MODULATION_CENTER_INC ((uint32_t)5U) /*!< minimum factor of PLLN in center mode */ +#define RCU_SS_MODULATION_DOWN_INC ((uint32_t)7U) /*!< minimum factor of PLLN in down mode */ + +/* The PLLP output frequency division factor from PLL VCO clock */ +#define RCU_PLLP_DIV_MIN ((uint32_t)2U) /*!< PLLP_DIV min value */ +#define RCU_PLLP_DIV_MAX ((uint32_t)8U) /*!< PLLP_DIV max value */ + +/* PLL Clock Source Selection */ +#define RCU_PLLSRC_IRC16M ((uint32_t)0x00000000U) /*!< IRC16M clock selected as source clock of PLL, PLLSAI, PLLI2S */ +#define RCU_PLLSRC_HXTAL RCU_PLL_PLLSEL /*!< HXTAL clock selected as source clock of PLL, PLLSAI, PLLI2S */ + +/* The PLL Q output frequency division factor from PLL VCO clock */ +#define RCU_PLLQ_DIV_MIN ((uint32_t)2U) /*!< PLLQ_DIV min value */ +#define RCU_PLLQ_DIV_MAX ((uint32_t)15U) /*!< PLLQ_DIV max value */ + +#define CHECK_PLL_PSC_VALID(val) (((val) >= RCU_PLLPSC_DIV_MIN)&&((val) <= RCU_PLLPSC_DIV_MAX)) +#define CHECK_PLL_N_VALID(val, inc) (((val) >= (RCU_PLLN_MUL_MIN + (inc)))&&((val) <= RCU_PLLN_MUL_MAX)) +#define CHECK_PLL_P_VALID(val) (((val) == 2U) || ((val) == 4U) || ((val) == 6U) || ((val) == 8U)) +#define CHECK_PLL_Q_VALID(val) (((val) >= RCU_PLLQ_DIV_MIN)&&((val) <= RCU_PLLQ_DIV_MAX)) + +/* RCU_BDCTL register bit define */ +/* LXTAL drive capability */ +#define RCU_LXTALDRI_LOWER_DRIVE ((uint32_t)0x00000000) /*!< LXTAL drive capability is selected lower */ +#define RCU_LXTALDRI_HIGHER_DRIVE RCU_BDCTL_LXTALDRI /*!< LXTAL drive capability is selected higher */ + +/* RTC clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#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_PLLI2S register bit define */ +/* The PLLI2S VCO clock multi factor */ +#define RCU_PLLI2SN_MUL_MIN 50U +#define RCU_PLLI2SN_MUL_MAX 500U + +/* The PLLI2S Q output frequency division factor from PLLI2S VCO clock */ +#define RCU_PLLI2SQ_DIV_MIN 2U +#define RCU_PLLI2SQ_DIV_MAX 15U + +/* The PLLI2S R output frequency division factor from PLLI2S VCO clock */ +#define RCU_PLLI2SR_DIV_MIN 2U +#define RCU_PLLI2SR_DIV_MAX 7U + +/* RCU_PLLSAI register bit define */ +/* The PLLSAI VCO clock multi factor */ +#define RCU_PLLSAIN_MUL_MIN 50U +#define RCU_PLLSAIN_MUL_MAX 500U + +/* The PLLSAI P output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAIP_DIV_MIN 2U +#define RCU_PLLSAIP_DIV_MAX 8U + +/* The PLLSAI Q output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAIQ_DIV_MIN 2U +#define RCU_PLLSAIQ_DIV_MAX 15U + +/* The PLLSAI R output frequency division factor from PLLSAI VCO clock */ +#define RCU_PLLSAIR_DIV_MIN 2U +#define RCU_PLLSAIR_DIV_MAX 7U + +#define CHECK_PLLI2S_PSC_VALID(val) (((val) >= RCU_PLLI2SPSC_DIV_MIN)&&((val) <= RCU_PLLI2SPSC_DIV_MAX)) +#define CHECK_PLLI2S_N_VALID(val) (((val) >= RCU_PLLI2SN_MUL_MIN)&&((val) <= RCU_PLLI2SN_MUL_MAX)) +#define CHECK_PLLI2S_Q_VALID(val) (((val) >= RCU_PLLI2SQ_DIV_MIN)&&((val) <= RCU_PLLI2SQ_DIV_MAX)) +#define CHECK_PLLI2S_R_VALID(val) (((val) >= RCU_PLLI2SR_DIV_MIN)&&((val) <= RCU_PLLI2SR_DIV_MAX)) + +#define CHECK_PLLSAI_N_VALID(val) (((val) >= (RCU_PLLSAIN_MUL_MIN))&&((val) <= RCU_PLLSAIN_MUL_MAX)) +#define CHECK_PLLSAI_P_VALID(val) (((val) == 2U) || ((val) == 4U) || ((val) == 6U) || ((val) == 8U)) +#define CHECK_PLLSAI_Q_VALID(val) (((val) >= RCU_PLLSAIQ_DIV_MIN)&&((val) <= RCU_PLLSAIQ_DIV_MAX)) +#define CHECK_PLLSAI_R_VALID(val) (((val) >= RCU_PLLSAIR_DIV_MIN)&&((val) <= RCU_PLLSAIR_DIV_MAX)) + +/* RCU_ADDCTL register bit define */ +/* 48MHz clock selection */ +#define RCU_CK48MSRC_PLL48M ((uint32_t)0x00000000U) /*!< CK48M source clock select PLL48M */ +#define RCU_CK48MSRC_IRC48M RCU_ADDCTL_CK48MSEL /*!< CK48M source clock select IRC48M */ + +/* PLL48M clock selection */ +#define RCU_PLL48MSRC_PLLQ ((uint32_t)0x00000000U) /*!< PLL48M source clock select PLLQ */ +#define RCU_PLL48MSRC_PLLSAIP RCU_ADDCTL_PLL48MSEL /*!< PLL48M source clock select PLLSAIP */ + +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_0 DSV_DSLPVS(0) /*!< core voltage is default value in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1 DSV_DSLPVS(1) /*!< core voltage is (default value-0.1)V in deep-sleep mode(customers are not recommended to use it)*/ +#define RCU_DEEPSLEEP_V_2 DSV_DSLPVS(2) /*!< core voltage is (default value-0.2)V in deep-sleep mode(customers are not recommended to use it)*/ +#define RCU_DEEPSLEEP_V_3 DSV_DSLPVS(3) /*!< core voltage is (default value-0.3)V in deep-sleep mode(customers are not recommended to use it)*/ + + +/* 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 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 clock source selection and PLL multiply factor */ +ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uint32_t pll_p, uint32_t pll_q); +/* configure the PLLI2S clock */ +ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_r); +/* configure the PLLSAI clock */ +ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsai_r); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +/* cconfigure 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 I2S clock source selection */ +void rcu_i2s_clock_config(uint32_t i2s_clock_source); +/* 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 TIMER clock prescaler selection */ +void rcu_timer_clock_prescaler_config(uint32_t timer_clock_prescaler); +/* configure the TLI clock division selection */ +void rcu_tli_clock_div_config(uint32_t pllsai_r_div); + +/* LXTAL, IRC8M, PLL 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 IRC16M adjust value */ +void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval); +/* configure the spread spectrum modulation for the main PLL clock */ +void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, uint32_t modcnt); +/* enable the spread spectrum modulation for the main PLL clock */ +void rcu_spread_spectrum_enable(void); +/* disable the spread spectrum modulation for the main PLL clock */ +void rcu_spread_spectrum_disable(void); + +/* 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); + +/* voltage configure and clock frequency get functions */ +/* unlock the voltage key */ +void rcu_voltage_key_unlock(void); +/* set the deep sleep mode voltage */ +void rcu_deepsleep_voltage_set(uint32_t dsvol); +/* 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); +/* 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); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum interrupt); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum interrupt); + +#endif /* GD32F4XX_RCU_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rtc.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rtc.h new file mode 100644 index 000000000..283abc653 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_rtc.h @@ -0,0 +1,641 @@ +/*! + \file gd32f4xx_rtc.c + \brief definitions for the RTC + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_RTC_H +#define GD32F4XX_RTC_H + +#include "gd32f4xx.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x04U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x08U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x10U) /*!< RTC time prescaler register */ +#define RTC_WUT REG32((RTC) + 0x14U) /*!< RTC wakeup timer regiser */ +#define RTC_COSC REG32((RTC) + 0x18U) /*!< RTC coarse calibration register */ +#define RTC_ALRM0TD REG32((RTC) + 0x1CU) /*!< RTC alarm 0 time and date register */ +#define RTC_ALRM1TD REG32((RTC) + 0x20U) /*!< RTC alarm 1 time and date register */ +#define RTC_WPK REG32((RTC) + 0x24U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x28U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x2CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x30U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x34U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x38U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x3CU) /*!< RTC high resolution frequency compensation registor */ +#define RTC_TAMP REG32((RTC) + 0x40U) /*!< RTC tamper register */ +#define RTC_ALRM0SS REG32((RTC) + 0x44U) /*!< RTC alarm 0 sub second register */ +#define RTC_ALRM1SS REG32((RTC) + 0x48U) /*!< RTC alarm 1 sub second register */ +#define RTC_BKP0 REG32((RTC) + 0x50U) /*!< RTC backup register */ +#define RTC_BKP1 REG32((RTC) + 0x54U) /*!< RTC backup register */ +#define RTC_BKP2 REG32((RTC) + 0x58U) /*!< RTC backup register */ +#define RTC_BKP3 REG32((RTC) + 0x5CU) /*!< RTC backup register */ +#define RTC_BKP4 REG32((RTC) + 0x60U) /*!< RTC backup register */ +#define RTC_BKP5 REG32((RTC) + 0x64U) /*!< RTC backup register */ +#define RTC_BKP6 REG32((RTC) + 0x68U) /*!< RTC backup register */ +#define RTC_BKP7 REG32((RTC) + 0x6CU) /*!< RTC backup register */ +#define RTC_BKP8 REG32((RTC) + 0x70U) /*!< RTC backup register */ +#define RTC_BKP9 REG32((RTC) + 0x74U) /*!< RTC backup register */ +#define RTC_BKP10 REG32((RTC) + 0x78U) /*!< RTC backup register */ +#define RTC_BKP11 REG32((RTC) + 0x7CU) /*!< RTC backup register */ +#define RTC_BKP12 REG32((RTC) + 0x80U) /*!< RTC backup register */ +#define RTC_BKP13 REG32((RTC) + 0x84U) /*!< RTC backup register */ +#define RTC_BKP14 REG32((RTC) + 0x88U) /*!< RTC backup register */ +#define RTC_BKP15 REG32((RTC) + 0x8CU) /*!< RTC backup register */ +#define RTC_BKP16 REG32((RTC) + 0x90U) /*!< RTC backup register */ +#define RTC_BKP17 REG32((RTC) + 0x94U) /*!< RTC backup register */ +#define RTC_BKP18 REG32((RTC) + 0x98U) /*!< RTC backup register */ +#define RTC_BKP19 REG32((RTC) + 0x9CU) /*!< RTC backup 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_CCEN BIT(7) /*!< coarse calibration function enable */ +#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 */ + +/* 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 occurs 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 tamper 0 detected flag */ +#define RTC_STAT_TP1F BIT(14) /*!< RTC tamper 1 detected flag */ +#define RTC_STAT_SCPF BIT(16) /*!< smooth calibration pending 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_COSC */ +#define RTC_COSC_COSS BITS(0,4) /*!< coarse calibration step */ +#define RTC_COSC_COSD BIT(7) /*!< coarse calibration direction */ + +/* 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 units 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 units 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 16 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) /*!< tamper detection interrupt enable */ +#define RTC_TAMP_TP1EN BIT(3) /*!< tamper 1 detection enable */ +#define RTC_TAMP_TP1EG BIT(4) /*!< Tamper 1 event trigger edge for RTC tamp 1 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 */ +#define RTC_TAMP_TP0SEL BIT(16) /*!< Tamper 0 function input mapping selection */ +#define RTC_TAMP_TSSEL BIT(17) /*!< Timestamp input mapping selection */ +#define RTC_TAMP_AOT BIT(18) /*!< RTC_ALARM output Type */ + +/* 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 */ + +/* 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_WEDSDAY ((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 */ + +/* ctl register value */ +#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_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 */ + +/* 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 */ + +/* tamp register value */ +#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 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_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 RTC_TAMPER0 RTC_TAMP_TP0EN /*!< tamper 0 detection enable */ +#define RTC_TAMPER1 RTC_TAMP_TP1EN /*!< tamper 1 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_TAMP_AOT /*!< RTC alarm output push-pull mode */ + +/* ALRMXSS register value */ +#define ALRMXSS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0)) /*!< write value to RTC_ALRMXSS_SSC bit field */ + +#define ALRMXSS_MASKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMXSS_MASKSSC bit field */ +#define RTC_MASKSSC_0_14 ALRMXSS_MASKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MASKSSC_1_14 ALRMXSS_MASKSSC(1) /*!< mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared */ +#define RTC_MASKSSC_2_14 ALRMXSS_MASKSSC(2) /*!< mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared */ +#define RTC_MASKSSC_3_14 ALRMXSS_MASKSSC(3) /*!< mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared */ +#define RTC_MASKSSC_4_14 ALRMXSS_MASKSSC(4) /*!< mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared */ +#define RTC_MASKSSC_5_14 ALRMXSS_MASKSSC(5) /*!< mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared */ +#define RTC_MASKSSC_6_14 ALRMXSS_MASKSSC(6) /*!< mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared */ +#define RTC_MASKSSC_7_14 ALRMXSS_MASKSSC(7) /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_8_14 ALRMXSS_MASKSSC(8) /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_9_14 ALRMXSS_MASKSSC(9) /*!< mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared */ +#define RTC_MASKSSC_10_14 ALRMXSS_MASKSSC(10) /*!< mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared */ +#define RTC_MASKSSC_11_14 ALRMXSS_MASKSSC(11) /*!< mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared */ +#define RTC_MASKSSC_12_14 ALRMXSS_MASKSSC(12) /*!< mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared */ +#define RTC_MASKSSC_13_14 ALRMXSS_MASKSSC(13) /*!< mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared */ +#define RTC_MASKSSC_14 ALRMXSS_MASKSSC(14) /*!< mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared */ +#define RTC_MASKSSC_NONE ALRMXSS_MASKSSC(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 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)0x00000000U) /*!< 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 coarse calibration direction */ +#define CALIB_INCREASE ((uint8_t)0x01U) /*!< RTC coarse calibration increase */ +#define CALIB_DECREASE ((uint8_t)0x02U) /*!< RTC coarse calibration decrease */ + +/* RTC wakeup timer clock */ +#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 */ + +/* RTC_AF pin */ +#define RTC_AF0_TIMESTAMP ((uint32_t)0x00000000) /*!< RTC_AF0 use for timestamp */ +#define RTC_AF1_TIMESTAMP RTC_TAMP_TSSEL /*!< RTC_AF1 use for timestamp */ +#define RTC_AF0_TAMPER0 ((uint32_t)0x00000000) /*!< RTC_AF0 use for tamper0 */ +#define RTC_AF1_TAMPER0 RTC_TAMP_TP0SEL /*!< RTC_AF1 use for tamper0 */ + +/* RTC flags */ +#define RTC_FLAG_ALRM0W RTC_STAT_ALRM0WF /*!< alarm0 configuration can be write flag */ +#define RTC_FLAG_ALRM1W 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 configuration mark status flag */ +#define RTC_FLAG_RSYN RTC_STAT_RSYNF /*!< register synchronization flag */ +#define RTC_FLAG_INIT RTC_STAT_INITF /*!< initialization state flag */ +#define RTC_FLAG_ALRM0 RTC_STAT_ALRM0F /*!< alarm0 occurs flag */ +#define RTC_FLAG_ALRM1 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_TP1 RTC_STAT_TP1F /*!< RTC tamper 1 detected flag */ +#define RTC_STAT_SCP RTC_STAT_SCPF /*!< smooth calibration pending flag */ + +/* function declarations */ +/* 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); + +/* 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); + +/* 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); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); +/* RTC time-stamp pin map */ +void rtc_timestamp_pin_map(uint32_t rtc_af); + +/* enable RTC tamper */ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper); +/* disable RTC tamper */ +void rtc_tamper_disable(uint32_t source); +/* RTC tamper0 pin map */ +void rtc_tamper0_pin_map(uint32_t rtc_af); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disble 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); + +/* 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 RTC coarse calibration */ +ErrStatus rtc_coarse_calibration_enable(void); +/* disable RTC coarse calibration */ +ErrStatus rtc_coarse_calibration_disable(void); +/* configure RTC coarse calibration direction and step */ +ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step); + +#endif /* GD32F4XX_RTC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_sdio.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_sdio.h new file mode 100644 index 000000000..1d88e4518 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_sdio.h @@ -0,0 +1,434 @@ +/*! + \file gd32f4xx_sdio.h + \brief definitions for the SDIO + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_SDIO_H +#define GD32F4XX_SDIO_H + +#include "gd32f4xx.h" + +/* SDIO definitions */ +#define SDIO SDIO_BASE + +/* registers definitions */ +#define SDIO_PWRCTL REG32(SDIO + 0x00000000U) /*!< SDIO power control register */ +#define SDIO_CLKCTL REG32(SDIO + 0x00000004U) /*!< SDIO clock control register */ +#define SDIO_CMDAGMT REG32(SDIO + 0x00000008U) /*!< SDIO command argument register */ +#define SDIO_CMDCTL REG32(SDIO + 0x0000000CU) /*!< SDIO command control register */ +#define SDIO_RSPCMDIDX REG32(SDIO + 0x00000010U) /*!< SDIO command index response register */ +#define SDIO_RESP0 REG32(SDIO + 0x00000014U) /*!< SDIO response register 0 */ +#define SDIO_RESP1 REG32(SDIO + 0x00000018U) /*!< SDIO response register 1 */ +#define SDIO_RESP2 REG32(SDIO + 0x0000001CU) /*!< SDIO response register 2 */ +#define SDIO_RESP3 REG32(SDIO + 0x00000020U) /*!< SDIO response register 3 */ +#define SDIO_DATATO REG32(SDIO + 0x00000024U) /*!< SDIO data timeout register */ +#define SDIO_DATALEN REG32(SDIO + 0x00000028U) /*!< SDIO data length register */ +#define SDIO_DATACTL REG32(SDIO + 0x0000002CU) /*!< SDIO data control register */ +#define SDIO_DATACNT REG32(SDIO + 0x00000030U) /*!< SDIO data counter register */ +#define SDIO_STAT REG32(SDIO + 0x00000034U) /*!< SDIO status register */ +#define SDIO_INTC REG32(SDIO + 0x00000038U) /*!< SDIO interrupt clear register */ +#define SDIO_INTEN REG32(SDIO + 0x0000003CU) /*!< SDIO interrupt enable register */ +#define SDIO_FIFOCNT REG32(SDIO + 0x00000048U) /*!< SDIO FIFO counter register */ +#define SDIO_FIFO REG32(SDIO + 0x00000080U) /*!< SDIO FIFO data register */ + +/* bits definitions */ +/* SDIO_PWRCTL */ +#define SDIO_PWRCTL_PWRCTL BITS(0,1) /*!< SDIO power control bits */ + +/* SDIO_CLKCTL */ +#define SDIO_CLKCTL_DIV BITS(0,7) /*!< clock division */ +#define SDIO_CLKCTL_CLKEN BIT(8) /*!< SDIO_CLK clock output enable bit */ +#define SDIO_CLKCTL_CLKPWRSAV BIT(9) /*!< SDIO_CLK clock dynamic switch on/off for power saving */ +#define SDIO_CLKCTL_CLKBYP BIT(10) /*!< clock bypass enable bit */ +#define SDIO_CLKCTL_BUSMODE BITS(11,12) /*!< SDIO card bus mode control bit */ +#define SDIO_CLKCTL_CLKEDGE BIT(13) /*!< SDIO_CLK clock edge selection bit */ +#define SDIO_CLKCTL_HWCLKEN BIT(14) /*!< hardware clock control enable bit */ +#define SDIO_CLKCTL_DIV8 BIT(31) /*!< MSB of clock division */ + +/* 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_CMDRESP BITS(6,7) /*!< command response type bits */ +#define SDIO_CMDCTL_INTWAIT BIT(8) /*!< interrupt wait instead of timeout */ +#define SDIO_CMDCTL_WAITDEND BIT(9) /*!< wait for ends of data transfer */ +#define SDIO_CMDCTL_CSMEN BIT(10) /*!< command state machine(CSM) enable bit */ +#define SDIO_CMDCTL_SUSPEND BIT(11) /*!< SD I/O suspend command(SD I/O only) */ +#define SDIO_CMDCTL_ENCMDC BIT(12) /*!< CMD completion signal enabled (CE-ATA only) */ +#define SDIO_CMDCTL_NINTEN BIT(13) /*!< no CE-ATA interrupt (CE-ATA only) */ +#define SDIO_CMDCTL_ATAEN BIT(14) /*!< CE-ATA command enable(CE-ATA only) */ + +/* 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 BIT(2) /*!< data transfer mode */ +#define SDIO_DATACTL_DMAEN BIT(3) /*!< DMA enable bit */ +#define SDIO_DATACTL_BLKSZ BITS(4,7) /*!< data block size */ +#define SDIO_DATACTL_RWEN BIT(8) /*!< read wait mode enabled(SD I/O only) */ +#define SDIO_DATACTL_RWSTOP BIT(9) /*!< read wait stop(SD I/O only) */ +#define SDIO_DATACTL_RWTYPE BIT(10) /*!< read wait type(SD I/O only) */ +#define SDIO_DATACTL_IOEN BIT(11) /*!< SD I/O specific function enable(SD I/O only) */ + +/* 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_STBITE BIT(9) /*!< start bit error in the bus */ +#define SDIO_STAT_DTBLKEND BIT(10) /*!< data block sent/received (CRC check passed) */ +#define SDIO_STAT_CMDRUN BIT(11) /*!< command transmission in progress */ +#define SDIO_STAT_TXRUN BIT(12) /*!< data transmission in progress */ +#define SDIO_STAT_RXRUN BIT(13) /*!< data reception in progress */ +#define SDIO_STAT_TFH BIT(14) /*!< transmit FIFO is half empty: at least 8 words can be written into the FIFO */ +#define SDIO_STAT_RFH BIT(15) /*!< receive FIFO is half full: at least 8 words can be read in the FIFO */ +#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_TXDTVAL BIT(20) /*!< data is valid in transmit FIFO */ +#define SDIO_STAT_RXDTVAL BIT(21) /*!< data is valid in receive FIFO */ +#define SDIO_STAT_SDIOINT BIT(22) /*!< SD I/O interrupt received */ +#define SDIO_STAT_ATAEND BIT(23) /*!< CE-ATA command completion signal received (only for CMD61) */ + +/* 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_STBITEC BIT(9) /*!< STBITE flag clear bit */ +#define SDIO_INTC_DTBLKENDC BIT(10) /*!< DTBLKEND flag clear bit */ +#define SDIO_INTC_SDIOINTC BIT(22) /*!< SDIOINT flag clear bit */ +#define SDIO_INTC_ATAENDC BIT(23) /*!< ATAEND 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_STBITEIE BIT(9) /*!< start bit error interrupt enable */ +#define SDIO_INTEN_DTBLKENDIE BIT(10) /*!< data block end interrupt enable */ +#define SDIO_INTEN_CMDRUNIE BIT(11) /*!< command transmission interrupt enable */ +#define SDIO_INTEN_TXRUNIE BIT(12) /*!< data transmission interrupt enable */ +#define SDIO_INTEN_RXRUNIE BIT(13) /*!< data reception 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_TFFIE BIT(16) /*!< transmit FIFO 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_RFEIE BIT(19) /*!< receive FIFO empty interrupt enable */ +#define SDIO_INTEN_TXDTVALIE BIT(20) /*!< data valid in transmit FIFO interrupt enable */ +#define SDIO_INTEN_RXDTVALIE BIT(21) /*!< data valid in receive FIFO interrupt enable */ +#define SDIO_INTEN_SDIOINTIE BIT(22) /*!< SD I/O interrupt received interrupt enable */ +#define SDIO_INTEN_ATAENDIE BIT(23) /*!< CE-ATA command completion signal received interrupt enable */ + +/* SDIO_FIFO */ +#define SDIO_FIFO_FIFODT BITS(0,31) /*!< receive FIFO data or transmit FIFO data */ + +/* 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_STBITE BIT(9) /*!< start bit error in the bus flag */ +#define SDIO_FLAG_DTBLKEND BIT(10) /*!< data block sent/received (CRC check passed) flag */ +#define SDIO_FLAG_CMDRUN BIT(11) /*!< command transmission in progress flag */ +#define SDIO_FLAG_TXRUN BIT(12) /*!< data transmission in progress flag */ +#define SDIO_FLAG_RXRUN BIT(13) /*!< data reception in progress 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_TXDTVAL BIT(20) /*!< data is valid in transmit FIFO flag */ +#define SDIO_FLAG_RXDTVAL BIT(21) /*!< data is valid in receive FIFO flag */ +#define SDIO_FLAG_SDIOINT BIT(22) /*!< SD I/O interrupt received flag */ +#define SDIO_FLAG_ATAEND BIT(23) /*!< CE-ATA command completion signal received (only for CMD61) 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_STBITE BIT(9) /*!< SDIO STBITE interrupt */ +#define SDIO_INT_DTBLKEND BIT(10) /*!< SDIO DTBLKEND interrupt */ +#define SDIO_INT_CMDRUN BIT(11) /*!< SDIO CMDRUN interrupt */ +#define SDIO_INT_TXRUN BIT(12) /*!< SDIO TXRUN interrupt */ +#define SDIO_INT_RXRUN BIT(13) /*!< SDIO RXRUN interrupt */ +#define SDIO_INT_TFH BIT(14) /*!< SDIO TFH interrupt */ +#define SDIO_INT_RFH BIT(15) /*!< SDIO RFH interrupt */ +#define SDIO_INT_TFF BIT(16) /*!< SDIO TFF interrupt */ +#define SDIO_INT_RFF BIT(17) /*!< SDIO RFF interrupt */ +#define SDIO_INT_TFE BIT(18) /*!< SDIO TFE interrupt */ +#define SDIO_INT_RFE BIT(19) /*!< SDIO RFE interrupt */ +#define SDIO_INT_TXDTVAL BIT(20) /*!< SDIO TXDTVAL interrupt */ +#define SDIO_INT_RXDTVAL BIT(21) /*!< SDIO RXDTVAL interrupt */ +#define SDIO_INT_SDIOINT BIT(22) /*!< SDIO SDIOINT interrupt */ +#define SDIO_INT_ATAEND BIT(23) /*!< SDIO ATAEND interrupt */ + +/* SDIO interrupt flags */ +#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_STBITE BIT(9) /*!< SDIO STBITE interrupt flag */ +#define SDIO_INT_FLAG_DTBLKEND BIT(10) /*!< SDIO DTBLKEND interrupt flag */ +#define SDIO_INT_FLAG_CMDRUN BIT(11) /*!< SDIO CMDRUN interrupt flag */ +#define SDIO_INT_FLAG_TXRUN BIT(12) /*!< SDIO TXRUN interrupt flag */ +#define SDIO_INT_FLAG_RXRUN BIT(13) /*!< SDIO RXRUN 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_TFF BIT(16) /*!< SDIO TFF 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_RFE BIT(19) /*!< SDIO RFE interrupt flag */ +#define SDIO_INT_FLAG_TXDTVAL BIT(20) /*!< SDIO TXDTVAL interrupt flag */ +#define SDIO_INT_FLAG_RXDTVAL BIT(21) /*!< SDIO RXDTVAL interrupt flag */ +#define SDIO_INT_FLAG_SDIOINT BIT(22) /*!< SDIO SDIOINT interrupt flag */ +#define SDIO_INT_FLAG_ATAEND BIT(23) /*!< SDIO ATAEND interrupt flag */ + +/* 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_ON PWRCTL_PWRCTL(3) /*!< SDIO power on */ + +/* SDIO card bus mode control */ +#define CLKCTL_BUSMODE(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) +#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_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 */ + +/* clock bypass enable or disable */ +#define SDIO_CLOCKBYPASS_DISABLE (uint32_t)0x00000000U /*!< no bypass */ +#define SDIO_CLOCKBYPASS_ENABLE SDIO_CLKCTL_CLKBYP /*!< clock bypass */ + +/* 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 command response type */ +#define CMDCTL_CMDRESP(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) +#define SDIO_RESPONSETYPE_NO CMDCTL_CMDRESP(0) /*!< no response */ +#define SDIO_RESPONSETYPE_SHORT CMDCTL_CMDRESP(1) /*!< short response */ +#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 */ + +#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 SDIO_TRANSMODE_BLOCK (uint32_t)0x00000000U /*!< block transfer */ +#define SDIO_TRANSMODE_STREAM SDIO_DATACTL_TRANSMOD /*!< stream transfer or SDIO multibyte transfer */ + +/* 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 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(void); +/* configure the SDIO clock */ +void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division); +/* enable hardware clock control */ +void sdio_hardware_clock_enable(void); +/* disable hardware clock control */ +void sdio_hardware_clock_disable(void); +/* set different SDIO card bus mode */ +void sdio_bus_mode_set(uint32_t bus_mode); +/* set the SDIO power state */ +void sdio_power_state_set(uint32_t power_state); +/* get the SDIO power state */ +uint32_t sdio_power_state_get(void); +/* enable SDIO_CLK clock output */ +void sdio_clock_enable(void); +/* disable SDIO_CLK clock output */ +void sdio_clock_disable(void); + +/* configure the command index, argument, response type, wait type and CSM to send command functions */ +/* configure the command and response */ +void sdio_command_response_config(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 wait_type); +/* enable the CSM(command state machine) */ +void sdio_csm_enable(void); +/* disable the CSM(command state machine) */ +void sdio_csm_disable(void); +/* get the last response command index */ +uint8_t sdio_command_index_get(void); +/* get the response for the last received command */ +uint32_t sdio_response_get(uint32_t sdio_responsex); + +/* 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 data_timeout, uint32_t data_length, uint32_t data_blocksize); +/* configure the data transfer mode and direction */ +void sdio_data_transfer_config(uint32_t transfer_mode, uint32_t transfer_direction); +/* enable the DSM(data state machine) for data transfer */ +void sdio_dsm_enable(void); +/* disable the DSM(data state machine) */ +void sdio_dsm_disable(void); +/* write data(one word) to the transmit FIFO */ +void sdio_data_write(uint32_t data); +/* read data(one word) from the receive FIFO */ +uint32_t sdio_data_read(void); +/* get the number of remaining data bytes to be transferred to card */ +uint32_t sdio_data_counter_get(void); +/* get the number of words remaining to be written or read from FIFO */ +uint32_t sdio_fifo_counter_get(void); +/* enable the DMA request for SDIO */ +void sdio_dma_enable(void); +/* disable the DMA request for SDIO */ +void sdio_dma_disable(void); + +/* flag and interrupt functions */ +/* get the flags state of SDIO */ +FlagStatus sdio_flag_get(uint32_t flag); +/* clear the pending flags of SDIO */ +void sdio_flag_clear(uint32_t flag); +/* enable the SDIO interrupt */ +void sdio_interrupt_enable(uint32_t int_flag); +/* disable the SDIO interrupt */ +void sdio_interrupt_disable(uint32_t int_flag); +/* get the interrupt flags state of SDIO */ +FlagStatus sdio_interrupt_flag_get(uint32_t int_flag); +/* clear the interrupt pending flags of SDIO */ +void sdio_interrupt_flag_clear(uint32_t int_flag); + +/* SD I/O card functions */ +/* enable the read wait mode(SD I/O only) */ +void sdio_readwait_enable(void); +/* disable the read wait mode(SD I/O only) */ +void sdio_readwait_disable(void); +/* enable the function that stop the read wait process(SD I/O only) */ +void sdio_stop_readwait_enable(void); +/* disable the function that stop the read wait process(SD I/O only) */ +void sdio_stop_readwait_disable(void); +/* set the read wait type(SD I/O only) */ +void sdio_readwait_type_set(uint32_t readwait_type); +/* enable the SD I/O mode specific operation(SD I/O only) */ +void sdio_operation_enable(void); +/* disable the SD I/O mode specific operation(SD I/O only) */ +void sdio_operation_disable(void); +/* enable the SD I/O suspend operation(SD I/O only) */ +void sdio_suspend_enable(void); +/* disable the SD I/O suspend operation(SD I/O only) */ +void sdio_suspend_disable(void); + +/* CE-ATA functions */ +/* enable the CE-ATA command(CE-ATA only) */ +void sdio_ceata_command_enable(void); +/* disable the CE-ATA command(CE-ATA only) */ +void sdio_ceata_command_disable(void); +/* enable the CE-ATA interrupt(CE-ATA only) */ +void sdio_ceata_interrupt_enable(void); +/* disable the CE-ATA interrupt(CE-ATA only) */ +void sdio_ceata_interrupt_disable(void); +/* enable the CE-ATA command completion signal(CE-ATA only) */ +void sdio_ceata_command_completion_enable(void); +/* disable the CE-ATA command completion signal(CE-ATA only) */ +void sdio_ceata_command_completion_disable(void); + +#endif /* GD32F4XX_SDIO_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_spi.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_spi.h new file mode 100644 index 000000000..c48b49a79 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_spi.h @@ -0,0 +1,380 @@ +/*! + \file gd32f4xx_spi.h + \brief definitions for the SPI + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_SPI_H +#define GD32F4XX_SPI_H + +#include "gd32f4xx.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 + 0x00011C00U) + +/* I2Sx_ADD(x=1,2) definitions */ +#define I2S1_ADD I2S_ADD_BASE +#define I2S2_ADD (I2S_ADD_BASE + 0x00000C00U) + +/* SPI registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00000000U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x00000004U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x00000008U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0000000CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x00000010U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x00000014U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x00000018U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x0000001CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x00000020U) /*!< SPI I2S clock prescaler register */ +#define SPI_QCTL(spix) REG32((spix) + 0x00000080U) /*!< SPI quad mode control register */ + +/* I2S_ADD registers definitions */ +#define I2S_ADD_CTL0(i2sx_add) REG32((i2sx_add) + 0x00000000U) /*!< I2S_ADD control register 0 */ +#define I2S_ADD_CTL1(i2sx_add) REG32((i2sx_add) + 0x00000004U) /*!< I2S_ADD control register 1*/ +#define I2S_ADD_STAT(i2sx_add) REG32((i2sx_add) + 0x00000008U) /*!< I2S_ADD status register */ +#define I2S_ADD_DATA(i2sx_add) REG32((i2sx_add) + 0x0000000CU) /*!< I2S_ADD data register */ +#define I2S_ADD_CRCPOLY(i2sx_add) REG32((i2sx_add) + 0x00000010U) /*!< I2S_ADD CRC polynomial register */ +#define I2S_ADD_RCRC(i2sx_add) REG32((i2sx_add) + 0x00000014U) /*!< I2S_ADD receive CRC register */ +#define I2S_ADD_TCRC(i2sx_add) REG32((i2sx_add) + 0x00000018U) /*!< I2S_ADD transmit CRC register */ +#define I2S_ADD_I2SCTL(i2sx_add) REG32((i2sx_add) + 0x0000001CU) /*!< I2S_ADD I2S control register */ +#define I2S_ADD_I2SPSC(i2sx_add) REG32((i2sx_add) + 0x00000020U) /*!< I2S_ADD I2S clock prescaler register */ + +/* bits definitions */ +/* SPI_CTL0 */ +#define SPI_CTL0_CKPH BIT(0) /*!< clock phase selection*/ +#define SPI_CTL0_CKPL BIT(1) /*!< clock polarity selection */ +#define SPI_CTL0_MSTMOD BIT(2) /*!< master mode enable */ +#define SPI_CTL0_PSC BITS(3,5) /*!< master clock prescaler selection */ +#define SPI_CTL0_SPIEN BIT(6) /*!< SPI enable*/ +#define SPI_CTL0_LF BIT(7) /*!< lsb first mode */ +#define SPI_CTL0_SWNSS BIT(8) /*!< nss pin selection in nss software mode */ +#define SPI_CTL0_SWNSSEN BIT(9) /*!< nss software mode selection */ +#define SPI_CTL0_RO BIT(10) /*!< receive only */ +#define SPI_CTL0_FF16 BIT(11) /*!< data frame size */ +#define SPI_CTL0_CRCNT BIT(12) /*!< CRC next transfer */ +#define SPI_CTL0_CRCEN BIT(13) /*!< CRC calculation enable */ +#define SPI_CTL0_BDOEN BIT(14) /*!< bidirectional transmit output enable*/ +#define SPI_CTL0_BDEN BIT(15) /*!< bidirectional enable */ + +/* SPI_CTL1 */ +#define SPI_CTL1_DMAREN BIT(0) /*!< receive buffer dma enable */ +#define SPI_CTL1_DMATEN BIT(1) /*!< transmit buffer dma enable */ +#define SPI_CTL1_NSSDRV BIT(2) /*!< drive nss output */ +#define SPI_CTL1_TMOD BIT(4) /*!< SPI TI mode enable */ +#define SPI_CTL1_ERRIE BIT(5) /*!< errors interrupt enable */ +#define SPI_CTL1_RBNEIE BIT(6) /*!< receive buffer not empty interrupt enable */ +#define SPI_CTL1_TBEIE BIT(7) /*!< transmit buffer empty interrupt enable */ + +/* SPI_STAT */ +#define SPI_STAT_RBNE BIT(0) /*!< receive buffer not empty */ +#define SPI_STAT_TBE BIT(1) /*!< transmit buffer empty */ +#define SPI_STAT_I2SCH BIT(2) /*!< I2S channel side */ +#define SPI_STAT_TXURERR BIT(3) /*!< I2S transmission underrun error bit */ +#define SPI_STAT_CRCERR BIT(4) /*!< SPI CRC error bit */ +#define SPI_STAT_CONFERR BIT(5) /*!< SPI configuration error bit */ +#define SPI_STAT_RXORERR BIT(6) /*!< SPI reception overrun error bit */ +#define SPI_STAT_TRANS BIT(7) /*!< transmitting on-going bit */ +#define SPI_STAT_FERR BIT(8) /*!< format error bit */ + +/* SPI_DATA */ +#define SPI_DATA_DATA BITS(0,15) /*!< data transfer register */ + +/* SPI_CRCPOLY */ +#define SPI_CRCPOLY_CPR BITS(0,15) /*!< CRC polynomial register */ + +/* SPI_RCRC */ +#define SPI_RCRC_RCR BITS(0,15) /*!< RX CRC register */ + +/* SPI_TCRC */ +#define SPI_TCRC_TCR BITS(0,15) /*!< TX CRC register */ + +/* 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 */ + +/* SPI_I2S_PSC */ +#define SPI_I2SPSC_DIV BITS(0,7) /*!< dividing factor for the prescaler */ +#define SPI_I2SPSC_OF BIT(8) /*!< odd factor for the prescaler */ +#define SPI_I2SPSC_MCKOEN BIT(9) /*!< I2S MCK output enable */ + +/* SPI_SPI_QCTL(only SPI5) */ +#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 */ + +/* 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 frame_size; /*!< SPI 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 mode definitions */ +#define SPI_MASTER (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS) /*!< SPI as master */ +#define SPI_SLAVE ((uint32_t)0x00000000U) /*!< SPI as slave */ + +/* SPI bidirectional transfer direction */ +#define SPI_BIDIRECTIONAL_TRANSMIT SPI_CTL0_BDOEN /*!< SPI work in transmit-only mode */ +#define SPI_BIDIRECTIONAL_RECEIVE (~SPI_CTL0_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_CTL0_RO /*!< SPI only receive data */ +#define SPI_TRANSMODE_BDRECEIVE SPI_CTL0_BDEN /*!< bidirectional receive data */ +#define SPI_TRANSMODE_BDTRANSMIT (SPI_CTL0_BDEN | SPI_CTL0_BDOEN) /*!< bidirectional transmit data*/ + +/* SPI frame size */ +#define SPI_FRAMESIZE_16BIT SPI_CTL0_FF16 /*!< SPI frame size is 16 bits */ +#define SPI_FRAMESIZE_8BIT ((uint32_t)0x00000000U) /*!< SPI frame size is 8 bits */ + +/* SPI NSS control mode */ +#define SPI_NSS_SOFT SPI_CTL0_SWNSSEN /*!< SPI nss control by sofrware */ +#define SPI_NSS_HARD ((uint32_t)0x00000000U) /*!< SPI nss control by hardware */ + +/* SPI transmit way */ +#define SPI_ENDIAN_MSB ((uint32_t)0x00000000U) /*!< SPI transmit way is big endian: transmit MSB first */ +#define SPI_ENDIAN_LSB SPI_CTL0_LF /*!< SPI transmit way is little endian: transmit LSB first */ + +/* SPI clock polarity and phase */ +#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_CTL0_CKPL /*!< SPI clock polarity is high level and phase is first edge */ +#define SPI_CK_PL_LOW_PH_2EDGE SPI_CTL0_CKPH /*!< SPI clock polarity is low level and phase is second edge */ +#define SPI_CK_PL_HIGH_PH_2EDGE (SPI_CTL0_CKPL|SPI_CTL0_CKPH) /*!< SPI clock polarity is high level and phase is second edge */ + +/* SPI clock prescale factor */ +#define CTL0_PSC(regval) (BITS(3,5)&((uint32_t)(regval)<<3)) +#define SPI_PSC_2 CTL0_PSC(0) /*!< SPI clock prescale factor is 2 */ +#define SPI_PSC_4 CTL0_PSC(1) /*!< SPI clock prescale factor is 4 */ +#define SPI_PSC_8 CTL0_PSC(2) /*!< SPI clock prescale factor is 8 */ +#define SPI_PSC_16 CTL0_PSC(3) /*!< SPI clock prescale factor is 16 */ +#define SPI_PSC_32 CTL0_PSC(4) /*!< SPI clock prescale factor is 32 */ +#define SPI_PSC_64 CTL0_PSC(5) /*!< SPI clock prescale factor is 64 */ +#define SPI_PSC_128 CTL0_PSC(6) /*!< SPI clock prescale factor is 128 */ +#define SPI_PSC_256 CTL0_PSC(7) /*!< SPI clock prescale factor is 256 */ + +/* 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_I2SPSC_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_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_ERR ((uint8_t)0x02U) /*!< error interrupt */ + +/* SPI/I2S interrupt flag constants definitions */ +#define SPI_I2S_INT_FLAG_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt flag */ +#define SPI_INT_FLAG_CONFERR ((uint8_t)0x03U) /*!< config error interrupt flag */ +#define SPI_INT_FLAG_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt flag */ +#define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */ +#define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x06U) /*!< format error interrupt flag */ + +/* SPI/I2S flag definitions */ +#define SPI_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define SPI_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define SPI_FLAG_CRCERR SPI_STAT_CRCERR /*!< CRC error flag */ +#define SPI_FLAG_CONFERR SPI_STAT_CONFERR /*!< mode config error flag */ +#define SPI_FLAG_RXORERR SPI_STAT_RXORERR /*!< receive overrun error flag */ +#define SPI_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define SPI_FLAG_FERR SPI_STAT_FERR /*!< format error flag */ +#define I2S_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define I2S_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define I2S_FLAG_CH SPI_STAT_I2SCH /*!< channel side flag */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error flag */ +#define I2S_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define I2S_FLAG_FERR SPI_STAT_FERR /*!< format error flag */ + +/* function declarations */ +/* initialization functions */ +/* deinitialize SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize the parameters of SPI struct with 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 prescale */ +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); + +/* NSS functions */ +/* 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 send or receive */ +void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma); +/* diable SPI DMA send or receive */ +void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma); + +/* SPI/I2S transfer configure functions */ +/* configure SPI/I2S data frame format */ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format); +/* SPI transmit data */ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data); +/* SPI receive data */ +uint16_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); +/* configure i2s full duplex mode */ +void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl, uint32_t i2s_frameformat); +/* clear TI Mode Format Error flag status */ +void spi_i2s_format_error_clear(uint32_t spi_periph, uint32_t flag); + +/* SPI CRC functions */ +/* set SPI CRC polynomial */ +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly); +/* get SPI CRC polynomial */ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph); +/* 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); +/* SPI next data is CRC value */ +void spi_crc_next(uint32_t spi_periph); +/* get SPI CRC send value or receive value */ +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t spi_crc); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +/* 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 SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_enable(uint32_t spi_periph); +/* disable SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_disable(uint32_t spi_periph); + +/* flag and interrupt functions */ +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag); +/* 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 status*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt); + +#endif /* GD32F4XX_SPI_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_syscfg.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_syscfg.h new file mode 100644 index 000000000..b3c598ede --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_syscfg.h @@ -0,0 +1,182 @@ +/*! + \file gd32f4xx_syscfg.h + \brief definitions for the SYSCFG + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_SYSCFG_H +#define GD32F4XX_SYSCFG_H + +#include "gd32f4xx.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00U) /*!< system configuration register 0 */ +#define SYSCFG_CFG1 REG32(SYSCFG + 0x04U) /*!< system configuration register 1 */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x08U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x10U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x14U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_CPSCTL REG32(SYSCFG + 0x20U) /*!< system I/O compensation control register */ + +/* SYSCFG_CFG0 bits definitions */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,2) /*!< SYSCFG memory remap config */ +#define SYSCFG_CFG0_FMC_SWP BIT(8) /*!< FMC memory swap config */ +#define SYSCFG_CFG0_EXMC_SWP BITS(10,11) /*!< EXMC memory swap config */ + +/* SYSCFG_CFG1 bits definitions */ +#define SYSCFG_CFG1_ENET_PHY_SEL BIT(23) /*!< Ethernet PHY selection config */ + +/* 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_CPSCTL bits definitions */ +#define SYSCFG_CPSCTL_CPS_EN BIT(0) /*!< I/O compensation cell enable */ +#define SYSCFG_CPSCTL_CPS_RDY BIT(8) /*!< I/O compensation cell is ready or not */ + +/* constants definitions */ +/* boot mode definitions */ +#define SYSCFG_BOOTMODE_FLASH ((uint8_t)0x00U) /*!< main flash memory remap */ +#define SYSCFG_BOOTMODE_BOOTLOADER ((uint8_t)0x01U) /*!< boot loader remap */ +#define SYSCFG_BOOTMODE_EXMC_SRAM ((uint8_t)0x02U) /*!< SRAM/NOR 0 and 1 of EXMC remap */ +#define SYSCFG_BOOTMODE_SRAM ((uint8_t)0x03U) /*!< SRAM0 of on-chip SRAM remap */ +#define SYSCFG_BOOTMODE_EXMC_SDRAM ((uint8_t)0x04U) /*!< SDRAM bank0 of EXMC remap */ + +/* FMC swap definitions */ +#define SYSCFG_FMC_SWP_BANK0 ((uint32_t)0x00000000U) /*!< main flash Bank 0 is mapped at address 0x08000000 */ +#define SYSCFG_FMC_SWP_BANK1 ((uint32_t)0x00000100U) /*!< main flash Bank 1 is mapped at address 0x08000000 */ + +/* EXMC swap enable/disable */ +#define SYSCFG_EXMC_SWP_ENABLE ((uint32_t)0x00000400U) /*!< SDRAM bank 0 and bank 1 are swapped with NAND bank 1 and PC card */ +#define SYSCFG_EXMC_SWP_DISABLE ((uint32_t)0x00000000U) /*!< no memory mapping swap */ + +/* EXTI source select definition */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select GPIOx pin 0~3 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select GPIOx pin 4~7 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select GPIOx pin 8~11 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select GPIOx pin 12~15 */ + +/* 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_GPIOI ((uint8_t)0x08U) /*!< EXTI GPIOI 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 */ + +/* ethernet PHY selection */ +#define SYSCFG_ENET_PHY_MII ((uint32_t)0x00000000U) /*!< MII is selected for the Ethernet MAC */ +#define SYSCFG_ENET_PHY_RMII ((uint32_t)0x00800000U) /*!< RMII is selected for the Ethernet MAC */ + +/* I/O compensation cell enable/disable */ +#define SYSCFG_COMPENSATION_ENABLE ((uint32_t)0x00000001U) /*!< I/O compensation cell enable */ +#define SYSCFG_COMPENSATION_DISABLE ((uint32_t)0x00000000U) /*!< I/O compensation cell disable */ + +/* function declarations */ +/* initialization functions */ +/* deinit syscfg module */ +void syscfg_deinit(void); + +/* function configuration */ +/* configure the boot mode */ +void syscfg_bootmode_config(uint8_t syscfg_bootmode); +/* configure FMC memory mapping swap */ +void syscfg_fmc_swap_config(uint32_t syscfg_fmc_swap); +/* configure the EXMC swap */ +void syscfg_exmc_swap_config(uint32_t syscfg_exmc_swap); +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); +/* configure the PHY interface for the ethernet MAC */ +void syscfg_enet_phy_interface_config(uint32_t syscfg_enet_phy_interface); +/* configure the I/O compensation cell */ +void syscfg_compensation_config(uint32_t syscfg_compensation); + +/* interrupt & flag functions */ +/* check the I/O compensation cell is ready or not */ +FlagStatus syscfg_flag_get(void); + +#endif /* GD32F4XX_SYSCFG_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_timer.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_timer.h new file mode 100644 index 000000000..593ecb837 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_timer.h @@ -0,0 +1,779 @@ +/*! + \file gd32f4xx_timer.h + \brief definitions for the TIMER + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_TIMER_H +#define GD32F4XX_TIMER_H + +#include "gd32f4xx.h" + +/* TIMERx(x=0..13) definitions */ +#define TIMER0 (TIMER_BASE + 0x00010000U) +#define TIMER1 (TIMER_BASE + 0x00000000U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER3 (TIMER_BASE + 0x00000800U) +#define TIMER4 (TIMER_BASE + 0x00000C00U) +#define TIMER5 (TIMER_BASE + 0x00001000U) +#define TIMER6 (TIMER_BASE + 0x00001400U) +#define TIMER7 (TIMER_BASE + 0x00010400U) +#define TIMER8 (TIMER_BASE + 0x00014000U) +#define TIMER9 (TIMER_BASE + 0x00014400U) +#define TIMER10 (TIMER_BASE + 0x00014800U) +#define TIMER11 (TIMER_BASE + 0x00001800U) +#define TIMER12 (TIMER_BASE + 0x00001C00U) +#define TIMER13 (TIMER_BASE + 0x00002000U) + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x04U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x08U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x10U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x14U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x18U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x1CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x20U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x24U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x28U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x2CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x30U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x34U) /*!< TIMER channel 0 capture/compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x38U) /*!< TIMER channel 1 capture/compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x3CU) /*!< TIMER channel 2 capture/compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x40U) /*!< TIMER channel 3 capture/compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x44U) /*!< TIMER complementary channel protection register */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x48U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x4CU) /*!< TIMER DMA transfer buffer register */ +#define TIMER_IRMP(timerx) REG32((timerx) + 0x50U) /*!< TIMER channel input remap register */ +#define TIMER_CFG(timerx) REG32((timerx) + 0xFCU) /*!< 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) /*!< center-aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ + +/* TIMER_CTL1 */ +#define TIMER_CTL1_CCSE BIT(0) /*!< commutation control shadow enable */ +#define TIMER_CTL1_CCUC BIT(2) /*!< commutation control shadow register update control */ +#define TIMER_CTL1_DMAS BIT(3) /*!< DMA request source selection */ +#define TIMER_CTL1_MMC BITS(4,6) /*!< master mode control */ +#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 */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_SMC BITS(0,2) /*!< slave mode control */ +#define TIMER_SMCFG_TRGS BITS(4,6) /*!< trigger selection */ +#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/compare interrupt enable */ +#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 capture/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 DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 DMA request enable */ +#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< commutation DMA request enable */ +#define TIMER_DMAINTEN_TRGDEN BIT(14) /*!< trigger DMA request enable */ + +/* TIMER_INTF */ +#define TIMER_INTF_UPIF BIT(0) /*!< update interrupt flag */ +#define TIMER_INTF_CH0IF BIT(1) /*!< channel 0 capture/compare interrupt flag */ +#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 capture/compare interrupt flag */ +#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 capture/compare interrupt flag */ +#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 capture/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_BRKIF BIT(7) /*!< break interrupt flag */ +#define TIMER_INTF_CH0OF BIT(9) /*!< channel 0 overcapture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 overcapture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 overcapture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 overcapture 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_BRKG BIT(7) /*!< break event generation */ + +/* TIMER_CHCTL0 */ +/* output compare mode */ +#define TIMER_CHCTL0_CH0MS BITS(0,1) /*!< channel 0 mode selection */ +#define TIMER_CHCTL0_CH0COMFEN BIT(2) /*!< channel 0 output compare fast enable */ +#define TIMER_CHCTL0_CH0COMSEN BIT(3) /*!< channel 0 output compare shadow enable */ +#define TIMER_CHCTL0_CH0COMCTL BITS(4,6) /*!< channel 0 output compare mode */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS BITS(8,9) /*!< channel 1 mode selection */ +#define TIMER_CHCTL0_CH1COMFEN BIT(10) /*!< channel 1 output compare fast enable */ +#define TIMER_CHCTL0_CH1COMSEN BIT(11) /*!< channel 1 output compare shadow enable */ +#define TIMER_CHCTL0_CH1COMCTL BITS(12,14) /*!< channel 1 output compare mode */ +#define TIMER_CHCTL0_CH1COMCEN BIT(15) /*!< channel 1 output compare clear 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) /*!< channel 2 mode selection */ +#define TIMER_CHCTL1_CH2COMFEN BIT(2) /*!< channel 2 output compare fast enable */ +#define TIMER_CHCTL1_CH2COMSEN BIT(3) /*!< channel 2 output compare shadow enable */ +#define TIMER_CHCTL1_CH2COMCTL BITS(4,6) /*!< channel 2 output compare mode */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS BITS(8,9) /*!< channel 3 mode selection */ +#define TIMER_CHCTL1_CH3COMFEN BIT(10) /*!< channel 3 output compare fast enable */ +#define TIMER_CHCTL1_CH3COMSEN BIT(11) /*!< channel 3 output compare shadow enable */ +#define TIMER_CHCTL1_CH3COMCTL BITS(12,14) /*!< channel 3 output compare mode */ +#define TIMER_CHCTL1_CH3COMCEN BIT(15) /*!< channel 3 output compare clear 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/compare function enable */ +#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 capture/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/compare function enable */ +#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 capture/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/compare function enable */ +#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 capture/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/compare function enable */ +#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 capture/compare function polarity */ + +/* TIMER_CNT */ +#define TIMER_CNT_CNT16 BITS(0,15) /*!< 16 bit timer counter */ +#define TIMER_CNT_CNT32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL16 BITS(0,15) /*!< 16 bit counter auto reload value */ +#define TIMER_CAR_CARL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) counter auto reload value */ + +/* TIMER_CREP */ +#define TIMER_CREP_CREP BITS(0,7) /*!< counter repetition value */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 0 */ +#define TIMER_CH0CV_CH0VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 1 */ +#define TIMER_CH1CV_CH1VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 2 */ +#define TIMER_CH2CV_CH2VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 3 */ +#define TIMER_CH3CV_CH3VAL32 BITS(0,31) /*!< 32 bit(TIMER1,TIMER4) capture/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_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,4) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,12) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,15) /*!< DMA transfer buffer address */ + +/* TIMER_IRMP */ +#define TIMER1_IRMP_ITI1_RMP BITS(10,11) /*!< TIMER1 internal trigger input 1 remap */ +#define TIMER4_IRMP_CI3_RMP BITS(6,7) /*!< TIMER4 channel 3 input remap */ +#define TIMER10_IRMP_ITI1_RMP BITS(0,1) /*!< TIMER10 internal trigger input 1 remap */ + +/* TIMER_CFG */ +#define TIMER_CFG_OUTSEL BIT(0) /*!< the output value selection */ +#define TIMER_CFG_CHVSEL BIT(1) /*!< write CHxVAL register selection */ + +/* constants definitions */ +/* TIMER init parameter struct definitions*/ +typedef struct +{ + uint16_t prescaler; /*!< prescaler value */ + uint16_t alignedmode; /*!< aligned mode */ + uint16_t counterdirection; /*!< counter direction */ + uint16_t clockdivision; /*!< clock division value */ + uint32_t period; /*!< period value */ + uint8_t repetitioncounter; /*!< the counter repetition value */ +}timer_parameter_struct; + +/* break parameter struct definitions*/ +typedef struct +{ + uint16_t runoffstate; /*!< run mode off-state */ + uint16_t ideloffstate; /*!< idle mode off-state */ + uint16_t deadtime; /*!< dead time */ + uint16_t breakpolarity; /*!< break polarity */ + uint16_t outputautostate; /*!< output automatic enable */ + uint16_t protectmode; /*!< complementary register protect control */ + uint16_t breakstate; /*!< break enable */ +}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; + +/* 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; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 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 */ + +/* TIMER flag */ +#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */ +#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 flag */ +#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 flag */ +#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 flag */ +#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 flag */ +#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation flag */ +#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */ +#define TIMER_FLAG_BRK TIMER_INTF_BRKIF /*!< break 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 */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INTF_UPIF /*!< update interrupt flag */ +#define TIMER_INT_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 interrupt flag */ +#define TIMER_INT_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 interrupt flag */ +#define TIMER_INT_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 interrupt flag */ +#define TIMER_INT_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 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_BRK TIMER_INTF_BRKIF + +/* TIMER DMA source enable */ +#define TIMER_DMA_UPD ((uint16_t)TIMER_DMAINTEN_UPDEN) /*!< update DMA enable */ +#define TIMER_DMA_CH0D ((uint16_t)TIMER_DMAINTEN_CH0DEN) /*!< channel 0 DMA enable */ +#define TIMER_DMA_CH1D ((uint16_t)TIMER_DMAINTEN_CH1DEN) /*!< channel 1 DMA enable */ +#define TIMER_DMA_CH2D ((uint16_t)TIMER_DMAINTEN_CH2DEN) /*!< channel 2 DMA enable */ +#define TIMER_DMA_CH3D ((uint16_t)TIMER_DMAINTEN_CH3DEN) /*!< channel 3 DMA enable */ +#define TIMER_DMA_CMTD ((uint16_t)TIMER_DMAINTEN_CMTDEN) /*!< commutation DMA request enable */ +#define TIMER_DMA_TRGD ((uint16_t)TIMER_DMAINTEN_TRGDEN) /*!< trigger DMA enable */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT ((uint8_t)0x00U) /*!< DMA request of channel y is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint8_t)0x01U) /*!< DMA request of channel y is sent when channel y event occurs */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0, 4) & ((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_CREP DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP */ +#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_DMACFG DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA_DMATB DMACFG_DMATA(19) /*!< DMA transfer address is TIMER_DMATB */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8, 12) & ((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 */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG ((uint16_t)0x0001U) /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G ((uint16_t)0x0002U) /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G ((uint16_t)0x0004U) /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G ((uint16_t)0x0008U) /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G ((uint16_t)0x0010U) /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG ((uint16_t)0x0020U) /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG ((uint16_t)0x0040U) /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG ((uint16_t)0x0080U) /*!< break 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 ((uint32_t)0x00000000U) /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000001U) /*!< 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 ((uint32_t)0x00000000U) /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000001U) /*!< repetitive pulse mode */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR ((uint32_t)0x00000000U) /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000001U) /*!< 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 ((uint16_t)TIMER_CCHP_ROS) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_ROS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint16_t)TIMER_CCHP_IOS) /*!< when POEN bit is reset, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_IOS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is reset, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint16_t)0x0000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint16_t)TIMER_CCHP_BRKP) /*!< break input polarity is high */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint16_t)TIMER_CCHP_OAEN) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint16_t)0x0000U) /*!< 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 */ + +/* break input enable */ +#define TIMER_BREAK_ENABLE ((uint16_t)TIMER_CCHP_BRKEN) /*!< break input enable */ +#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */ + +/* TIMER channel n(n=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel 0(TIMERx(x=0..4,7..13)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1(TIMERx(x=0..4,7,8,11)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2(TIMERx(x=0..4,7)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3(TIMERx(x=0..4,7)) */ + +/* channel enable state*/ +#define TIMER_CCX_ENABLE ((uint32_t)0x00000001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint32_t)0x00000000U) /*!< 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 */ + +/* 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 */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)0x0100) /*!< idle state of channel output is high */ +#define TIMER_OC_IDLE_STATE_LOW ((uint16_t)0x0000) /*!< 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 */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM1 mode*/ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output shadow state enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output shadow state disable */ + +/* channel output compare fast enable */ +#define TIMER_OC_FAST_ENABLE ((uint16_t)0x0004) /*!< channel output fast function enable */ +#define TIMER_OC_FAST_DISABLE ((uint16_t)0x0000) /*!< channel output fast function 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 TIMER_UPDATECTL_CCU ((uint32_t)0x00000000U) /*!< the shadow registers are updated when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI ((uint32_t)0x00000001U) /*!< the shadow registers update by when CMTG bit is set or an rising edge of TRGI 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 y is configured as input and icy is mapped on CIy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel y is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel y is configured as input and icy is mapped on ITS */ + +/* 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 */ + +/* trigger selection */ +#define SMCFG_TRGSEL(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_SMCFG_TRGSEL_ITI0 SMCFG_TRGSEL(0) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI1 SMCFG_TRGSEL(1) /*!< internal trigger 1 */ +#define TIMER_SMCFG_TRGSEL_ITI2 SMCFG_TRGSEL(2) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 SMCFG_TRGSEL(3) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED SMCFG_TRGSEL(4) /*!< TI0 Edge Detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 SMCFG_TRGSEL(5) /*!< filtered TIMER input 0 */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 SMCFG_TRGSEL(6) /*!< filtered TIMER input 1 */ +#define TIMER_SMCFG_TRGSEL_ETIFP SMCFG_TRGSEL(7) /*!< external trigger */ + +/* master mode control */ +#define CTL1_MMC(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_TRI_OUT_SRC_RESET CTL1_MMC(0) /*!< the UPG bit as trigger output */ +#define TIMER_TRI_OUT_SRC_ENABLE CTL1_MMC(1) /*!< the counter enable signal TIMER_CTL0_CEN as trigger output */ +#define TIMER_TRI_OUT_SRC_UPDATE CTL1_MMC(2) /*!< update event as trigger output */ +#define TIMER_TRI_OUT_SRC_CH0 CTL1_MMC(3) /*!< a capture or a compare match occurred in channal0 as trigger output TRGO */ +#define TIMER_TRI_OUT_SRC_O0CPRE CTL1_MMC(4) /*!< O0CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O1CPRE CTL1_MMC(5) /*!< O1CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O2CPRE CTL1_MMC(6) /*!< O2CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O3CPRE CTL1_MMC(7) /*!< O3CPRE as trigger output */ + +/* slave mode control */ +#define SMCFG_SMC(regval) (BITS(0, 2) & ((uint32_t)(regval) << 0U)) +#define TIMER_SLAVE_MODE_DISABLE SMCFG_SMC(0) /*!< slave mode disable */ +#define TIMER_QUAD_DECODER_MODE0 SMCFG_SMC(1) /*!< quadrature decoder mode 0 */ +#define TIMER_QUAD_DECODER_MODE1 SMCFG_SMC(2) /*!< quadrature decoder mode 1 */ +#define TIMER_QUAD_DECODER_MODE2 SMCFG_SMC(3) /*!< quadrature decoder mode 2 */ +#define TIMER_SLAVE_MODE_RESTART SMCFG_SMC(4) /*!< restart mode */ +#define TIMER_SLAVE_MODE_PAUSE SMCFG_SMC(5) /*!< pause mode */ +#define TIMER_SLAVE_MODE_EVENT SMCFG_SMC(6) /*!< event mode */ +#define TIMER_SLAVE_MODE_EXTERNAL0 SMCFG_SMC(7) /*!< external clock mode 0 */ + +/* master slave mode selection */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE ((uint32_t)0x00000000U) /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000001U) /*!< 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 ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000001U) /*!< TIMER hall sensor mode disable */ + +/* timer1 internal trigger input1 remap */ +#define TIMER1_IRMP(regval) (BITS(10, 11) & ((uint32_t)(regval) << 10U)) +#define TIMER1_ITI1_RMP_TIMER7_TRGO TIMER1_IRMP(0) /*!< timer1 internal trigger input 1 remap to TIMER7_TRGO */ +#define TIMER1_ITI1_RMP_ETHERNET_PTP TIMER1_IRMP(1) /*!< timer1 internal trigger input 1 remap to ethernet PTP */ +#define TIMER1_ITI1_RMP_USB_FS_SOF TIMER1_IRMP(2) /*!< timer1 internal trigger input 1 remap to USB FS SOF */ +#define TIMER1_ITI1_RMP_USB_HS_SOF TIMER1_IRMP(3) /*!< timer1 internal trigger input 1 remap to USB HS SOF */ + +/* timer4 channel 3 input remap */ +#define TIMER4_IRMP(regval) (BITS(6, 7) & ((uint32_t)(regval) << 6U)) +#define TIMER4_CI3_RMP_GPIO TIMER4_IRMP(0) /*!< timer4 channel 3 input remap to GPIO pin */ +#define TIMER4_CI3_RMP_IRC32K TIMER4_IRMP(1) /*!< timer4 channel 3 input remap to IRC32K */ +#define TIMER4_CI3_RMP_LXTAL TIMER4_IRMP(2) /*!< timer4 channel 3 input remap to LXTAL */ +#define TIMER4_CI3_RMP_RTC_WAKEUP_INT TIMER4_IRMP(3) /*!< timer4 channel 3 input remap to RTC wakeup interrupt */ + +/* timer10 internal trigger input1 remap */ +#define TIMER10_IRMP(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0U)) +#define TIMER10_ITI1_RMP_GPIO TIMER10_IRMP(0) /*!< timer10 internal trigger input1 remap based on GPIO setting */ +#define TIMER10_ITI1_RMP_RTC_HXTAL_DIV TIMER10_IRMP(2) /*!< timer10 internal trigger input1 remap HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register) */ + +/* timerx(x=0,1,2,13,14,15,16) write cc register selection */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)0x0002U) /*!< write CHxVAL register selection enable */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ + +/* the output value selection */ +#define TIMER_OUTSEL_ENABLE ((uint16_t)0x0001U) /*!< output value selection enable */ +#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection disable */ + +/* 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, uint8_t pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition); +/* configure TIMER autoreload register value */ +void timer_autoreload_value_config(uint32_t timer_periph,uint32_t autoreload); +/* configure TIMER counter register value */ +void timer_counter_value_config(uint32_t timer_periph , uint32_t counter); +/* read TIMER counter value */ +uint32_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 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, uint16_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_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, uint16_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); +/* disable TIMER break function */ +void timer_break_disable(uint32_t timer_periph); +/* 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); +/* enable or disable TIMER primary output function */ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue); +/* enable or disable channel capture/compare 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, uint8_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,uint16_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 fast function */ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast); +/* 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 master and slave */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_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 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); +/* configure TIMER channel remap function */ +void timer_channel_remap_config(uint32_t timer_periph,uint32_t remap); + +/* 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); + +/* 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 flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt); + +#endif /* GD32F4XX_TIMER_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_tli.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_tli.h new file mode 100644 index 000000000..e261acc1a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_tli.h @@ -0,0 +1,373 @@ +/*! + \file gd32f4xx_tli.h + \brief definitions for the TLI + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_TLI_H +#define GD32F4XX_TLI_H + +#include "gd32f4xx.h" + +/* TLI definitions */ +#define TLI TLI_BASE /*!< TLI base address */ +/* TLI layer definitions */ +#define LAYER0 TLI_BASE /*!< TLI layer0 base address */ +#define LAYER1 (TLI_BASE + 0x00000080U) /*!< 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) + 0x00000084U) /*!< TLI layer x control register */ +#define TLI_LxHPOS(layerx) REG32((layerx) + 0x00000088U) /*!< TLI layer x horizontal position parameters register */ +#define TLI_LxVPOS(layerx) REG32((layerx) + 0x0000008CU) /*!< TLI layer x vertical position parameters register */ +#define TLI_LxCKEY(layerx) REG32((layerx) + 0x00000090U) /*!< TLI layer x color key register */ +#define TLI_LxPPF(layerx) REG32((layerx) + 0x00000094U) /*!< TLI layer x packeted pixel format register */ +#define TLI_LxSA(layerx) REG32((layerx) + 0x00000098U) /*!< TLI layer x specified alpha register */ +#define TLI_LxDC(layerx) REG32((layerx) + 0x0000009CU) /*!< TLI layer x default color register */ +#define TLI_LxBLEND(layerx) REG32((layerx) + 0x000000A0U) /*!< TLI layer x blending register */ +#define TLI_LxFBADDR(layerx) REG32((layerx) + 0x000000ACU) /*!< TLI layer x frame base address register */ +#define TLI_LxFLLEN(layerx) REG32((layerx) + 0x000000B0U) /*!< TLI layer x frame line length register */ +#define TLI_LxFTLN(layerx) REG32((layerx) + 0x000000B4U) /*!< TLI layer x frame total line number register */ +#define TLI_LxLUT(layerx) REG32((layerx) + 0x000000C4U) /*!< 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_HIGHT 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_HIGHT 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)<<8)) +#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); +/* configurate 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 /* GD32F4XX_TLI_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_trng.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_trng.h new file mode 100644 index 000000000..5c1ce6e6a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_trng.h @@ -0,0 +1,103 @@ +/*! + \file gd32f4xx_trng.h + \brief definitions for the TRNG + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_TRNG_H +#define GD32F4XX_TRNG_H + +#include "gd32f4xx.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 */ + +/* bits definitions */ +/* TRNG_CTL */ +#define TRNG_CTL_TRNGEN BIT(2) /*!< TRNG enable bit */ +#define TRNG_CTL_TRNGIE BIT(3) /*!< interrupt enable 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_CEIF BIT(5) /*!< clock error interrupt flag */ +#define TRNG_STAT_SEIF BIT(6) /*!< seed error interrupt flag */ + +/* TRNG_DATA */ +#define TRNG_DATA_TRNGDATA BITS(0,31) /*!< 32-Bit Random data */ + +/* constants definitions */ +/* 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 inerrupt 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 */ +/* reset TRNG */ +void trng_deinit(void); +/* enable TRNG */ +void trng_enable(void); +/* disable TRNG */ +void trng_disable(void); +/* get the true random data */ +uint32_t trng_get_true_random_data(void); + +/* interrupt & flag functions */ +/* enable TRNG interrupt */ +void trng_interrupt_enable(void); +/* disable TRNG interrupt */ +void trng_interrupt_disable(void); +/* get TRNG flag status */ +FlagStatus trng_flag_get(trng_flag_enum flag); +/* get TRNG interrupt flag status */ +FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag); +/* clear TRNG interrupt flag status */ +void trng_interrupt_flag_clear(trng_int_flag_enum int_flag); + +#endif /* GD32F4XX_TRNG_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_usart.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_usart.h new file mode 100644 index 000000000..5246ab12f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_usart.h @@ -0,0 +1,492 @@ +/*! + \file gd32f4xx_usart.h + \brief definitions for the USART + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_USART_H +#define GD32F4XX_USART_H + +#include "gd32f4xx.h" + +/* USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) definitions */ +#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 UART6 (USART_BASE+0x00003400U) /*!< UART6 base address */ +#define UART7 (USART_BASE+0x00003800U) /*!< UART7 base address */ +#define USART0 (USART_BASE+0x0000CC00U) /*!< USART0 base address */ +#define USART5 (USART_BASE+0x0000D000U) /*!< USART5 base address */ + +/* registers definitions */ +#define USART_STAT0(usartx) REG32((usartx) + 0x00U) /*!< USART status register 0 */ +#define USART_DATA(usartx) REG32((usartx) + 0x04U) /*!< USART data register */ +#define USART_BAUD(usartx) REG32((usartx) + 0x08U) /*!< USART baud rate register */ +#define USART_CTL0(usartx) REG32((usartx) + 0x0CU) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x10U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x14U) /*!< USART control register 2 */ +#define USART_GP(usartx) REG32((usartx) + 0x18U) /*!< USART guard time and prescaler register */ +#define USART_CTL3(usartx) REG32((usartx) + 0x80U) /*!< USART control register 3 */ +#define USART_RT(usartx) REG32((usartx) + 0x84U) /*!< USART receiver timeout register */ +#define USART_STAT1(usartx) REG32((usartx) + 0x88U) /*!< USART status register 1 */ +#define USART_CHC(usartx) REG32((usartx) + 0xC0U) /*!< USART coherence control register */ + +/* bits definitions */ +/* USARTx_STAT0 */ +#define USART_STAT0_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT0_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT0_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT0_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT0_IDLEF BIT(4) /*!< IDLE frame detected flag */ +#define USART_STAT0_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT0_TC BIT(6) /*!< transmission complete */ +#define USART_STAT0_TBE BIT(7) /*!< transmit data buffer empty */ +#define USART_STAT0_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT0_CTSF BIT(9) /*!< CTS change flag */ + +/* USARTx_DATA */ +#define USART_DATA_DATA BITS(0,8) /*!< transmit or read data value */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction part of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer part of baud-rate divider */ + +/* USARTx_CTL0 */ +#define USART_CTL0_SBKCMD BIT(0) /*!< send break command */ +#define USART_CTL0_RWU BIT(1) /*!< receiver wakeup from mute 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 */ +#define USART_CTL0_TCIE BIT(6) /*!< enable transmission complete interrupt */ +#define USART_CTL0_TBEIE BIT(7) /*!< enable transmitter buffer empty interrupt */ +#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 check function */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_UEN BIT(13) /*!< enable USART */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDR BITS(0,3) /*!< address of USART */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< enable LIN break detected interrupt */ +#define USART_CTL1_CLEN BIT(8) /*!< CK length */ +#define USART_CTL1_CPH BIT(9) /*!< CK phase */ +#define USART_CTL1_CPL BIT(10) /*!< CK 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 */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< enable error interrupt */ +#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) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< enable smartcard mode */ +#define USART_CTL2_DENR BIT(6) /*!< enable DMA request for reception */ +#define USART_CTL2_DENT BIT(7) /*!< enable DMA request 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 method */ + +/* 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_CTL3 */ +#define USART_CTL3_RTEN BIT(0) /*!< enable receiver timeout */ +#define USART_CTL3_SCRTNUM BITS(1,3) /*!< smartcard auto-retry number */ +#define USART_CTL3_RTIE BIT(4) /*!< interrupt enable bit of receive timeout event */ +#define USART_CTL3_EBIE BIT(5) /*!< interrupt enable bit of end of block event */ +#define USART_CTL3_RINV BIT(8) /*!< RX pin level inversion */ +#define USART_CTL3_TINV BIT(9) /*!< TX pin level inversion */ +#define USART_CTL3_DINV BIT(10) /*!< data bit level inversion */ +#define USART_CTL3_MSBF BIT(11) /*!< most significant bit first */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_STAT1 */ +#define USART_STAT1_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT1_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT1_BSY BIT(16) /*!< busy flag */ + +/* USARTx_CHC */ +#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ +#define USART_CHC_PCM BIT(1) /*!< parity check coherence mode */ +#define USART_CHC_BCM BIT(2) /*!< break frame coherence mode */ +#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ + +/* 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) & 0xFFFFU) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#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) & 0x1F0000U) >> 16) + +/* register offset */ +#define USART_STAT0_REG_OFFSET 0x00U /*!< STAT0 register offset */ +#define USART_STAT1_REG_OFFSET 0x88U /*!< STAT1 register offset */ +#define USART_CTL0_REG_OFFSET 0x0CU /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET 0x10U /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET 0x14U /*!< CTL2 register offset */ +#define USART_CTL3_REG_OFFSET 0x80U /*!< CTL3 register offset */ +#define USART_CHC_REG_OFFSET 0xC0U /*!< CHC register offset */ + +/* USART flags */ +typedef enum { + /* flags in STAT0 register */ + USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 7U), /*!< transmit data buffer empty */ + USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 5U), /*!< read data buffer not empty */ + USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 4U), /*!< IDLE frame detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT0_REG_OFFSET, 0U), /*!< parity error flag */ + /* flags in STAT1 register */ + USART_FLAG_BSY = USART_REGIDX_BIT(USART_STAT1_REG_OFFSET, 16U), /*!< busy flag */ + USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT1_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT1_REG_OFFSET, 11U), /*!< receiver timeout flag */ + /* flags in CHC register */ + USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U), /*!< early parity error flag */ +} usart_flag_enum; + +/* USART interrupt flags */ +typedef enum { + /* interrupt flags in CTL0 register */ + USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT0_REG_OFFSET, 0U), /*!< parity error interrupt and flag */ + USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag */ + USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT0_REG_OFFSET, 6U), /*!< transmission complete interrupt and flag */ + USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and flag */ + USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT0_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag */ + USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT0_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_STAT0_REG_OFFSET, 8U), /*!< LIN break detected interrupt and flag */ + /* interrupt flags in CTL2 register */ + USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT0_REG_OFFSET, 9U), /*!< CTS interrupt and flag */ + USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT0_REG_OFFSET, 3U), /*!< error interrupt and overrun error */ + USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT0_REG_OFFSET, 2U), /*!< error interrupt and noise error flag */ + USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT0_REG_OFFSET, 1U), /*!< error interrupt and frame error flag */ + /* interrupt flags in CTL3 register */ + USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL3_REG_OFFSET, 5U, USART_STAT1_REG_OFFSET, 12U), /*!< interrupt enable bit of end of block event and flag */ + USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL3_REG_OFFSET, 4U, USART_STAT1_REG_OFFSET, 11U), /*!< interrupt enable bit of receive timeout event and flag */ +} usart_interrupt_flag_enum; + +/* USART interrupt flags */ +typedef enum { + /* interrupt in CTL0 register */ + 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 */ + 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 */ + 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_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 CTL3 register */ + USART_INT_EB = USART_REGIDX_BIT(USART_CTL3_REG_OFFSET, 5U), /*!< interrupt enable bit of end of block event */ + USART_INT_RT = USART_REGIDX_BIT(USART_CTL3_REG_OFFSET, 4U), /*!< interrupt enable bit of receive timeout event */ +} 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 */ +} 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 mask */ + +/* USART word length definitions */ +#define CTL0_WL(regval) (BIT(12) & ((uint32_t)(regval) << 12)) +#define USART_WL_8BIT CTL0_WL(0) /*!< 8 bits */ +#define USART_WL_9BIT CTL0_WL(1) /*!< 9 bits */ + +/* USART oversampling mode definitions */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< 16 bits */ +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< 8 bits */ + +/* 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 LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits */ + +/* USART CK length */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame */ + +/* 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 */ + +/* configure USART DMA request for receive */ +#define CLT2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_RECEIVE_DMA_ENABLE CLT2_DENR(1) /*!< DMA request enable for reception */ +#define USART_RECEIVE_DMA_DISABLE CLT2_DENR(0) /*!< DMA request disable for reception */ + +/* configure USART DMA request for transmission */ +#define CLT2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_TRANSMIT_DMA_ENABLE CLT2_DENT(1) /*!< DMA request enable for transmission */ +#define USART_TRANSMIT_DMA_DISABLE CLT2_DENT(0) /*!< DMA request disable for transmission */ + +/* configure USART RTS */ +#define CLT2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CLT2_RTSEN(1) /*!< enable RTS */ +#define USART_RTS_DISABLE CLT2_RTSEN(0) /*!< disable RTS */ + +/* configure USART CTS */ +#define CLT2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CLT2_CTSEN(1) /*!< enable CTS */ +#define USART_CTS_DISABLE CLT2_CTSEN(0) /*!< disable CTS */ + +/* configure USART one sample bit method */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1bit CTL2_OSB(1) /*!< 1 bit */ +#define USART_OSB_3bit CTL2_OSB(0) /*!< 3 bits */ + +/* 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 data is transmitted/received with the LSB/MSB first */ +#define CTL3_MSBF(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_MSBF_LSB CTL3_MSBF(0) /*!< LSB first */ +#define USART_MSBF_MSB CTL3_MSBF(1) /*!< MSB first */ + +/* break frame coherence mode */ +#define CHC_BCM(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_BCM_NONE CHC_BCM(0) /*!< no parity error is detected */ +#define USART_BCM_EN CHC_BCM(1) /*!< parity error is detected */ + +/* USART parity check coherence mode */ +#define CHC_PCM(regval) (BIT(1) & ((uint32_t)(regval) << 1)) +#define USART_PCM_NONE CHC_PCM(0) /*!< not check parity */ +#define USART_PCM_EN CHC_PCM(1) /*!< check the parity */ + +/* 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 */ + +/* 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); +/* configure USART inverted */ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara); +/* 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 obsm); +/* 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); + +/* multi-processor communication */ +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* 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 wmehtod); + +/* 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); +/* send break frame */ +void usart_send_break(uint32_t usart_periph); + +/* 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 CK pin in synchronous mode */ +void usart_synchronous_clock_enable(uint32_t usart_periph); +/* disable CK pin in synchronous mode */ +void usart_synchronous_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, uint8_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); +/* configure smartcard auto-retry number */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint8_t scrtnum); +/* configure block length */ +void usart_block_length_config(uint32_t usart_periph, uint8_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 */ +void usart_prescaler_config(uint32_t usart_periph, uint8_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 break frame coherence mode */ +void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm); +/* configure parity check coherence mode */ +void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm); +/* configure hardware flow control coherence mode */ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm); + +/* DMA communication */ +/* configure USART DMA for reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd); +/* configure USART DMA for transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd); + +/* flag & interrupt functions */ +/* get flag in STAT0/STAT1 register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear flag in STAT0/STAT1 register */ +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 interrupt flag in STAT0/STAT1 register */ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); + +#endif /* GD32F4XX_USART_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_wwdgt.h b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_wwdgt.h new file mode 100644 index 000000000..7a7735ca4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/include/gd32f4xx_wwdgt.h @@ -0,0 +1,94 @@ +/*! + \file gd32f4xx_wwdgt.h + \brief definitions for the WWDGT + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 GD32F4XX_WWDGT_H +#define GD32F4XX_WWDGT_H + +#include "gd32f4xx.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE /*!< WWDGT base address */ + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x04U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x08U) /*!< 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) /*!< early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval) (BITS(7,8) & ((uint32_t)(regval) << 7)) /*!< write value to WWDGT_CFG_PSC bit field */ +#define WWDGT_CFG_PSC_DIV1 CFG_PSC(0) /*!< the time base of WWDGT = (PCLK1/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 CFG_PSC(1) /*!< the time base of WWDGT = (PCLK1/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 CFG_PSC(2) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 CFG_PSC(3) /*!< the time base of WWDGT = (PCLK1/4096)/8 */ + +/* write value to WWDGT_CTL_CNT bit field */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) +/* write value to WWDGT_CFG_WIN bit field */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) + +/* function declarations */ +/* reset the window watchdog timer configuration */ +void wwdgt_deinit(void); +/* start the window watchdog timer counter */ +void wwdgt_enable(void); + +/* configure the window watchdog timer 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); + +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); + +#endif /* GD32F4XX_WWDGT_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/Makefile b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/Makefile new file mode 100644 index 000000000..0c45f13c2 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := $(wildcard *.c) + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_adc.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_adc.c new file mode 100644 index 000000000..be2524faa --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_adc.c @@ -0,0 +1,1203 @@ +/*! + \file gd32f4xx_adc.c + \brief ADC driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_adc.h" + +#define ROUTINE_TRIGGER_MODE ((uint32_t)28U) +#define INSERTED_TRIGGER_MODE ((uint32_t)20U) +/* discontinuous mode macro*/ +#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)1U) + +/* ADC routine channel macro */ +#define ADC_ROUTINE_CHANNEL_RANK_SIX ((uint8_t)6U) +#define ADC_ROUTINE_CHANNEL_RANK_TWELVE ((uint8_t)12U) +#define ADC_ROUTINE_CHANNEL_RANK_SIXTEEN ((uint8_t)16U) +#define ADC_ROUTINE_CHANNEL_RANK_LENGTH ((uint8_t)5U) + +/* ADC sampling time macro */ +#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)10U) +#define ADC_CHANNEL_SAMPLE_EIGHTEEN ((uint8_t)18U) +#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)3U) + +/* ADC inserted channel macro */ +#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)5U) +#define ADC_INSERTED_CHANNEL_SHIFT_LENGTH ((uint8_t)15U) + +/* ADC inserted channel offset macro */ +#define ADC_OFFSET_LENGTH ((uint8_t)3U) +#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)4U) + +/*! + \brief reset ADC + \param[in] none + \param[out] none + \retval none +*/ +void adc_deinit(void) +{ + rcu_periph_reset_enable(RCU_ADCRST); + rcu_periph_reset_disable(RCU_ADCRST); +} + +/*! + \brief configure the ADC clock for all the ADCs + \param[in] prescaler: configure ADCs prescaler ratio + only one parameter can be selected which is shown as below: + \arg ADC_ADCCK_PCLK2_DIV2: PCLK2 div2 + \arg ADC_ADCCK_PCLK2_DIV4: PCLK2 div4 + \arg ADC_ADCCK_PCLK2_DIV6: PCLK2 div6 + \arg ADC_ADCCK_PCLK2_DIV8: PCLK2 div8 + \arg ADC_ADCCK_HCLK_DIV5: HCLK div5 + \arg ADC_ADCCK_HCLK_DIV6: HCLK div6 + \arg ADC_ADCCK_HCLK_DIV10: HCLK div10 + \arg ADC_ADCCK_HCLK_DIV20: HCLK div20 + \param[out] none + \retval none +*/ +void adc_clock_config(uint32_t prescaler) +{ + ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_ADCCK); + ADC_SYNCCTL |= (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 sequence 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(newvalue) { + if(0U != (function & ADC_SCAN_MODE)) { + /* enable scan mode */ + ADC_CTL0(adc_periph) |= ADC_SCAN_MODE; + } + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { + /* enable inserted sequence convert automatically */ + ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO; + } + if(0U != (function & ADC_CONTINUOUS_MODE)) { + /* enable continuous mode */ + ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE; + } + } else { + if(0U != (function & ADC_SCAN_MODE)) { + /* disable scan mode */ + ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE; + } + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { + /* disable inserted sequence convert automatically */ + ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO; + } + if(0U != (function & ADC_CONTINUOUS_MODE)) { + /* disable continuous mode */ + ADC_CTL1(adc_periph) &= ~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) { + /* MSB alignment */ + ADC_CTL1(adc_periph) |= ADC_CTL1_DAL; + } else { + /* LSB alignment */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \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 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) |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) { + } +} + +/*! + \brief configure temperature sensor and internal reference voltage channel or VBAT channel function + \param[in] function: temperature sensor and internal reference voltage channel or VBAT channel + only one parameter can be selected which is shown as below: + \arg ADC_VBAT_CHANNEL_SWITCH: channel 18 (1/4 voltate of external battery) switch of ADC0 + \arg ADC_TEMP_VREF_CHANNEL_SWITCH: channel 16 (temperature sensor) and 17 (internal reference voltage) switch of ADC0 + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_channel_16_to_18(uint32_t function, ControlStatus newvalue) +{ + if(newvalue) { + if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)) { + /* enable ADC0 Vbat channel */ + ADC_SYNCCTL |= ADC_VBAT_CHANNEL_SWITCH; + } + if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)) { + /* enable ADC0 Vref and Temperature channel */ + ADC_SYNCCTL |= ADC_TEMP_VREF_CHANNEL_SWITCH; + } + } else { + if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)) { + /* disable ADC0 Vbat channel */ + ADC_SYNCCTL &= ~ADC_VBAT_CHANNEL_SWITCH; + } + if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)) { + /* disable ADC0 Vref and Temperature channel */ + ADC_SYNCCTL &= ~ADC_TEMP_VREF_CHANNEL_SWITCH; + } + } +} + +/*! + \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_12B: 12-bit ADC resolution + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution + \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); + ADC_CTL0(adc_periph) |= (uint32_t)resolution; +} + +/*! + \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: 3-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 + \param[in] ratio: ADC oversampling ratio + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint8_t ratio) +{ + if(ADC_OVERSAMPLING_ONE_CONVERT == mode) { + ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS; + } else { + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + /* 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)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) |= 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 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 routine 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 configure ADC discontinuous mode + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of routine & inserted channel + \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 + for routine sequence ,the number has no effect for inserted sequence + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_sequence, uint8_t length) +{ + /* disable discontinuous mode of routine & inserted channel */ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + switch(adc_sequence) { + case ADC_ROUTINE_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 routine sequence discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + /* enable inserted sequence discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + /* disable discontinuous mode of routine & inserted channel */ + default: + break; + } +} + +/*! + \brief configure the length of routine sequence or inserted sequence + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[in] length: the length of the channel + routine channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t length) +{ + switch(adc_sequence) { + case ADC_ROUTINE_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_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + break; + default: + break; + } +} + +/*! + \brief configure ADC routine channel + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] rank: the routine sequence 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..18): ADC channelx + \param[in] sample_time: the sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_3: 3 cycles + \arg ADC_SAMPLETIME_15: 15 cycles + \arg ADC_SAMPLETIME_28: 28 cycles + \arg ADC_SAMPLETIME_56: 56 cycles + \arg ADC_SAMPLETIME_84: 84 cycles + \arg ADC_SAMPLETIME_112: 112 cycles + \arg ADC_SAMPLETIME_144: 144 cycles + \arg ADC_SAMPLETIME_480: 480 cycles + \param[out] none + \retval none +*/ +void adc_routine_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint32_t rsq, sampt; + + /* ADC routine sequence config */ + if(rank < ADC_ROUTINE_CHANNEL_RANK_SIX) { + /* the routine sequence rank is smaller than six */ + rsq = ADC_RSQ2(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * rank))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)adc_channel << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * rank)); + ADC_RSQ2(adc_periph) = rsq; + } else if(rank < ADC_ROUTINE_CHANNEL_RANK_TWELVE) { + /* the routine sequence rank is smaller than twelve */ + rsq = ADC_RSQ1(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_SIX)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)adc_channel << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_SIX))); + ADC_RSQ1(adc_periph) = rsq; + } else if(rank < ADC_ROUTINE_CHANNEL_RANK_SIXTEEN) { + /* the routine sequence rank is smaller than sixteen */ + rsq = ADC_RSQ0(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_TWELVE)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)adc_channel << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_TWELVE))); + ADC_RSQ0(adc_periph) = rsq; + } else { + } + + /* ADC sampling time config */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) { + /* the routine sequence rank is smaller than ten */ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); + /* channel sample time set*/ + sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)); + ADC_SAMPT1(adc_periph) = sampt; + } else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN) { + /* the routine sequence rank is smaller than eighteen */ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)))); + /* channel sample time set*/ + sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); + ADC_SAMPT0(adc_periph) = sampt; + } else { + } +} + +/*! + \brief configure ADC inserted channel + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] rank: the inserted sequence 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..18): ADC Channelx + \param[in] sample_time: The sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_3: 3 cycles + \arg ADC_SAMPLETIME_15: 15 cycles + \arg ADC_SAMPLETIME_28: 28 cycles + \arg ADC_SAMPLETIME_56: 56 cycles + \arg ADC_SAMPLETIME_84: 84 cycles + \arg ADC_SAMPLETIME_112: 112 cycles + \arg ADC_SAMPLETIME_144: 144 cycles + \arg ADC_SAMPLETIME_480: 480 cycles + \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; + uint32_t isq, sampt; + + /* get inserted sequence length */ + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U); + /* the channel number is written to these bits to select a channel as the nth conversion in the inserted sequence */ + if(rank < 4U) { + isq = ADC_ISQ(adc_periph); + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH))); + isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH)); + ADC_ISQ(adc_periph) = isq; + } + + /* ADC sampling time config */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) { + /* the inserted sequence rank is smaller than ten */ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); + /* channel sample time set*/ + sampt |= (uint32_t) sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel); + ADC_SAMPT1(adc_periph) = sampt; + } else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN) { + /* the inserted sequence rank is smaller than eighteen */ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)))); + /* channel sample time set*/ + sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); + ADC_SAMPT0(adc_periph) = sampt; + } else { + } +} + +/*! + \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, uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(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) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief configure ADC external trigger source + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[in] external_trigger_source: routine or inserted sequence trigger source + for routine sequence: + only one parameter can be selected which is shown as below: + \arg ADC_EXTTRIG_ROUTINE_T0_CH0: external trigger timer 0 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T0_CH1: external trigger timer 0 CC1 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T0_CH2: external trigger timer 0 CC2 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_CH1: external trigger timer 1 CC1 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_CH2: external trigger timer 1 CC2 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_CH3: external trigger timer 1 CC3 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T1_TRGO: external trigger timer 1 TRGO event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T2_CH0 : external trigger timer 2 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T2_TRGO : external trigger timer 2 TRGO event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T3_CH3: external trigger timer 3 CC3 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T4_CH0: external trigger timer 4 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T4_CH1: external trigger timer 4 CC1 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T4_CH2: external trigger timer 4 CC2 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T7_CH0: external trigger timer 7 CC0 event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_T7_TRGO: external trigger timer 7 TRGO event select for routine sequence + \arg ADC_EXTTRIG_ROUTINE_EXTI_11: external trigger extiline 11 select for routine sequence + for inserted sequence: + only one parameter can be selected which is shown as below: + \arg ADC_EXTTRIG_INSERTED_T0_CH3: timer0 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: timer0 TRGO event + \arg ADC_EXTTRIG_INSERTED_T1_CH0: timer1 capture compare 0 + \arg ADC_EXTTRIG_INSERTED_T1_TRGO: timer1 TRGO event + \arg ADC_EXTTRIG_INSERTED_T2_CH1: timer2 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T2_CH3: timer2 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T3_CH0: timer3 capture compare 0 + \arg ADC_EXTTRIG_INSERTED_T3_CH1: timer3 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T3_CH2: timer3 capture compare 2 + \arg ADC_EXTTRIG_INSERTED_T3_TRGO: timer3 capture compare TRGO + \arg ADC_EXTTRIG_INSERTED_T4_CH3: timer4 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_T4_TRGO: timer4 capture compare TRGO + \arg ADC_EXTTRIG_INSERTED_T7_CH1: timer7 capture compare 1 + \arg ADC_EXTTRIG_INSERTED_T7_CH2: timer7 capture compare 2 + \arg ADC_EXTTRIG_INSERTED_T7_CH3: timer7 capture compare 3 + \arg ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_sequence, uint32_t external_trigger_source) +{ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* configure ADC routine sequence external trigger source */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + /* configure ADC inserted sequence external trigger source */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief enable ADC external trigger + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \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_sequence, uint32_t trigger_mode) +{ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* configure ADC routine sequence external trigger mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC); + ADC_CTL1(adc_periph) |= (uint32_t)(trigger_mode << ROUTINE_TRIGGER_MODE); + break; + case ADC_INSERTED_CHANNEL: + /* configure ADC inserted sequence 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_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_sequence) +{ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* enable ADC routine sequence software trigger */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST; + break; + case ADC_INSERTED_CHANNEL: + /* enable ADC inserted sequence software trigger */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWICST; + break; + default: + break; + } +} + +/*! + \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 routine conversions, the EOC bit is set.Overflow detection is disabled unless DMA=1. + \arg ADC_EOC_SET_CONVERSION: at the end of each routine 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, uint8_t end_selection) +{ + switch(end_selection) { + case ADC_EOC_SET_SEQUENCE: + /* only at the end of a sequence of routine conversions, the EOC bit is set */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_EOCM); + break; + case ADC_EOC_SET_CONVERSION: + /* at the end of each routine conversion, the EOC bit is set.Overflow is detected automatically */ + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_EOCM); + break; + default: + break; + } +} + +/*! + \brief read ADC routine data register + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_routine_data_read(uint32_t adc_periph) +{ + return (uint16_t)(ADC_RDATA(adc_periph)); +} + +/*! + \brief read ADC inserted 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 +*/ +uint16_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 (uint16_t)idata; +} + +/*! + \brief disable ADC analog watchdog single channel + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_disable(uint32_t adc_periph) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDSC); +} + +/*! + \brief enable ADC analog watchdog 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..18) + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDCHSEL); + + /* analog watchdog channel select */ + ADC_CTL0(adc_periph) |= (uint32_t)adc_channel; + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDSC; +} + +/*! + \brief configure ADC analog watchdog sequence channel + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: the sequence use analog watchdog + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_ROUTINE_INSERTED_CHANNEL: both routine and inserted sequence + \param[out] none + \retval none +*/ +void adc_watchdog_sequence_channel_enable(uint32_t adc_periph, uint8_t adc_sequence) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC)); + /* select the sequence */ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* routine channel analog watchdog enable */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN; + break; + case ADC_INSERTED_CHANNEL: + /* inserted channel analog watchdog enable */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN; + break; + case ADC_ROUTINE_INSERTED_CHANNEL: + /* routine and inserted channel analog watchdog enable */ + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); + break; + default: + break; + } +} + +/*! + \brief disable ADC analog watchdog + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_sequence: the sequence use analog watchdog + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_ROUTINE_INSERTED_CHANNEL: both routine and inserted sequence + \param[out] none + \retval none +*/ +void adc_watchdog_disable(uint32_t adc_periph, uint8_t adc_sequence) +{ + /* select the sequence */ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* disable ADC analog watchdog routine sequence */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_RWDEN); + break; + case ADC_INSERTED_CHANNEL: + /* disable ADC analog watchdog inserted sequence */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_IWDEN); + break; + case ADC_ROUTINE_INSERTED_CHANNEL: + /* disable ADC analog watchdog routine and inserted sequence */ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN)); + break; + default: + break; + } +} + +/*! + \brief configure ADC analog watchdog threshold + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] low_threshold: analog watchdog low threshold,0..4095 + \param[in] high_threshold: analog watchdog high threshold,0..4095 + \param[out] none + \retval none +*/ +void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold) +{ + /* configure ADC analog watchdog low threshold */ + ADC_WDLT(adc_periph) = (uint32_t)WDLT_WDLT(low_threshold); + /* configure ADC analog watchdog high threshold */ + ADC_WDHT(adc_periph) = (uint32_t)WDHT_WDHT(high_threshold); +} + +/*! + \brief get the ADC flag bits + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_flag: the adc flag bits + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of sequence conversion flag + \arg ADC_FLAG_EOIC: end of inserted sequence conversion flag + \arg ADC_FLAG_STIC: start flag of inserted sequence + \arg ADC_FLAG_STRC: start flag of routine sequence + \arg ADC_FLAG_ROVF: routine data register overflow flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag) +{ + FlagStatus reval = RESET; + if(ADC_STAT(adc_periph) & adc_flag) { + reval = SET; + } + return reval; + +} + +/*! + \brief clear the ADC flag bits + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_flag: the adc flag bits + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of sequence conversion flag + \arg ADC_FLAG_EOIC: end of inserted sequence conversion flag + \arg ADC_FLAG_STIC: start flag of inserted sequence + \arg ADC_FLAG_STRC: start flag of routine sequence + \arg ADC_FLAG_ROVF: routine data register overflow flag + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag) +{ + ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag); +} + +/*! + \brief get the bit state of ADCx software start conversion + \param[in] adc_periph: ADCx, x=0,1,2 only one among these parameters can be selected + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_routine_software_startconv_flag_get(uint32_t adc_periph) +{ + FlagStatus reval = RESET; + if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STRC)) { + reval = SET; + } + return reval; +} + +/*! + \brief get the bit state of ADCx software inserted channel start conversion + \param[in] adc_periph: ADCx, x=0,1,2 only one among these parameters can be selected + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph) +{ + FlagStatus reval = RESET; + if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STIC)) { + reval = SET; + } + return reval; +} + +/*! + \brief get the ADC interrupt bits + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_interrupt: the adc interrupt bits + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt + \arg ADC_INT_FLAG_EOC: end of sequence conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted sequence conversion interrupt + \arg ADC_INT_FLAG_ROVF: routine data register overflow interrupt + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(adc_interrupt) { + case ADC_INT_FLAG_WDE: + /* get the ADC analog watchdog interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_WDE; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state) { + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + /* get the ADC end of sequence conversion interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_EOC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state) { + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + /* get the ADC end of inserted sequence conversion interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_EOIC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state) { + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_ROVF: + /* get the ADC routine data register overflow interrupt bits */ + state = ADC_STAT(adc_periph) & ADC_STAT_ROVF; + if((ADC_CTL0(adc_periph) & ADC_CTL0_ROVFIE) && state) { + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear the ADC flag + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_interrupt: the adc status flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt + \arg ADC_INT_FLAG_EOC: end of sequence conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted sequence conversion interrupt + \arg ADC_INT_FLAG_ROVF: routine data register overflow interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt) +{ + ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt); +} + +/*! + \brief enable ADC interrupt + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_interrupt: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of sequence conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted sequence conversion interrupt flag + \arg ADC_INT_ROVF: routine data register overflow interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt) +{ + switch(adc_interrupt) { + case ADC_INT_WDE: + /* enable analog watchdog interrupt */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE; + break; + case ADC_INT_EOC: + /* enable end of sequence conversion interrupt */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE; + break; + case ADC_INT_EOIC: + /* enable end of inserted sequence conversion interrupt */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE; + break; + case ADC_INT_ROVF: + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_ROVFIE; + break; + default: + break; + } +} + +/*! + \brief disable ADC interrupt + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_flag: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt flag + \arg ADC_INT_EOC: end of sequence conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted sequence conversion interrupt flag + \arg ADC_INT_ROVF: routine data register overflow interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt) +{ + switch(adc_interrupt) { + /* select the interrupt source */ + case ADC_INT_WDE: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDEIE); + break; + case ADC_INT_EOC: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOCIE); + break; + case ADC_INT_EOIC: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOICIE); + break; + case ADC_INT_ROVF: + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_ROVFIE); + break; + default: + break; + } +} + +/*! + \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_ROUTINE_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined routine parallel & inserted parallel mode + \arg ADC_DAUL_ROUTINE_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined routine parallel & trigger rotation mode + \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode + \arg ADC_DAUL_ROUTINE_PARALLEL: ADC0 and ADC1 work in routine parallel mode + \arg ADC_DAUL_ROUTINE_FOLLOW_UP: ADC0 and ADC1 work in follow-up mode + \arg ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode + \arg ADC_ALL_ROUTINE_PARALLEL_INSERTED_PARALLEL: all ADCs work in combined routine parallel & inserted parallel mode + \arg ADC_ALL_ROUTINE_PARALLEL_INSERTED_ROTATION: all ADCs work in combined routine parallel & trigger rotation mode + \arg ADC_ALL_INSERTED_PARALLEL: all ADCs work in inserted parallel mode + \arg ADC_ALL_ROUTINE_PARALLEL: all ADCs work in routine parallel mode + \arg ADC_ALL_ROUTINE_FOLLOW_UP: all ADCs work in follow-up mode + \arg ADC_ALL_INSERTED_TRRIGGER_ROTATION: all ADCs work in trigger rotation mode + \param[out] none + \retval none +*/ +void adc_sync_mode_config(uint32_t sync_mode) +{ + ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCM); + ADC_SYNCCTL |= 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 &= ~(ADC_SYNCCTL_SYNCDLY); + ADC_SYNCCTL |= 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 &= ~(ADC_SYNCCTL_SYNCDMA); + ADC_SYNCCTL |= dma_mode; +} + +/*! + \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_enable(void) +{ + ADC_SYNCCTL |= ADC_SYNCCTL_SYNCDDM; +} + +/*! + \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_disable(void) +{ + ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDDM); +} + +/*! + \brief read ADC sync routine data register + \param[in] none + \param[out] none + \retval sync routine data +*/ +uint32_t adc_sync_routine_data_read(void) +{ + return (uint32_t)ADC_SYNCDATA; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_can.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_can.c new file mode 100644 index 000000000..e14f91c81 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_can.c @@ -0,0 +1,1026 @@ +/*! + \file gd32f4xx_can.c + \brief CAN driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2019-11-27, V2.0.1, firmware for GD32F4xx + \version 2020-07-14, V2.0.2, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2021-12-28, V2.1.1, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_can.h" +#include + +#define CAN_ERROR_HANDLE(s) do{}while(1) + +/*! + \brief deinitialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_deinit(uint32_t can_periph) +{ + if(CAN0 == can_periph){ + rcu_periph_reset_enable(RCU_CAN0RST); + rcu_periph_reset_disable(RCU_CAN0RST); + }else{ + rcu_periph_reset_enable(RCU_CAN1RST); + rcu_periph_reset_disable(RCU_CAN1RST); + } +} + +/*! + \brief initialize CAN parameter struct 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_FILTER_STRUCT: the CAN filter struct + \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct + \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct + \param[out] p_struct: the pointer of the specific struct + \retval none +*/ +void can_struct_para_init(can_struct_type_enum type, void *p_struct) +{ + uint8_t i; + + if(NULL == p_struct) { + CAN_ERROR_HANDLE("struct parameter can not be NULL \r\n"); + } + + /* get type of the struct */ + switch(type) { + /* used for can_init() */ + case CAN_INIT_STRUCT: + ((can_parameter_struct *)p_struct)->auto_bus_off_recovery = DISABLE; + ((can_parameter_struct *)p_struct)->auto_retrans = DISABLE; + ((can_parameter_struct *)p_struct)->auto_wake_up = DISABLE; + ((can_parameter_struct *)p_struct)->prescaler = 0x03FFU; + ((can_parameter_struct *)p_struct)->rec_fifo_overwrite = DISABLE; + ((can_parameter_struct *)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ; + ((can_parameter_struct *)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ; + ((can_parameter_struct *)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ; + ((can_parameter_struct *)p_struct)->time_triggered = DISABLE; + ((can_parameter_struct *)p_struct)->trans_fifo_order = DISABLE; + ((can_parameter_struct *)p_struct)->working_mode = CAN_NORMAL_MODE; + + break; + /* used for can_filter_init() */ + case CAN_FILTER_STRUCT: + ((can_filter_parameter_struct *)p_struct)->filter_bits = CAN_FILTERBITS_32BIT; + ((can_filter_parameter_struct *)p_struct)->filter_enable = DISABLE; + ((can_filter_parameter_struct *)p_struct)->filter_fifo_number = CAN_FIFO0; + ((can_filter_parameter_struct *)p_struct)->filter_list_high = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_list_low = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_mask_high = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_mask_low = 0x0000U; + ((can_filter_parameter_struct *)p_struct)->filter_mode = CAN_FILTERMODE_MASK; + ((can_filter_parameter_struct *)p_struct)->filter_number = 0U; + + break; + /* used for can_message_transmit() */ + case CAN_TX_MESSAGE_STRUCT: + for(i = 0U; i < 8U; i++) { + ((can_trasnmit_message_struct *)p_struct)->tx_data[i] = 0U; + } + + ((can_trasnmit_message_struct *)p_struct)->tx_dlen = 0u; + ((can_trasnmit_message_struct *)p_struct)->tx_efid = 0U; + ((can_trasnmit_message_struct *)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD; + ((can_trasnmit_message_struct *)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA; + ((can_trasnmit_message_struct *)p_struct)->tx_sfid = 0U; + + break; + /* used for can_message_receive() */ + case CAN_RX_MESSAGE_STRUCT: + for(i = 0U; i < 8U; i++) { + ((can_receive_message_struct *)p_struct)->rx_data[i] = 0U; + } + + ((can_receive_message_struct *)p_struct)->rx_dlen = 0U; + ((can_receive_message_struct *)p_struct)->rx_efid = 0U; + ((can_receive_message_struct *)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD; + ((can_receive_message_struct *)p_struct)->rx_fi = 0U; + ((can_receive_message_struct *)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA; + ((can_receive_message_struct *)p_struct)->rx_sfid = 0U; + + break; + + default: + CAN_ERROR_HANDLE("parameter is invalid \r\n"); + } +} + +/*! + \brief initialize CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_parameter_init: parameters for CAN initializtion + \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE + \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4) + \arg time_segment_1: CAN_BT_BS1_xTQ(1..16) + \arg time_segment_2: CAN_BT_BS2_xTQ(1..8) + \arg time_triggered: ENABLE or DISABLE + \arg auto_bus_off_recovery: ENABLE or DISABLE + \arg auto_wake_up: ENABLE or DISABLE + \arg auto_retrans: ENABLE or DISABLE + \arg rec_fifo_overwrite: ENABLE or DISABLE + \arg trans_fifo_order: ENABLE or DISABLE + \arg prescaler: 0x0001 - 0x0400 + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init) +{ + uint32_t timeout = CAN_TIMEOUT; + ErrStatus flag = GD_ERROR; + + /* disable sleep mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + /* enable initialize mode */ + CAN_CTL(can_periph) |= CAN_CTL_IWMOD; + /* wait ACK */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) { + timeout--; + } + /* check initialize working success */ + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) { + flag = GD_ERROR; + } else { + /* set the bit timing register */ + CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \ + BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \ + BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \ + BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \ + BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U))); + + /* time trigger communication mode */ + if(ENABLE == can_parameter_init->time_triggered) { + CAN_CTL(can_periph) |= CAN_CTL_TTC; + } else { + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + } + /* automatic bus-off management */ + if(ENABLE == can_parameter_init->auto_bus_off_recovery) { + CAN_CTL(can_periph) |= CAN_CTL_ABOR; + } else { + CAN_CTL(can_periph) &= ~CAN_CTL_ABOR; + } + /* automatic wakeup mode */ + if(ENABLE == can_parameter_init->auto_wake_up) { + CAN_CTL(can_periph) |= CAN_CTL_AWU; + } else { + CAN_CTL(can_periph) &= ~CAN_CTL_AWU; + } + /* automatic retransmission mode */ + if(ENABLE == can_parameter_init->auto_retrans) { + CAN_CTL(can_periph) &= ~CAN_CTL_ARD; + } else { + CAN_CTL(can_periph) |= CAN_CTL_ARD; + } + /* receive FIFO overwrite mode */ + if(ENABLE == can_parameter_init->rec_fifo_overwrite) { + CAN_CTL(can_periph) &= ~CAN_CTL_RFOD; + } else { + CAN_CTL(can_periph) |= CAN_CTL_RFOD; + } + /* transmit FIFO order */ + if(ENABLE == can_parameter_init->trans_fifo_order) { + CAN_CTL(can_periph) |= CAN_CTL_TFO; + } else { + CAN_CTL(can_periph) &= ~CAN_CTL_TFO; + } + /* disable initialize mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD; + timeout = CAN_TIMEOUT; + /* wait the ACK */ + while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) { + timeout--; + } + /* check exit initialize mode */ + if(0U != timeout) { + flag = GD_SUCCESS; + } + } + return flag; +} + +/*! + \brief initialize CAN filter + \param[in] can_filter_parameter_init: struct for CAN filter initialization + \arg filter_list_high: 0x0000 - 0xFFFF + \arg filter_list_low: 0x0000 - 0xFFFF + \arg filter_mask_high: 0x0000 - 0xFFFF + \arg filter_mask_low: 0x0000 - 0xFFFF + \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1 + \arg filter_number: 0 - 27 + \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST + \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT + \arg filter_enable: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void can_filter_init(can_filter_parameter_struct *can_filter_parameter_init) +{ + uint32_t val = 0U; + + val = ((uint32_t)1) << (can_filter_parameter_init->filter_number); + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* disable filter */ + CAN_FW(CAN0) &= ~(uint32_t)val; + + /* filter 16 bits */ + if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits) { + /* set filter 16 bits */ + CAN_FSCFG(CAN0) &= ~(uint32_t)val; + /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \ + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS); + } + /* filter 32 bits */ + if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits) { + /* set filter 32 bits */ + CAN_FSCFG(CAN0) |= (uint32_t)val; + /* 32 bits list or first 32 bits list */ + CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS); + /* 32 bits mask or second 32 bits list */ + CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \ + FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | + FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS); + } + + /* filter mode */ + if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode) { + /* mask mode */ + CAN_FMCFG(CAN0) &= ~(uint32_t)val; + } else { + /* list mode */ + CAN_FMCFG(CAN0) |= (uint32_t)val; + } + + /* filter FIFO */ + if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)) { + /* FIFO0 */ + CAN_FAFIFO(CAN0) &= ~(uint32_t)val; + } else { + /* FIFO1 */ + CAN_FAFIFO(CAN0) |= (uint32_t)val; + } + + /* filter working */ + if(ENABLE == can_filter_parameter_init->filter_enable) { + + CAN_FW(CAN0) |= (uint32_t)val; + } + + /* filter lock enable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief set CAN1 filter start bank number + \param[in] start_bank: CAN1 start bank number + only one parameter can be selected which is shown as below: + \arg (1..27) + \param[out] none + \retval none +*/ +void can1_filter_start_bank(uint8_t start_bank) +{ + /* filter lock disable */ + CAN_FCTL(CAN0) |= CAN_FCTL_FLD; + /* set CAN1 filter start number */ + CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F; + CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank); + /* filter lock enable */ + CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD; +} + +/*! + \brief enable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_enable(uint32_t can_periph) +{ + /* set DFZ bit */ + CAN_CTL(can_periph) |= CAN_CTL_DFZ; + + if(CAN0 == can_periph) { + dbg_periph_enable(DBG_CAN0_HOLD); + }else{ + dbg_periph_enable(DBG_CAN1_HOLD); + } +} + +/*! + \brief disable CAN debug freeze + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_debug_freeze_disable(uint32_t can_periph) +{ + /* set DFZ bit */ + CAN_CTL(can_periph) &= ~CAN_CTL_DFZ; + + if(CAN0 == can_periph){ + dbg_periph_disable(DBG_CAN0_HOLD); + }else{ + dbg_periph_disable(DBG_CAN1_HOLD); + } +} + +/*! + \brief enable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_enable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* enable the TTC mode */ + CAN_CTL(can_periph) |= CAN_CTL_TTC; + /* enable time stamp */ + for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++) { + CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN; + } +} + +/*! + \brief disable CAN time trigger mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_trigger_mode_disable(uint32_t can_periph) +{ + uint8_t mailbox_number; + + /* disable the TTC mode */ + CAN_CTL(can_periph) &= ~CAN_CTL_TTC; + /* reset TSEN bits */ + for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++) { + CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN; + } +} + +/*! + \brief transmit CAN message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] transmit_message: struct for CAN transmit message + \arg tx_sfid: 0x00000000 - 0x000007FF + \arg tx_efid: 0x00000000 - 0x1FFFFFFF + \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg tx_dlen: 0 - 8 + \arg tx_data[]: 0x00 - 0xFF + \param[out] none + \retval mailbox_number +*/ +uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct *transmit_message) +{ + uint8_t mailbox_number = CAN_MAILBOX0; + + /* select one empty mailbox */ + if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)) { + mailbox_number = CAN_MAILBOX0; + } else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)) { + mailbox_number = CAN_MAILBOX1; + } else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)) { + mailbox_number = CAN_MAILBOX2; + } else { + mailbox_number = CAN_NOMAILBOX; + } + /* return no mailbox empty */ + if(CAN_NOMAILBOX == mailbox_number) { + return CAN_NOMAILBOX; + } + + CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN; + if(CAN_FF_STANDARD == transmit_message->tx_ff) { + /* set transmit mailbox standard identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \ + transmit_message->tx_ft); + } else { + /* set transmit mailbox extended identifier */ + CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \ + transmit_message->tx_ff | \ + transmit_message->tx_ft); + } + /* set the data length */ + CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC; + CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen; + /* set the data */ + CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \ + TMDATA0_DB2(transmit_message->tx_data[2]) | \ + TMDATA0_DB1(transmit_message->tx_data[1]) | \ + TMDATA0_DB0(transmit_message->tx_data[0]); + CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \ + TMDATA1_DB6(transmit_message->tx_data[6]) | \ + TMDATA1_DB5(transmit_message->tx_data[5]) | \ + TMDATA1_DB4(transmit_message->tx_data[4]); + /* enable transmission */ + CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN; + + return mailbox_number; +} + +/*! + \brief get CAN transmit state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + only one parameter can be selected which is shown as below: + \arg CAN_MAILBOX(x=0,1,2) + \param[out] none + \retval can_transmit_state_enum +*/ +can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number) +{ + can_transmit_state_enum state = CAN_TRANSMIT_FAILED; + uint32_t val = 0U; + + /* check selected mailbox state */ + switch(mailbox_number) { + /* mailbox0 */ + case CAN_MAILBOX0: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0); + break; + /* mailbox1 */ + case CAN_MAILBOX1: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1); + break; + /* mailbox2 */ + case CAN_MAILBOX2: + val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2); + break; + default: + val = CAN_TRANSMIT_FAILED; + break; + } + + switch(val) { + /* transmit pending */ + case(CAN_STATE_PENDING): + state = CAN_TRANSMIT_PENDING; + break; + /* mailbox0 transmit succeeded */ + case(CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0): + state = CAN_TRANSMIT_OK; + break; + /* mailbox1 transmit succeeded */ + case(CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1): + state = CAN_TRANSMIT_OK; + break; + /* mailbox2 transmit succeeded */ + case(CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2): + state = CAN_TRANSMIT_OK; + break; + /* transmit failed */ + default: + state = CAN_TRANSMIT_FAILED; + break; + } + return state; +} + +/*! + \brief stop CAN transmission + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] mailbox_number + only one parameter can be selected which is shown as below: + \arg CAN_MAILBOXx(x=0,1,2) + \param[out] none + \retval none +*/ +void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number) +{ + if(CAN_MAILBOX0 == mailbox_number) { + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0; + while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) { + } + } else if(CAN_MAILBOX1 == mailbox_number) { + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1; + while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)) { + } + } else if(CAN_MAILBOX2 == mailbox_number) { + CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2; + while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)) { + } + } else { + /* illegal parameters */ + } +} + +/*! + \brief CAN receive message + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + \arg CAN_FIFOx(x=0,1) + \param[out] receive_message: struct for CAN receive message + \arg rx_sfid: 0x00000000 - 0x000007FF + \arg rx_efid: 0x00000000 - 0x1FFFFFFF + \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED + \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE + \arg rx_dlen: 0 - 8 + \arg rx_data[]: 0x00 - 0xFF + \arg rx_fi: 0 - 27 + \retval none +*/ +void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct *receive_message) +{ + /* get the frame format */ + receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number)); + if(CAN_FF_STANDARD == receive_message->rx_ff) { + /* get standard identifier */ + receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number))); + } else { + /* get extended identifier */ + receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number))); + } + + /* get frame type */ + receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number)); + /* filtering index */ + receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number))); + /* get receive data length */ + receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number))); + + /* receive data */ + receive_message -> rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number))); + receive_message -> rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number))); + receive_message -> rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number))); + + /* release FIFO */ + if(CAN_FIFO0 == fifo_number) { + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + } else { + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + } +} + +/*! + \brief release FIFO + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + only one parameter can be selected which is shown as below: + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval none +*/ +void can_fifo_release(uint32_t can_periph, uint8_t fifo_number) +{ + if(CAN_FIFO0 == fifo_number) { + CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0; + } else if(CAN_FIFO1 == fifo_number) { + CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1; + } else { + /* illegal parameters */ + CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n"); + } +} + +/*! + \brief CAN receive message length + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] fifo_number + only one parameter can be selected which is shown as below: + \arg CAN_FIFOx(x=0,1) + \param[out] none + \retval message length +*/ +uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number) +{ + uint8_t val = 0U; + + if(CAN_FIFO0 == fifo_number) { + /* FIFO0 */ + val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK); + } else if(CAN_FIFO1 == fifo_number) { + /* FIFO1 */ + val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK); + } else { + /* illegal parameters */ + } + return val; +} + +/*! + \brief set CAN working mode + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] can_working_mode + only one parameter can be selected which is shown as below: + \arg CAN_MODE_INITIALIZE + \arg CAN_MODE_NORMAL + \arg CAN_MODE_SLEEP + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode) +{ + ErrStatus flag = GD_ERROR; + /* timeout for IWS or also for SLPWS bits */ + uint32_t timeout = CAN_TIMEOUT; + + if(CAN_MODE_INITIALIZE == working_mode) { + /* disable sleep mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD); + /* set initialize mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD; + /* wait the acknowledge */ + while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)) { + timeout--; + } + if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) { + flag = GD_ERROR; + } else { + flag = GD_SUCCESS; + } + } else if(CAN_MODE_NORMAL == working_mode) { + /* enter normal mode */ + CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD); + /* wait the acknowledge */ + while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)) { + timeout--; + } + if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) { + flag = GD_ERROR; + } else { + flag = GD_SUCCESS; + } + } else if(CAN_MODE_SLEEP == working_mode) { + /* disable initialize mode */ + CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD); + /* set sleep mode */ + CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD; + /* wait the acknowledge */ + while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)) { + timeout--; + } + if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) { + flag = GD_ERROR; + } else { + flag = GD_SUCCESS; + } + } else { + flag = GD_ERROR; + } + return flag; +} + +/*! + \brief wake up CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus can_wakeup(uint32_t can_periph) +{ + ErrStatus flag = GD_ERROR; + uint32_t timeout = CAN_TIMEOUT; + + /* wakeup */ + CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD; + + while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)) { + timeout--; + } + /* check state */ + if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) { + flag = GD_ERROR; + } else { + flag = GD_SUCCESS; + } + return flag; +} + +/*! + \brief get CAN error type + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval can_error_enum + \arg CAN_ERROR_NONE: no error + \arg CAN_ERROR_FILL: fill error + \arg CAN_ERROR_FORMATE: format error + \arg CAN_ERROR_ACK: ACK error + \arg CAN_ERROR_BITRECESSIVE: bit recessive + \arg CAN_ERROR_BITDOMINANTER: bit dominant error + \arg CAN_ERROR_CRC: CRC error + \arg CAN_ERROR_SOFTWARECFG: software configure +*/ +can_error_enum can_error_get(uint32_t can_periph) +{ + can_error_enum error; + error = CAN_ERROR_NONE; + + /* get error type */ + error = (can_error_enum)(GET_ERR_ERRN(CAN_ERR(can_periph))); + return error; +} + +/*! + \brief get CAN receive error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_receive_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + /* get error count */ + val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph))); + return val; +} + +/*! + \brief get CAN transmit error number + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval error number +*/ +uint8_t can_transmit_error_number_get(uint32_t can_periph) +{ + uint8_t val; + + val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph))); + return val; +} + +/*! + \brief get CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_RXL: RX level + \arg CAN_FLAG_LASTRX: last sample value of RX pin + \arg CAN_FLAG_RS: receiving state + \arg CAN_FLAG_TS: transmitting state + \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode + \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode + \arg CAN_FLAG_ERRIF: error flag + \arg CAN_FLAG_SLPWS: sleep working state + \arg CAN_FLAG_IWS: initial working state + \arg CAN_FLAG_TMLS2: transmit mailbox 2 last sending in TX FIFO + \arg CAN_FLAG_TMLS1: transmit mailbox 1 last sending in TX FIFO + \arg CAN_FLAG_TMLS0: transmit mailbox 0 last sending in TX FIFO + \arg CAN_FLAG_TME2: transmit mailbox 2 empty + \arg CAN_FLAG_TME1: transmit mailbox 1 empty + \arg CAN_FLAG_TME0: transmit mailbox 0 empty + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost + \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost + \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost + \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error + \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error + \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \arg CAN_FLAG_BOERR: bus-off error + \arg CAN_FLAG_PERR: passive error + \arg CAN_FLAG_WERR: warning error + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) +{ + /* get flag and interrupt enable state */ + if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear CAN flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode + \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode + \arg CAN_FLAG_ERRIF: error flag + \arg CAN_FLAG_MTE2: mailbox 2 transmit error + \arg CAN_FLAG_MTE1: mailbox 1 transmit error + \arg CAN_FLAG_MTE0: mailbox 0 transmit error + \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost + \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost + \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost + \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error + \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error + \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error + \arg CAN_FLAG_MTF2: mailbox 2 transmit finished + \arg CAN_FLAG_MTF1: mailbox 1 transmit finished + \arg CAN_FLAG_MTF0: mailbox 0 transmit finished + \arg CAN_FLAG_RFO0: receive FIFO0 overfull + \arg CAN_FLAG_RFF0: receive FIFO0 full + \arg CAN_FLAG_RFO1: receive FIFO1 overfull + \arg CAN_FLAG_RFF1: receive FIFO1 full + \param[out] none + \retval none +*/ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag) +{ + CAN_REG_VAL(can_periph, flag) = BIT(CAN_BIT_POS(flag)); +} + +/*! + \brief enable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + one or more parameters can be selected which are shown as below: + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WAKEUP: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) |= interrupt; +} + +/*! + \brief disable CAN interrupt + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] interrupt + one or more parameters can be selected which are shown as below: + \arg CAN_INT_TME: transmit mailbox empty interrupt enable + \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable + \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable + \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable + \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable + \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable + \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable + \arg CAN_INT_WERR: warning error interrupt enable + \arg CAN_INT_PERR: passive error interrupt enable + \arg CAN_INT_BO: bus-off interrupt enable + \arg CAN_INT_ERRN: error number interrupt enable + \arg CAN_INT_ERR: error interrupt enable + \arg CAN_INT_WAKEUP: wakeup interrupt enable + \arg CAN_INT_SLPW: sleep working interrupt enable + \param[out] none + \retval none +*/ +void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt) +{ + CAN_INTEN(can_periph) &= ~interrupt; +} + +/*! + \brief get CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] 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_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFL0: receive FIFO0 not empty interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \arg CAN_INT_FLAG_RFL1: receive FIFO1 not empty interrupt flag + \arg CAN_INT_FLAG_ERRN: error number interrupt flag + \arg CAN_INT_FLAG_BOERR: bus-off error interrupt flag + \arg CAN_INT_FLAG_PERR: passive error interrupt flag + \arg CAN_INT_FLAG_WERR: warning error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + uint32_t ret1 = RESET; + uint32_t ret2 = RESET; + + /* get the status of interrupt flag */ + if(flag == CAN_INT_FLAG_RFL0) { + ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0); + } else if(flag == CAN_INT_FLAG_RFL1) { + ret1 = can_receive_message_length_get(can_periph, CAN_FIFO1); + } else if(flag == CAN_INT_FLAG_ERRN) { + ret1 = can_error_get(can_periph); + } else { + ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag)); + } + /* get the status of interrupt enable bit */ + ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag)); + if(ret1 && ret2) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear CAN interrupt flag state + \param[in] can_periph + \arg CANx(x=0,1) + \param[in] 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_SLPIF: status change interrupt flag of sleep working mode entering + \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode + \arg CAN_INT_FLAG_ERRIF: error interrupt flag + \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag + \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag + \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag + \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag + \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag + \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag + \param[out] none + \retval none +*/ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag) +{ + CAN_REG_VALS(can_periph, flag) = BIT(CAN_BIT_POS0(flag)); +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_crc.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_crc.c new file mode 100644 index 000000000..753d5f292 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_crc.c @@ -0,0 +1,130 @@ +/*! + \file gd32f4xx_crc.c + \brief CRC driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_crc.h" + +#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU) +#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U) + +/*! + \brief deinit CRC calculation unit + \param[in] none + \param[out] none + \retval none +*/ +void crc_deinit(void) +{ + CRC_DATA = CRC_DATA_RESET_VALUE; + CRC_FDATA = CRC_FDATA_RESET_VALUE; + CRC_CTL = (uint32_t)CRC_CTL_RST; +} + +/*! + \brief reset data register(CRC_DATA) to the value of 0xFFFFFFFF + \param[in] none + \param[out] none + \retval none +*/ +void crc_data_register_reset(void) +{ + CRC_CTL |= (uint32_t)CRC_CTL_RST; +} + +/*! + \brief read the value of 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 value of 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 data to the free data register + \param[in] free_data: specified 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 calculate the CRC value of a 32-bit data + \param[in] sdata: specified 32-bit data + \param[out] none + \retval 32-bit value calculated by CRC +*/ +uint32_t crc_single_data_calculate(uint32_t sdata) +{ + CRC_DATA = sdata; + return (CRC_DATA); +} + +/*! + \brief calculate the CRC value of an array of 32-bit values + \param[in] array: pointer to an array of 32-bit values + \param[in] size: size of the array + \param[out] none + \retval 32-bit value calculated by CRC +*/ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size) +{ + uint32_t index; + for(index = 0U; index < size; index++) { + CRC_DATA = array[index]; + } + return (CRC_DATA); +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ctc.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ctc.c new file mode 100644 index 000000000..16573b951 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ctc.c @@ -0,0 +1,391 @@ +/*! + \file gd32f4xx_ctc.c + \brief CTC driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_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] ctc_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: + 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: + 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: + 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 enable the CTC interrupt + \param[in] interrupt: CTC interrupt enable + one or more parameters can be selected which are shown as below: + \arg CTC_INT_CKOK: clock trim OK interrupt enable + \arg CTC_INT_CKWARN: clock trim warning interrupt enable + \arg CTC_INT_ERR: error interrupt enable + \arg CTC_INT_EREF: expect reference interrupt enable + \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 enable source + one or more parameters can be selected which are shown as below: + \arg CTC_INT_CKOK: clock trim OK interrupt enable + \arg CTC_INT_CKWARN: clock trim warning interrupt enable + \arg CTC_INT_ERR: error interrupt enable + \arg CTC_INT_EREF: expect reference interrupt enable + \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 + \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt + \arg CTC_INT_FLAG_ERR: error interrupt + \arg CTC_INT_FLAG_EREF: expect reference interrupt + \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt + \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt + \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt + \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 + \arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt + \arg CTC_INT_FLAG_ERR: error interrupt + \arg CTC_INT_FLAG_EREF: expect reference interrupt + \arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt + \arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt + \arg CTC_INT_FLAG_TRIMERR: trim value error interrupt + \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; + } +} + +/*! + \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 bit + \arg CTC_FLAG_REFMISS: reference sync pulse miss + \arg CTC_FLAG_TRIMERR: trim value error bit + \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 bit + \arg CTC_FLAG_REFMISS: reference sync pulse miss + \arg CTC_FLAG_TRIMERR: trim value error bit + \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; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dac.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dac.c new file mode 100644 index 000000000..cea862036 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dac.c @@ -0,0 +1,678 @@ +/*! + \file gd32f4xx_dac.c + \brief DAC driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_dac.h" + +/* DAC register bit offset */ +#define DAC1_REG_OFFSET ((uint32_t)16U) +#define DH_12BIT_OFFSET ((uint32_t)16U) +#define DH_8BIT_OFFSET ((uint32_t)8U) + +/*! + \brief deinitialize DAC + \param[in] none + \param[out] none + \retval none +*/ +void dac_deinit(void) +{ + rcu_periph_reset_enable(RCU_DACRST); + rcu_periph_reset_disable(RCU_DACRST); +} + +/*! + \brief enable DAC + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL |= DAC_CTL_DEN0; + } else { + DAC_CTL |= DAC_CTL_DEN1; + } +} + +/*! + \brief disable DAC + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL &= ~DAC_CTL_DEN0; + } else { + DAC_CTL &= ~DAC_CTL_DEN1; + } +} + +/*! + \brief enable DAC DMA function + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_dma_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL |= DAC_CTL_DDMAEN0; + } else { + DAC_CTL |= DAC_CTL_DDMAEN1; + } +} + +/*! + \brief disable DAC DMA function + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_dma_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL &= ~DAC_CTL_DDMAEN0; + } else { + DAC_CTL &= ~DAC_CTL_DDMAEN1; + } +} + +/*! + \brief enable DAC output buffer + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL &= ~DAC_CTL_DBOFF0; + } else { + DAC_CTL &= ~DAC_CTL_DBOFF1; + } +} + +/*! + \brief disable DAC output buffer + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_output_buffer_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL |= DAC_CTL_DBOFF0; + } else { + DAC_CTL |= DAC_CTL_DBOFF1; + } +} + +/*! + \brief get DAC output value + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval DAC output data +*/ +uint16_t dac_output_value_get(uint32_t dac_periph) +{ + uint16_t data = 0U; + if(DAC0 == dac_periph) { + /* store the DAC0 output value */ + data = (uint16_t)DAC0_DO; + } else { + /* store the DAC1 output value */ + data = (uint16_t)DAC1_DO; + } + return data; +} + +/*! + \brief set the DAC specified data holding register value + \param[in] dac_periph: DACx(x = 0,1) + \param[in] dac_align: data alignment + only one parameter can be selected which is shown as below: + \arg DAC_ALIGN_8B_R: data right 8 bit alignment + \arg DAC_ALIGN_12B_R: data right 12 bit alignment + \arg DAC_ALIGN_12B_L: data left 12 bit alignment + \param[in] data: data to be loaded + \param[out] none + \retval none +*/ +void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data) +{ + if(DAC0 == dac_periph) { + switch(dac_align) { + /* data right 12 bit alignment */ + case DAC_ALIGN_12B_R: + DAC0_R12DH = data; + break; + /* data left 12 bit alignment */ + case DAC_ALIGN_12B_L: + DAC0_L12DH = data; + break; + /* data right 8 bit alignment */ + case DAC_ALIGN_8B_R: + DAC0_R8DH = data; + break; + default: + break; + } + } else { + switch(dac_align) { + /* data right 12 bit alignment */ + case DAC_ALIGN_12B_R: + DAC1_R12DH = data; + break; + /* data left 12 bit alignment */ + case DAC_ALIGN_12B_L: + DAC1_L12DH = data; + break; + /* data right 8 bit alignment */ + case DAC_ALIGN_8B_R: + DAC1_R8DH = data; + break; + default: + break; + } + } +} + +/*! + \brief enable DAC trigger + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL |= DAC_CTL_DTEN0; + } else { + DAC_CTL |= DAC_CTL_DTEN1; + } +} + +/*! + \brief disable DAC trigger + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL &= ~DAC_CTL_DTEN0; + } else { + DAC_CTL &= ~DAC_CTL_DTEN1; + } +} + +/*! + \brief set DAC trigger source + \param[in] dac_periph: DACx(x = 0,1) + \param[in] triggersource: external triggers of DAC + only one parameter can be selected which is shown as below: + \arg DAC_TRIGGER_T1_TRGO: TIMER1 TRGO + \arg DAC_TRIGGER_T3_TRGO: TIMER3 TRGO + \arg DAC_TRIGGER_T4_TRGO: TIMER4 TRGO + \arg DAC_TRIGGER_T5_TRGO: TIMER5 TRGO + \arg DAC_TRIGGER_T6_TRGO: TIMER6 TRGO + \arg DAC_TRIGGER_T7_TRGO: TIMER7 TRGO + \arg DAC_TRIGGER_EXTI_9: EXTI interrupt line9 event + \arg DAC_TRIGGER_SOFTWARE: software trigger + \param[out] none + \retval none +*/ +void dac_trigger_source_config(uint32_t dac_periph, uint32_t triggersource) +{ + if(DAC0 == dac_periph) { + /* configure DAC0 trigger source */ + DAC_CTL &= ~DAC_CTL_DTSEL0; + DAC_CTL |= triggersource; + } else { + /* configure DAC1 trigger source */ + DAC_CTL &= ~DAC_CTL_DTSEL1; + DAC_CTL |= (triggersource << DAC1_REG_OFFSET); + } +} + +/*! + \brief enable DAC software trigger + \param[in] dac_periph: DACx(x = 0,1) + \retval none +*/ +void dac_software_trigger_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_SWT |= DAC_SWT_SWTR0; + } else { + DAC_SWT |= DAC_SWT_SWTR1; + } +} + +/*! + \brief disable DAC software trigger + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_software_trigger_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_SWT &= ~DAC_SWT_SWTR0; + } else { + DAC_SWT &= ~DAC_SWT_SWTR1; + } +} + +/*! + \brief configure DAC wave mode + \param[in] dac_periph: DACx(x = 0,1) + \param[in] wave_mode: noise wave mode + only one parameter can be selected which is shown as below: + \arg DAC_WAVE_DISABLE: wave 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, uint32_t wave_mode) +{ + if(DAC0 == dac_periph) { + /* configure DAC0 wave mode */ + DAC_CTL &= ~DAC_CTL_DWM0; + DAC_CTL |= wave_mode; + } else { + /* configure DAC1 wave mode */ + DAC_CTL &= ~DAC_CTL_DWM1; + DAC_CTL |= (wave_mode << DAC1_REG_OFFSET); + } +} + +/*! + \brief configure DAC wave bit width + \param[in] dac_periph: DACx(x = 0,1) + \param[in] bit_width: noise wave bit width + only one parameter can be selected which is shown as below: + \arg DAC_WAVE_BIT_WIDTH_1: bit width of the wave signal is 1 + \arg DAC_WAVE_BIT_WIDTH_2: bit width of the wave signal is 2 + \arg DAC_WAVE_BIT_WIDTH_3: bit width of the wave signal is 3 + \arg DAC_WAVE_BIT_WIDTH_4: bit width of the wave signal is 4 + \arg DAC_WAVE_BIT_WIDTH_5: bit width of the wave signal is 5 + \arg DAC_WAVE_BIT_WIDTH_6: bit width of the wave signal is 6 + \arg DAC_WAVE_BIT_WIDTH_7: bit width of the wave signal is 7 + \arg DAC_WAVE_BIT_WIDTH_8: bit width of the wave signal is 8 + \arg DAC_WAVE_BIT_WIDTH_9: bit width of the wave signal is 9 + \arg DAC_WAVE_BIT_WIDTH_10: bit width of the wave signal is 10 + \arg DAC_WAVE_BIT_WIDTH_11: bit width of the wave signal is 11 + \arg DAC_WAVE_BIT_WIDTH_12: bit width of the wave signal is 12 + \param[out] none + \retval none +*/ +void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width) +{ + if(DAC0 == dac_periph) { + /* configure DAC0 wave bit width */ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= bit_width; + } else { + /* configure DAC1 wave bit width */ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= (bit_width << DAC1_REG_OFFSET); + } +} + +/*! + \brief configure DAC LFSR noise mode + \param[in] dac_periph: DACx(x = 0,1) + \param[in] unmask_bits: unmask LFSR bits in DAC LFSR noise mode + 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, uint32_t unmask_bits) +{ + if(DAC0 == dac_periph) { + /* configure DAC0 LFSR noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= unmask_bits; + } else { + /* configure DAC1 LFSR noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= (unmask_bits << DAC1_REG_OFFSET); + } +} + +/*! + \brief configure DAC triangle noise mode + \param[in] dac_periph: DACx(x = 0,1) + \param[in] amplitude: triangle amplitude in DAC triangle noise mode + 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, uint32_t amplitude) +{ + if(DAC0 == dac_periph) { + /* configure DAC0 triangle noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW0; + DAC_CTL |= amplitude; + } else { + /* configure DAC1 triangle noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW1; + DAC_CTL |= (amplitude << DAC1_REG_OFFSET); + } +} + +/*! + \brief enable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL |= (ctl); +} + +/*! + \brief disable DAC concurrent mode + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1; + DAC_CTL &= (~ctl); +} + +/*! + \brief enable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_enable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT |= (swt); +} + +/*! + \brief disable DAC concurrent software trigger function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_software_trigger_disable(void) +{ + uint32_t swt = 0U; + swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1; + DAC_SWT &= (~swt); +} + +/*! + \brief enable DAC concurrent buffer function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL &= (~ctl); +} + +/*! + \brief disable DAC concurrent buffer function + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_output_buffer_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1; + DAC_CTL |= (ctl); +} + +/*! + \brief set DAC concurrent mode data holding register value + \param[in] dac_align: data alignment + only one parameter can be selected which is shown as below: + \arg DAC_ALIGN_8B_R: data right 8b alignment + \arg DAC_ALIGN_12B_R: data right 12b alignment + \arg DAC_ALIGN_12B_L: data left 12b alignment + \param[in] data0: data to be loaded + \param[in] data1: data to be loaded + \param[out] none + \retval none +*/ +void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1) +{ + uint32_t data = 0U; + switch(dac_align) { + /* data right 12b alignment */ + case DAC_ALIGN_12B_R: + data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0; + DACC_R12DH = data; + break; + /* data left 12b alignment */ + case DAC_ALIGN_12B_L: + data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0; + DACC_L12DH = data; + break; + /* data right 8b alignment */ + case DAC_ALIGN_8B_R: + data = ((uint32_t)data1 << DH_8BIT_OFFSET) | data0; + DACC_R8DH = data; + break; + default: + break; + } +} + +/*! + \brief enable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_enable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DDUDRIE0 | DAC_CTL_DDUDRIE1; + DAC_CTL |= (ctl); +} + +/*! + \brief disable DAC concurrent interrupt funcution + \param[in] none + \param[out] none + \retval none +*/ +void dac_concurrent_interrupt_disable(void) +{ + uint32_t ctl = 0U; + ctl = DAC_CTL_DDUDRIE0 | DAC_CTL_DDUDRIE1; + DAC_CTL &= (~ctl); +} + +/*! + \brief get the specified DAC flag (DAC DMA underrun flag) + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dac_flag_get(uint32_t dac_periph) +{ + FlagStatus temp_flag = RESET; + if(DAC0 == dac_periph) { + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)) { + temp_flag = SET; + } + } else { + /* check the DMA underrun flag */ + if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)) { + temp_flag = SET; + } + } + return temp_flag; +} + +/*! + \brief clear the specified DAC flag (DAC DMA underrun flag) + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_flag_clear(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_STAT |= DAC_STAT_DDUDR0; + } else { + DAC_STAT |= DAC_STAT_DDUDR1; + } +} + +/*! + \brief enable DAC interrupt(DAC DMA underrun interrupt) + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_enable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL |= DAC_CTL_DDUDRIE0; + } else { + DAC_CTL |= DAC_CTL_DDUDRIE1; + } +} + +/*! + \brief disable DAC interrupt(DAC DMA underrun interrupt) + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_disable(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_CTL &= ~DAC_CTL_DDUDRIE0; + } else { + DAC_CTL &= ~DAC_CTL_DDUDRIE1; + } +} + +/*! + \brief get the specified DAC interrupt flag (DAC DMA underrun interrupt flag) + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dac_interrupt_flag_get(uint32_t dac_periph) +{ + FlagStatus temp_flag = RESET; + uint32_t ddudr_flag = 0U, ddudrie_flag = 0U; + + if(DAC0 == dac_periph) { + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR0; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0; + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)) { + temp_flag = SET; + } + } else { + /* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */ + ddudr_flag = DAC_STAT & DAC_STAT_DDUDR1; + ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE1; + if((RESET != ddudr_flag) && (RESET != ddudrie_flag)) { + temp_flag = SET; + } + } + return temp_flag; +} + +/*! + \brief clear the specified DAC interrupt flag (DAC DMA underrun interrupt flag) + \param[in] dac_periph: DACx(x = 0,1) + \param[out] none + \retval none +*/ +void dac_interrupt_flag_clear(uint32_t dac_periph) +{ + if(DAC0 == dac_periph) { + DAC_STAT |= DAC_STAT_DDUDR0; + } else { + DAC_STAT |= DAC_STAT_DDUDR1; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dbg.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dbg.c new file mode 100644 index 000000000..f931302ff --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dbg.c @@ -0,0 +1,183 @@ +/*! + \file gd32f4xx_dbg.c + \brief DBG_DEVICE driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_dbg.h" + +#define DBG_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the DBG_DEVICE + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL0 = DBG_RESET_VAL; + DBG_CTL1 = 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: + this parameter can be any combination of the following values: + \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: + this parameter can be any combination of the following values: + \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 peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: dbg_periph_enum + only one parameter can be selected which is shown as below: + \arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted + \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted + \arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted + \arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted + \arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted + \arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted + \arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted + \arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted + \arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted + \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted + \arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted + \arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted + \arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted + \arg DBG_TIMER10_HOLD: hold TIMER10 counter when core is halted + \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: dbg_periph_enum + only one parameter can be selected which is shown as below: + \arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted + \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted + \arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted + \arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted + \arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted + \arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted + \arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted + \arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted + \arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted + \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted + \arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted + \arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted + \arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted + \arg DBG_TIMER10_HOLD: hold TIMER10 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)); +} + +/*! + \brief enable trace pin assignment + \param[in] none + \param[out] none + \retval none +*/ +void dbg_trace_pin_enable(void) +{ + DBG_CTL0 |= DBG_CTL0_TRACE_IOEN; +} + +/*! + \brief disable trace pin assignment + \param[in] none + \param[out] none + \retval none +*/ +void dbg_trace_pin_disable(void) +{ + DBG_CTL0 &= ~DBG_CTL0_TRACE_IOEN; +} + diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dci.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dci.c new file mode 100644 index 000000000..2bce7696a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dci.c @@ -0,0 +1,346 @@ +/*! + \file gd32f4xx_dci.c + \brief DCI driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_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 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 << 16)); + DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height << 16)); +} + +/*! + \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 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 << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24)); +} + +/*! + \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 << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24)); +} + +/*! + \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: + \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 >> 31) { + /* 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: + \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 + \param[out] none + \retval none +*/ +void dci_interrupt_enable(uint32_t interrupt) +{ + DCI_INTEN |= interrupt; +} + +/*! + \brief disable specified DCI interrupt + \param[in] interrupt: + \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 + \param[out] none + \retval none +*/ +void dci_interrupt_disable(uint32_t interrupt) +{ + DCI_INTEN &= ~interrupt; +} + +/*! + \brief clear specified interrupt flag + \param[in] int_flag: + \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 + \param[out] none + \retval none +*/ +void dci_interrupt_flag_clear(uint32_t int_flag) +{ + DCI_INTC |= int_flag; +} + +/*! + \brief get specified interrupt flag + \param[in] int_flag: + \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 + \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; + } +} + + diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dma.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dma.c new file mode 100644 index 000000000..c5a1f9edd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_dma.c @@ -0,0 +1,904 @@ +/*! + \file gd32f4xx_dma.c + \brief DMA driver + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_dma.h" + +/* DMA register bit offset */ +#define CHXCTL_PERIEN_OFFSET ((uint32_t)25U) + +/*! + \brief deinitialize DMA a channel registers + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is deinitialized + \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 struct with the default values + \param[in] init_struct: the initialization data needed to initialize DMA channel + \param[out] none + \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->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 struct with the default values + \param[in] init_struct: the initialization data needed to initialize DMA channel + \param[out] none + \retval none +*/ +void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct *init_struct) +{ + /* set the DMA struct with the default values */ + 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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + \arg DMA_CHx(x=0..7) + \param[in] init_struct: the data needed to initialize DMA single data mode + 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 << 2) | 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_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; + } +} + +/*! + \brief initialize DMA multi data mode + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + \arg DMA_CHx(x=0..7) + \param[in] dma_multi_data_parameter_struct: the data needed to initialize DMA multi data mode + 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_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; + } +} + +/*! + \brief set DMA peripheral base address + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set peripheral base address + \arg DMA_CHx(x=0..7) + \param[in] address: peripheral base address + \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 set DMA Memory0 base address + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set Memory base address + \arg DMA_CHx(x=0..7) + \param[in] memory_flag: DMA_MEMORY_x(x=0,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 set the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..7) + \param[in] number: the number of remaining data to be transferred by the DMA + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + \arg DMA_CHx(x=0..7) + \param[out] none + \retval uint32_t: 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) +{ + return (uint32_t)DMA_CHCNT(dma_periph, channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] mbeat: 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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] pbeat: 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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] msize: transfer data size of peripheral + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data size of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data size of peripheral is 16-bit + \arg DMA_PERIPHERAL_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 generation_algorithm + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \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 DMA switch buffer mode config + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] memory1_addr: memory1 base address + \param[in] memory_select: DMA_MEMORY_0 or 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 DMA using memory get + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval the using memory +*/ +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 DMA channel peripheral select + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] sub_periph: specify DMA channel peripheral + \arg DMA_SUBPERIx(x=0..7) + \param[out] none + \retval none +*/ +void dma_channel_subperipheral_select(uint32_t dma_periph, dma_channel_enum channelx, dma_subperipheral_enum sub_periph) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PERIEN; + ctl |= ((uint32_t)sub_periph << CHXCTL_PERIEN_OFFSET); + + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief DMA flow controller configure + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] controller: specify DMA flow controler + only one parameter can be selected which is shown as below: + \arg DMA_FLOW_CONTROLLER_DMA: DMA is the flow controller + \arg DMA_FLOW_CONTROLLER_PERI: peripheral is the flow controller + \param[out] none + \retval none +*/ +void dma_flow_controller_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t controller) +{ + if(DMA_FLOW_CONTROLLER_DMA == controller) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_TFCS; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_TFCS; + } +} + +/*! + \brief DMA switch buffer mode enable + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void dma_switch_buffer_mode_enable(uint32_t dma_periph, dma_channel_enum channelx, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + /* switch buffer mode enable */ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_SBMEN; + } else { + /* switch buffer mode disable */ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_SBMEN; + } +} + +/*! + \brief DMA FIFO status get + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[out] none + \retval the using memory +*/ +uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx) +{ + return (DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FCNT); +} + +/*! + \brief get DMA flag is set or not + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + \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 a channel flag + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + \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) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] source: specify which interrupt to enbale + only one parameters can be selected which are shown as below: + \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable + \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable + \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable + \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable + \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable + \param[out] none + \retval none +*/ +void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + if(DMA_CHXFCTL_FEEIE != source) { + DMA_CHCTL(dma_periph, channelx) |= source; + } else { + DMA_CHFCTL(dma_periph, channelx) |= source; + } +} + +/*! + \brief disable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel + \arg DMA_CHx(x=0..7) + \param[in] source: specify which interrupt to disbale + only one parameters can be selected which are shown as below: + \arg DMA_CHXCTL_SDEIE: single data mode exception interrupt enable + \arg DMA_CHXCTL_TAEIE: tranfer access error interrupt enable + \arg DMA_CHXCTL_HTFIE: half transfer finish interrupt enable + \arg DMA_CHXCTL_FTFIE: full transfer finish interrupt enable + \arg DMA_CHXFCTL_FEEIE: FIFO exception interrupt enable + \param[out] none + \retval none +*/ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + if(DMA_CHXFCTL_FEEIE != source) { + DMA_CHCTL(dma_periph, channelx) &= ~source; + } else { + DMA_CHFCTL(dma_periph, channelx) &= ~source; + } +} + +/*! + \brief get DMA interrupt flag is set or not + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get interrupt flag + \arg DMA_CHx(x=0..7) + \param[in] interrupt: 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 interrupt) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + dma_channel_enum channel_flag_offset = channelx; + if(channelx < DMA_CH4) { + switch(interrupt) { + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, 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(interrupt, 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(interrupt, 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(interrupt, 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(interrupt, channelx)); + interrupt_enable = (DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE); + break; + default: + break; + } + } else { + channel_flag_offset -= (dma_channel_enum)4; + switch(interrupt) { + case DMA_INTF_FEEIF: + interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, 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(interrupt, 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(interrupt, 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(interrupt, 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(interrupt, 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 a channel interrupt flag + \param[in] dma_periph: DMAx(x=0,1) + \arg DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear interrupt flag + \arg DMA_CHx(x=0..7) + \param[in] interrupt: 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 interrupt) +{ + if(channelx < DMA_CH4) { + DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(interrupt, channelx); + } else { + channelx -= (dma_channel_enum)4; + DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(interrupt, channelx); + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_enet.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_enet.c new file mode 100644 index 000000000..20d5e8618 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_enet.c @@ -0,0 +1,3510 @@ +/*! + \file gd32f4xx_enet.c + \brief ENET driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_enet.h" + +#if defined (__CC_ARM) /*!< ARM compiler */ +__align(4) +enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM]; /*!< ENET RxDMA descriptor */ +__align(4) +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */ +__align(4) +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive buffer */ +__align(4) +uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE]; /*!< ENET transmit buffer */ + +#elif defined ( __ICCARM__ ) /*!< IAR compiler */ +#pragma data_alignment=4 +enet_descriptors_struct rxdesc_tab[ENET_RXBUF_NUM]; /*!< ENET RxDMA descriptor */ +#pragma data_alignment=4 +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM]; /*!< ENET TxDMA descriptor */ +#pragma data_alignment=4 +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE]; /*!< ENET receive buffer */ +#pragma data_alignment=4 +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__((aligned(4))); /*!< ENET RxDMA descriptor */ +enet_descriptors_struct txdesc_tab[ENET_TXBUF_NUM] __attribute__((aligned(4))); /*!< ENET TxDMA descriptor */ +uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE] __attribute__((aligned(4))); /*!< ENET receive buffer */ +uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE] __attribute__((aligned(4))); /*!< 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 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static uint32_t enet_unknow_err = 0U; +/* array of register offset for debug information get */ +static const uint16_t enet_reg_tab[] = { + 0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C, 0x0028, 0x002C, 0x0034, + 0x0038, 0x003C, 0x0040, 0x0044, 0x0048, 0x004C, 0x0050, 0x0054, 0x0058, 0x005C, 0x1080, + + 0x0100, 0x0104, 0x0108, 0x010C, 0x0110, 0x014C, 0x0150, 0x0168, 0x0194, 0x0198, 0x01C4, + + 0x0700, 0x0704, 0x0708, 0x070C, 0x0710, 0x0714, 0x0718, 0x071C, 0x0720, 0x0728, 0x072C, + + 0x1000, 0x1004, 0x1008, 0x100C, 0x1010, 0x1014, 0x1018, 0x101C, 0x1020, 0x1024, 0x1048, + 0x104C, 0x1050, 0x1054 +}; + +/* initialize ENET peripheral with generally concerned parameters, call it by enet_init() */ +static void enet_default_init(void); +#ifdef USE_DELAY +/* user can provide more timing precise _ENET_DELAY_ function */ +#define _ENET_DELAY_ delay_ms +#else +/* insert a delay time */ +static void enet_delay(uint32_t ncount); +/* default _ENET_DELAY_ function with less precise timing */ +#define _ENET_DELAY_ enet_delay +#endif + + +/*! + \brief deinitialize the ENET, and reset structure parameters for ENET initialization + \param[in] none + \param[out] none + \retval none +*/ +void enet_deinit(void) +{ + rcu_periph_reset_enable(RCU_ENETRST); + rcu_periph_reset_disable(RCU_ENETRST); + enet_initpara_reset(); +} + +/*! + \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, refer to enet_option_enum + only one parameter can be selected which is shown as below + \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] mediamode: PHY mode and mac loopback configurations, refer to enet_mediamode_enum + only one parameter can be selected which is shown as below + \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, refer to enet_mediamode_enum + only one parameter can be selected which is shown as below + \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, refer to enet_frmrecept_enum + only one parameter can be selected which is shown as below + \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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus enet_init(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 = GD_ERROR, enet_state = GD_ERROR; + + /* PHY interface configuration, configure SMI clock and reset PHY chip */ + if(GD_ERROR == enet_phy_config()) { + _ENET_DELAY_(PHY_RESETDELAY); + if(GD_ERROR == enet_phy_config()) { + return enet_state; + } + } + /* initialize ENET peripheral with generally concerned parameters */ + enet_default_init(); + + /* 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_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value); + phy_value &= PHY_LINKED_STATUS; + timeout++; + } while((RESET == phy_value) && (timeout < PHY_READ_TO)); + /* return GD_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_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); + if(!phy_state) { + /* return GD_ERROR due to write timeout */ + return enet_state; + } + + /* wait for the PHY_AUTONEGO_COMPLETE bit be set */ + do { + enet_phy_write_read(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 GD_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_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) >> 3); + phy_value |= (uint16_t)((media_temp & ENET_MAC_CFG_SPD) >> 1); + phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value); + if(!phy_state) { + /* return GD_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; + /* 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 = reg_value; + + + /* 2st, configure checksum */ + if(RESET != ((uint32_t)checksum & ENET_CHECKSUMOFFLOAD_ENABLE)) { + ENET_MAC_CFG |= ENET_CHECKSUMOFFLOAD_ENABLE; + + reg_value = ENET_DMA_CTL; + /* configure ENET_DMA_CTL register */ + reg_value &= ~ENET_DMA_CTL_DTCERFD; + reg_value |= ((uint32_t)checksum & ENET_DMA_CTL_DTCERFD); + ENET_DMA_CTL = reg_value; + } + + /* 3rd, configure recept */ + ENET_MAC_FRMF |= (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; + 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 = reg_value; + + reg_value = ENET_DMA_CTL; + 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) << 2); + reg_value |= (temp >> 2); + ENET_DMA_CTL = 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; + /* 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 = 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; + /* 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 = 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; + /* configure ENET_DMA_BCTL register */ + reg_value &= ~(ENET_DMA_BCTL_RTPR | ENET_DMA_BCTL_DAB); + reg_value |= temp; + ENET_DMA_BCTL = 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; + /* 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 = 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; + 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 = reg_value; + + reg_value = ENET_DMA_BCTL; + 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 = 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; + /* configure ENET_MAC_VLT register */ + reg_value &= ~(ENET_MAC_VLT_VLTI | ENET_MAC_VLT_VLTC); + reg_value |= reg_temp; + ENET_MAC_VLT = 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; + 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 = reg_value; + + reg_value = ENET_MAC_FCTH; + 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) << 8); + reg_value |= (temp >> 8); + ENET_MAC_FCTH = reg_value; + } + + /* configure hashtable_high related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHH_OPTION)) { + ENET_MAC_HLH = enet_initpara.hashtable_high; + } + + /* configure hashtable_low related registers */ + if(RESET != (enet_initpara.option_enable & (uint32_t)HASHL_OPTION)) { + ENET_MAC_HLL = 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; + /* 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 = 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; + /* 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 = 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; + /* configure ENET_MAC_CFG register */ + reg_value &= ~(ENET_MAC_CFG_WDD | ENET_MAC_CFG_JBD); + reg_value |= reg_temp; + ENET_MAC_CFG = 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; + /* configure ENET_MAC_CFG register */ + reg_value &= ~ENET_MAC_CFG_IGBS; + reg_value |= reg_temp; + ENET_MAC_CFG = reg_value; + } + + enet_state = GD_SUCCESS; + return enet_state; +} + +/*! + \brief reset all core internal registers located in CLK_TX and CLK_RX + \param[in] none + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_software_reset(void) +{ + uint32_t timeout = 0U; + ErrStatus enet_state = GD_ERROR; + uint32_t dma_flag; + + /* reset all core internal registers located in CLK_TX and CLK_RX */ + ENET_DMA_BCTL |= ENET_DMA_BCTL_SWR; + + /* wait for reset operation complete */ + do { + dma_flag = (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR); + timeout++; + } while((RESET != dma_flag) && (ENET_DELAY_TO != timeout)); + + /* reset operation complete */ + if(RESET == (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR)) { + enet_state = GD_SUCCESS; + } + + return enet_state; +} + +/*! + \brief check receive frame valid and return frame size + \param[in] none + \param[out] none + \retval size of received frame: 0x0 - 0x3FFF +*/ +uint32_t enet_rxframe_size_get(void) +{ + 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(); + + 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(); + + 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(); + + 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_MAC_CFG_TFCD)) && (RESET != (status & ENET_RDES0_FRMT))) { + size = size + 4U; + } + } else { + enet_unknow_err++; + enet_rxframe_drop(); + + return 1U; + } + + /* return packet size */ + return size; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in chain mode + \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(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 = (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 = (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] 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(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_DMA_BCTL_DPSL; + ENET_DMA_BCTL |= 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 = (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 = (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] 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: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_frame_receive(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 GD_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_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 GD_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 GD_ERROR */ + return GD_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_DMA_STAT_RBU)) { + /* clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 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); + } 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))); + } + } + + return GD_SUCCESS; +} + +/*! + \brief handle application buffer data to transmit it + \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: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_frame_transmit(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 GD_ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE) { + return GD_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_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { + /* clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 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); + } 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))); + } + } + + return GD_SUCCESS; +} + +/*! + \brief configure the transmit IP frame checksum offload calculation and insertion + \param[in] desc: the descriptor pointer which users want to configure, refer to enet_descriptors_struct + \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 none +*/ +void enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum) +{ + desc->status &= ~ENET_TDES0_CM; + desc->status |= checksum; +} + +/*! + \brief ENET Tx and Rx function enable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_enable(void) +{ + enet_tx_enable(); + enet_rx_enable(); +} + +/*! + \brief ENET Tx and Rx function disable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_disable(void) +{ + enet_tx_disable(); + enet_rx_disable(); +} + +/*! + \brief configure MAC address + \param[in] mac_addr: select which MAC address will be set, refer to enet_macaddress_enum + 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(enet_macaddress_enum mac_addr, uint8_t paddr[]) +{ + REG32(ENET_ADDRH_BASE + (uint32_t)mac_addr) = ENET_SET_MACADDRH(paddr); + REG32(ENET_ADDRL_BASE + (uint32_t)mac_addr) = ENET_SET_MACADDRL(paddr); +} + +/*! + \brief get MAC address + \param[in] mac_addr: select which MAC address will be get, refer to enet_macaddress_enum + 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}) + \retval none +*/ +void enet_mac_address_get(enet_macaddress_enum mac_addr, uint8_t paddr[]) +{ + paddr[0] = ENET_GET_MACADDR(mac_addr, 0U); + paddr[1] = ENET_GET_MACADDR(mac_addr, 1U); + paddr[2] = ENET_GET_MACADDR(mac_addr, 2U); + paddr[3] = ENET_GET_MACADDR(mac_addr, 3U); + paddr[4] = ENET_GET_MACADDR(mac_addr, 4U); + paddr[5] = ENET_GET_MACADDR(mac_addr, 5U); +} + +/*! + \brief get the ENET MAC/MSC/PTP/DMA status flag + \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(enet_flag_enum enet_flag) +{ + if(RESET != (ENET_REG_VAL(enet_flag) & BIT(ENET_BIT_POS(enet_flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the ENET DMA status flag + \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(enet_flag_clear_enum enet_flag) +{ + /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */ + ENET_REG_VAL(enet_flag) = BIT(ENET_BIT_POS(enet_flag)); +} + +/*! + \brief enable ENET MAC/MSC/DMA interrupt + \param[in] enet_int: ENET interrupt,, refer to enet_int_enum + 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(enet_int_enum enet_int) +{ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)) { + /* ENET_DMA_INTEN register interrupt */ + ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int)); + } else { + /* other INTMSK register interrupt */ + ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); + } +} + +/*! + \brief disable ENET MAC/MSC/DMA interrupt + \param[in] enet_int: ENET interrupt, refer to enet_int_enum + 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(enet_int_enum enet_int) +{ + if(DMA_INTEN_REG_OFFSET == ((uint32_t)enet_int >> 6)) { + /* ENET_DMA_INTEN register interrupt */ + ENET_REG_VAL(enet_int) &= ~BIT(ENET_BIT_POS(enet_int)); + } else { + /* other INTMSK register interrupt */ + ENET_REG_VAL(enet_int) |= BIT(ENET_BIT_POS(enet_int)); + } +} + +/*! + \brief get ENET MAC/MSC/DMA interrupt flag + \param[in] int_flag: ENET interrupt flag, refer to enet_int_flag_enum + 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(enet_int_flag_enum int_flag) +{ + if(RESET != (ENET_REG_VAL(int_flag) & BIT(ENET_BIT_POS(int_flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear ENET DMA interrupt flag + \param[in] int_flag_clear: clear ENET interrupt flag, refer to enet_int_flag_clear_enum + 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(enet_int_flag_clear_enum int_flag_clear) +{ + /* write 1 to the corresponding bit in ENET_DMA_STAT, to clear it */ + ENET_REG_VAL(int_flag_clear) = BIT(ENET_BIT_POS(int_flag_clear)); +} + +/*! + \brief ENET Tx function enable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_tx_enable(void) +{ + ENET_MAC_CFG |= ENET_MAC_CFG_TEN; + enet_txfifo_flush(); + ENET_DMA_CTL |= ENET_DMA_CTL_STE; +} + +/*! + \brief ENET Tx function disable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_tx_disable(void) +{ + ENET_DMA_CTL &= ~ENET_DMA_CTL_STE; + enet_txfifo_flush(); + ENET_MAC_CFG &= ~ENET_MAC_CFG_TEN; +} + +/*! + \brief ENET Rx function enable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_rx_enable(void) +{ + ENET_MAC_CFG |= ENET_MAC_CFG_REN; + ENET_DMA_CTL |= ENET_DMA_CTL_SRE; +} + +/*! + \brief ENET Rx function disable (include MAC and DMA module) + \param[in] none + \param[out] none + \retval none +*/ +void enet_rx_disable(void) +{ + ENET_DMA_CTL &= ~ENET_DMA_CTL_SRE; + ENET_MAC_CFG &= ~ENET_MAC_CFG_REN; +} + +/*! + \brief put registers value into the application buffer + \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(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) + enet_reg_tab[offset]); + preg++; + } +} + +/*! + \brief get the enet debug status from the debug register + \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 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); + break; + case ENET_RXFIFO_READ_STATUS: + temp_state = GET_MAC_DBG_RXFRS(ENET_MAC_DBG); + break; + case ENET_RXFIFO_STATE: + temp_state = GET_MAC_DBG_RXFS(ENET_MAC_DBG); + break; + case ENET_MAC_TRANSMITTER_STATUS: + temp_state = GET_MAC_DBG_SOMT(ENET_MAC_DBG); + break; + case ENET_TXFIFO_READ_STATUS: + temp_state = GET_MAC_DBG_TXFRS(ENET_MAC_DBG); + break; + default: + if(RESET != (ENET_MAC_DBG & mac_debug)) { + temp_state = 0x1U; + } + break; + } + return temp_state; +} + +/*! + \brief enable the MAC address filter + \param[in] mac_addr: select which MAC address will be enable, refer to enet_macaddress_enum + \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(enet_macaddress_enum mac_addr) +{ + REG32(ENET_ADDRH_BASE + mac_addr) |= ENET_MAC_ADDR1H_AFE; +} + +/*! + \brief disable the MAC address filter + \param[in] mac_addr: select which MAC address will be disable, refer to enet_macaddress_enum + 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(enet_macaddress_enum mac_addr) +{ + REG32(ENET_ADDRH_BASE + mac_addr) &= ~ENET_MAC_ADDR1H_AFE; +} + +/*! + \brief configure the MAC address filter + \param[in] mac_addr: select which MAC address will be configured, refer to enet_macaddress_enum + 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(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 + 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 + mac_addr) = reg; +} + +/*! + \brief PHY interface configuration (configure SMI clock and reset PHY chip) + \param[in] none + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_phy_config(void) +{ + uint32_t ahbclk; + uint32_t reg; + uint16_t phy_value; + ErrStatus enet_state = GD_ERROR; + + /* clear the previous MDC clock */ + reg = ENET_MAC_PHY_CTL; + 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, 240000000U)) || (240000000U == ahbclk)) { + reg |= ENET_MDC_HCLK_DIV102; + } else { + return enet_state; + } + ENET_MAC_PHY_CTL = reg; + + /* reset PHY */ + phy_value = PHY_RESET; + if(GD_ERROR == (enet_phy_write_read(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(GD_ERROR == (enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value))) { + return enet_state; + } + + /* PHY reset complete */ + if(RESET == (phy_value & PHY_RESET)) { + enet_state = GD_SUCCESS; + } + + return enet_state; +} + +/*! + \brief write to / read from a PHY register + \param[in] direction: only one parameter can be selected which is shown as below, refer to enet_phydirection_enum + \arg ENET_PHY_WRITE: write data to phy register + \arg ENET_PHY_READ: read data from phy register + \param[in] phy_address: 0x0000 - 0x001F + \param[in] phy_reg: 0x0000 - 0x001F + \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: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_phy_write_read(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 = GD_ERROR; + + /* configure ENET_MAC_PHY_CTL with write/read operation */ + reg = ENET_MAC_PHY_CTL; + 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 = *pvalue; + } + + /* do PHY write/read operation, and wait the operation complete */ + ENET_MAC_PHY_CTL = reg; + do { + phy_flag = (ENET_MAC_PHY_CTL & 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_MAC_PHY_CTL_PB)) { + enet_state = GD_SUCCESS; + } + + /* if do the read operation, get value from the register */ + if(ENET_PHY_READ == direction) { + *pvalue = (uint16_t)ENET_MAC_PHY_DATA; + } + + return enet_state; +} + +/*! + \brief enable the loopback function of PHY chip + \param[in] none + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus enet_phyloopback_enable(void) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = GD_ERROR; + + /* get the PHY configuration to update it */ + enet_phy_write_read(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_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + return phy_state; +} + +/*! + \brief disable the loopback function of PHY chip + \param[in] none + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus enet_phyloopback_disable(void) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = GD_ERROR; + + /* get the PHY configuration to update it */ + enet_phy_write_read(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_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &temp_phy); + + return phy_state; +} + +/*! + \brief enable ENET forward feature + \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 feature) +{ + uint32_t mask; + + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); + ENET_MAC_CFG |= mask; + + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); + ENET_DMA_CTL |= (mask >> 2); +} + +/*! + \brief disable ENET forward feature + \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 feature) +{ + uint32_t mask; + + mask = (feature & (~(ENET_FORWARD_ERRFRAMES | ENET_FORWARD_UNDERSZ_GOODFRAMES))); + ENET_MAC_CFG &= ~mask; + + mask = (feature & (~(ENET_AUTO_PADCRC_DROP | ENET_TYPEFRAME_CRC_DROP))); + ENET_DMA_CTL &= ~(mask >> 2); +} + +/*! + \brief enable ENET fliter feature + \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 feature) +{ + ENET_MAC_FRMF |= feature; +} + +/*! + \brief disable ENET fliter feature + \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 feature) +{ + ENET_MAC_FRMF &= ~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] none + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus enet_pauseframe_generate(void) +{ + ErrStatus enet_state = GD_ERROR; + uint32_t temp = 0U; + + /* in full-duplex mode, must make sure this bit is 0 before writing register */ + temp = ENET_MAC_FCTL & ENET_MAC_FCTL_FLCBBKPA; + if(RESET == temp) { + ENET_MAC_FCTL |= ENET_MAC_FCTL_FLCBBKPA; + enet_state = GD_SUCCESS; + } + return enet_state; +} + +/*! + \brief configure the pause frame detect type + \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 detect) +{ + ENET_MAC_FCTL &= ~ENET_MAC_FCTL_UPFDT; + ENET_MAC_FCTL |= detect; +} + +/*! + \brief configure the pause frame parameters + \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 pausetime, uint32_t pause_threshold) +{ + ENET_MAC_FCTL &= ~(ENET_MAC_FCTL_PTM | ENET_MAC_FCTL_PLTS); + ENET_MAC_FCTL |= (MAC_FCTL_PTM(pausetime) | pause_threshold); +} + +/*! + \brief configure the threshold of the flow control(deactive and active threshold) + \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 deactive, uint32_t active) +{ + ENET_MAC_FCTH = ((deactive | active) >> 8); +} + +/*! + \brief enable ENET flow control feature + \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 feature) +{ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)) { + ENET_MAC_FCTL &= ~ENET_ZERO_QUANTA_PAUSE; + } + feature &= ~ENET_ZERO_QUANTA_PAUSE; + ENET_MAC_FCTL |= feature; +} + +/*! + \brief disable ENET flow control feature + \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 feature) +{ + if(RESET != (feature & ENET_ZERO_QUANTA_PAUSE)) { + ENET_MAC_FCTL |= ENET_ZERO_QUANTA_PAUSE; + } + feature &= ~ENET_ZERO_QUANTA_PAUSE; + ENET_MAC_FCTL &= ~feature; +} + +/*! + \brief get the dma transmit/receive process state + \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(enet_dmadirection_enum direction) +{ + uint32_t reval; + reval = (uint32_t)(ENET_DMA_STAT & (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] 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(enet_dmadirection_enum direction) +{ + if(ENET_DMA_TX == direction) { + ENET_DMA_TPEN = 0U; + } else { + ENET_DMA_RPEN = 0U; + } +} + +/*! + \brief check and recover the Rx process + \param[in] none + \param[out] none + \retval none +*/ +void enet_rxprocess_check_recovery(void) +{ + 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 != ((uint32_t)dma_current_rxdesc)) && + (ENET_RDES0_DAV == status)) { + dma_current_rxdesc = (enet_descriptors_struct *)ENET_DMA_CRDADDR; + } +} + +/*! + \brief flush the ENET transmit FIFO, and wait until the flush operation completes + \param[in] none + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus enet_txfifo_flush(void) +{ + uint32_t flush_state; + uint32_t timeout = 0U; + ErrStatus enet_state = GD_ERROR; + + /* set the FTF bit for flushing transmit FIFO */ + ENET_DMA_CTL |= ENET_DMA_CTL_FTF; + /* wait until the flush operation completes */ + do { + flush_state = ENET_DMA_CTL & ENET_DMA_CTL_FTF; + timeout++; + } while((RESET != flush_state) && (timeout < ENET_DELAY_TO)); + /* return GD_ERROR due to timeout */ + if(RESET == flush_state) { + enet_state = GD_SUCCESS; + } + + return enet_state; +} + +/*! + \brief get the transmit/receive address of current descriptor, or current buffer, or descriptor table + \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(enet_desc_reg_enum addr_get) +{ + uint32_t reval = 0U; + + reval = REG32((ENET) + (uint32_t)addr_get); + return reval; +} + +/*! + \brief get the Tx or Rx descriptor information + \param[in] desc: the descriptor pointer which users want to get information + \param[in] info_get: the descriptor information type which is selected, refer to enet_descstate_enum + 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(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_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] none + \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 *rxfifo_drop, uint32_t *rxdma_drop) +{ + uint32_t temp_counter = 0U; + + temp_counter = ENET_DMA_MFBOCNT; + *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] desc: the descriptor pointer which users want to configure + \param[in] delay_time: delay a time of 256*delay_time HCLK(0x00000000 - 0x000000FF) + \param[out] none + \retval none +*/ +void enet_rx_desc_delay_receive_complete_interrupt(enet_descriptors_struct *desc, uint32_t delay_time) +{ + desc->control_buffer_size |= ENET_RDES1_DINTC; + ENET_DMA_RSWDC = DMA_RSWDC_WDCFRS(delay_time); +} + +/*! + \brief drop current receive frame + \param[in] none + \param[out] none + \retval none +*/ +void enet_rxframe_drop(void) +{ + /* 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); + 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)); + if(NULL != dma_current_ptp_rxdesc) { + dma_current_ptp_rxdesc++; + } + } + } +} + +/*! + \brief enable DMA feature + \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 feature) +{ + ENET_DMA_CTL |= feature; +} + +/*! + \brief disable DMA feature + \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 feature) +{ + ENET_DMA_CTL &= ~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(void) +{ + ENET_DMA_BCTL |= ENET_DMA_BCTL_DFM; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in enhanced chain mode with ptp function + \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(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 = (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 = (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] 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(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_DMA_BCTL_DPSL; + ENET_DMA_BCTL |= 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 = (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 = (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] 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: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_ptpframe_receive_enhanced_mode(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 GD_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_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 GD_ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0; offset < size; offset++) { + (*(buffer + offset)) = (*(__IO uint8_t *)((dma_current_rxdesc->buffer1_addr) + offset)); + } + } else { + return GD_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 GD_ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + return GD_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_DMA_STAT_RBU)) { + /* Clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 0; + } + + /* 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); + } 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)); + } + } + + return GD_SUCCESS; +} + +/*! + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in enhanced mode + \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: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_ptpframe_transmit_enhanced_mode(uint8_t *buffer, uint32_t length, uint32_t timestamp[]) +{ + uint32_t offset = 0; + uint32_t dma_tbu_flag, dma_tu_flag; + uint32_t tdes0_ttmss_flag; + uint32_t timeout = 0; + + /* the descriptor is busy due to own by the DMA */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)) { + return GD_ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE) { + return GD_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 = 0; 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_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { + /* Clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 0; + } + + /* 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 GD_ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + return GD_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); + } 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)); + } + } + + return GD_SUCCESS; +} + +#else + +/*! + \brief configure descriptor to work in normal mode + \param[in] none + \param[out] none + \retval none +*/ +void enet_desc_select_normal_mode(void) +{ + ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DFM; +} + +/*! + \brief initialize the DMA Tx/Rx descriptors's parameters in normal chain mode with PTP function + \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(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 = (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 = (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] 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(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_DMA_BCTL_DPSL; + ENET_DMA_BCTL |= 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 = (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 = (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] 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 + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_ptpframe_receive_normal_mode(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 GD_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_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 GD_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 GD_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_DMA_STAT_RBU)) { + /* clear RBU flag */ + ENET_DMA_STAT = ENET_DMA_STAT_RBU; + /* resume DMA reception by writing to the RPEN register*/ + ENET_DMA_RPEN = 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); + /* 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)); + dma_current_ptp_rxdesc ++; + } + } + + return GD_SUCCESS; +} + +/*! + \brief send data with timestamp values in application buffer as a transmit packet, when the DMA is in normal mode + \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: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_ptpframe_transmit_normal_mode(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 GD_ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE) { + return GD_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)0x1FFF); + /* 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_DMA_STAT_TBU); + dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU); + + if((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)) { + /* clear TBU and TU flag */ + ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag); + /* resume DMA transmission by writing to the TPEN register*/ + ENET_DMA_TPEN = 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 GD_ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + return GD_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); + /* 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)); + dma_current_ptp_txdesc ++; + } + } + return GD_SUCCESS; +} + +#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */ + +/*! + \brief wakeup frame filter register pointer reset + \param[in] none + \param[out] none + \retval none +*/ +void enet_wum_filter_register_pointer_reset(void) +{ + ENET_MAC_WUM |= ENET_MAC_WUM_WUFFRPR; +} + +/*! + \brief set the remote wakeup frame registers + \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 pdata[]) +{ + uint32_t num = 0U; + + /* configure ENET_MAC_RWFF register */ + for(num = 0U; num < ETH_WAKEUP_REGISTER_LENGTH; num++) { + ENET_MAC_RWFF = pdata[num]; + } +} + +/*! + \brief enable wakeup management features + \param[in] feature: the wake up type which is selected + 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 feature) +{ + ENET_MAC_WUM |= feature; +} + +/*! + \brief disable wakeup management features + \param[in] feature: the wake up type which is selected + 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 feature) +{ + ENET_MAC_WUM &= (~feature); +} + +/*! + \brief reset the MAC statistics counters + \param[in] none + \param[out] none + \retval none +*/ +void enet_msc_counters_reset(void) +{ + /* reset all counters */ + ENET_MSC_CTL |= ENET_MSC_CTL_CTR; +} + +/*! + \brief enable the MAC statistics counter features + \param[in] feature: the feature of MAC statistics counter + 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 feature) +{ + ENET_MSC_CTL |= feature; +} + +/*! + \brief disable the MAC statistics counter features + \param[in] feature: the feature of MAC statistics counter + 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 feature) +{ + ENET_MSC_CTL &= (~feature); +} + +/*! + \brief configure MAC statistics counters preset mode + \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(enet_msc_preset_enum mode) +{ + ENET_MSC_CTL &= ENET_MSC_PRESET_MASK; + ENET_MSC_CTL |= (uint32_t)mode; +} + +/*! + \brief get MAC statistics counter + \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(enet_msc_counter_enum counter) +{ + uint32_t reval; + + reval = REG32((ENET + (uint32_t)counter)); + + return reval; +} + +/*! + \brief enable the PTP features + \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 feature) +{ + ENET_PTP_TSCTL |= feature; +} + +/*! + \brief disable the PTP features + \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 feature) +{ + ENET_PTP_TSCTL &= ~feature; +} + +/*! + \brief configure the PTP timestamp function + \param[in] func: the function of PTP timestamp + 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: GD_SUCCESS or GD_ERROR +*/ +ErrStatus enet_ptp_timestamp_function_config(enet_ptp_function_enum func) +{ + uint32_t temp_config = 0U, temp_state = 0U; + uint32_t timeout = 0U; + ErrStatus enet_state = GD_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_PTP_TSCTL_CKNT; + ENET_PTP_TSCTL |= (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_PTP_TSCTL_TMSARU; + timeout++; + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return GD_ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + enet_state = GD_ERROR; + } else { + ENET_PTP_TSCTL |= 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_PTP_TSCTL_TMSSTU | ENET_PTP_TSCTL_TMSSTI); + timeout++; + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return GD_ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + enet_state = GD_ERROR; + } else { + ENET_PTP_TSCTL |= 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_PTP_TSCTL_TMSSTI; + timeout++; + } while((RESET != temp_state) && (timeout < ENET_DELAY_TO)); + /* return GD_ERROR due to timeout */ + if(ENET_DELAY_TO == timeout) { + enet_state = GD_ERROR; + } else { + ENET_PTP_TSCTL |= ENET_PTP_TSCTL_TMSSTI; + } + break; + default: + temp_config = (uint32_t)func & (~BIT(31)); + if(RESET != ((uint32_t)func & BIT(31))) { + ENET_PTP_TSCTL |= temp_config; + } else { + ENET_PTP_TSCTL &= ~temp_config; + } + break; + } + + return enet_state; +} + +/*! + \brief configure system time subsecond increment value + \param[in] subsecond: the value will be added to the subsecond value of system time(0x00000000 - 0x000000FF) + \param[out] none + \retval none +*/ +void enet_ptp_subsecond_increment_config(uint32_t subsecond) +{ + ENET_PTP_SSINC = PTP_SSINC_STMSSI(subsecond); +} + +/*! + \brief adjusting the clock frequency only in fine update mode + \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 add) +{ + ENET_PTP_TSADDEND = add; +} + +/*! + \brief initialize or add/subtract to second of the system time + \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 sign, uint32_t second, uint32_t subsecond) +{ + ENET_PTP_TSUH = second; + ENET_PTP_TSUL = sign | PTP_TSUL_TMSUSS(subsecond); +} + +/*! + \brief configure the expected target time + \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 second, uint32_t nanosecond) +{ + ENET_PTP_ETH = second; + ENET_PTP_ETL = nanosecond; +} + +/*! + \brief get the current system time + \param[in] none + \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 + subsecond: 0x0 - 0x7FFF FFFF + sign: ENET_PTP_TIME_POSITIVE, ENET_PTP_TIME_NEGATIVE + \retval none +*/ +void enet_ptp_system_time_get(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; + temp_subs = (uint32_t)ENET_PTP_TSL; + + /* get sysytem time and construct the enet_ptp_systime_struct structure */ + systime_struct->second = temp_sec; + systime_struct->subsecond = GET_PTP_TSL_STMSS(temp_subs); + systime_struct->sign = GET_PTP_TSL_STS(temp_subs); +} + +/*! + \brief configure the PPS output frequency + \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 freq) +{ + ENET_PTP_PPSCTL = freq; +} + +/*! + \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] none + \param[out] none + \retval none +*/ +static void enet_default_init(void) +{ + uint32_t reg_value = 0U; + + /* MAC */ + /* configure ENET_MAC_CFG register */ + reg_value = ENET_MAC_CFG; + 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 = reg_value; + + /* configure ENET_MAC_FRMF register */ + ENET_MAC_FRMF = 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 = 0x0U; + + ENET_MAC_HLL = 0x0U; + + /* configure ENET_MAC_FCTL, ENET_MAC_FCTH register */ + reg_value = ENET_MAC_FCTL; + 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 = reg_value; + + /* configure ENET_MAC_VLT register */ + ENET_MAC_VLT = ENET_VLANTAGCOMPARISON_16BIT | MAC_VLT_VLTI(0); + + /* DMA */ + /* configure ENET_DMA_CTL register */ + reg_value = ENET_DMA_CTL; + 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 = reg_value; + + /* configure ENET_DMA_BCTL register */ + reg_value = ENET_DMA_BCTL; + 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 = 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 */ diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exmc.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exmc.c new file mode 100644 index 000000000..05956722f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exmc.c @@ -0,0 +1,1252 @@ +/*! + \file gd32f4xx_exmc.c + \brief EXMC driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx + \version 2022-06-08, V3.0.1, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_exmc.h" + +/* EXMC bank0 register reset value */ +#define BANK0_SNCTL_RESET ((uint32_t)0x000030DAU) +#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU) +#define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU) + +/* EXMC bank1/2 register reset mask */ +#define BANK1_2_NPCTL_RESET ((uint32_t)0x00000008U) +#define BANK1_2_NPINTEN_RESET ((uint32_t)0x00000042U) +#define BANK1_2_NPCTCFG_RESET ((uint32_t)0xFFFFFFFFU) +#define BANK1_2_NPATCFG_RESET ((uint32_t)0xFFFFFFFFU) + +/* EXMC bank3 register reset mask */ +#define BANK3_NPCTL_RESET ((uint32_t)0x00000008U) +#define BANK3_NPINTEN_RESET ((uint32_t)0x00000040U) +#define BANK3_NPCTCFG_RESET ((uint32_t)0xFFFFFFFFU) +#define BANK3_NPATCFG_RESET ((uint32_t)0xFFFFFFFFU) +#define BANK3_PIOTCFG3_RESET ((uint32_t)0xFFFFFFFFU) + +/* EXMC SDRAM device register reset mask */ +#define SDRAM_DEVICE_SDCTL_RESET ((uint32_t)0x000002D0U) +#define SDRAM_DEVICE_SDTCFG_RESET ((uint32_t)0x0FFFFFFFU) +#define SDRAM_DEVICE_SDCMD_RESET ((uint32_t)0x00000000U) +#define SDRAM_DEVICE_SDARI_RESET ((uint32_t)0x00000000U) +#define SDRAM_DEVICE_SDSTAT_RESET ((uint32_t)0x00000000U) +#define SDRAM_DEVICE_SDRSCTL_RESET ((uint32_t)0x00000000U) + +/* EXMC bank0 SQPI-PSRAM register reset mask */ +#define BANK0_SQPI_SINIT_RESET ((uint32_t)0x18010000U) +#define BANK0_SQPI_SRCMD_RESET ((uint32_t)0x00000000U) +#define BANK0_SQPI_SWCMD_RESET ((uint32_t)0x00000000U) +#define BANK0_SQPI_SIDL_RESET ((uint32_t)0x00000000U) +#define BANK0_SQPI_SIDH_RESET ((uint32_t)0x00000000U) + +/* EXMC register bit offset */ +#define SNCTL_NRMUX_OFFSET ((uint32_t)1U) +#define SNCTL_SBRSTEN_OFFSET ((uint32_t)8U) +#define SNCTL_WRAPEN_OFFSET ((uint32_t)10U) +#define SNCTL_WREN_OFFSET ((uint32_t)12U) +#define SNCTL_NRWTEN_OFFSET ((uint32_t)13U) +#define SNCTL_EXMODEN_OFFSET ((uint32_t)14U) +#define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U) + +#define SNTCFG_AHLD_OFFSET ((uint32_t)4U) +#define SNTCFG_DSET_OFFSET ((uint32_t)8U) +#define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U) + +#define NPCTL_NDWTEN_OFFSET ((uint32_t)1U) +#define NPCTL_ECCEN_OFFSET ((uint32_t)6U) + +#define NPCTCFG_COMWAIT_OFFSET ((uint32_t)8U) +#define NPCTCFG_COMHLD_OFFSET ((uint32_t)16U) +#define NPCTCFG_COMHIZ_OFFSET ((uint32_t)24U) + +#define NPATCFG_ATTWAIT_OFFSET ((uint32_t)8U) +#define NPATCFG_ATTHLD_OFFSET ((uint32_t)16U) +#define NPATCFG_ATTHIZ_OFFSET ((uint32_t)24U) + +#define PIOTCFG_IOWAIT_OFFSET ((uint32_t)8U) +#define PIOTCFG_IOHLD_OFFSET ((uint32_t)16U) +#define PIOTCFG_IOHIZ_OFFSET ((uint32_t)24U) + +#define SDCTL_WPEN_OFFSET ((uint32_t)9U) +#define SDCTL_BRSTRD_OFFSET ((uint32_t)12U) + +#define SDTCFG_XSRD_OFFSET ((uint32_t)4U) +#define SDTCFG_RASD_OFFSET ((uint32_t)8U) +#define SDTCFG_ARFD_OFFSET ((uint32_t)12U) +#define SDTCFG_WRD_OFFSET ((uint32_t)16U) +#define SDTCFG_RPD_OFFSET ((uint32_t)20U) +#define SDTCFG_RCD_OFFSET ((uint32_t)24U) + +#define SDCMD_NARF_OFFSET ((uint32_t)5U) +#define SDCMD_MRC_OFFSET ((uint32_t)9U) + +#define SDARI_ARINTV_OFFSET ((uint32_t)1U) + +#define SDSTAT_STA0_OFFSET ((uint32_t)1U) +#define SDSTAT_STA1_OFFSET ((uint32_t)3U) + +#define SRCMD_RWAITCYCLE_OFFSET ((uint32_t)16U) +#define SWCMD_WWAITCYCLE_OFFSET ((uint32_t)16U) + +#define INTEN_INTS_OFFSET ((uint32_t)3U) + +/*! + \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) + \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 the structure 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->wrap_burst_mode = DISABLE; + 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->write_mode = EXMC_ASYN_WRITE; + + /* configure read/write timing */ + exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU; + exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU; + exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU; + exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU; + exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK; + exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK; + exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A; + + /* configure write timing, when extended mode is used */ + exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU; + exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU; + exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU; + exmc_norsram_init_struct->write_timing->bus_latency = 0xFU; + exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A; +} + +/*! + \brief initialize EXMC NOR/SRAM region + \param[in] exmc_norsram_parameter_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 + wrap_burst_mode: ENABLE or DISABLE + 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 + 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_DISABLE, EXMC_SYN_CLOCK_RATIO_x_CLK, x=2..16 + bus_latency: 0x0U~0xFU + asyn_data_setuptime: 0x01U~0xFFU + asyn_address_holdtime: 0x1U~0xFU + asyn_address_setuptime: 0x0U~0xFU + 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: 0x01U~0xFFU + asyn_address_holdtime: 0x1U~0xFU + asyn_address_setuptime: 0x0U~0xFU + \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 the register value */ + snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region); + + /* clear relative bits */ + snctl &= ((uint32_t)~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN | + EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WEN | + EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWTEN | EXMC_SNCTL_SYNCWR | + EXMC_SNCTL_NRMUX)); + + /* 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->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) | + 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_ASYNCWAIT_OFFSET) | + exmc_norsram_init_struct->write_mode; + + /* 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; + + /* enable nor flash access */ + if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type) { + snctl |= (uint32_t)EXMC_SNCTL_NREN; + } + + /* configure extended mode */ + if(ENABLE == exmc_norsram_init_struct->extended_mode) { + 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) + \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) + \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] exmc_nand_bank: select the bank of NAND + only one parameter can be selected which is shown as below: + \arg EXMC_BANKx_NAND(x=1..2) + \param[out] none + \retval none +*/ +void exmc_nand_deinit(uint32_t exmc_nand_bank) +{ + /* EXMC_BANK1_NAND or EXMC_BANK2_NAND */ + EXMC_NPCTL(exmc_nand_bank) = BANK1_2_NPCTL_RESET; + EXMC_NPINTEN(exmc_nand_bank) = BANK1_2_NPINTEN_RESET; + EXMC_NPCTCFG(exmc_nand_bank) = BANK1_2_NPCTCFG_RESET; + EXMC_NPATCFG(exmc_nand_bank) = BANK1_2_NPATCFG_RESET; +} + +/*! + \brief initialize exmc_norsram_parameter_struct with the default values + \param[in] none + \param[out] the initialized struct exmc_norsram_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->nand_bank = EXMC_BANK1_NAND; + 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 = 0x0U; + exmc_nand_init_struct->atr_latency = 0x0U; + exmc_nand_init_struct->common_space_timing->setuptime = 0xFCU; + exmc_nand_init_struct->common_space_timing->waittime = 0xFCU; + exmc_nand_init_struct->common_space_timing->holdtime = 0xFCU; + exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xFCU; + exmc_nand_init_struct->attribute_space_timing->setuptime = 0xFCU; + exmc_nand_init_struct->attribute_space_timing->waittime = 0xFCU; + exmc_nand_init_struct->attribute_space_timing->holdtime = 0xFCU; + exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xFCU; +} + +/*! + \brief initialize EXMC NAND bank + \param[in] exmc_nand_parameter_struct: configure the EXMC NAND parameter + nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND + ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096 + atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16 + ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16 + ecc_logic: ENABLE or DISABLE + databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B + wait_feature: ENABLE or DISABLE + common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + databus_hiztime: 0x01U~0xFFU + holdtime: 0x01U~0xFEU + waittime: 0x02U~0xFFU + setuptime: 0x01U~0xFFU + attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + databus_hiztime: 0x00U~0xFEU + holdtime: 0x01U~0xFEU + waittime: 0x02U~0xFFU + setuptime: 0x01U~0xFFU + \param[out] none + \retval none +*/ +void exmc_nand_init(exmc_nand_parameter_struct *exmc_nand_init_struct) +{ + uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U; + + npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) | + EXMC_NPCTL_NDTP | + exmc_nand_init_struct->databus_width | + (exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET) | + exmc_nand_init_struct->ecc_size | + exmc_nand_init_struct->ctr_latency | + exmc_nand_init_struct->atr_latency; + + npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET) | + (((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT) | + ((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD) | + (((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ); + + npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET) | + (((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT) | + ((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD) | + ((exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ); + + /* initialize EXMC_BANK1_NAND or EXMC_BANK2_NAND */ + EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl; + EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg; + EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg; +} + +/*! + \brief enable NAND bank + \param[in] exmc_nand_bank: specify the NAND bank + only one parameter can be selected which is shown as below: + \arg EXMC_BANKx_NAND(x=1,2) + \param[out] none + \retval none +*/ +void exmc_nand_enable(uint32_t exmc_nand_bank) +{ + EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_NDBKEN; +} + +/*! + \brief disable NAND bank + \param[in] exmc_nand_bank: specify the NAND bank + only one parameter can be selected which is shown as below: + \arg EXMC_BANKx_NAND(x=1,2) + \param[out] none + \retval none +*/ +void exmc_nand_disable(uint32_t exmc_nand_bank) +{ + EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_NDBKEN; +} + +/*! + \brief deinitialize EXMC PC card bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_pccard_deinit(void) +{ + /* EXMC_BANK3_PCCARD */ + EXMC_NPCTL3 = BANK3_NPCTL_RESET; + EXMC_NPINTEN3 = BANK3_NPINTEN_RESET; + EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET; + EXMC_NPATCFG3 = BANK3_NPATCFG_RESET; + EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET; +} + +/*! + \brief initialize exmc_pccard_parameter_struct with the default values + \param[in] none + \param[out] the initialized struct exmc_pccard_parameter_struct pointer + \retval none +*/ +void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct *exmc_pccard_init_struct) +{ + /* configure the structure with default values */ + exmc_pccard_init_struct->wait_feature = DISABLE; + exmc_pccard_init_struct->ctr_latency = 0x0U; + exmc_pccard_init_struct->atr_latency = 0x0U; + exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU; + exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU; + exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU; + exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU; + exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU; + exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU; +} + +/*! + \brief initialize EXMC PC card bank + \param[in] exmc_pccard_parameter_struct: configure the EXMC NAND parameter + atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16 + ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16 + wait_feature: ENABLE or DISABLE + common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + databus_hiztime: 0x01U~0xFFU + holdtime: 0x01U~0xFEU + waittime: 0x02U~0xFFU + setuptime: 0x01U~0xFFU + attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time + databus_hiztime: 0x00U~0xFEU + holdtime: 0x01U~0xFEU + waittime: 0x02U~0xFFU + setuptime: 0x01U~0xFFU + io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time + databus_hiztime: 0x00U~0xFFU + holdtime: 0x01U~0xFFU + waittime: 0x02U~0x100U + setuptime: 0x01U~0x100U + \param[out] none + \retval none +*/ +void exmc_pccard_init(exmc_pccard_parameter_struct *exmc_pccard_init_struct) +{ + /* configure the EXMC bank3 PC card control register */ + EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) | + EXMC_NAND_DATABUS_WIDTH_16B | + exmc_pccard_init_struct->ctr_latency | + exmc_pccard_init_struct->atr_latency ; + + /* configure the EXMC bank3 PC card common space timing configuration register */ + EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET) | + (((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT) | + ((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD) | + (((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ); + + /* configure the EXMC bank3 PC card attribute space timing configuration register */ + EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET) | + (((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT) | + ((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD) | + ((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ); + + /* configure the EXMC bank3 PC card io space timing configuration register */ + EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET) | + (((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT) | + ((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD) | + ((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ); +} + +/*! + \brief enable PC Card Bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_pccard_enable(void) +{ + EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN; +} + +/*! + \brief disable PC Card Bank + \param[in] none + \param[out] none + \retval none +*/ +void exmc_pccard_disable(void) +{ + EXMC_NPCTL3 &= ~EXMC_NPCTL_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_pccard_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_HCLK; + + exmc_sdram_init_struct->timing->load_mode_register_delay = 16U; + exmc_sdram_init_struct->timing->exit_selfrefresh_delay = 16U; + exmc_sdram_init_struct->timing->row_address_select_delay = 16U; + exmc_sdram_init_struct->timing->auto_refresh_delay = 16U; + exmc_sdram_init_struct->timing->write_recovery_delay = 16U; + exmc_sdram_init_struct->timing->row_precharge_delay = 16U; + exmc_sdram_init_struct->timing->row_to_column_delay = 16U; +} + +/*! + \brief initialize EXMC SDRAM device + \param[in] exmc_sdram_parameter_struct: configure the EXMC SDRAM parameter + sdram_device: EXMC_SDRAM_DEVICE0,EXMC_SDRAM_DEVICE1 + pipeline_read_delay: EXMC_PIPELINE_DELAY_x_HCLK,x=0..2 + burst_read_switch: ENABLE or DISABLE + sdclock_config: EXMC_SDCLK_DISABLE,EXMC_SDCLK_PERIODS_2_HCLK,EXMC_SDCLK_PERIODS_3_HCLK + 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: 1U~16U + row_precharge_delay: 1U~16U + write_recovery_delay: 1U~16U + auto_refresh_delay: 1U~16U + row_address_select_delay: 1U~16U + exit_selfrefresh_delay: 1U~16U + load_mode_register_delay: 1U~16U + \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)); + + 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 initialize exmc_sdram_struct_command_para_init with the default values + \param[in] none + \param[out] the initialized struct exmc_sdram_struct_command_para_init pointer + \retval none +*/ +void exmc_sdram_struct_command_para_init(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct) +{ + /* configure the structure with default value */ + exmc_sdram_command_init_struct->mode_register_content = 0U; + exmc_sdram_command_init_struct->auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_1_SDCLK; + exmc_sdram_command_init_struct->bank_select = EXMC_SDRAM_DEVICE0_SELECT; + exmc_sdram_command_init_struct->command = EXMC_SDRAM_NORMAL_OPERATION; +} + +/*! + \brief deinitialize exmc SQPIPSRAM + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sqpipsram_deinit(void) +{ + /* reset the registers */ + EXMC_SINIT = BANK0_SQPI_SINIT_RESET; + EXMC_SRCMD = BANK0_SQPI_SRCMD_RESET; + EXMC_SWCMD = BANK0_SQPI_SWCMD_RESET; + EXMC_SIDL = BANK0_SQPI_SIDL_RESET; + EXMC_SIDH = BANK0_SQPI_SIDH_RESET; +} + +/*! + \brief initialize exmc_sqpipsram_parameter_struct with the default values + \param[in] the struct exmc_sqpipsram_parameter_struct pointer + \param[out] none + \retval none +*/ +void exmc_sqpipsram_struct_para_init(exmc_sqpipsram_parameter_struct *exmc_sqpipsram_init_struct) +{ + /* configure the structure with default values */ + exmc_sqpipsram_init_struct->sample_polarity = EXMC_SQPIPSRAM_SAMPLE_RISING_EDGE; + exmc_sqpipsram_init_struct->id_length = EXMC_SQPIPSRAM_ID_LENGTH_64B; + exmc_sqpipsram_init_struct->address_bits = EXMC_SQPIPSRAM_ADDR_LENGTH_24B; + exmc_sqpipsram_init_struct->command_bits = EXMC_SQPIPSRAM_COMMAND_LENGTH_8B; +} + +/*! + \brief initialize EXMC SQPIPSRAM + \param[in] exmc_sqpipsram_parameter_struct: configure the EXMC SQPIPSRAM parameter + sample_polarity: EXMC_SQPIPSRAM_SAMPLE_RISING_EDGE,EXMC_SQPIPSRAM_SAMPLE_FALLING_EDGE + id_length: EXMC_SQPIPSRAM_ID_LENGTH_xB,x=8,16,32,64 + address_bits: EXMC_SQPIPSRAM_ADDR_LENGTH_xB,x=1..26 + command_bits: EXMC_SQPIPSRAM_COMMAND_LENGTH_xB,x=4,8,16 + \param[out] none + \retval none +*/ +void exmc_sqpipsram_init(exmc_sqpipsram_parameter_struct *exmc_sqpipsram_init_struct) +{ + /* initialize SQPI controller */ + EXMC_SINIT = (uint32_t)exmc_sqpipsram_init_struct->sample_polarity | + exmc_sqpipsram_init_struct->id_length | + exmc_sqpipsram_init_struct->address_bits | + exmc_sqpipsram_init_struct->command_bits; +} + +/*! + \brief configure consecutive clock + \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; + + /* set the CPS bits */ + EXMC_SNCTL(exmc_norsram_region) |= page_size; +} + +/*! + \brief enable or disable the EXMC NAND ECC function + \param[in] exmc_nand_bank: specify the NAND bank + only one parameter can be selected which is shown as below: + \arg EXMC_BANKx_NAND(x=1,2) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void exmc_nand_ecc_config(uint32_t exmc_nand_bank, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + /* enable the selected NAND bank ECC function */ + EXMC_NPCTL(exmc_nand_bank) |= EXMC_NPCTL_ECCEN; + } else { + /* disable the selected NAND bank ECC function */ + EXMC_NPCTL(exmc_nand_bank) &= ~EXMC_NPCTL_ECCEN; + } +} + +/*! + \brief get the EXMC ECC value + \param[in] exmc_nand_bank: specify the NAND bank + only one parameter can be selected which is shown as below: + \arg EXMC_BANKx_NAND(x=1,2) + \param[out] none + \retval the error correction code(ECC) value +*/ +uint32_t exmc_ecc_get(uint32_t exmc_nand_bank) +{ + return(EXMC_NECC(exmc_nand_bank)); +} + +/*! + \brief enable or disable read sample + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void exmc_sdram_readsample_enable(ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + EXMC_SDRSCTL |= EXMC_SDRSCTL_RSEN; + } else { + 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_hclk: sample cycle of read data + only one parameter can be selected which is shown as below: + \arg EXMC_SDRAM_READSAMPLE_x_EXTRAHCLK(x=0,1) + \param[out] none + \retval none +*/ +void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_hclk) +{ + 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_hclk); + 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, 0x0000~0x1FFF + \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 set the read command + \param[in] read_command_mode: configure SPI PSRAM read command mode + only one parameter can be selected which is shown as below: + \arg EXMC_SQPIPSRAM_READ_MODE_DISABLE: not SPI mode + \arg EXMC_SQPIPSRAM_READ_MODE_SPI: SPI mode + \arg EXMC_SQPIPSRAM_READ_MODE_SQPI: SQPI mode + \arg EXMC_SQPIPSRAM_READ_MODE_QPI: QPI mode + \param[in] read_wait_cycle: wait cycle number after address phase,0..15 + \param[in] read_command_code: read command for AHB read transfer + \param[out] none + \retval none +*/ +void exmc_sqpipsram_read_command_set(uint32_t read_command_mode, uint32_t read_wait_cycle, uint32_t read_command_code) +{ + uint32_t srcmd; + + srcmd = (uint32_t) read_command_mode | + ((read_wait_cycle << SRCMD_RWAITCYCLE_OFFSET) & EXMC_SRCMD_RWAITCYCLE) | + ((read_command_code & EXMC_SRCMD_RCMD)); + EXMC_SRCMD = srcmd; +} + +/*! + \brief set the write command + \param[in] write_command_mode: configure SPI PSRAM write command mode + only one parameter can be selected which is shown as below: + \arg EXMC_SQPIPSRAM_WRITE_MODE_DISABLE: not SPI mode + \arg EXMC_SQPIPSRAM_WRITE_MODE_SPI: SPI mode + \arg EXMC_SQPIPSRAM_WRITE_MODE_SQPI: SQPI mode + \arg EXMC_SQPIPSRAM_WRITE_MODE_QPI: QPI mode + \param[in] write_wait_cycle: wait cycle number after address phase,0..15 + \param[in] write_command_code: read command for AHB read transfer + \param[out] none + \retval none +*/ +void exmc_sqpipsram_write_command_set(uint32_t write_command_mode, uint32_t write_wait_cycle, uint32_t write_command_code) +{ + uint32_t swcmd; + + swcmd = (uint32_t) write_command_mode | + ((write_wait_cycle << SWCMD_WWAITCYCLE_OFFSET) & EXMC_SWCMD_WWAITCYCLE) | + ((write_command_code & EXMC_SWCMD_WCMD)); + EXMC_SWCMD = swcmd; +} + +/*! + \brief send SPI read ID command + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sqpipsram_read_id_command_send(void) +{ + EXMC_SRCMD |= EXMC_SRCMD_RDID; +} + +/*! + \brief send SPI special command which does not have address and data phase + \param[in] none + \param[out] none + \retval none +*/ +void exmc_sqpipsram_write_cmd_send(void) +{ + EXMC_SWCMD |= EXMC_SWCMD_SC; +} + +/*! + \brief get the EXMC SPI ID low data + \param[in] none + \param[out] none + \retval the ID low data +*/ +uint32_t exmc_sqpipsram_low_id_get(void) +{ + return (EXMC_SIDL); +} + +/*! + \brief get the EXMC SPI ID high data + \param[in] none + \param[out] none + \retval the ID high data +*/ +uint32_t exmc_sqpipsram_high_id_get(void) +{ + return (EXMC_SIDH); +} + +/*! + \brief get the bit value of EXMC send write command bit or read ID command + \param[in] send_command_flag: the send command flag + only one parameter can be selected which is shown as below: + \arg EXMC_SEND_COMMAND_FLAG_RDID: EXMC_SRCMD_RDID flag bit + \arg EXMC_SEND_COMMAND_FLAG_SC: EXMC_SWCMD_SC flag bit + \param[out] none + \retval the new value of send command flag +*/ +FlagStatus exmc_sqpipsram_send_command_state_get(uint32_t send_command_flag) +{ + uint32_t flag = 0x00000000U; + + if(EXMC_SEND_COMMAND_FLAG_RDID == send_command_flag) { + flag = EXMC_SRCMD; + } else if(EXMC_SEND_COMMAND_FLAG_SC == send_command_flag) { + flag = EXMC_SWCMD; + } else { + } + + if(flag & send_command_flag) { + /* flag is set */ + return SET; + } else { + /* flag is reset */ + return RESET; + } +} + +/*! + \brief enable EXMC interrupt + \param[in] exmc_bank: specify the NAND bank,PC card bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt: specify EXMC interrupt flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag + \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag + \arg EXMC_NAND_PCCARD_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_enable(uint32_t exmc_bank, uint32_t interrupt) +{ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) |= interrupt; + } else { + /* SDRAM device0 or device1 */ + EXMC_SDARI |= EXMC_SDARI_REIE; + } +} + +/*! + \brief disable EXMC interrupt + \param[in] exmc_bank: specify the NAND bank , PC card bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \arg EXMC_SDRAM_DEVICE0: the SDRAM device0 + \arg EXMC_SDRAM_DEVICE1: the SDRAM device1 + \param[in] interrupt: specify EXMC interrupt flag + only one parameter can be selected which is shown as below: + \arg EXMC_NAND_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag + \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag + \arg EXMC_NAND_PCCARD_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_disable(uint32_t exmc_bank, uint32_t interrupt) +{ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) &= ~interrupt; + } else { + /* SDRAM device0 or device1 */ + EXMC_SDARI &= ~EXMC_SDARI_REIE; + } +} + +/*! + \brief get EXMC flag status + \param[in] exmc_bank: specify the NAND bank , PC card bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC Card bank + \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_PCCARD_FLAG_RISE: interrupt rising edge status + \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status + \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status + \arg EXMC_NAND_PCCARD_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_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { + /* NAND bank1,bank2 or PC card bank3 */ + status = EXMC_NPINTEN(exmc_bank); + } 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 , PCCARD bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \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_PCCARD_FLAG_RISE: interrupt rising edge status + \arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status + \arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status + \arg EXMC_NAND_PCCARD_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 none +*/ +void exmc_flag_clear(uint32_t exmc_bank, uint32_t flag) +{ + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) &= ~flag; + } else { + /* SDRAM device0 or device1 */ + EXMC_SDSTAT &= ~flag; + } +} + +/*! + \brief get EXMC interrupt flag + \param[in] exmc_bank: specify the NAND bank , PC card bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \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_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag + \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag + \arg EXMC_NAND_PCCARD_INT_FLAG_FALL: falling edge interrupt and 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 status = 0x00000000U, interrupt_enable = 0x00000000U, interrupt_state = 0x00000000U; + + if((EXMC_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { + /* NAND bank1,bank2 or PC card bank3 */ + status = EXMC_NPINTEN(exmc_bank); + interrupt_state = (status & (interrupt >> INTEN_INTS_OFFSET)); + } else { + /* SDRAM device0 or device1 */ + status = EXMC_SDARI; + interrupt_state = (EXMC_SDSTAT & EXMC_SDSDAT_REIF); + } + + interrupt_enable = (status & interrupt); + + if((interrupt_enable) && (interrupt_state)) { + /* 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 , PC card bank or SDRAM device + only one parameter can be selected which is shown as below: + \arg EXMC_BANK1_NAND: the NAND bank1 + \arg EXMC_BANK2_NAND: the NAND bank2 + \arg EXMC_BANK3_PCCARD: the PC card bank + \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_PCCARD_INT_FLAG_RISE: rising edge interrupt and flag + \arg EXMC_NAND_PCCARD_INT_FLAG_LEVEL: high-level interrupt and flag + \arg EXMC_NAND_PCCARD_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_BANK1_NAND == exmc_bank) || (EXMC_BANK2_NAND == exmc_bank) || (EXMC_BANK3_PCCARD == exmc_bank)) { + /* NAND bank1,bank2 or PC card bank3 */ + EXMC_NPINTEN(exmc_bank) &= ~(interrupt >> INTEN_INTS_OFFSET); + } else { + /* SDRAM device0 or device1 */ + EXMC_SDARI |= EXMC_SDARI_REC; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exti.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exti.c new file mode 100644 index 000000000..ba1cbff4c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_exti.c @@ -0,0 +1,253 @@ +/*! + \file gd32f4xx_exti.c + \brief EXTI driver + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_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_INTEN = EXTI_REG_RESET_VALUE; + EXTI_EVEN = EXTI_REG_RESET_VALUE; + EXTI_RTEN = EXTI_REG_RESET_VALUE; + EXTI_FTEN = EXTI_REG_RESET_VALUE; + EXTI_SWIEV = 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..22): 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 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 &= ~(uint32_t)linex; + EXTI_EVEN &= ~(uint32_t)linex; + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + + /* set the EXTI mode and enable the interrupts or events from EXTI line x */ + switch(mode) { + case EXTI_INTERRUPT: + EXTI_INTEN |= (uint32_t)linex; + break; + case EXTI_EVENT: + EXTI_EVEN |= (uint32_t)linex; + break; + default: + break; + } + + /* set the EXTI trigger type */ + switch(trig_type) { + case EXTI_TRIG_RISING: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + break; + case EXTI_TRIG_FALLING: + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN |= (uint32_t)linex; + break; + case EXTI_TRIG_BOTH: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN |= (uint32_t)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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_enable(exti_line_enum linex) +{ + EXTI_INTEN |= (uint32_t)linex; +} + +/*! + \brief disable the interrupt 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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(uint32_t)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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (uint32_t)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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t)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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_enable(exti_line_enum linex) +{ + EXTI_SWIEV |= (uint32_t)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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t)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..22): 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 & (uint32_t)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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)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..22): 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 & (uint32_t)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..22): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fmc.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fmc.c new file mode 100644 index 000000000..34227734a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fmc.c @@ -0,0 +1,1048 @@ +/*! + \file gd32f4xx_fmc.c + \brief FMC driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_fmc.h" + +/*! + \brief set the FMC wait state counter + \param[in] wscnt: wait state counter value + only one parameter can be selected which is shown as below: + \arg WS_WSCNT_0: FMC 0 wait + \arg WS_WSCNT_1: FMC 1 wait + \arg WS_WSCNT_2: FMC 2 wait + \arg WS_WSCNT_3: FMC 3 wait + \arg WS_WSCNT_4: FMC 4 wait + \arg WS_WSCNT_5: FMC 5 wait + \arg WS_WSCNT_6: FMC 6 wait + \arg WS_WSCNT_7: FMC 7 wait + \arg WS_WSCNT_8: FMC 8 wait + \arg WS_WSCNT_9: FMC 9 wait + \arg WS_WSCNT_10: FMC 10 wait + \arg WS_WSCNT_11: FMC 11 wait + \arg WS_WSCNT_12: FMC 12 wait + \arg WS_WSCNT_13: FMC 13 wait + \arg WS_WSCNT_14: FMC 14 wait + \arg WS_WSCNT_15: FMC 15 wait + \param[out] none + \retval none +*/ +void fmc_wscnt_set(uint32_t wscnt) +{ + uint32_t reg; + + reg = FMC_WS; + /* set the wait state counter value */ + reg &= ~FMC_WC_WSCNT; + FMC_WS = (reg | wscnt); +} + +/*! + \brief unlock the main FMC operation + \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 the main FMC operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit*/ + FMC_CTL |= FMC_CTL_LK; +} + +#if defined (GD32F425) || defined (GD32F427) || defined (GD32F470) + +/*! + \brief FMC erase page + \param[in] page_addr: the page address to be erased. + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_page_erase(uint32_t page_addr) +{ + 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) { + /* unlock page erase operation */ + FMC_PEKEY = UNLOCK_PE_KEY; + + /* start page erase */ + FMC_PECFG = FMC_PE_EN | page_addr; + FMC_CTL &= ~FMC_CTL_SN; + FMC_CTL |= FMC_CTL_SER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + FMC_PECFG &= ~FMC_PE_EN; + FMC_CTL &= ~FMC_CTL_SER; + } + + /* return the FMC state */ + return fmc_state; +} + +#endif + +/*! + \brief FMC erase sector + \param[in] fmc_sector: select the sector to erase + only one parameter can be selected which is shown as below: + \arg CTL_SECTOR_NUMBER_0: sector 0 + \arg CTL_SECTOR_NUMBER_1: sector 1 + \arg CTL_SECTOR_NUMBER_2: sector 2 + \arg CTL_SECTOR_NUMBER_3: sector 3 + \arg CTL_SECTOR_NUMBER_4: sector 4 + \arg CTL_SECTOR_NUMBER_5: sector 5 + \arg CTL_SECTOR_NUMBER_6: sector 6 + \arg CTL_SECTOR_NUMBER_7: sector 7 + \arg CTL_SECTOR_NUMBER_8: sector 8 + \arg CTL_SECTOR_NUMBER_9: sector 9 + \arg CTL_SECTOR_NUMBER_10: sector 10 + \arg CTL_SECTOR_NUMBER_11: sector 11 + \arg CTL_SECTOR_NUMBER_12: sector 12 + \arg CTL_SECTOR_NUMBER_13: sector 13 + \arg CTL_SECTOR_NUMBER_14: sector 14 + \arg CTL_SECTOR_NUMBER_15: sector 15 + \arg CTL_SECTOR_NUMBER_16: sector 16 + \arg CTL_SECTOR_NUMBER_17: sector 17 + \arg CTL_SECTOR_NUMBER_18: sector 18 + \arg CTL_SECTOR_NUMBER_19: sector 19 + \arg CTL_SECTOR_NUMBER_20: sector 20 + \arg CTL_SECTOR_NUMBER_21: sector 21 + \arg CTL_SECTOR_NUMBER_22: sector 22 + \arg CTL_SECTOR_NUMBER_23: sector 23 + \arg CTL_SECTOR_NUMBER_24: sector 24 + \arg CTL_SECTOR_NUMBER_25: sector 25 + \arg CTL_SECTOR_NUMBER_26: sector 26 + \arg CTL_SECTOR_NUMBER_27: sector 27 + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_sector_erase(uint32_t fmc_sector) +{ + 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) { + /* start sector erase */ + FMC_CTL &= ~FMC_CTL_SN; + FMC_CTL |= (FMC_CTL_SER | fmc_sector); + 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); + FMC_CTL &= ~FMC_CTL_SN; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief FMC erase whole chip + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_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) { + /* start whole chip erase */ + FMC_CTL |= (FMC_CTL_MER0 | FMC_CTL_MER1); + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bits */ + FMC_CTL &= ~(FMC_CTL_MER0 | FMC_CTL_MER1); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief FMC erase whole bank0 + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_bank0_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) { + /* start FMC bank0 erase */ + FMC_CTL |= FMC_CTL_MER0; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER0 bit */ + FMC_CTL &= (~FMC_CTL_MER0); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief FMC erase whole bank1 + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_bank1_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) { + /* start FMC bank1 erase */ + FMC_CTL |= FMC_CTL_MER1; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER1 bit */ + FMC_CTL &= (~FMC_CTL_MER1); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a word at the corresponding address + \param[in] address: address to program + \param[in] data: word to program(0x00000000 - 0xFFFFFFFF) + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation 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_PSZ; + FMC_CTL |= CTL_PSZ_WORD; + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + + /* 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 program a half word at the corresponding address + \param[in] address: address to program + \param[in] data: halfword to program(0x0000 - 0xFFFF) + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_halfword_program(uint32_t address, uint16_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_PSZ; + FMC_CTL |= CTL_PSZ_HALF_WORD; + FMC_CTL |= FMC_CTL_PG; + + REG16(address) = data; + + /* 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 program a byte at the corresponding address + \param[in] address: address to program + \param[in] data: byte to program(0x00 - 0xFF) + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_byte_program(uint32_t address, uint8_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_PSZ; + FMC_CTL |= CTL_PSZ_BYTE; + FMC_CTL |= FMC_CTL_PG; + + REG8(address) = data; + + /* 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 unlock the option byte operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_OB_LK)) { + /* 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) +{ + /* reset the OB_LK bit */ + FMC_OBCTL0 |= FMC_OBCTL0_OB_LK; +} + +/*! + \brief send option byte change command + \param[in] none + \param[out] none + \retval none +*/ +void ob_start(void) +{ + /* set the OB_START bit in OBCTL0 register */ + FMC_OBCTL0 |= FMC_OBCTL0_OB_START; +} + +/*! + \brief erase option byte + \param[in] none + \param[out] none + \retval none +*/ +void ob_erase(void) +{ + uint32_t reg, reg1; + fmc_state_enum fmc_state = FMC_READY; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + reg = FMC_OBCTL0; + reg1 = FMC_OBCTL1; + + if(FMC_READY == fmc_state) { + + /* reset the OB_FWDGT, OB_DEEPSLEEP and OB_STDBY, set according to ob_fwdgt ,ob_deepsleep and ob_stdby */ + reg |= (FMC_OBCTL0_NWDG_HW | FMC_OBCTL0_NRST_DPSLP | FMC_OBCTL0_NRST_STDBY); + /* reset the BOR level */ + reg |= FMC_OBCTL0_BOR_TH; + /* reset option byte boot bank value */ + reg &= ~FMC_OBCTL0_BB; + /* reset option byte dbs value */ + reg &= ~FMC_OBCTL0_DBS; + + /* reset drp and wp value */ + reg |= FMC_OBCTL0_WP0; + reg &= (~FMC_OBCTL0_DRP); + FMC_OBCTL0 = reg; + + reg1 |= FMC_OBCTL1_WP1; + FMC_OBCTL1 = reg1; + + FMC_OBCTL0 = reg; + } +} + +/*! + \brief enable write protection + \param[in] ob_wp: specify sector to be write protected + one or more parameters can be selected which are shown as below: + \arg OB_WP_x(x=0..22):sector x(x = 0,1,2...22) + \arg OB_WP_23_27: sector23~27 + \arg OB_WP_ALL: all sector + \param[out] none + \retval GD_SUCCESS or GD_ERROR +*/ +ErrStatus ob_write_protection_enable(uint32_t ob_wp) +{ + uint32_t reg0 = FMC_OBCTL0; + uint32_t reg1 = FMC_OBCTL1; + fmc_state_enum fmc_state = FMC_READY; + if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_DRP)) { + return GD_ERROR; + } + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + reg0 &= (~((uint32_t)ob_wp << 16U)); + reg1 &= (~(ob_wp & 0xFFFF0000U)); + FMC_OBCTL0 = reg0; + FMC_OBCTL1 = reg1; + + return GD_SUCCESS; + } else { + return GD_ERROR; + } +} + +/*! + \brief disable write protection + \param[in] ob_wp: specify sector to be write protected + one or more parameters can be selected which are shown as below: + \arg OB_WP_x(x=0..22):sector x(x = 0,1,2...22) + \arg OB_WP_23_27: sector23~27 + \arg OB_WP_ALL: all sector + \param[out] none + \retval GD_SUCCESS or GD_ERROR +*/ +ErrStatus ob_write_protection_disable(uint32_t ob_wp) +{ + uint32_t reg0 = FMC_OBCTL0; + uint32_t reg1 = FMC_OBCTL1; + fmc_state_enum fmc_state = FMC_READY; + if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_DRP)) { + return GD_ERROR; + } + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + reg0 |= ((uint32_t)ob_wp << 16U); + reg1 |= (ob_wp & 0xFFFF0000U); + FMC_OBCTL0 = reg0; + FMC_OBCTL1 = reg1; + + return GD_SUCCESS; + } else { + return GD_ERROR; + } +} + +/*! + \brief enable erase/program protection and D-bus read protection + \param[in] ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector + one or more parameters can be selected which are shown as below: + \arg OB_DRP_x(x=0..22): sector x(x = 0,1,2...22) + \arg OB_DRP_23_27: sector23~27 + \arg OB_DRP_ALL: all sector + \param[out] none + \retval none +*/ +void ob_drp_enable(uint32_t ob_drp) +{ + uint32_t reg0 = FMC_OBCTL0; + uint32_t reg1 = FMC_OBCTL1; + fmc_state_enum fmc_state = FMC_READY; + uint32_t drp_state = FMC_OBCTL0 & FMC_OBCTL0_DRP; + uint32_t wp0_state = FMC_OBCTL0 & FMC_OBCTL0_WP0; + uint32_t wp1_state = FMC_OBCTL1 & FMC_OBCTL1_WP1; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + if(RESET == drp_state) { + reg0 &= ~FMC_OBCTL0_WP0; + reg1 &= ~FMC_OBCTL1_WP1; + } + reg0 |= ((uint32_t)ob_drp << 16U); + reg0 |= FMC_OBCTL0_DRP; + reg1 |= ((uint32_t)ob_drp & 0xFFFF0000U); + + FMC_OBCTL0 = reg0; + FMC_OBCTL1 = reg1; + } +} + +/*! + \brief disable erase/program protection and D-bus read protection + \param[in] none + \param[out] none + \retval none +*/ +void ob_drp_disable(void) +{ + uint32_t reg0 = FMC_OBCTL0; + uint32_t reg1 = FMC_OBCTL1; + 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) { + if(((uint8_t)(reg0 >> 8U)) == (uint8_t)FMC_NSPC) { + /* security protection should be set as low level protection before disable D-BUS read protection */ + reg0 &= ~FMC_OBCTL0_SPC; + reg0 |= ((uint32_t)FMC_LSPC << 8U); + FMC_OBCTL0 = reg0; + /* set the OB_START bit in OBCTL0 register */ + FMC_OBCTL0 |= FMC_OBCTL0_OB_START; + } + + /* it is necessary to disable the security protection at the same time when D-BUS read protection is disabled */ + reg0 &= ~FMC_OBCTL0_SPC; + reg0 |= ((uint32_t)FMC_NSPC << 8U); + reg0 |= FMC_OBCTL0_WP0; + reg0 &= (~FMC_OBCTL0_DRP); + FMC_OBCTL0 = reg0; + + reg1 |= FMC_OBCTL1_WP1; + FMC_OBCTL1 = reg1; + + } +} + +/*! + \brief configure 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 security protection + \arg FMC_LSPC: low security protection + \arg FMC_HSPC: high security protection + \param[out] none + \retval none +*/ +void ob_security_protection_config(uint8_t ob_spc) +{ + 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) { + uint32_t reg; + + reg = FMC_OBCTL0; + /* reset the OBCTL0_SPC, set according to ob_spc */ + reg &= ~FMC_OBCTL0_SPC; + reg |= ((uint32_t)ob_spc << 8U); + FMC_OBCTL0 = reg; + } +} + +/*! + \brief program the FMC user 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[out] none + \retval none +*/ +void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby) +{ + 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) { + uint32_t reg; + + reg = FMC_OBCTL0; + /* reset the OB_FWDGT, OB_DEEPSLEEP and OB_STDBY, set according to ob_fwdgt ,ob_deepsleep and ob_stdby */ + reg &= ~(FMC_OBCTL0_NWDG_HW | FMC_OBCTL0_NRST_DPSLP | FMC_OBCTL0_NRST_STDBY); + FMC_OBCTL0 = (reg | ob_fwdgt | ob_deepsleep | ob_stdby); + } +} + +/*! + \brief program the option byte BOR threshold value + \param[in] ob_bor_th: user option byte + 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 none +*/ +void ob_user_bor_threshold(uint32_t ob_bor_th) +{ + uint32_t reg; + + reg = FMC_OBCTL0; + /* set the BOR level */ + reg &= ~FMC_OBCTL0_BOR_TH; + FMC_OBCTL0 = (reg | ob_bor_th); +} + +/*! + \brief configure the option byte boot bank value + \param[in] boot_mode: specifies the option byte boot bank value + only one parameter can be selected which is shown as below: + \arg OB_BB_DISABLE: boot from bank0 + \arg OB_BB_ENABLE: boot from bank1 or bank0 if bank1 is void + \param[out] none + \retval none +*/ +void ob_boot_mode_config(uint32_t boot_mode) +{ + uint32_t reg; + + reg = FMC_OBCTL0; + /* set option byte boot bank value */ + reg &= ~FMC_OBCTL0_BB; + FMC_OBCTL0 = (reg | boot_mode); +} + +/*! + \brief get the FMC user option byte + \param[in] none + \param[out] none + \retval the FMC user option byte values: ob_fwdgt(Bit0), ob_deepsleep(Bit1), ob_stdby(Bit2) +*/ +uint8_t ob_user_get(void) +{ + return (uint8_t)((uint8_t)(FMC_OBCTL0 >> 5U) & 0x07U); +} + +/*! + \brief get the FMC option byte write protection + \param[in] none + \param[out] none + \retval the FMC write protection option byte value +*/ +uint16_t ob_write_protection0_get(void) +{ + /* return the FMC write protection option byte value */ + return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16U)) & 0x0FFFU); +} + +/*! + \brief get the FMC option byte write protection + \param[in] none + \param[out] none + \retval the FMC write protection option byte value +*/ +uint16_t ob_write_protection1_get(void) +{ + /* return the the FMC write protection option byte value */ + return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16U)) & 0x0FFFU); +} + +/*! + \brief get the FMC erase/program protection and D-bus read protection option bytes value + \param[in] none + \param[out] none + \retval the FMC erase/program protection and D-bus read protection option bytes value +*/ +uint16_t ob_drp0_get(void) +{ + /* return the FMC erase/program protection and D-bus read protection option bytes value */ + if(FMC_OBCTL0 & FMC_OBCTL0_DRP) { + return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16U)) & 0x0FFFU); + } else { + return 0xF000U; + } +} + +/*! + \brief get the FMC erase/program protection and D-bus read protection option bytes value + \param[in] none + \param[out] none + \retval the FMC erase/program protection and D-bus read protection option bytes value +*/ +uint16_t ob_drp1_get(void) +{ + /* return the FMC erase/program protection and D-bus read protection option bytes value */ + if(FMC_OBCTL0 & FMC_OBCTL0_DRP) { + return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16U)) & 0x0FFFU); + } else { + return 0xF000U; + } +} + +/*! + \brief get option byte security protection code value + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus ob_spc_get(void) +{ + FlagStatus spc_state = RESET; + + if(((uint8_t)(FMC_OBCTL0 >> 8U)) != FMC_NSPC) { + spc_state = SET; + } else { + spc_state = RESET; + } + return spc_state; +} + +/*! + \brief get the FMC option byte BOR threshold value + \param[in] none + \param[out] none + \retval the FMC BOR threshold value:OB_BOR_TH_OFF,OB_BOR_TH_VALUE1,OB_BOR_TH_VALUE2,OB_BOR_TH_VALUE3 +*/ +uint8_t ob_user_bor_threshold_get(void) +{ + /* return the FMC BOR threshold value */ + return (uint8_t)((uint8_t)FMC_OBCTL0 & 0x0CU); +} + +/*! + \brief get flag set or reset + \param[in] fmc_flag: check FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_BUSY: FMC busy flag bit + \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit + \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit + \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit + \arg FMC_FLAG_WPERR: FMC Erase/Program protection error flag bit + \arg FMC_FLAG_OPERR: FMC operation error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t fmc_flag) +{ + if(FMC_STAT & fmc_flag) { + return SET; + } + /* return the state of corresponding FMC flag */ + return RESET; +} + +/*! + \brief clear the FMC pending flag + \param[in] FMC_flag: clear FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit + \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit + \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit + \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit + \arg FMC_FLAG_OPERR: FMC operation error flag bit + \arg FMC_FLAG_END: FMC end of operation flag bit + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t fmc_flag) +{ + /* clear the flags */ + FMC_STAT = fmc_flag; +} + +/*! + \brief enable FMC interrupt + \param[in] fmc_int: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_INT_END: enable FMC end of program interrupt + \arg FMC_INT_ERR: enable FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(uint32_t fmc_int) +{ + FMC_CTL |= fmc_int; +} + +/*! + \brief disable FMC interrupt + \param[in] fmc_int: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_INT_END: disable FMC end of program interrupt + \arg FMC_INT_ERR: disable FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(uint32_t fmc_int) +{ + FMC_CTL &= ~(uint32_t)fmc_int; +} + +/*! + \brief get FMC interrupt flag set or reset + \param[in] fmc_int_flag: FMC interrupt flag + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_RDDERR: FMC read D-bus protection error interrupt flag + \arg FMC_INT_FLAG_PGSERR: FMC program sequence error interrupt flag + \arg FMC_INT_FLAG_PGMERR: FMC program size not match error interrupt flag + \arg FMC_INT_FLAG_WPERR: FMC Erase/Program protection error interrupt flag + \arg FMC_INT_FLAG_OPERR: FMC operation error interrupt flag + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_interrupt_flag_get(uint32_t fmc_int_flag) +{ + if(FMC_FLAG_END == fmc_int_flag) { + /* end of operation interrupt flag */ + if(FMC_CTL & FMC_CTL_ENDIE) { + if(FMC_STAT & fmc_int_flag) { + return SET; + } + } + } else { + /* error interrupt flags */ + if(FMC_CTL & FMC_CTL_ERRIE) { + if(FMC_STAT & fmc_int_flag) { + return SET; + } + } + } + + return RESET; +} + +/*! + \brief clear the FMC interrupt flag + \param[in] fmc_int_flag: FMC interrupt flag + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_RDDERR: FMC read D-bus protection error interrupt flag + \arg FMC_INT_FLAG_PGSERR: FMC program sequence error interrupt flag + \arg FMC_INT_FLAG_PGMERR: FMC program size not match error interrupt flag + \arg FMC_INT_FLAG_WPERR: FMC Erase/Program protection error interrupt flag + \arg FMC_INT_FLAG_OPERR: FMC operation error interrupt flag + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag + \param[out] none + \retval none +*/ +void fmc_interrupt_flag_clear(uint32_t fmc_int_flag) +{ + /* clear the interrupt flag */ + FMC_STAT = fmc_int_flag; +} + +/*! + \brief get the FMC state + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + uint32_t temp_val = FMC_STAT; + + if(RESET != (temp_val & FMC_FLAG_BUSY)) { + fmc_state = FMC_BUSY; + } else if(RESET != (temp_val & FMC_FLAG_RDDERR)) { + fmc_state = FMC_RDDERR; + } else if(RESET != (temp_val & FMC_FLAG_PGSERR)) { + fmc_state = FMC_PGSERR; + } else if(RESET != (temp_val & FMC_FLAG_PGMERR)) { + fmc_state = FMC_PGMERR; + } else if(RESET != (temp_val & FMC_FLAG_WPERR)) { + fmc_state = FMC_WPERR; + } else if(RESET != (temp_val & FMC_FLAG_OPERR)) { + fmc_state = FMC_OPERR; + } else { + fmc_state = FMC_READY; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \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_RDDERR: read D-bus protection error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size not match error + \arg FMC_WPERR: erase/program protection error + \arg FMC_OPERR: operation error + \arg FMC_TOERR: timeout error +*/ +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(0U == timeout) { + fmc_state = FMC_TOERR; + } + + /* return the FMC state */ + return fmc_state; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fwdgt.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fwdgt.c new file mode 100644 index 000000000..339e9f4ce --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_fwdgt.c @@ -0,0 +1,218 @@ +/*! + \file gd32f4xx_fwdgt.c + \brief FWDGT driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_fwdgt.h" + +/*! + \brief enable write access to FWDGT_PSC and FWDGT_RLD + \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 and FWDGT_RLD + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_disable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE; +} + +/*! + \brief start the free watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the free watchdog timer 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: GD_ERROR or GD_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 > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return GD_ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_value; + + return GD_SUCCESS; +} + +/*! + \brief configure the free watchdog timer counter reload value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: GD_ERROR or GD_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 > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return GD_ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + return GD_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: GD_ERROR or GD_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 > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return GD_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 > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return GD_ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return GD_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_STAT_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_STAT_RUD: a write operation to FWDGT_RLD 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/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_gpio.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_gpio.c new file mode 100644 index 000000000..ee490f95a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_gpio.c @@ -0,0 +1,434 @@ +/*! + \file gd32f4xx_gpio.c + \brief GPIO driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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 GPIOI: + /* reset GPIOI */ + rcu_periph_reset_enable(RCU_GPIOIRST); + rcu_periph_reset_disable(RCU_GPIOIRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO mode + \param[in] gpio_periph: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \param[in] mode: GPIO pin mode + \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 + \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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \param[in] otype: GPIO pin output mode + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed: GPIO pin output max speed + \arg GPIO_OSPEED_2MHZ: output max speed 2MHz + \arg GPIO_OSPEED_25MHZ: output max speed 25MHz + \arg GPIO_OSPEED_50MHZ: output max speed 50MHz + \arg GPIO_OSPEED_MAX: output max speed more than 50MHz + \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 ospeedr; + + 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 */ + ospeedr = GPIO_OSPD(gpio_periph); + + for(i = 0U; i < 16U; i++) { + if((1U << i) & pin) { + /* clear the specified pin output speed bits */ + ospeedr &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeedr |= GPIO_OSPEED_SET(i, speed); + } + } + GPIO_OSPD(gpio_periph) = ospeedr; +} + +/*! + \brief set GPIO pin bit + \param[in] gpio_periph: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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 + \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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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 get GPIO pin input status + \param[in] gpio_periph: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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 input status of GPIO pin: 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 all pins input status + \param[in] gpio_periph: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \param[out] none + \retval input status 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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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 output status of GPIO pin: 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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \param[out] none + \retval output status 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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \param[in] alt_func_num: GPIO pin af function + \arg GPIO_AF_0: SYSTEM + \arg GPIO_AF_1: TIMER0, TIMER1 + \arg GPIO_AF_2: TIMER2, TIMER3, TIMER4 + \arg GPIO_AF_3: TIMER7, TIMER8, TIMER9, TIMER10 + \arg GPIO_AF_4: I2C0, I2C1, I2C2 + \arg GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5 + \arg GPIO_AF_6: SPI2, SPI3, SPI4 + \arg GPIO_AF_7: USART0, USART1, USART2, SPI1, SPI2 + \arg GPIO_AF_8: UART3, UART4, USART5, UART6, UART7 + \arg GPIO_AF_9: CAN0, CAN1, TLI, TIMER11, TIMER12, TIMER13, I2C1, I2C2, CTC + \arg GPIO_AF_10: USB_FS, USB_HS + \arg GPIO_AF_11: ENET + \arg GPIO_AF_12: EXMC, SDIO, USB_HS + \arg GPIO_AF_13: DCI + \arg GPIO_AF_14: TLI + \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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + \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: GPIO port + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F,G,H,I) + + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_i2c.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_i2c.c new file mode 100644 index 000000000..3b2adfdfd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_i2c.c @@ -0,0 +1,840 @@ +/*! + \file gd32f4xx_i2c.c + \brief I2C driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2019-04-16, V2.0.2, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_i2c.h" + +/* I2C register bit mask */ +#define I2CCLK_MAX ((uint32_t)0x0000003CU) /*!< i2cclk maximum value */ +#define I2CCLK_MIN ((uint32_t)0x00000002U) /*!< i2cclk minimum value */ +#define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag 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 STAT1_PECV_OFFSET ((uint32_t)0x00000008U) /* bit offset of PECV in I2C_STAT1 */ + +/*! + \brief reset I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph) { + case I2C0: + /* reset I2C0 */ + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + /* reset I2C1 */ + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; + case I2C2: + /* reset I2C2 */ + rcu_periph_reset_enable(RCU_I2C2RST); + rcu_periph_reset_disable(RCU_I2C2RST); + break; + default: + break; + } +} + +/*! + \brief configure I2C clock + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz) + \param[in] dutycyc: duty cycle in fast mode + only one parameter can be selected which is shown as below: + \arg I2C_DTCY_2: T_low/T_high = 2 in fast mode + \arg I2C_DTCY_16_9: T_low/T_high = 16/9 in fast mode + \param[out] none + \retval none +*/ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) +{ + uint32_t pclk1, clkc, freq, risetime; + uint32_t temp; + + pclk1 = rcu_clock_freq_get(CK_APB1); + /* I2C peripheral clock frequency */ + freq = (uint32_t)(pclk1 / 1000000U); + if(freq >= I2CCLK_MAX) { + freq = I2CCLK_MAX; + } + temp = I2C_CTL1(i2c_periph); + temp &= ~I2C_CTL1_I2CCLK; + temp |= freq; + + I2C_CTL1(i2c_periph) = temp; + + if(100000U >= clkspeed) { + /* the maximum SCL rise time is 1000ns in standard mode */ + risetime = (uint32_t)((pclk1 / 1000000U) + 1U); + if(risetime >= I2CCLK_MAX) { + I2C_RT(i2c_periph) = I2CCLK_MAX; + } else if(risetime <= I2CCLK_MIN) { + I2C_RT(i2c_periph) = I2CCLK_MIN; + } else { + I2C_RT(i2c_periph) = risetime; + } + clkc = (uint32_t)(pclk1 / (clkspeed * 2U)); + if(clkc < 0x04U) { + /* the CLKC in standard mode minmum value is 4 */ + clkc = 0x04U; + } + + I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc); + + } else if(400000U >= clkspeed) { + /* the maximum SCL rise time is 300ns in fast mode */ + I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)300U) / (uint32_t)1000U) + (uint32_t)1U); + if(I2C_DTCY_2 == dutycyc) { + /* I2C duty cycle is 2 */ + clkc = (uint32_t)(pclk1 / (clkspeed * 3U)); + I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; + } else { + /* I2C duty cycle is 16/9 */ + clkc = (uint32_t)(pclk1 / (clkspeed * 25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + if(0U == (clkc & I2C_CKCFG_CLKC)) { + /* the CLKC in fast mode minmum value is 1 */ + clkc |= 0x0001U; + } + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; + I2C_CKCFG(i2c_periph) |= clkc; + } else { + } +} + +/*! + \brief configure I2C address + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] mode: + only one parameter can be selected which is shown as below: + \arg I2C_I2CMODE_ENABLE: I2C mode + \arg I2C_SMBUSMODE_ENABLE: SMBus mode + \param[in] addformat: 7bits or 10bits + 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[in] addr: I2C address + \param[out] none + \retval none +*/ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr) +{ + /* SMBus/I2C mode selected */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SMBEN); + ctl |= mode; + I2C_CTL0(i2c_periph) = ctl; + /* configure address */ + addr = addr & I2C_ADDRESS_MASK; + I2C_SADDR0(i2c_periph) = (addformat | addr); +} + +/*! + \brief select SMBus type + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] type: + only one parameter can be selected which is shown as below: + \arg I2C_SMBUS_DEVICE: SMBus mode device type + \arg I2C_SMBUS_HOST: SMBus mode host type + \param[out] none + \retval none +*/ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) +{ + if(I2C_SMBUS_HOST == type) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL; + } else { + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL); + } +} + +/*! + \brief whether or not to send an ACK + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] ack: + only one parameter can be selected which is shown as below: + \arg I2C_ACK_ENABLE: ACK will be sent + \arg I2C_ACK_DISABLE: ACK will not be sent + \param[out] none + \retval none +*/ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack) +{ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ACKEN); + ctl |= ack; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief configure I2C POAP position + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pos: + only one parameter can be selected which is shown as below: + \arg I2C_ACKPOS_CURRENT: ACKEN bit decides whether or not to send ACK or not for the current byte + \arg I2C_ACKPOS_NEXT: ACKEN bit decides whether or not to send ACK for the next byte + \param[out] none + \retval none +*/ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) +{ + uint32_t ctl = 0U; + /* configure I2C POAP position */ + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_POAP); + ctl |= pos; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief master sends slave address + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] addr: slave address + \param[in] trandirection: transmitter or receiver + only one parameter can be selected which is shown as below: + \arg I2C_TRANSMITTER: transmitter + \arg I2C_RECEIVER: receiver + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection) +{ + /* master is a transmitter or a receiver */ + if(I2C_TRANSMITTER == trandirection) { + addr = addr & I2C_TRANSMITTER; + } else { + addr = addr | I2C_RECEIVER; + } + /* send slave address */ + I2C_DATA(i2c_periph) = addr; +} + +/*! + \brief enable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] addr: the second address in dual-address mode + \param[out] none + \retval none +*/ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr) +{ + /* configure address */ + addr = addr & I2C_ADDRESS2_MASK; + I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr); +} + +/*! + \brief disable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_dualaddr_disable(uint32_t i2c_periph) +{ + I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN); +} + +/*! + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \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) + \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) + \param[out] none + \retval none +*/ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_START; +} + +/*! + \brief generate a STOP condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP; +} + +/*! + \brief I2C transmit data function + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) +{ + I2C_DATA(i2c_periph) = DATA_TRANS(data); +} + +/*! + \brief I2C receive data function + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval data of received +*/ +uint8_t i2c_data_receive(uint32_t i2c_periph) +{ + return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph)); +} + +/*! + \brief configure I2C DMA mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmastate: + only one parameter can be selected which is shown as below: + \arg I2C_DMA_ON: enable DMA mode + \arg I2C_DMA_OFF: disable DMA mode + \param[out] none + \retval none +*/ +void i2c_dma_config(uint32_t i2c_periph, uint32_t dmastate) +{ + /* configure I2C DMA function */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMAON); + ctl |= dmastate; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief configure whether next DMA EOT is DMA last transfer or not + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dmalast: + only one parameter can be selected which is shown as below: + \arg I2C_DMALST_ON: next DMA EOT is the last transfer + \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer + \param[out] none + \retval none +*/ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast) +{ + /* configure DMA last transfer */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMALST); + ctl |= dmalast; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief whether to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] stretchpara: + only one parameter can be selected which is shown as below: + \arg I2C_SCLSTRETCH_ENABLE: enable SCL stretching + \arg I2C_SCLSTRETCH_DISABLE: disable SCL stretching + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) +{ + /* configure I2C SCL strerching */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SS); + ctl |= stretchpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief whether or not to response to a general call + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] gcallpara: + only one parameter can be selected which is shown as below: + \arg I2C_GCEN_ENABLE: slave will response to a general call + \arg I2C_GCEN_DISABLE: slave will not response to a general call + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara) +{ + /* configure slave response to a general call enable or disable */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_GCEN); + ctl |= gcallpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief configure software reset of I2C + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] sreset: + only one parameter can be selected which is shown as below: + \arg I2C_SRESET_SET: I2C is under reset + \arg I2C_SRESET_RESET: I2C is not under reset + \param[out] none + \retval none +*/ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset) +{ + /* modify CTL0 and configure software reset I2C state */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SRESET); + ctl |= sreset; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief configure I2C PEC calculation + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pecstate: + only one parameter can be selected which is shown as below: + \arg I2C_PEC_ENABLE: PEC calculation on + \arg I2C_PEC_DISABLE: PEC calculation off + \param[out] none + \retval none +*/ +void i2c_pec_config(uint32_t i2c_periph, uint32_t pecstate) +{ + /* on/off PEC calculation */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECEN); + ctl |= pecstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief configure whether to transfer PEC value + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] pecpara: + only one parameter can be selected which is shown as below: + \arg I2C_PECTRANS_ENABLE: transfer PEC value + \arg I2C_PECTRANS_DISABLE: not transfer PEC value + \param[out] none + \retval none +*/ +void i2c_pec_transfer_config(uint32_t i2c_periph, uint32_t pecpara) +{ + /* whether to transfer PEC */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECTRANS); + ctl |= pecpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval PEC value +*/ +uint8_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV) >> STAT1_PECV_OFFSET); +} + +/*! + \brief configure I2C alert through SMBA pin + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] smbuspara: + only one parameter can be selected which is shown as below: + \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin + \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin + \param[out] none + \retval none +*/ +void i2c_smbus_alert_config(uint32_t i2c_periph, uint32_t smbuspara) +{ + /* configure smubus alert through SMBA pin */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SALT); + ctl |= smbuspara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief configure I2C ARP protocol in SMBus + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] arpstate: + only one parameter can be selected which is shown as below: + \arg I2C_ARP_ENABLE: enable ARP + \arg I2C_ARP_DISABLE: disable ARP + \param[out] none + \retval none +*/ +void i2c_smbus_arp_config(uint32_t i2c_periph, uint32_t arpstate) +{ + /* enable or disable I2C ARP protocol*/ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ARPEN); + ctl |= arpstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief disable analog noise filter + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph) +{ + I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD; +} + +/*! + \brief enable analog noise filter + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph) +{ + I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD); +} + +/*! + \brief configure digital noise filter + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dfilterpara: refer to i2c_digital_filter_enum + only one parameter can be selected which is shown as below: + \arg I2C_DF_DISABLE: disable digital noise filter + \arg I2C_DF_1PCLK: enable digital noise filter and the maximum filtered spiker's length 1 PCLK1 + \arg I2C_DF_2PCLK: enable digital noise filter and the maximum filtered spiker's length 2 PCLK1 + \arg I2C_DF_3PCLK: enable digital noise filter and the maximum filtered spiker's length 3 PCLK1 + \arg I2C_DF_4PCLK: enable digital noise filter and the maximum filtered spiker's length 4 PCLK1 + \arg I2C_DF_5PCLK: enable digital noise filter and the maximum filtered spiker's length 5 PCLK1 + \arg I2C_DF_6PCLK: enable digital noise filter and the maximum filtered spiker's length 6 PCLK1 + \arg I2C_DF_7PCLK: enable digital noise filter and the maximum filtered spiker's length 7 PCLK1 + \arg I2C_DF_8PCLK: enable digital noise filter and the maximum filtered spiker's length 8 PCLK1 + \arg I2C_DF_9PCLK: enable digital noise filter and the maximum filtered spiker's length 9 PCLK1 + \arg I2C_DF_10PCLK: enable digital noise filter and the maximum filtered spiker's length 10 PCLK1 + \arg I2C_DF_11CLK: enable digital noise filter and the maximum filtered spiker's length 11 PCLK1 + \arg I2C_DF_12CLK: enable digital noise filter and the maximum filtered spiker's length 12 PCLK1 + \arg I2C_DF_13PCLK: enable digital noise filter and the maximum filtered spiker's length 13 PCLK1 + \arg I2C_DF_14PCLK: enable digital noise filter and the maximum filtered spiker's length 14 PCLK1 + \arg I2C_DF_15PCLK: enable digital noise filter and the maximum filtered spiker's length 15 PCLK1 + \param[out] none + \retval none +*/ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, i2c_digital_filter_enum dfilterpara) +{ + I2C_FCTL(i2c_periph) |= dfilterpara; +} + +/*! + \brief enable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; +} + +/*! + \brief disable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); +} + +/*! + \brief enable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; +} + +/*! + \brief disable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); +} + +/*! + \brief get I2C flag status + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] flag: I2C flags, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_SBSEND: start condition sent out in master mode + \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode + \arg I2C_FLAG_BTC: byte transmission finishes + \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode + \arg I2C_FLAG_STPDET: stop condition detected in slave mode + \arg I2C_FLAG_RBNE: I2C_DATA is not empty during receiving + \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting + \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_SMBALT: SMBus alert status + \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver + \arg I2C_FLAG_RXGC: general call address (00h) received + \arg I2C_FLAG_DEFSMB: default address of SMBus device + \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode + \arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode + \arg I2C_FLAG_TFF: txframe fall flag + \arg I2C_FLAG_TFR: txframe rise flag + \arg I2C_FLAG_RFF: rxframe fall flag + \arg I2C_FLAG_RFR: rxframe rise flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag) +{ + if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear I2C flag status + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] flag: I2C flags, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_SMBALT: SMBus alert status + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode + \arg I2C_FLAG_TFF: txframe fall flag + \arg I2C_FLAG_TFR: txframe rise flag + \arg I2C_FLAG_RFF: rxframe fall flag + \arg I2C_FLAG_RFR: rxframe rise flag + \param[out] none + \retval none +*/ +void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag) +{ + if(I2C_FLAG_ADDSEND == flag) { + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + } else { + I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag)); + } +} + +/*! + \brief enable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_EV: event interrupt + \arg I2C_INT_BUF: buffer interrupt + \arg I2C_INT_TFF: txframe fall interrupt + \arg I2C_INT_TFR: txframe rise interrupt + \arg I2C_INT_RFF: rxframe fall interrupt + \arg I2C_INT_RFR: rxframe rise interrupt + \param[out] none + \retval none +*/ +void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) +{ + I2C_REG_VAL(i2c_periph, interrupt) |= BIT(I2C_BIT_POS(interrupt)); +} + +/*! + \brief disable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_EV: event interrupt + \arg I2C_INT_BUF: buffer interrupt + \arg I2C_INT_TFF: txframe fall interrupt + \arg I2C_INT_TFR: txframe rise interrupt + \arg I2C_INT_RFF: rxframe fall interrupt + \arg I2C_INT_RFR: rxframe rise interrupt + \param[out] none + \retval none +*/ +void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) +{ + I2C_REG_VAL(i2c_periph, interrupt) &= ~BIT(I2C_BIT_POS(interrupt)); +} + +/*! + \brief get I2C interrupt flag status + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BTC: byte transmission finishes interrupt flag + \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag + \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag + \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag + \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag + \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag + \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag + \arg I2C_INT_FLAG_RFR: rxframe rise 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 intenable = 0U, flagstatus = 0U, bufie; + + /* check BUFIE */ + bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE; + + /* get the interrupt enable bit status */ + intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag))); + + if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)) { + if(intenable && bufie) { + intenable = 1U; + } else { + intenable = 0U; + } + } + if((0U != flagstatus) && (0U != intenable)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear I2C interrupt flag status + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag + \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag + \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag + \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag + \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag + \param[out] none + \retval none +*/ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + if(I2C_INT_FLAG_ADDSEND == int_flag) { + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + } else { + I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag)); + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ipa.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ipa.c new file mode 100644 index 000000000..02e8e85a7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_ipa.c @@ -0,0 +1,639 @@ +/*! + \file gd32f4xx_ipa.c + \brief IPA driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_ipa.h" + +#define IPA_DEFAULT_VALUE 0x00000000U + +/*! + \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 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 + 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_ARG1555,FOREGROUND_PPF_ARGB4444,FOREGROUND_PPF_L8,FOREGROUND_PPF_AL44, + FOREGROUND_PPF_AL88,FOREGROUND_PPF_L4,FOREGROUND_PPF_A8,FOREGROUND_PPF_A4) + foreground_prered: foreground pre-defined red value + foreground_pregreen: foreground pre-defined green value + foreground_preblue: foreground pre-defined blue value + \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; +} + +/*! + \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_ARG1555,FOREGROUND_PPF_ARGB4444,FOREGROUND_PPF_L8,FOREGROUND_PPF_AL44, + FOREGROUND_PPF_AL88,FOREGROUND_PPF_L4,FOREGROUND_PPF_A8,FOREGROUND_PPF_A4) + foreground_prered: foreground pre-defined red value + foreground_pregreen: foreground pre-defined green value + foreground_preblue: foreground pre-defined blue value + \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 |= (foreground_struct->foreground_prealpha << 24U); + IPA_FPCTL |= foreground_struct->foreground_alpha_algorithm; + IPA_FPCTL |= foreground_struct->foreground_pf; + /* 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)); + + 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 + 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_BG_ALPHA_MODE_1,IPA_BG_ALPHA_MODE_2 + background_pf: background pixel format(BACKGROUND_PPF_ARGB8888,BACKGROUND_PPF_RGB888,BACKGROUND_PPF_RGB565, + BACKGROUND_PPF_ARG1555,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 + \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_ARG1555,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 + 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 + \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; +} + +/*! + \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 + \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 configuration */ + IPA_DPCTL &= ~(IPA_DPCTL_DPF); + IPA_DPCTL = destination_struct->destination_pf; + 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)); + + 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 { + IPA_FPCTL &= ~(IPA_FPCTL_FLPF); + } + /* 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 { + IPA_BPCTL &= ~(IPA_BPCTL_BLPF); + } + /* 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) { + IPA_ITCTL |= IPA_ITCTL_ITEN; + } else { + IPA_ITCTL &= ~(IPA_ITCTL_ITEN); + } +} + +/*! + \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 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(0U != (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/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_iref.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_iref.c new file mode 100644 index 000000000..731d4fcd1 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_iref.c @@ -0,0 +1,127 @@ +/*! + \file gd32f4xx_iref.c + \brief IREF driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_iref.h" + +/*! + \brief deinitialize IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_deinit(void) +{ + rcu_periph_reset_enable(RCU_IREFRST); + rcu_periph_reset_disable(RCU_IREFRST); +} + +/*! + \brief enable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_enable(void) +{ + IREF_CTL |= IREF_CTL_CREN; +} + +/*! + \brief disable IREF + \param[in] none + \param[out] none + \retval none +*/ +void iref_disable(void) +{ + IREF_CTL &= ~IREF_CTL_CREN; +} + +/*! + \brief set IREF mode + \param[in] step + \arg IREF_MODE_LOW_POWER: 1uA step + \arg IREF_MODE_HIGH_CURRENT: 8uA step + \param[out] none + \retval none +*/ +void iref_mode_set(uint32_t step) +{ + IREF_CTL &= ~IREF_CTL_SSEL; + IREF_CTL |= step; +} + +/*! + \brief set IREF precision_trim_value + \param[in] precisiontrim + \arg IREF_CUR_PRECISION_TRIM_X(x=0..31): (-15+ x)% + \param[out] none + \retval none +*/ +void iref_precision_trim_value_set(uint32_t precisiontrim) +{ + IREF_CTL &= ~IREF_CTL_CPT; + IREF_CTL |= precisiontrim; +} + +/*! + \brief set IREF sink mode + \param[in] sinkmode + \arg IREF_SOURCE_CURRENT : source current. + \arg IREF_SINK_CURRENT: sink current + \param[out] none + \retval none +*/ +void iref_sink_set(uint32_t sinkmode) +{ + IREF_CTL &= ~IREF_CTL_SCMOD; + IREF_CTL |= sinkmode; +} + +/*! + \brief set IREF step data + \param[in] stepdata + \arg IREF_CUR_STEP_DATA_X:(x=0..63): step*x + \param[out] none + \retval none +*/ + +void iref_step_data_config(uint32_t stepdata) +{ + IREF_CTL &= ~IREF_CTL_CSDT; + IREF_CTL |= stepdata; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_it.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_it.c new file mode 100644 index 000000000..8e859dddc --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_it.c @@ -0,0 +1,81 @@ +/*! + \file gd32f4xx_it.c + \brief interrupt service routines + + \version 2020-12-04, V2.0.0, demo for GD32F4xx +*/ + +/* + Copyright (c) 2020, 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 "gd32f4xx_it.h" + +/*! + \brief this function handles NMI exception + \param[in] none + \param[out] none + \retval none +*/ +void NMI_Handler(void) +{ +} + +/*! + \brief this function handles BusFault exception + \param[in] none + \param[out] none + \retval none +*/ +void BusFault_Handler(void) +{ + /* if Bus Fault exception occurs, go to infinite loop */ + while(1) { + } +} + +/*! + \brief this function handles UsageFault exception + \param[in] none + \param[out] none + \retval none +*/ +void UsageFault_Handler(void) +{ + /* if Usage Fault exception occurs, go to infinite loop */ + while(1) { + } +} + +/*! + \brief this function handles SVC exception + \param[in] none + \param[out] none + \retval none +*/ +void SVC_Handler(void) +{ +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_misc.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_misc.c new file mode 100644 index 000000000..3198d4aa6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_misc.c @@ -0,0 +1,175 @@ +/*! + \file gd32f4xx_misc.c + \brief MISC driver + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_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 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 */ + if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE0_SUB4) { + temp_pre = 0U; + temp_sub = 0x4U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE1_SUB3) { + temp_pre = 1U; + temp_sub = 0x3U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE2_SUB2) { + temp_pre = 2U; + temp_sub = 0x2U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE3_SUB1) { + temp_pre = 3U; + temp_sub = 0x1U; + } else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE4_SUB0) { + temp_pre = 4U; + temp_sub = 0x0U; + } else { + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + temp_pre = 2U; + temp_sub = 0x2U; + } + /* 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 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 >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F); +} + +/*! + \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 + \are 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 lowpower 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 lowpower 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_HCLK: systick clock source is from HCLK + \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8 + \param[out] none + \retval none +*/ + +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource) { + /* set the systick clock source from HCLK */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + } else { + /* set the systick clock source from HCLK/8 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_pmu.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_pmu.c new file mode 100644 index 000000000..229a55729 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_pmu.c @@ -0,0 +1,412 @@ +/*! + \file gd32f4xx_pmu.c + \brief PMU driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_pmu.h" +#include "core_cm4.h" + +/*! + \brief reset PMU registers + \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: + \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: voltage threshold is 3.1V + \param[out] none + \retval none +*/ +void pmu_lvd_select(uint32_t lvdt_n) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; + /* clear LVDT bits */ + PMU_CTL &= ~PMU_CTL_LVDT; + /* set LVDT bits according to pmu_lvdt_n */ + PMU_CTL |= lvdt_n; + /* enable LVD */ + PMU_CTL |= PMU_CTL_LVDEN; +} + +/*! + \brief disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief select LDO output voltage + this bit set by software when the main PLL closed, before closing PLL, change the system clock to IRC16M or HXTAL + \param[in] ldo_output: + \arg PMU_LDOVS_LOW: low-driver mode enable in deep-sleep mode + \arg PMU_LDOVS_MID: mid-driver mode disable in deep-sleep mode + \arg PMU_LDOVS_HIGH: high-driver mode disable in deep-sleep mode + \param[out] none + \retval none +*/ +void pmu_ldo_output_select(uint32_t ldo_output) +{ + PMU_CTL &= ~PMU_CTL_LDOVS; + PMU_CTL |= ldo_output; +} + +/*! + \brief enable high-driver mode + this bit set by software only when IRC16M or HXTAL used as system clock + \param[in] none + \param[out] none + \retval none +*/ +void pmu_highdriver_mode_enable(void) +{ + PMU_CTL |= PMU_CTL_HDEN; +} + +/*! + \brief disable high-driver mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_highdriver_mode_disable(void) +{ + PMU_CTL &= ~PMU_CTL_HDEN; +} + +/*! + \brief switch high-driver mode + this bit set by software only when IRC16M or HXTAL used as system clock + \param[in] highdr_switch: + \arg PMU_HIGHDR_SWITCH_NONE: disable high-driver mode switch + \arg PMU_HIGHDR_SWITCH_EN: enable high-driver mode switch + \param[out] none + \retval none +*/ +void pmu_highdriver_switch_select(uint32_t highdr_switch) +{ + /* wait for HDRF flag set */ + while(SET != pmu_flag_get(PMU_FLAG_HDRF)) { + } + PMU_CTL &= ~PMU_CTL_HDS; + PMU_CTL |= highdr_switch; +} + +/*! + \brief enable low-driver mode in deep-sleep + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lowdriver_mode_enable(void) +{ + PMU_CTL |= PMU_CTL_LDEN; +} + +/*! + \brief disable low-driver mode in deep-sleep + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lowdriver_mode_disable(void) +{ + PMU_CTL &= ~PMU_CTL_LDEN; +} + +/*! + \brief in deep-sleep mode, driver mode when use low power LDO + \param[in] mode: + \arg PMU_NORMALDR_LOWPWR: normal driver when use low power LDO + \arg PMU_LOWDR_LOWPWR: low-driver mode enabled when LDEN is 11 and use low power LDO + \param[out] none + \retval none +*/ +void pmu_lowpower_driver_config(uint32_t mode) +{ + PMU_CTL &= ~PMU_CTL_LDLP; + PMU_CTL |= mode; +} + +/*! + \brief in deep-sleep mode, driver mode when use normal power LDO + \param[in] mode: + \arg PMU_NORMALDR_NORMALPWR: normal driver when use normal power LDO + \arg PMU_LOWDR_NORMALPWR: low-driver mode enabled when LDEN is 11 and use normal power LDO + \param[out] none + \retval none +*/ +void pmu_normalpower_driver_config(uint32_t mode) +{ + PMU_CTL &= ~PMU_CTL_LDNP; + PMU_CTL |= mode; +} + +/*! + \brief PMU work in sleep mode + \param[in] sleepmodecmd: + \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-M4 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(); + } +} + +/*! + \brief PMU work in deep-sleep mode + \param[in] ldo + \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deep-sleep mode + \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deep-sleep mode + \param[in] lowdrive: + only one parameter can be selected which is shown as below: + \arg PMU_LOWDRIVER_DISABLE: Low-driver mode disable in deep-sleep mode + \arg PMU_LOWDRIVER_ENABLE: Low-driver mode enable in deep-sleep mode + \param[in] deepsleepmodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint32_t ldo, uint32_t lowdrive, uint8_t deepsleepmodecmd) +{ + static uint32_t reg_snap[4]; + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP | PMU_CTL_LDEN | PMU_CTL_LDNP | PMU_CTL_LDLP)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= ldo; + + /* configure low drive mode in deep-sleep mode */ + if(PMU_LOWDRIVER_ENABLE == lowdrive) { + if(PMU_LDO_NORMAL == ldo) { + PMU_CTL |= (uint32_t)(PMU_CTL_LDEN | PMU_CTL_LDNP); + } else { + PMU_CTL |= (uint32_t)(PMU_CTL_LDEN | PMU_CTL_LDLP); + } + } + /* set sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + reg_snap[0] = REG32(0xE000E010U); + reg_snap[1] = REG32(0xE000E100U); + reg_snap[2] = REG32(0xE000E104U); + reg_snap[3] = REG32(0xE000E108U); + + REG32(0xE000E010U) &= 0x00010004U; + REG32(0xE000E180U) = 0XFF7FF831U; + REG32(0xE000E184U) = 0XBFFFF8FFU; + REG32(0xE000E188U) = 0xFFFFEFFFU; + + /* select WFI or WFE command to enter deep-sleep mode */ + if(WFI_CMD == deepsleepmodecmd) { + __WFI(); + } else { + __SEV(); + __WFE(); + __WFE(); + } + + REG32(0xE000E010U) = reg_snap[0]; + REG32(0xE000E100U) = reg_snap[1]; + REG32(0xE000E104U) = reg_snap[2]; + REG32(0xE000E108U) = reg_snap[3]; + + /* reset sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief pmu work in standby mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_to_standbymode(void) +{ + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* set sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + REG32(0xE000E010U) &= 0x00010004U; + REG32(0xE000E180U) = 0XFFFFFFF7U; + REG32(0xE000E184U) = 0XFFFFFDFFU; + REG32(0xE000E188U) = 0xFFFFFFFFU; + + /* select WFI command to enter standby mode */ + __WFI(); +} + +/*! + \brief enable PMU wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(void) +{ + PMU_CS |= PMU_CS_WUPEN; +} + +/*! + \brief disable PMU wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(void) +{ + PMU_CS &= ~PMU_CS_WUPEN; +} + +/*! + \brief backup SRAM LDO on + \param[in] bkp_ldo: + \arg PMU_BLDOON_OFF: backup SRAM LDO closed + \arg PMU_BLDOON_ON: open the backup SRAM LDO + \param[out] none + \retval none +*/ +void pmu_backup_ldo_config(uint32_t bkp_ldo) +{ + PMU_CS &= ~PMU_CS_BLDOON; + PMU_CS |= bkp_ldo; +} + +/*! + \brief enable write access to the registers in backup domain + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief disable write access to the registers in backup domain + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief get flag state + \param[in] flag: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVD: lvd flag + \arg PMU_FLAG_BLDORF: backup SRAM LDO ready flag + \arg PMU_FLAG_LDOVSRF: LDO voltage select ready flag + \arg PMU_FLAG_HDRF: high-driver ready flag + \arg PMU_FLAG_HDSRF: high-driver switch ready flag + \arg PMU_FLAG_LDRF: low-driver mode ready flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag) +{ + if(PMU_CS & flag) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear flag bit + \param[in] flag: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag) +{ + switch(flag) { + case PMU_FLAG_RESET_WAKEUP: + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + break; + case PMU_FLAG_RESET_STANDBY: + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + break; + default : + break; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rcu.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rcu.c new file mode 100644 index 000000000..c53eb050c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rcu.c @@ -0,0 +1,1332 @@ +/*! + \file gd32f4xx_rcu.c + \brief RCU driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_rcu.h" + +/* define clock source */ +#define SEL_IRC16M ((uint16_t)0U) /* IRC16M is selected as CK_SYS */ +#define SEL_HXTAL ((uint16_t)1U) /* HXTAL is selected as CK_SYS */ +#define SEL_PLLP ((uint16_t)2U) /* PLLP is selected as CK_SYS */ +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0x000fffffU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x0fffffffU) + +/* RCU IRC16M adjust value mask and offset*/ +#define RCU_IRC16M_ADJUST_MASK ((uint8_t)0x1FU) +#define RCU_IRC16M_ADJUST_OFFSET ((uint32_t)3U) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + rcu_osci_stab_wait(RCU_IRC16M); + RCU_CFG0 &= ~RCU_CFG0_SCS; + + /* reset CTL register */ + RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLLEN | RCU_CTL_PLLI2SEN + | RCU_CTL_PLLSAIEN); + RCU_CTL &= ~(RCU_CTL_HXTALBPS); + /* reset CFG0 register */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | + RCU_CFG0_RTCDIV | RCU_CFG0_CKOUT0SEL | RCU_CFG0_I2SSEL | RCU_CFG0_CKOUT0DIV | + RCU_CFG0_CKOUT1DIV | RCU_CFG0_CKOUT1SEL); + /* reset PLL register */ + RCU_PLL = 0x24003010U; + /* reset PLLI2S register */ + RCU_PLLI2S = 0x24003000U; + /* reset PLLSAI register */ + RCU_PLLSAI = 0x24003010U; + /* reset INT register */ + RCU_INT = 0x00000000U; + /* reset CFG1 register */ + RCU_CFG1 &= ~(RCU_CFG1_PLLSAIRDIV | RCU_CFG1_TIMERSEL); +} + +/*! + \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_GPIOx (x = A, B, C, D, E, F, G, H, I): GPIO ports clock + \arg RCU_CRC: CRC clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_TCMSRAM: TCMSRAM clock + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_IPA: IPA clock + \arg RCU_ENET: ENET clock + \arg RCU_ENETTX: ENETTX clock + \arg RCU_ENETRX: ENETRX clock + \arg RCU_ENETPTP: ENETPTP clock + \arg RCU_USBHS: USBHS clock + \arg RCU_USBHSULPI: USBHSULPI clock + \arg RCU_DCI: DCI clock + \arg RCU_TRNG: TRNG clock + \arg RCU_USBFS: USBFS clock + \arg RCU_EXMC: EXMC clock + \arg RCU_TIMERx (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SPIx (x = 0, 1, 2, 3, 4, 5): SPI 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): I2C clock + \arg RCU_CANx (x = 0, 1): CAN clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_RTC: RTC clock + \arg RCU_ADCx (x = 0, 1, 2): ADC clock + \arg RCU_SDIO: SDIO clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_TLI: TLI clock + \arg RCU_CTC: CTC clock + \arg RCU_IREF: IREF 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_GPIOx (x = A, B, C, D, E, F, G, H, I): GPIO ports clock + \arg RCU_CRC: CRC clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_TCMSRAM: TCMSRAM clock + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_IPA: IPA clock + \arg RCU_ENET: ENET clock + \arg RCU_ENETTX: ENETTX clock + \arg RCU_ENETRX: ENETRX clock + \arg RCU_ENETPTP: ENETPTP clock + \arg RCU_USBHS: USBHS clock + \arg RCU_USBHSULPI: USBHSULPI clock + \arg RCU_DCI: DCI clock + \arg RCU_TRNG: TRNG clock + \arg RCU_USBFS: USBFS clock + \arg RCU_EXMC: EXMC clock + \arg RCU_TIMERx (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_SPIx (x = 0, 1, 2, 3, 4, 5): SPI 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): I2C clock + \arg RCU_CANx (x = 0, 1): CAN clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC clock + \arg RCU_RTC: RTC clock + \arg RCU_ADCx (x = 0, 1, 2): ADC clock + \arg RCU_SDIO: SDIO clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_TLI: TLI clock + \arg RCU_CTC: CTC clock + \arg RCU_IREF: IREF 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_GPIOx_SLP (x = A, B, C, D, E, F, G, H, I): GPIO ports clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM0_SLP: SRAM0 clock + \arg RCU_SRAM1_SLP: SRAM1 clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_SRAM2_SLP: SRAM2 clock + \arg RCU_DMAx_SLP (x=0,1): DMA clock + \arg RCU_IPA_SLP: IPA clock + \arg RCU_ENET_SLP: ENET clock + \arg RCU_ENETTX_SLP: ENETTX clock + \arg RCU_ENETRX_SLP: ENETRX clock + \arg RCU_ENETPTP_SLP: ENETPTP clock + \arg RCU_USBHS_SLP: USBHS clock + \arg RCU_USBHSULPI_SLP: USBHSULPI clock + \arg RCU_DCI_SLP: DCI clock + \arg RCU_TRNG_SLP: TRNG clock + \arg RCU_USBFS_SLP: USBFS clock + \arg RCU_EXMC_SLP: EXMC clock + \arg RCU_TIMERx_SLP (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_SPIx_SLP (x = 0, 1, 2, 3, 4, 5): SPI 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): I2C clock + \arg RCU_CANx_SLP (x = 0, 1): CAN clock + \arg RCU_PMU_SLP: PMU clock + \arg RCU_DAC_SLP: DAC clock + \arg RCU_RTC_SLP: RTC clock + \arg RCU_ADCx_SLP (x = 0, 1, 2): ADC clock + \arg RCU_SDIO_SLP: SDIO clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_TLI_SLP: TLI clock + \arg RCU_CTC_SLP: CTC clock + \arg RCU_IREF_SLP: IREF 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_GPIOx_SLP (x = A, B, C, D, E, F, G, H, I): GPIO ports clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM0_SLP: SRAM0 clock + \arg RCU_SRAM1_SLP: SRAM1 clock + \arg RCU_BKPSRAM: BKPSRAM clock + \arg RCU_SRAM2_SLP: SRAM2 clock + \arg RCU_DMAx_SLP (x=0,1): DMA clock + \arg RCU_IPA_SLP: IPA clock + \arg RCU_ENET_SLP: ENET clock + \arg RCU_ENETTX_SLP: ENETTX clock + \arg RCU_ENETRX_SLP: ENETRX clock + \arg RCU_ENETPTP_SLP: ENETPTP clock + \arg RCU_USBHS_SLP: USBHS clock + \arg RCU_USBHSULPI_SLP: USBHSULPI clock + \arg RCU_DCI_SLP: DCI clock + \arg RCU_TRNG_SLP: TRNG clock + \arg RCU_USBFS_SLP: USBFS clock + \arg RCU_EXMC_SLP: EXMC clock + \arg RCU_TIMERx_SLP (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): TIMER clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_SPIx_SLP (x = 0, 1, 2, 3, 4, 5): SPI 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): I2C clock + \arg RCU_CANx_SLP (x = 0, 1): CAN clock + \arg RCU_PMU_SLP: PMU clock + \arg RCU_DAC_SLP: DAC clock + \arg RCU_RTC_SLP: RTC clock + \arg RCU_ADCx_SLP (x = 0, 1, 2): ADC clock + \arg RCU_SDIO_SLP: SDIO clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_TLI_SLP: TLI clock + \arg RCU_CTC_SLP: CTC clock + \arg RCU_IREF_SLP: IREF 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_GPIOxRST (x = A, B, C, D, E, F, G, H, I): reset GPIO ports + \arg RCU_CRCRST: reset CRC + \arg RCU_DMAxRST (x=0,1): reset DMA + \arg RCU_IPARST: reset IPA + \arg RCU_ENETRST: reset ENET + \arg RCU_USBHSRST: reset USBHS + \arg RCU_DCIRST: reset DCI + \arg RCU_TRNGRST: reset TRNG + \arg RCU_USBFSRST: reset USBFS + \arg RCU_EXMCRST: reset EXMC + \arg RCU_TIMERxRST (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): reset TIMER + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SPIxRST (x = 0, 1, 2, 3, 4, 5): reset SPI + \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): reset I2C + \arg RCU_CANxRST (x = 0, 1): reset CAN + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_ADCRST (x = 0, 1, 2): reset ADC + \arg RCU_SDIORST: reset SDIO + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_TLIRST: reset TLI + \arg RCU_CTCRST: reset CTC + \arg RCU_IREFRST: reset IREF + \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_GPIOxRST (x = A, B, C, D, E, F, G, H, I): reset GPIO ports + \arg RCU_CRCRST: reset CRC + \arg RCU_DMAxRST (x=0,1): reset DMA + \arg RCU_IPARST: reset IPA + \arg RCU_ENETRST: reset ENET + \arg RCU_USBHSRST: reset USBHS + \arg RCU_DCIRST: reset DCI + \arg RCU_TRNGRST: reset TRNG + \arg RCU_USBFSRST: reset USBFS + \arg RCU_EXMCRST: reset EXMC + \arg RCU_TIMERxRST (x = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13): reset TIMER + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_SPIxRST (x = 0, 1, 2, 3, 4, 5): reset SPI + \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): reset I2C + \arg RCU_CANxRST (x = 0, 1): reset CAN + \arg RCU_PMURST: reset PMU + \arg RCU_DACRST: reset DAC + \arg RCU_ADCRST (x = 0, 1, 2): reset ADC + \arg RCU_SDIORST: reset SDIO + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_TLIRST: reset TLI + \arg RCU_CTCRST: reset CTC + \arg RCU_IREFRST: reset IREF + \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_IRC16M: select CK_IRC16M as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_PLLP: select CK_PLLP 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_IRC16M: CK_IRC16M is selected as the CK_SYS source + \arg RCU_SCSS_HXTAL: CK_HXTAL is selected as the CK_SYS source + \arg RCU_SCSS_PLLP: CK_PLLP 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): select CK_SYS / x as CK_AHB + \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 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_IRC16M: IRC16M selected + \arg RCU_CKOUT0SRC_LXTAL: LXTAL selected + \arg RCU_CKOUT0SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT0SRC_PLLP: PLLP selected + \param[in] ckout0_div: CK_OUT0 divider + \arg RCU_CKOUT0_DIVx(x = 1, 2, 3, 4, 5): 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_CFG0; + /* reset the CKOUT0SRC, CKOUT0DIV and set according to ckout0_src and ckout0_div */ + reg &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV); + RCU_CFG0 = (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_PLLI2SR: PLLI2SR selected + \arg RCU_CKOUT1SRC_HXTAL: HXTAL selected + \arg RCU_CKOUT1SRC_PLLP: PLLP selected + \param[in] ckout1_div: CK_OUT1 divider + \arg RCU_CKOUT1_DIVx(x = 1, 2, 3, 4, 5): 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_CFG0; + /* reset the CKOUT1SRC, CKOUT1DIV and set according to ckout1_src and ckout1_div */ + reg &= ~(RCU_CFG0_CKOUT1SEL | RCU_CFG0_CKOUT1DIV); + RCU_CFG0 = (reg | ckout1_src | ckout1_div); +} + +/*! + \brief configure the main PLL clock + \param[in] pll_src: PLL clock source selection + \arg RCU_PLLSRC_IRC16M: select IRC16M as PLL source clock + \arg RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock + \param[in] pll_psc: the PLL VCO source clock prescaler + \arg this parameter should be selected between 2 and 63 + \param[in] pll_n: the PLL VCO clock multi factor + \arg this parameter should be selected between 64 and 500 + \param[in] pll_p: the PLLP output frequency division factor from PLL VCO clock + \arg this parameter should be selected 2,4,6,8 + \param[in] pll_q: the PLL Q output frequency division factor from PLL VCO clock + \arg this parameter should be selected between 2 and 15 + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus rcu_pll_config(uint32_t pll_src, uint32_t pll_psc, uint32_t pll_n, uint32_t pll_p, uint32_t pll_q) +{ + uint32_t ss_modulation_inc; + uint32_t ss_modulation_reg; + + ss_modulation_inc = 0U; + ss_modulation_reg = RCU_PLLSSCTL; + + /* calculate the minimum factor of PLLN */ + if((ss_modulation_reg & RCU_PLLSSCTL_SSCGON) == RCU_PLLSSCTL_SSCGON) { + if((ss_modulation_reg & RCU_SS_TYPE_DOWN) == RCU_SS_TYPE_DOWN) { + ss_modulation_inc += RCU_SS_MODULATION_DOWN_INC; + } else { + ss_modulation_inc += RCU_SS_MODULATION_CENTER_INC; + } + } + + /* check the function parameter */ + if(CHECK_PLL_PSC_VALID(pll_psc) && CHECK_PLL_N_VALID(pll_n, ss_modulation_inc) && + CHECK_PLL_P_VALID(pll_p) && CHECK_PLL_Q_VALID(pll_q)) { + RCU_PLL = pll_psc | (pll_n << 6) | (((pll_p >> 1) - 1U) << 16) | + (pll_src) | (pll_q << 24); + } else { + /* return status */ + return GD_ERROR; + } + + /* return status */ + return GD_SUCCESS; +} + +/*! + \brief configure the PLLI2S clock + \param[in] plli2s_n: the PLLI2S VCO clock multi factor + \arg this parameter should be selected between 50 and 500 + \param[in] plli2s_r: the PLLI2S R output frequency division factor from PLLI2S VCO clock + \arg this parameter should be selected between 2 and 7 + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus rcu_plli2s_config(uint32_t plli2s_n, uint32_t plli2s_r) +{ + /* check the function parameter */ + if(CHECK_PLLI2S_N_VALID(plli2s_n) && CHECK_PLLI2S_R_VALID(plli2s_r)) { + RCU_PLLI2S = (plli2s_n << 6) | (plli2s_r << 28); + } else { + /* return status */ + return GD_ERROR; + } + + /* return status */ + return GD_SUCCESS; +} + +/*! + \brief configure the PLLSAI clock + \param[in] pllsai_n: the PLLSAI VCO clock multi factor + \arg this parameter should be selected between 50 and 500 + \param[in] pllsai_p: the PLLSAI P output frequency division factor from PLL VCO clock + \arg this parameter should be selected 2,4,6,8 + \param[in] pllsai_r: the PLLSAI R output frequency division factor from PLL VCO clock + \arg this parameter should be selected between 2 and 7 + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus rcu_pllsai_config(uint32_t pllsai_n, uint32_t pllsai_p, uint32_t pllsai_r) +{ + /* check the function parameter */ + if(CHECK_PLLSAI_N_VALID(pllsai_n) && CHECK_PLLSAI_P_VALID(pllsai_p) && CHECK_PLLSAI_R_VALID(pllsai_r)) { + RCU_PLLSAI = (pllsai_n << 6U) | (((pllsai_p >> 1U) - 1U) << 16U) | (pllsai_r << 28U); + } else { + /* return status */ + return GD_ERROR; + } + + /* return status */ + return GD_SUCCESS; +} + +/*! + \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....31 + \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 I2S clock source selection + \param[in] i2s_clock_source: I2S clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_I2SSRC_PLLI2S: CK_PLLI2S selected as I2S source clock + \arg RCU_I2SSRC_I2S_CKIN: external i2s_ckin pin selected as I2S source clock + \param[out] none + \retval none +*/ +void rcu_i2s_clock_config(uint32_t i2s_clock_source) +{ + uint32_t reg; + + reg = RCU_CFG0; + /* reset the I2SSEL bit and set according to i2s_clock_source */ + reg &= ~RCU_CFG0_I2SSEL; + RCU_CFG0 = (reg | i2s_clock_source); +} + +/*! + \brief configure the CK48M clock source selection + \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_ADDCTL; + /* reset the CK48MSEL bit and set according to i2s_clock_source */ + reg &= ~RCU_ADDCTL_CK48MSEL; + RCU_ADDCTL = (reg | ck48m_clock_source); +} + +/*! + \brief configure the PLL48M clock source selection + \param[in] pll48m_clock_source: PLL48M clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PLL48MSRC_PLLQ: CK_PLLQ selected as PLL48M source clock + \arg RCU_PLL48MSRC_PLLSAIP: CK_PLLSAIP 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_ADDCTL; + /* reset the PLL48MSEL bit and set according to pll48m_clock_source */ + reg &= ~RCU_ADDCTL_PLL48MSEL; + RCU_ADDCTL = (reg | pll48m_clock_source); +} + +/*! + \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 PLLSAIR divider used as input of TLI + \param[in] pllsai_r_div: PLLSAIR divider used as input of TLI + only one parameter can be selected which is shown as below: + \arg RCU_PLLSAIR_DIVx(x=2,4,8,16): PLLSAIR divided x used as input of TLI + \param[out] none + \retval none +*/ +void rcu_tli_clock_div_config(uint32_t pllsai_r_div) +{ + uint32_t reg; + + reg = RCU_CFG1; + /* reset the PLLSAIRDIV bit and set according to pllsai_r_div */ + reg &= ~RCU_CFG1_PLLSAIRDIV; + RCU_CFG1 = (reg | pllsai_r_div); +} + +/*! + \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_LXTALDRI_LOWER_DRIVE: lower driving capability + \arg RCU_LXTALDRI_HIGHER_DRIVE: higher 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_IRC16M: IRC16M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_PLL_CK: PLL + \arg RCU_PLLI2S_CK: PLLI2S + \arg RCU_PLLSAI_CK: PLLSAI + \param[out] none + \retval ErrStatus: GD_SUCCESS or GD_ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = GD_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 = GD_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 = GD_SUCCESS; + } + break; + /* wait IRC16M stable */ + case RCU_IRC16M: + while((RESET == osci_stat) && (IRC16M_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_IRC16MSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC16MSTB)) { + reval = GD_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 = GD_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 = GD_SUCCESS; + } + break; + /* wait PLL stable */ + case RCU_PLL_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)) { + reval = GD_SUCCESS; + } + break; + /* wait PLLI2S stable */ + case RCU_PLLI2S_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLLI2SSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLI2SSTB)) { + reval = GD_SUCCESS; + } + break; + /* wait PLLSAI stable */ + case RCU_PLLSAI_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLLSAISTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSAISTB)) { + reval = GD_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_IRC16M: IRC16M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_PLL_CK: PLL + \arg RCU_PLLI2S_CK: PLLI2S + \arg RCU_PLLSAI_CK: PLLSAI + \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_IRC16M: IRC16M + \arg RCU_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \arg RCU_PLL_CK: PLL + \arg RCU_PLLI2S_CK: PLLI2S + \arg RCU_PLLSAI_CK: PLLSAI + \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; + case RCU_IRC16M: + case RCU_IRC48M: + case RCU_IRC32K: + case RCU_PLL_CK: + case RCU_PLLI2S_CK: + case RCU_PLLSAI_CK: + 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; + case RCU_IRC16M: + case RCU_IRC48M: + case RCU_IRC32K: + case RCU_PLL_CK: + case RCU_PLLI2S_CK: + case RCU_PLLSAI_CK: + break; + default: + break; + } +} + +/*! + \brief set the IRC16M adjust value + \param[in] irc16m_adjval: IRC16M adjust value, must be between 0 and 0x1F + \arg 0x00 - 0x1F + \param[out] none + \retval none +*/ +void rcu_irc16m_adjust_value_set(uint32_t irc16m_adjval) +{ + uint32_t reg; + + reg = RCU_CTL; + /* reset the IRC16MADJ bits and set according to irc16m_adjval */ + reg &= ~RCU_CTL_IRC16MADJ; + RCU_CTL = (reg | ((irc16m_adjval & RCU_IRC16M_ADJUST_MASK) << RCU_IRC16M_ADJUST_OFFSET)); +} + +/*! + \brief configure the spread spectrum modulation for the main PLL clock + \param[in] spread_spectrum_type: PLL spread spectrum modulation type select + \arg RCU_SS_TYPE_CENTER: center spread type is selected + \arg RCU_SS_TYPE_DOWN: down spread type is selected + \param[in] modstep: configure PLL spread spectrum modulation profile amplitude and frequency + \arg This parameter should be selected between 0 and 7FFF.The following criteria must be met: MODSTEP*MODCNT <=2^15-1 + \param[in] modcnt: configure PLL spread spectrum modulation profile amplitude and frequency + \arg This parameter should be selected between 0 and 1FFF.The following criteria must be met: MODSTEP*MODCNT <=2^15-1 + \param[out] none + \retval none +*/ +void rcu_spread_spectrum_config(uint32_t spread_spectrum_type, uint32_t modstep, uint32_t modcnt) +{ + uint32_t reg; + + reg = RCU_PLLSSCTL; + /* reset the RCU_PLLSSCTL register bits */ + reg &= ~(RCU_PLLSSCTL_MODCNT | RCU_PLLSSCTL_MODSTEP | RCU_PLLSSCTL_SS_TYPE); + RCU_PLLSSCTL = (reg | spread_spectrum_type | modstep << 13 | modcnt); +} + +/*! + \brief enable the PLL spread spectrum modulation + \param[in] none + \param[out] none + \retval none +*/ +void rcu_spread_spectrum_enable(void) +{ + RCU_PLLSSCTL |= RCU_PLLSSCTL_SSCGON; +} + +/*! + \brief disable the PLL spread spectrum modulation + \param[in] none + \param[out] none + \retval none +*/ +void rcu_spread_spectrum_disable(void) +{ + RCU_PLLSSCTL &= ~RCU_PLLSSCTL_SSCGON; +} + +/*! + \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 unlock the voltage key + \param[in] none + \param[out] none + \retval none +*/ +void rcu_voltage_key_unlock(void) +{ + RCU_VKEY = RCU_VKEY_UNLOCK; +} + +/*! + \brief deep-sleep mode voltage select + \param[in] dsvol: deep sleep mode voltage + only one parameter can be selected which is shown as below: + \arg RCU_DEEPSLEEP_V_0: the core voltage is default value + \arg RCU_DEEPSLEEP_V_1: the core voltage is (default value-0.1)V(customers are not recommended to use it) + \arg RCU_DEEPSLEEP_V_2: the core voltage is (default value-0.2)V(customers are not recommended to use it) + \arg RCU_DEEPSLEEP_V_3: the core voltage is (default value-0.3)V(customers are not recommended to use it) + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + dsvol &= RCU_DSV_DSLPVS; + RCU_DSV = dsvol; +} + +/*! + \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 + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2 +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws, ck_freq = 0U; + uint32_t cksys_freq, ahb_freq, apb1_freq, apb2_freq; + uint32_t pllpsc, plln, pllsel, pllp, ck_src, idx, clk_exp; + + /* 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}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws) { + /* IRC16M is selected as CK_SYS */ + case SEL_IRC16M: + cksys_freq = IRC16M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLLP is selected as CK_SYS */ + case SEL_PLLP: + /* get the value of PLLPSC[5:0] */ + pllpsc = GET_BITS(RCU_PLL, 0U, 5U); + plln = GET_BITS(RCU_PLL, 6U, 14U); + pllp = (GET_BITS(RCU_PLL, 16U, 17U) + 1U) * 2U; + /* PLL clock source selection, HXTAL or IRC16M/2 */ + pllsel = (RCU_PLL & RCU_PLL_PLLSEL); + if(RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else { + ck_src = IRC16M_VALUE; + } + cksys_freq = ((ck_src / pllpsc) * plln) / pllp; + break; + /* IRC16M is selected as CK_SYS */ + default: + cksys_freq = IRC16M_VALUE; + 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; + + /* 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; + 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_IRC16MSTB: IRC16M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_PLLI2SSTB: PLLI2S stabilization flag + \arg RCU_FLAG_PLLSAISTB: PLLSAI 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_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 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_IRC16MSTB: IRC16M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLI2SSTB: PLLI2S stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSAISTB: PLLSAI stabilization interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \arg RCU_INT_FLAG_IRC48MSTB: IRC48M 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_IRC16MSTB_CLR: IRC16M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLI2SSTB_CLR: PLLI2S stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSAISTB_CLR: PLLSAI stabilization interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \arg RCU_INT_FLAG_IRC48MSTB_CLR: IRC48M 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)); +} + +/*! + \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_IRC16MSTB: IRC16M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt enable + \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt enable + \arg RCU_INT_IRC48MSTB: IRC48M 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_IRC16MSTB: IRC16M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable + \arg RCU_INT_PLLI2SSTB: PLLI2S stabilization interrupt disable + \arg RCU_INT_PLLSAISTB: PLLSAI stabilization interrupt disable + \arg RCU_INT_IRC48MSTB: IRC48M 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)); +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rtc.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rtc.c new file mode 100644 index 000000000..1fd78059a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_rtc.c @@ -0,0 +1,1294 @@ +/*! + \file gd32f4xx_rtc.c + \brief RTC driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_rtc.h" + +/* RTC timeout value */ +#define RTC_WTWF_TIMEOUT ((uint32_t)0x00004000U) /*!< wakeup timer can be write 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 write flag timeout */ + +/*! + \brief reset most of the RTC registers + \param[in] none + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + ErrStatus error_status = GD_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; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(GD_ERROR != error_status) { + /* reset RTC_CTL register, but RTC_CTL[2��0] */ + RTC_CTL &= (RTC_REGISTER_RESET | RTC_CTL_WTCS); + /* 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; + /* 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 = GD_ERROR; + } else { + RTC_CTL &= RTC_REGISTER_RESET; + RTC_WUT = RTC_WUT_RESET; + RTC_COSC = RTC_REGISTER_RESET; + /* to write RTC_ALRMxSS register, ALRMxEN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM1TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + RTC_ALRM1SS = 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; + /* reset RTC_SHIFTCTL and RTC_HRFC register, this 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_WEDSDAY, 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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct *rtc_initpara_struct) +{ + ErrStatus error_status = GD_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(GD_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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + volatile uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = GD_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 > 0U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status) { + error_status = GD_SUCCESS; + } + } else { + error_status = GD_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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = GD_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 = GD_SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + } else { + error_status = GD_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_WEDSDAY, 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_WEDSDAY, 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; + + 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)); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + 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 + \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MASKSSC_1_14: mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared + \arg RTC_MASKSSC_2_14: mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared + \arg RTC_MASKSSC_3_14: mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared + \arg RTC_MASKSSC_4_14: mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared + \arg RTC_MASKSSC_5_14: mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared + \arg RTC_MASKSSC_6_14: mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared + \arg RTC_MASKSSC_7_14: mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared + \arg RTC_MASKSSC_8_14: mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared + \arg RTC_MASKSSC_9_14: mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared + \arg RTC_MASKSSC_10_14: mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared + \arg RTC_MASKSSC_11_14: mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared + \arg RTC_MASKSSC_12_14: mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared + \arg RTC_MASKSSC_13_14: mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared + \arg RTC_MASKSSC_14: mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared + \arg RTC_MASKSSC_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; + + 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_WEDSDAY, 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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_alarm_disable(uint8_t rtc_alarm) +{ + volatile uint32_t time_index = RTC_ALRMXWF_TIMEOUT; + ErrStatus error_status = GD_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 = GD_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 + \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; + + /* 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); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + 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 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_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + 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 RTC time-stamp mapping + \param[in] rtc_af: + \arg RTC_AF0_TIMESTAMP: RTC_AF0 use for timestamp + \arg RTC_AF1_TIMESTAMP: RTC_AF1 use for timestamp + \param[out] none + \retval none +*/ +void rtc_timestamp_pin_map(uint32_t rtc_af) +{ + RTC_TAMP &= ~RTC_TAMP_TSSEL; + RTC_TAMP |= rtc_af; +} + +/*! + \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 + \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 RTC tamper0 mapping + \param[in] rtc_af: + \arg RTC_AF0_TAMPER0: RTC_AF0 use for tamper0 + \arg RTC_AF1_TAMPER0: RTC_AF1 use for tamper0 + \param[out] none + \retval none +*/ +void rtc_tamper0_pin_map(uint32_t rtc_af) +{ + RTC_TAMP &= ~(RTC_TAMP_TP0EN | RTC_TAMP_TP0SEL); + RTC_TAMP |= rtc_af; +} + +/*! + \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: 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_TAMP_TPIE); + /* enable the interrupts in RTC_TAMP register */ + RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disble specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be disabled + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM0: alarm interrupt + \arg RTC_INT_ALARM1: alarm interrupt + \arg RTC_INT_TAMP: 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_STAT_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_ALRM0: alarm0 occurs flag + \arg RTC_FLAG_ALRM1: 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_ALRM0W: alarm0 configuration can be write flag + \arg RTC_FLAG_ALRM1W: alarm1 configuration can be write flag + \arg RTC_FLAG_WTW: wakeup timer can be write 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 + \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) +{ + RTC_STAT &= (uint32_t)(~flag); +} + +/*! + \brief configure rtc alarm output source + \param[in] source: specify signal to output + \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 + \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_TAMP &= ~RTC_TAMP_AOT; + + RTC_CTL |= (uint32_t)(source); + /* alarm output */ + RTC_TAMP |= (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 + \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 + \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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) +{ + volatile uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = GD_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 |= 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 &= ~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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = GD_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(GD_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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = GD_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(GD_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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_wakeup_disable(void) +{ + ErrStatus error_status = GD_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 = GD_ERROR; + } else { + error_status = GD_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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock) +{ + ErrStatus error_status = GD_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 = GD_ERROR; + } else { + RTC_CTL &= (uint32_t)~ RTC_CTL_WTCS; + RTC_CTL |= (uint32_t)wakeup_clock; + error_status = GD_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: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer) +{ + ErrStatus error_status = GD_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 = GD_ERROR; + } else { + RTC_WUT = (uint32_t)wakeup_timer; + error_status = GD_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: GD_ERROR or GD_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 = GD_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 = GD_SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC coarse calibration + \param[in] none + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_coarse_calibration_enable(void) +{ + ErrStatus error_status = GD_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(GD_ERROR != error_status) { + RTC_CTL |= (uint32_t)RTC_CTL_CCEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief disable RTC coarse calibration + \param[in] none + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_coarse_calibration_disable(void) +{ + ErrStatus error_status = GD_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(GD_ERROR != error_status) { + RTC_CTL &= (uint32_t)~RTC_CTL_CCEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief config coarse calibration direction and step + \param[in] direction: CALIB_INCREASE or CALIB_DECREASE + \param[in] step: 0x00-0x1F + COSD=0: + 0x00:+0 PPM + 0x01:+4 PPM + 0x02:+8 PPM + .... + 0x1F:+126 PPM + COSD=1: + 0x00:-0 PPM + 0x01:-2 PPM + 0x02:-4 PPM + .... + 0x1F:-63 PPM + \param[out] none + \retval ErrStatus: GD_ERROR or GD_SUCCESS +*/ +ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step) +{ + ErrStatus error_status = GD_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(GD_ERROR != error_status) { + if(CALIB_DECREASE == direction) { + RTC_COSC |= (uint32_t)RTC_COSC_COSD; + } else { + RTC_COSC &= (uint32_t)~RTC_COSC_COSD; + } + RTC_COSC &= ~RTC_COSC_COSS; + RTC_COSC |= (uint32_t)((uint32_t)step & 0x1FU); + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_sdio.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_sdio.c new file mode 100644 index 000000000..867e97d93 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_sdio.c @@ -0,0 +1,804 @@ +/*! + \file gd32f4xx_sdio.c + \brief SDIO driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.1, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_sdio.h" + +/*! + \brief deinitialize the SDIO + \param[in] none + \param[out] none + \retval none +*/ +void sdio_deinit(void) +{ + rcu_periph_reset_enable(RCU_SDIORST); + rcu_periph_reset_disable(RCU_SDIORST); +} + +/*! + \brief configure the SDIO clock + \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_bypass: clock bypass + only one parameter can be selected which is shown as below: + \arg SDIO_CLOCKBYPASS_ENABLE: clock bypass + \arg SDIO_CLOCKBYPASS_DISABLE: no bypass + \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 512 + \param[out] none + \retval none +*/ +void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division) +{ + uint32_t clock_config = 0U; + clock_config = SDIO_CLKCTL; + /* reset the CLKEDGE, CLKBYP, CLKPWRSAV, DIV */ + clock_config &= ~(SDIO_CLKCTL_CLKEDGE | SDIO_CLKCTL_CLKBYP | SDIO_CLKCTL_CLKPWRSAV | SDIO_CLKCTL_DIV8 | SDIO_CLKCTL_DIV); + /* if the clock division is greater or equal to 256, set the DIV[8] */ + if(clock_division >= 256U) { + clock_config |= SDIO_CLKCTL_DIV8; + clock_division -= 256U; + } + /* configure the SDIO_CLKCTL according to the parameters */ + clock_config |= (clock_edge | clock_bypass | clock_powersave | clock_division); + SDIO_CLKCTL = clock_config; +} + +/*! + \brief enable hardware clock control + \param[in] none + \param[out] none + \retval none +*/ +void sdio_hardware_clock_enable(void) +{ + SDIO_CLKCTL |= SDIO_CLKCTL_HWCLKEN; +} + +/*! + \brief disable hardware clock control + \param[in] none + \param[out] none + \retval none +*/ +void sdio_hardware_clock_disable(void) +{ + SDIO_CLKCTL &= ~SDIO_CLKCTL_HWCLKEN; +} + +/*! + \brief set different SDIO card bus mode + \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 bus_mode) +{ + /* reset the SDIO card bus mode bits and set according to bus_mode */ + SDIO_CLKCTL &= ~SDIO_CLKCTL_BUSMODE; + SDIO_CLKCTL |= bus_mode; +} + +/*! + \brief set the SDIO power state + \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_OFF: SDIO power off + \param[out] none + \retval none +*/ +void sdio_power_state_set(uint32_t power_state) +{ + SDIO_PWRCTL = power_state; +} + +/*! + \brief get the SDIO power state + \param[in] none + \param[out] none + \retval SDIO power state + \arg SDIO_POWER_ON: SDIO power on + \arg SDIO_POWER_OFF: SDIO power off +*/ +uint32_t sdio_power_state_get(void) +{ + return SDIO_PWRCTL; +} + +/*! + \brief enable SDIO_CLK clock output + \param[in] none + \param[out] none + \retval none +*/ +void sdio_clock_enable(void) +{ + SDIO_CLKCTL |= SDIO_CLKCTL_CLKEN; +} + +/*! + \brief disable SDIO_CLK clock output + \param[in] none + \param[out] none + \retval none +*/ +void sdio_clock_disable(void) +{ + SDIO_CLKCTL &= ~SDIO_CLKCTL_CLKEN; +} + +/*! + \brief configure the command and response + \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_LONG: long response + \param[out] none + \retval none +*/ +void sdio_command_response_config(uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type) +{ + uint32_t cmd_config = 0U; + /* disable the CSM */ + SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN; + /* reset the command index, command argument and response type */ + SDIO_CMDAGMT &= ~SDIO_CMDAGMT_CMDAGMT; + SDIO_CMDAGMT = cmd_argument; + cmd_config = SDIO_CMDCTL; + 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 = cmd_config; +} + +/*! + \brief set the command state machine wait type + \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 wait_type) +{ + /* reset INTWAIT and WAITDEND */ + SDIO_CMDCTL &= ~(SDIO_CMDCTL_INTWAIT | SDIO_CMDCTL_WAITDEND); + /* set the wait type according to wait_type */ + SDIO_CMDCTL |= wait_type; +} + +/*! + \brief enable the CSM(command state machine) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_csm_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_CSMEN; +} + +/*! + \brief disable the CSM(command state machine) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_csm_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN; +} + +/*! + \brief get the last response command index + \param[in] none + \param[out] none + \retval last response command index +*/ +uint8_t sdio_command_index_get(void) +{ + return (uint8_t)SDIO_RSPCMDIDX; +} + +/*! + \brief get the response for the last received command + \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_responsex) +{ + uint32_t resp_content = 0U; + switch(sdio_responsex) { + case SDIO_RESPONSE0: + resp_content = SDIO_RESP0; + break; + case SDIO_RESPONSE1: + resp_content = SDIO_RESP1; + break; + case SDIO_RESPONSE2: + resp_content = SDIO_RESP2; + break; + case SDIO_RESPONSE3: + resp_content = SDIO_RESP3; + break; + default: + break; + } + return resp_content; +} + +/*! + \brief configure the data timeout, data length and data block size + \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 data_timeout, uint32_t data_length, uint32_t data_blocksize) +{ + /* reset data timeout, data length and data block size */ + SDIO_DATATO &= ~SDIO_DATATO_DATATO; + SDIO_DATALEN &= ~SDIO_DATALEN_DATALEN; + SDIO_DATACTL &= ~SDIO_DATACTL_BLKSZ; + /* configure the related parameters of data */ + SDIO_DATATO = data_timeout; + SDIO_DATALEN = data_length; + SDIO_DATACTL |= data_blocksize; +} + +/*! + \brief configure the data transfer mode and direction + \param[in] transfer_mode: mode of data transfer + only one parameter can be selected which is shown as below: + \arg SDIO_TRANSMODE_BLOCK: block transfer + \arg SDIO_TRANSMODE_STREAM: stream transfer or SDIO multibyte transfer + \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 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; + data_trans &= ~(SDIO_DATACTL_TRANSMOD | SDIO_DATACTL_DATADIR); + data_trans |= (transfer_mode | transfer_direction); + SDIO_DATACTL = data_trans; +} + +/*! + \brief enable the DSM(data state machine) for data transfer + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dsm_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_DATAEN; +} + +/*! + \brief disable the DSM(data state machine) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dsm_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_DATAEN; +} + +/*! + \brief write data(one word) to the transmit FIFO + \param[in] data: 32-bit data write to card + \param[out] none + \retval none +*/ +void sdio_data_write(uint32_t data) +{ + SDIO_FIFO = data; +} + +/*! + \brief read data(one word) from the receive FIFO + \param[in] none + \param[out] none + \retval received data +*/ +uint32_t sdio_data_read(void) +{ + return SDIO_FIFO; +} + +/*! + \brief get the number of remaining data bytes to be transferred to card + \param[in] none + \param[out] none + \retval number of remaining data bytes to be transferred +*/ +uint32_t sdio_data_counter_get(void) +{ + return SDIO_DATACNT; +} + +/*! + \brief get the number of words remaining to be written or read from FIFO + \param[in] none + \param[out] none + \retval remaining number of words +*/ +uint32_t sdio_fifo_counter_get(void) +{ + return SDIO_FIFOCNT; +} + +/*! + \brief enable the DMA request for SDIO + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dma_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_DMAEN; +} + +/*! + \brief disable the DMA request for SDIO + \param[in] none + \param[out] none + \retval none +*/ +void sdio_dma_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_DMAEN; +} + +/*! + \brief get the flags state of SDIO + \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_STBITE: start bit error in the bus flag + \arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_FLAG_CMDRUN: command transmission in progress flag + \arg SDIO_FLAG_TXRUN: data transmission in progress flag + \arg SDIO_FLAG_RXRUN: data reception in progress 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_TXDTVAL: data is valid in transmit FIFO flag + \arg SDIO_FLAG_RXDTVAL: data is valid in receive FIFO flag + \arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag + \arg SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sdio_flag_get(uint32_t flag) +{ + FlagStatus temp_flag = RESET; + if(RESET != (SDIO_STAT & flag)) { + temp_flag = SET; + } + return temp_flag; +} + +/*! + \brief clear the pending flags of SDIO + \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_STBITE: start bit error in the bus flag + \arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag + \arg SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag + \param[out] none + \retval none +*/ +void sdio_flag_clear(uint32_t flag) +{ + SDIO_INTC = flag; +} + +/*! + \brief enable the SDIO interrupt + \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_STBITE: SDIO STBITE interrupt + \arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt + \arg SDIO_INT_CMDRUN: SDIO CMDRUN interrupt + \arg SDIO_INT_TXRUN: SDIO TXRUN interrupt + \arg SDIO_INT_RXRUN: SDIO RXRUN interrupt + \arg SDIO_INT_TFH: SDIO TFH interrupt + \arg SDIO_INT_RFH: SDIO RFH interrupt + \arg SDIO_INT_TFF: SDIO TFF interrupt + \arg SDIO_INT_RFF: SDIO RFF interrupt + \arg SDIO_INT_TFE: SDIO TFE interrupt + \arg SDIO_INT_RFE: SDIO RFE interrupt + \arg SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt + \arg SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt + \arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt + \arg SDIO_INT_ATAEND: SDIO ATAEND interrupt + \param[out] none + \retval none +*/ +void sdio_interrupt_enable(uint32_t int_flag) +{ + SDIO_INTEN |= int_flag; +} + +/*! + \brief disable the SDIO interrupt + \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_STBITE: SDIO STBITE interrupt + \arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt + \arg SDIO_INT_CMDRUN: SDIO CMDRUN interrupt + \arg SDIO_INT_TXRUN: SDIO TXRUN interrupt + \arg SDIO_INT_RXRUN: SDIO RXRUN interrupt + \arg SDIO_INT_TFH: SDIO TFH interrupt + \arg SDIO_INT_RFH: SDIO RFH interrupt + \arg SDIO_INT_TFF: SDIO TFF interrupt + \arg SDIO_INT_RFF: SDIO RFF interrupt + \arg SDIO_INT_TFE: SDIO TFE interrupt + \arg SDIO_INT_RFE: SDIO RFE interrupt + \arg SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt + \arg SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt + \arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt + \arg SDIO_INT_ATAEND: SDIO ATAEND interrupt + \param[out] none + \retval none +*/ +void sdio_interrupt_disable(uint32_t int_flag) +{ + SDIO_INTEN &= ~int_flag; +} + +/*! + \brief get the interrupt flags state of SDIO + \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_STBITE: SDIO STBITE interrupt flag + \arg SDIO_INT_FLAG_DTBLKEND: SDIO DTBLKEND interrupt flag + \arg SDIO_INT_FLAG_CMDRUN: SDIO CMDRUN interrupt flag + \arg SDIO_INT_FLAG_TXRUN: SDIO TXRUN interrupt flag + \arg SDIO_INT_FLAG_RXRUN: SDIO RXRUN interrupt flag + \arg SDIO_INT_FLAG_TFH: SDIO TFH interrupt flag + \arg SDIO_INT_FLAG_RFH: SDIO RFH interrupt flag + \arg SDIO_INT_FLAG_TFF: SDIO TFF interrupt flag + \arg SDIO_INT_FLAG_RFF: SDIO RFF interrupt flag + \arg SDIO_INT_FLAG_TFE: SDIO TFE interrupt flag + \arg SDIO_INT_FLAG_RFE: SDIO RFE interrupt flag + \arg SDIO_INT_FLAG_TXDTVAL: SDIO TXDTVAL interrupt flag + \arg SDIO_INT_FLAG_RXDTVAL: SDIO RXDTVAL interrupt flag + \arg SDIO_INT_FLAG_SDIOINT: SDIO SDIOINT interrupt flag + \arg SDIO_INT_FLAG_ATAEND: SDIO ATAEND interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus sdio_interrupt_flag_get(uint32_t int_flag) +{ + FlagStatus temp_flag = RESET; + if(RESET != (SDIO_STAT & int_flag)) { + temp_flag = SET; + } + return temp_flag; +} + +/*! + \brief clear the interrupt pending flags of SDIO + \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: command response received (CRC check failed) flag + \arg SDIO_INT_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag + \arg SDIO_INT_FLAG_CMDTMOUT: command response timeout flag + \arg SDIO_INT_FLAG_DTTMOUT: data timeout flag + \arg SDIO_INT_FLAG_TXURE: transmit FIFO underrun error occurs flag + \arg SDIO_INT_FLAG_RXORE: received FIFO overrun error occurs flag + \arg SDIO_INT_FLAG_CMDRECV: command response received (CRC check passed) flag + \arg SDIO_INT_FLAG_CMDSEND: command sent (no response required) flag + \arg SDIO_INT_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag + \arg SDIO_INT_FLAG_STBITE: start bit error in the bus flag + \arg SDIO_INT_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag + \arg SDIO_INT_FLAG_SDIOINT: SD I/O interrupt received flag + \arg SDIO_INT_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag + \param[out] none + \retval none +*/ +void sdio_interrupt_flag_clear(uint32_t int_flag) +{ + SDIO_INTC = int_flag; +} + +/*! + \brief enable the read wait mode(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_readwait_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_RWEN; +} + +/*! + \brief disable the read wait mode(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_readwait_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_RWEN; +} + +/*! + \brief enable the function that stop the read wait process(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_stop_readwait_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_RWSTOP; +} + +/*! + \brief disable the function that stop the read wait process(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_stop_readwait_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_RWSTOP; +} + +/*! + \brief set the read wait type(SD I/O only) + \param[in] readwait_type: SD I/O read wait type + only one parameter can be selected which is shown as below: + \arg SDIO_READWAITTYPE_CLK: read wait control by stopping SDIO_CLK + \arg SDIO_READWAITTYPE_DAT2: read wait control using SDIO_DAT[2] + \param[out] none + \retval none +*/ +void sdio_readwait_type_set(uint32_t readwait_type) +{ + if(SDIO_READWAITTYPE_CLK == readwait_type) { + SDIO_DATACTL |= SDIO_DATACTL_RWTYPE; + } else { + SDIO_DATACTL &= ~SDIO_DATACTL_RWTYPE; + } +} + +/*! + \brief enable the SD I/O mode specific operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_operation_enable(void) +{ + SDIO_DATACTL |= SDIO_DATACTL_IOEN; +} + +/*! + \brief disable the SD I/O mode specific operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_operation_disable(void) +{ + SDIO_DATACTL &= ~SDIO_DATACTL_IOEN; +} + +/*! + \brief enable the SD I/O suspend operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_suspend_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_SUSPEND; +} + +/*! + \brief disable the SD I/O suspend operation(SD I/O only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_suspend_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_SUSPEND; +} + +/*! + \brief enable the CE-ATA command(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_ATAEN; +} + +/*! + \brief disable the CE-ATA command(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_ATAEN; +} + +/*! + \brief enable the CE-ATA interrupt(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_interrupt_enable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_NINTEN; +} + +/*! + \brief disable the CE-ATA interrupt(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_interrupt_disable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_NINTEN; +} + +/*! + \brief enable the CE-ATA command completion signal(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_completion_enable(void) +{ + SDIO_CMDCTL |= SDIO_CMDCTL_ENCMDC; +} + +/*! + \brief disable the CE-ATA command completion signal(CE-ATA only) + \param[in] none + \param[out] none + \retval none +*/ +void sdio_ceata_command_completion_disable(void) +{ + SDIO_CMDCTL &= ~SDIO_CMDCTL_ENCMDC; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_spi.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_spi.c new file mode 100644 index 000000000..efaaed554 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_spi.c @@ -0,0 +1,893 @@ +/*! + \file gd32f4xx_spi.c + \brief SPI driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_spi.h" +#include "gd32f4xx_rcu.h" + +/* SPI/I2S parameter initialization mask */ +#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI parameter initialization mask */ +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */ +#define I2S_FULL_DUPLEX_MASK ((uint32_t)0x00000480U) /*!< I2S full duples mode configure parameter initialization mask */ + +/* default value */ +#define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /*!< default value of SPI_I2SPSC register */ + +/*! + \brief deinitialize SPI and I2S + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5),include I2S1_ADD and I2S2_ADD + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph) { + case SPI0: + /* reset SPI0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1,I2S1 and I2S1_ADD */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + case SPI2: + /* reset SPI2,I2S2 and I2S2_ADD */ + 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 */ + 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] none + \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->frame_size = SPI_FRAMESIZE_8BIT; + spi_struct->nss = SPI_NSS_HARD; + spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + spi_struct->prescale = SPI_PSC_2; + spi_struct->endian = SPI_ENDIAN_MSB; +} +/*! + \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 + frame_size: SPI_FRAMESIZE_16BIT, SPI_FRAMESIZE_8BIT + 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 reg = 0U; + reg = SPI_CTL0(spi_periph); + reg &= SPI_INIT_MASK; + + /* select SPI as master or slave */ + reg |= spi_struct->device_mode; + /* select SPI transfer mode */ + reg |= spi_struct->trans_mode; + /* select SPI frame size */ + reg |= spi_struct->frame_size; + /* select SPI nss use hardware or software */ + reg |= spi_struct->nss; + /* select SPI LSB or MSB */ + reg |= spi_struct->endian; + /* select SPI polarity and phase */ + reg |= spi_struct->clock_polarity_phase; + /* select SPI prescale to adjust transmit speed */ + reg |= spi_struct->prescale; + + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg; + + 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=1,2) + \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 prescale + \param[in] spi_periph: SPIx(x=1,2) + \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; + +#ifndef I2S_EXTERNAL_CLOCK_IN + uint32_t plli2sm = 0U, plli2sn = 0U, plli2sr = 0U; +#endif /* I2S_EXTERNAL_CLOCK_IN */ + + /* deinit SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = SPI_I2SPSC_DEFAULT_VALUE; + +#ifdef I2S_EXTERNAL_CLOCK_IN + rcu_i2s_clock_config(RCU_I2SSRC_I2S_CKIN); + + /* set the I2S clock to the external clock input value */ + i2sclock = I2S_EXTERNAL_CLOCK_IN; +#else + + /* turn on the oscillator HXTAL */ + rcu_osci_on(RCU_HXTAL); + /* wait for oscillator stabilization flags is SET */ + rcu_osci_stab_wait(RCU_HXTAL); + /* turn on the PLLI2S */ + rcu_osci_on(RCU_PLLI2S_CK); + /* wait for PLLI2S flags is SET */ + rcu_osci_stab_wait(RCU_PLLI2S_CK); + /* configure the I2S clock source selection */ + rcu_i2s_clock_config(RCU_I2SSRC_PLLI2S); + + /* get the RCU_PLL_PLLPSC value */ + plli2sm = (uint32_t)(RCU_PLL & RCU_PLL_PLLPSC); + /* get the RCU_PLLI2S_PLLI2SN value */ + plli2sn = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SN) >> 6); + /* get the RCU_PLLI2S_PLLI2SR value */ + plli2sr = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SR) >> 28); + + if((RCU_PLL & RCU_PLL_PLLSEL) == RCU_PLLSRC_HXTAL) { + /* get the I2S source clock value */ + i2sclock = (uint32_t)(((HXTAL_VALUE / plli2sm) * plli2sn) / plli2sr); + } else { + /* get the I2S source clock value */ + i2sclock = (uint32_t)(((IRC16M_VALUE / plli2sm) * plli2sn) / plli2sr); + } +#endif /* I2S_EXTERNAL_CLOCK_IN */ + + /* 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); + i2sof = (i2sof << 8U); + + /* set the default values */ + if((i2sdiv < 2U) || (i2sdiv > 255U)) { + i2sdiv = 2U; + i2sof = 0U; + } + + /* configure SPI_I2SPSC */ + SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | 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=1,2) + \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=1,2) + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \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_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_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_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_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_SWNSS; +} + +/*! + \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_SWNSS); +} + +/*! + \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_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + } else { + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief diable 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_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + } else { + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI/I2S data frame format + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] frame_format: SPI frame size + only one parameter can be selected which is shown as below: + \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits + \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits + \param[out] none + \retval none +*/ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + /* clear SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16); + /* configure SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= (uint32_t)frame_format; +} + +/*! + \brief SPI transmit data + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data) +{ + SPI_DATA(spi_periph) = (uint32_t)data; +} + +/*! + \brief SPI receive data + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 16-bit data +*/ +uint16_t spi_i2s_data_receive(uint32_t spi_periph) +{ + return ((uint16_t)SPI_DATA(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_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; + } else { + /* set the receive only mode */ + SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief configure i2s full duplex mode + \param[in] i2s_add_periph: I2Sx_ADD(x=1,2) + \param[in] i2s_mode: + \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: + \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: + \arg I2S_CKPL_LOW : I2S clock polarity low level + \arg I2S_CKPL_HIGH : I2S clock polarity high level + \param[in] i2s_frameformat: + \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[out] none + \retval none +*/ +void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard, + uint32_t i2s_ckpl, uint32_t i2s_frameformat) +{ + uint32_t reg = 0U, tmp = 0U; + + reg = I2S_ADD_I2SCTL(i2s_add_periph); + reg &= I2S_FULL_DUPLEX_MASK; + + /* get the mode of the extra I2S module I2Sx_ADD */ + if((I2S_MODE_MASTERTX == i2s_mode) || (I2S_MODE_SLAVETX == i2s_mode)) { + tmp = I2S_MODE_SLAVERX; + } else { + tmp = I2S_MODE_SLAVETX; + } + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)tmp; + /* select I2S standard */ + reg |= (uint32_t)i2s_standard; + /* select I2S polarity */ + reg |= (uint32_t)i2s_ckpl; + /* configure data frame format */ + reg |= (uint32_t)i2s_frameformat; + + /* write to SPI_I2SCTL register */ + I2S_ADD_I2SCTL(i2s_add_periph) = (uint32_t)reg; +} + +/*! + \brief clear SPI/I2S format error flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] flag: SPI/I2S frame format error flag + \arg SPI_FLAG_FERR: only for SPI work in TI mode + \arg I2S_FLAG_FERR: for I2S + \param[out] none + \retval none +*/ +void spi_i2s_format_error_clear(uint32_t spi_periph, uint32_t flag) +{ + SPI_STAT(spi_periph) = (uint32_t)(~flag); +} + +/*! + \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, uint16_t crc_poly) +{ + /* 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 16-bit CRC polynomial +*/ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + return ((uint16_t)SPI_CRCPOLY(spi_periph)); +} + +/*! + \brief turn on SPI 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_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief turn off SPI 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_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN); +} + +/*! + \brief SPI next data is CRC value + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_next(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT; +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_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 16-bit CRC value +*/ +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t spi_crc) +{ + if(SPI_CRC_TX == spi_crc) { + return ((uint16_t)(SPI_TCRC(spi_periph))); + } else { + return ((uint16_t)(SPI_RCRC(spi_periph))); + } +} + +/*! + \brief clear SPI CRC error flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) = (uint32_t)(~SPI_FLAG_CRCERR); +} + +/*! + \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_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_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_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD); +} + +/*! + \brief enable quad wire SPI + \param[in] spi_periph: SPIx(only x=5) + \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(only x=5) + \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(only x=5) + \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(only x=5) + \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(only x=5) + \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(only x=5) + \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 get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_flag: SPI/I2S flag status + only one parameter can be selected which are shown as below: + \arg SPI_FLAG_TBE: transmit buffer empty flag + \arg SPI_FLAG_RBNE: receive buffer not empty flag + \arg SPI_FLAG_TRANS: transmit on-going flag + \arg SPI_FLAG_RXORERR: receive overrun error flag + \arg SPI_FLAG_CONFERR: mode config error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: format error flag + \arg I2S_FLAG_TBE: transmit buffer empty flag + \arg I2S_FLAG_RBNE: receive buffer not empty flag + \arg I2S_FLAG_TRANS: transmit on-going flag + \arg I2S_FLAG_RXORERR: overrun error flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_CH: channel side flag + \arg I2S_FLAG_FERR: format 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 enable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_int: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt) { + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE; + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE; + break; + default: + break; + } +} + +/*! + \brief disable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[in] spi_i2s_int: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt) { + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE); + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE); + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR : + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE); + 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] spi_i2s_int: SPI/I2S interrupt flag status + only one parameter can be selected which are shown as below: + \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag + \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag + \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag + \arg SPI_INT_FLAG_CONFERR: config error interrupt flag + \arg SPI_INT_FLAG_CRCERR: CRC error interrupt flag + \arg I2S_INT_FLAG_TXURERR: underrun error interrupt flag + \arg SPI_I2S_INT_FLAG_FERR: format error 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_CTL1(spi_periph); + + switch(interrupt) { + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_FLAG_TBE : + reg1 = reg1 & SPI_STAT_TBE; + reg2 = reg2 & SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_FLAG_RBNE : + reg1 = reg1 & SPI_STAT_RBNE; + reg2 = reg2 & SPI_CTL1_RBNEIE; + break; + /* SPI/I2S overrun interrupt */ + case SPI_I2S_INT_FLAG_RXORERR : + reg1 = reg1 & SPI_STAT_RXORERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI config error interrupt */ + case SPI_INT_FLAG_CONFERR : + reg1 = reg1 & SPI_STAT_CONFERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI CRC error interrupt */ + case SPI_INT_FLAG_CRCERR : + reg1 = reg1 & SPI_STAT_CRCERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* I2S underrun error interrupt */ + case I2S_INT_FLAG_TXURERR : + reg1 = reg1 & SPI_STAT_TXURERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI/I2S format error interrupt */ + case SPI_I2S_INT_FLAG_FERR : + reg1 = reg1 & SPI_STAT_FERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + default : + break; + } + /*get SPI/I2S interrupt flag status */ + if(reg1 && reg2) { + return SET; + } else { + return RESET; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_syscfg.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_syscfg.c new file mode 100644 index 000000000..6b11c0139 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_syscfg.c @@ -0,0 +1,205 @@ +/*! + \file gd32f4xx_syscfg.c + \brief SYSCFG driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_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 configure the boot mode + \param[in] syscfg_bootmode: selects the memory remapping + only one parameter can be selected which is shown as below: + \arg SYSCFG_BOOTMODE_FLASH: main flash memory (0x08000000~0x083BFFFF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_BOOTLOADER: boot loader (0x1FFF0000 - 0x1FFF77FF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_EXMC_SRAM: SRAM/NOR 0 and 1 of EXMC (0x60000000~0x67FFFFFF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_SRAM: SRAM0 of on-chip SRAM (0x20000000~0x2001BFFF) is mapped at address 0x00000000 + \arg SYSCFG_BOOTMODE_EXMC_SDRAM: SDRAM bank0 of EXMC (0xC0000000~0xC7FFFFFF) is mapped at address 0x00000000 + \param[out] none + \retval none +*/ +void syscfg_bootmode_config(uint8_t syscfg_bootmode) +{ + /* reset the SYSCFG_CFG0_BOOT_MODE bit and set according to syscfg_bootmode */ + SYSCFG_CFG0 &= ~SYSCFG_CFG0_BOOT_MODE; + SYSCFG_CFG0 |= (uint32_t)syscfg_bootmode; +} + +/*! + \brief FMC memory mapping swap + \param[in] syscfg_fmc_swap: selects the interal flash bank swapping + only one parameter can be selected which is shown as below: + \arg SYSCFG_FMC_SWP_BANK0: bank 0 is mapped at address 0x08000000 and bank 1 is mapped at address 0x08100000 + \arg SYSCFG_FMC_SWP_BANK1: bank 1 is mapped at address 0x08000000 and bank 0 is mapped at address 0x08100000 + \param[out] none + \retval none +*/ +void syscfg_fmc_swap_config(uint32_t syscfg_fmc_swap) +{ + uint32_t reg; + reg = SYSCFG_CFG0; + /* reset the FMC_SWP bit and set according to syscfg_fmc_swap */ + reg &= ~SYSCFG_CFG0_FMC_SWP; + SYSCFG_CFG0 = (reg | syscfg_fmc_swap); +} + +/*! + \brief EXMC memory mapping swap + \param[in] syscfg_exmc_swap: selects the memories in EXMC swapping + only one parameter can be selected which is shown as below: + \arg SYSCFG_EXMC_SWP_ENABLE: SDRAM bank 0 and bank 1 are swapped with NAND bank 1 and PC card + \arg SYSCFG_EXMC_SWP_DISABLE: no memory mapping swap + \param[out] none + \retval none +*/ +void syscfg_exmc_swap_config(uint32_t syscfg_exmc_swap) +{ + uint32_t reg; + + reg = SYSCFG_CFG0; + /* reset the SYSCFG_CFG0_EXMC_SWP bits and set according to syscfg_exmc_swap */ + reg &= ~SYSCFG_CFG0_EXMC_SWP; + SYSCFG_CFG0 = (reg | syscfg_exmc_swap); +} + +/*! + \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,I): 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(x = 0..15): 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 configure the PHY interface for the ethernet MAC + \param[in] syscfg_enet_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 syscfg_enet_phy_interface) +{ + uint32_t reg; + + reg = SYSCFG_CFG1; + /* reset the ENET_PHY_SEL bit and set according to syscfg_enet_phy_interface */ + reg &= ~SYSCFG_CFG1_ENET_PHY_SEL; + SYSCFG_CFG1 = (reg | syscfg_enet_phy_interface); +} + +/*! + \brief configure the I/O compensation cell + \param[in] syscfg_compensation: specifies the I/O compensation cell mode + only one parameter can be selected which is shown as below: + \arg SYSCFG_COMPENSATION_ENABLE: I/O compensation cell is enabled + \arg SYSCFG_COMPENSATION_DISABLE: I/O compensation cell is disabled + \param[out] none + \retval none +*/ +void syscfg_compensation_config(uint32_t syscfg_compensation) +{ + 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_compensation); +} + +/*! + \brief checks whether the I/O compensation cell ready flag is set or not + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET + */ +FlagStatus syscfg_flag_get(void) +{ + if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)) { + return SET; + } else { + return RESET; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_timer.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_timer.c new file mode 100644 index 000000000..7d91bac15 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_timer.c @@ -0,0 +1,2064 @@ +/*! + \file gd32f4xx_timer.c + \brief TIMER driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_timer.h" + +/*! + \brief deinit a TIMER + \param[in] timer_periph: TIMERx(x=0..13) + \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 TIMER8: + /* reset TIMER8 */ + rcu_periph_reset_enable(RCU_TIMER8RST); + rcu_periph_reset_disable(RCU_TIMER8RST); + break; + case TIMER9: + /* reset TIMER9 */ + rcu_periph_reset_enable(RCU_TIMER9RST); + rcu_periph_reset_disable(RCU_TIMER9RST); + break; + case TIMER10: + /* reset TIMER10 */ + rcu_periph_reset_enable(RCU_TIMER10RST); + rcu_periph_reset_disable(RCU_TIMER10RST); + break; + case TIMER11: + /* reset TIMER11 */ + rcu_periph_reset_enable(RCU_TIMER11RST); + rcu_periph_reset_disable(RCU_TIMER11RST); + break; + case TIMER12: + /* reset TIMER12 */ + rcu_periph_reset_enable(RCU_TIMER12RST); + rcu_periph_reset_disable(RCU_TIMER12RST); + break; + case TIMER13: + /* reset TIMER13 */ + rcu_periph_reset_enable(RCU_TIMER13RST); + rcu_periph_reset_disable(RCU_TIMER13RST); + 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 = 65535U; + initpara->clockdivision = TIMER_CKDIV_DIV1; + initpara->repetitioncounter = 0U; +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0..13) + \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,(TIMER1,TIMER4,32 bit) + clockdivision: TIMER_CKDIV_DIV1,TIMER_CKDIV_DIV2,TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value,0~255 + \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) || (TIMER1 == timer_periph) || (TIMER2 == timer_periph) + || (TIMER3 == timer_periph) || (TIMER4 == timer_periph) || (TIMER7 == timer_periph)) { + TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR | TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->alignedmode; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + + if((TIMER5 != timer_periph) && (TIMER6 != timer_periph)) { + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CKDIV; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->clockdivision; + } + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + /* configure the repetition counter value */ + TIMER_CREP(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..13) + \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..13) + \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..13) + \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..13) + \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..13) + \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..13) + \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) + \param[in] aligned: + 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) + \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) + \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..13) + \param[in] prescaler: prescaler value,0~65535 + \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, uint8_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) + \param[in] repetition: the counter repetition value,0~255 + \param[out] none + \retval none +*/ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition) +{ + TIMER_CREP(timer_periph) = (uint32_t)repetition; +} + +/*! + \brief configure TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0..13) + \param[in] autoreload: the counter auto-reload value + \param[out] none + \retval none +*/ +void timer_autoreload_value_config(uint32_t timer_periph, uint32_t autoreload) +{ + TIMER_CAR(timer_periph) = (uint32_t)autoreload; +} + +/*! + \brief configure TIMER counter register value + \param[in] timer_periph: TIMERx(x=0..13) + \param[in] counter: the counter value,0~65535 + \param[out] none + \retval none +*/ +void timer_counter_value_config(uint32_t timer_periph, uint32_t counter) +{ + TIMER_CNT(timer_periph) = (uint32_t)counter; +} + +/*! + \brief read TIMER counter value + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval counter value +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0..13) + \param[out] none + \retval prescaler register value +*/ +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..8,11) + \param[in] spmode: + 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 update source + \param[in] timer_periph: TIMERx(x=0..13) + \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: please refer to the following parameters + \param[in] dma: specify which DMA to enable + one or more parameters can be selected which is shown as below: + \arg TIMER_DMA_UPD: update DMA,TIMERx(x=0..7) + \arg TIMER_DMA_CH0D: channel 0 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH1D: channel 1 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH2D: channel 2 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH3D: channel 3 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CMTD: commutation DMA request,TIMERx(x=0,7) + \arg TIMER_DMA_TRGD: trigger DMA request,TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: please refer to the following parameters + \param[in] dma: specify which DMA to disable + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA,TIMERx(x=0..7) + \arg TIMER_DMA_CH0D: channel 0 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH1D: channel 1 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH2D: channel 2 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CH3D: channel 3 DMA request,TIMERx(x=0..4,7) + \arg TIMER_DMA_CMTD: commutation DMA request ,TIMERx(x=0,7) + \arg TIMER_DMA_TRGD: trigger DMA request,TIMERx(x=0..4,7) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0..4,7) + \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 y is sent when channel y event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_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: please refer to the following parameters + \param[in] dma_baseaddr: + 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) + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP,TIMERx(x=0,7) + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG,TIMERx(x=0..4,7) + \arg TIMER_DMACFG_DMATA_DMATB: DMA transfer address is TIMER_DMATB,TIMERx(x=0..4,7) + \param[in] dma_lenth: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): 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: please refer to the following parameters + \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,TIMERx(x=0..13) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation,TIMERx(x=0..4,7..13) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation,TIMERx(x=0..4,7,8,11) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation,TIMERx(x=0..4,7) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation,TIMERx(x=0..4,7) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation,TIMERx(x=0,7) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation,TIMERx(x=0..4,7,8,11) + \arg TIMER_EVENT_SRC_BRKG: break event generation,TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief initialize TIMER break parameter struct + \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->breakpolarity = TIMER_BREAK_POLARITY_LOW; + breakpara->outputautostate = TIMER_OUTAUTO_DISABLE; + breakpara->protectmode = TIMER_CCHP_PROT_OFF; + breakpara->breakstate = TIMER_BREAK_DISABLE; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,7) + \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 + breakpolarity: TIMER_BREAK_POLARITY_LOW,TIMER_BREAK_POLARITY_HIGH + outputautostate: TIMER_OUTAUTO_ENABLE,TIMER_OUTAUTO_DISABLE + protectmode: TIMER_CCHP_PROT_OFF,TIMER_CCHP_PROT_0,TIMER_CCHP_PROT_1,TIMER_CCHP_PROT_2 + breakstate: TIMER_BREAK_ENABLE,TIMER_BREAK_DISABLE + \param[out] none + \retval none +*/ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara) +{ + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | + ((uint32_t)(breakpara->ideloffstate)) | + ((uint32_t)(breakpara->deadtime)) | + ((uint32_t)(breakpara->breakpolarity)) | + ((uint32_t)(breakpara->outputautostate)) | + ((uint32_t)(breakpara->protectmode)) | + ((uint32_t)(breakpara->breakstate))) ; +} + +/*! + \brief enable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,7) + \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) + \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) + \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 enable or disable channel capture/compare control shadow register + \param[in] timer_periph: TIMERx(x=0,7) + \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) + \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 + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl) +{ + if(TIMER_UPDATECTL_CCU == ccuctl) { + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + } else if(TIMER_UPDATECTL_CCUTRI == ccuctl) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; + } else { + /* illegal parameters */ + } +} + +/*! + \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 = (uint16_t)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: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0..4,7)) + \param[in] ocpara: TIMER channeln 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); + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS; + /* 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)) { + /* reset the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + /* set the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + /* reset the CH0NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + /* set the CH0NP 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; + } + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS; + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((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)((uint32_t)(ocpara->ocpolarity) << 4U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + /* reset the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + /* set the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 4U); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((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)((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)((uint32_t)(ocpara->ocnidlestate) << 2U); + } + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS; + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((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)((uint32_t)(ocpara->ocpolarity) << 8U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + /* reset the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + /* set the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 8U); + /* reset the CH2NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + /* set the CH2NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((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)((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)((uint32_t)(ocpara->ocnidlestate) << 4U); + } + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS; + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((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)((uint32_t)(ocpara->ocpolarity) << 12U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph)) { + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 6U); + } + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,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: PWM0 mode + \arg TIMER_OC_MODE_PWM1: PWM1 mode + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_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) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] pulse: channel output pulse value,0~65535 + \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; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] ocshadow: channel output shadow state + only one parameter can be selected which is shown as below: + \arg TIMER_OC_SHADOW_ENABLE: channel output shadow state enable + \arg TIMER_OC_SHADOW_DISABLE: channel output shadow state 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)((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)((uint32_t)(ocshadow) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] ocfast: channel output fast function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_FAST_ENABLE: channel output fast function enable + \arg TIMER_OC_FAST_DISABLE: channel output fast function disable + \param[out] none + \retval none +*/ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,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 + \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)((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)((uint32_t)occlear << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,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 + \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)((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)((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)((uint32_t)ocpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \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_CH0NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,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 + \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)((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)((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)((uint32_t)state << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,7) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0 + \arg TIMER_CH_1: TIMER channel1 + \arg TIMER_CH_2: TIMER channel2 + \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_CH0NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER channel input parameter struct + \param[in] icpara: TIMER channel intput 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: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[in] icpara: TIMER channel intput 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 + 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 CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + 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)((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 CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((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 CH2NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P | TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 8U); + + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection)); + + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((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(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 12U); + + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + 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: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,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; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0..4,7..13)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0..4,7)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0..4,7)) + \param[out] none + \retval channel capture compare register value +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value = 0U; + + switch(channel) { + /* read TIMER channel 0 capture compare register value */ + case TIMER_CH_0: + count_value = TIMER_CH0CV(timer_periph); + break; + /* read TIMER channel 1 capture compare register value */ + case TIMER_CH_1: + count_value = TIMER_CH1CV(timer_periph); + break; + /* read TIMER channel 2 capture compare register value */ + case TIMER_CH_2: + count_value = TIMER_CH2CV(timer_periph); + break; + /* read TIMER channel 3 capture compare register value */ + case TIMER_CH_3: + count_value = TIMER_CH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0 + \arg TIMER_CH_1: TIMER channel1 + \param[in] icpwm:TIMER channel intput 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 = 0x0U; + uint16_t icselection = 0x0U; + + /* 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 CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP 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 CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((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)((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)((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 CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((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)((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)((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 CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP 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) + \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 select TIMER input trigger source + \param[in] timer_periph: please refer to the following parameters + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SMCFG_TRGSEL_ETIFP: external trigger(TIMERx(x=0..4,7,8,11)) + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS); + TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0..7) + \param[in] outrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output(TIMERx(x=0..7,9,10,12,13)) + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output(TIMERx(x=0..7,9,10,12,13)) + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0..7,9,10,12,13)) + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channal0 as trigger output TRGO(TIMERx(x=0..4,7,9,10,12,13)) + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output(TIMERx(x=0..4,7,9,10,12,13)) + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output(TIMERx(x=0..4,7)) + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output(TIMERx(x=0..4,7)) + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output(TIMERx(x=0..4,7)) + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) |= (uint32_t)outrigger; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] slavemode: + only one parameter can be selected which is shown as below: + \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable(TIMERx(x=0..4,7,8,11)) + \arg TIMER_QUAD_DECODER_MODE0: quadrature decoder mode 0(TIMERx(x=0..4,7)) + \arg TIMER_QUAD_DECODER_MODE1: quadrature decoder mode 1(TIMERx(x=0..4,7)) + \arg TIMER_QUAD_DECODER_MODE2: quadrature decoder mode 2(TIMERx(x=0..4,7)) + \arg TIMER_SLAVE_MODE_RESTART: restart mode(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SLAVE_MODE_PAUSE: pause mode(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SLAVE_MODE_EVENT: event mode(TIMERx(x=0..4,7,8,11)) + \arg TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0.(TIMERx(x=0..4,7,8,11)) + \param[out] none + \retval none +*/ + +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + + TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] masterslave: + 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) + \param[in] extprescaler: + 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: + 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) + \param[in] decomode: + 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: + 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[in] ic1polarity: + 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_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, + uint16_t ic0polarity, uint16_t ic1polarity) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; + + 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)); + + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity | ((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0 + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1 + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2 + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3 + \param[out] none + \retval none +*/ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger) +{ + timer_input_trigger_source_select(timer_periph, intrigger); + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external trigger as external clock input + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] extrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \param[in] extpolarity: + 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 + \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 CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + /* set the CH1NP bit */ + 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 { + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP 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 input trigger source */ + timer_input_trigger_source_select(timer_periph, extrigger); + /* reset the SMC bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + /* set the SMC bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external clock mode0 + \param[in] timer_periph: TIMERx(x=0..4,7,8,11) + \param[in] extprescaler: + 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: + 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); + + /* reset the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS)); + /* set the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0..4,7) + \param[in] extprescaler: + 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: + 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) + \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 channel remap function + \param[in] timer_periph: TIMERx(x=1,4,10) + \param[in] remap: + only one parameter can be selected which is shown as below: + \arg TIMER1_ITI1_RMP_TIMER7_TRGO: timer1 internal trigger input1 remap to TIMER7_TRGO + \arg TIMER1_ITI1_RMP_ETHERNET_PTP: timer1 internal trigger input1 remap to ethernet PTP + \arg TIMER1_ITI1_RMP_USB_FS_SOF: timer1 internal trigger input1 remap to USB FS SOF + \arg TIMER1_ITI1_RMP_USB_HS_SOF: timer1 internal trigger input1 remap to USB HS SOF + \arg TIMER4_CI3_RMP_GPIO: timer4 channel 3 input remap to GPIO pin + \arg TIMER4_CI3_RMP_IRC32K: timer4 channel 3 input remap to IRC32K + \arg TIMER4_CI3_RMP_LXTAL: timer4 channel 3 input remap to LXTAL + \arg TIMER4_CI3_RMP_RTC_WAKEUP_INT: timer4 channel 3 input remap to RTC wakeup interrupt + \arg TIMER10_ITI1_RMP_GPIO: timer10 internal trigger input1 remap based on GPIO setting + \arg TIMER10_ITI1_RMP_RTC_HXTAL_DIV: timer10 internal trigger input1 remap HXTAL _DIV(clock used for RTC which is HXTAL clock divided by RTCDIV bits in RCU_CFG0 register) + \param[out] none + \retval none +*/ +void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap) +{ + TIMER_IRMP(timer_periph) = (uint32_t)remap; +} + +/*! + \brief configure TIMER write CHxVAL register selection + \param[in] timer_periph: TIMERx(x=0,1,2,13,14,15,16) + \param[in] ccsel: + 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) + \param[in] outsel: + 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 get TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag,TIMERx(x=0..4,7) + \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: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag,TIMERx(x=0..13) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0..4,7..13) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CMT: channel control update flag,TIMERx(x=0,7) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,7,8,11) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,7) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag,TIMERx(x=0..4,7) + \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: please refer to the following parameters + \param[in] interrupt: timer interrupt enable source + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) + \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: please refer to the following parameters + \param[in] interrupt: timer interrupt source enable + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0..13) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0..4,7..13) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0..4,7) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0..4,7) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,7) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,7) + \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 flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0..13) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,7) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) + \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,7) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) +{ + uint32_t val; + val = (TIMER_DMAINTEN(timer_periph) & interrupt); + if((RESET != (TIMER_INTF(timer_periph) & interrupt)) && (RESET != val)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0..13) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0..4,7..13) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0..4,7) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,7) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,7,8,11) + \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,7) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)interrupt); +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_tli.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_tli.c new file mode 100644 index 000000000..04f9e31ff --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_tli.c @@ -0,0 +1,598 @@ +/*! + \file gd32f4xx_tli.c + \brief TLI driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_tli.h" + +#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_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 + \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/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_trng.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_trng.c new file mode 100644 index 000000000..8330a57fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_trng.c @@ -0,0 +1,156 @@ +/*! + \file gd32f4xx_trng.c + \brief TRNG driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_trng.h" + +/*! + \brief reset 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 TRNG + \param[in] none + \param[out] none + \retval none +*/ +void trng_enable(void) +{ + TRNG_CTL |= TRNG_CTL_TRNGEN; +} + +/*! + \brief disable TRNG + \param[in] none + \param[out] none + \retval none +*/ +void trng_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_TRNGEN; +} + +/*! + \brief get the true random data + \param[in] none + \param[out] none + \retval uint32_t: 0x0-0xFFFFFFFF +*/ +uint32_t trng_get_true_random_data(void) +{ + return (TRNG_DATA); +} + +/*! + \brief enable TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_enable(void) +{ + TRNG_CTL |= TRNG_CTL_TRNGIE; +} + +/*! + \brief disable TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_TRNGIE; +} + +/*! + \brief get TRNG flag status + \param[in] flag: TRNG flag + 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 get TRNG interrupt flag status + \param[in] int_flag: TRNG interrupt flag + 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 TRNG interrupt flag status + \param[in] int_flag: TRNG interrupt flag + 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/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_usart.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_usart.c new file mode 100644 index 000000000..e52591be0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_usart.c @@ -0,0 +1,981 @@ +/*! + \file gd32f4xx_usart.c + \brief USART driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_usart.h" + +/* USART register bit offset */ +#define GP_GUAT_OFFSET ((uint32_t)8U) /* bit offset of GUAT in USART_GP */ +#define CTL3_SCRTNUM_OFFSET ((uint32_t)1U) /* bit offset of SCRTNUM in USART_CTL3 */ +#define RT_BL_OFFSET ((uint32_t)24U) /* bit offset of BL in USART_RT */ + +/*! + \brief reset USART/UART + \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: + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + case USART2: + rcu_periph_reset_enable(RCU_USART2RST); + rcu_periph_reset_disable(RCU_USART2RST); + break; + case USART5: + rcu_periph_reset_enable(RCU_USART5RST); + rcu_periph_reset_disable(RCU_USART5RST); + break; + case UART3: + rcu_periph_reset_enable(RCU_UART3RST); + rcu_periph_reset_disable(RCU_UART3RST); + break; + case UART4: + rcu_periph_reset_enable(RCU_UART4RST); + rcu_periph_reset_disable(RCU_UART4RST); + break; + case UART6: + rcu_periph_reset_enable(RCU_UART6RST); + rcu_periph_reset_disable(RCU_UART6RST); + break; + case 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: + uclk = rcu_clock_freq_get(CK_APB2); + break; + case USART5: + uclk = rcu_clock_freq_get(CK_APB2); + break; + case USART1: + uclk = rcu_clock_freq_get(CK_APB1); + break; + case USART2: + uclk = rcu_clock_freq_get(CK_APB1); + break; + case UART3: + uclk = rcu_clock_freq_get(CK_APB1); + break; + case UART4: + uclk = rcu_clock_freq_get(CK_APB1); + break; + case UART6: + uclk = rcu_clock_freq_get(CK_APB1); + break; + case UART7: + uclk = rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD) { + /* when oversampling by 8, configure the value of USART_BAUD */ + udiv = ((2U * uclk) + baudval / 2U) / baudval; + intdiv = udiv & 0xfff0U; + fradiv = (udiv >> 1U) & 0x7U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } else { + /* when oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk + baudval / 2U) / baudval; + intdiv = udiv & 0xfff0U; + fradiv = udiv & 0xfU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity function + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] paritycfg: configure USART parity + only one parameter can be selected which is shown as below: + \arg USART_PM_NONE: no parity + \arg USART_PM_EVEN: even parity + \arg USART_PM_ODD: odd parity + \param[out] none + \retval none +*/ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) +{ + /* 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 + \param[out] none + \retval none +*/ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen) +{ + /* clear USART_CTL0 WL bit */ + USART_CTL0(usart_periph) &= ~USART_CTL0_WL; + /* 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.5 bit(not available for UARTx(x=3,4,6,7)) + \arg USART_STB_2BIT: 2 bits + \arg USART_STB_1_5BIT: 1.5 bits(not available for UARTx(x=3,4,6,7)) + \param[out] none + \retval none +*/ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) +{ + /* clear USART_CTL1 STB bits */ + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + /* configure USART stop bits */ + 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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL0(usart_periph); + ctl &= ~USART_CTL0_TEN; + ctl |= txconfig; + /* configure transfer mode */ + USART_CTL0(usart_periph) = ctl; +} + +/*! + \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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL0(usart_periph); + ctl &= ~USART_CTL0_REN; + ctl |= rxconfig; + /* configure transfer mode */ + USART_CTL0(usart_periph) = ctl; +} + +/*! + \brief data is transmitted/received with the LSB/MSB first + \param[in] usart_periph: USARTx(x=0,1,2,5) + \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) +{ + uint32_t ctl = 0U; + + ctl = USART_CTL3(usart_periph); + ctl &= ~(USART_CTL3_MSBF); + ctl |= msbf; + /* configure data transmitted/received mode */ + USART_CTL3(usart_periph) = ctl; +} + +/*! + \brief configure USART inversion + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] invertpara: refer to enum USART_INVERT_CONFIG + 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 + \param[out] none + \retval none +*/ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) +{ + /* inverted or not the specified siginal */ + switch(invertpara) { + case USART_DINV_ENABLE: + USART_CTL3(usart_periph) |= USART_CTL3_DINV; + break; + case USART_TXPIN_ENABLE: + USART_CTL3(usart_periph) |= USART_CTL3_TINV; + break; + case USART_RXPIN_ENABLE: + USART_CTL3(usart_periph) |= USART_CTL3_RINV; + break; + case USART_DINV_DISABLE: + USART_CTL3(usart_periph) &= ~(USART_CTL3_DINV); + break; + case USART_TXPIN_DISABLE: + USART_CTL3(usart_periph) &= ~(USART_CTL3_TINV); + break; + case USART_RXPIN_DISABLE: + USART_CTL3(usart_periph) &= ~(USART_CTL3_RINV); + break; + default: + break; + } +} + +/*! + \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: 8 bits + \arg USART_OVSMOD_16: 16 bits + \param[out] none + \retval none +*/ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp) +{ + /* clear OVSMOD bit */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD); + USART_CTL0(usart_periph) |= oversamp; +} + +/*! + \brief configure sample bit method + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] obsm: 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 obsm) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); + USART_CTL2(usart_periph) |= obsm; +} + +/*! + \brief enable receiver timeout of USART + \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_CTL3(usart_periph) |= USART_CTL3_RTEN; +} + +/*! + \brief disable receiver timeout of USART + \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_CTL3(usart_periph) &= ~(USART_CTL3_RTEN); +} + +/*! + \brief set the receiver timeout threshold of USART + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] rtimeout: 0-0x00FFFFFF + \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_DATA(usart_periph) = USART_DATA_DATA & (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_DATA(usart_periph), 0U, 8U)); +} + +/*! + \brief configure the address of the USART in wake up by address match mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] addr: address of USART/UART + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (uint32_t)addr); +} + +/*! + \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_RWU; +} + +/*! + \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_RWU); +} + +/*! + \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] wmehtod: two method 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 mask + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmehtod; +} + +/*! + \brief enable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief configure lin break frame length + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] lblen: lin break frame length + only one parameter can be selected which is shown as below: + \arg USART_LBLEN_10B: 10 bits + \arg USART_LBLEN_11B: 11 bits + \param[out] none + \retval none +*/ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= (USART_CTL1_LBLEN & lblen); +} + +/*! + \brief send break frame + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_send_break(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_SBKCMD; +} + +/*! + \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) +{ + 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) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable CK pin in synchronous mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_synchronous_clock_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable CK pin in synchronous mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[out] none + \retval none +*/ +void usart_synchronous_clock_disable(uint32_t usart_periph) +{ + 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: CK length + only one parameter can be selected which is shown as below: + \arg USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame + \arg USART_CLEN_EN: there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame + \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) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + USART_CTL1(usart_periph) = (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (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: guard time value, 0-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, uint8_t guat) +{ + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((uint32_t)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) +{ + 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) +{ + 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) +{ + 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) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief configure smartcard auto-retry number + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] scrtnum: smartcard auto-retry number + \param[out] none + \retval none +*/ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint8_t scrtnum) +{ + USART_CTL3(usart_periph) &= ~(USART_CTL3_SCRTNUM); + USART_CTL3(usart_periph) |= (USART_CTL3_SCRTNUM & ((uint32_t)scrtnum << CTL3_SCRTNUM_OFFSET)); +} + +/*! + \brief configure block length in Smartcard T=1 reception + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] bl: block length + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint8_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((uint32_t)bl << RT_BL_OFFSET)); +} + +/*! + \brief enable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] psc: 0-0xFF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint8_t psc) +{ + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= (uint32_t)psc; +} + +/*! + \brief configure IrDA low-power + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \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) +{ + 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) + \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) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN); + USART_CTL2(usart_periph) |= (USART_CTL2_RTSEN & rtsconfig); +} +/*! + \brief configure hardware flow control CTS + \param[in] usart_periph: USARTx(x=0,1,2,5) + \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) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_CTSEN); + USART_CTL2(usart_periph) |= (USART_CTL2_CTSEN & ctsconfig); +} + +/*! + \brief configure break frame coherence mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \param[in] bcm: + only one parameter can be selected which is shown as below: + \arg USART_BCM_NONE: no parity error is detected + \arg USART_BCM_EN: parity error is detected + \param[out] none + \retval none +*/ +void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_BCM); + USART_CHC(usart_periph) |= (USART_CHC_BCM & bcm); +} + +/*! + \brief configure parity check coherence mode + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] pcm: + only one parameter can be selected which is shown as below: + \arg USART_PCM_NONE: not check parity + \arg USART_PCM_EN: check the parity + \param[out] none + \retval none +*/ +void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_PCM); + USART_CHC(usart_periph) |= (USART_CHC_PCM & pcm); +} + +/*! + \brief configure hardware flow control coherence mode + \param[in] usart_periph: USARTx(x=0,1,2,5) + \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 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: DMA enable for reception + \arg USART_RECEIVE_DMA_DISABLE: DMA disable for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DENR); + USART_CTL2(usart_periph) |= (USART_CTL2_DENR & dmacmd); +} + +/*! + \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: DMA enable for transmission + \arg USART_TRANSMIT_DMA_DISABLE: DMA disable for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DENT); + USART_CTL2(usart_periph) |= (USART_CTL2_DENT & dmacmd); +} + +/*! + \brief get flag in STAT0/STAT1/CHC register + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] flag: USART flags, refer to usart_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_FLAG_CTS: CTS change flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_TBE: transmit data buffer empty + \arg USART_FLAG_TC: transmission complete + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_IDLE: IDLE frame detected flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EPERR: early parity error 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 flag in STAT0/STAT1/CHC register + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] flag: USART flags, refer to usart_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_FLAG_CTS: CTS change flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_TC: transmission complete + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EPERR: early parity error flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_REG_VAL(usart_periph, flag) &= ~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: USART interrupts, refer to usart_interrupt_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_TBE: transmitter buffer empty interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INT_IDLE: IDLE line detected interrupt + \arg USART_INT_LBD: LIN break detected interrupt + \arg USART_INT_ERR: error interrupt + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_RT: interrupt enable bit of receive timeout event + \arg USART_INT_EB: interrupt enable bit of end of block event + \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: USART interrupts, refer to usart_interrupt_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_TBE: transmitter buffer empty interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INT_IDLE: IDLE line detected interrupt + \arg USART_INT_LBD: LIN break detected interrupt + \arg USART_INT_ERR: error interrupt + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_RT: interrupt enable bit of receive timeout event + \arg USART_INT_EB: interrupt enable bit of end of block event + \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: USART interrupt flags, refer to usart_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_PERR: parity error interrupt and flag + \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag + \arg USART_INT_FLAG_TC: transmission complete interrupt and flag + \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \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_CTS: CTS interrupt and flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag + \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag + \arg USART_INT_FLAG_EB: interrupt enable bit of end of block event and flag + \arg USART_INT_FLAG_RT: interrupt enable bit of receive timeout event 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((0U != flagstatus) && (0U != intenable)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear USART interrupt flag in STAT0/STAT1 register + \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7) + \param[in] int_flag: USART interrupt flags, refer to usart_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_TC: transmission complete + \arg USART_INT_FLAG_RBNE: read data buffer not empty + \arg USART_INT_FLAG_EB: end of block flag + \arg USART_INT_FLAG_RT: receiver timeout flag + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + USART_REG_VAL2(usart_periph, int_flag) &= ~BIT(USART_BIT_POS2(int_flag)); +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_wwdgt.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_wwdgt.c new file mode 100644 index 000000000..8b85c68c6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/gd32f4xx_wwdgt.c @@ -0,0 +1,129 @@ +/*! + \file gd32f4xx_wwdgt.c + \brief WWDGT driver + + \version 2016-08-15, V1.0.0, firmware for GD32F4xx + \version 2018-12-12, V2.0.0, firmware for GD32F4xx + \version 2020-09-30, V2.1.0, firmware for GD32F4xx + \version 2022-03-09, V3.0.0, firmware for GD32F4xx +*/ + +/* + Copyright (c) 2022, 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 "gd32f4xx_wwdgt.h" + +/*! + \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 window watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure the window watchdog timer 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: 0x00 - 0x7F + \param[in] window: 0x00 - 0x7F + \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 = (PCLK1/4096)/1 + \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2 + \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4 + \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8 + \param[out] none + \retval none +*/ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler) +{ + /* configure WIN and PSC bits, configure CNT bit */ + WWDGT_CTL = (uint32_t)(CTL_CNT(counter)); + WWDGT_CFG = (uint32_t)(CFG_WIN(window) | prescaler); +} + +/*! + \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); +} + +/*! + \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; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/system_gd32f4xx.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/system_gd32f4xx.c new file mode 100644 index 000000000..243c5bc5b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/src/system_gd32f4xx.c @@ -0,0 +1,1153 @@ +/*! + \file system_gd32f4xx.c + \brief CMSIS Cortex-M4 Device Peripheral Access Layer Source File for + GD32F4xx Device Series +*/ + +/* Copyright (c) 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#include "gd32f4xx.h" + +/* system frequency define */ +#define __IRC16M (IRC16M_VALUE) /* internal 16 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __SYS_OSC_CLK (__IRC16M) /* main oscillator frequency */ + +/* select a system clock by uncommenting the following line */ +//#define __SYSTEM_CLOCK_IRC16M (uint32_t)(__IRC16M) +//#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL) +//#define __SYSTEM_CLOCK_120M_PLL_IRC16M (uint32_t)(120000000) +//#define __SYSTEM_CLOCK_120M_PLL_8M_HXTAL (uint32_t)(120000000) +//#define __SYSTEM_CLOCK_120M_PLL_25M_HXTAL (uint32_t)(120000000) +//#define __SYSTEM_CLOCK_168M_PLL_IRC16M (uint32_t)(168000000) +//#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL (uint32_t)(168000000) +//#define __SYSTEM_CLOCK_168M_PLL_25M_HXTAL (uint32_t)(168000000) +//#define __SYSTEM_CLOCK_200M_PLL_IRC16M (uint32_t)(200000000) +//#define __SYSTEM_CLOCK_200M_PLL_8M_HXTAL (uint32_t)(200000000) +#define __SYSTEM_CLOCK_200M_PLL_25M_HXTAL (uint32_t)(200000000) +//#define __SYSTEM_CLOCK_240M_PLL_IRC16M (uint32_t)(240000000) +//#define __SYSTEM_CLOCK_240M_PLL_8M_HXTAL (uint32_t)(240000000) +//#define __SYSTEM_CLOCK_240M_PLL_25M_HXTAL (uint32_t)(240000000) + +#define RCU_MODIFY(__delay) do{ \ + volatile uint32_t i; \ + if(0 != __delay){ \ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; \ + for(i=0; i<__delay; i++){ \ + } \ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV4; \ + for(i=0; i<__delay; i++){ \ + } \ + } \ + }while(0) + +#define SEL_IRC16M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLLP 0x02U + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_IRC16M +uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC16M; +static void system_clock_16m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL; +static void system_clock_hxtal(void); +#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_IRC16M; +static void system_clock_120m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_8M_HXTAL; +static void system_clock_120m_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_25M_HXTAL; +static void system_clock_120m_25m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_IRC16M; +static void system_clock_168m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_8M_HXTAL; +static void system_clock_168m_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_25M_HXTAL; +static void system_clock_168m_25m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_IRC16M; +static void system_clock_200m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_8M_HXTAL; +static void system_clock_200m_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL_25M_HXTAL; +static void system_clock_200m_25m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_240M_PLL_IRC16M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_240M_PLL_IRC16M; +static void system_clock_240m_irc16m(void); +#elif defined (__SYSTEM_CLOCK_240M_PLL_8M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_240M_PLL_8M_HXTAL; +static void system_clock_240m_8m_hxtal(void); +#elif defined (__SYSTEM_CLOCK_240M_PLL_25M_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_240M_PLL_25M_HXTAL; +static void system_clock_240m_25m_hxtal(void); + +#endif /* __SYSTEM_CLOCK_IRC16M */ + +/* 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 == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ +#endif + /* Reset the RCU clock configuration to the default reset state */ + /* Set IRC16MEN bit */ + RCU_CTL |= RCU_CTL_IRC16MEN; + while(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + } + RCU_MODIFY(0x50); + + RCU_CFG0 &= ~RCU_CFG0_SCS; + + /* Reset HXTALEN, CKMEN and PLLEN bits */ + RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN); + + /* Reset HSEBYP bit */ + RCU_CTL &= ~(RCU_CTL_HXTALBPS); + + /* Reset CFG0 register */ + RCU_CFG0 = 0x00000000U; + + /* wait until IRC16M is selected as system clock */ + while(0 != (RCU_CFG0 & RCU_SCSS_IRC16M)){ + } + + /* Reset PLLCFGR register */ + RCU_PLL = 0x24003010U; + + /* Disable all interrupts */ + RCU_INT = 0x00000000U; + + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings */ + system_clock_config(); +} +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_IRC16M + system_clock_16m_irc16m(); +#elif defined (__SYSTEM_CLOCK_HXTAL) + system_clock_hxtal(); +#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M) + system_clock_120m_irc16m(); +#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL) + system_clock_120m_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL) + system_clock_120m_25m_hxtal(); +#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M) + system_clock_168m_irc16m(); +#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL) + system_clock_168m_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL) + system_clock_168m_25m_hxtal(); +#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M) + system_clock_200m_irc16m(); +#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL) + system_clock_200m_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL) + system_clock_200m_25m_hxtal(); +#elif defined (__SYSTEM_CLOCK_240M_PLL_IRC16M) + system_clock_240m_irc16m(); +#elif defined (__SYSTEM_CLOCK_240M_PLL_8M_HXTAL) + system_clock_240m_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_240M_PLL_25M_HXTAL) + system_clock_240m_25m_hxtal(); +#endif /* __SYSTEM_CLOCK_IRC16M */ +} + +#ifdef __SYSTEM_CLOCK_IRC16M +/*! + \brief configure the system clock to 16M by IRC16M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_16m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + }while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select IRC16M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC16M; + + /* wait until IRC16M is selected as system clock */ + while(0 != (RCU_CFG0 & RCU_SCSS_IRC16M)){ + } +} + +#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){ + } + } + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + 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(0 == (RCU_CFG0 & RCU_SCSS_HXTAL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC16M) +/*! + \brief configure the system clock to 120M by PLL which selects IRC16M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_120m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + }while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* IRC16M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 16, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ + RCU_PLL = (16U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_IRC16M) | (5U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 120 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_120M_PLL_8M_HXTAL) +/*! + \brief configure the system clock to 120M by PLL which selects HXTAL(8M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_120m_8m_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){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 8, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ + RCU_PLL = (8U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (5U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 120 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_120M_PLL_25M_HXTAL) +/*! + \brief configure the system clock to 120M by PLL which selects HXTAL(25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_120m_25m_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){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 25, PLL_N = 240, PLL_P = 2, PLL_Q = 5 */ + RCU_PLL = (25U | (240U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (5U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 120 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC16M) +/*! + \brief configure the system clock to 168M by PLL which selects IRC16M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_168m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + }while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* IRC16M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 16, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ + RCU_PLL = (16U | (336U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_IRC16M) | (7U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 168 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_168M_PLL_8M_HXTAL) +/*! + \brief configure the system clock to 168M by PLL which selects HXTAL(8M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_168m_8m_hxtal(void) +{ + uint32_t timeout = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + while((0U == (RCU_CTL & RCU_CTL_HXTALSTB)) && (HXTAL_STARTUP_TIMEOUT != timeout++)){ + } + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 8, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ + RCU_PLL = (8U | (336 << 6U) | (((2 >> 1U) -1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (7 << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 168 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_168M_PLL_25M_HXTAL) +/*! + \brief configure the system clock to 168M by PLL which selects HXTAL(25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_168m_25m_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){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 25, PLL_N = 336, PLL_P = 2, PLL_Q = 7 */ + RCU_PLL = (25U | (336U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (7U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 168 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_200M_PLL_IRC16M) +/*! + \brief configure the system clock to 200M by PLL which selects IRC16M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_200m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + }while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* IRC16M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 16, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ + RCU_PLL = (16U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_IRC16M) | (9U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 200 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_200M_PLL_8M_HXTAL) +/*! + \brief configure the system clock to 200M by PLL which selects HXTAL(8M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_200m_8m_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){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 8, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ + RCU_PLL = (8U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (9U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 200 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_200M_PLL_25M_HXTAL) +/*! + \brief configure the system clock to 200M by PLL which selects HXTAL(25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_200m_25m_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){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 25, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */ + RCU_PLL = (25U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (9U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 200 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_240M_PLL_IRC16M) +/*! + \brief configure the system clock to 240M by PLL which selects IRC16M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_240m_irc16m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC16M */ + RCU_CTL |= RCU_CTL_IRC16MEN; + + /* wait until IRC16M is stable or the startup time is longer than IRC16M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC16MSTB); + }while((0U == stab_flag) && (IRC16M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC16MSTB)){ + while(1){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* IRC16M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 16, PLL_N = 480, PLL_P = 2, PLL_Q = 10 */ + RCU_PLL = (16U | (480U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_IRC16M) | (10U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 240 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_240M_PLL_8M_HXTAL) +/*! + \brief configure the system clock to 240M by PLL which selects HXTAL(8M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_240m_8m_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){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 8, PLL_N = 480, PLL_P = 2, PLL_Q = 10 */ + RCU_PLL = (8U | (480U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (10U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 240 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} + +#elif defined (__SYSTEM_CLOCK_240M_PLL_25M_HXTAL) +/*! + \brief configure the system clock to 240M by PLL which selects HXTAL(25M) as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_240m_25m_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){ + } + } + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + PMU_CTL |= PMU_CTL_LDOVS; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/2 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; + /* APB1 = AHB/4 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; + + /* Configure the main PLL, PSC = 25, PLL_N = 480, PLL_P = 2, PLL_Q = 10 */ + RCU_PLL = (25U | (480U << 6U) | (((2U >> 1U) - 1U) << 16U) | + (RCU_PLLSRC_HXTAL) | (10U << 24U)); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ + } + + /* Enable the high-drive to extend the clock frequency to 240 Mhz */ + PMU_CTL |= PMU_CTL_HDEN; + while(0U == (PMU_CS & PMU_CS_HDRF)){ + } + + /* select the high-drive mode */ + PMU_CTL |= PMU_CTL_HDS; + while(0U == (PMU_CS & PMU_CS_HDSRF)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLLP; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){ + } +} +#endif /* __SYSTEM_CLOCK_IRC16M */ +/*! + \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; + uint32_t pllpsc, plln, pllsel, pllp, ck_src, idx, clk_exp; + + /* 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}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC16M is selected as CK_SYS */ + case SEL_IRC16M: + SystemCoreClock = IRC16M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLLP is selected as CK_SYS */ + case SEL_PLLP: + /* get the value of PLLPSC[5:0] */ + pllpsc = GET_BITS(RCU_PLL, 0U, 5U); + plln = GET_BITS(RCU_PLL, 6U, 14U); + pllp = (GET_BITS(RCU_PLL, 16U, 17U) + 1U) * 2U; + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = (RCU_PLL & RCU_PLL_PLLSEL); + if (RCU_PLLSRC_HXTAL == pllsel) { + ck_src = HXTAL_VALUE; + } else { + ck_src = IRC16M_VALUE; + } + SystemCoreClock = ((ck_src / pllpsc) * plln) / pllp; + break; + /* IRC16M is selected as CK_SYS */ + default: + SystemCoreClock = IRC16M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + SystemCoreClock = SystemCoreClock >> clk_exp; +} diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Kconfig b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Kconfig new file mode 100644 index 000000000..ef9fa0dbc --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Kconfig @@ -0,0 +1,15 @@ +menuconfig BSP_USING_UART5 + bool "Enable UART5" + default n + if BSP_USING_UART5 + config SERIAL_BUS_NAME_5 + string "serial bus 5 name" + default "uart5" + config SERIAL_DRV_NAME_5 + string "serial bus 5 driver name" + default "uart5_drv" + config SERIAL_5_DEVICE_NAME_0 + string "serial bus 5 device 0 name" + default "uart5_dev5" + endif + diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Makefile b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Makefile new file mode 100644 index 000000000..b515f58a4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_uart.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/connect_uart.c b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/connect_uart.c new file mode 100644 index 000000000..393180055 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/gd32f415rgo6/third_party_driver/uart/connect_uart.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2020 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +/** +* @file connect_usart.c +* @brief support stm32f407zgt6-board usart function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: connect_uart.c +Description: support stm32f407zgt6-board usart configure and uart bus register function +Others: take RT-Thread v4.0.2/bsp/stm32/libraries/HAL_Drivers/drv_usart.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. support stm32f407zgt6-board usart configure, write and read +2. support stm32f407zgt6-board usart bus device and driver register +*************************************************/ + +#include "board.h" +#include "connect_uart.h" +#include "gd32f4xx_usart.h" +#include "gd32f4xx_gpio.h" + + +static void RCCConfiguration(void) +{ +#ifdef BSP_USING_UART5 + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_USART5); +#endif +} + +static void GPIOConfiguration(void) +{ +#ifdef BSP_USING_UART5 + gpio_af_set(GPIOA, GPIO_AF_8, GPIO_PIN_11 | GPIO_PIN_12); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11 | GPIO_PIN_12); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11 | GPIO_PIN_12); +#endif +} + +static void NVIC_Configuration(IRQn_Type irq) +{ + // TODO: add interrupt handler function here +} + +static void SerialCfgParamCheck(struct SerialCfgParam *serial_cfg_default, struct SerialCfgParam *serial_cfg_new) +{ + struct SerialDataCfg *data_cfg_default = &serial_cfg_default->data_cfg; + struct SerialDataCfg *data_cfg_new = &serial_cfg_new->data_cfg; + +} + +static uint32 Gd32SerialInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(serial_drv); + + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + struct UsartHwCfg *serial_hw_cfg = (struct UsartHwCfg *)serial_cfg->hw_cfg.private_data; + + uint32_t uart_device = serial_hw_cfg->uart_device; + + // Reset USART5 + usart_deinit(uart_device); + + // Set baud rate to 115200 + usart_baudrate_set(uart_device, 115200); + + // Configure other parameters, such as no parity, 8 data bits, 1 stop bit + usart_parity_config(uart_device, USART_PM_NONE); + usart_word_length_set(uart_device, USART_WL_8BIT); + usart_stop_bit_set(uart_device, USART_STB_1BIT); + + // Enable transmission and reception + usart_transmit_config(uart_device, USART_TRANSMIT_ENABLE); + usart_receive_config(uart_device, USART_RECEIVE_ENABLE); + + // Enable USART5 + usart_enable(uart_device); + + return EOK; +} + +static uint32 Gd32SerialConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd) +{ + NULL_PARAM_CHECK(serial_drv); + + struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev; + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + struct UsartHwCfg *serial_hw_cfg = (struct UsartHwCfg *)serial_cfg->hw_cfg.private_data; + struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data; + + switch (serial_operation_cmd) + { + default: + break; + } + + return EOK; +} + +static int Gd32SerialPutchar(struct SerialHardwareDevice *serial_dev, char c) +{ + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data; + struct UsartHwCfg *serial_hw_cfg = (struct UsartHwCfg *)serial_cfg->hw_cfg.private_data; + + while(RESET == usart_flag_get(USART5, USART_FLAG_TBE)); + usart_data_transmit(USART5, (uint8_t)c); + + return EOK; +} + +static int Gd32SerialGetchar(struct SerialHardwareDevice *serial_dev) +{ + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data; + struct UsartHwCfg *serial_hw_cfg = (struct UsartHwCfg *)serial_cfg->hw_cfg.private_data; + + int ch = -1; + + if (usart_flag_get(serial_hw_cfg->uart_device, USART_FLAG_RBNE)) + { + ch = usart_data_receive(serial_hw_cfg->uart_device); + } + + return ch; +} + +static uint32 Gd32SerialDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + int serial_operation_cmd; + struct SerialDriver *serial_drv = (struct SerialDriver *)drv; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = Gd32SerialInit(serial_drv, configure_info); + break; + default: + break; + } + + return ret; +} + +/*manage the serial device operations*/ +static const struct SerialDrvDone drv_done = +{ + .init = Gd32SerialInit, + .configure = Gd32SerialConfigure, +}; + +/*manage the serial device hal operations*/ +static struct SerialHwDevDone hwdev_done = +{ + .put_char = Gd32SerialPutchar, + .get_char = Gd32SerialGetchar, +}; + +static int BoardSerialBusInit(struct SerialBus *serial_bus, struct SerialDriver *serial_driver, const char *bus_name, const char *drv_name) +{ + x_err_t ret = EOK; + + /*Init the serial bus */ + ret = SerialBusInit(serial_bus, bus_name); + if (EOK != ret){ + KPrintf("hw_serial_init SerialBusInit error %d\n", ret); + return ERROR; + } + + /*Init the serial driver*/ + ret = SerialDriverInit(serial_driver, drv_name); + if (EOK != ret){ + KPrintf("hw_serial_init SerialDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the serial driver to the serial bus*/ + ret = SerialDriverAttachToBus(drv_name, bus_name); + if (EOK != ret){ + KPrintf("hw_serial_init SerialDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the serial device to the serial bus*/ +static int BoardSerialDevBend(struct SerialHardwareDevice *serial_device, void *serial_param, const char *bus_name, const char *dev_name) +{ + x_err_t ret = EOK; + + ret = SerialDeviceRegister(serial_device, serial_param, dev_name); + if (EOK != ret){ + KPrintf("hw_serial_init SerialDeviceInit device %s error %d\n", dev_name, ret); + return ERROR; + } + + ret = SerialDeviceAttachToBus(dev_name, bus_name); + if (EOK != ret) { + KPrintf("hw_serial_init SerialDeviceAttachToBus device %s error %d\n", dev_name, ret); + return ERROR; + } + + return ret; +} + +#ifdef BSP_USING_UART5 +struct Gd32Usart serial_5; +struct SerialDriver serial_driver_5; +struct SerialHardwareDevice serial_device_5; + +#endif + +int Gd32HwUsartInit(void) +{ + x_err_t ret = EOK; + + RCCConfiguration(); + GPIOConfiguration(); + +#ifdef BSP_USING_UART5 + static struct SerialCfgParam serial_cfg_5; + memset(&serial_cfg_5, 0, sizeof(struct SerialCfgParam)); + + static struct UsartHwCfg serial_hw_cfg_5; + memset(&serial_hw_cfg_5, 0, sizeof(struct UsartHwCfg)); + + static struct SerialDevParam serial_dev_param_5; + memset(&serial_dev_param_5, 0, sizeof(struct SerialDevParam)); + + serial_driver_5.drv_done = &drv_done; + serial_driver_5.configure = &Gd32SerialDrvConfigure; + serial_device_5.hwdev_done = &hwdev_done; + + serial_hw_cfg_5.uart_device = USART5; + serial_cfg_5.hw_cfg.private_data = (void *)&serial_hw_cfg_5; + serial_driver_5.private_data = (void *)&serial_cfg_5; + + serial_device_5.haldev.private_data = (void *)&serial_dev_param_5; + + ret = BoardSerialBusInit(&serial_5.serial_bus, &serial_driver_5, SERIAL_BUS_NAME_5, SERIAL_DRV_NAME_5); + if (EOK != ret) { + KPrintf("Gd32HwUsartInit usart5 error ret %u\n", ret); + return ERROR; + } + + ret = BoardSerialDevBend(&serial_device_5, (void *)&serial_cfg_5, SERIAL_BUS_NAME_5, SERIAL_5_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("Gd32HwUsartInit usart5 error ret %u\n", ret); + return ERROR; + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/path_kernel.mk b/Ubiquitous/XiZi_IIoT/path_kernel.mk index 6a7b053c9..95a40599b 100755 --- a/Ubiquitous/XiZi_IIoT/path_kernel.mk +++ b/Ubiquitous/XiZi_IIoT/path_kernel.mk @@ -548,6 +548,16 @@ KERNELPATHS += \ -I$(KERNEL_ROOT)/include # endif +ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/gd32f415rgo6) +KERNELPATHS += \ + -I$(KERNEL_ROOT)/arch/arm/cortex-m4/hc32f4a0 \ + -I$(KERNEL_ROOT)/arch/arm/cortex-m4 \ + -I$(BSP_ROOT)/third_party_driver \ + -I$(BSP_ROOT)/include \ + -I$(BSP_ROOT)/third_party_driver/include \ + -I$(KERNEL_ROOT)/include # +endif + ifeq ($(BSP_ROOT),$(KERNEL_ROOT)/board/xishutong-arm32) KERNELPATHS += \ -I$(KERNEL_ROOT)/arch/arm/cortex-m4/hc32f4a0 \