From d55f310d786a3ecc33a41f40c23ea9c58a198fdb Mon Sep 17 00:00:00 2001 From: Ouxiaolong <1576690133@qq.com> Date: Thu, 2 Sep 2021 22:38:47 +0800 Subject: [PATCH 1/6] add gd32407v-start --- bsp/gd32/gd32407v-start/.config | 571 +++ bsp/gd32/gd32407v-start/Kconfig | 21 + bsp/gd32/gd32407v-start/README.md | 88 + bsp/gd32/gd32407v-start/SConscript | 15 + bsp/gd32/gd32407v-start/SConstruct | 60 + .../gd32407v-start/applications/SConscript | 11 + bsp/gd32/gd32407v-start/applications/main.c | 35 + bsp/gd32/gd32407v-start/board/Kconfig | 81 + bsp/gd32/gd32407v-start/board/SConscript | 28 + bsp/gd32/gd32407v-start/board/board.c | 85 + bsp/gd32/gd32407v-start/board/board.h | 47 + .../gd32407v-start/board/gd32f4xx_libopt.h | 45 + .../board/linker_scripts/link.icf | 40 + .../board/linker_scripts/link.ld | 142 + .../board/linker_scripts/link.sct | 15 + bsp/gd32/gd32407v-start/figures/board.jpg | Bin 0 -> 98061 bytes bsp/gd32/gd32407v-start/project.uvoptx | 890 +++++ bsp/gd32/gd32407v-start/project.uvproj | 1442 +++++++ bsp/gd32/gd32407v-start/project.uvprojx | 723 ++++ bsp/gd32/gd32407v-start/rtconfig.h | 172 + bsp/gd32/gd32407v-start/rtconfig.py | 150 + bsp/gd32/gd32407v-start/template.uvoptx | 190 + bsp/gd32/gd32407v-start/template.uvproj | 628 +++ bsp/gd32/gd32407v-start/template.uvprojx | 417 ++ .../CMSIS/GD/GD32F4xx/Include/gd32f4xx.h | 366 ++ .../GD/GD32F4xx/Include/system_gd32f4xx.h | 58 + .../GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s | 427 ++ .../GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S | 315 ++ .../GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s | 640 +++ .../GD/GD32F4xx/Source/system_gd32f4xx.c | 916 +++++ .../libraries/GD32F4xx_HAL/CMSIS/core_cm4.h | 1790 +++++++++ .../GD32F4xx_HAL/CMSIS/core_cm4_simd.h | 697 ++++ .../GD32F4xx_HAL/CMSIS/core_cmFunc.h | 664 ++++ .../GD32F4xx_HAL/CMSIS/core_cmInstr.h | 916 +++++ .../Include/gd32f4xx_adc.h | 515 +++ .../Include/gd32f4xx_can.h | 753 ++++ .../Include/gd32f4xx_crc.h | 80 + .../Include/gd32f4xx_ctc.h | 192 + .../Include/gd32f4xx_dac.h | 270 ++ .../Include/gd32f4xx_dbg.h | 161 + .../Include/gd32f4xx_dci.h | 238 ++ .../Include/gd32f4xx_dma.h | 428 ++ .../Include/gd32f4xx_enet.h | 1680 ++++++++ .../Include/gd32f4xx_exmc.h | 809 ++++ .../Include/gd32f4xx_exti.h | 277 ++ .../Include/gd32f4xx_fmc.h | 383 ++ .../Include/gd32f4xx_fwdgt.h | 106 + .../Include/gd32f4xx_gpio.h | 408 ++ .../Include/gd32f4xx_i2c.h | 422 ++ .../Include/gd32f4xx_ipa.h | 384 ++ .../Include/gd32f4xx_iref.h | 186 + .../Include/gd32f4xx_misc.h | 93 + .../Include/gd32f4xx_pmu.h | 199 + .../Include/gd32f4xx_rcu.h | 1179 ++++++ .../Include/gd32f4xx_rtc.h | 640 +++ .../Include/gd32f4xx_sdio.h | 433 ++ .../Include/gd32f4xx_spi.h | 379 ++ .../Include/gd32f4xx_syscfg.h | 181 + .../Include/gd32f4xx_timer.h | 781 ++++ .../Include/gd32f4xx_tli.h | 376 ++ .../Include/gd32f4xx_trng.h | 104 + .../Include/gd32f4xx_usart.h | 495 +++ .../Include/gd32f4xx_wwdgt.h | 88 + .../Source/gd32f4xx_adc.c | 1202 ++++++ .../Source/gd32f4xx_can.c | 1027 +++++ .../Source/gd32f4xx_crc.c | 128 + .../Source/gd32f4xx_ctc.c | 405 ++ .../Source/gd32f4xx_dac.c | 677 ++++ .../Source/gd32f4xx_dbg.c | 198 + .../Source/gd32f4xx_dci.c | 345 ++ .../Source/gd32f4xx_dma.c | 905 +++++ .../Source/gd32f4xx_enet.c | 3505 +++++++++++++++++ .../Source/gd32f4xx_exmc.c | 1237 ++++++ .../Source/gd32f4xx_exti.c | 257 ++ .../Source/gd32f4xx_fmc.c | 932 +++++ .../Source/gd32f4xx_fwdgt.c | 157 + .../Source/gd32f4xx_gpio.c | 433 ++ .../Source/gd32f4xx_i2c.c | 819 ++++ .../Source/gd32f4xx_ipa.c | 637 +++ .../Source/gd32f4xx_iref.c | 126 + .../Source/gd32f4xx_misc.c | 174 + .../Source/gd32f4xx_pmu.c | 391 ++ .../Source/gd32f4xx_rcu.c | 1329 +++++++ .../Source/gd32f4xx_rtc.c | 1295 ++++++ .../Source/gd32f4xx_sdio.c | 803 ++++ .../Source/gd32f4xx_spi.c | 882 +++++ .../Source/gd32f4xx_syscfg.c | 204 + .../Source/gd32f4xx_timer.c | 2063 ++++++++++ .../Source/gd32f4xx_tli.c | 598 +++ .../Source/gd32f4xx_trng.c | 155 + .../Source/gd32f4xx_usart.c | 1009 +++++ .../Source/gd32f4xx_wwdgt.c | 148 + bsp/gd32/libraries/GD32F4xx_HAL/SConscript | 58 + bsp/gd32/libraries/HAL_Drivers/Kconfig | 62 + bsp/gd32/libraries/HAL_Drivers/SConscript | 22 + bsp/gd32/libraries/HAL_Drivers/drv_gpio.c | 514 +++ bsp/gd32/libraries/HAL_Drivers/drv_gpio.h | 61 + bsp/gd32/libraries/HAL_Drivers/drv_usart.c | 465 +++ bsp/gd32/libraries/HAL_Drivers/drv_usart.h | 22 + bsp/gd32/libraries/Kconfig | 7 + bsp/gd32/tools/sdk_dist.py | 22 + bsp/stm32/stm32f746-st-nucleo/README.md | 3 +- 102 files changed, 48200 insertions(+), 2 deletions(-) create mode 100644 bsp/gd32/gd32407v-start/.config create mode 100644 bsp/gd32/gd32407v-start/Kconfig create mode 100644 bsp/gd32/gd32407v-start/README.md create mode 100644 bsp/gd32/gd32407v-start/SConscript create mode 100644 bsp/gd32/gd32407v-start/SConstruct create mode 100644 bsp/gd32/gd32407v-start/applications/SConscript create mode 100644 bsp/gd32/gd32407v-start/applications/main.c create mode 100644 bsp/gd32/gd32407v-start/board/Kconfig create mode 100644 bsp/gd32/gd32407v-start/board/SConscript create mode 100644 bsp/gd32/gd32407v-start/board/board.c create mode 100644 bsp/gd32/gd32407v-start/board/board.h create mode 100644 bsp/gd32/gd32407v-start/board/gd32f4xx_libopt.h create mode 100644 bsp/gd32/gd32407v-start/board/linker_scripts/link.icf create mode 100644 bsp/gd32/gd32407v-start/board/linker_scripts/link.ld create mode 100644 bsp/gd32/gd32407v-start/board/linker_scripts/link.sct create mode 100644 bsp/gd32/gd32407v-start/figures/board.jpg create mode 100644 bsp/gd32/gd32407v-start/project.uvoptx create mode 100644 bsp/gd32/gd32407v-start/project.uvproj create mode 100644 bsp/gd32/gd32407v-start/project.uvprojx create mode 100644 bsp/gd32/gd32407v-start/rtconfig.h create mode 100644 bsp/gd32/gd32407v-start/rtconfig.py create mode 100644 bsp/gd32/gd32407v-start/template.uvoptx create mode 100644 bsp/gd32/gd32407v-start/template.uvproj create mode 100644 bsp/gd32/gd32407v-start/template.uvprojx create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cm4.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cm4_simd.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmFunc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmInstr.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_wwdgt.c create mode 100644 bsp/gd32/libraries/GD32F4xx_HAL/SConscript create mode 100644 bsp/gd32/libraries/HAL_Drivers/Kconfig create mode 100644 bsp/gd32/libraries/HAL_Drivers/SConscript create mode 100644 bsp/gd32/libraries/HAL_Drivers/drv_gpio.c create mode 100644 bsp/gd32/libraries/HAL_Drivers/drv_gpio.h create mode 100644 bsp/gd32/libraries/HAL_Drivers/drv_usart.c create mode 100644 bsp/gd32/libraries/HAL_Drivers/drv_usart.h create mode 100644 bsp/gd32/libraries/Kconfig create mode 100644 bsp/gd32/tools/sdk_dist.py diff --git a/bsp/gd32/gd32407v-start/.config b/bsp/gd32/gd32407v-start/.config new file mode 100644 index 0000000000..ab161f892e --- /dev/null +++ b/bsp/gd32/gd32407v-start/.config @@ -0,0 +1,571 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=4 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=100 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +# CONFIG_RT_USING_TIMER_SOFT is not set + +# +# kservice optimization +# +# CONFIG_RT_KSERVICE_USING_STDLIB is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +CONFIG_RT_DEBUG=y +CONFIG_RT_DEBUG_COLOR=y +# CONFIG_RT_DEBUG_INIT_CONFIG is not set +# CONFIG_RT_DEBUG_THREAD_CONFIG is not set +# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set +# CONFIG_RT_DEBUG_IPC_CONFIG is not set +# CONFIG_RT_DEBUG_TIMER_CONFIG is not set +# CONFIG_RT_DEBUG_IRQ_CONFIG is not set +# CONFIG_RT_DEBUG_MEM_CONFIG is not set +# CONFIG_RT_DEBUG_SLAB_CONFIG is not set +# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set +# CONFIG_RT_DEBUG_MODULE_CONFIG is not set + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +# CONFIG_RT_USING_MEMHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart1" +# CONFIG_RT_PRINTF_LONGLONG is not set +CONFIG_RT_VER_NUM=0x40004 +# CONFIG_RT_USING_CPU_FFS is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 + +# +# C++ features +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Command shell +# +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_CMD_SIZE=80 +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_USING_MSH_DEFAULT=y +# CONFIG_FINSH_USING_MSH_ONLY is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# Device virtual file system +# +# CONFIG_RT_USING_DFS is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_PIPE_BUFSZ=512 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +CONFIG_RT_SERIAL_USING_DMA=y +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +# CONFIG_RT_USING_I2C is not set +# CONFIG_RT_USING_PHY is not set +CONFIG_RT_USING_PIN=y +# CONFIG_RT_USING_ADC is not set +# CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_PWM is not set +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +# CONFIG_RT_USING_SPI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_WIFI is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# POSIX layer and C standard library +# +# CONFIG_RT_USING_LIBC is not set +# CONFIG_RT_USING_PTHREADS is not set +CONFIG_RT_LIBC_USING_TIME=y +CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# Network interface device +# +# CONFIG_RT_USING_NETDEV is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# AT commands +# +# CONFIG_RT_USING_AT is not set + +# +# VBUS(Virtual Software BUS) +# +# CONFIG_RT_USING_VBUS is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_RT_LINK is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_libsodium is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set + +# +# multimedia packages +# +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ULOG_FILE is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set + +# +# system packages +# + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_GUIENGINE is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_FAL is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_CMSIS is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# miscellaneous packages +# +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_UKAL is not set +# CONFIG_PKG_USING_CRCLIB is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_COWSAY is not set +CONFIG_SOC_GD32407V=y +# CONFIG_BSP_USING_SDRAM is not set +# CONFIG_BSP_USING_UART0 is not set +CONFIG_BSP_USING_UART1=y +# CONFIG_BSP_USING_UART2 is not set +# CONFIG_BSP_USING_UART3 is not set +# CONFIG_BSP_USING_UART4 is not set +# CONFIG_BSP_USING_UART5 is not set +# CONFIG_BSP_USING_LPUART1 is not set diff --git a/bsp/gd32/gd32407v-start/Kconfig b/bsp/gd32/gd32407v-start/Kconfig new file mode 100644 index 0000000000..8cbc7b71a8 --- /dev/null +++ b/bsp/gd32/gd32407v-start/Kconfig @@ -0,0 +1,21 @@ +mainmenu "RT-Thread Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" +source "../libraries/Kconfig" +source "board/Kconfig" diff --git a/bsp/gd32/gd32407v-start/README.md b/bsp/gd32/gd32407v-start/README.md new file mode 100644 index 0000000000..a95a715158 --- /dev/null +++ b/bsp/gd32/gd32407v-start/README.md @@ -0,0 +1,88 @@ +# GD32407V-START开发板BSP说明 + +## 简介 + +GD32407V-STARTL是-兆易创新推出的一款GD32F4XX系列的评估板,最高主频高达168M,该开发板具有丰富的板载资源,可以充分发挥 GD32407V 的芯片性能。 + + +开发板外观如下图所示: + +![board](figures/board.jpg) + +该开发板常用 **板载资源** 如下: + +- GD32407V,主频 168MHz,3072KB FLASH ,192KB RAM + +- 常用外设 + + - LED :3个,LED1 (电源指示灯),LED2(PC6) + - 按键:2个,K1(复位引脚),K2(用户按键,PA0) + +- 常用接口:USB 接口 + +- 调试接口:GD-LINK + + + +## 使用说明 + +使用说明分为如下两个章节: + +- 快速上手 + + 本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。 + +- 进阶使用 + + 本章节是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。 + + +### 快速上手 + +本 BSP 为开发者提供 MDK5 和 IAR 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。 + +#### 硬件连接 + +使用数据线连接开发板到 PC,使用USB转TTL模块连接PA2(MCU TX)和PA3(MCU RX),打开电源开关。 + +#### 编译下载 + +双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。 + +> 工程默认配置使用 GD-Link 仿真器下载程序,在通过 GD-Link 连接开发板的基础上,点击下载按钮即可下载程序到开发板 + +#### 运行结果 + +下载程序成功之后,系统会自动运行,LED 闪烁。 + +连接开发板对应串口到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-Thread 的输出信息: + +```bash + \ | / +- RT - Thread Operating System + / | \ 4.0.4 build Jan 9 2021 + 2006 - 2021 Copyright by rt-thread team +msh > +``` + +### 进阶使用 + +此 BSP 默认只开启了 GPIO 和 串口1的功能,如果需使用高级功能,需要利用 ENV 工具对BSP 进行配置,步骤如下: + +1. 在 bsp 下打开 env 工具。 + +2. 输入`menuconfig`命令配置工程,配置好之后保存退出。 + +3. 输入`pkgs --update`命令更新软件包。 + +4. 输入`scons --target=mdk4/mdk5/iar` 命令重新生成工程。 + +## 注意事项 + +暂无 + +## 联系人信息 + +维护人: + +- [BruceOu](https://github.com/Ouxiaolong/), 邮箱: \ No newline at end of file diff --git a/bsp/gd32/gd32407v-start/SConscript b/bsp/gd32/gd32407v-start/SConscript new file mode 100644 index 0000000000..20f7689c53 --- /dev/null +++ b/bsp/gd32/gd32407v-start/SConscript @@ -0,0 +1,15 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/gd32/gd32407v-start/SConstruct b/bsp/gd32/gd32407v-start/SConstruct new file mode 100644 index 0000000000..8ad4ca2869 --- /dev/null +++ b/bsp/gd32/gd32407v-start/SConstruct @@ -0,0 +1,60 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = env["LINKCOM"] + ' --map rtthread.map') + +Export('RTT_ROOT') +Export('rtconfig') + +SDK_ROOT = os.path.abspath('./') + +if os.path.exists(SDK_ROOT + '/libraries'): + libraries_path_prefix = SDK_ROOT + '/libraries' +else: + libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries' + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +stm32_library = 'GD32F4xx_HAL' +rtconfig.BSP_LIBRARY_TYPE = stm32_library + +# include libraries +objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript'))) + +# include drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'))) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/gd32/gd32407v-start/applications/SConscript b/bsp/gd32/gd32407v-start/applications/SConscript new file mode 100644 index 0000000000..01eb940dfb --- /dev/null +++ b/bsp/gd32/gd32407v-start/applications/SConscript @@ -0,0 +1,11 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = os.path.join(str(Dir('#')), 'applications') +src = Glob('*.c') +CPPPATH = [cwd, str(Dir('#'))] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32/gd32407v-start/applications/main.c b/bsp/gd32/gd32407v-start/applications/main.c new file mode 100644 index 0000000000..4a528128b4 --- /dev/null +++ b/bsp/gd32/gd32407v-start/applications/main.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-20 BruceOu first implementation + */ + +#include +#include +#include +#include + +/* defined the LED2 pin: PC6 */ +#define LED2_PIN GET_PIN(C, 6) + +int main(void) +{ + int count = 1; + + /* set LED2 pin mode to output */ + rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); + + while (count++) + { + rt_pin_write(LED2_PIN, PIN_HIGH); + rt_thread_mdelay(500); + rt_pin_write(LED2_PIN, PIN_LOW); + rt_thread_mdelay(500); + } + + return RT_EOK; +} diff --git a/bsp/gd32/gd32407v-start/board/Kconfig b/bsp/gd32/gd32407v-start/board/Kconfig new file mode 100644 index 0000000000..4bf9b828c3 --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/Kconfig @@ -0,0 +1,81 @@ +menu "Hardware Drivers Config" + +config SOC_GD32407V + bool + select SOC_SERIES_GD32F4 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +menu "Onboard Peripheral Drivers" + +endmenu + +menu "On-chip Peripheral Drivers" + + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN + default y + + menuconfig BSP_USING_UART + bool "Enable UART" + default y + select RT_USING_SERIAL + if BSP_USING_UART + config BSP_USING_UART1 + bool "Enable UART1" + default y + + config BSP_UART1_RX_USING_DMA + bool "Enable UART1 RX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + endif + + menuconfig BSP_USING_SPI + bool "Enable SPI BUS" + default n + select RT_USING_SPI + if BSP_USING_SPI + config BSP_USING_SPI1 + bool "Enable SPI1 BUS" + default n + + config BSP_SPI1_TX_USING_DMA + bool "Enable SPI1 TX DMA" + depends on BSP_USING_SPI1 + default n + + config BSP_SPI1_RX_USING_DMA + bool "Enable SPI1 RX DMA" + depends on BSP_USING_SPI1 + select BSP_SPI1_TX_USING_DMA + default n + endif + + menuconfig BSP_USING_I2C1 + bool "Enable I2C1 BUS (software simulation)" + default n + select RT_USING_I2C + select RT_USING_I2C_BITOPS + select RT_USING_PIN + if BSP_USING_I2C1 + config BSP_I2C1_SCL_PIN + int "i2c1 scl pin number" + range 1 216 + default 24 + config BSP_I2C1_SDA_PIN + int "I2C1 sda pin number" + range 1 216 + default 25 + endif + source "../libraries/HAL_Drivers/Kconfig" + +endmenu + +menu "Board extended module Drivers" + +endmenu + +endmenu diff --git a/bsp/gd32/gd32407v-start/board/SConscript b/bsp/gd32/gd32407v-start/board/SConscript new file mode 100644 index 0000000000..fa88754d91 --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/SConscript @@ -0,0 +1,28 @@ +import os +import rtconfig +from building import * + +Import('SDK_LIB') + +cwd = GetCurrentDir() + +# add general drivers +src = Split(''' +board.c +''') + +path = [cwd] + +startup_path_prefix = SDK_LIB + +if rtconfig.CROSS_TOOL == 'gcc': + src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S'] +elif rtconfig.CROSS_TOOL == 'keil': + src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s'] + +CPPDEFINES = ['GD3232F407xx'] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/gd32/gd32407v-start/board/board.c b/bsp/gd32/gd32407v-start/board/board.c new file mode 100644 index 0000000000..0e9f89865a --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/board.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-20 BruceOu first implementation + */ +#include +#include +#include +#include + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler */ + /* User can add his own implementation to report the HAL error return state */ + while (1) + { + } + /* USER CODE END Error_Handler */ +} + +/** System Clock Configuration +*/ +void SystemClock_Config(void) +{ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); + NVIC_SetPriority(SysTick_IRQn, 0); +} + +/** + * This is the timer interrupt service routine. + * + */ +void SysTick_Handler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +/** + * This function will initial GD32 board. + */ +void rt_hw_board_init() +{ + /* NVIC Configuration */ +#define NVIC_VTOR_MASK 0x3FFFFF80 +#ifdef VECT_TAB_RAM + /* Set the Vector Table base location at 0x10000000 */ + SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); +#else /* VECT_TAB_FLASH */ + /* Set the Vector Table base location at 0x08000000 */ + SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK); +#endif + + SystemClock_Config(); + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef BSP_USING_SDRAM + rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END); +#else + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif +} + +/*@}*/ diff --git a/bsp/gd32/gd32407v-start/board/board.h b/bsp/gd32/gd32407v-start/board/board.h new file mode 100644 index 0000000000..b13b5439f6 --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/board.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-20 BruceOu first implementation + */ +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include "gd32f4xx.h" +#include "drv_usart.h" +#include "drv_gpio.h" + +#include "gd32f4xx_exti.h" + +#define EXT_SDRAM_BEGIN (0xC0000000U) /* the begining address of external SDRAM */ +#define EXT_SDRAM_END (EXT_SDRAM_BEGIN + (32U * 1024 * 1024)) /* the end address of external SDRAM */ + +// Internal SRAM memory size[Kbytes] <8-64> +// Default: 64 +#ifdef __ICCARM__ +// Use *.icf ram symbal, to avoid hardcode. +extern char __ICFEDIT_region_RAM_end__; +#define GD32_SRAM_END &__ICFEDIT_region_RAM_end__ +#else +#define GD32_SRAM_SIZE 128 +#define GD32_SRAM_END (0x20000000 + GD32_SRAM_SIZE * 1024) +#endif + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define HEAP_BEGIN (__segment_end("HEAP")) +#else +extern int __bss_end; +#define HEAP_BEGIN (&__bss_end) +#endif + +#define HEAP_END GD32_SRAM_END + +#endif + diff --git a/bsp/gd32/gd32407v-start/board/gd32f4xx_libopt.h b/bsp/gd32/gd32407v-start/board/gd32f4xx_libopt.h new file mode 100644 index 0000000000..d26e3d15ec --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/gd32f4xx_libopt.h @@ -0,0 +1,45 @@ +/*! + \file gd32f4xx_libopt.h + \brief library optional for gd32f4xx +*/ + +/* + Copyright (C) 2016 GigaDevice + + 2016-10-19, V1.0.0, firmware for GD32F4xx +*/ + +#ifndef GD32F4XX_LIBOPT_H +#define GD32F4XX_LIBOPT_H +#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_enet.h" +#include "gd32f4xx_exmc.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_ipa.h" +#include "gd32f4xx_iref.h" +#include "gd32f4xx_pmu.h" +#include "gd32f4xx_rcu.h" +#include "gd32f4xx_rtc.h" +#include "gd32f4xx_sdio.h" +#include "gd32f4xx_spi.h" +#include "gd32f4xx_timer.h" +#include "gd32f4xx_tli.h" +#include "gd32f4xx_trng.h" +#include "gd32f4xx_usart.h" +#include "gd32f4xx_wwdgt.h" +#include "gd32f4xx_misc.h" + +#endif /* GD32F4XX_LIBOPT_H */ diff --git a/bsp/gd32/gd32407v-start/board/linker_scripts/link.icf b/bsp/gd32/gd32407v-start/board/linker_scripts/link.icf new file mode 100644 index 0000000000..1741be6a71 --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/linker_scripts/link.icf @@ -0,0 +1,40 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x082FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_heap__ = 0x2000; +/**** End of ICF editor section. ###ICF###*/ + +export symbol __ICFEDIT_region_RAM_end__; + +define symbol __region_RAM1_start__ = 0x10000000; +define symbol __region_RAM1_end__ = 0x1000FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in RAM1_region { section .sram }; \ No newline at end of file diff --git a/bsp/gd32/gd32407v-start/board/linker_scripts/link.ld b/bsp/gd32/gd32407v-start/board/linker_scripts/link.ld new file mode 100644 index 0000000000..ec1c65c34e --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/linker_scripts/link.ld @@ -0,0 +1,142 @@ +/* + * linker script for GD32F4xx with GNU ld + * bernard.xiong 2009-10-14 + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + CODE (rx) : ORIGIN = 0x08000000, LENGTH = 3072k /* 3072KB flash */ + DATA (rw) : ORIGIN = 0x20000000, LENGTH = 192k /* 192KB sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + . = ALIGN(4); + _etext = .; + } > CODE = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >DATA + + .stack : + { + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >DATA + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > DATA + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/gd32/gd32407v-start/board/linker_scripts/link.sct b/bsp/gd32/gd32407v-start/board/linker_scripts/link.sct new file mode 100644 index 0000000000..f8a5eaf1e2 --- /dev/null +++ b/bsp/gd32/gd32407v-start/board/linker_scripts/link.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x00300000 { ; load region size_region + ER_IROM1 0x08000000 0x00300000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x00030000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/gd32/gd32407v-start/figures/board.jpg b/bsp/gd32/gd32407v-start/figures/board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4dece91b3ff233d6f3144f2237818a7c71dac171 GIT binary patch literal 98061 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 fV2}S + + + 1.0 + +

### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 3 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + CMSIS_AGDI + -X"CMSIS-DAP" -O206 -S0 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB.FLM -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM) + + + 0 + JL2CM3 + -U59401765 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB.FLM -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM)) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Applications + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + applications\main.c + main.c + 0 + 0 + + + + + CPU + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\backtrace.c + backtrace.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m4\cpuport.c + cpuport.c + 0 + 0 + + + 2 + 6 + 2 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m4\context_rvds.S + context_rvds.S + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 3 + 7 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\pin.c + pin.c + 0 + 0 + + + 3 + 8 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 3 + 9 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringblk_buf.c + ringblk_buf.c + 0 + 0 + + + 3 + 10 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\pipe.c + pipe.c + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\waitqueue.c + waitqueue.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\completion.c + completion.c + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\workqueue.c + workqueue.c + 0 + 0 + + + 3 + 15 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\src\dataqueue.c + dataqueue.c + 0 + 0 + + + + + Drivers + 1 + 0 + 0 + 0 + + 4 + 16 + 2 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f4xx.s + startup_gd32f4xx.s + 0 + 0 + + + 4 + 17 + 1 + 0 + 0 + 0 + board\board.c + board.c + 0 + 0 + + + 4 + 18 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_gpio.c + drv_gpio.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_usart.c + drv_usart.c + 0 + 0 + + + + + finsh + 0 + 0 + 0 + 0 + + 5 + 20 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_node.c + finsh_node.c + 0 + 0 + + + 5 + 21 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_parser.c + finsh_parser.c + 0 + 0 + + + 5 + 22 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\cmd.c + cmd.c + 0 + 0 + + + 5 + 23 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\msh.c + msh.c + 0 + 0 + + + 5 + 24 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_vm.c + finsh_vm.c + 0 + 0 + + + 5 + 25 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\shell.c + shell.c + 0 + 0 + + + 5 + 26 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_var.c + finsh_var.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_compiler.c + finsh_compiler.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_heap.c + finsh_heap.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_ops.c + finsh_ops.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_error.c + finsh_error.c + 0 + 0 + + + 5 + 31 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_token.c + finsh_token.c + 0 + 0 + + + 5 + 32 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\finsh_init.c + finsh_init.c + 0 + 0 + + + + + Kernel + 0 + 0 + 0 + 0 + + 6 + 33 + 1 + 0 + 0 + 0 + ..\..\..\src\thread.c + thread.c + 0 + 0 + + + 6 + 34 + 1 + 0 + 0 + 0 + ..\..\..\src\timer.c + timer.c + 0 + 0 + + + 6 + 35 + 1 + 0 + 0 + 0 + ..\..\..\src\clock.c + clock.c + 0 + 0 + + + 6 + 36 + 1 + 0 + 0 + 0 + ..\..\..\src\components.c + components.c + 0 + 0 + + + 6 + 37 + 1 + 0 + 0 + 0 + ..\..\..\src\device.c + device.c + 0 + 0 + + + 6 + 38 + 1 + 0 + 0 + 0 + ..\..\..\src\scheduler.c + scheduler.c + 0 + 0 + + + 6 + 39 + 1 + 0 + 0 + 0 + ..\..\..\src\mem.c + mem.c + 0 + 0 + + + 6 + 40 + 1 + 0 + 0 + 0 + ..\..\..\src\mempool.c + mempool.c + 0 + 0 + + + 6 + 41 + 1 + 0 + 0 + 0 + ..\..\..\src\idle.c + idle.c + 0 + 0 + + + 6 + 42 + 1 + 0 + 0 + 0 + ..\..\..\src\ipc.c + ipc.c + 0 + 0 + + + 6 + 43 + 1 + 0 + 0 + 0 + ..\..\..\src\kservice.c + kservice.c + 0 + 0 + + + 6 + 44 + 1 + 0 + 0 + 0 + ..\..\..\src\irq.c + irq.c + 0 + 0 + + + 6 + 45 + 1 + 0 + 0 + 0 + ..\..\..\src\object.c + object.c + 0 + 0 + + + + + libc + 0 + 0 + 0 + 0 + + 7 + 46 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\time.c + time.c + 0 + 0 + + + + + Libraries + 0 + 0 + 0 + 0 + + 8 + 47 + 1 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + gd32f4xx_syscfg.c + 0 + 0 + + + 8 + 48 + 1 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + gd32f4xx_exti.c + 0 + 0 + + + 8 + 49 + 1 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + gd32f4xx_gpio.c + 0 + 0 + + + 8 + 50 + 1 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + gd32f4xx_rcu.c + 0 + 0 + + + 8 + 51 + 1 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + gd32f4xx_misc.c + 0 + 0 + + + 8 + 52 + 1 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + gd32f4xx_usart.c + 0 + 0 + + + 8 + 53 + 1 + 0 + 0 + 0 + ..\libraries\GD32F4xx_HAL\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + system_gd32f4xx.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + + diff --git a/bsp/gd32/gd32407v-start/project.uvproj b/bsp/gd32/gd32407v-start/project.uvproj new file mode 100644 index 0000000000..55b6c9db1a --- /dev/null +++ b/bsp/gd32/gd32407v-start/project.uvproj @@ -0,0 +1,1442 @@ + + + 1.1 +
### uVision Project, (C) Keil Software
+ + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + 0 + + + GD32F407VK + GigaDevice + IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x08000000-0x082FFFFF) CLOCK(16000000) CPUTYPE("Cortex-M4") FPU2 + + "Startup\GD\GD32F4xx\startup_gd32f4xx.s" ("GD32F4xx Startup Code") + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000) + 0 + gd32f4xx0.h + + + + + + + + + + SFD\GD\GD32F4xx\GD32F4xx.SFR + 0 + 0 + + + + GD\GD32F4xx\ + GD\GD32F4xx\ + + 0 + 0 + 0 + 0 + 1 + + .\output\ + rtthread-gd32f4xx + 1 + 0 + 1 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DCM.DLL + -pCM3 + SARMCM3.DLL + + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + + 0 + 3 + + + + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + GD32F4XX, RT_USING_ARM_LIBC, USE_STDPERIPH_DRIVER + + .;..\..\include;applications;.;drivers;Libraries\CMSIS\GD\GD32F4xx\Include;Libraries\CMSIS;Libraries\GD32F4xx_standard_peripheral\Include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m4;..\..\components\dfs\include;..\..\components\dfs\filesystems\devfs;..\..\components\dfs\filesystems\elmfat;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\libc\compilers\armlibc;..\..\components\libc\compilers\common;..\..\components\net\lwip-2.0.2\src;..\..\components\net\lwip-2.0.2\src\include;..\..\components\net\lwip-2.0.2\src\include\ipv4;..\..\components\net\lwip-2.0.2\src\arch\include;..\..\components\net\lwip-2.0.2\src\include\netif;..\..\components\net\netdev\include;..\..\components\net\sal_socket\include;..\..\components\net\sal_socket\include\socket;..\..\components\net\sal_socket\impl;..\..\components\net\sal_socket\include\dfs_net;..\..\components\net\sal_socket\include\dfs_net\sys_select;..\..\components\net\sal_socket\include\socket\sys_socket + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + Kernel + + + clock.c + 1 + ..\..\src\clock.c + + + + + components.c + 1 + ..\..\src\components.c + + + + + cpu.c + 1 + ..\..\src\cpu.c + + + + + device.c + 1 + ..\..\src\device.c + + + + + idle.c + 1 + ..\..\src\idle.c + + + + + ipc.c + 1 + ..\..\src\ipc.c + + + + + irq.c + 1 + ..\..\src\irq.c + + + + + kservice.c + 1 + ..\..\src\kservice.c + + + + + mem.c + 1 + ..\..\src\mem.c + + + + + mempool.c + 1 + ..\..\src\mempool.c + + + + + object.c + 1 + ..\..\src\object.c + + + + + scheduler.c + 1 + ..\..\src\scheduler.c + + + + + signal.c + 1 + ..\..\src\signal.c + + + + + thread.c + 1 + ..\..\src\thread.c + + + + + timer.c + 1 + ..\..\src\timer.c + + + + + Applications + + + main.c + 1 + applications\main.c + + + + + Drivers + + + board.c + 1 + drivers\board.c + + + + + drv_usart.c + 1 + drivers\drv_usart.c + + + + + drv_exmc_sdram.c + 1 + drivers\drv_exmc_sdram.c + + + + + drv_enet.c + 1 + drivers\drv_enet.c + + + + + synopsys_emac.c + 1 + drivers\synopsys_emac.c + + + + + GD32_Lib + + + gd32f4xx_adc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_adc.c + + + + + gd32f4xx_can.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_can.c + + + + + gd32f4xx_crc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_crc.c + + + + + gd32f4xx_ctc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ctc.c + + + + + gd32f4xx_dac.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dac.c + + + + + gd32f4xx_dbg.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dbg.c + + + + + gd32f4xx_dci.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dci.c + + + + + gd32f4xx_dma.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_dma.c + + + + + gd32f4xx_enet.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_enet.c + + + + + gd32f4xx_exmc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exmc.c + + + + + gd32f4xx_exti.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + + + + + gd32f4xx_fmc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fmc.c + + + + + gd32f4xx_fwdgt.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_fwdgt.c + + + + + gd32f4xx_gpio.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + + + + + gd32f4xx_i2c.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_i2c.c + + + + + gd32f4xx_ipa.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_ipa.c + + + + + gd32f4xx_iref.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_iref.c + + + + + gd32f4xx_misc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + + + + + gd32f4xx_pmu.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_pmu.c + + + + + gd32f4xx_rcu.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + + + + + gd32f4xx_rtc.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_rtc.c + + + + + gd32f4xx_sdio.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_sdio.c + + + + + gd32f4xx_spi.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_spi.c + + + + + gd32f4xx_syscfg.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + + + + + gd32f4xx_timer.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_timer.c + + + + + gd32f4xx_tli.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_tli.c + + + + + gd32f4xx_trng.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_trng.c + + + + + gd32f4xx_usart.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + + + + + gd32f4xx_wwdgt.c + 1 + Libraries\GD32F4xx_standard_peripheral\Source\gd32f4xx_wwdgt.c + + + + + system_gd32f4xx.c + 1 + Libraries\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + + + + + startup_gd32f4xx.s + 2 + Libraries\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f4xx.s + + + + + cpu + + + backtrace.c + 1 + ..\..\libcpu\arm\common\backtrace.c + + + + + div0.c + 1 + ..\..\libcpu\arm\common\div0.c + + + + + showmem.c + 1 + ..\..\libcpu\arm\common\showmem.c + + + + + cpuport.c + 1 + ..\..\libcpu\arm\cortex-m4\cpuport.c + + + + + context_rvds.S + 2 + ..\..\libcpu\arm\cortex-m4\context_rvds.S + + + + + Filesystem + + + dfs.c + 1 + ..\..\components\dfs\src\dfs.c + + + + + dfs_file.c + 1 + ..\..\components\dfs\src\dfs_file.c + + + + + dfs_fs.c + 1 + ..\..\components\dfs\src\dfs_fs.c + + + + + dfs_posix.c + 1 + ..\..\components\dfs\src\dfs_posix.c + + + + + poll.c + 1 + ..\..\components\dfs\src\poll.c + + + + + select.c + 1 + ..\..\components\dfs\src\select.c + + + + + devfs.c + 1 + ..\..\components\dfs\filesystems\devfs\devfs.c + + + + + dfs_elm.c + 1 + ..\..\components\dfs\filesystems\elmfat\dfs_elm.c + + + + + ff.c + 1 + ..\..\components\dfs\filesystems\elmfat\ff.c + + + + + DeviceDrivers + + + pin.c + 1 + ..\..\components\drivers\misc\pin.c + + + + + serial.c + 1 + ..\..\components\drivers\serial\serial.c + + + + + completion.c + 1 + ..\..\components\drivers\src\completion.c + + + + + dataqueue.c + 1 + ..\..\components\drivers\src\dataqueue.c + + + + + pipe.c + 1 + ..\..\components\drivers\src\pipe.c + + + + + ringblk_buf.c + 1 + ..\..\components\drivers\src\ringblk_buf.c + + + + + ringbuffer.c + 1 + ..\..\components\drivers\src\ringbuffer.c + + + + + waitqueue.c + 1 + ..\..\components\drivers\src\waitqueue.c + + + + + workqueue.c + 1 + ..\..\components\drivers\src\workqueue.c + + + + + finsh + + + shell.c + 1 + ..\..\components\finsh\shell.c + + + + + symbol.c + 1 + ..\..\components\finsh\symbol.c + + + + + cmd.c + 1 + ..\..\components\finsh\cmd.c + + + + + msh.c + 1 + ..\..\components\finsh\msh.c + + + + + msh_cmd.c + 1 + ..\..\components\finsh\msh_cmd.c + + + + + msh_file.c + 1 + ..\..\components\finsh\msh_file.c + + + + + finsh_compiler.c + 1 + ..\..\components\finsh\finsh_compiler.c + + + + + finsh_error.c + 1 + ..\..\components\finsh\finsh_error.c + + + + + finsh_heap.c + 1 + ..\..\components\finsh\finsh_heap.c + + + + + finsh_init.c + 1 + ..\..\components\finsh\finsh_init.c + + + + + finsh_node.c + 1 + ..\..\components\finsh\finsh_node.c + + + + + finsh_ops.c + 1 + ..\..\components\finsh\finsh_ops.c + + + + + finsh_parser.c + 1 + ..\..\components\finsh\finsh_parser.c + + + + + finsh_var.c + 1 + ..\..\components\finsh\finsh_var.c + + + + + finsh_vm.c + 1 + ..\..\components\finsh\finsh_vm.c + + + + + finsh_token.c + 1 + ..\..\components\finsh\finsh_token.c + + + + + libc + + + libc.c + 1 + ..\..\components\libc\compilers\armlibc\libc.c + + + + + mem_std.c + 1 + ..\..\components\libc\compilers\armlibc\mem_std.c + + + + + stdio.c + 1 + ..\..\components\libc\compilers\armlibc\stdio.c + + + + + stubs.c + 1 + ..\..\components\libc\compilers\armlibc\stubs.c + + + + + time.c + 1 + ..\..\components\libc\compilers\armlibc\time.c + + + + + gmtime_r.c + 1 + ..\..\components\libc\compilers\common\gmtime_r.c + + + + + lwIP + + + sys_arch.c + 1 + ..\..\components\net\lwip-2.0.2\src\arch\sys_arch.c + + + + + api_lib.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\api_lib.c + + + + + api_msg.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\api_msg.c + + + + + err.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\err.c + + + + + netbuf.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\netbuf.c + + + + + netdb.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\netdb.c + + + + + netifapi.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\netifapi.c + + + + + sockets.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\sockets.c + + + + + tcpip.c + 1 + ..\..\components\net\lwip-2.0.2\src\api\tcpip.c + + + + + def.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\def.c + + + + + dns.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\dns.c + + + + + inet_chksum.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\inet_chksum.c + + + + + init.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\init.c + + + + + ip.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ip.c + + + + + memp.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\memp.c + + + + + netif.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\netif.c + + + + + pbuf.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\pbuf.c + + + + + raw.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\raw.c + + + + + stats.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\stats.c + + + + + sys.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\sys.c + + + + + tcp.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\tcp.c + + + + + tcp_in.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\tcp_in.c + + + + + tcp_out.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\tcp_out.c + + + + + timeouts.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\timeouts.c + + + + + udp.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\udp.c + + + + + ethernet.c + 1 + ..\..\components\net\lwip-2.0.2\src\netif\ethernet.c + + + + + ethernetif.c + 1 + ..\..\components\net\lwip-2.0.2\src\netif\ethernetif.c + + + + + lowpan6.c + 1 + ..\..\components\net\lwip-2.0.2\src\netif\lowpan6.c + + + + + autoip.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\autoip.c + + + + + dhcp.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\dhcp.c + + + + + etharp.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\etharp.c + + + + + icmp.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\icmp.c + + + + + igmp.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\igmp.c + + + + + ip4.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4.c + + + + + ip4_addr.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4_addr.c + + + + + ip4_frag.c + 1 + ..\..\components\net\lwip-2.0.2\src\core\ipv4\ip4_frag.c + + + + + ping.c + 1 + ..\..\components\net\lwip-2.0.2\src\apps\ping\ping.c + + + + + netdev + + + netdev.c + 1 + ..\..\components\net\netdev\src\netdev.c + + + + + netdev_ipaddr.c + 1 + ..\..\components\net\netdev\src\netdev_ipaddr.c + + + + + SAL + + + sal_socket.c + 1 + ..\..\components\net\sal_socket\src\sal_socket.c + + + + + net_netdb.c + 1 + ..\..\components\net\sal_socket\socket\net_netdb.c + + + + + af_inet_lwip.c + 1 + ..\..\components\net\sal_socket\impl\af_inet_lwip.c + + + + + net_sockets.c + 1 + ..\..\components\net\sal_socket\socket\net_sockets.c + + + + + dfs_net.c + 1 + ..\..\components\net\sal_socket\dfs_net\dfs_net.c + + + + + + +
diff --git a/bsp/gd32/gd32407v-start/project.uvprojx b/bsp/gd32/gd32407v-start/project.uvprojx new file mode 100644 index 0000000000..64c3b12177 --- /dev/null +++ b/bsp/gd32/gd32407v-start/project.uvprojx @@ -0,0 +1,723 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::.\ARMCC + 0 + + + GD32F407VK + GigaDevice + GigaDevice.GD32F4xx_DFP.2.1.0 + http://gd32mcu.com/data/documents/pack/ + IRAM(0x20000000,0x030000) IRAM2(0x10000000,0x010000) IROM(0x08000000,0x0300000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM)) + 0 + $$Device:GD32F407VK$Device\Include\gd32f4xx.h + + + + + + + + + + $$Device:GD32F407VK$SVD\GD32F4xx.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32f4xx + 1 + 0 + 0 + 1 + 0 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + GD3232F407xx, USE_STDPERIPH_DRIVER, __RTTHREAD__, __CLK_TCK=RT_TICK_PER_SECOND + + applications;.;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;board;..\libraries\HAL_Drivers;..\..\..\components\finsh;.;..\..\..\include;..\..\..\components\libc\compilers\common;..\..\..\components\libc\compilers\common\none-gcc;..\libraries\GD32F4xx_HAL\CMSIS\GD\GD32F4xx\Include;..\libraries\GD32F4xx_HAL\CMSIS;..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Include;..\..\..\examples\utest\testcases\kernel + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\gd32_rom.ld + + + + + + + + + + + Applications + + + main.c + 1 + applications\main.c + + + + + CPU + + + showmem.c + 1 + ..\..\..\libcpu\arm\common\showmem.c + + + backtrace.c + 1 + ..\..\..\libcpu\arm\common\backtrace.c + + + div0.c + 1 + ..\..\..\libcpu\arm\common\div0.c + + + cpuport.c + 1 + ..\..\..\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + ..\..\..\libcpu\arm\cortex-m4\context_rvds.S + + + + + DeviceDrivers + + + pin.c + 1 + ..\..\..\components\drivers\misc\pin.c + + + serial.c + 1 + ..\..\..\components\drivers\serial\serial.c + + + ringblk_buf.c + 1 + ..\..\..\components\drivers\src\ringblk_buf.c + + + pipe.c + 1 + ..\..\..\components\drivers\src\pipe.c + + + waitqueue.c + 1 + ..\..\..\components\drivers\src\waitqueue.c + + + ringbuffer.c + 1 + ..\..\..\components\drivers\src\ringbuffer.c + + + completion.c + 1 + ..\..\..\components\drivers\src\completion.c + + + workqueue.c + 1 + ..\..\..\components\drivers\src\workqueue.c + + + dataqueue.c + 1 + ..\..\..\components\drivers\src\dataqueue.c + + + + + Drivers + + + startup_gd32f4xx.s + 2 + ..\libraries\GD32F4xx_HAL\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f4xx.s + + + board.c + 1 + board\board.c + + + drv_gpio.c + 1 + ..\libraries\HAL_Drivers\drv_gpio.c + + + drv_usart.c + 1 + ..\libraries\HAL_Drivers\drv_usart.c + + + + + finsh + + + finsh_node.c + 1 + ..\..\..\components\finsh\finsh_node.c + + + finsh_parser.c + 1 + ..\..\..\components\finsh\finsh_parser.c + + + cmd.c + 1 + ..\..\..\components\finsh\cmd.c + + + msh.c + 1 + ..\..\..\components\finsh\msh.c + + + finsh_vm.c + 1 + ..\..\..\components\finsh\finsh_vm.c + + + shell.c + 1 + ..\..\..\components\finsh\shell.c + + + finsh_var.c + 1 + ..\..\..\components\finsh\finsh_var.c + + + finsh_compiler.c + 1 + ..\..\..\components\finsh\finsh_compiler.c + + + finsh_heap.c + 1 + ..\..\..\components\finsh\finsh_heap.c + + + finsh_ops.c + 1 + ..\..\..\components\finsh\finsh_ops.c + + + finsh_error.c + 1 + ..\..\..\components\finsh\finsh_error.c + + + finsh_token.c + 1 + ..\..\..\components\finsh\finsh_token.c + + + finsh_init.c + 1 + ..\..\..\components\finsh\finsh_init.c + + + + + Kernel + + + thread.c + 1 + ..\..\..\src\thread.c + + + timer.c + 1 + ..\..\..\src\timer.c + + + clock.c + 1 + ..\..\..\src\clock.c + + + components.c + 1 + ..\..\..\src\components.c + + + device.c + 1 + ..\..\..\src\device.c + + + scheduler.c + 1 + ..\..\..\src\scheduler.c + + + mem.c + 1 + ..\..\..\src\mem.c + + + mempool.c + 1 + ..\..\..\src\mempool.c + + + idle.c + 1 + ..\..\..\src\idle.c + + + ipc.c + 1 + ..\..\..\src\ipc.c + + + kservice.c + 1 + ..\..\..\src\kservice.c + + + irq.c + 1 + ..\..\..\src\irq.c + + + object.c + 1 + ..\..\..\src\object.c + + + + + libc + + + time.c + 1 + ..\..\..\components\libc\compilers\common\time.c + + + + + Libraries + + + gd32f4xx_syscfg.c + 1 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + + + gd32f4xx_exti.c + 1 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + + + gd32f4xx_gpio.c + 1 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + + + gd32f4xx_rcu.c + 1 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + + + gd32f4xx_misc.c + 1 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + + + gd32f4xx_usart.c + 1 + ..\libraries\GD32F4xx_HAL\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + + + system_gd32f4xx.c + 1 + ..\libraries\GD32F4xx_HAL\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + + + + + <Project Info> + + + + + + 0 + 1 + + + + +
diff --git a/bsp/gd32/gd32407v-start/rtconfig.h b/bsp/gd32/gd32407v-start/rtconfig.h new file mode 100644 index 0000000000..5e3a5e4ea1 --- /dev/null +++ b/bsp/gd32/gd32407v-start/rtconfig.h @@ -0,0 +1,172 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 4 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 100 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 256 + +/* kservice optimization */ + +#define RT_DEBUG +#define RT_DEBUG_COLOR + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLE_DEVICE_NAME "uart1" +#define RT_VER_NUM 0x40004 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 + +/* C++ features */ + + +/* Command shell */ + +#define RT_USING_FINSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_CMD_SIZE 80 +#define FINSH_USING_MSH +#define FINSH_USING_MSH_DEFAULT +#define FINSH_ARG_MAX 10 + +/* Device virtual file system */ + + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_PIPE_BUFSZ 512 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_PIN + +/* Using USB */ + + +/* POSIX layer and C standard library */ + +#define RT_LIBC_USING_TIME +#define RT_LIBC_DEFAULT_TIMEZONE 8 + +/* Network */ + +/* Socket abstraction layer */ + + +/* Network interface device */ + + +/* light weight TCP/IP stack */ + + +/* AT commands */ + + +/* VBUS(Virtual Software BUS) */ + + +/* Utilities */ + + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + + +/* multimedia packages */ + + +/* tools packages */ + + +/* system packages */ + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + + +/* AI packages */ + + +/* miscellaneous packages */ + + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + +#define SOC_GD32407V +#define BSP_USING_UART1 + +#endif diff --git a/bsp/gd32/gd32407v-start/rtconfig.py b/bsp/gd32/gd32407v-start/rtconfig.py new file mode 100644 index 0000000000..70651871c5 --- /dev/null +++ b/bsp/gd32/gd32407v-start/rtconfig.py @@ -0,0 +1,150 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m4' +CROSS_TOOL='keil' + +# bsp lib config +BSP_LIBRARY_TYPE = None + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'C:\Users\XXYYZZ' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = r'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + CXX = PREFIX + 'g++' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -DGD32F407' + CFLAGS = DEVICE + ' -Dgcc' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.ld' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -g' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + CXX = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M4.fp ' + CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99' + AFLAGS = DEVICE + ' --apcs=interwork ' + LFLAGS = DEVICE + ' --scatter "board\linker_scripts\link.sct" --info sizes --info totals --info unused --info veneers --list rtthread.map --strict' + CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include' + LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCC/lib' + + CFLAGS += ' -D__MICROLIB ' + AFLAGS += ' --pd "__MICROLIB SETA 1" ' + LFLAGS += ' --library_type=microlib ' + EXEC_PATH += '/ARM/ARMCC/bin/' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + CFLAGS += ' -std=c99' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + CXX = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = '-Dewarm' + + CFLAGS = DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M4' + CFLAGS += ' -e' + CFLAGS += ' --fpu=VFPv4_sp' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' --silent' + + AFLAGS = DEVICE + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M4' + AFLAGS += ' --fpu VFPv4_sp' + AFLAGS += ' -S' + + if BUILD == 'debug': + CFLAGS += ' --debug' + CFLAGS += ' -On' + else: + CFLAGS += ' -Oh' + + LFLAGS = ' --config "board/linker_scripts/link.icf"' + LFLAGS += ' --entry __iar_program_start' + + CXXFLAGS = CFLAGS + + EXEC_PATH = EXEC_PATH + '/arm/bin/' + POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' + +def dist_handle(BSP_ROOT, dist_dir): + import sys + cwd_path = os.getcwd() + sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) + from sdk_dist import dist_do_building + dist_do_building(BSP_ROOT, dist_dir) diff --git a/bsp/gd32/gd32407v-start/template.uvoptx b/bsp/gd32/gd32407v-start/template.uvoptx new file mode 100644 index 0000000000..664bc65176 --- /dev/null +++ b/bsp/gd32/gd32407v-start/template.uvoptx @@ -0,0 +1,190 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\build\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 3 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + 0 + CMSIS_AGDI + -X"CMSIS-DAP" -O206 -S0 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB.FLM -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM) + + + 0 + JL2CM3 + -U59401765 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB.FLM -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM)) + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/bsp/gd32/gd32407v-start/template.uvproj b/bsp/gd32/gd32407v-start/template.uvproj new file mode 100644 index 0000000000..408784da46 --- /dev/null +++ b/bsp/gd32/gd32407v-start/template.uvproj @@ -0,0 +1,628 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + 0 + + + GD32F407VK + GigaDevice + IRAM(0x20000000-0x2002FFFF) IRAM2(0x10000000-0x1000FFFF) IROM(0x08000000-0x082FFFFF) CLOCK(16000000) CPUTYPE("Cortex-M4") FPU2 + + "Startup\GD\GD32F4xx\startup_gd32f4xx.s" ("GD32F4xx Startup Code") + UL2CM3(-O207 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000) + 0 + gd32f4xx0.h + + + + + + + + + + SFD\GD\GD32F4xx\GD32F4xx.SFR + 0 + 0 + + + + GD\GD32F4xx\ + GD\GD32F4xx\ + + 0 + 0 + 0 + 0 + 1 + + .\output\ + rtthread-gd32f4xx + 1 + 0 + 1 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP + DCM.DLL + -pCM3 + SARMCM3.DLL + + TCM.DLL + -pCM3 + + + + 1 + 0 + 0 + 0 + 16 + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + + 0 + 3 + + + + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 1 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Include;..\..\..\Library\Firmware\CMSIS\GD\GD32F4xx\Include;..\..\..\Library\Utilities;..\ + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + Application + + + main.c + 1 + ..\main.c + + + gd32f4xx_it.c + 1 + ..\gd32f4xx_it.c + + + + + CMSIS + + + system_gd32f4xx.c + 1 + ..\..\..\Library\Firmware\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c + + + + + GD32F4xx_Peripherals + + + gd32f4xx_adc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_adc.c + + + gd32f4xx_can.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_can.c + + + gd32f4xx_crc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_crc.c + + + gd32f4xx_ctc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_ctc.c + + + gd32f4xx_dac.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dac.c + + + gd32f4xx_dbg.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dbg.c + + + gd32f4xx_dci.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dci.c + + + gd32f4xx_dma.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_dma.c + + + gd32f4xx_enet.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_enet.c + + + gd32f4xx_exmc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_exmc.c + + + gd32f4xx_exti.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_exti.c + + + gd32f4xx_fmc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_fmc.c + + + gd32f4xx_fwdgt.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_fwdgt.c + + + gd32f4xx_gpio.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_gpio.c + + + gd32f4xx_i2c.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_i2c.c + + + gd32f4xx_ipa.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_ipa.c + + + gd32f4xx_iref.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_iref.c + + + gd32f4xx_misc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_misc.c + + + gd32f4xx_pmu.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_pmu.c + + + gd32f4xx_rcu.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_rcu.c + + + gd32f4xx_rtc.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_rtc.c + + + gd32f4xx_sdio.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_sdio.c + + + gd32f4xx_spi.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_spi.c + + + gd32f4xx_syscfg.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_syscfg.c + + + gd32f4xx_timer.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_timer.c + + + gd32f4xx_tli.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_tli.c + + + gd32f4xx_trng.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_trng.c + + + gd32f4xx_usart.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_usart.c + + + gd32f4xx_wwdgt.c + 1 + ..\..\..\Library\Firmware\GD32F4xx_standard_peripheral\Source\gd32f4xx_wwdgt.c + + + + + GD32F4xx_EVAL + + + gd32f450z_eval.c + 1 + ..\..\..\Library\Utilities\gd32f450z_eval.c + + + + + Startup + + + startup_gd32f4xx.s + 2 + ..\..\..\Library\Firmware\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f4xx.s + + + + + Doc + + + readme.txt + 5 + ..\readme.txt + + + + + + + +
diff --git a/bsp/gd32/gd32407v-start/template.uvprojx b/bsp/gd32/gd32407v-start/template.uvprojx new file mode 100644 index 0000000000..e06b13d247 --- /dev/null +++ b/bsp/gd32/gd32407v-start/template.uvprojx @@ -0,0 +1,417 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32f4xx + 0x4 + ARM-ADS + 0 + + + GD32F407VK + GigaDevice + GigaDevice.GD32F4xx_DFP.2.1.0 + http://gd32mcu.com/data/documents/pack/ + IRAM(0x20000000,0x030000) IRAM2(0x10000000,0x010000) IROM(0x08000000,0x0300000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32F4xx_3MB -FS08000000 -FL0300000 -FP0($$Device:GD32F407VK$Flash\GD32F4xx_3MB.FLM)) + 0 + $$Device:GD32F407VK$Device\Include\gd32f4xx.h + + + + + + + + + + $$Device:GD32F407VK$SVD\GD32F4xx.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32f4xx + 1 + 0 + 0 + 1 + 0 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 1 + 0x8000000 + 0x300000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x300000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x30000 + + + 0 + 0x10000000 + 0x10000 + + + + + + 1 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\gd32_rom.ld + + + + + + + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + + + + + <Project Info> + + + + + + 0 + 1 + + + + +
diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h new file mode 100644 index 0000000000..a901975bbd --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h @@ -0,0 +1,366 @@ +/*! + \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) + /* #define GD32F450 */ + /* #define GD32F405 */ + /* #define GD32F407 */ +#endif /* define GD32F4xx */ + +#if !defined (GD32F450) && !defined (GD32F405) && !defined (GD32F407) + #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) + 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 */ + +#if defined (GD32F405) + 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 */ + +#if defined (GD32F407) + 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 */ + +} IRQn_Type; + +/* includes */ +#include "core_cm4.h" +#include "system_gd32f4xx.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {FALSE = 0, TRUE = !FALSE} bool; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !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 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/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Include/system_gd32f4xx.h new file mode 100644 index 0000000000..ab8e80e7e9 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/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/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s new file mode 100644 index 0000000000..eb11e413dc --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s @@ -0,0 +1,427 @@ +;/*! +; \file startup_gd32f4xx.s +; \brief start up file +;*/ + +;/* +; Copyright (C) 2016 GigaDevice + +; 2016-08-15, V1.0.0, firmware for GD32F4xx +;*/ + +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000400 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; /* reset Vector Mapped to at Address 0 */ + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD TAMPER_STAMP_IRQHandler ; 18:Tamper and TimeStamp through EXTI Line detect + DCD RTC_WKUP_IRQHandler ; 19:RTC Wakeup through EXTI Line + DCD FMC_IRQHandler ; 20:FMC + DCD RCU_CTC_IRQHandler ; 21:RCU and CTC + DCD EXTI0_IRQHandler ; 22:EXTI Line 0 + DCD EXTI1_IRQHandler ; 23:EXTI Line 1 + DCD EXTI2_IRQHandler ; 24:EXTI Line 2 + DCD EXTI3_IRQHandler ; 25:EXTI Line 3 + DCD EXTI4_IRQHandler ; 26:EXTI Line 4 + DCD DMA0_Channel0_IRQHandler ; 27:DMA0 Channel0 + DCD DMA0_Channel1_IRQHandler ; 28:DMA0 Channel1 + DCD DMA0_Channel2_IRQHandler ; 29:DMA0 Channel2 + DCD DMA0_Channel3_IRQHandler ; 30:DMA0 Channel3 + DCD DMA0_Channel4_IRQHandler ; 31:DMA0 Channel4 + DCD DMA0_Channel5_IRQHandler ; 32:DMA0 Channel5 + DCD DMA0_Channel6_IRQHandler ; 33:DMA0 Channel6 + DCD ADC_IRQHandler ; 34:ADC + DCD CAN0_TX_IRQHandler ; 35:CAN0 TX + DCD CAN0_RX0_IRQHandler ; 36:CAN0 RX0 + DCD CAN0_RX1_IRQHandler ; 37:CAN0 RX1 + DCD CAN0_EWMC_IRQHandler ; 38:CAN0 EWMC + DCD EXTI5_9_IRQHandler ; 39:EXTI5 to EXTI9 + DCD TIMER0_BRK_TIMER8_IRQHandler ; 40:TIMER0 Break and TIMER8 + DCD TIMER0_UP_TIMER9_IRQHandler ; 41:TIMER0 Update and TIMER9 + DCD TIMER0_TRG_CMT_TIMER10_IRQHandler ; 42:TIMER0 Trigger and Commutation and TIMER10 + DCD TIMER0_CC_IRQHandler ; 43:TIMER0 Capture Compare + DCD TIMER1_IRQHandler ; 44:TIMER1 + DCD TIMER2_IRQHandler ; 45:TIMER2 + DCD TIMER3_IRQHandler ; 46:TIMER3 + DCD I2C0_EV_IRQHandler ; 47:I2C0 Event + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD I2C1_EV_IRQHandler ; 49:I2C1 Event + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD SPI0_IRQHandler ; 51:SPI0 + DCD SPI1_IRQHandler ; 52:SPI1 + DCD USART0_IRQHandler ; 53:USART0 + DCD USART1_IRQHandler ; 54:USART1 + DCD USART2_IRQHandler ; 55:USART2 + DCD EXTI10_15_IRQHandler ; 56:EXTI10 to EXTI15 + DCD RTC_Alarm_IRQHandler ; 57:RTC Alarm + DCD USBFS_WKUP_IRQHandler ; 58:USBFS Wakeup + DCD TIMER7_BRK_TIMER11_IRQHandler ; 59:TIMER7 Break and TIMER11 + DCD TIMER7_UP_TIMER12_IRQHandler ; 60:TIMER7 Update and TIMER12 + DCD TIMER7_TRG_CMT_TIMER13_IRQHandler ; 61:TIMER7 Trigger and Commutation and TIMER13 + DCD TIMER7_CC_IRQHandler ; 62:TIMER7 Capture Compare + DCD DMA0_Channel7_IRQHandler ; 63:DMA0 Channel7 + DCD EXMC_IRQHandler ; 64:EXMC + DCD SDIO_IRQHandler ; 65:SDIO + DCD TIMER4_IRQHandler ; 66:TIMER4 + DCD SPI2_IRQHandler ; 67:SPI2 + DCD UART3_IRQHandler ; 68:UART3 + DCD UART4_IRQHandler ; 69:UART4 + DCD TIMER5_DAC_IRQHandler ; 70:TIMER5 and DAC0 DAC1 Underrun error + DCD TIMER6_IRQHandler ; 71:TIMER6 + DCD DMA1_Channel0_IRQHandler ; 72:DMA1 Channel0 + DCD DMA1_Channel1_IRQHandler ; 73:DMA1 Channel1 + DCD DMA1_Channel2_IRQHandler ; 74:DMA1 Channel2 + DCD DMA1_Channel3_IRQHandler ; 75:DMA1 Channel3 + DCD DMA1_Channel4_IRQHandler ; 76:DMA1 Channel4 + DCD ENET_IRQHandler ; 77:Ethernet + DCD ENET_WKUP_IRQHandler ; 78:Ethernet Wakeup through EXTI Line + DCD CAN1_TX_IRQHandler ; 79:CAN1 TX + DCD CAN1_RX0_IRQHandler ; 80:CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; 81:CAN1 RX1 + DCD CAN1_EWMC_IRQHandler ; 82:CAN1 EWMC + DCD USBFS_IRQHandler ; 83:USBFS + DCD DMA1_Channel5_IRQHandler ; 84:DMA1 Channel5 + DCD DMA1_Channel6_IRQHandler ; 85:DMA1 Channel6 + DCD DMA1_Channel7_IRQHandler ; 86:DMA1 Channel7 + DCD USART5_IRQHandler ; 87:USART5 + DCD I2C2_EV_IRQHandler ; 88:I2C2 Event + DCD I2C2_ER_IRQHandler ; 89:I2C2 Error + DCD USBHS_EP1_Out_IRQHandler ; 90:USBHS Endpoint 1 Out + DCD USBHS_EP1_In_IRQHandler ; 91:USBHS Endpoint 1 in + DCD USBHS_WKUP_IRQHandler ; 92:USBHS Wakeup through EXTI Line + DCD USBHS_IRQHandler ; 93:USBHS + DCD DCI_IRQHandler ; 94:DCI + DCD 0 ; 95:Reserved + DCD TRNG_IRQHandler ; 96:TRNG + DCD FPU_IRQHandler ; 97:FPU + DCD UART6_IRQHandler ; 98:UART6 + DCD UART7_IRQHandler ; 98:UART7 + DCD SPI3_IRQHandler ; 100:SPI3 + DCD SPI4_IRQHandler ; 101:SPI4 + DCD SPI5_IRQHandler ; 102:SPI5 + DCD TLI_IRQHandler ; 104:TLI + DCD TLI_ER_IRQHandler ; 105:TLI Error + DCD IPA_IRQHandler ; 106:IPA + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +;/* reset Handler */ +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +;/* dummy Exception Handlers */ +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC +; /* external interrupts handler */ + EXPORT WWDGT_IRQHandler [WEAK] + EXPORT LVD_IRQHandler [WEAK] + EXPORT TAMPER_STAMP_IRQHandler [WEAK] + EXPORT RTC_WKUP_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT RCU_CTC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT DMA0_Channel0_IRQHandler [WEAK] + EXPORT DMA0_Channel1_IRQHandler [WEAK] + EXPORT DMA0_Channel2_IRQHandler [WEAK] + EXPORT DMA0_Channel3_IRQHandler [WEAK] + EXPORT DMA0_Channel4_IRQHandler [WEAK] + EXPORT DMA0_Channel5_IRQHandler [WEAK] + EXPORT DMA0_Channel6_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT CAN0_TX_IRQHandler [WEAK] + EXPORT CAN0_RX0_IRQHandler [WEAK] + EXPORT CAN0_RX1_IRQHandler [WEAK] + EXPORT CAN0_EWMC_IRQHandler [WEAK] + EXPORT EXTI5_9_IRQHandler [WEAK] + EXPORT TIMER0_BRK_TIMER8_IRQHandler [WEAK] + EXPORT TIMER0_UP_TIMER9_IRQHandler [WEAK] + EXPORT TIMER0_TRG_CMT_TIMER10_IRQHandler [WEAK] + EXPORT TIMER0_CC_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT I2C0_EV_IRQHandler [WEAK] + EXPORT I2C0_ER_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT SPI0_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT USART0_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT EXTI10_15_IRQHandler [WEAK] + EXPORT RTC_Alarm_IRQHandler [WEAK] + EXPORT USBFS_WKUP_IRQHandler [WEAK] + EXPORT TIMER7_BRK_TIMER11_IRQHandler [WEAK] + EXPORT TIMER7_UP_TIMER12_IRQHandler [WEAK] + EXPORT TIMER7_TRG_CMT_TIMER13_IRQHandler [WEAK] + EXPORT TIMER7_CC_IRQHandler [WEAK] + EXPORT DMA0_Channel7_IRQHandler [WEAK] + EXPORT EXMC_IRQHandler [WEAK] + EXPORT SDIO_IRQHandler [WEAK] + EXPORT TIMER4_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT UART3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT TIMER5_DAC_IRQHandler [WEAK] + EXPORT TIMER6_IRQHandler [WEAK] + EXPORT DMA1_Channel0_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel2_IRQHandler [WEAK] + EXPORT DMA1_Channel3_IRQHandler [WEAK] + EXPORT DMA1_Channel4_IRQHandler [WEAK] + EXPORT ENET_IRQHandler [WEAK] + EXPORT ENET_WKUP_IRQHandler [WEAK] + EXPORT CAN1_TX_IRQHandler [WEAK] + EXPORT CAN1_RX0_IRQHandler [WEAK] + EXPORT CAN1_RX1_IRQHandler [WEAK] + EXPORT CAN1_EWMC_IRQHandler [WEAK] + EXPORT USBFS_IRQHandler [WEAK] + EXPORT DMA1_Channel5_IRQHandler [WEAK] + EXPORT DMA1_Channel6_IRQHandler [WEAK] + EXPORT DMA1_Channel7_IRQHandler [WEAK] + EXPORT USART5_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT USBHS_EP1_Out_IRQHandler [WEAK] + EXPORT USBHS_EP1_In_IRQHandler [WEAK] + EXPORT USBHS_WKUP_IRQHandler [WEAK] + EXPORT USBHS_IRQHandler [WEAK] + EXPORT DCI_IRQHandler [WEAK] + EXPORT TRNG_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT UART6_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT TLI_IRQHandler [WEAK] + EXPORT TLI_ER_IRQHandler [WEAK] + EXPORT IPA_IRQHandler [WEAK] + +;/* external interrupts handler */ +WWDGT_IRQHandler +LVD_IRQHandler +TAMPER_STAMP_IRQHandler +RTC_WKUP_IRQHandler +FMC_IRQHandler +RCU_CTC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +DMA0_Channel0_IRQHandler +DMA0_Channel1_IRQHandler +DMA0_Channel2_IRQHandler +DMA0_Channel3_IRQHandler +DMA0_Channel4_IRQHandler +DMA0_Channel5_IRQHandler +DMA0_Channel6_IRQHandler +ADC_IRQHandler +CAN0_TX_IRQHandler +CAN0_RX0_IRQHandler +CAN0_RX1_IRQHandler +CAN0_EWMC_IRQHandler +EXTI5_9_IRQHandler +TIMER0_BRK_TIMER8_IRQHandler +TIMER0_UP_TIMER9_IRQHandler +TIMER0_TRG_CMT_TIMER10_IRQHandler +TIMER0_CC_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +TIMER3_IRQHandler +I2C0_EV_IRQHandler +I2C0_ER_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +SPI0_IRQHandler +SPI1_IRQHandler +USART0_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +EXTI10_15_IRQHandler +RTC_Alarm_IRQHandler +USBFS_WKUP_IRQHandler +TIMER7_BRK_TIMER11_IRQHandler +TIMER7_UP_TIMER12_IRQHandler +TIMER7_TRG_CMT_TIMER13_IRQHandler +TIMER7_CC_IRQHandler +DMA0_Channel7_IRQHandler +EXMC_IRQHandler +SDIO_IRQHandler +TIMER4_IRQHandler +SPI2_IRQHandler +UART3_IRQHandler +UART4_IRQHandler +TIMER5_DAC_IRQHandler +TIMER6_IRQHandler +DMA1_Channel0_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel2_IRQHandler +DMA1_Channel3_IRQHandler +DMA1_Channel4_IRQHandler +ENET_IRQHandler +ENET_WKUP_IRQHandler +CAN1_TX_IRQHandler +CAN1_RX0_IRQHandler +CAN1_RX1_IRQHandler +CAN1_EWMC_IRQHandler +USBFS_IRQHandler +DMA1_Channel5_IRQHandler +DMA1_Channel6_IRQHandler +DMA1_Channel7_IRQHandler +USART5_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +USBHS_EP1_Out_IRQHandler +USBHS_EP1_In_IRQHandler +USBHS_WKUP_IRQHandler +USBHS_IRQHandler +DCI_IRQHandler +TRNG_IRQHandler +FPU_IRQHandler +UART6_IRQHandler +UART7_IRQHandler +SPI3_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +TLI_IRQHandler +TLI_ER_IRQHandler +IPA_IRQHandler + + B . + ENDP + + ALIGN + +; user Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S new file mode 100644 index 0000000000..149472da00 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S @@ -0,0 +1,315 @@ +;/* +; * Copyright (c) 2006-2021, RT-Thread Development Team +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Change Logs: +; * Date Author Notes +; * 2018-05-22 tanek first implementation +; */ + +.syntax unified +.cpu cortex-m4 +.fpu softvfp +.thumb + +.global g_pfnVectors +.global Default_Handler + + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + +g_pfnVectors: + .word _estack // Top of Stack + .word Reset_Handler // Reset Handler + .word NMI_Handler // NMI Handler + .word HardFault_Handler // Hard Fault Handler + .word MemManage_Handler // MPU Fault Handler + .word BusFault_Handler // Bus Fault Handler + .word UsageFault_Handler // Usage Fault Handler + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word 0 // Reserved + .word SVC_Handler // SVCall Handler + .word DebugMon_Handler // Debug Monitor Handler + .word 0 // Reserved + .word PendSV_Handler // PendSV Handler + .word SysTick_Handler // SysTick Handler + + // external interrupts handler + .word WWDGT_IRQHandler // 16:Window Watchdog Timer + .word LVD_IRQHandler // 17:LVD through EXTI Line detect + .word TAMPER_STAMP_IRQHandler // 18:Tamper and TimeStamp through EXTI Line detect + .word RTC_WKUP_IRQHandler // 19:RTC Wakeup through EXTI Line + .word FMC_IRQHandler // 20:FMC + .word RCU_CTC_IRQHandler // 21:RCU and CTC + .word EXTI0_IRQHandler // 22:EXTI Line 0 + .word EXTI1_IRQHandler // 23:EXTI Line 1 + .word EXTI2_IRQHandler // 24:EXTI Line 2 + .word EXTI3_IRQHandler // 25:EXTI Line 3 + .word EXTI4_IRQHandler // 26:EXTI Line 4 + .word DMA0_Channel0_IRQHandler // 27:DMA0 Channel0 + .word DMA0_Channel1_IRQHandler // 28:DMA0 Channel1 + .word DMA0_Channel2_IRQHandler // 29:DMA0 Channel2 + .word DMA0_Channel3_IRQHandler // 30:DMA0 Channel3 + .word DMA0_Channel4_IRQHandler // 31:DMA0 Channel4 + .word DMA0_Channel5_IRQHandler // 32:DMA0 Channel5 + .word DMA0_Channel6_IRQHandler // 33:DMA0 Channel6 + .word ADC_IRQHandler // 34:ADC + .word CAN0_TX_IRQHandler // 35:CAN0 TX + .word CAN0_RX0_IRQHandler // 36:CAN0 RX0 + .word CAN0_RX1_IRQHandler // 37:CAN0 RX1 + .word CAN0_EWMC_IRQHandler // 38:CAN0 EWMC + .word EXTI5_9_IRQHandler // 39:EXTI5 to EXTI9 + .word TIMER0_BRK_TIMER8_IRQHandler // 40:TIMER0 Break and TIMER8 + .word TIMER0_UP_TIMER9_IRQHandler // 41:TIMER0 Update and TIMER9 + .word TIMER0_TRG_CMT_TIMER10_IRQHandler // 42:TIMER0 Trigger and Commutation and TIMER10 + .word TIMER0_CC_IRQHandler // 43:TIMER0 Capture Compare + .word TIMER1_IRQHandler // 44:TIMER1 + .word TIMER2_IRQHandler // 45:TIMER2 + .word TIMER3_IRQHandler // 46:TIMER3 + .word I2C0_EV_IRQHandler // 47:I2C0 Event + .word I2C0_ER_IRQHandler // 48:I2C0 Error + .word I2C1_EV_IRQHandler // 49:I2C1 Event + .word I2C1_ER_IRQHandler // 50:I2C1 Error + .word SPI0_IRQHandler // 51:SPI0 + .word SPI1_IRQHandler // 52:SPI1 + .word USART0_IRQHandler // 53:USART0 + .word USART1_IRQHandler // 54:USART1 + .word USART2_IRQHandler // 55:USART2 + .word EXTI10_15_IRQHandler // 56:EXTI10 to EXTI15 + .word RTC_Alarm_IRQHandler // 57:RTC Alarm + .word USBFS_WKUP_IRQHandler // 58:USBFS Wakeup + .word TIMER7_BRK_TIMER11_IRQHandler // 59:TIMER7 Break and TIMER11 + .word TIMER7_UP_TIMER12_IRQHandler // 60:TIMER7 Update and TIMER12 + .word TIMER7_TRG_CMT_TIMER13_IRQHandler // 61:TIMER7 Trigger and Commutation and TIMER13 + .word TIMER7_CC_IRQHandler // 62:TIMER7 Capture Compare + .word DMA0_Channel7_IRQHandler // 63:DMA0 Channel7 + .word EXMC_IRQHandler // 64:EXMC + .word SDIO_IRQHandler // 65:SDIO + .word TIMER4_IRQHandler // 66:TIMER4 + .word SPI2_IRQHandler // 67:SPI2 + .word UART3_IRQHandler // 68:UART3 + .word UART4_IRQHandler // 69:UART4 + .word TIMER5_DAC_IRQHandler // 70:TIMER5 and DAC0 DAC1 Underrun error + .word TIMER6_IRQHandler // 71:TIMER6 + .word DMA1_Channel0_IRQHandler // 72:DMA1 Channel0 + .word DMA1_Channel1_IRQHandler // 73:DMA1 Channel1 + .word DMA1_Channel2_IRQHandler // 74:DMA1 Channel2 + .word DMA1_Channel3_IRQHandler // 75:DMA1 Channel3 + .word DMA1_Channel4_IRQHandler // 76:DMA1 Channel4 + .word ENET_IRQHandler // 77:Ethernet + .word ENET_WKUP_IRQHandler // 78:Ethernet Wakeup through EXTI Line + .word CAN1_TX_IRQHandler // 79:CAN1 TX + .word CAN1_RX0_IRQHandler // 80:CAN1 RX0 + .word CAN1_RX1_IRQHandler // 81:CAN1 RX1 + .word USBFS_IRQHandler // 83:USBFS + .word DMA1_Channel5_IRQHandler // 84:DMA1 Channel5 + .word DMA1_Channel6_IRQHandler // 85:DMA1 Channel6 + .word DMA1_Channel7_IRQHandler // 86:DMA1 Channel7 + .word USART5_IRQHandler // 87:USART5 + .word I2C2_EV_IRQHandler // 88:I2C2 Event + .word I2C2_ER_IRQHandler // 89:I2C2 Error + .word USBHS_EP1_Out_IRQHandler // 90:USBHS Endpoint 1 Out + .word USBHS_EP1_In_IRQHandler // 91:USBHS Endpoint 1 in + .word USBHS_WKUP_IRQHandler // 92:USBHS Wakeup through EXTI Line + .word USBHS_IRQHandler // 93:USBHS + .word DCI_IRQHandler // 94:DCI + .word 0 // 95:Reserved + .word TRNG_IRQHandler // 96:TRNG + .word FPU_IRQHandler // 97:FPU + .word UART6_IRQHandler // 98:UART6 + .word UART7_IRQHandler // 98:UART7 + .word SPI3_IRQHandler // 100:SPI3 + .word SPI4_IRQHandler // 101:SPI4 + .word SPI5_IRQHandler // 102:SPI5 + .word TLI_IRQHandler // 104:TLI + .word TLI_ER_IRQHandler // 105:TLI Error + .word IPA_IRQHandler // 106:IPA + + .size g_pfnVectors, .-g_pfnVectors + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r1, =_sidata + ldr r2, =_sdata + ldr r3, =_edata + + subs r3, r2 + ble fill_bss_start + +loop_copy_data: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt loop_copy_data + +fill_bss_start: + ldr r1, =__bss_start + ldr r2, =__bss_end + movs r0, 0 + subs r2, r1 + ble startup_enter + +loop_fill_bss: + subs r2, #4 + str r0, [r1, r2] + bgt loop_fill_bss + +startup_enter: + bl SystemInit + bl entry + + /* Exception Handlers */ + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + .weak MemManage_Handler + .type MemManage_Handler, %function +MemManage_Handler: + b . + .size MemManage_Handler, . - MemManage_Handler + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + .size BusFault_Handler, . - BusFault_Handler + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + .size UsageFault_Handler, . - UsageFault_Handler + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + /* IQR Handler */ + .section .text.Default_Handler,"ax",%progbits + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ WWDGT_IRQHandler + IRQ LVD_IRQHandler + IRQ TAMPER_STAMP_IRQHandler + IRQ RTC_WKUP_IRQHandler + IRQ FMC_IRQHandler + IRQ RCU_CTC_IRQHandler + IRQ EXTI0_IRQHandler + IRQ EXTI1_IRQHandler + IRQ EXTI2_IRQHandler + IRQ EXTI3_IRQHandler + IRQ EXTI4_IRQHandler + IRQ DMA0_Channel0_IRQHandler + IRQ DMA0_Channel1_IRQHandler + IRQ DMA0_Channel2_IRQHandler + IRQ DMA0_Channel3_IRQHandler + IRQ DMA0_Channel4_IRQHandler + IRQ DMA0_Channel5_IRQHandler + IRQ DMA0_Channel6_IRQHandler + IRQ ADC_IRQHandler + IRQ CAN0_TX_IRQHandler + IRQ CAN0_RX0_IRQHandler + IRQ CAN0_RX1_IRQHandler + IRQ CAN0_EWMC_IRQHandler + IRQ EXTI5_9_IRQHandler + IRQ TIMER0_BRK_TIMER8_IRQHandler + IRQ TIMER0_UP_TIMER9_IRQHandler + IRQ TIMER0_TRG_CMT_TIMER10_IRQHandler + IRQ TIMER0_CC_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ TIMER3_IRQHandler + IRQ I2C0_EV_IRQHandler + IRQ I2C0_ER_IRQHandler + IRQ I2C1_EV_IRQHandler + IRQ I2C1_ER_IRQHandler + IRQ SPI0_IRQHandler + IRQ SPI1_IRQHandler + IRQ USART0_IRQHandler + IRQ USART1_IRQHandler + IRQ USART2_IRQHandler + IRQ EXTI10_15_IRQHandler + IRQ RTC_Alarm_IRQHandler + IRQ USBFS_WKUP_IRQHandler + IRQ TIMER7_BRK_TIMER11_IRQHandler + IRQ TIMER7_UP_TIMER12_IRQHandler + IRQ TIMER7_TRG_CMT_TIMER13_IRQHandler + IRQ TIMER7_CC_IRQHandler + IRQ DMA0_Channel7_IRQHandler + IRQ EXMC_IRQHandler + IRQ SDIO_IRQHandler + IRQ TIMER4_IRQHandler + IRQ SPI2_IRQHandler + IRQ UART3_IRQHandler + IRQ UART4_IRQHandler + IRQ TIMER5_DAC_IRQHandler + IRQ TIMER6_IRQHandler + IRQ DMA1_Channel0_IRQHandler + IRQ DMA1_Channel1_IRQHandler + IRQ DMA1_Channel2_IRQHandler + IRQ DMA1_Channel3_IRQHandler + IRQ DMA1_Channel4_IRQHandler + IRQ ENET_IRQHandler + IRQ ENET_WKUP_IRQHandler + IRQ CAN1_TX_IRQHandler + IRQ CAN1_RX0_IRQHandler + IRQ CAN1_RX1_IRQHandler + IRQ CAN1_EWMC_IRQHandler + IRQ USBFS_IRQHandler + IRQ DMA1_Channel5_IRQHandler + IRQ DMA1_Channel6_IRQHandler + IRQ DMA1_Channel7_IRQHandler + IRQ USART5_IRQHandler + IRQ I2C2_EV_IRQHandler + IRQ I2C2_ER_IRQHandler + IRQ USBHS_EP1_Out_IRQHandler + IRQ USBHS_EP1_In_IRQHandler + IRQ USBHS_WKUP_IRQHandler + IRQ USBHS_IRQHandler + IRQ DCI_IRQHandler + IRQ TRNG_IRQHandler + IRQ FPU_IRQHandler + IRQ UART6_IRQHandler + IRQ UART7_IRQHandler + IRQ SPI3_IRQHandler + IRQ SPI4_IRQHandler + IRQ SPI5_IRQHandler + IRQ TLI_IRQHandler + IRQ TLI_ER_IRQHandler + IRQ IPA_IRQHandler diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s new file mode 100644 index 0000000000..87bf921267 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s @@ -0,0 +1,640 @@ +;/*! +; \file startup_gd32f4xx.s +; \brief start up file +;*/ + +;/* +; Copyright (C) 2016 GigaDevice + +; 2016-08-15, V1.0.0, firmware for GD32F4xx + +;*/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) ; top of stack + DCD Reset_Handler ; Vector Number 1,Reset Handler + + DCD NMI_Handler ; Vector Number 2,NMI Handler + DCD HardFault_Handler ; Vector Number 3,Hard Fault Handler + DCD MemManage_Handler ; Vector Number 4,MPU Fault Handler + DCD BusFault_Handler ; Vector Number 5,Bus Fault Handler + DCD UsageFault_Handler ; Vector Number 6,Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; Vector Number 11,SVCall Handler + DCD DebugMon_Handler ; Vector Number 12,Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; Vector Number 14,PendSV Handler + DCD SysTick_Handler ; Vector Number 15,SysTick Handler + + ; External Interrupts + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD TAMPER_STAMP_IRQHandler ; 18:Tamper and TimeStamp through EXTI Line detect + DCD RTC_WKUP_IRQHandler ; 19:RTC Wakeup through EXTI Line + DCD FMC_IRQHandler ; 20:FMC + DCD RCU_CTC_IRQHandler ; 21:RCU and CTC + DCD EXTI0_IRQHandler ; 22:EXTI Line 0 + DCD EXTI1_IRQHandler ; 23:EXTI Line 1 + DCD EXTI2_IRQHandler ; 24:EXTI Line 2 + DCD EXTI3_IRQHandler ; 25:EXTI Line 3 + DCD EXTI4_IRQHandler ; 26:EXTI Line 4 + DCD DMA0_Channel0_IRQHandler ; 27:DMA0 Channel0 + DCD DMA0_Channel1_IRQHandler ; 28:DMA0 Channel1 + DCD DMA0_Channel2_IRQHandler ; 29:DMA0 Channel2 + DCD DMA0_Channel3_IRQHandler ; 30:DMA0 Channel3 + DCD DMA0_Channel4_IRQHandler ; 31:DMA0 Channel4 + DCD DMA0_Channel5_IRQHandler ; 32:DMA0 Channel5 + DCD DMA0_Channel6_IRQHandler ; 33:DMA0 Channel6 + DCD ADC_IRQHandler ; 34:ADC + DCD CAN0_TX_IRQHandler ; 35:CAN0 TX + DCD CAN0_RX0_IRQHandler ; 36:CAN0 RX0 + DCD CAN0_RX1_IRQHandler ; 37:CAN0 RX1 + DCD CAN0_EWMC_IRQHandler ; 38:CAN0 EWMC + DCD EXTI5_9_IRQHandler ; 39:EXTI5 to EXTI9 + DCD TIMER0_BRK_TIMER8_IRQHandler ; 40:TIMER0 Break and TIMER8 + DCD TIMER0_UP_TIMER9_IRQHandler ; 41:TIMER0 Update and TIMER9 + DCD TIMER0_TRG_CMT_TIMER10_IRQHandler ; 42:TIMER0 Trigger and Commucation and TIMER10 + DCD TIMER0_CC_IRQHandler ; 43:TIMER0 Capture Compare + DCD TIMER1_IRQHandler ; 44:TIMER1 + DCD TIMER2_IRQHandler ; 45:TIMER2 + DCD TIMER3_IRQHandler ; 46:TIMER3 + DCD I2C0_EV_IRQHandler ; 47:I2C0 Event + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD I2C1_EV_IRQHandler ; 49:I2C1 Event + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + DCD SPI0_IRQHandler ; 51:SPI0 + DCD SPI1_IRQHandler ; 52:SPI1 + DCD USART0_IRQHandler ; 53:USART0 + DCD USART1_IRQHandler ; 54:USART1 + DCD USART2_IRQHandler ; 55:USART2 + DCD EXTI10_15_IRQHandler ; 56:EXTI10 to EXTI15 + DCD RTC_Alarm_IRQHandler ; 57:RTC Alarm + DCD USBFS_WKUP_IRQHandler ; 58:USBFS Wakeup + DCD TIMER7_BRK_TIMER11_IRQHandler ; 59:TIMER7 Break and TIMER11 + DCD TIMER7_UP_TIMER12_IRQHandler ; 60:TIMER7 Update and TIMER12 + DCD TIMER7_TRG_CMT_TIMER13_IRQHandler ; 61:TIMER7 Trigger and Commucation and TIMER13 + DCD TIMER7_CC_IRQHandler ; 62:TIMER7 Capture Compare + DCD DMA0_Channel7_IRQHandler ; 63:DMA0 Channel7 + DCD EXMC_IRQHandler ; 64:EXMC + DCD SDIO_IRQHandler ; 65:SDIO + DCD TIMER4_IRQHandler ; 66:TIMER4 + DCD SPI2_IRQHandler ; 67:SPI2 + DCD UART3_IRQHandler ; 68:UART3 + DCD UART4_IRQHandler ; 69:UART4 + DCD TIMER5_DAC_IRQHandler ; 70:TIMER5 and DAC0 DAC1 Underrun error + DCD TIMER6_IRQHandler ; 71:TIMER6 + DCD DMA1_Channel0_IRQHandler ; 72:DMA1 Channel0 + DCD DMA1_Channel1_IRQHandler ; 73:DMA1 Channel1 + DCD DMA1_Channel2_IRQHandler ; 74:DMA1 Channel2 + DCD DMA1_Channel3_IRQHandler ; 75:DMA1 Channel3 + DCD DMA1_Channel4_IRQHandler ; 76:DMA1 Channel4 + DCD ENET_IRQHandler ; 77:Ethernet + DCD ENET_WKUP_IRQHandler ; 78:Ethernet Wakeup through EXTI Line + DCD CAN1_TX_IRQHandler ; 79:CAN1 TX + DCD CAN1_RX0_IRQHandler ; 80:CAN1 RX0 + DCD CAN1_RX1_IRQHandler ; 81:CAN1 RX1 + DCD CAN1_EWMC_IRQHandler ; 82:CAN1 EWMC + DCD USBFS_IRQHandler ; 83:USBFS + DCD DMA1_Channel5_IRQHandler ; 84:DMA1 Channel5 + DCD DMA1_Channel6_IRQHandler ; 85:DMA1 Channel6 + DCD DMA1_Channel7_IRQHandler ; 86:DMA1 Channel7 + DCD USART5_IRQHandler ; 87:USART5 + DCD I2C2_EV_IRQHandler ; 88:I2C2 Event + DCD I2C2_ER_IRQHandler ; 89:I2C2 Error + DCD USBHS_EP1_Out_IRQHandler ; 90:USBHS Endpoint 1 Out + DCD USBHS_EP1_In_IRQHandler ; 91:USBHS Endpoint 1 in + DCD USBHS_WKUP_IRQHandler ; 92:USBHS Wakeup through EXTI Line + DCD USBHS_IRQHandler ; 93:USBHS + DCD DCI_IRQHandler ; 94:DCI + DCD 0 ; 95:Reserved + DCD TRNG_IRQHandler ; 96:TRNG + DCD FPU_IRQHandler ; 97:FPU + DCD UART6_IRQHandler ; 98:UART6 + DCD UART7_IRQHandler ; 98:UART7 + DCD SPI3_IRQHandler ; 100:SPI3 + DCD SPI4_IRQHandler ; 101:SPI4 + DCD SPI5_IRQHandler ; 102:SPI5 + DCD TLI_IRQHandler ; 104:TLI + DCD TLI_ER_IRQHandler ; 105:TLI Error + DCD IPA_IRQHandler ; 106:IPA + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDGT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDGT_IRQHandler + B WWDGT_IRQHandler + + PUBWEAK LVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LVD_IRQHandler + B LVD_IRQHandler + + PUBWEAK TAMPER_STAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMPER_STAMP_IRQHandler + B TAMPER_STAMP_IRQHandler + + PUBWEAK RTC_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_WKUP_IRQHandler + B RTC_WKUP_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK RCU_CTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCU_CTC_IRQHandler + B RCU_CTC_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK DMA0_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel0_IRQHandler + B DMA0_Channel0_IRQHandler + + PUBWEAK DMA0_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel1_IRQHandler + B DMA0_Channel1_IRQHandler + + PUBWEAK DMA0_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel2_IRQHandler + B DMA0_Channel2_IRQHandler + + PUBWEAK DMA0_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel3_IRQHandler + B DMA0_Channel3_IRQHandler + + PUBWEAK DMA0_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel4_IRQHandler + B DMA0_Channel4_IRQHandler + + PUBWEAK DMA0_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel5_IRQHandler + B DMA0_Channel5_IRQHandler + + PUBWEAK DMA0_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel6_IRQHandler + B DMA0_Channel6_IRQHandler + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_IRQHandler + B ADC_IRQHandler + + PUBWEAK CAN0_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_TX_IRQHandler + B CAN0_TX_IRQHandler + + PUBWEAK CAN0_RX0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_RX0_IRQHandler + B CAN0_RX0_IRQHandler + + PUBWEAK CAN0_RX1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_RX1_IRQHandler + B CAN0_RX1_IRQHandler + + PUBWEAK CAN0_EWMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN0_EWMC_IRQHandler + B CAN0_EWMC_IRQHandler + + PUBWEAK EXTI5_9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_9_IRQHandler + B EXTI5_9_IRQHandler + + PUBWEAK TIMER0_BRK_TIMER8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_BRK_TIMER8_IRQHandler + B TIMER0_BRK_TIMER8_IRQHandler + + PUBWEAK TIMER0_UP_TIMER9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_UP_TIMER9_IRQHandler + B TIMER0_UP_TIMER9_IRQHandler + + PUBWEAK TIMER0_TRG_CMT_TIMER10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_TRG_CMT_TIMER10_IRQHandler + B TIMER0_TRG_CMT_TIMER10_IRQHandler + + PUBWEAK TIMER0_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_CC_IRQHandler + B TIMER0_CC_IRQHandler + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER1_IRQHandler + B TIMER1_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER3_IRQHandler + B TIMER3_IRQHandler + + PUBWEAK I2C0_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_EV_IRQHandler + B I2C0_EV_IRQHandler + + PUBWEAK I2C0_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_ER_IRQHandler + B I2C0_ER_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK SPI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI0_IRQHandler + B SPI0_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK USART0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART0_IRQHandler + B USART0_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK EXTI10_15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_15_IRQHandler + B EXTI10_15_IRQHandler + + PUBWEAK RTC_Alarm_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_Alarm_IRQHandler + B RTC_Alarm_IRQHandler + + PUBWEAK USBFS_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBFS_WKUP_IRQHandler + B USBFS_WKUP_IRQHandler + + PUBWEAK TIMER7_BRK_TIMER11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_BRK_TIMER11_IRQHandler + B TIMER7_BRK_TIMER11_IRQHandler + + PUBWEAK TIMER7_UP_TIMER12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_UP_TIMER12_IRQHandler + B TIMER7_UP_TIMER12_IRQHandler + + PUBWEAK TIMER7_TRG_CMT_TIMER13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_TRG_CMT_TIMER13_IRQHandler + B TIMER7_TRG_CMT_TIMER13_IRQHandler + + PUBWEAK TIMER7_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER7_CC_IRQHandler + B TIMER7_CC_IRQHandler + + PUBWEAK DMA0_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA0_Channel7_IRQHandler + B DMA0_Channel7_IRQHandler + + PUBWEAK EXMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXMC_IRQHandler + B EXMC_IRQHandler + + PUBWEAK SDIO_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDIO_IRQHandler + B SDIO_IRQHandler + + PUBWEAK TIMER4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER4_IRQHandler + B TIMER4_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK UART3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART3_IRQHandler + B UART3_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK TIMER5_DAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER5_DAC_IRQHandler + B TIMER5_DAC_IRQHandler + + PUBWEAK TIMER6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER6_IRQHandler + B TIMER6_IRQHandler + + PUBWEAK DMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel0_IRQHandler + B DMA1_Channel0_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel2_IRQHandler + B DMA1_Channel2_IRQHandler + + PUBWEAK DMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel3_IRQHandler + B DMA1_Channel3_IRQHandler + + PUBWEAK DMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel4_IRQHandler + B DMA1_Channel4_IRQHandler + + PUBWEAK ENET_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET_IRQHandler + B ENET_IRQHandler + + PUBWEAK ENET_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ENET_WKUP_IRQHandler + B ENET_WKUP_IRQHandler + + PUBWEAK CAN1_TX_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_TX_IRQHandler + B CAN1_TX_IRQHandler + + PUBWEAK CAN1_RX0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_RX0_IRQHandler + B CAN1_RX0_IRQHandler + + PUBWEAK CAN1_RX1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_RX1_IRQHandler + B CAN1_RX1_IRQHandler + + PUBWEAK CAN1_EWMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CAN1_EWMC_IRQHandler + B CAN1_EWMC_IRQHandler + + PUBWEAK USBFS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBFS_IRQHandler + B USBFS_IRQHandler + + PUBWEAK DMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel5_IRQHandler + B DMA1_Channel5_IRQHandler + + PUBWEAK DMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel6_IRQHandler + B DMA1_Channel6_IRQHandler + + PUBWEAK DMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA1_Channel7_IRQHandler + B DMA1_Channel7_IRQHandler + + PUBWEAK USART5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART5_IRQHandler + B USART5_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK USBHS_EP1_Out_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_EP1_Out_IRQHandler + B USBHS_EP1_Out_IRQHandler + + PUBWEAK USBHS_EP1_In_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_EP1_In_IRQHandler + B USBHS_EP1_In_IRQHandler + + PUBWEAK USBHS_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_WKUP_IRQHandler + B USBHS_WKUP_IRQHandler + + PUBWEAK USBHS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USBHS_IRQHandler + B USBHS_IRQHandler + + PUBWEAK DCI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCI_IRQHandler + B DCI_IRQHandler + + PUBWEAK TRNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TRNG_IRQHandler + B TRNG_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK UART6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART6_IRQHandler + B UART6_IRQHandler + + PUBWEAK UART7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART7_IRQHandler + B UART7_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK SPI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI4_IRQHandler + B SPI4_IRQHandler + + PUBWEAK SPI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI5_IRQHandler + B SPI5_IRQHandler + + PUBWEAK TLI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TLI_IRQHandler + B TLI_IRQHandler + + PUBWEAK TLI_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TLI_ER_IRQHandler + B TLI_ER_IRQHandler + + PUBWEAK IPA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IPA_IRQHandler + B IPA_IRQHandler + END \ No newline at end of file diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c new file mode 100644 index 0000000000..2ea97ae3f8 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/system_gd32f4xx.c @@ -0,0 +1,916 @@ +/*! + \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 SEL_IRC16M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLLP 0x02U +#define RCU_MODIFY {volatile uint32_t i; \ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV2; \ + for(i=0;i<50000;i++);} + +/* 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); + +#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; + + RCU_MODIFY + + /* Reset CFG0 register */ + RCU_CFG0 = 0x00000000U; + + /* Reset HXTALEN, CKMEN and PLLEN bits */ + RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN); + + /* Reset PLLCFGR register */ + RCU_PLL = 0x24003010U; + + /* Reset HSEBYP bit */ + RCU_CTL &= ~(RCU_CTL_HXTALBPS); + + /* 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(); +#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)){ + } +} + +#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/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cm4.h b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cm4.h new file mode 100644 index 0000000000..e3cd89f728 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cm4.h @@ -0,0 +1,1790 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer 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 + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* 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/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cm4_simd.h b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cm4_simd.h new file mode 100644 index 0000000000..f9bceff1e5 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/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/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmFunc.h b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmFunc.h new file mode 100644 index 0000000000..834bd17645 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmFunc.h @@ -0,0 +1,664 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V4.10 + * @date 18. March 2015 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __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) || (__CORTEX_SC >= 300) + +/** \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 Set Base Priority with condition + + This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 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) || (__CORTEX_SC >= 300) */ + + +#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) + +/** \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) || (__CORTEX_M == 0x07) */ + + +#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" : : : "memory"); +} + + +/** \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" : : : "memory"); +} + + +/** \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) : "memory"); +} + + +/** \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) : "sp"); +} + + +/** \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) : "sp"); +} + + +/** \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) : "memory"); +} + + +#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" : : : "memory"); +} + + +/** \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" : : : "memory"); +} + + +/** \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" : "=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) : "memory"); +} + + +/** \brief Set Base Priority with condition + + This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); +} + + +/** \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) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) + +/** \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; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + 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) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ + + +#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 */ +/* + * 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. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + +#endif /* __CORE_CMFUNC_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmInstr.h b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmInstr.h new file mode 100644 index 0000000000..fca425c51d --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/CMSIS/core_cmInstr.h @@ -0,0 +1,916 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V4.10 + * @date 18. March 2015 + * + * @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. + ---------------------------------------------------------------------------*/ + + +#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() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0) + +/** \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() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0) + +/** \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() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0) + +/** \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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** \brief Reverse byte order 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 + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** \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 + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end + + result = value; // r will be reversed bits of v; first get LSB of v + for (value >>= 1; value; value >>= 1) + { + result <<= 1; + result |= value & 1; + s--; + } + result <<= s; // shift when v's highest bits are zero + return(result); +} +#endif + + +/** \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 + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief LDR Exclusive (8 bit) + + This function executes a exclusive LDR instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function executes a exclusive LDR instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function executes a exclusive LDR instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function executes a exclusive STR instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function executes a exclusive STR instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function executes a exclusive STR instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(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 Rotate Right with Extend (32 bit) + + This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** \brief LDRT Unprivileged (8 bit) + + This function executes a Unprivileged LDRT instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** \brief LDRT Unprivileged (16 bit) + + This function executes a Unprivileged LDRT instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** \brief LDRT Unprivileged (32 bit) + + This function executes a Unprivileged LDRT instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** \brief STRT Unprivileged (8 bit) + + This function executes a Unprivileged STRT instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** \brief STRT Unprivileged (16 bit) + + This function executes a Unprivileged STRT instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** \brief STRT Unprivileged (32 bit) + + This function executes a Unprivileged STRT instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constrant "l" + * Otherwise, use general registers, specified by constrant "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** \brief No Operation + + 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 0xF":::"memory"); +} + + +/** \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 0xF":::"memory"); +} + + +/** \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 0xF":::"memory"); +} + + +/** \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) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Reverse byte order (16 bit) + + 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" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (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) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + uint32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + 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) +{ + return (op1 >> op2) | (op1 << (32 - op2)); +} + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** \brief Reverse bit order of value + + 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; + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end + + result = value; // r will be reversed bits of v; first get LSB of v + for (value >>= 1; value; value >>= 1) + { + result <<= 1; + result |= value & 1; + s--; + } + result <<= s; // shift when v's highest bits are zero +#endif + return(result); +} + + +/** \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 __builtin_clz + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief LDR Exclusive (8 bit) + + This function executes a exclusive LDR instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (16 bit) + + This function executes a exclusive LDR instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (32 bit) + + This function executes a exclusive LDR instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function executes a exclusive STR instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__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), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function executes a exclusive STR instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__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), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function executes a exclusive STR instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__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), "=Q" (*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" ::: "memory"); +} + + +/** \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 Rotate Right with Extend (32 bit) + + This function moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief LDRT Unprivileged (8 bit) + + This function executes a Unprivileged LDRT instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDRT Unprivileged (16 bit) + + This function executes a Unprivileged LDRT instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDRT Unprivileged (32 bit) + + This function executes a Unprivileged LDRT instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STRT Unprivileged (8 bit) + + This function executes a Unprivileged STRT instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** \brief STRT Unprivileged (16 bit) + + This function executes a Unprivileged STRT instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** \brief STRT Unprivileged (32 bit) + + This function executes a Unprivileged STRT instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); +} + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#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 */ +/* + * 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. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h new file mode 100644 index 0000000000..4f6020a50a --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_adc.h @@ -0,0 +1,515 @@ +/*! + \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 +*/ + +/* + 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_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 regular sequence register 0 */ +#define ADC_RSQ1(adcx) REG32((adcx) + 0x30U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2(adcx) REG32((adcx) + 0x34U) /*!< ADC regular 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 regular 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 regular 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) /*!< regular channel start flag */ +#define ADC_STAT_ROVF BIT(5) /*!< regular 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 group conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< 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 regular 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 group */ +#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 regular group */ +#define ADC_CTL1_ETMRC BITS(28,29) /*!< external trigger conversion mode for regular channels */ +#define ADC_CTL1_SWRCST BIT(30) /*!< start conversion of regular 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 regular sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< x conversion in regular 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) /*!< regular 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) /*!< regular data1 in ADC synchronization mode */ +#define ADC_SYNCDATA_SYNCDATA1 BITS(16,31) /*!< regular 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 /*!< regular channel start flag */ +#define ADC_FLAG_ROVF ADC_STAT_ROVF /*!< regular 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 channel group 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_REGULAL_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(1) /*!< ADC0 and ADC1 work in combined regular parallel & inserted parallel mode. ADC2 works independently */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(2) /*!< ADC0 and ADC1 work in combined regular 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_REGULAL_PARALLEL SYNCCTL_SYNCM(6) /*!< ADC0 and ADC1 work in regular parallel mode. ADC2 works independently */ +#define ADC_DAUL_REGULAL_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_REGULAL_PARALLEL_INSERTED_PARALLEL SYNCCTL_SYNCM(17) /*!< all ADCs work in combined regular parallel & inserted parallel mode */ +#define ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION SYNCCTL_SYNCM(18) /*!< all ADCs work in combined regular parallel & trigger rotation mode */ +#define ADC_ALL_INSERTED_PARALLEL SYNCCTL_SYNCM(21) /*!< all ADCs work in inserted parallel mode */ +#define ADC_ALL_REGULAL_PARALLEL SYNCCTL_SYNCM(22) /*!< all ADCs work in regular parallel mode */ +#define ADC_ALL_REGULAL_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 regular and inserted channel */ +#define EXTERNAL_TRIGGER_DISABLE ((uint32_t)0x00000000U) /*!< external trigger disable */ +#define EXTERNAL_TRIGGER_RISING ((uint32_t)0x00000001U) /*!< rising edge of external trigger */ +#define EXTERNAL_TRIGGER_FALLING ((uint32_t)0x00000002U) /*!< falling edge of external trigger */ +#define EXTERNAL_TRIGGER_RISING_FALLING ((uint32_t)0x00000003U) /*!< rising and falling edge of external trigger */ + +/* ADC external trigger select for regular channel */ +#define CTL1_ETSRC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) +#define ADC_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< timer 0 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< timer 0 CC1 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< timer 0 CC2 event select */ +#define ADC_EXTTRIG_REGULAR_T1_CH1 CTL1_ETSRC(3) /*!< timer 1 CC1 event select */ +#define ADC_EXTTRIG_REGULAR_T1_CH2 CTL1_ETSRC(4) /*!< timer 1 CC2 event select */ +#define ADC_EXTTRIG_REGULAR_T1_CH3 CTL1_ETSRC(5) /*!< timer 1 CC3 event select */ +#define ADC_EXTTRIG_REGULAR_T1_TRGO CTL1_ETSRC(6) /*!< timer 1 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_T2_CH0 CTL1_ETSRC(7) /*!< timer 2 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(8) /*!< timer 2 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_T3_CH3 CTL1_ETSRC(9) /*!< timer 3 CC3 event select */ +#define ADC_EXTTRIG_REGULAR_T4_CH0 CTL1_ETSRC(10) /*!< timer 4 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T4_CH1 CTL1_ETSRC(11) /*!< timer 4 CC1 event select */ +#define ADC_EXTTRIG_REGULAR_T4_CH2 CTL1_ETSRC(12) /*!< timer 4 CC2 event select */ +#define ADC_EXTTRIG_REGULAR_T7_CH0 CTL1_ETSRC(13) /*!< timer 7 CC0 event select */ +#define ADC_EXTTRIG_REGULAR_T7_TRGO CTL1_ETSRC(14) /*!< timer 7 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_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 group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< adc regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< adc inserted channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< adc inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< adc inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< adc inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< adc inserted channel 3 */ + +/* ADC channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ +#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ +#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ +#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ +#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ +#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ +#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ +#define ADC_CHANNEL_18 ((uint8_t)0x12U) /*!< ADC channel 18 */ + +/* ADC interrupt flag */ +#define ADC_INT_WDE ADC_CTL0_WDEIE /*!< analog watchdog event interrupt */ +#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< end of group conversion interrupt */ +#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< end of inserted group conversion interrupt */ +#define ADC_INT_ROVF ADC_CTL0_ROVFIE /*!< regular 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 group conversion interrupt */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */ +#define ADC_INT_FLAG_ROVF ADC_STAT_ROVF /*!< regular 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 regular conversions, the EOC bit is set */ +#define ADC_EOC_SET_CONVERSION ((uint8_t)0x01U) /*!< at the end of each regular 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 regular conversion */ +void adc_dma_request_after_last_enable(uint32_t adc_periph); +/* the DMA engine is disabled after the end of transfer signal from DMA controller is detected */ +void adc_dma_request_after_last_disable(uint32_t adc_periph); + +/* regular group and inserted group config */ +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length); +/* configure the length of regular channel group or inserted channel group */ +void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length); +/* configure ADC regular channel */ +void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); +/* configure ADC inserted channel */ +void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); +/* configure ADC inserted channel offset */ +void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset); +/* configure ADC external trigger source */ +void adc_external_trigger_source_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t external_trigger_source); +/* enable ADC external trigger */ +void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group); +/* configure end of conversion mode */ +void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection); + +/* get channel data */ +/* read ADC regular group data register */ +uint16_t adc_regular_data_read(uint32_t adc_periph); +/* read ADC inserted group 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 group channel */ +void adc_watchdog_group_channel_enable(uint32_t adc_periph , uint8_t adc_channel_group); +/* disable ADC analog watchdog */ +void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group); +/* 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_regular_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 regular data register */ +uint32_t adc_sync_regular_data_read(void); + +#endif /* GD32F4XX_ADC_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h new file mode 100644 index 0000000000..7310f63a75 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_can.h @@ -0,0 +1,753 @@ +/*! + \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 +*/ + +/* + 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_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) + 0x00U) /*!< CAN control register */ +#define CAN_STAT(canx) REG32((canx) + 0x04U) /*!< CAN status register */ +#define CAN_TSTAT(canx) REG32((canx) + 0x08U) /*!< CAN transmit status register*/ +#define CAN_RFIFO0(canx) REG32((canx) + 0x0CU) /*!< CAN receive FIFO0 register */ +#define CAN_RFIFO1(canx) REG32((canx) + 0x10U) /*!< CAN receive FIFO1 register */ +#define CAN_INTEN(canx) REG32((canx) + 0x14U) /*!< CAN interrupt enable register */ +#define CAN_ERR(canx) REG32((canx) + 0x18U) /*!< CAN error register */ +#define CAN_BT(canx) REG32((canx) + 0x1CU) /*!< CAN bit timing register */ +#define CAN_TMI0(canx) REG32((canx) + 0x180U) /*!< CAN transmit mailbox0 identifier register */ +#define CAN_TMP0(canx) REG32((canx) + 0x184U) /*!< CAN transmit mailbox0 property register */ +#define CAN_TMDATA00(canx) REG32((canx) + 0x188U) /*!< CAN transmit mailbox0 data0 register */ +#define CAN_TMDATA10(canx) REG32((canx) + 0x18CU) /*!< CAN transmit mailbox0 data1 register */ +#define CAN_TMI1(canx) REG32((canx) + 0x190U) /*!< CAN transmit mailbox1 identifier register */ +#define CAN_TMP1(canx) REG32((canx) + 0x194U) /*!< CAN transmit mailbox1 property register */ +#define CAN_TMDATA01(canx) REG32((canx) + 0x198U) /*!< CAN transmit mailbox1 data0 register */ +#define CAN_TMDATA11(canx) REG32((canx) + 0x19CU) /*!< CAN transmit mailbox1 data1 register */ +#define CAN_TMI2(canx) REG32((canx) + 0x1A0U) /*!< CAN transmit mailbox2 identifier register */ +#define CAN_TMP2(canx) REG32((canx) + 0x1A4U) /*!< CAN transmit mailbox2 property register */ +#define CAN_TMDATA02(canx) REG32((canx) + 0x1A8U) /*!< CAN transmit mailbox2 data0 register */ +#define CAN_TMDATA12(canx) REG32((canx) + 0x1ACU) /*!< CAN transmit mailbox2 data1 register */ +#define CAN_RFIFOMI0(canx) REG32((canx) + 0x1B0U) /*!< CAN receive FIFO0 mailbox identifier register */ +#define CAN_RFIFOMP0(canx) REG32((canx) + 0x1B4U) /*!< CAN receive FIFO0 mailbox property register */ +#define CAN_RFIFOMDATA00(canx) REG32((canx) + 0x1B8U) /*!< CAN receive FIFO0 mailbox data0 register */ +#define CAN_RFIFOMDATA10(canx) REG32((canx) + 0x1BCU) /*!< CAN receive FIFO0 mailbox data1 register */ +#define CAN_RFIFOMI1(canx) REG32((canx) + 0x1C0U) /*!< CAN receive FIFO1 mailbox identifier register */ +#define CAN_RFIFOMP1(canx) REG32((canx) + 0x1C4U) /*!< CAN receive FIFO1 mailbox property register */ +#define CAN_RFIFOMDATA01(canx) REG32((canx) + 0x1C8U) /*!< CAN receive FIFO1 mailbox data0 register */ +#define CAN_RFIFOMDATA11(canx) REG32((canx) + 0x1CCU) /*!< CAN receive FIFO1 mailbox data1 register */ +#define CAN_FCTL(canx) REG32((canx) + 0x200U) /*!< CAN filter control register */ +#define CAN_FMCFG(canx) REG32((canx) + 0x204U) /*!< CAN filter mode register */ +#define CAN_FSCFG(canx) REG32((canx) + 0x20CU) /*!< CAN filter scale register */ +#define CAN_FAFIFO(canx) REG32((canx) + 0x214U) /*!< CAN filter associated FIFO register */ +#define CAN_FW(canx) REG32((canx) + 0x21CU) /*!< CAN filter working register */ +#define CAN_F0DATA0(canx) REG32((canx) + 0x240U) /*!< CAN filter 0 data 0 register */ +#define CAN_F1DATA0(canx) REG32((canx) + 0x248U) /*!< CAN filter 1 data 0 register */ +#define CAN_F2DATA0(canx) REG32((canx) + 0x250U) /*!< CAN filter 2 data 0 register */ +#define CAN_F3DATA0(canx) REG32((canx) + 0x258U) /*!< CAN filter 3 data 0 register */ +#define CAN_F4DATA0(canx) REG32((canx) + 0x260U) /*!< CAN filter 4 data 0 register */ +#define CAN_F5DATA0(canx) REG32((canx) + 0x268U) /*!< CAN filter 5 data 0 register */ +#define CAN_F6DATA0(canx) REG32((canx) + 0x270U) /*!< CAN filter 6 data 0 register */ +#define CAN_F7DATA0(canx) REG32((canx) + 0x278U) /*!< CAN filter 7 data 0 register */ +#define CAN_F8DATA0(canx) REG32((canx) + 0x280U) /*!< CAN filter 8 data 0 register */ +#define CAN_F9DATA0(canx) REG32((canx) + 0x288U) /*!< CAN filter 9 data 0 register */ +#define CAN_F10DATA0(canx) REG32((canx) + 0x290U) /*!< CAN filter 10 data 0 register */ +#define CAN_F11DATA0(canx) REG32((canx) + 0x298U) /*!< CAN filter 11 data 0 register */ +#define CAN_F12DATA0(canx) REG32((canx) + 0x2A0U) /*!< CAN filter 12 data 0 register */ +#define CAN_F13DATA0(canx) REG32((canx) + 0x2A8U) /*!< CAN filter 13 data 0 register */ +#define CAN_F14DATA0(canx) REG32((canx) + 0x2B0U) /*!< CAN filter 14 data 0 register */ +#define CAN_F15DATA0(canx) REG32((canx) + 0x2B8U) /*!< CAN filter 15 data 0 register */ +#define CAN_F16DATA0(canx) REG32((canx) + 0x2C0U) /*!< CAN filter 16 data 0 register */ +#define CAN_F17DATA0(canx) REG32((canx) + 0x2C8U) /*!< CAN filter 17 data 0 register */ +#define CAN_F18DATA0(canx) REG32((canx) + 0x2D0U) /*!< CAN filter 18 data 0 register */ +#define CAN_F19DATA0(canx) REG32((canx) + 0x2D8U) /*!< CAN filter 19 data 0 register */ +#define CAN_F20DATA0(canx) REG32((canx) + 0x2E0U) /*!< CAN filter 20 data 0 register */ +#define CAN_F21DATA0(canx) REG32((canx) + 0x2E8U) /*!< CAN filter 21 data 0 register */ +#define CAN_F22DATA0(canx) REG32((canx) + 0x2F0U) /*!< CAN filter 22 data 0 register */ +#define CAN_F23DATA0(canx) REG32((canx) + 0x3F8U) /*!< CAN filter 23 data 0 register */ +#define CAN_F24DATA0(canx) REG32((canx) + 0x300U) /*!< CAN filter 24 data 0 register */ +#define CAN_F25DATA0(canx) REG32((canx) + 0x308U) /*!< CAN filter 25 data 0 register */ +#define CAN_F26DATA0(canx) REG32((canx) + 0x310U) /*!< CAN filter 26 data 0 register */ +#define CAN_F27DATA0(canx) REG32((canx) + 0x318U) /*!< CAN filter 27 data 0 register */ +#define CAN_F0DATA1(canx) REG32((canx) + 0x244U) /*!< CAN filter 0 data 1 register */ +#define CAN_F1DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 1 data 1 register */ +#define CAN_F2DATA1(canx) REG32((canx) + 0x254U) /*!< CAN filter 2 data 1 register */ +#define CAN_F3DATA1(canx) REG32((canx) + 0x25CU) /*!< CAN filter 3 data 1 register */ +#define CAN_F4DATA1(canx) REG32((canx) + 0x264U) /*!< CAN filter 4 data 1 register */ +#define CAN_F5DATA1(canx) REG32((canx) + 0x26CU) /*!< CAN filter 5 data 1 register */ +#define CAN_F6DATA1(canx) REG32((canx) + 0x274U) /*!< CAN filter 6 data 1 register */ +#define CAN_F7DATA1(canx) REG32((canx) + 0x27CU) /*!< CAN filter 7 data 1 register */ +#define CAN_F8DATA1(canx) REG32((canx) + 0x284U) /*!< CAN filter 8 data 1 register */ +#define CAN_F9DATA1(canx) REG32((canx) + 0x28CU) /*!< CAN filter 9 data 1 register */ +#define CAN_F10DATA1(canx) REG32((canx) + 0x294U) /*!< CAN filter 10 data 1 register */ +#define CAN_F11DATA1(canx) REG32((canx) + 0x29CU) /*!< CAN filter 11 data 1 register */ +#define CAN_F12DATA1(canx) REG32((canx) + 0x2A4U) /*!< CAN filter 12 data 1 register */ +#define CAN_F13DATA1(canx) REG32((canx) + 0x2ACU) /*!< CAN filter 13 data 1 register */ +#define CAN_F14DATA1(canx) REG32((canx) + 0x2B4U) /*!< CAN filter 14 data 1 register */ +#define CAN_F15DATA1(canx) REG32((canx) + 0x2BCU) /*!< CAN filter 15 data 1 register */ +#define CAN_F16DATA1(canx) REG32((canx) + 0x2C4U) /*!< CAN filter 16 data 1 register */ +#define CAN_F17DATA1(canx) REG32((canx) + 0x24CU) /*!< CAN filter 17 data 1 register */ +#define CAN_F18DATA1(canx) REG32((canx) + 0x2D4U) /*!< CAN filter 18 data 1 register */ +#define CAN_F19DATA1(canx) REG32((canx) + 0x2DCU) /*!< CAN filter 19 data 1 register */ +#define CAN_F20DATA1(canx) REG32((canx) + 0x2E4U) /*!< CAN filter 20 data 1 register */ +#define CAN_F21DATA1(canx) REG32((canx) + 0x2ECU) /*!< CAN filter 21 data 1 register */ +#define CAN_F22DATA1(canx) REG32((canx) + 0x2F4U) /*!< CAN filter 22 data 1 register */ +#define CAN_F23DATA1(canx) REG32((canx) + 0x2FCU) /*!< CAN filter 23 data 1 register */ +#define CAN_F24DATA1(canx) REG32((canx) + 0x304U) /*!< CAN filter 24 data 1 register */ +#define CAN_F25DATA1(canx) REG32((canx) + 0x30CU) /*!< CAN filter 25 data 1 register */ +#define CAN_F26DATA1(canx) REG32((canx) + 0x314U) /*!< CAN filter 26 data 1 register */ +#define CAN_F27DATA1(canx) REG32((canx) + 0x31CU) /*!< 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 */ + +/* consts 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 FIFO0 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 struct */ +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 no_auto_retrans; /*!< automatic retransmission mode disable */ + 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 struct */ +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 struct */ +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 struct */ +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 standrad 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 */ +/* deinitialize CAN */ +void can_deinit(uint32_t can_periph); +/* initialize CAN struct */ +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 init */ +void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init); +/* set can1 fliter 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 */ +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); + +/* 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 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 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h new file mode 100644 index 0000000000..01f2c6bc3f --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_crc.h @@ -0,0 +1,80 @@ +/*! + \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 +*/ + +/* + 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_CRC_H +#define GD32F4XX_CRC_H + +#include "gd32f4xx.h" + +/* CRC definitions */ +#define CRC CRC_BASE + +/* registers definitions */ +#define CRC_DATA REG32(CRC + 0x00U) /*!< CRC data register */ +#define CRC_FDATA REG32(CRC + 0x04U) /*!< CRC free data register */ +#define CRC_CTL REG32(CRC + 0x08U) /*!< 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h new file mode 100644 index 0000000000..00e4e7f298 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ctc.h @@ -0,0 +1,192 @@ +/*! + \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 +*/ + +/* + 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_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_USBSOFSEL BIT(30) /*!< USBFS or USBHS SOF signal 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*/ + +/* USBFS or USBHS SOF signal selection definitions */ +#define CTC_USBSOFSEL_USBHS CTC_CTL1_USBSOFSEL /*!< USBHS SOF signal is selected*/ +#define CTC_USBSOFSEL_USBFS ((uint32_t)0x00000000U) /*!< USBFS SOF signal is selected*/ + +/* 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 */ +#define CTC_REFSOURCE_USBSOF CTL1_REFSEL(2) /*!< USBSOF is selected */ + +/* reference signal source prescaler definitions */ +#define CTL1_REFPSC(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define CTC_REFSOURCE_PSC_OFF CTL1_REFPSC(0) /*!< reference signal not divided */ +#define CTC_REFSOURCE_PSC_DIV2 CTL1_REFPSC(1) /*!< reference signal divided by 2 */ +#define CTC_REFSOURCE_PSC_DIV4 CTL1_REFPSC(2) /*!< reference signal divided by 4 */ +#define CTC_REFSOURCE_PSC_DIV8 CTL1_REFPSC(3) /*!< reference signal divided by 8 */ +#define CTC_REFSOURCE_PSC_DIV16 CTL1_REFPSC(4) /*!< reference signal divided by 16 */ +#define CTC_REFSOURCE_PSC_DIV32 CTL1_REFPSC(5) /*!< reference signal divided by 32 */ +#define CTC_REFSOURCE_PSC_DIV64 CTL1_REFPSC(6) /*!< reference signal divided by 64 */ +#define CTC_REFSOURCE_PSC_DIV128 CTL1_REFPSC(7) /*!< reference signal divided by 128 */ + +/* CTC interrupt enable definitions */ +#define CTC_INT_CKOK CTC_CTL0_CKOKIE /*!< clock trim OK interrupt enable */ +#define CTC_INT_CKWARN CTC_CTL0_CKWARNIE /*!< clock trim warning interrupt enable */ +#define CTC_INT_ERR CTC_CTL0_ERRIE /*!< error interrupt enable */ +#define CTC_INT_EREF CTC_CTL0_EREFIE /*!< expect reference interrupt enable */ + +/* CTC interrupt source definitions */ +#define CTC_INT_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK interrupt flag */ +#define CTC_INT_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning interrupt flag */ +#define CTC_INT_FLAG_ERR CTC_STAT_ERRIF /*!< error interrupt flag */ +#define CTC_INT_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference interrupt flag */ +#define CTC_INT_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */ +#define CTC_INT_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */ +#define CTC_INT_FLAG_TRIMERR CTC_STAT_TRIMERR /*!< trim value error */ + +/* CTC flag definitions */ +#define CTC_FLAG_CKOK CTC_STAT_CKOKIF /*!< clock trim OK flag */ +#define CTC_FLAG_CKWARN CTC_STAT_CKWARNIF /*!< clock trim warning flag */ +#define CTC_FLAG_ERR CTC_STAT_ERRIF /*!< error flag */ +#define CTC_FLAG_EREF CTC_STAT_EREFIF /*!< expect reference flag */ +#define CTC_FLAG_CKERR CTC_STAT_CKERR /*!< clock trim error bit */ +#define CTC_FLAG_REFMISS CTC_STAT_REFMISS /*!< reference sync pulse miss */ +#define CTC_FLAG_TRIMERR CTC_STAT_TRIMERR /*!< trim value error bit */ + +/* function declarations */ +/* reset ctc clock trim controller */ +void ctc_deinit(void); +/* enable CTC trim counter */ +void ctc_counter_enable(void); +/* disable CTC trim counter */ +void ctc_counter_disable(void); + +/* configure the IRC48M trim value */ +void ctc_irc48m_trim_value_config(uint8_t trim_value); +/* generate software reference source sync pulse */ +void ctc_software_refsource_pulse_generate(void); +/* configure hardware automatically trim mode */ +void ctc_hardware_trim_mode_config(uint32_t hardmode); + +/* configure reference signal source polarity */ +void ctc_refsource_polarity_config(uint32_t polarity); +/* select USBFS or USBHS SOF signal */ +void ctc_usbsof_signal_select(uint32_t usbsof); +/* 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h new file mode 100644 index 0000000000..573fb31336 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dac.h @@ -0,0 +1,270 @@ +/*! + \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 +*/ + +/* + 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_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 */ +/* 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 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); +/* 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h new file mode 100644 index 0000000000..fde91597f7 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dbg.h @@ -0,0 +1,161 @@ +/*! + \file gd32f4xx_dbg.h + \brief definitions for the DBG + + \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_DBG_H +#define GD32F4XX_DBG_H + +#include "gd32f4xx.h" + +/* DBG definitions */ +#define DBG DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x04U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x08U) /*!< DBG control register 1 */ +#define DBG_CTL2 REG32(DBG + 0x0CU) /*!< DBG control register 2 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL0 */ +#define DBG_CTL0_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL0_TRACE_IOEN BIT(5) /*!< enable trace pin assignment */ +#define DBG_CTL0_TRACE_MODE BITS(6,7) /*!< trace pin mode selection */ + +/* 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 + ((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; + +#define CTL0_TRACE_MODE(regval) (BITS(6,7)&((uint32_t)(regval)<<6)) +#define TRACE_MODE_ASYNC CTL0_TRACE_MODE(0) /*!< trace pin used for async mode */ +#define TRACE_MODE_SYNC_DATASIZE_1 CTL0_TRACE_MODE(1) /*!< trace pin used for sync mode and data size is 1 */ +#define TRACE_MODE_SYNC_DATASIZE_2 CTL0_TRACE_MODE(2) /*!< trace pin used for sync mode and data size is 2 */ +#define TRACE_MODE_SYNC_DATASIZE_4 CTL0_TRACE_MODE(3) /*!< trace pin used for sync mode and data size is 4 */ + +/* function declarations */ +/* deinitialize the DBG */ +void dbg_deinit(void); +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/* enable low power behavior when the MCU is in debug mode */ +void dbg_low_power_enable(uint32_t dbg_low_power); +/* disable low power behavior when the MCU is in debug mode */ +void dbg_low_power_disable(uint32_t dbg_low_power); + +/* enable 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); +/* set trace pin mode */ +void dbg_trace_pin_mode_set(uint32_t trace_mode); + +#endif /* GD32F4XX_DBG_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h new file mode 100644 index 0000000000..4986d5afd4 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dci.h @@ -0,0 +1,238 @@ +/*! + \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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h new file mode 100644 index 0000000000..cac70b85eb --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_dma.h @@ -0,0 +1,428 @@ +/*! + \file gd32f4xx_dma.c + \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 +*/ + +/* + 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_DMA_H +#define GD32F4XX_DMA_H + +#include "gd32f4xx.h" + +/* DMA definitions */ +#define DMA0 (DMA_BASE) /*!< DMA0 base address */ +#define DMA1 (DMA_BASE + 0x0400U) /*!< DMA1 base address */ + +/* registers definitions */ +#define DMA_INTF0(dmax) REG32((dmax) + 0x00U) /*!< DMA interrupt flag register 0 */ +#define DMA_INTF1(dmax) REG32((dmax) + 0x04U) /*!< DMA interrupt flag register 1 */ +#define DMA_INTC0(dmax) REG32((dmax) + 0x08U) /*!< DMA interrupt flag clear register 0 */ +#define DMA_INTC1(dmax) REG32((dmax) + 0x0CU) /*!< DMA interrupt flag clear register 1 */ + +#define DMA_CH0CTL(dmax) REG32((dmax) + 0x10U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT(dmax) REG32((dmax) + 0x14U) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x18U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0M0ADDR(dmax) REG32((dmax) + 0x1CU) /*!< DMA channel 0 memory 0 base address register */ +#define DMA_CH0M1ADDR(dmax) REG32((dmax) + 0x20U) /*!< DMA channel 0 memory 1 base address register */ +#define DMA_CH0FCTL(dmax) REG32((dmax) + 0x24U) /*!< DMA channel 0 FIFO control register */ + +#define DMA_CH1CTL(dmax) REG32((dmax) + 0x28U) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT(dmax) REG32((dmax) + 0x2CU) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x30U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1M0ADDR(dmax) REG32((dmax) + 0x34U) /*!< DMA channel 1 memory 0 base address register */ +#define DMA_CH1M1ADDR(dmax) REG32((dmax) + 0x38U) /*!< DMA channel 1 memory 1 base address register */ +#define DMA_CH1FCTL(dmax) REG32((dmax) + 0x3CU) /*!< DMA channel 1 FIFO control register */ + +#define DMA_CH2CTL(dmax) REG32((dmax) + 0x40U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT(dmax) REG32((dmax) + 0x44U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x48U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2M0ADDR(dmax) REG32((dmax) + 0x4CU) /*!< DMA channel 2 memory 0 base address register */ +#define DMA_CH2M1ADDR(dmax) REG32((dmax) + 0x50U) /*!< DMA channel 2 memory 1 base address register */ +#define DMA_CH2FCTL(dmax) REG32((dmax) + 0x54U) /*!< DMA channel 2 FIFO control register */ + +#define DMA_CH3CTL(dmax) REG32((dmax) + 0x58U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT(dmax) REG32((dmax) + 0x5CU) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x60U) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3M0ADDR(dmax) REG32((dmax) + 0x64U) /*!< DMA channel 3 memory 0 base address register */ +#define DMA_CH3M1ADDR(dmax) REG32((dmax) + 0x68U) /*!< DMA channel 3 memory 1 base address register */ +#define DMA_CH3FCTL(dmax) REG32((dmax) + 0x6CU) /*!< DMA channel 3 FIFO control register */ + +#define DMA_CH4CTL(dmax) REG32((dmax) + 0x70U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT(dmax) REG32((dmax) + 0x74U) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x78U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4M0ADDR(dmax) REG32((dmax) + 0x7CU) /*!< DMA channel 4 memory 0 base address register */ +#define DMA_CH4M1ADDR(dmax) REG32((dmax) + 0x80U) /*!< DMA channel 4 memory 1 base address register */ +#define DMA_CH4FCTL(dmax) REG32((dmax) + 0x84U) /*!< DMA channel 4 FIFO control register */ + +#define DMA_CH5CTL(dmax) REG32((dmax) + 0x88U) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT(dmax) REG32((dmax) + 0x8CU) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x90U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5M0ADDR(dmax) REG32((dmax) + 0x94U) /*!< DMA channel 5 memory 0 base address register */ +#define DMA_CH5M1ADDR(dmax) REG32((dmax) + 0x98U) /*!< DMA channel 5 memory 1 base address register */ +#define DMA_CH5FCTL(dmax) REG32((dmax) + 0x9CU) /*!< DMA channel 5 FIFO control register */ + +#define DMA_CH6CTL(dmax) REG32((dmax) + 0xA0U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT(dmax) REG32((dmax) + 0xA4U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR(dmax) REG32((dmax) + 0xA8U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6M0ADDR(dmax) REG32((dmax) + 0xACU) /*!< DMA channel 6 memory 0 base address register */ +#define DMA_CH6M1ADDR(dmax) REG32((dmax) + 0xB0U) /*!< DMA channel 6 memory 1 base address register */ +#define DMA_CH6FCTL(dmax) REG32((dmax) + 0xB4U) /*!< DMA channel 6 FIFO control register */ + +#define DMA_CH7CTL(dmax) REG32((dmax) + 0xB8U) /*!< DMA channel 7 control register */ +#define DMA_CH7CNT(dmax) REG32((dmax) + 0xBCU) /*!< DMA channel 7 counter register */ +#define DMA_CH7PADDR(dmax) REG32((dmax) + 0xC0U) /*!< DMA channel 7 peripheral base address register */ +#define DMA_CH7M0ADDR(dmax) REG32((dmax) + 0xC4U) /*!< DMA channel 7 memory 0 base address register */ +#define DMA_CH7M1ADDR(dmax) REG32((dmax) + 0xC8U) /*!< DMA channel 7 memory 1 base address register */ +#define DMA_CH7FCTL(dmax) REG32((dmax) + 0xCCU) /*!< 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); +/* 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); +/* 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); + +#endif /* GD32F4XX_DMA_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h new file mode 100644 index 0000000000..1dfc880d37 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_enet.h @@ -0,0 +1,1680 @@ +/*! + \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 +*/ + +/* + 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_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 MII 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-200 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h new file mode 100644 index 0000000000..94baf2f6f3 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exmc.h @@ -0,0 +1,809 @@ +/*! + \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 +*/ + +/* + 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_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_WREN 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_ASYNCWAIT BIT(15) /*!< asynchronous wait enable */ +#define EXMC_SNCTL_CPS BITS(16,18) /*!< CRAM page size */ +#define EXMC_SNCTL_SYNCWR BIT(19) /*!< synchronous write config */ +#define EXMC_SNCTL_CCK BIT(20) /*!< consecutive clock config */ + +/* 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) /*!< interrupt refresh error 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 struct */ +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 struct */ +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 struct */ +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 struct */ +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 struct */ +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 brust_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 struct */ +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 struct */ +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_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 select */ +#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 select */ +#define EXMC_SDRAM_DEVICE0_UNSELECT ((uint32_t)0x00000000U) /*!< SDRAM device0 unselect */ +#define EXMC_SDRAM_DEVICE0_SELECT EXMC_SDCMD_DS0 /*!< SDRAM device0 select */ + +/* SDRAM device1 select */ +#define EXMC_SDRAM_DEVICE1_UNSELECT ((uint32_t)0x00000000U) /*!< SDRAM device1 unselect */ +#define EXMC_SDRAM_DEVICE1_SELECT EXMC_SDCMD_DS1 /*!< SDRAM device1 select */ + +/* SDRAM device status */ +#define EXMC_SDRAM_DEVICE_NORMAL ((uint32_t)0x00000000U) /*!< normal status */ +#define EXMC_SDRAM_DEVICE_SELF_REFRESH ((uint32_t)0x00000001U) /*!< self refresh status */ +#define EXMC_SDRAM_DEVICE_POWER_DOWN ((uint32_t)0x00000002U) /*!< power down status */ + +/* sample cycle of read data */ +#define EXMC_SDRAM_READSAMPLE_0_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_norsram_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); +/* 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); +/* config 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h new file mode 100644 index 0000000000..3c2a27149d --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_exti.h @@ -0,0 +1,277 @@ +/*! + \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.1, 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_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/event pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt/event pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt/event pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt/event pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt/event pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt/event pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt/event pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt/event pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt/event pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt/event pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt/event pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt/event pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt/event pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt/event pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt/event pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt/event pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt/event pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt/event pending status from line 17 */ +#define EXTI_PD_PD18 BIT(18) /*!< interrupt/event pending status from line 18 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt/event pending status from line 19 */ +#define EXTI_PD_PD20 BIT(20) /*!< interrupt/event pending status from line 20 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt/event pending status from line 21 */ +#define EXTI_PD_PD22 BIT(22) /*!< interrupt/event 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); +/* enable the configuration of EXTI initialize */ +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); +/* EXTI software interrupt event enable */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* EXTI software interrupt event disable */ +void exti_software_interrupt_disable(exti_line_enum linex); + +/* interrupt & flag functions */ +/* get EXTI lines pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI lines flag when the interrupt flag is set */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); + +#endif /* GD32F4XX_EXTI_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h new file mode 100644 index 0000000000..9b1b82c083 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fmc.h @@ -0,0 +1,383 @@ +/*! + \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 +*/ + +/* + 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_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) + 0x0000U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x0004U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x0008U) /*!< FMC option byte unlock key register */ +#define FMC_STAT REG32((FMC) + 0x000CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x0010U) /*!< FMC control register */ +#define FMC_OBCTL0 REG32((FMC) + 0x0014U) /*!< FMC option byte control register 0 */ +#define FMC_OBCTL1 REG32((FMC) + 0x0018U) /*!< FMC option byte control register 1 */ +#define FMC_WSEN REG32((FMC) + 0x00FCU) /*!< FMC wait state enable register */ +#define FMC_PID REG32((FMC) + 0x0100U) /*!< 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_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, /*!< 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_PGERR, /*!< program 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 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 */ + +/* double banks or single bank selection when flash size is 1M bytes */ +#define OBCTL0_DBS(regval) (BIT(30) & ((uint32_t)(regval)<<30)) +#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)<<31)) +#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))<< 8) +#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 ((uint32_t)0x00000001U) /*!< FMC end of operation flag bit */ +#define FMC_FLAG_OPERR ((uint32_t)0x00000002U) /*!< FMC operation error flag bit */ +#define FMC_FLAG_WPERR ((uint32_t)0x00000010U) /*!< FMC erase/program protection error flag bit */ +#define FMC_FLAG_PGMERR ((uint32_t)0x00000040U) /*!< FMC program size not match error flag bit */ +#define FMC_FLAG_PGSERR ((uint32_t)0x00000080U) /*!< FMC program sequence error flag bit */ +#define FMC_FLAG_RDDERR ((uint32_t)0x00000100U) /*!< FMC read D-bus protection error flag bit */ +#define FMC_FLAG_BUSY ((uint32_t)0x00010000U) /*!< FMC busy flag */ + +/* 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); +/* 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 */ +void ob_write_protection_enable(uint32_t ob_wp); +/* disable write protect */ +void 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(uint32_t ob_drp); +/* set the option byte security protection level */ +void ob_security_protection_config(uint8_t ob_spc); +/* write the FMC option byte user */ +void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby); +/* 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 option byte user */ +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 threshold value */ +uint8_t ob_user_bor_threshold_get(void); + +/* FMC interrupts and flags management functions */ +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t fmc_int); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t fmc_int); +/* 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); +/* return the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check FMC ready or not */ +fmc_state_enum fmc_ready_wait(void); + +#endif /* GD32F4XX_FMC_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h new file mode 100644 index 0000000000..ebee04b637 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_fwdgt.h @@ -0,0 +1,106 @@ +/*! + \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 +*/ + +/* + 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_FWDGT_H +#define GD32F4XX_FWDGT_H + +#include "gd32f4xx.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* 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 */ + +/* 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); + +/* 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h new file mode 100644 index 0000000000..81da899427 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_gpio.h @@ -0,0 +1,408 @@ +/*! + \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 +*/ + +/* + 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_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 operation 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 bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4,7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8,11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12,15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16,19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20,23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24,27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28,31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0,3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4,7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8,11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12,15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16,19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20,23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24,27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28,31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +/* GPIO_TG */ +#define GPIO_TG_TG0 BIT(0) /*!< pin 0 toggle bit */ +#define GPIO_TG_TG1 BIT(1) /*!< pin 1 toggle bit */ +#define GPIO_TG_TG2 BIT(2) /*!< pin 2 toggle bit */ +#define GPIO_TG_TG3 BIT(3) /*!< pin 3 toggle bit */ +#define GPIO_TG_TG4 BIT(4) /*!< pin 4 toggle bit */ +#define GPIO_TG_TG5 BIT(5) /*!< pin 5 toggle bit */ +#define GPIO_TG_TG6 BIT(6) /*!< pin 6 toggle bit */ +#define GPIO_TG_TG7 BIT(7) /*!< pin 7 toggle bit */ +#define GPIO_TG_TG8 BIT(8) /*!< pin 8 toggle bit */ +#define GPIO_TG_TG9 BIT(9) /*!< pin 9 toggle bit */ +#define GPIO_TG_TG10 BIT(10) /*!< pin 10 toggle bit */ +#define GPIO_TG_TG11 BIT(11) /*!< pin 11 toggle bit */ +#define GPIO_TG_TG12 BIT(12) /*!< pin 12 toggle bit */ +#define GPIO_TG_TG13 BIT(13) /*!< pin 13 toggle bit */ +#define GPIO_TG_TG14 BIT(14) /*!< pin 14 toggle bit */ +#define GPIO_TG_TG15 BIT(15) /*!< pin 15 toggle bit */ + +/* 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_200MHZ GPIO_OSPEED_LEVEL3 /*!< output max speed 200MHz */ + +/* 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h new file mode 100644 index 0000000000..121e42f497 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_i2c.h @@ -0,0 +1,422 @@ +/*! + \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 +*/ + +/* + 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_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+0x400U) /*!< I2C1 base address */ +#define I2C2 (I2C_BASE+0x800U) /*!< I2C2 base address */ + +/* registers definitions */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x04U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x08U) /*!< I2C slave address register 0 */ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0CU) /*!< I2C slave address register 1 */ +#define I2C_DATA(i2cx) REG32((i2cx) + 0x10U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x14U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */ +#define I2C_FCTL(i2cx) REG32((i2cx) + 0x24U) /*!< I2C filter control register */ +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< 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, cleared by software write 0 */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag, cleared by software write 0 */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag, cleared by software write 0 */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag, cleared by software write 0 */ + +/* constants definitions */ + +/* the digital noise filter can filter spikes's length */ +typedef enum { + I2C_DF_DISABLE, /*!< 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; + +/* 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) & 0xFFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#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) & 0x1F0000U) >> 16) + +/* register offset */ +#define I2C_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */ +#define I2C_STAT0_REG_OFFSET 0x14U /*!< STAT0 register offset */ +#define I2C_STAT1_REG_OFFSET 0x18U /*!< STAT1 register offset */ +#define I2C_SAMCS_REG_OFFSET 0x80U /*!< 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_TRS = 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 */ + 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 enable or disable */ +typedef enum +{ + /* interrupt in CTL1 register */ + I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U), /*!< error interrupt enable */ + I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U), /*!< event interrupt enable */ + I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U), /*!< buffer interrupt enable */ + /* interrupt in SAMCS register */ + I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U), /*!< txframe fall interrupt enable */ + I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U), /*!< txframe rise interrupt enable */ + I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U), /*!< rxframe fall interrupt enable */ + I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U) /*!< rxframe rise interrupt enable */ +}i2c_interrupt_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 ((uint32_t)0x00000001U) /*!< ACK will be sent */ + +/* I2C POAP position*/ +#define I2C_ACKPOS_NEXT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK for the next byte */ +#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000001U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ + +/* I2C dual-address mode switch */ +#define I2C_DUADEN_DISABLE ((uint32_t)0x00000000U) /*!< dual-address mode disabled */ +#define I2C_DUADEN_ENABLE ((uint32_t)0x00000001U) /*!< dual-address mode enabled */ + +/* whether or not to stretch SCL low */ +#define I2C_SCLSTRETCH_ENABLE ((uint32_t)0x00000000U) /*!< SCL stretching is enabled */ +#define I2C_SCLSTRETCH_DISABLE I2C_CTL0_SS /*!< SCL stretching is disabled */ + +/* 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_SET I2C_CTL0_SRESET /*!< I2C is under reset */ +#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ + +/* I2C DMA mode configure */ +/* DMA mode switch */ +#define I2C_DMA_ON I2C_CTL1_DMAON /*!< DMA mode enabled */ +#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< DMA mode disabled */ + +/* flag indicating DMA last transfer */ +#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ +#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ + +/* I2C PEC configure */ +/* PEC enable */ +#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ +#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ + +/* PEC transfer */ +#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC */ +#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ + +/* I2C SMBus configure */ +/* issue or not alert through SMBA pin */ +#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ +#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ + +/* ARP protocol in SMBus switch */ +#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< ARP is enabled */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP is disabled */ + +/* 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) /*!< I2C fast mode Tlow/Thigh = 2 */ +#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< I2C fast mode Tlow/Thigh = 16/9 */ + +/* address mode for the I2C slave */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address:7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address:10 bits */ + +/* function declarations */ +/* 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); +/* SMBus type selection */ +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); +/* enable I2C DMA mode */ +void i2c_dma_enable(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); +/* software reset I2C */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); + +/* I2C PEC calculation on or off */ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate); +/* I2C whether to transfer PEC value */ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara); +/* packet error checking value */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph); +/* I2C issue alert through SMBA pin */ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara); +/* I2C ARP protocol in SMBus switch */ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate); + +/* I2C analog noise filter disable */ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph); +/* I2C analog noise filter enable */ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph); +/* 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); + +/* check I2C flag is set or not */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag); +/* clear I2C flag */ +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); +/* check I2C interrupt flag */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); +/* clear I2C interrupt flag */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); + +#endif /* GD32F4XX_I2C_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h new file mode 100644 index 0000000000..d9ae8ce33a --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_ipa.h @@ -0,0 +1,384 @@ +/*! + \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 +*/ + +/* + 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_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 + 0x00U) /*!< IPA control register */ +#define IPA_INTF REG32(IPA + 0x04U) /*!< IPA interrupt flag register */ +#define IPA_INTC REG32(IPA + 0x08U) /*!< IPA interrupt flag clear register */ +#define IPA_FMADDR REG32(IPA + 0x0CU) /*!< IPA foreground memory base address register */ +#define IPA_FLOFF REG32(IPA + 0x10U) /*!< IPA foreground line offset register */ +#define IPA_BMADDR REG32(IPA + 0x14U) /*!< IPA background memory base address register */ +#define IPA_BLOFF REG32(IPA + 0x18U) /*!< IPA background line offset register */ +#define IPA_FPCTL REG32(IPA + 0x1CU) /*!< IPA foreground pixel control register */ +#define IPA_FPV REG32(IPA + 0x20U) /*!< IPA foreground pixel value register */ +#define IPA_BPCTL REG32(IPA + 0x24U) /*!< IPA background pixel control register */ +#define IPA_BPV REG32(IPA + 0x28U) /*!< IPA background pixel value register */ +#define IPA_FLMADDR REG32(IPA + 0x2CU) /*!< IPA foreground LUT memory base address register */ +#define IPA_BLMADDR REG32(IPA + 0x30U) /*!< IPA background LUT memory base address register */ +#define IPA_DPCTL REG32(IPA + 0x34U) /*!< IPA destination pixel control register */ +#define IPA_DPV REG32(IPA + 0x38U) /*!< IPA destination pixel value register */ +#define IPA_DMADDR REG32(IPA + 0x3CU) /*!< IPA destination memory base address register */ +#define IPA_DLOFF REG32(IPA + 0x40U) /*!< IPA destination line offset register */ +#define IPA_IMS REG32(IPA + 0x44U) /*!< IPA image size register */ +#define IPA_LM REG32(IPA + 0x48U) /*!< IPA line mark register */ +#define IPA_ITCTL REG32(IPA + 0x4CU) /*!< 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h new file mode 100644 index 0000000000..4be9181ed8 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_iref.h @@ -0,0 +1,186 @@ +/*! + \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 +*/ + +/* + 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_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 */ +/* deinit 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_misc.h new file mode 100644 index 0000000000..21ae664c14 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h new file mode 100644 index 0000000000..f19b1cb2ec --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_pmu.h @@ -0,0 +1,199 @@ +/*! + \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 +*/ + +/* + 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_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) + 0x00U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x04U) /*!< 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 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 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 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 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 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 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 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 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 ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO normal work when PMU enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deepsleep mode */ + +/* 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 register */ +void pmu_deinit(void); + +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* LDO output voltage select */ +void pmu_ldo_output_select(uint32_t ldo_output); +/* PMU lvd disable */ +void pmu_lvd_disable(void); + +/* functions of low-driver mode and high-driver mode in deep-sleep mode */ +/* high-driver mode switch */ +void pmu_highdriver_switch_select(uint32_t highdr_switch); +/* high-driver mode enable */ +void pmu_highdriver_mode_enable(void); +/* high-driver mode disable */ +void pmu_highdriver_mode_disable(void); +/* low-driver mode enable in deep-sleep mode */ +void pmu_low_driver_mode_enable(uint32_t lowdr_mode); +/* in deep-sleep mode, low-driver mode when use low power LDO */ +void pmu_lowdriver_lowpower_config(uint32_t mode); +/* in deep-sleep mode, low-driver mode when use normal power LDO */ +void pmu_lowdriver_normalpower_config(uint32_t mode); + +/* set PMU mode */ +/* PMU work at sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work at deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd); +/* PMU work at standby mode */ +void pmu_to_standbymode(uint8_t standbymodecmd); +/* PMU wakeup pin enable */ +void pmu_wakeup_pin_enable(void); +/* PMU wakeup pin disable */ +void pmu_wakeup_pin_disable(void); + +/* backup related functions */ +/* backup SRAM LDO on */ +void pmu_backup_ldo_config(uint32_t bkp_ldo); +/* backup domain write enable */ +void pmu_backup_write_enable(void); +/* backup domain write disable */ +void pmu_backup_write_disable(void); + +/* flag functions */ +/* reset flag bit */ +void pmu_flag_reset(uint32_t flag_reset); +/* get flag status */ +FlagStatus pmu_flag_get(uint32_t pmu_flag); + +#endif /* GD32F4XX_PMU_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h new file mode 100644 index 0000000000..0445df4eb0 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rcu.h @@ -0,0 +1,1179 @@ +/*! + \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 +*/ + +/* + 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_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_PLLI2SQ BITS(24,27) /*!< the PLLI2S Q output frequency division factor from PLLI2S VCO clock */ +#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_PLLSAIQ BITS(24,27) /*!< the PLLSAI Q 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_1_2 DSV_DSLPVS(0) /*!< core voltage is 1.2V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_1 DSV_DSLPVS(1) /*!< core voltage is 1.1V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(2) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(3) /*!< core voltage is 0.9V in deep-sleep mode */ + + +/* function declarations */ +/* 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); + +/* 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); + + +/* 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); + +/* 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); +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); + +/* 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); +/* 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); + +#endif /* GD32F4XX_RCU_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h new file mode 100644 index 0000000000..75e66f236e --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_rtc.h @@ -0,0 +1,640 @@ +/*! + \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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h new file mode 100644 index 0000000000..a18214c023 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_sdio.h @@ -0,0 +1,433 @@ +/*! + \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 +*/ + +/* + 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_SDIO_H +#define GD32F4XX_SDIO_H + +#include "gd32f4xx.h" + +/* SDIO definitions */ +#define SDIO SDIO_BASE + +/* registers definitions */ +#define SDIO_PWRCTL REG32(SDIO + 0x00U) /*!< SDIO power control register */ +#define SDIO_CLKCTL REG32(SDIO + 0x04U) /*!< SDIO clock control register */ +#define SDIO_CMDAGMT REG32(SDIO + 0x08U) /*!< SDIO command argument register */ +#define SDIO_CMDCTL REG32(SDIO + 0x0CU) /*!< SDIO command control register */ +#define SDIO_RSPCMDIDX REG32(SDIO + 0x10U) /*!< SDIO command index response register */ +#define SDIO_RESP0 REG32(SDIO + 0x14U) /*!< SDIO response register 0 */ +#define SDIO_RESP1 REG32(SDIO + 0x18U) /*!< SDIO response register 1 */ +#define SDIO_RESP2 REG32(SDIO + 0x1CU) /*!< SDIO response register 2 */ +#define SDIO_RESP3 REG32(SDIO + 0x20U) /*!< SDIO response register 3 */ +#define SDIO_DATATO REG32(SDIO + 0x24U) /*!< SDIO data timeout register */ +#define SDIO_DATALEN REG32(SDIO + 0x28U) /*!< SDIO data length register */ +#define SDIO_DATACTL REG32(SDIO + 0x2CU) /*!< SDIO data control register */ +#define SDIO_DATACNT REG32(SDIO + 0x30U) /*!< SDIO data counter register */ +#define SDIO_STAT REG32(SDIO + 0x34U) /*!< SDIO status register */ +#define SDIO_INTC REG32(SDIO + 0x38U) /*!< SDIO interrupt clear register */ +#define SDIO_INTEN REG32(SDIO + 0x3CU) /*!< SDIO interrupt enable register */ +#define SDIO_FIFOCNT REG32(SDIO + 0x48U) /*!< SDIO FIFO counter register */ +#define SDIO_FIFO REG32(SDIO + 0x80U) /*!< 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h new file mode 100644 index 0000000000..61bf8b1af2 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_spi.h @@ -0,0 +1,379 @@ +/*! + \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 +*/ + +/* + 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_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) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ +#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< SPI quad mode control register */ + +/* I2S_ADD registers definitions */ +#define I2S_ADD_CTL0(i2sx_add) REG32((i2sx_add) + 0x00U) /*!< I2S_ADD control register 0 */ +#define I2S_ADD_CTL1(i2sx_add) REG32((i2sx_add) + 0x04U) /*!< I2S_ADD control register 1*/ +#define I2S_ADD_STAT(i2sx_add) REG32((i2sx_add) + 0x08U) /*!< I2S_ADD status register */ +#define I2S_ADD_DATA(i2sx_add) REG32((i2sx_add) + 0x0CU) /*!< I2S_ADD data register */ +#define I2S_ADD_CRCPOLY(i2sx_add) REG32((i2sx_add) + 0x10U) /*!< I2S_ADD CRC polynomial register */ +#define I2S_ADD_RCRC(i2sx_add) REG32((i2sx_add) + 0x14U) /*!< I2S_ADD receive CRC register */ +#define I2S_ADD_TCRC(i2sx_add) REG32((i2sx_add) + 0x18U) /*!< I2S_ADD transmit CRC register */ +#define I2S_ADD_I2SCTL(i2sx_add) REG32((i2sx_add) + 0x1CU) /*!< I2S_ADD I2S control register */ +#define I2S_ADD_I2SPSC(i2sx_add) REG32((i2sx_add) + 0x20U) /*!< 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 the default values */ +void spi_struct_para_init(spi_parameter_struct* spi_struct); +/* initialize SPI parameter */ +void spi_init(uint32_t spi_periph,spi_parameter_struct* spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph,uint32_t i2s_mode,uint32_t i2s_standard,uint32_t i2s_ckpl); +/* configure I2S 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 */ +void spi_dma_enable(uint32_t spi_periph,uint8_t spi_dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph,uint8_t spi_dma); + +/* SPI/I2S transfer configure functions */ +/* configure SPI/I2S data frame 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); + +/* 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); + +/* 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); + +/* 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); + +/* quad wire SPI functions */ +/* enable quad wire SPI */ +void qspi_enable(uint32_t spi_periph); +/* disable quad wire SPI */ +void qspi_disable(uint32_t spi_periph); +/* enable quad wire SPI write */ +void qspi_write_enable(uint32_t spi_periph); +/* enable quad wire SPI read */ +void qspi_read_enable(uint32_t spi_periph); +/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_enable(uint32_t spi_periph); +/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_disable(uint32_t spi_periph); + +/* flag & interrupt functions */ +/* enable SPI interrupt */ +void spi_i2s_interrupt_enable(uint32_t spi_periph,uint8_t spi_i2s_int); +/* disable SPI interrupt */ +void spi_i2s_interrupt_disable(uint32_t spi_periph,uint8_t spi_i2s_int); +/* get SPI and I2S interrupt status*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph,uint8_t spi_i2s_int); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph,uint32_t spi_i2s_flag); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +#endif /* GD32F4XX_SPI_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h new file mode 100644 index 0000000000..047910478a --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_syscfg.h @@ -0,0 +1,181 @@ +/*! + \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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h new file mode 100644 index 0000000000..9da6e12bdd --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_timer.h @@ -0,0 +1,781 @@ +/*! + \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 +*/ + +/* + Copyright (c) 2020, GigaDevice Semiconductor Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#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_ENCODER_MODE0 SMCFG_SMC(1) /*!< encoder mode 0 */ +#define TIMER_ENCODER_MODE1 SMCFG_SMC(2) /*!< encoder mode 1 */ +#define TIMER_ENCODER_MODE2 SMCFG_SMC(3) /*!< encoder 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 interrupt and 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); +/* 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); + +/* 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); + +#endif /* GD32F4XX_TIMER_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h new file mode 100644 index 0000000000..8b1232fa17 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_tli.h @@ -0,0 +1,376 @@ +/*! + \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 +*/ + +/* + 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_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+0x80) /*!< TLI layer1 base address */ + +/* registers definitions */ +#define TLI_SPSZ REG32(TLI + 0x08U) /*!< TLI synchronous pulse size register */ +#define TLI_BPSZ REG32(TLI + 0x0CU) /*!< TLI back-porch size register */ +#define TLI_ASZ REG32(TLI + 0x10U) /*!< TLI active size register */ +#define TLI_TSZ REG32(TLI + 0x14U) /*!< TLI total size register */ +#define TLI_CTL REG32(TLI + 0x18U) /*!< TLI control register */ +#define TLI_RL REG32(TLI + 0x24U) /*!< TLI reload Layer register */ +#define TLI_BGC REG32(TLI + 0x2CU) /*!< TLI background color register */ +#define TLI_INTEN REG32(TLI + 0x34U) /*!< TLI interrupt enable register */ +#define TLI_INTF REG32(TLI + 0x38U) /*!< TLI interrupt flag register */ +#define TLI_INTC REG32(TLI + 0x3CU) /*!< TLI interrupt flag clear register */ +#define TLI_LM REG32(TLI + 0x40U) /*!< TLI line mark register */ +#define TLI_CPPOS REG32(TLI + 0x44U) /*!< TLI current pixel position register */ +#define TLI_STAT REG32(TLI + 0x48U) /*!< TLI status register */ +#define TLI_LxCTL(layerx) REG32((layerx) + 0x84U) /*!< TLI layer x control register */ +#define TLI_LxHPOS(layerx) REG32((layerx) + 0x88U) /*!< TLI layer x horizontal position parameters register */ +#define TLI_LxVPOS(layerx) REG32((layerx) + 0x8CU) /*!< TLI layer x vertical position parameters register */ +#define TLI_LxCKEY(layerx) REG32((layerx) + 0x90U) /*!< TLI layer x color key register */ +#define TLI_LxPPF(layerx) REG32((layerx) + 0x94U) /*!< TLI layer x packeted pixel format register */ +#define TLI_LxSA(layerx) REG32((layerx) + 0x98U) /*!< TLI layer x specified alpha register */ +#define TLI_LxDC(layerx) REG32((layerx) + 0x9CU) /*!< TLI layer x default color register */ +#define TLI_LxBLEND(layerx) REG32((layerx) + 0xA0U) /*!< TLI layer x blending register */ +#define TLI_LxFBADDR(layerx) REG32((layerx) + 0xACU) /*!< TLI layer x frame base address register */ +#define TLI_LxFLLEN(layerx) REG32((layerx) + 0xB0U) /*!< TLI layer x frame line length register */ +#define TLI_LxFTLN(layerx) REG32((layerx) + 0xB4U) /*!< TLI layer x frame total line number register */ +#define TLI_LxLUT(layerx) REG32((layerx) + 0xC4U) /*!< 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h new file mode 100644 index 0000000000..f321b15d28 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_trng.h @@ -0,0 +1,104 @@ +/*! + \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 +*/ + +/* + 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_TRNG_H +#define GD32F4XX_TRNG_H + +#include "gd32f4xx.h" + +/* TRNG definitions */ +#define TRNG TRNG_BASE + +/* registers definitions */ +#define TRNG_CTL REG32(TRNG + 0x00U) /*!< control register */ +#define TRNG_STAT REG32(TRNG + 0x04U) /*!< status register */ +#define TRNG_DATA REG32(TRNG + 0x08U) /*!< data register */ + +/* bits definitions */ +/* TRNG_CTL */ +#define TRNG_CTL_TRNGEN BIT(2) /*!< TRNG enable bit */ +#define TRNG_CTL_IE 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_TRNDATA 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 */ +/* deinitialize the TRNG */ +void trng_deinit(void); +/* enable the TRNG interface */ +void trng_enable(void); +/* disable the TRNG interface */ +void trng_disable(void); +/* get the true random data */ +uint32_t trng_get_true_random_data(void); + +/* flag & interrupt functions */ +/* trng interrupt enable */ +void trng_interrupt_enable(void); +/* trng interrupt disable */ +void trng_interrupt_disable(void); +/* get the trng status flags */ +FlagStatus trng_flag_get(trng_flag_enum flag); +/* get the trng interrupt flags */ +FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag); +/* clear the trng interrupt flags */ +void trng_interrupt_flag_clear(trng_int_flag_enum int_flag); + +#endif /* GD32F4XX_TRNG_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h new file mode 100644 index 0000000000..3cd49d827f --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_usart.h @@ -0,0 +1,495 @@ +/*! + \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 +*/ + +/* + 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_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) /*!< receiver enable */ +#define USART_CTL0_TEN BIT(3) /*!< transmitter enable */ +#define USART_CTL0_IDLEIE BIT(4) /*!< idle line detected interrupt enable */ +#define USART_CTL0_RBNEIE BIT(5) /*!< read data buffer not empty interrupt and overrun error interrupt enable */ +#define USART_CTL0_TCIE BIT(6) /*!< transmission complete interrupt enable */ +#define USART_CTL0_TBEIE BIT(7) /*!< transmitter buffer empty interrupt enable */ +#define USART_CTL0_PERRIE BIT(8) /*!< parity error interrupt enable */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< parity check function enable */ +#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) /*!< USART enable */ +#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) /*!< LIN break detected interrupt eanble */ +#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) /*!< CK pin enable */ +#define USART_CTL1_STB BITS(12,13) /*!< STOP bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable */ +#define USART_CTL2_IREN BIT(1) /*!< IrDA mode enable */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< half-duplex enable */ +#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< smartcard mode enable */ +#define USART_CTL2_DENR BIT(6) /*!< DMA request enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA request enable for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< RTS enable */ +#define USART_CTL2_CTSEN BIT(9) /*!< CTS enable */ +#define USART_CTL2_CTSIE BIT(10) /*!< CTS interrupt enable */ +#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) /*!< receiver timeout enable */ +#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; + +/* USART invert configure */ +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; + +/* USART receiver configure */ +#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 */ + +/* USART transmitter configure */ +#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 */ + +/* USART DMA request for receive configure */ +#define CLT2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_DENR_ENABLE CLT2_DENR(1) /*!< DMA request enable for reception */ +#define USART_DENR_DISABLE CLT2_DENR(0) /*!< DMA request disable for reception */ + +/* USART DMA request for transmission configure */ +#define CLT2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_DENT_ENABLE CLT2_DENT(1) /*!< DMA request enable for transmission */ +#define USART_DENT_DISABLE CLT2_DENT(0) /*!< DMA request disable for transmission */ + +/* USART RTS configure */ +#define CLT2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CLT2_RTSEN(1) /*!< RTS enable */ +#define USART_RTS_DISABLE CLT2_RTSEN(0) /*!< RTS disable */ + +/* USART CTS configure */ +#define CLT2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CLT2_CTSEN(1) /*!< CTS enable */ +#define USART_CTS_DISABLE CLT2_CTSEN(0) /*!< CTS disable */ + +/* USART one sample bit method configure */ +#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 */ + +/* USART IrDA low-power enable */ +#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, uint32_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, uint32_t guat); +/* enable smartcard mode */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* disable smartcard mode */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* enable NACK in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* disable NACK in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* configure smartcard auto-retry number */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); +/* configure block length */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler */ +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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h new file mode 100644 index 0000000000..525b9a6e5a --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Include/gd32f4xx_wwdgt.h @@ -0,0 +1,88 @@ +/*! + \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 +*/ + +/* + 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_WWDGT_H +#define GD32F4XX_WWDGT_H + +#include "gd32f4xx.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* 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 */ + +/* 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); + +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); + +#endif /* GD32F4XX_WWDGT_H */ diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c new file mode 100644 index 0000000000..f249e6c840 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_adc.c @@ -0,0 +1,1202 @@ +/*! + \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 +*/ + +/* + 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_adc.h" + +#define REGULAR_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 regular channel macro */ +#define ADC_REGULAR_CHANNEL_RANK_SIX ((uint8_t)6U) +#define ADC_REGULAR_CHANNEL_RANK_TWELVE ((uint8_t)12U) +#define ADC_REGULAR_CHANNEL_RANK_SIXTEEN ((uint8_t)16U) +#define ADC_REGULAR_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 channel group convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_special_function_config(uint32_t adc_periph , uint32_t function , ControlStatus newvalue) +{ + if(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 channel group 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 channel group 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 regular conversion + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_request_after_last_enable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DDM); +} + +/*! + \brief the DMA engine is disabled after the end of transfer signal from DMA controller is detected + \param[in] adc_periph: ADCx,x=0,1,2 + \param[out] none + \retval none +*/ +void adc_dma_request_after_last_disable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DDM); +} + +/*! + \brief configure ADC discontinuous mode + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel + \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 + for regular channel ,the number has no effect for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length) +{ + /* disable discontinuous mode of regular & inserted channel */ + ADC_CTL0(adc_periph) &= ~((uint32_t)( ADC_CTL0_DISRC | ADC_CTL0_DISIC )); + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* config the number of conversions in discontinuous mode */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM); + if((length <= 8U) && (length >= 1U)){ + ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + /* enable regular channel group discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + /* enable inserted channel group discontinuous mode */ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + /* disable discontinuous mode of regular & inserted channel */ + default: + break; + } +} + +/*! + \brief configure the length of regular channel group or inserted channel group + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: the length of the channel + regular channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + if((length >= 1U) && (length <= 16U)){ + ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length-ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + break; + case ADC_INSERTED_CHANNEL: + if((length >= 1U) && (length <= 4U)){ + ADC_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 regular channel + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] rank: the regular group sequencer rank,this parameter must be between 0 to 15 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..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_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time) +{ + uint32_t rsq,sampt; + + /* ADC regular sequence config */ + if(rank < ADC_REGULAR_CHANNEL_RANK_SIX){ + /* the regular group sequence rank is smaller than six */ + rsq = ADC_RSQ2(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*rank))); + /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ + rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*rank)); + ADC_RSQ2(adc_periph) = rsq; + }else if(rank < ADC_REGULAR_CHANNEL_RANK_TWELVE){ + /* the regular group sequence rank is smaller than twelve */ + rsq = ADC_RSQ1(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_SIX)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ + rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_SIX))); + ADC_RSQ1(adc_periph) = rsq; + }else if(rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN){ + /* the regular group sequence rank is smaller than sixteen */ + rsq = ADC_RSQ0(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_TWELVE)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */ + rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH*(rank-ADC_REGULAR_CHANNEL_RANK_TWELVE))); + ADC_RSQ0(adc_periph) = rsq; + }else{ + } + + /* ADC sampling time config */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN){ + /* the regular group 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 regular group 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 group sequencer rank,this parameter must be between 0 to 3 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..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 channel group 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 channel group */ + 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 group 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 group 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_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] external_trigger_source: regular or inserted group trigger source + for regular channel: + only one parameter can be selected which is shown as below: + \arg ADC_EXTTRIG_REGULAR_T0_CH0: external trigger timer 0 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CC1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CC2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CC1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH2: external trigger timer 1 CC2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_CH3: external trigger timer 1 CC3 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T1_TRGO: external trigger timer 1 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T2_CH0 : external trigger timer 2 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T2_TRGO : external trigger timer 2 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T3_CH3: external trigger timer 3 CC3 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T4_CH0: external trigger timer 4 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T4_CH1: external trigger timer 4 CC1 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T4_CH2: external trigger timer 4 CC2 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T7_CH0: external trigger timer 7 CC0 event select for regular channel + \arg ADC_EXTTRIG_REGULAR_T7_TRGO: external trigger timer 7 TRGO event select for regular channel + \arg ADC_EXTTRIG_REGULAR_EXTI_11: external trigger extiline 11 select for regular channel + for inserted channel: + 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_channel_group , uint32_t external_trigger_source) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure ADC regular group 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 group 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_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] trigger_mode: external trigger mode + only one parameter can be selected which is shown as below: + \arg EXTERNAL_TRIGGER_DISABLE: external trigger disable + \arg EXTERNAL_TRIGGER_RISING: rising edge of external trigger + \arg EXTERNAL_TRIGGER_FALLING: falling edge of external trigger + \arg EXTERNAL_TRIGGER_RISING_FALLING: rising and falling edge of external trigger + \param[out] none + \retval none +*/ +void adc_external_trigger_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t trigger_mode) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure ADC regular channel group external trigger mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC); + ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << REGULAR_TRIGGER_MODE); + break; + case ADC_INSERTED_CHANNEL: + /* configure ADC inserted channel group external trigger mode */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMIC); + ADC_CTL1(adc_periph) |= (uint32_t) (trigger_mode << INSERTED_TRIGGER_MODE); + break; + default: + break; + } +} + +/*! + \brief enable ADC software trigger + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* enable ADC regular channel group software trigger */ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST; + break; + case ADC_INSERTED_CHANNEL: + /* enable ADC inserted channel group 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 regular conversions, the EOC bit is set.Overflow detection is disabled unless DMA=1. + \arg ADC_EOC_SET_CONVERSION: at the end of each regular conversion, the EOC bit is set.Overflow is detected automatically. + \param[out] none + \retval none +*/ +void adc_end_of_conversion_config(uint32_t adc_periph , uint8_t end_selection) +{ + switch(end_selection){ + case ADC_EOC_SET_SEQUENCE: + /* only at the end of a sequence of regular 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 regular 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 regular group data register + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_regular_data_read(uint32_t adc_periph) +{ + return (uint16_t)(ADC_RDATA(adc_periph)); +} + +/*! + \brief read ADC inserted group data register + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] inserted_channel : insert channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: inserted Channel0 + \arg ADC_INSERTED_CHANNEL_1: inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: inserted Channel2 + \arg ADC_INSERTED_CHANNEL_3: inserted Channel3 + \param[out] none + \retval the conversion value +*/ +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 group channel + \param[in] adc_periph: ADCx,x=0,1,2 + \param[in] adc_channel_group: the channel group use analog watchdog + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog_group_channel_enable(uint32_t adc_periph , uint8_t adc_channel_group) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC)); + /* select the group */ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* regular 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_REGULAR_INSERTED_CHANNEL: + /* regular 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_channel_group: the channel group use analog watchdog + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog_disable(uint32_t adc_periph , uint8_t adc_channel_group) +{ + /* select the group */ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* disable ADC analog watchdog regular channel group */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_RWDEN); + break; + case ADC_INSERTED_CHANNEL: + /* disable ADC analog watchdog inserted channel group */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_IWDEN); + break; + case ADC_REGULAR_INSERTED_CHANNEL: + /* disable ADC analog watchdog regular and inserted channel group */ + 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 group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \arg ADC_FLAG_ROVF: regular data register overflow flag + \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 group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \arg ADC_FLAG_ROVF: regular data register overflow flag + \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_regular_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 group conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt + \arg ADC_INT_FLAG_ROVF: regular 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 group 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 group 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 regular 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 group conversion interrupt + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt + \arg ADC_INT_FLAG_ROVF: regular 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 group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_ROVF: regular 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 group conversion interrupt */ + ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE; + break; + case ADC_INT_EOIC: + /* enable end of inserted group 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 group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_ROVF: regular 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_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel & inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel & trigger rotation mode + \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode + \arg ADC_DAUL_REGULAL_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_REGULAL_PARALLEL_INSERTED_PARALLEL: all ADCs work in combined regular parallel & inserted parallel mode + \arg ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION: all ADCs work in combined regular parallel & trigger rotation mode + \arg ADC_ALL_INSERTED_PARALLEL: all ADCs work in inserted parallel mode + \arg ADC_ALL_REGULAL_PARALLEL: all ADCs work in regular parallel mode + \arg ADC_ALL_REGULAL_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 regular data register + \param[in] none + \param[out] none + \retval sync regular data +*/ +uint32_t adc_sync_regular_data_read(void) +{ + return (uint32_t)ADC_SYNCDATA; +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c new file mode 100644 index 0000000000..5eb2974739 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_can.c @@ -0,0 +1,1027 @@ +/*! + \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 +*/ + +/* + 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_can.h" + +#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[in] p_struct: the pointer of the specific struct + \param[out] none + \retval none +*/ +void can_struct_para_init(can_struct_type_enum type, void* p_struct) +{ + uint8_t i; + + /* 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)->no_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 no_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: SUCCESS or ERROR +*/ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init) +{ + uint32_t timeout = CAN_TIMEOUT; + ErrStatus flag = 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 = 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 managment */ + 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 disable*/ + if(ENABLE == can_parameter_init->no_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(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){ + flag = 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; + } + + if(CAN_FIFO1 == can_filter_parameter_init->filter_fifo_number){ + /* 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 fliter start bank number + \param[in] can1_start_bank_number + \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 enaable */ + 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) +{ + 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) +{ + CAN_CTL(can_periph) &= ~CAN_CTL_DFZ; + if(CAN0 == can_periph){ + dbg_periph_disable(DBG_CAN0_HOLD); + }else{ + dbg_periph_disable(DBG_CAN0_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 tcc 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 TCC 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 */ + transmit_message->tx_dlen &= (uint8_t)(CAN_TMP_DLENC); + CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~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; + /* transmit failed */ + case (CAN_TSTAT_MTF0 | CAN_TSTAT_TME0): + state = CAN_TRANSMIT_FAILED; + break; + case (CAN_TSTAT_MTF1 | CAN_TSTAT_TME1): + state = CAN_TRANSMIT_FAILED; + break; + case (CAN_TSTAT_MTF2 | CAN_TSTAT_TME2): + state = CAN_TRANSMIT_FAILED; + break; + /* 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 recevie 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 FIFO0 + \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: SUCCESS or ERROR +*/ +ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode) +{ + ErrStatus flag = 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 = ERROR; + }else{ + flag = 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 = ERROR; + }else{ + flag = 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 = ERROR; + }else{ + flag = SUCCESS; + } + }else{ + flag = ERROR; + } + return flag; +} + +/*! + \brief wake up CAN + \param[in] can_periph + \arg CANx(x=0,1) + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus can_wakeup(uint32_t can_periph) +{ + ErrStatus flag = 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 = ERROR; + }else{ + flag = 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 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_WU: 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_WU: 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 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 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 staus of interrupt flag */ + if (flag == CAN_INT_FLAG_RFF0) { + ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0); + } else if (flag == CAN_INT_FLAG_RFF1) { + 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 staus of interrupt enale 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c new file mode 100644 index 0000000000..bfe79cb9aa --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_crc.c @@ -0,0 +1,128 @@ +/*! + \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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c new file mode 100644 index 0000000000..ab67c4ad73 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ctc.c @@ -0,0 +1,405 @@ +/*! + \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 +*/ + +/* + 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_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 USBFS or USBHS SOF signal + \param[in] usbsof: + \arg CTC_USBSOFSEL_USBHS: USBHS SOF signal is selected + \arg CTC_USBSOFSEL_USBFS: USBFS SOF signal is selected + \param[out] none + \retval none +*/ +void ctc_usbsof_signal_select(uint32_t usbsof) +{ + CTC_CTL1 &= (uint32_t)(~CTC_CTL1_USBSOFSEL); + CTC_CTL1 |= (uint32_t)usbsof; +} + +/*! + \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 + \arg CTC_REFSOURCE_USBSOF: USBSOF 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c new file mode 100644 index 0000000000..3a5dd52cdd --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dac.c @@ -0,0 +1,677 @@ +/*! + \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 +*/ + +/* + 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_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 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 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 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c new file mode 100644 index 0000000000..a408136ea4 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dbg.c @@ -0,0 +1,198 @@ +/*! + \file gd32f4xx_dbg.c + \brief DBG 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 +*/ + +/* + 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_dbg.h" + +#define DBG_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the DBG + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL0 = DBG_RESET_VAL; + DBG_CTL1 = DBG_RESET_VAL; +} + +/*! + \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 + \arg \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: 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; +} + +/*! + \brief trace pin mode selection + \param[in] trace_mode: + \arg TRACE_MODE_ASYNC: trace pin used for async mode + \arg TRACE_MODE_SYNC_DATASIZE_1: trace pin used for sync mode and data size is 1 + \arg TRACE_MODE_SYNC_DATASIZE_2: trace pin used for sync mode and data size is 2 + \arg TRACE_MODE_SYNC_DATASIZE_4: trace pin used for sync mode and data size is 4 + \param[out] none + \retval none +*/ +void dbg_trace_pin_mode_set(uint32_t trace_mode) +{ + DBG_CTL0 &= ~DBG_CTL0_TRACE_MODE; + DBG_CTL0 |= trace_mode; +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c new file mode 100644 index 0000000000..a1ddcab384 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dci.c @@ -0,0 +1,345 @@ +/*! + \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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c new file mode 100644 index 0000000000..d8bd7be2d7 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_dma.c @@ -0,0 +1,905 @@ +/*! + \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 +*/ + +/* + 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_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 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); + } +} + +/*! + \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 + one or more 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 + one or more 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; + } +} + diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c new file mode 100644 index 0000000000..456e476fd8 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_enet.c @@ -0,0 +1,3505 @@ +/*! + \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 +*/ + +/* + 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_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 . + 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: ERROR or 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= ERROR, enet_state = ERROR; + + /* PHY interface configuration, configure SMI clock and reset PHY chip */ + if(ERROR == enet_phy_config()){ + _ENET_DELAY_(PHY_RESETDELAY); + if(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 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 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 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 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 = 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: SUCCESS or ERROR +*/ +ErrStatus enet_software_reset(void) +{ + uint32_t timeout = 0U; + ErrStatus enet_state = ERROR; + uint32_t dma_flag; + + /* reset all core internal registers located in CLK_TX and CLK_RX */ + ENET_DMA_BCTL |= ENET_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 = 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: SUCCESS or 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 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 ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0U; offsetbuffer1_addr) + offset)); + } + + }else{ + /* return ERROR */ + return ERROR; + } + } + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_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 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: SUCCESS or 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 ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer){ + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0U; offset < length; offset++){ + (*(__IO uint8_t *) (uint32_t)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + + /* set the frame length */ + dma_current_txdesc->control_buffer_size = length; + /* set the segment of frame, frame is transmitted in one descriptor */ + dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG; + /* enable the DMA transmission */ + dma_current_txdesc->status |= ENET_TDES0_DAV; + + /* check Tx buffer unavailable flag status */ + dma_tbu_flag = (ENET_DMA_STAT & ENET_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 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: SUCCESS or ERROR +*/ +ErrStatus enet_phy_config(void) +{ + uint32_t ahbclk; + uint32_t reg; + uint16_t phy_value; + ErrStatus enet_state = 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, 200000000U))||(200000000U == ahbclk)){ + reg |= ENET_MDC_HCLK_DIV102; + }else{ + return enet_state; + } + ENET_MAC_PHY_CTL = reg; + + /* reset PHY */ + phy_value = PHY_RESET; + if(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(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 = 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: SUCCESS or 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 = 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 = 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: ERROR or SUCCESS +*/ +ErrStatus enet_phyloopback_enable(void) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = 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: ERROR or SUCCESS +*/ +ErrStatus enet_phyloopback_disable(void) +{ + uint16_t temp_phy = 0U; + ErrStatus phy_state = 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 automatic zero-quanta generation function + \arg ENET_TYPEFRAME_CRC_DROP: the flow control operation in the MAC + \arg ENET_FORWARD_ERRFRAMES: decoding function for the received pause frame and process it + \arg ENET_FORWARD_UNDERSZ_GOODFRAMES: back pressure operation in the MAC(only use in half-dulex mode) + \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: ERROR or SUCCESS +*/ +ErrStatus enet_pauseframe_generate(void) +{ + ErrStatus enet_state =ERROR; + uint32_t temp = 0U; + + /* in full-duplex mode, must make sure this bit is 0 before writing register */ + temp = ENET_MAC_FCTL & ENET_MAC_FCTL_FLCBBKPA; + if(RESET == temp){ + ENET_MAC_FCTL |= ENET_MAC_FCTL_FLCBBKPA; + enet_state = 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: ERROR or SUCCESS +*/ +ErrStatus enet_txfifo_flush(void) +{ + uint32_t flush_state; + uint32_t timeout = 0U; + ErrStatus enet_state = 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 ERROR due to timeout */ + if(RESET == flush_state){ + enet_state = SUCCESS; + } + + return enet_state; +} + +/*! + \brief get the transmit/receive address of current descriptor, or current buffer, or descriptor table + \param[in] 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: SUCCESS or 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 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 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 ERROR; + } + } + + /* if timestamp pointer is null, indicates that users don't care timestamp in application */ + if(NULL != timestamp){ + /* wait for ENET_RDES0_TSV flag to be set, the timestamp value is taken and + write to the RDES6 and RDES7 */ + do{ + rdes0_tsv_flag = (dma_current_rxdesc->status & ENET_RDES0_TSV); + timeout++; + }while ((RESET == rdes0_tsv_flag) && (timeout < ENET_DELAY_TO)); + + /* return ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + return ERROR; + } + + /* clear the ENET_RDES0_TSV flag */ + dma_current_rxdesc->status &= ~ENET_RDES0_TSV; + /* get the timestamp value of the received frame */ + timestamp[0] = dma_current_rxdesc->timestamp_low; + timestamp[1] = dma_current_rxdesc->timestamp_high; + } + + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_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 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: SUCCESS or 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 ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer){ + /* copy frame data from application buffer to Tx buffer */ + for(offset = 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 ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + return ERROR; + } + + /* clear the ENET_TDES0_TTMSS flag */ + dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; + /* get the timestamp value of the transmit frame */ + timestamp[0] = dma_current_txdesc->timestamp_low; + timestamp[1] = dma_current_txdesc->timestamp_high; + } + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ + dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr); + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); + }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 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: SUCCESS or 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 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 ERROR; + } + + /* copy data from Rx buffer to application buffer */ + for(offset = 0U; offset < size; offset++){ + (*(buffer + offset)) = (*(__IO uint8_t *)(uint32_t)((dma_current_ptp_rxdesc->buffer1_addr) + offset)); + } + + }else{ + return ERROR; + } + } + /* copy timestamp value from Rx descriptor to application array */ + timestamp[0] = dma_current_rxdesc->buffer1_addr; + timestamp[1] = dma_current_rxdesc->buffer2_next_desc_addr; + + dma_current_rxdesc->buffer1_addr = dma_current_ptp_rxdesc ->buffer1_addr ; + dma_current_rxdesc->buffer2_next_desc_addr = dma_current_ptp_rxdesc ->buffer2_next_desc_addr; + + /* enable reception, descriptor is owned by DMA */ + dma_current_rxdesc->status = ENET_RDES0_DAV; + + /* check Rx buffer unavailable flag status */ + if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_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 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: SUCCESS or 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 ERROR; + } + + /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */ + if(length > ENET_MAX_FRAME_SIZE){ + return ERROR; + } + + /* if buffer pointer is null, indicates that users has handled data in application */ + if(NULL != buffer){ + /* copy frame data from application buffer to Tx buffer */ + for(offset = 0U; offset < length; offset++){ + (*(__IO uint8_t *) (uint32_t)((dma_current_ptp_txdesc->buffer1_addr) + offset)) = (*(buffer + offset)); + } + } + /* set the frame length */ + dma_current_txdesc->control_buffer_size = (length & (uint32_t)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 ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + return ERROR; + } + + /* clear the ENET_TDES0_TTMSS flag */ + dma_current_txdesc->status &= ~ENET_TDES0_TTMSS; + /* get the timestamp value of the transmit frame */ + timestamp[0] = dma_current_txdesc->buffer1_addr; + timestamp[1] = dma_current_txdesc->buffer2_next_desc_addr; + } + dma_current_txdesc->buffer1_addr = dma_current_ptp_txdesc ->buffer1_addr ; + dma_current_txdesc->buffer2_next_desc_addr = dma_current_ptp_txdesc ->buffer2_next_desc_addr; + + /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table */ + /* chained mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){ + dma_current_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->buffer2_next_desc_addr); + /* if it is the last ptp descriptor */ + if(0U != dma_current_ptp_txdesc->status){ + /* pointer back to the first ptp descriptor address in the desc_ptptab list address */ + dma_current_ptp_txdesc = (enet_descriptors_struct*) (dma_current_ptp_txdesc->status); + }else{ + /* ponter to the next ptp descriptor */ + dma_current_ptp_txdesc++; + } + }else{ + /* ring mode */ + if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){ + /* if is the last descriptor in table, the next descriptor is the table header */ + dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR); + /* 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 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: SUCCESS or 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 = 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 ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + enet_state = 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 ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + enet_state = 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 ERROR due to timeout */ + if(ENET_DELAY_TO == timeout){ + enet_state = 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; + + ENET_MAC_FCTH = ENET_DEACTIVE_THRESHOLD_512BYTES |ENET_ACTIVE_THRESHOLD_1536BYTES; + + /* 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_FORWARD_ERRFRAMES_DISABLE |ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE \ + |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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c new file mode 100644 index 0000000000..e225258eb5 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exmc.c @@ -0,0 +1,1237 @@ +/*! + \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 +*/ + +/* + 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_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 SDRSCTL_SSCR_OFFSET ((uint32_t)1U) +#define SDRSCTL_SDSC_OFFSET ((uint32_t)4U) + +#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; + + /* write timing configure, 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_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_WREN | + EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_SYNCWR | + EXMC_SNCTL_NRMUX )); + + 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; + + 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; + + /* nor flash access enable */ + if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){ + snctl |= (uint32_t)EXMC_SNCTL_NREN; + } + + /* extended mode configure */ + 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: specifie 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: specifie 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 ); + + /* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */ + 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: specifie 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: specifie 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->brust_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 + brust_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; + + /* configuration EXMC_SDCTL0 or EXMC_SDCTL1 */ + if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device){ + /* configuration 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->brust_read_switch << SDCTL_BRSTRD_OFFSET)| + exmc_sdram_init_struct->pipeline_read_delay; + + /* configuration 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{ + /* configuration 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->brust_read_switch | + 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 ; + + EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = sdctl0; + EXMC_SDCTL(EXMC_SDRAM_DEVICE1) = sdctl1; + + /* configuration 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 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: specifie 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: specifie 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: specifie 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 & EXMC_SDRSCTL_SDSC) | + ((extra_hclk << SDRSCTL_SSCR_OFFSET) & EXMC_SDRSCTL_SSCR); + 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)<> 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: specifies 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 get which 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: specifies 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 get which 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: specifies 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: specifie 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: specifies 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: specifies 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c new file mode 100644 index 0000000000..a3eacb0202 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_exti.c @@ -0,0 +1,257 @@ +/*! + \file gd32f4xx_exti.c + \brief EXTI 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 +*/ + +/* + 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_exti.h" + +/*! + \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 = (uint32_t)0x00000000U; + EXTI_EVEN = (uint32_t)0x00000000U; + EXTI_RTEN = (uint32_t)0x00000000U; + EXTI_FTEN = (uint32_t)0x00000000U; + EXTI_SWIEV = (uint32_t)0x00000000U; +} + +/*! + \brief initialize the EXTI + \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 EXTI software interrupt event + \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 EXTI software interrupt event + \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 lines 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 lines 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 lines flag when the interrupt flag is set + \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) +{ + uint32_t flag_left, flag_right; + + flag_left = EXTI_PD & (uint32_t)linex; + flag_right = EXTI_INTEN & (uint32_t)linex; + + if((RESET != flag_left) && (RESET != flag_right)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c new file mode 100644 index 0000000000..4e2b0db9a5 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fmc.c @@ -0,0 +1,932 @@ +/*! + \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 +*/ + +/* + 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_fmc.h" + +/*! + \brief set the wait state counter value + \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; +} + +/*! + \brief 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_PGERR: program 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(); + + 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(); + + /* reset the SER bit */ + FMC_CTL &= (~FMC_CTL_SER); + FMC_CTL &= ~FMC_CTL_SN; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief 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_PGERR: program 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(); + + 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(); + + /* reset the MER bits */ + FMC_CTL &= ~(FMC_CTL_MER0 | FMC_CTL_MER1); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief erase all FMC sectors in 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_PGERR: program 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(); + + 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(); + + /* reset the MER0 bit */ + FMC_CTL &= (~FMC_CTL_MER0); + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief erase all FMC sectors in 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_PGERR: program 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(); + + 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(); + + /* 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_PGERR: program 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(); + + 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(); + + /* 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_PGERR: program 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(); + + 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(); + + /* 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_PGERR: program 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(); + + 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(); + + /* 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) +{ + fmc_state_enum fmc_state = FMC_READY; + /* set the OB_START bit in OBCTL0 register */ + FMC_OBCTL0 |= FMC_OBCTL0_OB_START; + fmc_state = fmc_ready_wait(); + if(FMC_READY != fmc_state){ + while(1){ + } + } +} + +/*! + \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(); + + if(FMC_READY == fmc_state){ + reg = FMC_OBCTL0; + reg1 = FMC_OBCTL1; + + /* 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 none +*/ +void 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)){ + while(1){ + } + } + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(); + + if(FMC_READY == fmc_state){ + reg0 &= (~((uint32_t)ob_wp << 16)); + reg1 &= (~(ob_wp & 0xFFFF0000U)); + FMC_OBCTL0 = reg0; + FMC_OBCTL1 = reg1; + } +} + +/*! + \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 none +*/ +void 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)){ + while(1){ + } + } + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(); + + if(FMC_READY == fmc_state){ + reg0 |= ((uint32_t)ob_wp << 16); + reg1 |= (ob_wp & 0xFFFF0000U); + FMC_OBCTL0 = reg0; + FMC_OBCTL1 = reg1; + } +} + +/*! + \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; + /*disable write protection before enable D-bus read protection*/ + if((RESET != drp_state) && ((FMC_OBCTL0_WP0 != wp0_state) && (FMC_OBCTL1_WP1 != wp1_state))){ + while(1){ + } + } + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(); + + if(FMC_READY == fmc_state){ + reg0 &= ~FMC_OBCTL0_WP0; + reg1 &= ~FMC_OBCTL1_WP1; + reg0 |= ((uint32_t)ob_drp << 16); + reg1 |= ((uint32_t)ob_drp & 0xFFFF0000U); + FMC_OBCTL0 = reg0; + FMC_OBCTL1 = reg1; + FMC_OBCTL0 |= FMC_OBCTL0_DRP; + } +} + +/*! + \brief disable erase/program protection and D-bus read protection + \param[in] ob_drp: disable 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_disable(uint32_t ob_drp) +{ + 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(); + + if(FMC_READY == fmc_state){ + 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(); + + 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 << 8); + 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(); + + 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 >> 5) & (uint8_t)0x07); +} + +/*! + \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 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \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 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \brief get the FMC D-bus read protection protection + \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 */ + return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \brief get the FMC D-bus read protection protection + \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 */ + return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF); +} + +/*! + \brief get the FMC option byte security protection + \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 >> 8)) != (uint8_t)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 & (uint8_t)0x0C); +} + +/*! + \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 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 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 + \arg FMC_PGERR: program error +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((FMC_STAT & FMC_FLAG_BUSY) == FMC_FLAG_BUSY){ + fmc_state = FMC_BUSY; + }else{ + if((FMC_STAT & FMC_FLAG_WPERR) != (uint32_t)0x00){ + fmc_state = FMC_WPERR; + }else{ + if((FMC_STAT & FMC_FLAG_RDDERR) != (uint32_t)0x00){ + fmc_state = FMC_RDDERR; + }else{ + if((FMC_STAT & (uint32_t)0xEF) != (uint32_t)0x00){ + fmc_state = FMC_PGERR; + }else{ + if((FMC_STAT & FMC_FLAG_OPERR) != (uint32_t)0x00){ + 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_PGERR: program error +*/ +fmc_state_enum fmc_ready_wait(void) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do{ + /* get FMC state */ + fmc_state = fmc_state_get(); + }while(FMC_BUSY == fmc_state); + + /* return the FMC state */ + return fmc_state; +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c new file mode 100644 index 0000000000..04e2c5b99d --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_fwdgt.c @@ -0,0 +1,157 @@ +/*! + \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 +*/ + +/* + 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_fwdgt.h" + +/* write value to FWDGT_CTL_CMD bit field */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0)) +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/*! + \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 reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief configure counter reload value, and prescaler divider value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[in] prescaler_div: FWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC,and FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + only one parameter can be selected which is shown as below: + \arg FWDGT_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c new file mode 100644 index 0000000000..d3693abb17 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_gpio.c @@ -0,0 +1,433 @@ +/*! + \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 +*/ + +/* + 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_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_200MHZ: output max speed 200MHz + \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 all pins 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: SPI1, SPI2, SAI0 + \arg GPIO_AF_7: USART0, USART1, USART2 + \arg GPIO_AF_8: UART3, UART4, USART5, UART6, UART7 + \arg GPIO_AF_9: CAN0, CAN1, TLI, TIMER11, TIMER12, TIMER13 + \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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c new file mode 100644 index 0000000000..c3ac50c178 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_i2c.c @@ -0,0 +1,819 @@ +/*! + \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 +*/ + +/* + 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_i2c.h" + +/* I2C register bit mask */ +#define I2CCLK_MAX ((uint32_t)0x00000032U) /*!< 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)8U) /* 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 + \arg I2C_DTCY_16_9: T_low/T_high=16/9 + \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{ + 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: 7bits + \arg I2C_ADDFORMAT_10BITS: 10bits + \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 SMBus type selection + \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: device + \arg I2C_SMBUS_HOST: host + \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) +{ + if(I2C_ACK_ENABLE == ack){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN); + } +} + +/*! + \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: whether to send ACK or not for the current + \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte + \param[out] none + \retval none +*/ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) +{ + /* configure I2C POAP position */ + if(I2C_ACKPOS_NEXT == pos){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP); + } +} + +/*! + \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 enable 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: DMA mode enable + \arg I2C_DMA_OFF: DMA mode disable + \param[out] none + \retval none +*/ +void i2c_dma_enable(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: SCL stretching is enabled + \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) +{ + /* configure I2C SCL strerching enable or disable */ + 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 software reset 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 I2C PEC calculation on or off + \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_enable(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 I2C 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 + \arg I2C_PECTRANS_DISABLE: not transfer PEC + \param[out] none + \retval none +*/ +void i2c_pec_transfer_enable(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 I2C issue 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_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) +{ + /* issue alert through SMBA pin configure*/ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SALT); + ctl |= smbuspara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable or disable I2C ARP protocol in SMBus switch + \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_enable(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 analog noise filter disable + \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 analog noise filter enable + \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 digital noise filter configuration + \param[in] i2c_periph: I2Cx(x=0,1,2) + \param[in] dfilterpara: refer to enum i2c_digital_filter_enum + \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 check I2C flag is set or not + \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 send out + \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: overrun or underrun 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_TRS: 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 + \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 + \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1 + \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 enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \arg I2C_INT_TFF: txframe fall interrupt enable + \arg I2C_INT_TFR: txframe rise interrupt enable + \arg I2C_INT_RFF: rxframe fall interrupt enable + \arg I2C_INT_RFR: rxframe rise interrupt enable + \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_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \arg I2C_INT_TFF: txframe fall interrupt enable + \arg I2C_INT_TFR: txframe rise interrupt enable + \arg I2C_INT_RFF: rxframe fall interrupt enable + \arg I2C_INT_RFR: rxframe rise interrupt enable + \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 check I2C interrupt flag + \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 + \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag + \arg I2C_INT_FLAG_STPDET: etop 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 + \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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c new file mode 100644 index 0000000000..5afcc48e0d --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_ipa.c @@ -0,0 +1,637 @@ +/*! + \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 +*/ + +/* + 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_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 |= 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c new file mode 100644 index 0000000000..218a070ef4 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_iref.c @@ -0,0 +1,126 @@ +/*! + \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 +*/ + +/* + 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_iref.h" + +/*! + \brief deinit 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c new file mode 100644 index 0000000000..c826722f13 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_misc.c @@ -0,0 +1,174 @@ +/*! + \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 +*/ + +/* + 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_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); +} + +/*! + \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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c new file mode 100644 index 0000000000..05f4cd7c3a --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_pmu.c @@ -0,0 +1,391 @@ +/*! + \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 +*/ + +/* + 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_pmu.h" +#include "core_cm4.h" +/*! + \brief reset PMU register + \param[in] none + \param[out] none + \retval none +*/ +void pmu_deinit(void) +{ + /* reset PMU */ + rcu_periph_reset_enable(RCU_PMURST); + rcu_periph_reset_disable(RCU_PMURST); +} + +/*! + \brief select low voltage detector threshold + \param[in] lvdt_n: + \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 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 low-driver mode in deep-sleep mode + \param[in] lowdr_mode: + \arg PMU_LOWDRIVER_ENABLE: enable low-driver mode in deep-sleep mode + \arg PMU_LOWDRIVER_DISABLE: disable low-driver mode in deep-sleep mode + \param[out] none + \retval none +*/ +void pmu_low_driver_mode_enable(uint32_t lowdr_mode) +{ + PMU_CTL &= ~PMU_CTL_LDEN; + PMU_CTL |= lowdr_mode; +} + +/*! + \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 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 disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief low-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_lowdriver_lowpower_config(uint32_t mode) +{ + PMU_CTL &= ~PMU_CTL_LDLP; + PMU_CTL |= mode; +} + +/*! + \brief low-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_lowdriver_normalpower_config(uint32_t mode) +{ + PMU_CTL &= ~PMU_CTL_LDNP; + PMU_CTL |= mode; +} + +/*! + \brief PMU work at 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 at deepsleep mode + \param[in] ldo + \arg PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode + \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep 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,uint8_t deepsleepmodecmd) +{ + static uint32_t reg_snap[ 4 ]; + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= ldo; + + /* 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 deepsleep 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 at standby mode + \param[in] standbymodecmd: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_standbymode(uint8_t standbymodecmd) +{ + /* set sleepdeep bit of Cortex-M4 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* select WFI or WFE command to enter standby mode */ + if(WFI_CMD == standbymodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \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 reset flag bit + \param[in] flag_reset: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_reset(uint32_t flag_reset) +{ + switch(flag_reset){ + 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; + } +} + +/*! + \brief get flag state + \param[in] pmu_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 pmu_flag) +{ + if(PMU_CS & pmu_flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief enable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief disable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief enable wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(void) +{ + PMU_CS |= PMU_CS_WUPEN; +} + +/*! + \brief disable wakeup pin + \param[in] none + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(void) +{ + PMU_CS &= ~PMU_CS_WUPEN; +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c new file mode 100644 index 0000000000..aecc895a09 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rcu.c @@ -0,0 +1,1329 @@ +/*! + \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 +*/ + +/* + 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_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); + /* 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 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 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 + \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: SUCCESS or 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 ERROR; + } + + /* return status */ + return 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: SUCCESS or 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 ERROR; + } + + /* return status */ + return 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: SUCCESS or 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 ERROR; + } + + /* return status */ + return 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 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)); +} + +/*! + \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: SUCCESS or ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + + switch(osci){ + /* wait HXTAL stable */ + case RCU_HXTAL: + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){ + reval = SUCCESS; + } + break; + /* wait LXTAL stable */ + case RCU_LXTAL: + while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){ + reval = SUCCESS; + } + break; + /* wait 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 = SUCCESS; + } + break; + /* wait IRC48M stable */ + case RCU_IRC48M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC48MSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if (RESET != rcu_flag_get(RCU_FLAG_IRC48MSTB)){ + reval = SUCCESS; + } + break; + /* wait IRC32K stable */ + case RCU_IRC32K: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC32KSTB); + stb_cnt++; + } + + /* check whether flag is set */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC32KSTB)){ + reval = SUCCESS; + } + break; + /* wait 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 = 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 = 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 = 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 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 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 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_1_2: the core voltage is 1.2V + \arg RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + dsvol &= RCU_DSV_DSLPVS; + RCU_DSV = dsvol; +} + +/*! + \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 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; +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c new file mode 100644 index 0000000000..12ee6c3207 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_rtc.c @@ -0,0 +1,1295 @@ +/*! + \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 +*/ + +/* + 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_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: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* RTC_TAMP register is not under write protection */ + RTC_TAMP = RTC_REGISTER_RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(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 = 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: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; + uint32_t reg_time = 0U, reg_date = 0U; + + reg_date = (DATE_YR(rtc_initpara_struct->year) | \ + DATE_DOW(rtc_initpara_struct->day_of_week) | \ + DATE_MON(rtc_initpara_struct->month) | \ + DATE_DAY(rtc_initpara_struct->date)); + + reg_time = (rtc_initpara_struct->am_pm| \ + TIME_HR(rtc_initpara_struct->hour) | \ + TIME_MN(rtc_initpara_struct->minute) | \ + TIME_SC(rtc_initpara_struct->second)); + + /* 1st: disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn)| \ + PSC_FACTOR_S(rtc_initpara_struct->factor_syn)); + + RTC_TIME = (uint32_t)reg_time; + RTC_DATE = (uint32_t)reg_date; + + RTC_CTL &= (uint32_t)(~RTC_CTL_CS); + RTC_CTL |= rtc_initpara_struct->display_format; + + /* 3rd: exit init mode */ + rtc_init_mode_exit(); + + /* 4th: wait the RSYNF flag to set */ + error_status = rtc_register_sync_wait(); + } + + /* 5th: enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enter RTC init mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + volatile uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){ + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_INITF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + }else{ + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief exit RTC init mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + registers are updated + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* firstly clear RSYNF flag */ + RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); + + /* wait until RSYNF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_RSYNF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + }else{ + error_status = SUCCESS; + } + + return error_status; +} + +/*! + \brief get current time and date + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + year: 0x0 - 0x99(BCD format) + month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + date: 0x1 - 0x31(BCD format) + day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_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_pscr & 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: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(uint8_t rtc_alarm) +{ + volatile uint32_t time_index = RTC_ALRMXWF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of alarm */ + if(RTC_ALARM0 == rtc_alarm){ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + /* wait until ALRM0WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM0WF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + }else{ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM1EN); + /* wait until ALRM1WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM1WF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + } + + if ((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC time-stamp + \param[in] edge: specify which edge to detect of time-stamp + \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_ALARM0: alarm0 occurs flag + \arg RTC_FLAG_ALARM1: alarm1 occurs flag + \arg RTC_FLAG_WT: wakeup timer occurs flag + \arg RTC_FLAG_INIT: initialization state flag + \arg RTC_FLAG_RSYN: register synchronization flag + \arg RTC_FLAG_YCM: year configuration mark status flag + \arg RTC_FLAG_SOP: shift function operation pending flag + \arg RTC_FLAG_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: ERROR or SUCCESS +*/ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) +{ + volatile uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + uint32_t temp=0U; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a shift operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SOPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + /* check if the function of reference clock detection is disabled */ + temp = RTC_CTL & RTC_CTL_REFEN; + if((RESET == flag_status) && (RESET == temp)){ + RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= 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: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief disable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC auto wakeup function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_wakeup_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_WTEN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC auto wakeup function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_disable(void) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + RTC_CTL &= ~RTC_CTL_WTEN; + /* wait until the WTWF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_WTWF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET == flag_status){ + error_status = ERROR; + }else{ + error_status = SUCCESS; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief set RTC auto wakeup timer clock + \param[in] wakeup_clock: + \arg WAKEUP_RTCCK_DIV16: RTC auto wakeup timer clock is RTC clock divided by 16 + \arg WAKEUP_RTCCK_DIV8: RTC auto wakeup timer clock is RTC clock divided by 8 + \arg WAKEUP_RTCCK_DIV4: RTC auto wakeup timer clock is RTC clock divided by 4 + \arg WAKEUP_RTCCK_DIV2: RTC auto wakeup timer clock is RTC clock divided by 2 + \arg WAKEUP_CKSPRE: RTC auto wakeup timer clock is ckspre + \arg WAKEUP_CKSPRE_2EXP16: RTC auto wakeup timer clock is ckspre and wakeup timer add 2exp16 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2��0] */ + /* wait until the WTWF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_WTWF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET == flag_status){ + error_status = ERROR; + }else{ + RTC_CTL &= (uint32_t)~ RTC_CTL_WTCS; + RTC_CTL |= (uint32_t)wakeup_clock; + error_status = SUCCESS; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief set wakeup timer value + \param[in] wakeup_timer: 0x0000-0xffff + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer) +{ + ErrStatus error_status = ERROR; + volatile uint32_t time_index = RTC_WTWF_TIMEOUT; + uint32_t flag_status = RESET; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* wait until the WTWF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_WTWF; + }while((--time_index > 0U) && ((uint32_t)RESET == flag_status)); + + if ((uint32_t)RESET == flag_status){ + error_status = ERROR; + }else{ + RTC_WUT = (uint32_t)wakeup_timer; + error_status = SUCCESS; + } + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + return error_status; +} + +/*! + \brief get wakeup timer value + \param[in] none + \param[out] none + \retval wakeup timer value +*/ + uint16_t rtc_wakeup_timer_get(void) +{ + return (uint16_t)RTC_WUT; +} + +/*! + \brief configure RTC smooth calibration + \param[in] window: select calibration window + \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz + \param[in] plus: add RTC clock or not + \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock + \arg RTC_CALIBRATION_PLUS_RESET: no effect + \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus) +{ + volatile uint32_t time_index = RTC_HRFC_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a smooth calibration operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SCPF; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status){ + RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC coarse calibration + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_coarse_calibration_enable(void) +{ + ErrStatus error_status = ERROR; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_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: ERROR or SUCCESS +*/ +ErrStatus rtc_coarse_calibration_disable(void) +{ + ErrStatus error_status = ERROR; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_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: ERROR or SUCCESS +*/ +ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step) +{ + ErrStatus error_status = ERROR; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + 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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c new file mode 100644 index 0000000000..d1d0a0be32 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_sdio.c @@ -0,0 +1,803 @@ +/*! + \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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c new file mode 100644 index 0000000000..3f842251fc --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_spi.c @@ -0,0 +1,882 @@ +/*! + \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 +*/ + +/* + 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_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 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) +{ + /* enable SPI CRC */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; + + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval 16-bit CRC polynomial +*/ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + return ((uint16_t)SPI_CRCPOLY(spi_periph)); +} + +/*! + \brief turn on CRC function + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief turn off CRC function + \param[in] spi_periph: SPIx(x=0,1,2,3,4,5) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_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 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 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 enable quad wire SPI + \param[in] spi_periph: SPIx(only x=5) + \param[out] none + \retval none +*/ +void qspi_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 qspi_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 qspi_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 qspi_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 qspi_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 qspi_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} + +/*! + \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 spi_i2s_int) +{ + switch(spi_i2s_int){ + /* 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 spi_i2s_int) +{ + switch(spi_i2s_int){ + /* 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 + \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 spi_i2s_int) +{ + uint32_t reg1 = SPI_STAT(spi_periph); + uint32_t reg2 = SPI_CTL1(spi_periph); + + switch(spi_i2s_int){ + /* 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; + } +} + +/*! + \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 + \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 spi_i2s_flag) +{ + if(SPI_STAT(spi_periph) & spi_i2s_flag){ + return SET; + }else{ + return RESET; + } +} + +/*! + \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); +} + diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c new file mode 100644 index 0000000000..6fa0a776d0 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_syscfg.c @@ -0,0 +1,204 @@ +/*! + \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 +*/ + +/* + 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_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/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c new file mode 100644 index 0000000000..e312680222 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_timer.c @@ -0,0 +1,2063 @@ +/*! + \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 +*/ + +/* + 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_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 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); +} + +/*! + \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_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3OF: 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_CH0OF: channel 0 overcapture flag,TIMERx(x=0..4,7..11) + \arg TIMER_FLAG_CH1OF: channel 1 overcapture flag,TIMERx(x=0..4,7,8,11) + \arg TIMER_FLAG_CH2OF: channel 2 overcapture flag,TIMERx(x=0..4,7) + \arg TIMER_FLAG_CH3OF: 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 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 with a default value + \param[in] breakpara: TIMER break parameter struct + \param[out] none + \retval none +*/ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) +{ + /* initialize the break parameter struct member with the default value */ + breakpara->runoffstate = TIMER_ROS_STATE_DISABLE; + breakpara->ideloffstate = TIMER_IOS_STATE_DISABLE; + breakpara->deadtime = 0U; + breakpara->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 with a default value + \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_ENCODER_MODE0: encoder mode 0(TIMERx(x=0..4,7)) + \arg TIMER_ENCODER_MODE1: encoder mode 1(TIMERx(x=0..4,7)) + \arg TIMER_ENCODER_MODE2: encoder 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,8,11) + \param[in] decomode: + only one parameter can be selected which is shown as below: + \arg TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level + \arg TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level + \arg TIMER_ENCODER_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 */ + } +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_tli.c new file mode 100644 index 0000000000..9d719bb29b --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/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 +*/ + +/* + 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_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) &= ~(TLI_LxLUT_TB|TLI_LxLUT_TG|TLI_LxLUT_TR|TLI_LxLUT_TADD); + TLI_LxLUT(layerx) = (uint32_t)(((uint32_t)lut_struct->layer_lut_channel_blue)|((uint32_t)lut_struct->layer_lut_channel_green<<8U) + |((uint32_t)lut_struct->layer_lut_channel_red<<16U + |((uint32_t)lut_struct->layer_table_addr<<24U))); +} + +/*! + \brief initialize TLI layer color key + \param[in] layerx: LAYERx(x=0,1) + \param[in] redkey: color key red + \param[in] greenkey: color key green + \param[in] bluekey: color key blue + \param[out] none + \retval none +*/ +void tli_color_key_init(uint32_t layerx,uint8_t redkey,uint8_t greenkey,uint8_t bluekey) +{ + TLI_LxCKEY(layerx) = (((uint32_t)bluekey)|((uint32_t)greenkey<<8U)|((uint32_t)redkey<<16U)); +} + +/*! + \brief enable TLI layer + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_layer_enable(uint32_t layerx) +{ + TLI_LxCTL(layerx) |= TLI_LxCTL_LEN; +} + +/*! + \brief disable TLI layer + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_layer_disable(uint32_t layerx) +{ + TLI_LxCTL(layerx) &= ~(TLI_LxCTL_LEN); +} + +/*! + \brief enable TLI layer color keying + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_color_key_enable(uint32_t layerx) +{ + TLI_LxCTL(layerx) |= TLI_LxCTL_CKEYEN; +} + +/*! + \brief disable TLI layer color keying + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_color_key_disable(uint32_t layerx) +{ + TLI_LxCTL(layerx) &= ~(TLI_LxCTL_CKEYEN); +} + +/*! + \brief enable TLI layer LUT + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_lut_enable(uint32_t layerx) +{ + TLI_LxCTL(layerx) |= TLI_LxCTL_LUTEN; +} + +/*! + \brief disable TLI layer LUT + \param[in] layerx: LAYERx(x=0,1) + \param[out] none + \retval none +*/ +void tli_lut_disable(uint32_t layerx) +{ + TLI_LxCTL(layerx) &= ~(TLI_LxCTL_LUTEN); +} + +/*! + \brief set line mark value + \param[in] line_num: line number + \param[out] none + \retval none +*/ +void tli_line_mark_set(uint16_t line_num) +{ + TLI_LM &= ~(TLI_LM_LM); + TLI_LM = (uint32_t)line_num; +} + +/*! + \brief get current displayed position + \param[in] none + \param[out] none + \retval position of current pixel +*/ +uint32_t tli_current_pos_get(void) +{ + return TLI_CPPOS; +} + +/*! + \brief enable TLI interrupt + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_LM: line mark interrupt + \arg TLI_INT_FE: FIFO error interrupt + \arg TLI_INT_TE: transaction error interrupt + \arg TLI_INT_LCR: layer configuration reloaded interrupt + \param[out] none + \retval none +*/ +void tli_interrupt_enable(uint32_t int_flag) +{ + TLI_INTEN |= (int_flag); +} + +/*! + \brief disable TLI interrupt + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_LM: line mark interrupt + \arg TLI_INT_FE: FIFO error interrupt + \arg TLI_INT_TE: transaction error interrupt + \arg TLI_INT_LCR: layer configuration reloaded interrupt + \param[out] none + \retval none +*/ +void tli_interrupt_disable(uint32_t int_flag) +{ + TLI_INTEN &= ~(int_flag); +} + +/*! + \brief get TLI interrupt flag + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_FLAG_LM: line mark interrupt flag + \arg TLI_INT_FLAG_FE: FIFO error interrupt flag + \arg TLI_INT_FLAG_TE: transaction error interrupt flag + \arg TLI_INT_FLAG_LCR: layer configuration reloaded interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus tli_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t state; + state = TLI_INTF; + if(state & int_flag){ + state = TLI_INTEN; + if(state & int_flag){ + return SET; + } + } + return RESET; +} + +/*! + \brief clear TLI interrupt flag + \param[in] int_flag: TLI interrupt flags + one or more parameters can be selected which are shown as below: + \arg TLI_INT_FLAG_LM: line mark interrupt flag + \arg TLI_INT_FLAG_FE: FIFO error interrupt flag + \arg TLI_INT_FLAG_TE: transaction error interrupt flag + \arg TLI_INT_FLAG_LCR: layer configuration reloaded interrupt flag + \param[out] none + \retval none +*/ +void tli_interrupt_flag_clear(uint32_t int_flag) +{ + TLI_INTC |= (int_flag); +} + +/*! + \brief get TLI flag or state in TLI_INTF register or TLI_STAT register + \param[in] flag: TLI flags or states + only one parameter can be selected which is shown as below: + \arg TLI_FLAG_VDE: current VDE state + \arg TLI_FLAG_HDE: current HDE state + \arg TLI_FLAG_VS: current VS status of the TLI + \arg TLI_FLAG_HS: current HS status of the TLI + \arg TLI_FLAG_LM: line mark interrupt flag + \arg TLI_FLAG_FE: FIFO error interrupt flag + \arg TLI_FLAG_TE: transaction error interrupt flag + \arg TLI_FLAG_LCR: layer configuration reloaded interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus tli_flag_get(uint32_t flag) +{ + uint32_t stat; + /* choose which register to get flag or state */ + if(flag >> 31U){ + stat = TLI_INTF; + }else{ + stat = TLI_STAT; + } + if(flag & stat){ + return SET; + }else{ + return RESET; + } +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c new file mode 100644 index 0000000000..8c86bb832e --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_trng.c @@ -0,0 +1,155 @@ +/*! + \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 +*/ + +/* + 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_trng.h" + +/*! + \brief deinitialize the TRNG + \param[in] none + \param[out] none + \retval none +*/ +void trng_deinit(void) +{ + rcu_periph_reset_enable(RCU_TRNGRST); + rcu_periph_reset_disable(RCU_TRNGRST); +} + +/*! + \brief enable the TRNG interface + \param[in] none + \param[out] none + \retval none +*/ +void trng_enable(void) +{ + TRNG_CTL |= TRNG_CTL_TRNGEN; +} + +/*! + \brief disable the TRNG interface + \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 the generated random data +*/ +uint32_t trng_get_true_random_data(void) +{ + return (TRNG_DATA); +} + +/*! + \brief enable the TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_enable(void) +{ + TRNG_CTL |= TRNG_CTL_IE; +} + +/*! + \brief disable the TRNG interrupt + \param[in] none + \param[out] none + \retval none +*/ +void trng_interrupt_disable(void) +{ + TRNG_CTL &= ~TRNG_CTL_IE; +} + +/*! + \brief get the trng status flags + \param[in] flag: trng status flag, refer to trng_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_FLAG_DRDY: Random Data ready status + \arg TRNG_FLAG_CECS: Clock error current status + \arg TRNG_FLAG_SECS: Seed error current status + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus trng_flag_get(trng_flag_enum flag) +{ + if(RESET != (TRNG_STAT & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get the trng interrupt flags + \param[in] int_flag: trng interrupt flag, refer to trng_int_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag + \arg TRNG_INT_FLAG_SEIF: Seed error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag) +{ + if(RESET != (TRNG_STAT & int_flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the trng interrupt flags + \param[in] int_flag: trng interrupt flag, refer to trng_int_flag_enum + only one parameter can be selected which is shown as below: + \arg TRNG_INT_FLAG_CEIF: clock error interrupt flag + \arg TRNG_INT_FLAG_SEIF: Seed error interrupt flag + \param[out] none + \retval none +*/ +void trng_interrupt_flag_clear(trng_int_flag_enum int_flag) +{ + TRNG_STAT &= ~(uint32_t)int_flag; +} diff --git a/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c new file mode 100644 index 0000000000..1b864e3b96 --- /dev/null +++ b/bsp/gd32/libraries/GD32F4xx_HAL/GD32F4xx_standard_peripheral/Source/gd32f4xx_usart.c @@ -0,0 +1,1009 @@ +/*! + \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 +*/ + +/* + 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_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, uint32_t data) +{ + USART_DATA(usart_periph) = ((uint16_t)USART_DATA_DATA & 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 & 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) +{ + uint32_t ctl = 0U; + + /* read USART_CTL1 register */ + ctl = USART_CTL1(usart_periph); + ctl &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + /* set CK length, CK phase, CK polarity */ + ctl |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl); + + USART_CTL1(usart_periph) = ctl; +} + +/*! + \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,uint32_t guat) +{ + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat)< +#include + +#ifdef RT_USING_PIN + +#include "drv_gpio.h" + +static const struct pin_index pins[] = +{ + GD32_PIN(0, A, 0), + GD32_PIN(1, A, 1), + GD32_PIN(2, A, 2), + GD32_PIN(3, A, 3), + GD32_PIN(4, A, 4), + GD32_PIN(5, A, 5), + GD32_PIN(6, A, 6), + GD32_PIN(7, A, 7), + GD32_PIN(8, A, 8), + GD32_PIN(9, A, 9), + GD32_PIN(10, A, 10), + GD32_PIN(11, A, 11), + GD32_PIN(12, A, 12), + GD32_PIN(13, A, 13), + GD32_PIN(14, A, 14), + GD32_PIN(15, A, 15), + GD32_PIN(16, B, 0), + GD32_PIN(17, B, 1), + GD32_PIN(18, B, 2), + GD32_PIN(19, B, 3), + GD32_PIN(20, B, 4), + GD32_PIN(21, B, 5), + GD32_PIN(22, B, 6), + GD32_PIN(23, B, 7), + GD32_PIN(24, B, 8), + GD32_PIN(25, B, 9), + GD32_PIN(26, B, 10), + GD32_PIN(27, B, 11), + GD32_PIN(28, B, 12), + GD32_PIN(39, B, 13), + GD32_PIN(30, B, 14), + GD32_PIN(31, B, 15), + GD32_PIN(32, C, 0), + GD32_PIN(33, C, 1), + GD32_PIN(34, C, 2), + GD32_PIN(35, C, 3), + GD32_PIN(36, C, 4), + GD32_PIN(37, C, 5), + GD32_PIN(38, C, 6), + GD32_PIN(39, C, 7), + GD32_PIN(40, C, 8), + GD32_PIN(41, C, 9), + GD32_PIN(42, C, 10), + GD32_PIN(43, C, 11), + GD32_PIN(44, C, 12), + GD32_PIN(45, C, 13), + GD32_PIN(46, C, 14), + GD32_PIN(47, C, 15), + GD32_PIN(50, D, 2), + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN(64, F, 0), + GD32_PIN(65, F, 1), + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN(68, F, 4), + GD32_PIN(69, F, 5), + GD32_PIN(70, F, 6), + GD32_PIN(71, F, 7), + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, + GD32_PIN_DEFAULT, +}; + +static const struct pin_irq_map pin_irq_map[] = +{ + {GPIO_PIN_0, EXTI0_IRQn}, + {GPIO_PIN_1, EXTI1_IRQn}, + {GPIO_PIN_2, EXTI2_IRQn}, + {GPIO_PIN_3, EXTI3_IRQn}, + {GPIO_PIN_4, EXTI4_IRQn}, + {GPIO_PIN_5, EXTI5_9_IRQn}, + {GPIO_PIN_6, EXTI5_9_IRQn}, + {GPIO_PIN_7, EXTI5_9_IRQn}, + {GPIO_PIN_8, EXTI5_9_IRQn}, + {GPIO_PIN_9, EXTI5_9_IRQn}, + {GPIO_PIN_10, EXTI10_15_IRQn}, + {GPIO_PIN_11, EXTI10_15_IRQn}, + {GPIO_PIN_12, EXTI10_15_IRQn}, + {GPIO_PIN_13, EXTI10_15_IRQn}, + {GPIO_PIN_14, EXTI10_15_IRQn}, + {GPIO_PIN_15, EXTI10_15_IRQn}, +}; + +struct rt_pin_irq_hdr pin_irq_hdr_tab[] = +{ + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, +}; + +#define ITEM_NUM(items) sizeof(items) / sizeof(items[0]) +const struct pin_index *get_pin(rt_uint8_t pin) +{ + const struct pin_index *index; + + if (pin < ITEM_NUM(pins)) + { + index = &pins[pin]; + if (index->index == -1) + index = RT_NULL; + } + else + { + index = RT_NULL; + } + + return index; +}; + +void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) +{ + const struct pin_index *index = RT_NULL; + rt_uint32_t pin_mode = 0, pin_pupd = 0, pin_odpp = 0; + + index = get_pin(pin); + if (index == RT_NULL) + { + return; + } + + /* GPIO Periph clock enable */ + rcu_periph_clock_enable(index->clk); + pin_mode = GPIO_MODE_OUTPUT; + + switch(mode) + { + case PIN_MODE_OUTPUT: + /* output setting */ + pin_mode = GPIO_MODE_OUTPUT; + pin_pupd = GPIO_PUPD_NONE; + pin_odpp = GPIO_OTYPE_PP; + break; + case PIN_MODE_OUTPUT_OD: + /* output setting: od. */ + pin_mode = GPIO_MODE_OUTPUT; + pin_pupd = GPIO_PUPD_NONE; + pin_odpp = GPIO_OTYPE_OD; + break; + case PIN_MODE_INPUT: + /* input setting: not pull. */ + pin_mode = GPIO_MODE_INPUT; + pin_pupd = GPIO_PUPD_PULLUP | GPIO_PUPD_PULLDOWN; + break; + case PIN_MODE_INPUT_PULLUP: + /* input setting: pull up. */ + pin_mode = GPIO_MODE_INPUT; + pin_pupd = GPIO_PUPD_PULLUP; + break; + case PIN_MODE_INPUT_PULLDOWN: + /* input setting: pull down. */ + pin_mode = GPIO_MODE_INPUT; + pin_pupd = GPIO_PUPD_PULLDOWN; + break; + default: + break; + } + + gpio_mode_set(index->gpio_periph, pin_mode, pin_pupd, index->pin); + if(pin_mode == GPIO_MODE_OUTPUT) + { + gpio_output_options_set(index->gpio_periph, pin_odpp, GPIO_OSPEED_50MHZ, index->pin); + } +} + +void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) +{ + const struct pin_index *index = RT_NULL; + + index = get_pin(pin); + if (index == RT_NULL) + { + return; + } + + gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value); +} + +int gd32_pin_read(rt_device_t dev, rt_base_t pin) +{ + int value = PIN_LOW; + const struct pin_index *index = RT_NULL; + + index = get_pin(pin); + if (index == RT_NULL) + { + return value; + } + + value = gpio_input_bit_get(index->gpio_periph, index->pin); + return value; +} + +rt_inline rt_int32_t bit2bitno(rt_uint32_t bit) +{ + rt_uint8_t i; + for (i = 0; i < 32; i++) + { + if ((0x01 << i) == bit) + { + return i; + } + } + return -1; +} + +rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit) +{ + rt_int32_t map_index = bit2bitno(pinbit); + if (map_index < 0 || map_index >= ITEM_NUM(pin_irq_map)) + { + return RT_NULL; + } + return &pin_irq_map[map_index]; +}; + +rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, + rt_uint32_t mode, void (*hdr)(void *args), void *args) +{ + const struct pin_index *index = RT_NULL; + rt_base_t level; + rt_int32_t hdr_index = -1; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == pin && + pin_irq_hdr_tab[hdr_index].hdr == hdr && + pin_irq_hdr_tab[hdr_index].mode == mode && + pin_irq_hdr_tab[hdr_index].args == args) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + if (pin_irq_hdr_tab[hdr_index].pin != -1) + { + rt_hw_interrupt_enable(level); + return RT_EFULL; + } + pin_irq_hdr_tab[hdr_index].pin = pin; + pin_irq_hdr_tab[hdr_index].hdr = hdr; + pin_irq_hdr_tab[hdr_index].mode = mode; + pin_irq_hdr_tab[hdr_index].args = args; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + const struct pin_index *index = RT_NULL; + rt_base_t level; + rt_int32_t hdr_index = -1; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + pin_irq_hdr_tab[hdr_index].pin = -1; + pin_irq_hdr_tab[hdr_index].hdr = RT_NULL; + pin_irq_hdr_tab[hdr_index].mode = 0; + pin_irq_hdr_tab[hdr_index].args = RT_NULL; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} + +rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +{ + const struct pin_index *index; + const struct pin_irq_map *irqmap; + rt_base_t level; + rt_int32_t hdr_index = -1; + exti_trig_type_enum trigger_mode; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + + if (enabled == PIN_IRQ_ENABLE) + { + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EINVAL; + } + + irqmap = &pin_irq_map[hdr_index]; + + switch (pin_irq_hdr_tab[hdr_index].mode) + { + case PIN_IRQ_MODE_RISING: + trigger_mode = EXTI_TRIG_RISING; + break; + case PIN_IRQ_MODE_FALLING: + trigger_mode = EXTI_TRIG_FALLING; + break; + case PIN_IRQ_MODE_RISING_FALLING: + trigger_mode = EXTI_TRIG_BOTH; + break; + default: + rt_hw_interrupt_enable(level); + return RT_EINVAL; + } + + rcu_periph_clock_enable(RCU_SYSCFG); + + /* enable and set interrupt priority */ + nvic_irq_enable(irqmap->irqno, 5U, 0U); + + /* connect EXTI line to GPIO pin */ + syscfg_exti_line_config(index->port_src, index->pin_src); + + /* configure EXTI line */ + exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode); + exti_interrupt_flag_clear((exti_line_enum)(index->pin)); + + rt_hw_interrupt_enable(level); + } + else if (enabled == PIN_IRQ_DISABLE) + { + irqmap = get_pin_irq_map(index->pin); + if (irqmap == RT_NULL) + { + return RT_EINVAL; + } + nvic_irq_disable(irqmap->irqno); + } + else + { + return RT_EINVAL; + } + + return RT_EOK; +} + +const static struct rt_pin_ops gd32_pin_ops = +{ + gd32_pin_mode, + gd32_pin_write, + gd32_pin_read, + gd32_pin_attach_irq, + gd32_pin_detach_irq, + gd32_pin_irq_enable, + RT_NULL, +}; + +rt_inline void pin_irq_hdr(int irqno) +{ + if (pin_irq_hdr_tab[irqno].hdr) + { + pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args); + } +} + +void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line) +{ + if(RESET != exti_interrupt_flag_get((exti_line_enum)(1 << exti_line))) + { + pin_irq_hdr(exti_line); + exti_interrupt_flag_clear((exti_line_enum)(1 << exti_line)); + } +} + +void EXTI0_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(0); + rt_interrupt_leave(); +} + +void EXTI1_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(1); + rt_interrupt_leave(); +} + +void EXTI2_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(2); + rt_interrupt_leave(); +} + +void EXTI3_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(3); + rt_interrupt_leave(); +} + +void EXTI4_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(4); + rt_interrupt_leave(); +} + +void EXTI5_9_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(5); + GD32_GPIO_EXTI_IRQHandler(6); + GD32_GPIO_EXTI_IRQHandler(7); + GD32_GPIO_EXTI_IRQHandler(8); + GD32_GPIO_EXTI_IRQHandler(9); + rt_interrupt_leave(); +} + +void EXTI10_15_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(10); + GD32_GPIO_EXTI_IRQHandler(11); + GD32_GPIO_EXTI_IRQHandler(12); + GD32_GPIO_EXTI_IRQHandler(13); + GD32_GPIO_EXTI_IRQHandler(14); + GD32_GPIO_EXTI_IRQHandler(15); + rt_interrupt_leave(); +} + +int rt_hw_pin_init(void) +{ + int result; + + result = rt_device_pin_register("pin", &gd32_pin_ops, RT_NULL); + + return result; +} +INIT_BOARD_EXPORT(rt_hw_pin_init); + +#endif diff --git a/bsp/gd32/libraries/HAL_Drivers/drv_gpio.h b/bsp/gd32/libraries/HAL_Drivers/drv_gpio.h new file mode 100644 index 0000000000..5b6e32d69b --- /dev/null +++ b/bsp/gd32/libraries/HAL_Drivers/drv_gpio.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-20 BruceOu the first version + */ + +#ifndef __DRV_GPIO_H__ +#define __DRV_GPIO_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPIOA_BASE (GPIO_BASE + 0x00000800UL) +#define GPIOB_BASE (GPIO_BASE + 0x00000C00UL) +#define GPIOC_BASE (GPIO_BASE + 0x00001000UL) +#define GPIOD_BASE (GPIO_BASE + 0x00001400UL) +#define GPIOE_BASE (GPIO_BASE + 0x00001800UL) +#define GPIOF_BASE (GPIO_BASE + 0x00001C00UL) +#define GPIOG_BASE (GPIO_BASE + 0x00002000UL) + +#define __GD32_PORT(port) GPIO##port##_BASE + +#define GD32_PIN(index, port, pin) {index, RCU_GPIO##port, \ + GPIO##port, GPIO_PIN_##pin, \ + EXTI_SOURCE_GPIO##port, \ + EXTI_SOURCE_PIN##pin} +#define GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0, 0, 0} + +#define GET_PIN(PORTx, PIN) (rt_base_t)((16 * ( ((rt_base_t)__GD32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN) + +struct pin_index +{ + rt_int16_t index; + rcu_periph_enum clk; + rt_uint32_t gpio_periph; + rt_uint32_t pin; + rt_uint8_t port_src; + rt_uint8_t pin_src; +}; + +struct pin_irq_map +{ + rt_uint16_t pinbit; + IRQn_Type irqno; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __DRV_GPIO_H__ */ + diff --git a/bsp/gd32/libraries/HAL_Drivers/drv_usart.c b/bsp/gd32/libraries/HAL_Drivers/drv_usart.c new file mode 100644 index 0000000000..283eb47de3 --- /dev/null +++ b/bsp/gd32/libraries/HAL_Drivers/drv_usart.c @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-20 BruceOu first implementation + */ +#include "drv_usart.h" +#include + +#ifdef RT_USING_SERIAL + +#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && \ + !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) && \ + !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && \ + !defined(BSP_USING_UART6) && !defined(BSP_USING_UART7) +#error "Please define at least one UARTx" + +#endif + +#include + +/* GD32 uart driver */ +// Todo: compress uart info +struct gd32_uart +{ + uint32_t uart_periph; //Todo: 3bits + IRQn_Type irqn; //Todo: 7bits + rcu_periph_enum per_clk; //Todo: 5bits + rcu_periph_enum tx_gpio_clk; //Todo: 5bits + rcu_periph_enum rx_gpio_clk; //Todo: 5bits + uint32_t tx_port; //Todo: 4bits + uint16_t tx_af; //Todo: 4bits + uint16_t tx_pin; //Todo: 4bits + uint32_t rx_port; //Todo: 4bits + uint16_t rx_af; //Todo: 4bits + uint16_t rx_pin; //Todo: 4bits + + struct rt_serial_device * serial; + char *device_name; +}; + +static void uart_isr(struct rt_serial_device *serial); + +#if defined(BSP_USING_UART0) +struct rt_serial_device serial0; + +void USART0_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial0); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* BSP_USING_UART0 */ + +#if defined(BSP_USING_UART1) +struct rt_serial_device serial1; + +void USART1_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial1); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* BSP_USING_UART1 */ + +#if defined(BSP_USING_UART2) +struct rt_serial_device serial2; + +void USART2_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial2); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* BSP_USING_UART2 */ + +#if defined(BSP_USING_UART3) +struct rt_serial_device serial3; + +void UART3_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial3); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* BSP_USING_UART3 */ + +#if defined(BSP_USING_UART4) +struct rt_serial_device serial4; + +void UART4_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial4); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* BSP_USING_UART4 */ + +#if defined(BSP_USING_UART5) +struct rt_serial_device serial5; + +void USART5_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial5); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* BSP_USING_UART5 */ + +#if defined(BSP_USING_UART6) +struct rt_serial_device serial6; + +void UART6_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial6); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* BSP_USING_UART6 */ + +#if defined(BSP_USING_UART7) +struct rt_serial_device serial7; + +void UART7_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial7); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* BSP_USING_UART7 */ + +static const struct gd32_uart uarts[] = { + #ifdef BSP_USING_UART0 + { + USART0, // uart peripheral index + USART0_IRQn, // uart iqrn + RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_AF_7, GPIO_PIN_9, // tx port, tx alternate, tx pin + GPIOA, GPIO_AF_7, GPIO_PIN_10, // rx port, rx alternate, rx pin + &serial0, + "uart0", + }, + #endif + + #ifdef BSP_USING_UART1 + { + USART1, // uart peripheral index + USART1_IRQn, // uart iqrn + RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_AF_7, GPIO_PIN_2, // tx port, tx alternate, tx pin + GPIOA, GPIO_AF_7, GPIO_PIN_3, // rx port, rx alternate, rx pin + &serial1, + "uart1", + }, + #endif + + #ifdef BSP_USING_UART2 + { + USART2, // uart peripheral index + USART2_IRQn, // uart iqrn + RCU_USART2, RCU_GPIOB, RCU_GPIOB, // periph clock, tx gpio clock, rt gpio clock + GPIOB, GPIO_AF_7, GPIO_PIN_10, // tx port, tx alternate, tx pin + GPIOB, GPIO_AF_7, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial2, + "uart2", + }, + #endif + + #ifdef BSP_USING_UART3 + { + UART3, // uart peripheral index + UART3_IRQn, // uart iqrn + RCU_UART3, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_AF_8, GPIO_PIN_10, // tx port, tx alternate, tx pin + GPIOC, GPIO_AF_8, GPIO_PIN_11, // rx port, rx alternate, rx pin + &serial3, + "uart3", + }, + #endif + + #ifdef BSP_USING_UART4 + { + UART4, // uart peripheral index + UART4_IRQn, // uart iqrn + RCU_UART4, RCU_GPIOC, RCU_GPIOD, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_AF_8, GPIO_PIN_12, // tx port, tx alternate, tx pin + GPIOD, GPIO_AF_8, GPIO_PIN_2, // rx port, rx alternate, rx pin + &serial4, + "uart4", + }, + #endif + + #ifdef BSP_USING_UART5 + { + USART5, // uart peripheral index + USART5_IRQn, // uart iqrn + RCU_USART5, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock + GPIOC, GPIO_AF_8, GPIO_PIN_6, // tx port, tx alternate, tx pin + GPIOC, GPIO_AF_8, GPIO_PIN_7, // rx port, rx alternate, rx pin + &serial5, + "uart5", + }, + #endif + + #ifdef BSP_USING_UART6 + { + UART6, // uart peripheral index + UART6_IRQn, // uart iqrn + RCU_UART6, RCU_GPIOE, RCU_GPIOE, // periph clock, tx gpio clock, rt gpio clock + GPIOE, GPIO_AF_8, GPIO_PIN_7, // tx port, tx alternate, tx pin + GPIOE, GPIO_AF_8, GPIO_PIN_8, // rx port, rx alternate, rx pin + &serial6, + "uart6", + }, + #endif + + #ifdef BSP_USING_UART7 + { + UART7, // uart peripheral index + UART7_IRQn, // uart iqrn + RCU_UART7, RCU_GPIOE, RCU_GPIOE, // periph clock, tx gpio clock, rt gpio clock + GPIOE, GPIO_AF_8, GPIO_PIN_0, // tx port, tx alternate, tx pin + GPIOE, GPIO_AF_8, GPIO_PIN_1, // rx port, rx alternate, rx pin + &serial7, + "uart7", + }, + #endif +}; + + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example: +* - Peripheral's clock enable +* - Peripheral's GPIO Configuration +* - NVIC configuration for UART interrupt request enable +* @param huart: UART handle pointer +* @retval None +*/ +void gd32_uart_gpio_init(struct gd32_uart *uart) +{ + /* enable USART clock */ + rcu_periph_clock_enable(uart->tx_gpio_clk); + rcu_periph_clock_enable(uart->rx_gpio_clk); + rcu_periph_clock_enable(uart->per_clk); + + /* connect port to USARTx_Tx */ + gpio_af_set(uart->tx_port, uart->tx_af, uart->tx_pin); + + /* connect port to USARTx_Rx */ + gpio_af_set(uart->rx_port, uart->rx_af, uart->rx_pin); + + /* configure USART Tx as alternate function push-pull */ + gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->tx_pin); + gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->tx_pin); + + /* configure USART Rx as alternate function push-pull */ + gpio_mode_set(uart->rx_port, GPIO_MODE_AF, GPIO_PUPD_PULLUP, uart->rx_pin); + gpio_output_options_set(uart->rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, uart->rx_pin); + + NVIC_SetPriority(uart->irqn, 0); + NVIC_EnableIRQ(uart->irqn); +} + +static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart = (struct gd32_uart *)serial->parent.user_data; + + gd32_uart_gpio_init(uart); + + usart_baudrate_set(uart->uart_periph, cfg->baud_rate); + + switch (cfg->data_bits) + { + case DATA_BITS_9: + usart_word_length_set(uart->uart_periph, USART_WL_9BIT); + break; + + default: + usart_word_length_set(uart->uart_periph, USART_WL_8BIT); + break; + } + + switch (cfg->stop_bits) + { + case STOP_BITS_2: + usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT); + break; + default: + usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT); + break; + } + + switch (cfg->parity) + { + case PARITY_ODD: + usart_parity_config(uart->uart_periph, USART_PM_ODD); + break; + case PARITY_EVEN: + usart_parity_config(uart->uart_periph, USART_PM_EVEN); + break; + default: + usart_parity_config(uart->uart_periph, USART_PM_NONE); + break; + } + + usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE); + usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE); + usart_enable(uart->uart_periph); + + return RT_EOK; +} + +static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + NVIC_DisableIRQ(uart->irqn); + /* disable interrupt */ + usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE); + + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + NVIC_EnableIRQ(uart->irqn); + /* enable interrupt */ + usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE); + break; + } + + return RT_EOK; +} + +static int gd32_putc(struct rt_serial_device *serial, char ch) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + usart_data_transmit(uart->uart_periph, ch); + while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET)); + + return 1; +} + +static int gd32_getc(struct rt_serial_device *serial) +{ + int ch; + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + ch = -1; + if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET) + ch = usart_data_receive(uart->uart_periph); + return ch; +} + +/** + * Uart common interrupt process. This need add to uart ISR. + * + * @param serial serial device + */ +static void uart_isr(struct rt_serial_device *serial) +{ + struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + /* UART in mode Receiver -------------------------------------------------*/ + if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) && + (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + /* Clear RXNE interrupt flag */ + usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE); + } +} + +static const struct rt_uart_ops gd32_uart_ops = +{ + gd32_configure, + gd32_control, + gd32_putc, + gd32_getc, +}; + +int gd32_hw_usart_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + int i; + + + for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++) + { + uarts[i].serial->ops = &gd32_uart_ops; + uarts[i].serial->config = config; + + /* register UART1 device */ + rt_hw_serial_register(uarts[i].serial, + uarts[i].device_name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + (void *)&uarts[i]); + } + + return 0; +} +INIT_BOARD_EXPORT(gd32_hw_usart_init); +#endif diff --git a/bsp/gd32/libraries/HAL_Drivers/drv_usart.h b/bsp/gd32/libraries/HAL_Drivers/drv_usart.h new file mode 100644 index 0000000000..a07b0bafce --- /dev/null +++ b/bsp/gd32/libraries/HAL_Drivers/drv_usart.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-08-20 BruceOu first implementation + */ + +#ifndef __USART_H__ +#define __USART_H__ + +#include +#include + +#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) +#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) + +int gd32_hw_usart_init(void); + +#endif diff --git a/bsp/gd32/libraries/Kconfig b/bsp/gd32/libraries/Kconfig new file mode 100644 index 0000000000..eb9a1a9736 --- /dev/null +++ b/bsp/gd32/libraries/Kconfig @@ -0,0 +1,7 @@ +config SOC_FAMILY_GD32 + bool + +config SOC_SERIES_GD32F4 + bool + select ARCH_ARM_CORTEX_M4 + select SOC_FAMILY_GD32 diff --git a/bsp/gd32/tools/sdk_dist.py b/bsp/gd32/tools/sdk_dist.py new file mode 100644 index 0000000000..cc5ccce7c6 --- /dev/null +++ b/bsp/gd32/tools/sdk_dist.py @@ -0,0 +1,22 @@ +import os +import sys +import shutil + +cwd_path = os.getcwd() +sys.path.append(os.path.join(os.path.dirname(cwd_path), 'rt-thread', 'tools')) + + +# BSP dist function +def dist_do_building(BSP_ROOT, dist_dir): + from mkdist import bsp_copy_files + import rtconfig + + print("=> copy gd32 bsp library") + library_dir = os.path.join(dist_dir, 'libraries') + library_path = os.path.join(os.path.dirname(BSP_ROOT), 'libraries') + bsp_copy_files(os.path.join(library_path, rtconfig.BSP_LIBRARY_TYPE), + os.path.join(library_dir, rtconfig.BSP_LIBRARY_TYPE)) + + print("=> copy bsp drivers") + bsp_copy_files(os.path.join(library_path, 'HAL_Drivers'), os.path.join(library_dir, 'HAL_Drivers')) + shutil.copyfile(os.path.join(library_path, 'Kconfig'), os.path.join(library_dir, 'Kconfig')) diff --git a/bsp/stm32/stm32f746-st-nucleo/README.md b/bsp/stm32/stm32f746-st-nucleo/README.md index cf99b63464..ff13904cd0 100644 --- a/bsp/stm32/stm32f746-st-nucleo/README.md +++ b/bsp/stm32/stm32f746-st-nucleo/README.md @@ -4,7 +4,7 @@ ## MCU: STM32F746ZG @216MHz, 1MB FLASH, 320KB RAM -he STM32 Nucleo-144 board provides an affordable and flexible way for users to try out new concepts and build prototypes by choosing from the various combinations of performance and power consumption features, provided by the STM32 microcontroller. For the compatible boards, the internal or external SMPS significantly reduces power consumption in Run mode. +The STM32 Nucleo-144 board provides an affordable and flexible way for users to try out new concepts and build prototypes by choosing from the various combinations of performance and power consumption features, provided by the STM32 microcontroller. For the compatible boards, the internal or external SMPS significantly reduces power consumption in Run mode. ![board](figures/en.high-perf_nucleo-144_mbed.jpg) @@ -52,4 +52,3 @@ The STM32 Nucleo-144 board comes with the STM32 comprehensive free software lib - From f1fd03c3fc91d787643fd7e3bc6d14b2a3a99993 Mon Sep 17 00:00:00 2001 From: Ouxiaolong <1576690133@qq.com> Date: Sat, 4 Sep 2021 09:48:56 +0800 Subject: [PATCH 2/6] add gd32407v-start --- bsp/gd32/gd32407v-start/README.md | 2 +- bsp/gd32/gd32407v-start/board/Kconfig | 2 +- bsp/gd32/gd32407v-start/board/SConscript | 2 - bsp/gd32/gd32407v-start/project.uvoptx | 442 ++++++++------------- bsp/gd32/gd32407v-start/project.uvprojx | 219 ++++------ bsp/gd32/libraries/HAL_Drivers/Kconfig | 36 -- bsp/gd32/libraries/HAL_Drivers/drv_gpio.c | 46 +-- bsp/gd32/libraries/HAL_Drivers/drv_usart.c | 24 +- 8 files changed, 275 insertions(+), 498 deletions(-) diff --git a/bsp/gd32/gd32407v-start/README.md b/bsp/gd32/gd32407v-start/README.md index a95a715158..31a3403810 100644 --- a/bsp/gd32/gd32407v-start/README.md +++ b/bsp/gd32/gd32407v-start/README.md @@ -39,7 +39,7 @@ GD32407V-STARTL是-兆易创新推出的一款GD32F4XX系列的评估板,最 ### 快速上手 -本 BSP 为开发者提供 MDK5 和 IAR 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。 +本 BSP 为开发者提供 MDK5 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。 #### 硬件连接 diff --git a/bsp/gd32/gd32407v-start/board/Kconfig b/bsp/gd32/gd32407v-start/board/Kconfig index 4bf9b828c3..190489eaa9 100644 --- a/bsp/gd32/gd32407v-start/board/Kconfig +++ b/bsp/gd32/gd32407v-start/board/Kconfig @@ -2,7 +2,7 @@ menu "Hardware Drivers Config" config SOC_GD32407V bool - select SOC_SERIES_GD32F4 + select SOC_SERIES_GD32F4 select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN default y diff --git a/bsp/gd32/gd32407v-start/board/SConscript b/bsp/gd32/gd32407v-start/board/SConscript index fa88754d91..0e2bf06321 100644 --- a/bsp/gd32/gd32407v-start/board/SConscript +++ b/bsp/gd32/gd32407v-start/board/SConscript @@ -19,8 +19,6 @@ if rtconfig.CROSS_TOOL == 'gcc': src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S'] elif rtconfig.CROSS_TOOL == 'keil': src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s'] -elif rtconfig.CROSS_TOOL == 'iar': - src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s'] CPPDEFINES = ['GD3232F407xx'] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) diff --git a/bsp/gd32/gd32407v-start/project.uvoptx b/bsp/gd32/gd32407v-start/project.uvoptx index 88b9d8ef78..b6bd27ba2c 100644 --- a/bsp/gd32/gd32407v-start/project.uvoptx +++ b/bsp/gd32/gd32407v-start/project.uvoptx @@ -224,8 +224,8 @@ 0 0 0 - ..\..\..\libcpu\arm\common\backtrace.c - backtrace.c + ..\..\..\libcpu\arm\common\div0.c + div0.c 0 0 @@ -236,8 +236,8 @@ 0 0 0 - ..\..\..\libcpu\arm\common\div0.c - div0.c + ..\..\..\libcpu\arm\common\backtrace.c + backtrace.c 0 0 @@ -304,8 +304,8 @@ 0 0 0 - ..\..\..\components\drivers\src\ringblk_buf.c - ringblk_buf.c + ..\..\..\components\drivers\src\completion.c + completion.c 0 0 @@ -316,8 +316,8 @@ 0 0 0 - ..\..\..\components\drivers\src\pipe.c - pipe.c + ..\..\..\components\drivers\src\workqueue.c + workqueue.c 0 0 @@ -328,8 +328,8 @@ 0 0 0 - ..\..\..\components\drivers\src\waitqueue.c - waitqueue.c + ..\..\..\components\drivers\src\dataqueue.c + dataqueue.c 0 0 @@ -352,8 +352,8 @@ 0 0 0 - ..\..\..\components\drivers\src\completion.c - completion.c + ..\..\..\components\drivers\src\pipe.c + pipe.c 0 0 @@ -364,8 +364,8 @@ 0 0 0 - ..\..\..\components\drivers\src\workqueue.c - workqueue.c + ..\..\..\components\drivers\src\waitqueue.c + waitqueue.c 0 0 @@ -376,8 +376,8 @@ 0 0 0 - ..\..\..\components\drivers\src\dataqueue.c - dataqueue.c + ..\..\..\components\drivers\src\ringblk_buf.c + ringblk_buf.c 0 0 @@ -385,7 +385,7 @@ Drivers - 1 + 0 0 0 0 @@ -440,7 +440,7 @@ - finsh + Finsh 0 0 0 @@ -452,8 +452,8 @@ 0 0 0 - ..\..\..\components\finsh\finsh_node.c - finsh_node.c + ..\..\..\components\finsh\shell.c + shell.c 0 0 @@ -464,143 +464,11 @@ 0 0 0 - ..\..\..\components\finsh\finsh_parser.c - finsh_parser.c - 0 - 0 - - - 5 - 22 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\cmd.c - cmd.c - 0 - 0 - - - 5 - 23 - 1 - 0 - 0 - 0 ..\..\..\components\finsh\msh.c msh.c 0 0 - - 5 - 24 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_vm.c - finsh_vm.c - 0 - 0 - - - 5 - 25 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\shell.c - shell.c - 0 - 0 - - - 5 - 26 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_var.c - finsh_var.c - 0 - 0 - - - 5 - 27 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_compiler.c - finsh_compiler.c - 0 - 0 - - - 5 - 28 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_heap.c - finsh_heap.c - 0 - 0 - - - 5 - 29 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_ops.c - finsh_ops.c - 0 - 0 - - - 5 - 30 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_error.c - finsh_error.c - 0 - 0 - - - 5 - 31 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_token.c - finsh_token.c - 0 - 0 - - - 5 - 32 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\finsh_init.c - finsh_init.c - 0 - 0 - @@ -611,139 +479,19 @@ 0 6 - 33 + 22 1 0 0 0 - ..\..\..\src\thread.c - thread.c + ..\..\..\src\object.c + object.c 0 0 6 - 34 - 1 - 0 - 0 - 0 - ..\..\..\src\timer.c - timer.c - 0 - 0 - - - 6 - 35 - 1 - 0 - 0 - 0 - ..\..\..\src\clock.c - clock.c - 0 - 0 - - - 6 - 36 - 1 - 0 - 0 - 0 - ..\..\..\src\components.c - components.c - 0 - 0 - - - 6 - 37 - 1 - 0 - 0 - 0 - ..\..\..\src\device.c - device.c - 0 - 0 - - - 6 - 38 - 1 - 0 - 0 - 0 - ..\..\..\src\scheduler.c - scheduler.c - 0 - 0 - - - 6 - 39 - 1 - 0 - 0 - 0 - ..\..\..\src\mem.c - mem.c - 0 - 0 - - - 6 - 40 - 1 - 0 - 0 - 0 - ..\..\..\src\mempool.c - mempool.c - 0 - 0 - - - 6 - 41 - 1 - 0 - 0 - 0 - ..\..\..\src\idle.c - idle.c - 0 - 0 - - - 6 - 42 - 1 - 0 - 0 - 0 - ..\..\..\src\ipc.c - ipc.c - 0 - 0 - - - 6 - 43 - 1 - 0 - 0 - 0 - ..\..\..\src\kservice.c - kservice.c - 0 - 0 - - - 6 - 44 + 23 1 0 0 @@ -755,13 +503,133 @@ 6 - 45 + 24 1 0 0 0 - ..\..\..\src\object.c - object.c + ..\..\..\src\mempool.c + mempool.c + 0 + 0 + + + 6 + 25 + 1 + 0 + 0 + 0 + ..\..\..\src\timer.c + timer.c + 0 + 0 + + + 6 + 26 + 1 + 0 + 0 + 0 + ..\..\..\src\components.c + components.c + 0 + 0 + + + 6 + 27 + 1 + 0 + 0 + 0 + ..\..\..\src\kservice.c + kservice.c + 0 + 0 + + + 6 + 28 + 1 + 0 + 0 + 0 + ..\..\..\src\idle.c + idle.c + 0 + 0 + + + 6 + 29 + 1 + 0 + 0 + 0 + ..\..\..\src\mem.c + mem.c + 0 + 0 + + + 6 + 30 + 1 + 0 + 0 + 0 + ..\..\..\src\device.c + device.c + 0 + 0 + + + 6 + 31 + 1 + 0 + 0 + 0 + ..\..\..\src\ipc.c + ipc.c + 0 + 0 + + + 6 + 32 + 1 + 0 + 0 + 0 + ..\..\..\src\thread.c + thread.c + 0 + 0 + + + 6 + 33 + 1 + 0 + 0 + 0 + ..\..\..\src\clock.c + clock.c + 0 + 0 + + + 6 + 34 + 1 + 0 + 0 + 0 + ..\..\..\src\scheduler.c + scheduler.c 0 0 @@ -775,7 +643,7 @@ 0 7 - 46 + 35 1 0 0 @@ -795,7 +663,7 @@ 0 8 - 47 + 36 1 0 0 @@ -807,7 +675,7 @@ 8 - 48 + 37 1 0 0 @@ -819,7 +687,7 @@ 8 - 49 + 38 1 0 0 @@ -831,7 +699,7 @@ 8 - 50 + 39 1 0 0 @@ -843,7 +711,7 @@ 8 - 51 + 40 1 0 0 @@ -855,7 +723,7 @@ 8 - 52 + 41 1 0 0 @@ -867,7 +735,7 @@ 8 - 53 + 42 1 0 0 diff --git a/bsp/gd32/gd32407v-start/project.uvprojx b/bsp/gd32/gd32407v-start/project.uvprojx index 64c3b12177..bc6d9b4142 100644 --- a/bsp/gd32/gd32407v-start/project.uvprojx +++ b/bsp/gd32/gd32407v-start/project.uvprojx @@ -398,16 +398,16 @@ 1 ..\..\..\libcpu\arm\common\showmem.c - - backtrace.c - 1 - ..\..\..\libcpu\arm\common\backtrace.c - div0.c 1 ..\..\..\libcpu\arm\common\div0.c + + backtrace.c + 1 + ..\..\..\libcpu\arm\common\backtrace.c + cpuport.c 1 @@ -433,26 +433,6 @@ 1 ..\..\..\components\drivers\serial\serial.c - - ringblk_buf.c - 1 - ..\..\..\components\drivers\src\ringblk_buf.c - - - pipe.c - 1 - ..\..\..\components\drivers\src\pipe.c - - - waitqueue.c - 1 - ..\..\..\components\drivers\src\waitqueue.c - - - ringbuffer.c - 1 - ..\..\..\components\drivers\src\ringbuffer.c - completion.c 1 @@ -468,6 +448,26 @@ 1 ..\..\..\components\drivers\src\dataqueue.c + + ringbuffer.c + 1 + ..\..\..\components\drivers\src\ringbuffer.c + + + pipe.c + 1 + ..\..\..\components\drivers\src\pipe.c + + + waitqueue.c + 1 + ..\..\..\components\drivers\src\waitqueue.c + + + ringblk_buf.c + 1 + ..\..\..\components\drivers\src\ringblk_buf.c + @@ -496,72 +496,17 @@ - finsh + Finsh - - finsh_node.c - 1 - ..\..\..\components\finsh\finsh_node.c - - - finsh_parser.c - 1 - ..\..\..\components\finsh\finsh_parser.c - - - cmd.c - 1 - ..\..\..\components\finsh\cmd.c - - - msh.c - 1 - ..\..\..\components\finsh\msh.c - - - finsh_vm.c - 1 - ..\..\..\components\finsh\finsh_vm.c - shell.c 1 ..\..\..\components\finsh\shell.c - finsh_var.c + msh.c 1 - ..\..\..\components\finsh\finsh_var.c - - - finsh_compiler.c - 1 - ..\..\..\components\finsh\finsh_compiler.c - - - finsh_heap.c - 1 - ..\..\..\components\finsh\finsh_heap.c - - - finsh_ops.c - 1 - ..\..\..\components\finsh\finsh_ops.c - - - finsh_error.c - 1 - ..\..\..\components\finsh\finsh_error.c - - - finsh_token.c - 1 - ..\..\..\components\finsh\finsh_token.c - - - finsh_init.c - 1 - ..\..\..\components\finsh\finsh_init.c + ..\..\..\components\finsh\msh.c @@ -569,59 +514,9 @@ Kernel - thread.c + object.c 1 - ..\..\..\src\thread.c - - - timer.c - 1 - ..\..\..\src\timer.c - - - clock.c - 1 - ..\..\..\src\clock.c - - - components.c - 1 - ..\..\..\src\components.c - - - device.c - 1 - ..\..\..\src\device.c - - - scheduler.c - 1 - ..\..\..\src\scheduler.c - - - mem.c - 1 - ..\..\..\src\mem.c - - - mempool.c - 1 - ..\..\..\src\mempool.c - - - idle.c - 1 - ..\..\..\src\idle.c - - - ipc.c - 1 - ..\..\..\src\ipc.c - - - kservice.c - 1 - ..\..\..\src\kservice.c + ..\..\..\src\object.c irq.c @@ -629,9 +524,59 @@ ..\..\..\src\irq.c - object.c + mempool.c 1 - ..\..\..\src\object.c + ..\..\..\src\mempool.c + + + timer.c + 1 + ..\..\..\src\timer.c + + + components.c + 1 + ..\..\..\src\components.c + + + kservice.c + 1 + ..\..\..\src\kservice.c + + + idle.c + 1 + ..\..\..\src\idle.c + + + mem.c + 1 + ..\..\..\src\mem.c + + + device.c + 1 + ..\..\..\src\device.c + + + ipc.c + 1 + ..\..\..\src\ipc.c + + + thread.c + 1 + ..\..\..\src\thread.c + + + clock.c + 1 + ..\..\..\src\clock.c + + + scheduler.c + 1 + ..\..\..\src\scheduler.c diff --git a/bsp/gd32/libraries/HAL_Drivers/Kconfig b/bsp/gd32/libraries/HAL_Drivers/Kconfig index 41cf5cf08b..93e9ecd88f 100644 --- a/bsp/gd32/libraries/HAL_Drivers/Kconfig +++ b/bsp/gd32/libraries/HAL_Drivers/Kconfig @@ -24,39 +24,3 @@ if BSP_USING_USBD # "ULPI: UTMI+ Low Pin Interface" endif -config BSP_USING_CRC - bool "Enable CRC (CRC-32 0x04C11DB7 Polynomial)" - select RT_USING_HWCRYPTO - select RT_HWCRYPTO_USING_CRC - # "Crypto device frame dose not support above 8-bits granularity" - # "Reserve progress, running well, about 32-bits granularity, such as stm32f1, stm32f4" - depends on (SOC_SERIES_STM32L4 || SOC_SERIES_STM32F0 || SOC_SERIES_STM32F7 || SOC_SERIES_STM32H7 || SOC_SERIES_STM32MP1) - default n - -config BSP_USING_RNG - bool "Enable RNG (Random Number Generator)" - select RT_USING_HWCRYPTO - select RT_HWCRYPTO_USING_RNG - depends on (SOC_SERIES_STM32L4 || SOC_SERIES_STM32F4 || SOC_SERIES_STM32F7 || \ - SOC_SERIES_STM32H7 || SOC_SERIES_STM32MP1) - default n - -config BSP_USING_HASH - bool "Enable HASH (Hash House Harriers)" - select RT_USING_HWCRYPTO - select RT_HWCRYPTO_USING_HASH - depends on (SOC_SERIES_STM32MP1) - default n - -config BSP_USING_CRYP - bool "Enable CRYP (Encrypt And Decrypt Data)" - select RT_USING_HWCRYPTO - select RT_HWCRYPTO_USING_CRYP - depends on (SOC_SERIES_STM32MP1) - default n - -config BSP_USING_UDID - bool "Enable UDID (Unique Device Identifier)" - select RT_USING_HWCRYPTO - default n - diff --git a/bsp/gd32/libraries/HAL_Drivers/drv_gpio.c b/bsp/gd32/libraries/HAL_Drivers/drv_gpio.c index 1fc7339643..3ff4282c82 100644 --- a/bsp/gd32/libraries/HAL_Drivers/drv_gpio.c +++ b/bsp/gd32/libraries/HAL_Drivers/drv_gpio.c @@ -156,7 +156,7 @@ const struct pin_index *get_pin(rt_uint8_t pin) return index; }; -void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) +static void _pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) { const struct pin_index *index = RT_NULL; rt_uint32_t pin_mode = 0, pin_pupd = 0, pin_odpp = 0; @@ -211,7 +211,7 @@ void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) } } -void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) +static void _pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) { const struct pin_index *index = RT_NULL; @@ -224,7 +224,7 @@ void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value); } -int gd32_pin_read(rt_device_t dev, rt_base_t pin) +static int _pin_read(rt_device_t dev, rt_base_t pin) { int value = PIN_LOW; const struct pin_index *index = RT_NULL; @@ -262,7 +262,7 @@ rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit) return &pin_irq_map[map_index]; }; -rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, +static rt_err_t _pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) { const struct pin_index *index = RT_NULL; @@ -272,13 +272,13 @@ rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, index = get_pin(pin); if (index == RT_NULL) { - return RT_EINVAL; + return -RT_EINVAL; } hdr_index = bit2bitno(index->pin); if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) { - return RT_EINVAL; + return -RT_EINVAL; } level = rt_hw_interrupt_disable(); @@ -293,7 +293,7 @@ rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, if (pin_irq_hdr_tab[hdr_index].pin != -1) { rt_hw_interrupt_enable(level); - return RT_EFULL; + return -RT_EFULL; } pin_irq_hdr_tab[hdr_index].pin = pin; pin_irq_hdr_tab[hdr_index].hdr = hdr; @@ -304,7 +304,7 @@ rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, return RT_EOK; } -rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +static rt_err_t _pin_detach_irq(struct rt_device *device, rt_int32_t pin) { const struct pin_index *index = RT_NULL; rt_base_t level; @@ -313,13 +313,13 @@ rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin) index = get_pin(pin); if (index == RT_NULL) { - return RT_EINVAL; + return -RT_EINVAL; } hdr_index = bit2bitno(index->pin); if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) { - return RT_EINVAL; + return -RT_EINVAL; } level = rt_hw_interrupt_disable(); @@ -337,7 +337,7 @@ rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin) return RT_EOK; } -rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +static rt_err_t _pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { const struct pin_index *index; const struct pin_irq_map *irqmap; @@ -348,7 +348,7 @@ rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_ index = get_pin(pin); if (index == RT_NULL) { - return RT_EINVAL; + return -RT_EINVAL; } if (enabled == PIN_IRQ_ENABLE) @@ -356,14 +356,14 @@ rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_ hdr_index = bit2bitno(index->pin); if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) { - return RT_EINVAL; + return -RT_EINVAL; } level = rt_hw_interrupt_disable(); if (pin_irq_hdr_tab[hdr_index].pin == -1) { rt_hw_interrupt_enable(level); - return RT_EINVAL; + return -RT_EINVAL; } irqmap = &pin_irq_map[hdr_index]; @@ -381,7 +381,7 @@ rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_ break; default: rt_hw_interrupt_enable(level); - return RT_EINVAL; + return -RT_EINVAL; } rcu_periph_clock_enable(RCU_SYSCFG); @@ -403,13 +403,13 @@ rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_ irqmap = get_pin_irq_map(index->pin); if (irqmap == RT_NULL) { - return RT_EINVAL; + return -RT_EINVAL; } nvic_irq_disable(irqmap->irqno); } else { - return RT_EINVAL; + return -RT_EINVAL; } return RT_EOK; @@ -417,12 +417,12 @@ rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_ const static struct rt_pin_ops gd32_pin_ops = { - gd32_pin_mode, - gd32_pin_write, - gd32_pin_read, - gd32_pin_attach_irq, - gd32_pin_detach_irq, - gd32_pin_irq_enable, + _pin_mode, + _pin_write, + _pin_read, + _pin_attach_irq, + _pin_detach_irq, + _pin_irq_enable, RT_NULL, }; diff --git a/bsp/gd32/libraries/HAL_Drivers/drv_usart.c b/bsp/gd32/libraries/HAL_Drivers/drv_usart.c index 283eb47de3..54a36d6f73 100644 --- a/bsp/gd32/libraries/HAL_Drivers/drv_usart.c +++ b/bsp/gd32/libraries/HAL_Drivers/drv_usart.c @@ -304,7 +304,7 @@ void gd32_uart_gpio_init(struct gd32_uart *uart) NVIC_EnableIRQ(uart->irqn); } -static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) { struct gd32_uart *uart; @@ -358,7 +358,7 @@ static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_co return RT_EOK; } -static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) +static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *arg) { struct gd32_uart *uart; @@ -385,7 +385,7 @@ static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg return RT_EOK; } -static int gd32_putc(struct rt_serial_device *serial, char ch) +static int _uart_putc(struct rt_serial_device *serial, char ch) { struct gd32_uart *uart; @@ -395,10 +395,10 @@ static int gd32_putc(struct rt_serial_device *serial, char ch) usart_data_transmit(uart->uart_periph, ch); while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET)); - return 1; + return RT_EOK; } -static int gd32_getc(struct rt_serial_device *serial) +static int _uart_getc(struct rt_serial_device *serial) { int ch; struct gd32_uart *uart; @@ -435,10 +435,10 @@ static void uart_isr(struct rt_serial_device *serial) static const struct rt_uart_ops gd32_uart_ops = { - gd32_configure, - gd32_control, - gd32_putc, - gd32_getc, + _uart_configure, + _uart_control, + _uart_putc, + _uart_getc, }; int gd32_hw_usart_init(void) @@ -446,6 +446,7 @@ int gd32_hw_usart_init(void) struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; int i; + int result; for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++) { @@ -453,13 +454,14 @@ int gd32_hw_usart_init(void) uarts[i].serial->config = config; /* register UART1 device */ - rt_hw_serial_register(uarts[i].serial, + result = rt_hw_serial_register(uarts[i].serial, uarts[i].device_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, (void *)&uarts[i]); + RT_ASSERT(result == RT_EOK); } - return 0; + return result; } INIT_BOARD_EXPORT(gd32_hw_usart_init); #endif From 77638c9526a2390fd18352d8bf0064d0e43d312f Mon Sep 17 00:00:00 2001 From: Ouxiaolong <1576690133@qq.com> Date: Wed, 8 Sep 2021 20:45:35 +0800 Subject: [PATCH 3/6] add gd32407v-start --- bsp/gd32/gd32407v-start/board/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bsp/gd32/gd32407v-start/board/SConscript b/bsp/gd32/gd32407v-start/board/SConscript index 0e2bf06321..7580a9c5e8 100644 --- a/bsp/gd32/gd32407v-start/board/SConscript +++ b/bsp/gd32/gd32407v-start/board/SConscript @@ -20,7 +20,7 @@ if rtconfig.CROSS_TOOL == 'gcc': elif rtconfig.CROSS_TOOL == 'keil': src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s'] -CPPDEFINES = ['GD3232F407xx'] +CPPDEFINES = ['GD32F407xx'] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) Return('group') From a686bfa4c3237565d4fe9fbdc7b5b5dd210ef3d1 Mon Sep 17 00:00:00 2001 From: Ouxiaolong <1576690133@qq.com> Date: Thu, 9 Sep 2021 20:23:44 +0800 Subject: [PATCH 4/6] add gd32407v-start --- bsp/gd32/gd32407v-start/board/SConscript | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bsp/gd32/gd32407v-start/board/SConscript b/bsp/gd32/gd32407v-start/board/SConscript index 7580a9c5e8..95b376bd92 100644 --- a/bsp/gd32/gd32407v-start/board/SConscript +++ b/bsp/gd32/gd32407v-start/board/SConscript @@ -19,7 +19,9 @@ if rtconfig.CROSS_TOOL == 'gcc': src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S'] elif rtconfig.CROSS_TOOL == 'keil': src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s'] - +elif rtconfig.CROSS_TOOL == 'iar': + src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s'] + CPPDEFINES = ['GD32F407xx'] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) From 9386c4f6f8bdadef609375d02fa1e19135b2f684 Mon Sep 17 00:00:00 2001 From: Ouxiaolong <1576690133@qq.com> Date: Sat, 11 Sep 2021 19:01:59 +0800 Subject: [PATCH 5/6] add gd32407v-start --- bsp/gd32/README.md | 10 ++++++++++ bsp/gd32/gd32407v-start/SConstruct | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 bsp/gd32/README.md diff --git a/bsp/gd32/README.md b/bsp/gd32/README.md new file mode 100644 index 0000000000..1f0e415f5a --- /dev/null +++ b/bsp/gd32/README.md @@ -0,0 +1,10 @@ + +# GD32 BSP 说明 + +GD32 系列 BSP 目前支持情况如下表所示: + +| **BSP 文件夹名称** | **开发板名称** | +|:------------------------- |:-------------------------- | +| **F4 系列** | | +| [gd32407v-start](gd32407v-start) | 兆易创新 官方 GD32407V-START 开发板 | + diff --git a/bsp/gd32/gd32407v-start/SConstruct b/bsp/gd32/gd32407v-start/SConstruct index 8ad4ca2869..f1e671edb5 100644 --- a/bsp/gd32/gd32407v-start/SConstruct +++ b/bsp/gd32/gd32407v-start/SConstruct @@ -47,11 +47,11 @@ Export('SDK_LIB') # prepare building environment objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) -stm32_library = 'GD32F4xx_HAL' -rtconfig.BSP_LIBRARY_TYPE = stm32_library +gd32_library = 'GD32F4xx_HAL' +rtconfig.BSP_LIBRARY_TYPE = gd32_library # include libraries -objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript'))) +objs.extend(SConscript(os.path.join(libraries_path_prefix, gd32_library, 'SConscript'))) # include drivers objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'))) From bcfe5c19ebb2fe4b7f07e6673941079f2f97490f Mon Sep 17 00:00:00 2001 From: Ouxiaolong <1576690133@qq.com> Date: Fri, 17 Sep 2021 07:23:10 +0800 Subject: [PATCH 6/6] add gd32407v-start --- bsp/gd32/README.md | 9 + bsp/gd32/docs/GD32系列BSP制作教程.md | 941 ++++++++++++++++++ .../GD32系列BSP外设驱动使用教程.md | 77 ++ bsp/gd32/docs/GD32系列驱动介绍.md | 63 ++ bsp/gd32/docs/figures/CMSIS-DAP_Debugger.png | Bin 0 -> 9216 bytes bsp/gd32/docs/figures/FMC.png | Bin 0 -> 71903 bytes bsp/gd32/docs/figures/Gigadevice.png | Bin 0 -> 18777 bytes bsp/gd32/docs/figures/MDK_Build.png | Bin 0 -> 26873 bytes bsp/gd32/docs/figures/MDK_Build_Success.png | Bin 0 -> 29583 bytes bsp/gd32/docs/figures/Peripheral.png | Bin 0 -> 37871 bytes bsp/gd32/docs/figures/UART2.png | Bin 0 -> 48817 bytes bsp/gd32/docs/figures/chip.png | Bin 0 -> 152169 bytes bsp/gd32/docs/figures/com_print.png | Bin 0 -> 7109 bytes bsp/gd32/docs/figures/complise.png | Bin 0 -> 157684 bytes bsp/gd32/docs/figures/config1.png | Bin 0 -> 52454 bytes bsp/gd32/docs/figures/config2.png | Bin 0 -> 48578 bytes bsp/gd32/docs/figures/debug.png | Bin 0 -> 125348 bytes bsp/gd32/docs/figures/disable_lwip.png | Bin 0 -> 32451 bytes bsp/gd32/docs/figures/disable_net.png | Bin 0 -> 24065 bytes bsp/gd32/docs/figures/disable_socket.png | Bin 0 -> 24021 bytes bsp/gd32/docs/figures/dowmload.png | Bin 0 -> 14487 bytes bsp/gd32/docs/figures/download_success.png | Bin 0 -> 8078 bytes bsp/gd32/docs/figures/frame.png | Bin 0 -> 23635 bytes bsp/gd32/docs/figures/gdlink_debug.png | Bin 0 -> 285698 bytes bsp/gd32/docs/figures/gdlink_download.png | Bin 0 -> 13625 bytes .../docs/figures/import_rt-thread_studio.png | Bin 0 -> 212463 bytes bsp/gd32/docs/figures/install_pack.png | Bin 0 -> 37297 bytes bsp/gd32/docs/figures/mdk_keil.png | Bin 0 -> 60061 bytes .../figures/menuconfig_gd32407v-start.png | Bin 0 -> 27476 bytes bsp/gd32/docs/figures/pack_finish.png | Bin 0 -> 26016 bytes bsp/gd32/docs/figures/rename.png | Bin 0 -> 51628 bytes bsp/gd32/docs/figures/rt-thread_studio.png | Bin 0 -> 63511 bytes bsp/gd32/docs/figures/rt_device.png | Bin 0 -> 31457 bytes bsp/gd32/docs/figures/run_flash.png | Bin 0 -> 18970 bytes bsp/gd32/docs/figures/save.png | Bin 0 -> 49631 bytes bsp/gd32/docs/figures/scons.png | Bin 0 -> 14676 bytes bsp/gd32/docs/figures/scons_dist.png | Bin 0 -> 15200 bytes bsp/gd32/docs/figures/scons_mdk5.png | Bin 0 -> 94546 bytes bsp/gd32/docs/figures/scons_success.png | Bin 0 -> 13453 bytes bsp/gd32/docs/figures/setting1.png | Bin 0 -> 28938 bytes bsp/gd32/docs/figures/setting2.png | Bin 0 -> 19253 bytes bsp/gd32/docs/figures/storage.png | Bin 0 -> 107960 bytes bsp/gd32/docs/figures/update.png | Bin 0 -> 31611 bytes bsp/gd32/gd32407v-start/README.md | 2 +- 44 files changed, 1091 insertions(+), 1 deletion(-) create mode 100644 bsp/gd32/docs/GD32系列BSP制作教程.md create mode 100644 bsp/gd32/docs/GD32系列BSP外设驱动使用教程.md create mode 100644 bsp/gd32/docs/GD32系列驱动介绍.md create mode 100644 bsp/gd32/docs/figures/CMSIS-DAP_Debugger.png create mode 100644 bsp/gd32/docs/figures/FMC.png create mode 100644 bsp/gd32/docs/figures/Gigadevice.png create mode 100644 bsp/gd32/docs/figures/MDK_Build.png create mode 100644 bsp/gd32/docs/figures/MDK_Build_Success.png create mode 100644 bsp/gd32/docs/figures/Peripheral.png create mode 100644 bsp/gd32/docs/figures/UART2.png create mode 100644 bsp/gd32/docs/figures/chip.png create mode 100644 bsp/gd32/docs/figures/com_print.png create mode 100644 bsp/gd32/docs/figures/complise.png create mode 100644 bsp/gd32/docs/figures/config1.png create mode 100644 bsp/gd32/docs/figures/config2.png create mode 100644 bsp/gd32/docs/figures/debug.png create mode 100644 bsp/gd32/docs/figures/disable_lwip.png create mode 100644 bsp/gd32/docs/figures/disable_net.png create mode 100644 bsp/gd32/docs/figures/disable_socket.png create mode 100644 bsp/gd32/docs/figures/dowmload.png create mode 100644 bsp/gd32/docs/figures/download_success.png create mode 100644 bsp/gd32/docs/figures/frame.png create mode 100644 bsp/gd32/docs/figures/gdlink_debug.png create mode 100644 bsp/gd32/docs/figures/gdlink_download.png create mode 100644 bsp/gd32/docs/figures/import_rt-thread_studio.png create mode 100644 bsp/gd32/docs/figures/install_pack.png create mode 100644 bsp/gd32/docs/figures/mdk_keil.png create mode 100644 bsp/gd32/docs/figures/menuconfig_gd32407v-start.png create mode 100644 bsp/gd32/docs/figures/pack_finish.png create mode 100644 bsp/gd32/docs/figures/rename.png create mode 100644 bsp/gd32/docs/figures/rt-thread_studio.png create mode 100644 bsp/gd32/docs/figures/rt_device.png create mode 100644 bsp/gd32/docs/figures/run_flash.png create mode 100644 bsp/gd32/docs/figures/save.png create mode 100644 bsp/gd32/docs/figures/scons.png create mode 100644 bsp/gd32/docs/figures/scons_dist.png create mode 100644 bsp/gd32/docs/figures/scons_mdk5.png create mode 100644 bsp/gd32/docs/figures/scons_success.png create mode 100644 bsp/gd32/docs/figures/setting1.png create mode 100644 bsp/gd32/docs/figures/setting2.png create mode 100644 bsp/gd32/docs/figures/storage.png create mode 100644 bsp/gd32/docs/figures/update.png diff --git a/bsp/gd32/README.md b/bsp/gd32/README.md index 1f0e415f5a..8d7a969ed9 100644 --- a/bsp/gd32/README.md +++ b/bsp/gd32/README.md @@ -8,3 +8,12 @@ GD32 系列 BSP 目前支持情况如下表所示: | **F4 系列** | | | [gd32407v-start](gd32407v-start) | 兆易创新 官方 GD32407V-START 开发板 | +可以通过阅读相应 BSP 下的 README 来快速上手,如果想要使用 BSP 更多功能可参考 docs 文件夹下提供的说明文档,如下表所示: + +| **BSP 使用教程** | **简介** | +|:-------------------- |:------------------------------------------------- | +| [外设驱动使用教程](docs/GD32系列BSP外设驱动使用教程.md) | 讲解 BSP 上更多外设驱动的使用方法 | +| [外设驱动介绍与应用](docs/GD32系列驱动介绍.md) | 讲解 GD32 系列 BSP 驱动的支持情况,以及如何利用驱动框架开发应用程序 | +| **BSP 制作与提交** | **简介** | +| [BSP 制作教程](docs/GD32系列BSP制作教程.md) | 讲解 GD32 系列 BSP 的制作方法 | + diff --git a/bsp/gd32/docs/GD32系列BSP制作教程.md b/bsp/gd32/docs/GD32系列BSP制作教程.md new file mode 100644 index 0000000000..8f50f631c9 --- /dev/null +++ b/bsp/gd32/docs/GD32系列BSP制作教程.md @@ -0,0 +1,941 @@ +# GD32 系列 BSP 制作教程 + +## 1. BSP 框架介绍 + +BSP 框架结构如下图所示: + +![BSP 框架图](./figures/frame.png) + +GD32的BSP架构主要分为三个部分:libraries、tools和具体的Boards,其中libraries包含了GD32的通用库,包括每个系列的HAL以及适配RT-Thread的drivers;tools是生成工程的Python脚本工具;另外就是Boards文件,当然这里的Boards有很多,我这里值列举了GD32407V-START。 + + + + +## 2. 知识准备 + +制作一个 BSP 的过程就是构建一个新系统的过程,因此想要制作出好用的 BSP,要对 RT-Thread 系统的构建过程有一定了解,需要的知识准备如下所示: + +- 掌握 GD32 系列 BSP 的使用方法 + + 了解 BSP 的使用方法,可以阅读 [BSP 说明文档](../README.md) 中使用教程表格内的文档。 + +- 了解 Scons 工程构建方法 + + RT-Thread 使用 Scons 作为系统的构建工具,因此了解 Scons 的常用命令对制作新 BSP 是基本要求。 + +- 了解设备驱动框架 + + 在 RT-Thread 系统中,应用程序通过设备驱动框架来操作硬件,因此了解设备驱动框架,对添加 BSP 驱动是很重要的。 + +- 了解 Kconfig 语法 + + RT-Thread 系统通过 menuconfig 的方式进行配置,而 menuconfig 中的选项是由 Kconfig 文件决定的,因此想要对 RT-Thread 系统进行配置,需要对 kconfig 语法有一定了解。 + + + +## 3. BSP移植 + +### 3.1 Keil环境准备 + +目前市面通用的MDK for ARM版本有Keil 4和Keil 5:使用Keil 4建议安装4.74及以上;使用Keil 5建议安装5.20以上版本。本文的MDK是5.30。 + +从MDK的官网可以下载得到MDK的安装包,然后安装即可。 + +[MDK下载地址](https://www.keil.com/download/product/) + +![MDK_KEIL](./figures/mdk_keil.png) + +安装完成后会自动打开,我们将其关闭。 + +接下来我们下载GD32F30x的软件支持包。 + +[下载地址](http://www.gd32mcu.com/cn/download) + + ![Download](./figures/dowmload.png) + + + +下载好后双击GigaDevice.GD32F4xx_DFP.2.1.0.pack运行即可: + + + + ![install paxk](./figures/install_pack.png) + + + +点击[Next]即可安装完成。 + + ![finish](./figures/pack_finish.png) + + + +安装成功后,重新打开Keil,则可以在File->Device Database中出现Gigadevice的下拉选项,点击可以查看到相应的型号。 + + ![Gigadevice](./figures/Gigadevice.png) + + + +### 3.2 BSP工程制作 + +**1.构建基础工程** + +首先看看RT-Thread代码仓库中已有很多BSP,而我要移植的是Cortex-M4内核。这里我找了一个相似的内核,把它复制一份,并修改文件名为:gd32407v-start。这样就有一个基础的工程。然后就开始增删改查,完成最终的BSP,几乎所有的BSP的制作都是如此。 + +**2.修改BSP构建脚本** + +bsp/gd32/gd32407v-start/Kconfig修改后的内容如下: + +```config +mainmenu "RT-Thread Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" +source "../libraries/Kconfig" +source "board/Kconfig" +``` + +该文件是获取所有路径下的Kconfig。 + + + +bsp/gd32/gd32407v-start/SConscript修改后的内容如下: + +```python +# for module compiling + +import os +Import('RTT_ROOT') + +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') +``` + + +该文件是用于遍历当前目录的所有文件夹。 + + +bsp/gd32/gd32407v-start/SConstruct修改后的内容如下: +```python +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = env["LINKCOM"] + ' --map rtthread.map') + +Export('RTT_ROOT') +Export('rtconfig') + +SDK_ROOT = os.path.abspath('./') + +if os.path.exists(SDK_ROOT + '/libraries'): + libraries_path_prefix = SDK_ROOT + '/libraries' +else: + libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries' + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +gd32_library = 'GD32F4xx_HAL' +rtconfig.BSP_LIBRARY_TYPE = gd32_library + +# include libraries +objs.extend(SConscript(os.path.join(libraries_path_prefix, gd32_library, 'SConscript'))) + +# include drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'))) + +# make a building +DoBuilding(TARGET, objs) +``` +该文件用于链接所有的依赖文件,并调用make进行编译。 + + + +**3.修改开发环境信息** +bsp/gd32/gd32407v-start/cconfig.h修改后的内容如下: +```c +#ifndef CCONFIG_H__ +#define CCONFIG_H__ +/* Automatically generated file; DO NOT EDIT. */ +/* compiler configure file for RT-Thread in GCC*/ + +#define HAVE_NEWLIB_H 1 +#define LIBC_VERSION "newlib 2.4.0" + +#define HAVE_SYS_SIGNAL_H 1 +#define HAVE_SYS_SELECT_H 1 +#define HAVE_PTHREAD_H 1 + +#define HAVE_FDSET 1 +#define HAVE_SIGACTION 1 +#define GCC_VERSION_STR "5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]" +#define STDC "2011" + +#endif +``` +该文件是是编译BSP的环境信息,需根据实际修改。 + + + +**4.修改KEIL的模板工程** + +双击:template.uvprojx即可修改模板工程。 + +修改为对应芯片设备: + + ![Chip](./figures/chip.png) + + + +修改FLASH和RAM的配置: + + ![storage](./figures/storage.png) + + + +修改可执行文件名字: + +![rename](./figures/rename.png) + + + +修改默认调试工具:CMSIS-DAP Debugger。 + +![Debug](./figures/debug.png) + + + +修改编程算法:GD32F4xx FMC。 + +![FMC](./figures/FMC.png) + + + +**5.修改board文件夹** + +(1) 修改bsp/gd32/gd32407v-start/board/linker_scripts/link.icf + +修改后的内容如下: + +``` +/*###ICF### Section handled by ICF editor, don't touch! / +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x082FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_heap__ = 0x2000; +/ End of ICF editor section. ###ICF###*/ + +export symbol __ICFEDIT_region_RAM_end__; + +define symbol __region_RAM1_start__ = 0x10000000; +define symbol __region_RAM1_end__ = 0x1000FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in RAM1_region { section .sram }; +``` +该文件是IAR编译的链接脚本,根据《GD32F407xx_Datasheet_Rev2.1》可知,GD32F407VKT6的flash大小为3072KB,SRAM大小为192KB,因此需要设置ROM和RAM的起始地址和堆栈大小等。 + + + +(2) 修改bsp/gd32/gd32407v-start/board/linker_scripts/link.ld + +修改后的内容如下: + +``` +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + CODE (rx) : ORIGIN = 0x08000000, LENGTH = 3072k /* 3072KB flash */ + DATA (rw) : ORIGIN = 0x20000000, LENGTH = 192k /* 192KB sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + . = ALIGN(4); + _etext = .; + } > CODE = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >DATA + + .stack : + { + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >DATA + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > DATA + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} +``` +该文件是GCC编译的链接脚本,根据《GD32F407xx_Datasheet_Rev2.1》可知,GD32F407VKT6的flash大小为3072KB,SRAM大小为192KB,因此CODE和DATA 的LENGTH分别设置为3072KB和192KB,其他芯片类似,但其实地址都是一样的。 + +(3) 修改bsp/gd32/gd32407v-start/board/linker_scripts/link.sct +修改后的内容如下: + +``` +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x00300000 { ; load region size_region + ER_IROM1 0x08000000 0x00300000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x00030000 { ; RW data + .ANY (+RW +ZI) + } +} +``` +该文件是MDK的连接脚本,根据《GD32F407xx_Datasheet_Rev2.1》手册,因此需要将 LR_IROM1 和 ER_IROM1 的参数设置为 0x00300000;RAM 的大小为192k,因此需要将 RW_IRAM1 的参数设置为 0x00030000。 + + + +(4) 修改bsp/gd32/gd32407v-start/board/board.h文件 + +修改后内容如下: +```c +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include "gd32f4xx.h" +#include "drv_usart.h" +#include "drv_gpio.h" + +#include "gd32f4xx_exti.h" + +#define EXT_SDRAM_BEGIN (0xC0000000U) /* the begining address of external SDRAM */ +#define EXT_SDRAM_END (EXT_SDRAM_BEGIN + (32U * 1024 * 1024)) /* the end address of external SDRAM */ + +// Internal SRAM memory size[Kbytes] <8-64> +// Default: 64 +#ifdef __ICCARM__ +// Use *.icf ram symbal, to avoid hardcode. +extern char __ICFEDIT_region_RAM_end__; +#define GD32_SRAM_END &__ICFEDIT_region_RAM_end__ +#else +#define GD32_SRAM_SIZE 192 +#define GD32_SRAM_END (0x20000000 + GD32_SRAM_SIZE * 1024) +#endif + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="HEAP" +#define HEAP_BEGIN (__segment_end("HEAP")) +#else +extern int __bss_end; +#define HEAP_BEGIN (&__bss_end) +#endif + +#define HEAP_END GD32_SRAM_END + +#endif +``` +值得注意的是,不同的编译器规定的堆栈内存的起始地址 HEAP_BEGIN 和结束地址 HEAP_END。这里 HEAP_BEGIN 和 HEAP_END 的值需要和前面的链接脚本是一致的,需要结合实际去修改。 + + + +(5) 修改bsp/gd32/gd32407v-start/board/board.c文件 + +修改后的文件如下: +```c +#include +#include +#include +#include + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ + void Error_Handler(void) + { + /* USER CODE BEGIN Error_Handler */ + /* User can add his own implementation to report the HAL error return state */ + while (1) + { + } + /* USER CODE END Error_Handler */ + } + +/** System Clock Configuration +*/ +void SystemClock_Config(void) +{ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); + NVIC_SetPriority(SysTick_IRQn, 0); +} + +/** + * This is the timer interrupt service routine. + * + */ + void SysTick_Handler(void) + { + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); + } + +/** + * This function will initial GD32 board. + */ + void rt_hw_board_init() + { + /* NVIC Configuration */ + #define NVIC_VTOR_MASK 0x3FFFFF80 + #ifdef VECT_TAB_RAM + /* Set the Vector Table base location at 0x10000000 */ + SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); + #else /* VECT_TAB_FLASH */ + /* Set the Vector Table base location at 0x08000000 */ + SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK); + #endif + + SystemClock_Config(); + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef BSP_USING_SDRAM + rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END); +#else + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif +} +``` +该文件重点关注的就是SystemClock_Config配置,SystemCoreClock的定义在system_gd32f4xx.c中定义的。 + + + +(6) 修改bsp/gd32/gd32407v-start/board/Kconfig文件 +修改后内容如下: +```config +menu "Hardware Drivers Config" + +config SOC_GD32407V + bool + select SOC_SERIES_GD32F4 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +menu "Onboard Peripheral Drivers" + +endmenu + +menu "On-chip Peripheral Drivers" + + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN + default y + + menuconfig BSP_USING_UART + bool "Enable UART" + default y + select RT_USING_SERIAL + if BSP_USING_UART + config BSP_USING_UART1 + bool "Enable UART1" + default y + + config BSP_UART1_RX_USING_DMA + bool "Enable UART1 RX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + endif + + menuconfig BSP_USING_SPI + bool "Enable SPI BUS" + default n + select RT_USING_SPI + if BSP_USING_SPI + config BSP_USING_SPI1 + bool "Enable SPI1 BUS" + default n + + config BSP_SPI1_TX_USING_DMA + bool "Enable SPI1 TX DMA" + depends on BSP_USING_SPI1 + default n + + config BSP_SPI1_RX_USING_DMA + bool "Enable SPI1 RX DMA" + depends on BSP_USING_SPI1 + select BSP_SPI1_TX_USING_DMA + default n + endif + + menuconfig BSP_USING_I2C1 + bool "Enable I2C1 BUS (software simulation)" + default n + select RT_USING_I2C + select RT_USING_I2C_BITOPS + select RT_USING_PIN + if BSP_USING_I2C1 + config BSP_I2C1_SCL_PIN + int "i2c1 scl pin number" + range 1 216 + default 24 + config BSP_I2C1_SDA_PIN + int "I2C1 sda pin number" + range 1 216 + default 25 + endif + source "../libraries/HAL_Drivers/Kconfig" + +endmenu + +menu "Board extended module Drivers" + +endmenu + +endmenu +``` +这个文件就是配置板子驱动的,这里可根据实际需求添加。 + + + +(7) 修改bsp/gd32/gd32407v-start/board/SConscript文件 + +修改后内容如下: +```python +import os +import rtconfig +from building import * + +Import('SDK_LIB') + +cwd = GetCurrentDir() + +# add general drivers +src = Split(''' +board.c +''') + +path = [cwd] + +startup_path_prefix = SDK_LIB + +if rtconfig.CROSS_TOOL == 'gcc': + src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.S'] +elif rtconfig.CROSS_TOOL == 'keil': + src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src += [startup_path_prefix + '/GD32F4xx_HAL/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s'] + +CPPDEFINES = ['GD32F407xx'] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') +``` +该文件主要添加board文件夹的.c文件和头文件路径。另外根据开发环境选择相应的汇编文件,和前面的libraries的SConscript语法是一样,文件的结构都是类似的,这里就没有注释了。 + +到这里,基本所有的依赖脚本都配置完成了,接下来将通过menuconfig配置工程。 + + + +**6.menuconfig配置** +关闭套接字抽象层。 + +![Disable socket](./figures/disable_socket.png) + +关闭网络设备接口。 + +![Disable net](./figures/disable_net.png) + +关闭LWIP协议栈。 + +![Disable lwip](./figures/disable_lwip.png) + +GD32407V-START板载没有以太网,因此这里主要是关闭网络相关的内容,当然GD32407V-START的资源丰富,不关这些其实也不影响,如果是其他MCU,根据实际需求自行修改吧。 + + + +**7.驱动修改** +一个基本的BSP中,串口是必不可少的,所以还需要编写串口驱动,这里使用的串口2作为调试串口。 +板子上还有LED灯,主要要编写GPIO驱动即可。 +关于串口和LED的驱动可以查看源码,这里就不贴出来了。 + + + +**8.应用开发** + +笔者在applications的main.c中添加LED的应用代码, +```c +#include +#include +#include +#include + +/* defined the LED2 pin: PC6 */ +#define LED2_PIN GET_PIN(C, 6) + +int main(void) +{ + int count = 1; + + /* set LED2 pin mode to output */ + rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); + + while (count++) + { + rt_pin_write(LED2_PIN, PIN_HIGH); + rt_thread_mdelay(500); + rt_pin_write(LED2_PIN, PIN_LOW); + rt_thread_mdelay(500); + } + + return RT_EOK; +} +``` +当然,这需要GPIO驱动的支持。 + + + +**9.使用ENV编译工程** +在env中执行:scons + +![scons](./figures/scons.png) + +编译成功打印信息如下: + +![scons_success](./figures/scons_success.png) + + + +**10.使用env生成MDK工程** +在env中执行:scons --target=mdk5 + +![scons_mdk5](./figures/scons_mdk5.png) + + + +生成MDK工程后,打开MDK工程进行编译 + +![MDK Build](./figures/MDK_Build.png) + + +成功编译打印信息如下: + +![MDK Build success](./figures/MDK_Build_Success.png) + + + +### 3.3 使用GD-Link 下载调试GD32 + +前面使用ENV和MDK成功编译可BSP,那么接下来就是下载调试环节,下载需要下载器,而GD32部分开发板自带GD-link,可以用开发板上自带的GD-link调试仿真代码,不带的可外接GD-link模块,还是很方便的。具体操作方法如下。 + + + +1.第一次使用GD-link插入电脑后,会自动安装驱动。 + +在Options for Target -> Debug 中选择“CMSIS-DAP Debugger”,部分客户反馈找不到这一驱动器选项,那是因为MDK版本过低,只有Keil4.74以上的版本和Keil5才支持CMSIS-DAP Debugger选项。 + + ![CMSIS-DAP Debugger](./figures/CMSIS-DAP_Debugger.png) + +2.在Options for Target -> Debug ->Settings勾选SWJ、 Port选择 SW。右框IDcode会出现”0xXBAXXXXX”。 + + ![setting1](./figures/setting1.png) + +3.在Options for Target -> Debug ->Settings -> Flash Download中添加GD32的flash算法。 + + ![setting2](./figures/setting2.png) + +4.单击下图的快捷方式“debug”, 即可使用GD-Link进行仿真。 + + ![GD link debug](./figures/gdlink_debug.png) + + + +当然啦,也可使用GD-Link下载程序。 + + ![GD link download](./figures/gdlink_download.png) + +下载程序成功后,打印信息如下: + +![download success](./figures/download_success.png) + +接上串口,打印信息如下: + +![UART print](./figures/com_print.png) + +同时LED会不断闪烁。 + + + +### 3.4 RT-Thread studio开发 + +当然,该工程也可导出使用rt-thread studio开发。 + +先使用scons --dist导出工程。 + +![scons dist](./figures/scons_dist.png) + +再将工程导入rt-thread studio中 + + ![import_rt-thread_studio](./figures/import_rt-thread_studio.png) + +最后,就可在rt-thread studio就可进行开发工作了。 + +![rt-thread_studio](./figures/rt-thread_studio.png) + + + +## 4. 规范 + +本章节介绍 RT-Thread GD32 系列 BSP 制作与提交时应当遵守的规范 。开发人员在 BSP 制作完成后,可以根据本规范提出的检查点对制作的 BSP 进行检查,确保 BSP 在提交前有较高的质量 。 + +### 4.1 BSP 制作规范 + +GD32 BSP 的制作规范主要分为 3 个方面:工程配置,ENV 配置和 IDE 配置。在已有的 GD32 系列 BSP 的模板中,已经根据下列规范对模板进行配置。在制作新 BSP 的过程中,拷贝模板进行修改时,需要注意的是不要修改这些默认的配置。BSP 制作完成后,需要对新制作的 BSP 进行功能测试,功能正常后再进行代码提交。 + +下面将详细介绍 BSP 的制作规范。 + +#### 4.1.1 工程配置 + +- 遵从RT-Thread 编码规范,代码注释风格统一 +- main 函数功能保持一致 + - 如果有 LED 的话,main 函数里**只放一个** LED 1HZ 闪烁的程序 +- 在 `rt_hw_board_init` 中需要完成堆的初始化:调用 `rt_system_heap_init` +- 默认只初始化 GPIO 驱动和 FinSH 对应的串口驱动,不使用 DMA +- 当使能板载外设驱动时,应做到不需要修改代码就能编译下载使用 +- 提交前应检查 GCC/MDK/IAR 三种编译器直接编译或者重新生成后编译是否成功 +- 使用 `dist` 命令对 BSP 进行发布,检查使用 `dist` 命令生成的工程是否可以正常使用 + +#### 4.1.2 ENV 配置 + +- 系统心跳统一设置为 1000(宏:RT_TICK_PER_SECOND) +- BSP 中需要打开调试选项中的断言(宏:RT_DEBUG) +- 系统空闲线程栈大小统一设置为 256(宏:IDLE_THREAD_STACK_SIZE) +- 开启组件自动初始化(宏:RT_USING_COMPONENTS_INIT) +- 需要开启 user main 选项(宏:RT_USING_USER_MAIN) +- 默认关闭 libc(宏:RT_USING_LIBC) +- FinSH 默认只使用 MSH 模式(宏:FINSH_USING_MSH_ONLY) + +#### 4.1.3 IDE 配置 + +- 使能下载代码后自动运行 +- 使能 C99 支持 +- 使能 One ELF Section per Function(MDK) +- MDK/IAR 生成的临时文件分别放到build下的 MDK/IAR 文件夹下 +- MDK/GCC/IAR 生成 bin 文件名字统一成 rtthread.bin + +### 4.2 BSP 提交规范 + +- 提交前请认真修改 BSP 的 README.md 文件,README.md 文件的外设支持表单只填写 BSP 支持的外设,可参考其他 BSP 填写。查看文档[《GD32系列驱动介绍》](./GD32系列驱动介绍.md)了解驱动分类。 +- 提交 BSP 分为 2 个阶段提交: + - 第一阶段:基础 BSP 包括串口驱动和 GPIO 驱动,能运行 FinSH 控制台。完成 MDK4、MDK5 、IAR 和 GCC 编译器支持,如果芯片不支持某款编译器(比如MDK4)可以不用做。 BSP 的 README.md 文件需要填写第二阶段要完成的驱动。 + - 第二阶段:完成板载外设驱动支持,所有板载外设使用 menuconfig 配置后就能直接使用。若开发板没有板载外设,则此阶段可以不用完成。不同的驱动要分开提交,方便 review 和合并。 +- 只提交 BSP 必要的文件,删除无关的中间文件,能够提交的文件请对照其他 BSP。 +- 提交 GD32 不同系列的 Library 库时,请参考 f1/f4 系列的 HAL 库,删除多余库文件 +- 提交前要对 BSP 进行编译测试,确保在不同编译器下编译正常 +- 提交前要对 BSP 进行功能测试,确保 BSP 的在提交前符合工程配置章节中的要求 \ No newline at end of file diff --git a/bsp/gd32/docs/GD32系列BSP外设驱动使用教程.md b/bsp/gd32/docs/GD32系列BSP外设驱动使用教程.md new file mode 100644 index 0000000000..d33f9a7d01 --- /dev/null +++ b/bsp/gd32/docs/GD32系列BSP外设驱动使用教程.md @@ -0,0 +1,77 @@ +# GD32系列BSP外设驱动使用教程 + +## 简介 + +本文档是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。 + +主要包括以下内容: + +1. 如何使用开发板上更多的板载资源 +2. 如何使用更多的片上资源 +3. 如何添加更多片上资源选项 + +## 前提要求 + +- 学会如何使用 ENV 工具,参考:[RT-Thread env 工具用户手册](https://www.rt-thread.org/document/site/programming-manual/env/env/) + +## 如何使用更多的板载资源 + +开发板上一般有很多板载资源,如 Flash、SD卡等,但是 BSP 工程默认没有开启这些外设驱动。RT-Thread 提供了 ENV 工具来开启或关闭 BSP 的外设驱动。下面以在GD32407V-START开发板上开启 UART2 驱动为例,一步步的展示如何使用 ENV 工具对 BSP 进行配置。 + +### 1)打开配置工具 + +在目录 `rt-thread\bsp\gd32\gd32407v-start` 下打开 menuconfig 配置界面。 + +![打开 menuconfig](figures/menuconfig_gd32407v-start.png) + +打开的配置工具界面如下所示: + +![RT-Thread 配置菜单](figures/config1.png) + +通过键盘上的上下键移动光标,选中 `Hardware Drivers Config`然后按回车键进入硬件驱动配置菜单。 + +### 2)进入硬件驱动配置菜单 + +在硬件配置菜单里有三个选项,分别是 **板载外设配置菜单**、**片上外设配置菜单**和**扩展模块配置菜单**,按回车键进入板载外设配置菜单。 + +![硬件驱动 配置菜单](figures/config2.png) + +### 3)在板载外设配置菜单里开启 UART2 选项 + +![板载外设 配置菜单](figures/UART2.png) + +### 4)保存退出 + +然后右移光标选中 Save 按回车键保存,然后按 Esc 键退出配置工具。 + +![保存退出](figures/save.png) + +### 5)更新软件包 + +输入命令 `pkgs --update` 使软件包配置生效。 + +![1543477036034](figures/update.png) + +### 6)生成 MDK5 工程 + +输入命令 `scons --target=mdk5 -s` 重新生成 MDK5 的工程。 + +![1543477194829](figures/scons_mdk5.png) + +### 7)编译下载 + +打开生成的 MDK5 工程文件,编译并下载。 + +![1543478492157](figures/complise.png) + +### 8)查看运行结果 + +程序运行后,输入命令 `list_device` 可以看到名为 uart2的设备,此时 `UART2` 设备已经可以使用了。 + +![1543478742034](figures/run_flash.png) + + + +## 总结 + +当开发者需要使用未开启的外设时,只要在 ENV 工具中使能相关的外设即可,重新生成的工程中就会添加对应的驱动文件。开发者就可以利用 RT-Thread 提供的驱动开快速开发应用了。 \ No newline at end of file diff --git a/bsp/gd32/docs/GD32系列驱动介绍.md b/bsp/gd32/docs/GD32系列驱动介绍.md new file mode 100644 index 0000000000..9c993f5dca --- /dev/null +++ b/bsp/gd32/docs/GD32系列驱动介绍.md @@ -0,0 +1,63 @@ +# GD32系列驱动介绍 + +在 RT-Thread 实时操作系统中,各种各样的设备驱动是通过一套 I/O 设备管理框架来管理的。设备管理框架给上层应用提供了一套标准的设备操作 API,开发者通过调用这些标准设备操作 API,可以高效地完成和底层硬件外设的交互。设备管理框架的结构如下图所示: + +![rt_device](figures/rt_device.png) + +使用 I/O 设备管理框架开发应用程序,有如下优点: + +- 使用同一套标准的 API 开发应用程序,使应用程序具有更好的移植性 +- 底层驱动的升级和修改不会影响到上层代码 +- 驱动和应用程序相互独立,方便多个开发者协同开发 + +## 1. 驱动分类介绍 + +本小节介绍 BSP 提供的不同类别驱动的概念,对一个 BSP 而言,有如下三类驱动: + +- **板载外设驱动**:指 MCU 之外,开发板上外设,例如 TF 卡、以太网和 LCD 等 +- **片上外设驱动**:指 MCU 芯片上的外设,例如硬件定时器、ADC 和看门狗等 +- **扩展模块驱动**:指可以通过扩展接口或者杜邦线连接的开发板的模块,例如 ESP8266 模块 + +这三种外设的示意图如下所示: + +![Peripheral](figures/Peripheral.png) + +## 2. 外设驱动的使用方法 + +点击下表中的驱动名称,即可跳转到对应驱动框架的介绍文档。开发者可以通过阅读相关资料,了解如何在应用开发中通过设备驱动框架来使用这些外设驱动。 + +### 2.1 片上外设 + +| 序号 | 驱动 | 简介 | +| ---- | ------------------------------------------------------------ | ------------------------------------------------ | +| 1 | [GPIO](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/pin/pin.md) | 操作 GPIO 管脚 | +| 2 | [UART](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v1/uart) | 通过串口收发数据 | +| 3 | [soft I2C](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/i2c/i2c.md) | 通过软件 I2C 收发数据 | +| 4 | [SPI](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi) | 通过 SPI 收发数据 | +| 5 | [ADC](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/adc/adc.md) | 测量管脚上的模拟量 | +| 6 | SDIO | 通过 SDIO 读写数据 | +| 7 | [TIMER](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/hwtimer/hwtimer.md) | 使用硬件定时器实现测量时间和定时执行回调函数功能 | +| 8 | [PWM](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/pwm/pwm.md) | 在特定的管脚输出 PWM 波形 | +| 9 | [RTC](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/rtc/rtc.md) | 设置和读取时间 | +| 10 | [WDT](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/watchdog/watchdog.md) | 看门狗驱动 | +| 11 | [QSPI](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/spi/spi.md) | 通过 SPI(1、2、4线) 收发数据 | + +### 2.2 板载外设 + +| 序号 | 驱动 | 简介 | +| ---- | ------- | --------------------------------------- | +| 1 | SD | 适用于 SPI 接口或 SDIO 接口的 SD(TF) 卡 | +| 2 | ETH PHY | 以太网 | +| 3 | USB PHY | USB | +| 4 | LCD | 显示屏 | + +### 2.3 扩展模块 + +| 序号 | 驱动 | 简介 | +| ---- | -------- | ---------------------- | +| 1 | ESP8266 | 串口转 WIFI 模块 | +| 2 | ENC28J60 | SPI 接口的以太网控制器 | + +### 2.4 驱动示例代码 + +在 RT-Thread 的 `examples\test` 目录下,有 RT-Thread 提供的基于不同外设驱动的示例代码。在 env 工具中开启 BSP 中要测试的驱动,并将 `examples\test` 中对应的驱动框架测试文件加入工程,即可快速测试 BSP 中提供的驱动。 \ No newline at end of file diff --git a/bsp/gd32/docs/figures/CMSIS-DAP_Debugger.png b/bsp/gd32/docs/figures/CMSIS-DAP_Debugger.png new file mode 100644 index 0000000000000000000000000000000000000000..e630ea236259a0025b000e828b00e1ca3b2bd08c GIT binary patch literal 9216 zcmZX4Wl)?=&@E2z0D<5TT!IG+4nY>Tg(bMV1cJK+*TtQ{V!OZs!QDMTAXxC=?h-8D z=Dl_6R(_jEnc8fpr7*c8}ENJw}9#SdCYNGNWI_NNypNJz*PQu{Lq z0oh$kK?bRMf@&WjpxH>PN+TiFCgMDrp(A80S4DkyBqXBG|32hZYg%t4B!)D=2WcH| z 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 MKL7v# literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/FMC.png b/bsp/gd32/docs/figures/FMC.png new file mode 100644 index 0000000000000000000000000000000000000000..6a65b6e39efdf06099d2e0042977c2c33f9a603b GIT binary patch literal 71903 zcma(2WmFtZ*fk2{5(w@Ng9n1UyE_C65Zv9J1oz->Gq?s1FoXnmcXxM}0nXgd^S<9Y z=ik?BO-*-KcUM*SWwoze(dw#lA3uak3-m0fM!JiUbTyeIgpf^uJ0}7kPbm7#JLn|9-IRR+K(4Fz+P_(h}M}#;1A6 zU&#iZ9?}M#uM>9`6HfV~afMt@7hO+(SA_^38h#ty`2QTnw=9$qkxFIR^u#%~*3ed^`wECtoe2>AR)kgeQ;m` zv*QTR8I-fjXRpjx$G;jc>}Pm+ZdK2-=&JMb_f~P2&1F*7X&oG$KG1UZMN{+I)BCu` zwJns>FFi?O;H|Xs3@>FXgQ)xjFPV)wW^ch_rV14WNGMAKp5ktUxE{WnV6#oDw6wI? z$SX3)(zv3ZI5A#wF7%yrAF+_hjc;v9yFJjmGFuCd-fEeB$pYqZa&o4#=wIJVh=EQ> z1kna^va`=u+d|`b?B^}Ai66-~8r^$7q*g0o3VNaMu=@wVLIBu7MfB4J9Rdh z=e5^c!lneOW1rOA0yzgP6FhM-1IunUtYPbCd7wFL^w@xxy*68xp&@g9OS4v6>%&L18OcPm* zuddnmX?bykoQ^Rqa@rrav<%W0VH-!zTE zIkm=PpGkj=Z)aStf8h-MHpa{{{SkxUTwc;-G8Qz6Opw}OtEl*t7#xZ>fV}oJBfhtH({j4zMtV&cd z0XT!(XY|R*k4KzuOr-y!G(M-sHnzac|M>m9lw_1Ouc6LLvq0=7_o@TcXogs*+?HR&@nMp1ik@lf<2UT*CU3} zAE>OA+I=GAjc0oexyWy6JyYqTJ)CQbi;WD>OoxYtu-~_Qrg%pCc@PJjBN+M@2MDaN zO4<$!ij!N4DQe=@*Vj`yVt^JG7Qs@O00ndN6(@rHb5JPfC$3wMvz=TV!?=Kk6S;W) zh;NNc+T5Mr`0gGa8Z%!<--75<`ka2NejTmXKm3vKIUltgLmMq;jGEcv9z>>%Ic$-V zcGVu;BM}+Fz34!YBbDwp&LX5x-BTP(e@wqSYDO&vbVG=gd2(0Z(Pz0=+)0gIe$`x) zjz>MfnaFpg6eR<@KMdu`d5kwntc9hs&8k$dLgYU-UBh%VLmE63gMvUO>FdZAHD7BR zQO#$N`Yi+D!$H~GFGgplvcjh9sJSiM;z|b+f;<@Mf7+DNS!_GfQgcTc6F51wrfUu` z=#6>W3>FprFQ-y0AWZ^;Sw*b{Nz}O0`Raig!xKXjWpSPf&2(hv-(n|fiLweP=W`@v5(WlMm zq5N-Kk;kP3ylL5=-66$0+UdRKa)}hp{0(X2SsyBMq-A8-3J631pGmY7)|K*Od`na? zOJVQUM8rJ)X-}@36P4v;Ity!yL7M^|HD4-rCp7h&M}JTaM`4qd6fVp&$p-Anw-Q-rW#GfjY0z zB~ILN>HfYIJbY+D@S6Y&OWZigcAA&gSd%Zud)D>o5|`g=h0oX&cVuA)YG$qgd%=i( zNGo?wZ-@{e-`1Mm)BH7V^ijLySG3e~b1u#=DxmFSXN~6F3Arr53ucP}NJ*xMt(aqQ>QjNGlT&`hX- zG_j9Q+DdW}Po;UtZiarv^B0vvs63cde>gixPP6mk z5s|aW1%4o|I&~~98)|4sOw0oK%hRdMU)p#0*XQRA2{%m}9kQ}&>Pdz-8WoC*L73K! z0W}dPQP1Nyvx@oPmbJ2G zvL5sBlNa#=_wGCNTg)`R9I|X#Sp}vhC4H~0nsnP6PKzaED|L4z`}kvWu|e>Q`GCaO z&dR)9d)Y4EJy29I@Ra2kln1m|r>uE4W!;N=9-N;~KLqeNv@u%M1fS0u!?yz0TOu+E zpZ4}oxpqV)3qRox7rMKy&ZXts*b1^|jgF72a&wo>u*v!R3;AA2Uqb{Qj%NOSFPnh6 zI&>_tmSUueDE|jItE4^FZbGD+)EUA)d-8?jVG9rT*&M6YG+{X%1@9m6<@XX z&J%;{!zXzZF9F(`zZUMA5M?zdfdiX>JU3a_-QC@=?ef2d7wzjq20(PR9=KZ{eo>bAi&7t}$>F z=q_|b3lL($5u%f%mCv&0;ZfsF&;GLpC}uTT_t-p*SjV7@EVIM6*O!R`F}XnLGHlx& zwR$dc+1@FHI8r%}rDFAQt`mTtaZv-OT{^X3hFT-Jd1?ONP_@Q~R`jvb8JX8eo33bG zzoCveu7QmcGpj&uY~eAdqoWIJ_saxeA8GUvY&x3>1sj`Xqw~x298D^N+3&>JU%f5G zCtDQ5rA4i-5LsMYPd!~%ykihG;yC#>j9e`8}xFRjm)vMCS4ve z#h2-D$LcQl!sx%wHQrWQ>3M!BlR^OIxF1Bx174nCW%GF_*H2tSD)scI@C0A z%*uI^%W(bCrRh~xN|b&53Q>6kdFNZS2ZqT`@8SuujifNB*(m8r>=-VS5Ec4;LkbLA zKp=aSsDq2Q$o^1MovV#UJ2Gsxs(G`<`BbM@26KmPkT3AVvay{rurAY#gK3W3Q5oXq zrl22@m{GyK*FVvBlg!@;U>#hZ$s|&10x1>zln0yp+)vcjZcX8frMI7()Xm`vnbs9C zG6C$RLsf=N6ZiHOq)i-~s}e~F=RESE#i)|geJ+31zXg^Bc`$FPT>q5tpc(iJ(V5v}IKtVD+H zI&-@JNvy7}E=LWZkG!Y&F=R1~m?9}KF(yiq-AT$3O4-!9VRHhsCM5FylN6nq5=h(b zq@*GHJFM8*E96}{=yqdC3;)kW)6v;EUt!{-FT041v*_Uug(BgybI|s-+3blk=l{rW z9We1wKZrj3nl?yC6hHN#YFFo0Ls9XAV-oEGhl~unOrE^p81h{_E)54q5@*==g-JQO zw`WRLE)h;!N@@VqpYigx)Yf7ceM(JDjmyhCOS_7Bj(T)*(PUIJrbNXrT+)IMJM6UF zWWsY0@zwJ4;K+#msrEST-P8bOaBe}t#=-)hT?8fUJ+^@V$>5u~38XM!S}cW-Z$t^S>tym$?gH5FS~KJtDU=+?(HpNx^a8$k zd*W|I>Z!Su(Yo*wV7%s9ZQ)@Cab7oRd*I#=L`|Ett)t>W-}0Yg!wgpPG|UXv+Cbf6 z!(OphJU6M}*#IRJJ3~BeA#5-{ll3qX0^Cw3083MaWMwh~fyTDwyBeQ3J64i3<{#Ki znYIzJK-P=c7^b0-k(@s_I|GSK07gbe5s_Du_h-ViViz|zAnSBdadDXHWxdOm5NR}7m-dS=874Y$US;U}I zMHzE*P(cA@LlUX8!oS$!3DFmHR<^IdL(*YkVQq#kA}()lQ!_G5>dpFuF2GW2`dl0w z(Xp}qFK4Yx$Oz4f5)!a!Ve&XQ#ufBqNLUJz-7d8Ma^yn@rL?qgS*eplGA!GZnry2A zjdFYV3oLkGLG&*MUFn%d%Cb+)X}faI2&E+)s&8MVmo^Pn&NiLMbX%wX`k!#CyxywT zO6?2;QZi3c(2{xOH2Jnvx}xXND}3lW#!IF&6xm#dbA|?O^uN1(KDvYxEde4UOu`veJ5wIkiHU%$jh5O)Jw zZES6A75p!YYHC#0UW-3(RPK1*-Q9V9X52aRjVbHHduKS_!SmCTo#K!CUEEb(cX1xE z6^}ZQVA{6!+KM}v#ZS6(;-Bg3yO_Rbb-oW+m;R!mQB+=j2vu$e2W6ElTjs#+YH;th zTI-UHqhM8qEih>JV61((v{d!^Il>Ee8R-ChPA&ju3?-^K+NVNZvZ&Ew2xr*1&5cg+ zdLmbt)Wb7A-}G|5)BhIa2ci!pH@nylRzf12iq5c-O~Rw%KO|v@xW`2(XE;(+uo6iw z*AKzRBXDU$`w^;vhpmvR=6`8wZ@)4>AHf~{47*gGH6n+-9K|&XIzmX8$>!#mmHrhq zIjPQ^oa)Is*^sQDmigtYev!K;0l;=5(!WXz{xk9Q^5|Cl+w#ha|L?C820-6&?4oF9 z;Ku2tSCVM?d9Jmm08MMSqb4M-kNmfB?)%T!2mB6U|7im}TQ8yEq}3u*AF*`Vuy4yg zhArQ(qWs%X)YK+&w)Xc-TV|O%SO0zL8}n{^a3+it*|}dE;yGrCb{xIuLuE4Xo*grv zNCsr1qH~>Wo?4|eVc6kQfFuv_Ws<`XuoWsQQe-sU-MM&_*zZEKj`iYos=hdi6=qpF zxp&JH|)bd z$XG7l&&R+q>4)et%F!7s` zK1&2<_widN_U?^X*$AsjCr2&%21lYL%_F@8KWi&1k6uMR%H+9(uMKo-+O;^O+6MFg zmN?};*y`*tTS2DqDllmUSF!BOVwffH1w8_orgXiR?gO`leuY!Mvo&1KSDyLn`JgUK z;3<&zRg`(){)jI&ch)QrQGnNa8?xd zb!ohPK3nLPQX9&Bs3Ef^v05)9{XyZXL@pNm7JyszZ?Tu13v!*+DcE0XAlD41B6*`x z5nu0m>?x!jtYZ{Wu^!Hws&f<$Vg0&&;+p&K@2!e534K0hpllMi7#2`ITjzYEE72>> zY!$op+jsfwD5z1&|N0akd7i-6AXWPG>5z#A6{d6uFA0x~j0_(?ycQhfd%(8RBtkc# zXVUQS{1{dyVb`3Bmmb)0_QllHir@=r9pOo|0+YY3j|J39RlU`V^`8POOG`%;%vN!$ zI_EE^6-EWhi<=K*wMZH}>AMxD6iLyP>%drFemjy9Xc?z!rBBB1*cgWVqRv!njqX>l zva+(o9b*%dKD3O?OvZLTkh1^SNr9Tlg~FMfpAcY*%>JIai-jhd{I$ZH#%sgN%Zom4 z;p4kJyTD^iqdQ7oW(bw_K{mlMMR;y5nd8T)AfdITrC3#EnBz#Mj_#F}4*Txb&^S30 ze{$DQg2Y6+bN#Ps6z@7-PUGXXPS_sXbd%H5W{uHo@Q;9s#>SKuc`MfBLF8nwnpt;M z)z6G|^>d<)U*d?+6+Rj9@bpdUA;+iKrEn1MRq?j#i7%gd?(Qfy!Uogk2}nB7(P%RW z2((ol+$VtqM`Y?(7^_4!#01*F(Lobw)8CaGeeAzD)@gL##hscl<8tsO$JAouFB_1^ z&@n9BZ|VsHCNUb(MrE?-hlaBF$|+fPTXr4`*ywTC(rriDe!rkE3ucLpDg%zHf8@n} zFICd}_hv-2+@A!{Gq?Yu?sk1P@5NdnVo9uVFw_A-Z8cPMNIZ5Htf?qJCeZ(FjU16M zbG4Ic?dImn>YC_~4bGR>)YRmJ-Df()nn{lys+y$z{17C|bE0agI-!E(z4?8nIr})j zBj5AU=-fRe)6n5s_NKnsB>5fFz3lUeS7u#fwCV=#IU$f>MRZ~Kigq2Ym`Vad=5@v_ z;1pb8D{f`C*6HxT==SlS%f(X9X##WPPue4pA<_}pc6uQ&(Z0}8v5fItdsSk@zqi;Q z&njE`l$zhH+M)fT>~Kgmnggj)WQ zLWkKikf@j6zqg-pXEn@JZ`;2*DIAcmt$sIvXgK)3z&uFE30$cz8%|04d$8e*c#=j_ z@Oll)j^tuMjF<4bgk>W$TYj(V;wpU2>U(GZP=7i!Yxw(8?eG$EorrlZ>~nt-j@Ddj zrIj?h+rGyY&s{O0i;gkhBueE*al03A1p+pr?mXQbq;%cJ|{L&vILmfuDzFI$5jR-jP`Mt&jXN?xaY zOw@pjm$QNQ+{Jp(OEKLQ9-Z`b01~$?(SOY(A;8Qa{MXD4dvbqZ?5Q#|6a=y2d?~cV3Q>nR&DCy#t0J@Cr{O%!HMuJHm|AUe34QRWAcv%8lrnc@HDmwS9aXd*+*F4pA!^m7;}DXl!nM>o9m&#si~>83*y+r zO6c-Ye#hqf-|@4n(iWKlU`A7?pgm*j0msmO|Jo5RDJvV%;*vYEH=VxuGdUSpquYIB zt9&VJ=rxHmDONAsNhr zXz`&Zf$HM&Syfe9k)x*_g(|NBDp!~+lDVA$Zpu&H1odJfNP(q7v;)oBl(CY@VKns(q_Y~@#3qJ?Av8HS zJC`N@wYQcg>g(^ z5PM4+?{=kSw~6NL>FF668EI~A9vd60ppgy^4wjOF=aiI^qK*rTznU8y7(fnB%FbR+ zgd&7c{f16h*o?uMpLevNT?GMwlddYt%F>bV(|yN0vR7xqL2e}#jYDK0CESa(wb>Z#KYjd^_YD_?U9UWTawf@f5JlFZ!q`9!aSrFZ0M*q=3rFQX~xV3>WenQ zpwkHYUg0TsPtoU^FzBiV?kY}jBZAY)__pCyhAX8_@U6|1C@+&x8C!ObR-5SP?IOfP zX2o<(-o*J~l)dV1Lw+{AN}-^2!tn@oyi!9)V~Fwc)VWO|JgKGjd_GT=BctBk;Ehub zJ#VLyMmf(;$a#s_K17Qztq)KK^~MWf%E{b;N*G{@pVOGlR^#ECeg1DZ24Bi0cac!-wPZ5ffTs7dEtr;3;>`8KWi zy`#0J`rHA}@Y9!RqfW;K=6n)ga>5iry2Q4Uk=$O3`)csFb2eY>PaQ{%0kL6=cGZHe zQ{c=&6~qj2R`S8R{`L%OQ|@Tg zAE0pfXFk5x^QAWUXyyY6Yt-xvOi)|wuP_ZmL(z;mD#9unbad z5vQl8YrCCRIl8&ImG?kykF=N%Qd5)v1j$3rc!dA}R_|bYlMJr+x6{+_p5=p*#+oMY zica3|3FJihvj4JlY}!n-6vLX+!x87Zd#n89z-v%#Yi{OQ=4Oi+O|!KE~k>gv#S0ai|BzIMxJL`i;rw^lB~D$ENhXo zjNSNBrcItRB=k8Lgdgx^p(r-Q&V%&Te!}^Tt?u~L-chYv$UZNZT}>gr--QbsTNzT= z0lW{xeN03Pn@UBYk0W3+R;C;H2>AZbG$D#A`5<6YAK-g2Q7}0ldu?V4oyYn}ilR1E zQ5D+LX7#ZHX(G1o9i^Z~{vpsYFE6jQwziQQK{oBCun}P_HarOg0!$AcObn^rQs;lf zI{FSf9VE+wj2uk|yZ3y{ltuKdhLMn}bZ1iYa{Rt; zCH13|KVa?g%&~cq$zq9nR#NP^T72BH4)A1~)c4#mRFRp={&KRNcn#r+nJKuzzg>UU)ZCC91 znKaJN{^&sU-4%}QqmHFd>od9G&Lq|ZzirM`UH7G}m5BbyqBxnF=wlBf&!|x{6rR}O zT*R*rEPH=?(r2cW(Gar!miKx#Q@IYMADsJ;yY|O(_WOljVj%U|&B%`7 z<=x`_h)pb(4nC9FYEGt^3s|xh6=)uwgi+C~k9!%Yb0{2kQJs$iB~@Q)D*rB#X4FVZ zoi=|;{}Pey@RK@X5nGj6$(y|T1J61mh}epmDX81!^@Hz_loCAJ$noW$J0MLbL{a8P zHxvX#I}>Azt2M?tGv}dC^C;~%bXR2Q#cVga=}>>bVRO!-jmym21KOAz_h<^lpDfgx zv9pWS1RD8#W`=%WY(f|9uS`W?F7VmWgqaz2_*rCM3#Ra?C|e7-gXZS;UaKOZ^aV3h zkPKUQI{xQIps;YW)s1Y{edH`Gd4yP8dbPnGK^i_~d86H2QEcQwdE^&?!KcCiJXun{ z!BT&vz3|Ko>1VPf5J@4UuU@y7_Xf3G7g)-0BE4x{!n8N=P5!IHMrfomQ~g}xi#=`Y zX;CXjZxtEEAdzc+IPSV3bv)yzj2_9XPr&9KIphYnbC7}*A zyD}3Ls3j>9w04e)|6fZ=hz1aBLj3plFO1Pq?_}+dklG{*f}Zj?i;H!t;ljdXD6G~r zgH=;gb4cV8^Lt60)9 zEiSbF`>Qj1X40~{Xe)tJoXj!Xmq%?;AL^vOX^u0OveRzS1lsW4%qqc~WkYB)I+7y=-(gBKmnykGVvDwF5X;h`qK zkwO*)s%`1o*BKYVNxbeucf!8nbNF3y zS4Fsj`>qR|e^;Gq0%{}rIeFupc6^#r!W+Q#^|f_s5}|uMl;EnbT4`AMjqexVxV^-#-f~<$oS?QI9mBxT%?JYilQMGN;`bg_vkl z`jL_ni~ z+5Orbh#_MaV$br4uufudaN>VWQ-A)vgu3(Rh*Yef`T44bY-2rpj~lUNXW^yZ#>aJWoiwxRus?mO`twIr@ZY(+msjl>nPP&H zbIlC`7gt7F+SQ-=y{+@pTy37E)MOn6o1F2Xl36KK+#lUhEv0fH&iq%DRUL$^{*?oP z0VQqRh>q=7CBb2%@AAxIbu@9b_@P(px$`Y#3Q`N(SfOEHuUDny=D8y`H_puZMuo{{ z%MKnVZSIj_`Ia;p1x4e+FNFMn?((`ei~({sBAK=dlPdF)mQ7>8pr1g zKh9={PyFcU?vm8zb%3y{5&~|?$*(+9$;sC~4~_~dDqq}Va-YyC1cKL0XVbmhp6a0) z@Zr-(P}#@mx=&TF`j#y@-uyU(ki+KkANzrQpFb0p`kW|?U#}4 zo4MJjKgMr4XG233O}cWAoYf+h)LS zm>RU+_F|zApg)FN`xLsh_&h8|F&xP$H%@a{hykN4aoKgCVR9PwVyX0WB4ffo?hN$T zD@HbiA5uccBpb(4qnC=K+0E{rEg576j3>tWF3*|W-FL~_UuQaPJS$6&E(Lp{mNq6V ziU5Bl-dz`2c#*9+Uj)c_1tWQ#TjgvCQlb+SgM-C}C7foD;h;0RB&`RK{I|xaf?1q+ z>Xz8$ztX4;&E>2Pv)|}bRQ!Pbm}1*vPDDj(7DZn%aukG{6jFh~(&4=cGbg~BEuTF{ zjF>hO?P1ARar{dT5WD1Sbb5J`vKemqo-%=*a2uMeF%-*)jJ!=W?!^doH1hq*Q>~D z)BOq_=eLtHzjoHEg2!LHJRVC+|t+WKBJp*j-oCeSBcowRGrQ<=~* zCuEP~;u7ue6`t5H3W#J$4F=`)1ippYP?jB17_>YV%53ofbzmzzZ3I-TMB-X5?k&7$ zzllCE#!V(k3M>S~PfZInd>gq|>MJ=j_@~1d_h+Lvuxze5(59>4m!XQ*MJjj6iTN92 zT=Mme))0Hl#6qpC)mHlPuS&5~4{oFtDvK$=b#dR%0 zT(_$~v}*CN23~1HeYhGir4U&^5!+LEr3-T0`qz@4n_B>Pzjx{dRZ&E>qgPG-9@LuS0SZ2cd_4iLrKv;a<(&i0hLm@oxC3VrdSFPZ4 z`@^9=T85BM9Y#2|TTsZZpL{%p8**FxXSKyOG{PY6Ye+DY6Y|m7AFRmk!>5~nSrHm) zZ5!Q`_bw-AzZ3oaH5&bg2|q(%D>PI%;lro+DA|fdH5qxPv7Rn2WbQK9zWR_>U>oy} zu{SI?uhJjhKfgmtigwNo(K0~f?=RgGQ>8)1kK>IDiC+RBU8Sj2BYmGO4=MD$KbxkK z)Z4}C26VM9N?ja;o_9gyvLm2U=M_( z5E588nEwkY{C}>4F-1UuK>>)vh!g$)b;*CKhX^JfH6wy`rvDF4``@Qc*_XDpEh&qy zwtL3bdYBQRBb~iY|6P=i5;v7LWc&CY_6_&H3@3CqY|8#`KVMa8Q*EZ|mQNs_=cqMP z+&t^lg`>S4+07dP3P@mrZ{=2<=sYj9~{{Dg$2T?Gt%_99eOG|2`bX zp1m?ixq6(T(G?JWg{`5X;$QF?JX`mh+H<~}(fHyPTZAp+Q#6#EORlq2WjV&&7%lLV zI&PnVofi(_Z=R6%Bf-$9+IUgF14roBc5; zb($vm#}BwBDDxvOE^ZX+EXvCZI~Azn_K9%AHD-A5n}omFOc@cJ6f>-OoK25}VMD<}!lxBl1Y&*`a^uJcY4fRuN(82zkwB?L!kzGcCzH3=~ zd;9khSgF%2PRyP`NvuiFkEX0Bhwb|S=#WEnG5@bT{r}`74g&;b*TcbNQVR$OXhSAV zp%Cx?K!^KkL{n-HCfqF1PphnrRaS?0!!d zv$9D^N&hHiUteESSsB4#u+2$YNOu&J-+~IewY4Qd?EHnOqN>W?&hG7bq3i7slz3Pj zon=K-^nuS|QJkUwm(P{iGD+yK@Tm-wpr`*BlK0%fGEWf^Noi?wY+aD+c|+%^BL(Ok zuaKJw8(ULTS13CEgwsGui;c=K zpu!ikpdO^Lm{0NDRcsmy9hR>3$VMo!jXn6=il4m2i-MqyAKde3Pv0sfW!;G&otVTf z>xs}BG%BhJt21$E2lGw!yIE$7JQS6;u}9xI#1_o5iABgWk`I<1az|SVd;ICw+x1Z~ z5#>9u*$$zH!BiwvP^LoV5--M!h*>7i4!$zGGIRJ~1#6AyR%}kZlG#mPtdgTwP}8Hi zSilb#T$5OCHyF?9lT%8Pm>T)jww#!@JR`zR@+19f#3u<)49BQ0+;Trz&&~4P--f$q zh;_}Mk^Nl9NYQL~@Cfwtp!{4o_)P@$oWPvm7lE8Ze=`?c%}*C6OWff75cCw z{MqH*CSsQBu|#eWh8S+2yHE}W1_kZ^U4~IisX^djV8Ej1>zzWBw}()0Eb)K@lTx(U z5EBMw=+W=LWgS5hDcRXEcCrW5c?4vKy#$ZDSal)y_g>JIB7(3me}DUhHB2g~GSF{A z0ctxNn?l?f02`Z{l9K&!wh2tJE5vVhYU=8!tN^-9w@|giXN5A1exx7bNgfDr!okBgHa2P` z_nASPzq`FHq#G_vM&ZqgPlm+JfuK@xdFf&?J3CugIcYGPTBe=s@vma}r^KAHWrA5M z1-0nQX`_h$y*jU&){h@QpvG<@UnJInR;Qe|GAWhf3c@5TB9c@KB|`!H`(p5Ip2meP zZ0zj%`}&?9ALSJlfn>P2xZ2di61-}OP|mmSkmX2vQ4JZt3(OKx#CHnVzq_N#iGLv1 zBQ=JtrDbIRkxJ-PPL;tf=8N6(!bk=i0NEnW5=TVx@c3902?sz+kSZG$9bIH;W5Z|w z^YisMK(Xla^k@It>1~|9| z7khDW7&e7YLHMDi5~Ylv-*3?@zv$|wBybnAZ7HMLTUyekLD^{so15ZGshDt3rIh7p zrWixv{vlr0o}F!=t4o;2)BCBzIOkIcwD*j%CsU!wnE9fC&$~moO?WJ17|2E^W3ppV z&TB!3pY#Ph47dV1?y0g~JrSsEV1qy4z=Y^Zsi|SMmjiMC6D_c;cp?l87Qz3P2$gc= zPst}J7()i0TykPA+@dPc^QufKZTH$Hn%8B9lc_$r)$fIs;R4J^T!N)`Ie=7MdjM6UWo%T&+n8cJAg%XC={nxrAJx=-uDOsQLR!y9(I zTlz>sI^L(6i*46k!SCDZrcNPE(>hA|l@x^m7uT0C%d>BA$#NDGti@lP3; z6kZp7SB0O(19Rcr2e81c=Yz(h^F1*=Tl{(ol>FyQkw5-jK@6Q=jfX@^Xr8CL-db$x z_VB;dkJX#|2V?h?7h0t0A)Bc2h)6N9Z`*-Em8?bM=a*SuP@Gta$!eDxl0W;Q@S4(^!ksFkug{dYqvanUZ2sX_AJu=p6r&~ zmNzw}wlGHAMlJc6pL`Y?on&l{9Adr^bZ1IUD{nZ9(r^m=oxG|#ked9_j3_y?9dC33 zGbO!#@sDa}`cQ4$9GZNGThP)|eo#wWse)a5vvmM8MpLi+BmZUWG+De8lf~L+qF1^H5M{=ZL8+4gW`GtNX3V4g+ zJfhz+THVQXzR0oS#5*uDT;7D@4pxk>cJb1Rh~mCla|x7472Qd$%-$2kzN04)x~SAp z2FF)Qu#cNo7_rBr_n0YW2h`O6fE#6^72`vXWp(UcX^@fOKtzP{^7j8aRoCkNI4T5BTrts|X92I4A`;-zrXg?YTWs>fd+Li-cJfu z?QJzbIyUB2Z05SHYHAW2H5%dSP1D{Aznb4Z~czb;p(NHRjL6GdmF)v zzztn9XKU+5{nNz^Xi_!yyO8UIJ={-+ZR-80G40O-~x%$s9iHN! z&a6>W5nv%+Bn~+m8d`pQI%EeB2F)s8t^(oc4|I;9$tQEDFeS6QLR}P8W~R^lQK7!G z6AV673=f66bOk)?+GA`cA!4~izt`Io^1Fd82rcXDOo`I_wi_Yjc1DeniLRvoQwgN3 zEgI^yq2J77C;|lqg(y%=XvB8JF8dZL+{I0M`LZWuV)+J=)+l7hLA-XtV$QR#4yto$ zc~!a>bL@8HB69O#R3diH&KFE$1`IURWt+-IWm?>HNY#d|s>33fOKo4Sk!8G=5OipA zs2LdQ19rxS-~97bsGPA+s*EvU6!$SDSkCLoN(VNIi-wcHoZcz+g2)SQ&=3papEpf zUFvngIK9t9<9|zbwZr4%$1ENiI9o-e%L zeZ_OU#f0V|sg)z1ZuIhGY^`!71>{ucUe-PpL6-yG3-TwGY)@US!NMjRz9-%Lm>aJb z*}ZS`H#mfR&g+&|E$3_A?^P!PcUl>sb8BQo#Q4qvM_@t{zD^F4U4!fzg4x5}ob1KY zf#6>Fmcz{tzg}C8ug@KYk9K4icLJ|#&hLNPQ+qg;u68;u-tG#G6n>@DHr;k~y`H_Z zCjFU?WXQ>XDER`sg(lHr{i=ng4z24$7jiNe*k|x6aoZAqOa$!U5VhoLMB-ev3~-)d z8kXE)h?1(C`!Fo#*_{TDGNJ0*oA?jSlL~OZQ1CW+8`;Y74=hnkG>BQ`tqVQgMpx#k zf!B`c_i?>kF9i?if!onp@`=-Ip9;*Sac^AjX32zX@`%k9de=G(r~NBEF#_(-yE2w> z6T=VeoEi#eGp9jBLeaeAxL!pChs!nNM|X7pzEH=%dZC*)71ipoGQBM3@h%O1uGc5E zs0;YqM81R`;TrzhpSs+EX@J&yhAI&B_s>4I=IyT69ezAAxosjNNQtm zfscnOc8RnKtYtX^eD$!E2>~Y)PKS>__k)R8_#2t`IlVe7Qgq1MY!mmcKziik4vZCw zm$T0oe1tir?UBkyN%i#{&F|0!6gGsiN7(DR9yXL#p2yk_`ft}8kgJ&q>x!RWzG!|(%0OV z(TC~daf=zWpuLHLbw1CV5wz*gXTMicPYW|4+TD|TOy2A&CuNhnaSwFnDAsAsMnm+3 z@XYy`t30j`6R5MFFTg9A7Tz53C^ZV1@`>5m$Iq_0a~aH^fWIt}zib!=DxBWr`avQR zzX$F+=B^p)%=N$LF_p*>za5%i1O4N>V*A7ZOpBs?^`FIq5|E{_^u@; zeoyq!zPo)|vTyVqr+TQ!3n!qc^Wo`gtm9OmOIBA?O#EG)T{n?3u1QJA;O|sFO1_K1 z&f>Y~N+^XU^uk^%k*}t}@k~J1^`e@t ztN8TtWI27J2EWx_AR_XULV%yYkoSfQY6O9zFEQSnPjrTBAH%u)$G_?@i zzB?5Iih1g9);gL5P;rgx#;_C!}JCvY9R{=~=y2KXTpo(pymxMP=YR;!~#^$9fSSIXyE| zyfps>z_HfS?ic=~nUwEO9J2bssuwT-Q9wAIrk=;cC?AvQzIL%}FGqx}CoElV4AF62 zMgpABdNC^3{Aj?q_B3Lv;#no}@r(WLi*IQyhOOpP5r4k!jjg%CHoZydY&w|ao=(zT zRC|}rpmLKp4;3dt^v!IAkGtzd_Y2rqpbyErR#<%S(j8GeC>rPsFYghzSc1NFoX(z; zLgG#Km%wz2=T@|IUXibntI}U1d-XN1s~3i6DP;(e`dazJ7d6u4Y5X2!H|9(L6}-GS z)v7{`Gp9+BWz^J&Q9^?xgL=8{uUf@}$njjXowlkluY=4e0dtE&*R0gj{Cw$C-1JOq8 zFt#9F-xP(3PTXipX5z!;A1(p6bMex~uL{10>GCbzS)MXcOr-B#xHL@bm9h z@RuNs5Tf5&N=F#G6R9Y>6aK>!_Y1PJveVX9B*2p(PzS}5Jba(38NqlrvOI z1Lt{$fwXu*XgP*>`&kw5LMWqHZo%hwOOvk6fc$cCiC+{PsIf>*jz1cP3VjWF+4~BP zj1J_TtJ418B0D=f4G?^cv_T;e5e1>XZj#@=1^wQ|KtS+8cmaBe@KqhXh~$zppaJ71 z(D<@_!>vobRe@|SXf53d8z)YY+q*EUt~ARyg~j+K!r%B$@*o08`#1kwSu2G+Kff+2 zl{I-%kOtMr@Ud_=x zN}Lr`aUF^ejdw&f2L>6$Rc6-)gHF%c5@$Zw^3{8Urp2~5x7DW>mzIiuQy9Y;LttPa zo+=_#4Nx~57@w{I5^+sk$w)~lsgn;vd2T0qB5|x?>52zRtnFL&E!9SweA0TP6kY?` zSf8kV1!J7>mvE@JvCuNk3f~)u zs*~UHOmey~7FK_-m7K3b<@X|jQe+BRm`lzxABWAhI>69c4G|EerS0e)e zkii+zuT<}zK@VM+n_BAILC^ODfs7>zmdYlh2?xKk-@Cg*?(Xgu^4J4M46xqenx;{P zmLz|RadNIvW>K&&APLs5P7TwMT4}KSwUaVRD5wJ1D#YD=ujYrmq9QpBO<(r$%m{HyYpa8U z13y3i9>-_v@#Kp9{9m#^sADBeE7f-y3(BIiNHQ)UqEu%o2qrT71?N{YKUyZr>Mcs3+0wX+ir3gcsyXZ9D9NGV}^ULc0odoO}-0#IK=h$#Mdu zLG@v!QWAQ4x5g-T`SA>eKXw#URe|SvdWKJqWkEJ?yk~fR(ylE~SI9)BpP%qJ*C?20 ztcle)7qsBKx~vSc<S#!CqBr_5LVMv)>t+c18yCNW#_V zC}5?!?9R~RJ;GHHg|!LDOVNT1ssl4SH`9A^lhh!T#dy+Q#wxZAkig?;KimnR*j+-v zH3}2pk51mqrPMEMULTroxvC5M%+E05X&LVxS}G$`S^KP5vEOloN@?LR99;1n%lh1H zX;Fyg$i7gOI8DFdIF=H)dAV?)nmSwt`$avKOQB9|uFF3DI|!xCY&$iU=ydbLKAjN# zeW@)jUq+nWTXp6TH-dDocFoYamCx}LQ#WTwncZpVNMa}1D4i3$Mi8&-#LQsVf`XtB zboLO()lv1bon+6R2Vr?t*|e@59WEV1(eH~8f3Y1U>lSkpQXYT6Gmy;}1?6npvAA-R9%fKKi0}OEtMQ83c~6^iz5~1h2_Hp5e$L1m<`2xGb?AnWzx}mP4uN1O z>uBi0o-ek&+iu4apVi$;a!^k!D@KM!X4EEzTlGDJ58kdSwwPAyM?phW6>)SwLbN*< zjH;6yJY@Id-*Ks36cHc}r9#2{T!TD3yve$8=S<&C`3Cird(wz%mvdvK)ehOJIcKKo zBbC>(%WTb|<(oSOpUNELRZK$RW-}iHOViV^XE^vuw8sXLOvyl!t?PMJE2AAkgFXte z{;#vv6;02YYUdv&a?1*b)6&x3!-rQy_zu|Ox0v~OHHcd9R>L>wIWl-2+ zR5+a3SZ603gOyjaEX|Dd4U-gwhoeXG5n<7HSo=k><1d%#9(Qd zizqq_&vd$&98gHyNqGr|6r!4oT|-f6bEg{$4dF_~oP~*Y{gV6YpMl*|%{(yw#E)YB z!%jXCEK4k@*yRAmvd1d4E68ZJPypeFrFp_+Rx^o_rVy%SYKwz|kV@xvtKSN%y{qP9 zBn!*h!%S7^C*_OPuZDu^S7>bi8qrsaoZE-33po+Lb9XO0C7ed`@o}q$(=sqHTo`|Q zJ283oEg$RRtz_in)D*BXp?~}s2rv2(Fct`M7sON#udZK(ST4{h zaV0Lr8lRF$wp>mW|HV|k3!16k$|UuwR6JP4vRUDDQ9c#qB|Ux&IP!*kSZIHqD!eWG z5T!MkFL;k5d#0HXI9#sxbk@liS^+1oeq6yR{%lt3 zqlm6*PYv?(^5>Yi2ci}xY|50oS z=KQy)#C`k9*SuScNiWH*3|zW=)C`Kw`MZKjMMXtiiUi`uUw0eXLNi%N(H40|{Y$(W zU@@0`9SyoUj9zLS@%?qFrCMT~5T~r{4B8e5vg2Z|);S?0XuHXhP-?4x5XwENgQ_O< z9qAnXA!FF^Ejgc5ljg*^1Gi*K}b*>ew^zaaG1IdHhEjKahMwrRDjl@@`x zxAX)bem`a@>HiE47+wcX29J|l8(-=~{3;hy30K+Zu^xTj3VS8P#r$ILsl2kxlU5>* znjqb%`^41fQ*%h=Vqi8omM{-LD;z*fFiTDZ4jEVa`b8x=Z=2TX#EB%y3FCFgkU_40 zs?d*=RL2!r3o9YmT|85RB!8FRYQmH=H?v@Annlh8xw?>h_^5TQ;e8UPK*+u>6;*!v zAyPg0h-ZaqeBAW1=aZ3dPJ61r{q z7u^>8B#92=7HA?ZbLD|1jCkICUQ_KHr^%enE&O2lK*dbM;gqOXVJx`M5V{Og&~og# z3sU0B#=YLJw=#(8$~NukFfj#MXuls$HWo=1u3%iY@e%~!~@YrC4sMS0L*lMEp;Xz{8Mm*6?hzfs$U(m!&X0!5s=k^JM{#EZ;P z##qn7VbZzA`PW7_lE}Y9Ov5$<{Svy zGJ2B@*4uRvSl@YFY|5Fn`Sp9jfEh*jHy81h3m(tQaZ?xm`lDKAD08EZo|jFZhBzWc zZFyv9Vwt)=_pQ98$@DL)Sy`{qR#V&3iS_u#51Wc(zr5 zv3mKz6LKJas+x}7xgdI=5O5biywg^qyt1pw4Td%^cYHyjOC*$G$U}kobUibcH+X3> z#}Sd@R1nKW+E)-HIIorkSI&%jQ9@51eC`hmD(ANenaaUEx%30ytvQnA z7Y9CQ=Yc=s6B|({D%IHJz9YV766lrfW~j#aHHXJLeNz;MfdCO@%^(?}ms32FHZ~u& z+>`!#)1V|f5c~V|Z~^4eLiW+i^t%sN=3fyOU#hg?P!Hzo^{)G^K750yv0K(LH_7AG z?N%LCp8v|IfOZ9tSN+e|Btb|wkdz_p;Q!Bd^Z$Rx4(gGBqT}H`g3oQwy9Z@w z`M+)?FVNNmV)_65YRd;mxdsOZ9fi$y4-Q0NAJSbFlB5gj>bTO;33g5&tq_v%(@fHH zo5f~J<0e8{b+lGQVCNHSnyye^85-oBIFieqMqTYzQKM>qZ3&r~qZBSa_m^KIzef7Z zy)EpJl#!GfVQZ_A7W3#~y|`IjbQA$Z#8`byUxX8$3=3P9cUZi6qNe6G>>nX78hg_w zb2H4s(5FYQg@!f@$0cti?d?!e%mpLnKsDAIC5W9$jV5y8>Ix^7(h0OXx3CXo{VB#<9GvH>dVKUG@y_~=f z!LK)->xrBdy(ynS^dA!H-;Z``lr=#U#c-VADgk<9(EL`Re;2`vv@8he`PU2fuc@h- zo}JC<$EF8tv|i_cdwO~t!-YkFMCV^N-HG;}*PrNn3RnmTwqH7PfS()TCF1{}KVHDi z&;X6)PqbmnzKID1Ik`xiDc3J<=ZHN@CkMb!u8N!~`?BEG?gSCS-an8j-PQ9GYl>o| zIwLM{$id0!OERMHHF5`mr2za||Aj#9s(>%|p5wiY0!G*qr)hp-jx1$hRpH3cfr7H~ zG(g?%Xi!w-VA~Vy_29C;f7c0cHv4AOU?i zFRPT6wsF6Mhw=NLV1 zv-htd9N_=g^!z`js&HgZZZ69UV6q6CUE)Lk4P(W-aSDA(tK;!muDeGl00}uRX#3c} zTXKQ6?`l^g!iw2A#X2B^%g@dAqgw{_fElX>CXGmZm(z5~r2vgjD>)J9lHaeO$m;`V!oZ4GJd<|cFx~jKc zs+-tLKBeBp*eB&<`s8)H{c(ETQ5fBaWaI^65m;4K)hxIZnQ0AjzyuhVuxTM6t44Y~ z-I^|v1GJV1Owq-Kn+;u=I$o55#fY1ev$noo>Gq%RSs4Bc2nR2~T77MOJnJK+NF6b` zhfk0m6)s%L>qMKKWRcj40nzQBneE z8!$lj_EkYa$mc@I$m6+{$fA+s=dp4ELPKj0JKRO}0Im@=GL`%L_h&~&U?vr9g#sUq zpG4uXE2J62`EMZWL=GRX+a`XK~ zH0*TpF{Y;>xIt_|&l>}mwC+KW0NT9QLd2hr zL2?`Ij&x_sRSB>UB$iMA_KG$Y_Gd^a43ykwtjtdBYu1RZ_o%3t8)uWEMU;33@%w%^ zLKt~=AG@(_@y18(?IZ=Fu^gp%&>0*s4%`uq7tWljkxBBGdFX?I(|tE>P*7f+lnRSr zZwT6B(Pr|kxS~1I8KiMVaegT4T0%dm$(!~k@X4wJRNTenZ)@mFVl;^t0KYPbKUYLT zOG(j+C{+FlUa*;8lu|@Ynvd2+kpg*Rzo{b38McaE8%c41KjTXgvuPVW%UEJ!AYw$< zUiHf7v%Dx9eJ7Z;jU*aF;5}cmJTu1inPQRu^Rh^-(r62N6c1HEo-e(aDO-hrq+NhT z5sf7^5whA-K!nAs%r6S@7hGU9m9Z>~uksm1;w5jMOtLT~^ZI9KrYR6Lrd}#C2VD?# z@OKpx?Bd2|QF>>7avjNa_E$qOmM3Pj0d+B;bsUVL)bVIW7NL?^iXy%ALH7~sbC+}fLoW^1M{u7>TRc&i8U_M2INiQ50_hzG; zx;jt}XYdo5tkl-$;{lN}F|`0y3cQ&2t8P*|xzBrLQMWaO1RQ4)X!co{B5J>4wJR`G zW@5J=Xt)#vEyl);KgH)s1*QlI;ha&%tD%g2UCk}YkI99bDSO8hPiW;`rIz3`Z4SVT zbYA()y~BZGi%~inP-5)^c6hsvg-q*yg)Ru6KLYFYi*6p#pdREG5X52g|H&x*-^a+H zCcrZpl*;vwXZ#n&{BNEy1Hj<`-_J45-GWyLpSy1$j<8YUI68HciXEUU@95;@G|U+n zAAf&$S7ZaMsK9Lkpsp2q{O1gsy zJ_m0d4kxoa&gKEMoitd(>$-Vu0v82%pobZ}1ueFFw*zckQxjkO))}x$PR-Wf=Y#b; zFK3o)+gm+u?dfmX!X_zzemmeq0R&M>5*Z|%+}zNT5=AaHbYNZl7Kx36Q=!)`yM1x9 z5y~=d4?IuJ@JUE)OiTja>*?tMR~iS9!Fd*0&VhRW>h%E8MyDku#Xv_FTorxseDD1n zSw;7sD^l9UaGJ?2C=jOtPCswO#rE_76Qm%-2Vem+58p%JF+(40Rr7Wo6jQmG`$6Ca zfk}fAS2Mr4IkhB8GG^Nq&@)%LySqn+TZnhz(tBeYUKZ8X&MYpbNS?#Z&Nh0AxafnY zLo6sc1%y+in%;L+fO~s;&Hms3LBQcWYhHF7dwyQ~^W(`xj9#R)jEn-CfB?yWjGf(C zFcyt`0kHaOcHST(P@BGi_$Op%XE!?^33J6@8UettZnHCL_)BeVZFx3c-rK==hFzkF zhzROAk`7UbzyIO=Nqb^Uj4)>w<>Wh~-QC?!gfoX*Ti6&FzP&8FhbjsRWU7Q+4G>Y9 z8@Sn8n`e;;eK6(b`SuXE&2mySNw$hSyF8|`Y%!RXm9^;lpN9aO5O4?Z4S$W~vRQ73 zM_ib`Brv9!DJm@$E#x~FHRX?a6~~(p3`efCS>YS}+R)sbYXR^w!B&9TEQbw1ZGQbI z2|VSpxVRG(Afg=6aM7b|D@5-qC^VD}kZ;p=Ei5EIt72dZ(Pt)palc|@iyHiN`5qa$ zsJvV}pPHK5%$rUQQIeb#2?+@W1;ri&TsYCTl1mjW>67~w5chu$p@Z+XUa#H*kTWL- zM^yM5V$$eO_W<3=$yTHvR8m5(h`SZcTnez0QiJ-8z$BogL{#~ykJl7%H)8AM$Na14 zp|q4yxy#o3ehDC-0SkwdwtKX)pB7I5M@m!T7DqCI^WV43L>Mh2qv)c4c}Y=oJJ6~Z zz{LLd4Fu8iNMz7{?CTc@tIB{M z_^y&cDG2~N7P*%TaeJaouC2-aLm;COU%&qK>(>Mf7$J_2eFO*y!(u=E{D2WaKz|FI z{eR<+|F2`jVz8T<40pK*kzJ4R;VOZW5Opur*k)P>PEB25 zt~W(GC!J3I`MIydP4vQT#HUNz4#FX`<6eFX=AqIcX0vPunjX~;422_S#WKAQN_(y~ z6X~69Ns5HSpw`Ay3(bL=9Bfz4T{`{vJi7&XiqxC-x$Uj;^ug@bZwfa0glg#n;))7p z*E4fkp%V2m2eMC%GkLtshe7WO$9DN0?dSPI97i^%oV#9LtT04y))3C&tBvO^XQu}im{W_|5RGyfj{k_zPQZv9&&S|uB2}dRo zhdG3Pd_3TPzG7~nbetjY#)J_ORs7IBTN7iLwfcdd3r111y5NJH0W2nx)%F&%#PN;W zL=NY~wyRP~-`ul0{81bq%H$2XmpZHASQ;-avCCNbFhmwR_v(O!Winf^7BY8X9K5d2NDiv-&{SjJ8j_FJ3 z4y|+UQqGB~F1EK{Mjkfr4yxK#Hs@D#)~(HpDO(*fTUxi8(%qOqZu%A(UqFg+%Hv|L z?z+8IOYUa{-DO&pu}fn;b50w{d`V@gTRXY6N5hNo>1k1R4uKNc&X>8K%!3wJ)w~w_ zO>SoacLL_F4(0RoN*u0+Y{`xXzKPV7lv}_Ao7Uf0-`o`Wn3xDeck)If;Wqy4jMc2nK#TBIg zEmCo+jHM69e(|lEb3%7bU{w5_zSp0)pgI%zL%X$l(SW%=?i;9Zu zE_c_v0v&%Exq29t0U-L^q@VOmQt>_(1Ut?}#`2QxTI-48lD2=9vO0C3q^Sv3w7m*a zf2HByfMKkvJ>$DcTxTHFBbOp7uAw~w?bWIh75zLDdiSf9afhi{iU2n!XXoe=;|nOK ze9pe>a~{~Dpz`r`l7pFmT%=Djc{gP1Q?u2!MP>Yw3Xvz@y*owORfS%?YA-!r-#ti< ziCt#j@`^7PJBl4>KsP}z$13z%g_fyXt0+&;xiBjIw7O^MUaR`2eZb6mhXKf`(E0p@B6+M-Ev2L!EVWozO!k z*-$70C+AE!;sRE!2C`5Y@sO1?g8&pDD=U3S!V4-Z0kai;O3J(xQ5_vmQKU;{o#iHT zrU9xkMm`5V4r(H@Ilio&udq)RKVQCl;HaT+`?=2SZE;i}Q=+ECmh&)ppX7L4BlI$a z;7bTly=rp(hw}FRLwRdzI9yy@j?s6!U4bm~RM&A8(!nxaQjw#*2ij6o4#e zD>$r3_A`*xWZ3sEffJPJYC~J{!V?pH!{!4|ycrTi6C=lHK@h;z1yF>5_o9EQA};nD zoqnhs>FZrUQ_07!srI>YF@D`L~biEY|W^2Wi$?;Kb+6WyTE-N?KbV!NxL`3>;5ZK}J)?$WLbqmpHsQ99zN4 zyyhc&mLRw3nw;vgG9ItOe%(1U_Ub4?p62$tg77x+&G1M~Oc&egldZq{qrDVx_+53nDLB?qt4`VVS*T{R=qq$d~eH8`VFKe)XQZ|L=%q@WZrGZnn~`^w^DFEJ^Z zq+#WFT8g}BX;$Vh?(XB&aAH1xjB3)jBrPq&4Wt#w=_>8J1;8KJYJwZdz~J}qmPK@M zY19ChYL87U=P)KfL^A^H+^YApCkLM^D`+3^yR!2J3U~rBeUYTO>zFzLUm@@_Z?#e~ z9%k>D>0FZ$>*m=Cor^>qdTuuI9O2DSe7EEDUe<#8(JpVe!-RJTNwAB1U!_=|5K{6ww{{E z9Y&x?&pWSkyw}5iSte`sp4qx%b2|`DyVt48z=b5}F8L0q+rA!_1Kmw!KKa8pdf-7D z9ezkfpefr)D=Yvezm$HAwPRta0Mwg~tLN;(ktwmu70X!>LXRU+rAth%a`AqPx^@zV z2F&q0l;(D4sC{z>4fjc!lvzhTDbUc+(9EW-q{NRgp3PM3)Ojf*C|797Gr?*A6Q%wa zVr}#1@W42H&4J>pXHYpan3ad;+ebOEl;lJAlh*4%92&M1us7BXy<0p)SydJHlLs~q z23AoEWq5eFqf@7-rsg7L2)o)Pa`3y?m;{K=kB5~IQ9ewrR)J5;Es`L5IyyiCD22&J z%_n0bDk9R=18lBA@GAh2E8G_Rs~Y>Ch9M<3XSFQuXY69FUwI%rY`Cnra zRlJ#Ato(Da5bFcqU2b&fwyx{wD17C&g<6l|dItwY3PeP%d^}tCRz6Sre)kWze-Nx? zkG{~ooTe!0w5uCxZwJ~>o|38B20=2ZV@Ls4zM1&Ek@^A$6LNwJ3f^zu4ib&ZA?JZ% zW8QY_opMGo%pj-1!1KbnOl(JNz}XGhSjX}kpcfN&l$V?NHA1KwORJYLaIwIXVJGH& zv_C^XI^hVx{o&vsf=bdu2={RI4(+G}L0yi{rSjPe{0qVQi!j+BD-;RqY+1s$0i6?< zgj}muZa*rZxBVt`$(x$A)n`r5s?nRU%W^XQKFO!3e&(gWl158|0}`e4NqP(371d{- z?FF)B`0lN-c%5|x-z;!5qL}v1&>P8(iWW+oalXU$fR#S(!Shbxv_slYzx!qH$1O_i zL%v=*(1>yA3|Y8e-DGdPFyGTre7xB#?~FqwH{FV3rU+D&^8=CJ&!pL6tVX&6AbdSp z@_(pu^SzZx=`HOjX+HOu(K~mst74_mShmbdGhpALecQ7QzmAS~Xe8P`@cwDXj-JqW z@-b>n7V%iya)7!5*f0bTSQKrJkHP`*9hS)FF;kbmeo{75`_ms{2Y;17r9f+>8l!B>(>%x-kTkh-j0gu4Y z%@JSEC6OMpZrF=5aM?sNi@4x6+Y##f-8K>BK;9i?0q@yzi**(I5yrw~9h@U8U^@t% zA>SV2ps1BJdF|69*~~!gWwE>Oww0j)QmfUzT!6ilmV${JQ`(?qL_v?73Mb$y_#;_n zF7)ELKGZRRclkPKwNo_AI|W|wt$b?t`+9K3>Rx>I8Sk{^TWbH=+|^~$YhAbQZJtd2 zQHb>1m^GSU9?5gq(%9$PhE!ARq=jh>Ow*XjeSOoZA!2Fv_$vk*P4DR==Ige;jGlO+ zQRD5EXHS?TYDkgxX4YZB=muWwG#B?9d#?-&@@=(cT4#U9)#khq5nFxoRb-In@4ug7 zNGZjq^;~(}`gVW8gCHb|fVi&g`F`!0Ys=fcs+` z%$-f`4)p}@HuqcWT)k8Cr>{?*F1!m`VAZ_!oL9j(*wJfG*Y%o`UV)O854tVIyG8xY zKmr{avXEczec`>|#=RfQ(SEbkoC;r7H@-spaQryeKKgLt?R{@^n=e3VqQoj0x#|W> zR~R#`W?sDNPmjiUVgF!aGt2N#WV~xsrKE_5sj%LsNY$6mDL{g zg)K81U2SQ(i>-BDW%avV|H=1R^*C(yZo5y<6SEW~G1Ql$W6lS=+C?Q%U|`O1hzTx! zALx{-^UhIq){z6?e&a>fF#1Do>bYglam|K4fy9o_LdiOnDU(;M{8m-bI#v`3sxFyB z#uiTp))3By6Pq=d`kzaus2BZ+s)5H z(cC9p^++~$_K87Y!7M@oA53^Vn-P!?E5;nkl2lS>jJ55Q{m{L;=j^^%XqJ&C8hOQ5 zMZ{$#nD@!yA-0{gAaktuY$t|832W2yt-4UaV*s)89tLr^REOJSMdE;pL9rhjGOOy|VNyaUi0oE``IlrS5Zq<{&DV$G&6Kl0(`g_F`zIjy^CQit3;GkNazj!H^Y39bE>ovB9;tr;aXf0fT^Dqe-AI{)VFh&o@{N8jUk5@soe9Q z?f%?ZWqcLz%K2}D>6+-AW&9HZYW15&IbxaZWc&cVXUCSqW2NJ%=0%usumV=1JNq|i z-lMEiNUp&-yM#z$;ckxjJ?x*7gVG?wA@f#Ob1L2{XIJm(VGo4G-M;+ws4Aj4eBkP1 zEYc`J)M$!e09E0$Ld=gV1&o6XgZDs*y|O8VL5oj8C@R_9%)Jn-CXiv@!17I>W_f#P9ih6!FEwM{B)x;0w}GMf$Iubl0B04-svH zM)CdPmi*8c%=P1YzeVhiyvLA0n*twV?=0;;SYVWa(;7m_UZ;E3V*z?HMtpw<-%YZ< zt^Mb;cjBYjirx%+`B&eC|E=Yf8{aMVU$U|ahfPo8_75_DmC)S_gPReInR+udh5X&U z#S$4aJ;Bzh-e(z7u`v=2X3=V053)B_Dmz{nfz};1{8bYMWv(nm(Kgy{4yr&S2yYyn zXLmEQr3h`siB_tNW+ruZ1YTG`+h(sNMx6!Q>{dd$_HBj@r1HQzPPdqrbD>893X@zb zX9_MZ*ZyOso34f?e@3yiKr#FK_MUMvB4@{Mc^4Q`EdGV^k~mt;hxW6j0s$a0;IX`2 z9C0vPfw5AfBUm&Ewp`1oF0X{_6N;%4FHsjr?J3w!>qj3I^U!qmZ&EkDEd$G`2i$*1 z!@**o{(N)SUKi zb>JcQQn$JnTM6FH$!h*zkm|tdkY1BQWMavD~l$99_)zhUYJF&61JWfdf&}PPJEq@EF zXnywH`3?h>wbs%**{4ry5$sOa#4*@fo32#XC{Uo+T^*C!6RLF*C+b>(9?M?^E<0H_ z^cF+0tMmj@f=JQVQYRqrhV}%Wy{Zur(D{|@ z)C{VS_m>`x7Iij2*7N#Zn;4|V?Lsh-@iswvGGEWzTI6;LQ1$4$3%IAqkD2E7UI2xX z(+v6%zx{2q(%wUqDuH%b-13ZtYLJ{6R(01Z9|sp#P0B9;!=+)_3MOk$5DSL;*+Ffx z$N`4Icb|okdlL6ANyGduW)4}YV%{(iPmqfsB@^>?haZUnt&nhtiD z>2XX-24n?pKuqcAh)l_&i&|7`xObFp6o9F}r2=%XGV%kXh2N~SCHmaaiz6r3L%P3< zk~Kyrv~3&_gSSsb;s^V0Zg0l(;dik=1yq2(J0K3Sl$aI==8+CnyMh(q=|JeB+q7~e z40F>OMX3=8_WHs(5%dS|`t}fTv;e9or}US|==3{zBr`KJ@u-z9w(_p7Xz6&b=);5X zn1QYH;(%OXC@~neO*bCwDi8xvW zBcl^v9xFfBy&VYwOmU9q8;;VHZn4+qoz_O%Bw8w5Btvp5Ps!wRmE7xdP!Cs{kFvy< z-i0#?0ht@{Ek@|4G6b84T*C*$M-6&LNZT$lpFXt^vZdiTvJL&c#_BA{3EaLf7k1(ssIk-`c@eTfB8%DsLCo__0KMk zN>eNe(HgM0W1~o-^ZyCBipp9hjd78_5(6NT?$<5C(fY$iE(vmBfAY z_I{v=z82KsXIi}pT2LtWKL6V;_}q7rkW{32F{28hqc<1=RA-wJkrvf8+l~tlkS(7T zVQ@Pcc}o#}nIu zp7a@ww&JtdFQAga#?pg?IhB~ZKI4KeNZy{E#8xQ0Y1Fdd{#CDbh1jANrHk$atL))P zsX)yVK)NJhj_01aeb&nyvyp8iiV`95yZY>KkkDjsQlWi?pY`U7PD*l4%LzK8FH@O<7Ro=F^X9jS4OOf`28d5=V+DLC1P2Kc zQxIOi9ttO9(n`gwJHpkbc!7Y9_;ZGWF}JZ9O1A!og^yX_1s7LcG7hWwepMpTPyXOF zaX0$3#Q2^T2KpQw9qZ4-OLsXfrKPtCh_GOD7Yc946$`z%C zhAb>T*1mUoy4|y1I~^kA)}H(-5jy@9a1ar3b)Gm~{-(h~3-NRD03QN^>vl^63BYBE zqWW5q_sMRAdVAl_l&q-H^NofQhYd1tt=^pME?F0=@{6#=PRkze9h$PkE8`GBs8jNe z)+#Q|nx@8Q z%vVg2ENvkD1Nu-kLnav%r~tq6;-Wihb5g9|K+&zL*nydwDY((FQKwsqXpi_6!godg z-P=RJTVa)^(dC3BS|lPeh|Q$$mR;T2bfDKsojqc%(7?+pX}ae-ZUhho{k+YOTMMz9 z;B2-Bb(>I4=1%oDy87Y8peRPlqSBay&bzCYAg9@sc4C03MX}cb^j+AVe!@;My(zo)QdQM z^0KZWS#M<}uyiaft;LZwR$Vdax2<+@6o80kOy_<{SK|?r^+=x zws8F#IGbw&w!R$|FbD`I0-seR(3!%td0ln;W)vli5}JxcaOd zLY5ZoLK<7oyohV@O)yr1a*r!_e}Sk{t6); z-WSiiIN5iofcX`GEI1lO_{d@cC0C%NKV|-%I!lR@o<2l2O5T(;{qL*SN7bfdMb++% z4qqeX4*(`9s4&1M+Q`_L420P^YUk`M4w+tAktu||L`6jfnCO4bGE;w~kx@{D{#kYj z6>2c~ zf@(MdAgx4Y4U~n*T-jTr6}GpZq~yDy@4w!87edg(FrFL5KE!2#IEg}ZGSa8r`IdHR z2{YG=^fQwtyIMJi?eT#nw7Jm`igC&HcW#If3dXw>buOtGsqGz2`z9r^aFM}naZeD+ zl9tF?6WqJ-SefxACg!6yJADQC4L?8OHw$-TBY!u%A&C-#ow`-*dxh?C?%qkZf@UZ- zj-+hhsy zmQCB*)wd0g$>kFLOrR6bz^{95HkRMQPS046V(~lZuA!Z{W!cVL$*u{sbCe%(AqSxcu&4 zmrOHlh0xuuOv}Dxv1w#tj~ACfa&JXsqo;2e$nNbHyt})5;liikY3j{P8)2f*%cc(F zWCE!b;pJ;$yU&8;1W}V=YqG!VoE26Yn7BYlN=llVU&5}Nn+Gwg4R0QJfK&9 zBqV4`Ueu)Lb_kE>@L*8p2FoL~c&B%$YWxk2#er@ML_@X`%9F-h zd14`Dicqg&p)LQGJ&5DV5;<=de2dPo=GDN!LamHbF-F9F{a`?p;5CiT4=qq>+JfwE zG)=dI2XX|a{YL$c5$%!?w}x)Kk^mdm3RESd7%lc#g5TzknjbJ_xuE}!}EC0q;U;9(A5 zO$)$};h6lWWlqdVlvLRS>^5=m>tzn*_|+EW{Oqg6Hcz}e%Pdv%hPtz%scs_PfxTJ} zrzwbkPXAL_Uyq-_9-UNTO6{hr7ozhKf%EskH9LexCElOkio|Wx zLr{Fc`SGwHpENIa7jm>CGfdU;>AnhpKvcF8V<6RaIiC-!e0LSYQ)TKa^lBHHjyq*a z%CpZD^u+GQO0vyul6*y6&sC;czePHubGpC`Y;5N31{jJ=^1zJ?z4j>)TeA*}d+ZW_ zT8bfg^tQVIF=Jt1W;Whs#R2kO92fxVcl_+L7ik4$$5gfb8>uDsZ)Lf-FbP@cOWyBA zw}w=`?h;nJ4RdK))hHh7Q0tjBFxL;5d?Q{!uPCloQI;ABaojHrh;2>JI9&H1%&<)4 z+9%M|n8(YDtG`n2W_h+ZceUfr2J>UnEw=F8Na4_!smefsq2Eo-m6uHUr))v{Gb6=ACT_%XjJz*tecth~+DNg=qV z*k#up_r0JHUzezr>+Ap$Bzm&sQ z;->czc{9jhACy6$?W$kEcT?Np?y2dtedKpWR9(Bu0=8g+;^M-GFDurpNH5_Qgm}(# zX>wU%K+L^W#W9rgRTs(_+=ldw+$p#u)KoXTv<(T3^x7DTrQtcMPQcDyy0v2BDn-jA zyBk}9y4)s5%O0GN?hn86NO0aNTmJ%CbWdB1)liNuTSre%A2sz|n}GN55C$nF)|?fp z^bnjTT4%&LIaUbd;P5E$)6A;^8NTlA(-WTWWPI{mh*hM4#qY^IRHEZkJyhIN9a1!} zB08fFdHOA^pdJizee@FEyP;)Vp<1eRMla-Y>%&s%(-jM#WPH;CPZ0uAvF$WhA@wy& zlyMu+Kll}k=0${-86TS#=q}|P7B2T6Pbn#CTWk?IGIBb!T^6q5 zJNmVDak&)^Z#)KmlN<=8x4V}J-j5Yx|1C-{OcxsYm`f8a&Hm@f|CCtv#o%+;18`h5 zsMh3q_xZj3dguy|ASWy|GE&M@Q&Ur_FbD~Vo`(%>v!EWCF-I<_FAva_s3#VlB!Mz0!D34kOz!_W8r8<0`omp3q9hZ!fA zR4jk1y~|G!ci*zRL&7&;e1C32;vM?6b{?nox!Rqi*&kGmcWuV%>hZNXB~{#YvjaW% zcV4{L{|Fu^HYNBqt4}7beO$X&b;*jjsu>!XrK?rxRr03a&$9Act2J*|gUrWVoyuQA z*lH1{R7?g{*6&!iU#_y*6n(uOd}IGj)_#$X*5bwi#+owm-E8%aZ#Y$?k*!QR!?lMx zLRsatQn-)25_<+wQcX5{@7=xC?lf*}D{S+v=)uugDf!+Is`zj$2s_7 zA65!LL@tz7mb4`5m)l~^ImK)*&`A>(+m(CIV$a@iBVg(0GrgDCawC-2G*zc>-_4$P zndoFQT)=8~u9}ZEgSlI69y{a7xmE``O`>HI>Rg7^4I)FJYns#|(={pnn4_m&g-01c1Q8ccf1Ktta(3gj!Fq{95>2nSF7ii z3V6>5ZVn}0&n8~vGxG)E)#OhT%Y1}<6v#JE()$ab`Vkp^*ro*+q<{7V)XqQ6KztU( za#N-G+p&aJ7d-lWCJntxYhXv%Y@Xq`;nP1aSiK69yPP9Ngj5#l|E#WA`ZU~lGw*Ve z3bR(l*P@q-YlpGB(!~p&b`{d4#0cj>JNf^FYMA2L`s))E2O`oOPi%(3a8~mnXwGIM zrZA2++&?Y4V&IuUcL(~+K|{2)Xj1}ig%6lROmsv zYMGS2rlk&KuCOPVx0SEfw_Gz;)@K{e=mfF2dCN@r&b9J4I!B)gaTO^uhMAgFMT8_#_L|K^s(u;AcBVBw+%pQ`gD0qZB46-_3X)>apP09IX+OkXn}0t zYCTI6Qnp+BxR$j#H+mk|EHOC8z^$x0*sgZfx$sK#E_qg~@Hl*swHNTv~_ZS!iOL9>}m>d?O$8Yv);`O7mMoaE* z-2xiiR*oo?ccyCeor5$*wi%leDL18L^ahVMDjLADpb4-#LHHXZ#48dH-e%vVbt(OzkJ+8 zGbtxz90_p<4;YVm@`I==MccI$9=5vsRHfzX^AeshgDHmfuswk}soc*%p8m!<$#N|o zB-PJF><{aT_Ow9I4ixHmmV0T*Q5E}CBC#V%x#?5V*3wm9oO=7WNo(}|A=qGUf=yo5 zZ9=0z7~FW$lqqkjIVlCtBb1`Zcp!DO)jHR%_qTg*nXSvMFE8`I77p6%+UmO1e}P~K z7bRUTxOKhE2Ut1IsfN9uF29e(Ke+g&mU5p&+uD|)w`4EcH_A!RO#fg^8mEpJ{dz;Q zaJy~bzD(^Rxo~rnTP6fU5&1BG!mA}(_QFy5L-YnhvN4;otw;3B5ImR1{8@e!eLL%^ znI0^$1anhu96Jx{g}x2J{K(ul3;$hS!m8(Jl9g!qg2{xhYDMbJvsHelDcamzbR`Lx z4V8R-)+xSk?R-Kr>j(h@^L~6*)`Fu@><~P2TYYIMqUAb7+BvtPCn<@{N1kg~`zCwh zcty`N(!(l)5?b8uxuTO>x|6JtV(%)uW|jxAYYdNf)qR^=GLZ72VC4F}r$@ExM><7) zQp7ae_OjwD&E8RU8bhIw_Mcx=ONYnw^^Vg&q@H2GUe%7Xs3{E&mKW{Gc;;mZ*T-XS7Bf7hbVXDH2QWDC1eB$@(Nk53&6k#^Ci&{Z^%FlsI5WSsw-}4ZAUzN@?pEiisVX zx)@r{Cztvl>(8SbpTarVZ+^Z(%+b$=WMJfDuseM;kGNLiSKrcoyGL$|MlS*T-SC;` zj1*t2Iz>xlNwl9|%pO+@_LYkLIIda19L5!@P~nLLG;!$(1>e>J@9bs&L`Be)PwZ(9 zdE(jc`c-brnGX=oG;MP3hHmrf>{6%{@XfB~Z3#)4uLjYW1*RxuCKi@WFyRt^9)tf; zPAr;EQ|5|{FTt>S2@n9W_$|s|=X1FkN9jKeN4(RE_afL@OGcdG*0bc_LKTdVE!Ro= zne!2+({aDr?|-^byQg7p+LYXKNZ!g5I5ZWIimaaMkDGT(BLBn^!E@8OR@j7&iFwU_ zvsqryB5KlM5BxbT;rVpJy0QfNcJIAp#gP~R+s*qwbt2uwfe@dAy|y5!tcNaodN*wDo9MAgn4qRL1}$?scviL= z9e!Smc1xW~7PhSAbav2J!|?Ul*7bk@Nf5O27j1!)6=3+#bIHJvvcxFJC{K#ggmm|v z7vqA^?k~XnqI=}u zpcb!o*kJNHy$w1V=P-BA_&m1{mknrQhK7GgN1_}3G}rA%ot{{P?M7ye(L83fy4BUcZ^+k}8cu>KvA^B}(*%vRaw zL}>s?)`PW2VB6%=_y5CV+t-GVo%x1&pJTAGvB@HDoJE0>e)kb^ zdOvyj=NT_B0afm4KGfge9}q0xbEO>IU_Vks*+7(njIF!V`#DVhH|G(d8;EZX#P~tA zB$Li}97@$=B2{wSfT~pZa{Xs=a?ctsiSFUI;Vn@?FNy!~A)xPWd&%n)SWI~M@t=_c zg1Z7C`m%Wh{s>(^*)W_m#|*nu=~Y8*?)RFS<`g+|6_gF^4eSFFBQvhN1Wjj-KIYBv z@g%XG7Q|4BQ>TQo^4^d~?P#gKIw7X5VbfBwhc~;S6MlnC@fbK;O}LcpSj6Ea7EMeMHP-!|B9+^^Q&hqxZ^)+W*LA?#3w zr~$OR8nK}LZDTDY7^!+nUnVg)4`QG*YZ~P=S*X0#_e4bgIaj~!_Li0G`b+h)7A{ zxaj2Z6AA_f8C6v$G_3~*i|uD;XNE6-&CCe#@+R03a1;Wdfa@2C($V&oPFJ<{L;)P? zyi^VJAplu{XPSsA+{JRP5-fx1_=$IKx~Y)cKA${NdNubCRB1z zP*Ix@_sM)%az(Fw^#i%CmUFzc$hWM@B0$n`F%340`x+VBa2Dg@9VYIM*A z>WlVFv@R+tT~c1r=iPWNRES0IsAaf#Y+s)uNVA<|(SW+;MaMeXZIFtBAq+Xf;wV-oA0T>9}#ZgERS!I6z|Zu7a{G$?Ws%lcH}J7^5gdK}7mgIdY1M zJ3!Zf6Yvy;HU?s9Vv?Ps3KX?W5<=0rG4v`$cL1|NeF(gk81?!u{^!S#QlOIgZy
    xB)<5*c=e}jer6tK>fp9G%$%Yk|PfAQD` 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˖EsTAeAB5@i+ZfCOtX+3OstGjNcw1Qt-N@E0o6&5 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 literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/MDK_Build_Success.png b/bsp/gd32/docs/figures/MDK_Build_Success.png new file mode 100644 index 0000000000000000000000000000000000000000..6f421b11e8d0925a6087ebb29e777f1fcebdbe33 GIT binary patch literal 29583 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%0A5pl~TZ3e_q>C&YPIG!N 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 ilI4FW%mThPX}JGc+|{qL=shk2TZ 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 AqW}N^ literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/chip.png b/bsp/gd32/docs/figures/chip.png new file mode 100644 index 0000000000000000000000000000000000000000..e4e18a93f238aa19f927675b1d4a4320dc70e8e0 GIT binary patch literal 152169 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

    k8Pe*v0DZsZpzXysjb~{188BpP=0Vu z!qzvEWb%*Ig3tG_*`Sqdf)fqB-9Aw9S|o+V&z3goeS5r&?;$K&G@?n$vx!GOi7_?4 zm$RFC+bM0j7{cR?ndG1ETZyd&@NQ?rY;?`*_&9$@DFvOp(Y2Ie3`<-Sk%o88sFerhPR<_g`>Nq0uF@7x!zUp)&xvW4 z&?i!Ebo%?j>iy%mcbP{%Z>o_s$CKz90G?%qq1)_sTb7v~H^=wX2il`pXkJn@WA`eCV|n}U0y~{J`kk`QrfqD(YFV{IPLIa zv)9kJz4S;eHZl(jSJ-Q*Wn*o!3g75OOioIp|CdEPd{MDBmUY%a^8+sV5@u8uQw$g@0f#JWZ9jF=n;TnYu6Vp;bb0{-2w2zr#2P8+< z4ove0&?>U+@z*>UoI{068AB0lqs+SQO45dgx=QZksO)p=dN~H`u^s?B_8_991W2mC zZ4N{?G$aY&u|<;T&BZjx0G^t(grQ%)(2!CH2y&N496z_s& z_Ow|PSKYjrUF(3uiPTtwi=*^OM|$0f_isl7zlWpx7hPSCmkpfoPw*BQn%ew9JEDVw zjmFcTbjgQA65&-!nCjPe&5ZY;IaUUb5$b~1rd5PT_ZmDs3nAt5)Tp;f8naC1*ge)- z!XCq^7SJb!l!VzwWs^#uZ3**#KZ1YHToD0gvL<*_opN`M(sH9%Gn_M-k90a?-32Ej zWH*no9w3RDjorOpGvBQINm_WV935HFpmg>0AXDm~;_B*;%nc6nrZ$ahXZ!KDWi#gy zNUn37RukHNTBgn)?R?@rIp$-!kO_w)Ck-nLV2lfT1j~ZnE}~*KD0%627{D{Mho=D; z(D=CeqkSN+01ad-*AH?aEICJBJnt@GVrzJ83~uts+uIu+9-g0{f3zU3SbjDzaUgfl zPTR@XDYe_Oh%UvrH!2rxPfAV&`H`<4ZcXG*ii!+VN=hRmJ|Y_n{4FE;U5XI8*HgXm z+l0Kezc^*eSZFn5?uVNu$*QLS1YKxJwSlJkK>LFn(;r2OY1lLtS8-Un>8qJz)Ky{Z z6iOobl2l%nSsdo9w3H`Cn&GILguVr>!fr_igUU-Ik90~MV@?>HpL0rm96(35)yDw# z{s#lqX4(>B`%W0K8pttS=Z|#-Qwb(_X~i(HUb>!*Z6@gBij-K&fM)o(rKmIr<`6Q~ zrV~{j9(@|H1~o3Dg0qou2k5$qm5U#;L{*o_Q)9ue%-bPk$WX<_#NPh>iyo&MPan*~ zFMwPvY+)KXkx{6Cc8iXt#JPxbHG6+QbboJcwEpX!E0|M|Guls|Un*k*JhQUX2aKyt zU2wU(d6_3pWM@;%s+j@ zS1ZiLKjU^1{{=roh=W6fk58sJCb-WmIYSy`s`{-wU}op!WQ;yB^ipTS&bO{y)($sm zoErVx&PIn{$4K0VR1Z((@v#Yrj=F~1_xDi}M9_4nd8TaquJuVpuU*|H@%}0}3K+gF zPFUIqZ*@AHg_6Ivod=kM7b;Xa*n-SWesta(AP>TW>Kx(9#Z3|5@1dJiOXW`ZF$zWZ zr&Qag&$PX7FUT4eTbB@bqxpho4AT=uQg_Y`hM1h3X+7YrXZyv|ghnr2<9h}2_e*l5 zCp8ocBA_~Spq9=VL{Q`tdyF|t5D_24Xz5*VhLNe|X(x>xCH#@4JYP6Zf4e@c)%o60 z)rbtkK0K;D;en7-DBl@RtCKLR88>jvGt^}D$#mq#%&2{qL}*}vE>l}R8k?99kp}&t z?p&Ru6#EACg9~_;h{;I$Ef&*r8pyF)LEQTH%g2|)<+MksF+)|FwyrNXd@=TA6})V7 zCp(83sU#oE@f2rO>(C>cL@M@3@Ll$ZE1-|$*js`nkOlBedRFEG(~CY!%t9QCf(l<~ zaDqW8-??uu!G9*cB;KfYIY?^~Coy!#`aBKueM_+k79P2=-vEn%(_fDs>eAK6M2490476o`rV(EuP+hJdArZJegseRjTUJVL!SdBimW<*n*@I<{4E`bWbA~F3-kVd&{$sjQ8rObFa0#N*F&D z8`SQFh-!x#`QaOqdnoqv^E1!PEsdS1sg&O3OCnBfvDHID3{L~DQQ6G_Bdse_JiO0l z-7dKgcW$DeQx-9H^qE}y)F-M`Xbu!3C5FoH$P+5l4cWNW9L=|oS+q1Q_?HclB4TH!E9JP1Av$m=Hnb2Mv0YBU zMc8tZcBuj?#e6I#Ieo^IYTpc~9yLmiS~rML@T4g*_w1L=ife3^;EcMjDC9uk^73wp zV@sA2vYBN-)e!CHgrbsCfbX3>pp3ZQ%orH1b5VqljAZ=|nBd2E&~f7i&3I}3bV*bv zEgS(M0(Ap0Tb3hqV8A6$IPsh3W`D}3=%e=%m1*}yl7`|T4L=z^yIS+#Lu2$(9}@pE zMqC^(8>~_OBm*Dvyo7jKjEMw;{@0u}Zk;{qOl<=bT1pOS3kw2mAI-hvHu$Nw&rL(& zzSkfckD4V=0t3S5-XUWGaH8h--w~c_6|{r4omkrjspV?^i8Th@i{=(1KQ*|H?bmh-e}xY5Tr>9oB)Dc*X?s}V)K-aj>;U87Hm=ryQIV?jAtKyrsJ9pJT$N|c zAKxg)uBDfZ=JFlYAVBx%&}3K4Ig$659V%qdJ&yMf2<`_A9nDP$zEOaXUtH|Ww4=%q zG09e1T@e9H@p7xbtc?B)pKfD+ceh_Fg_byx+pW^x-X4UTy$5JD`8)lZ8PGKNG~DO~ z0LS!;GxM6~m0$mCbRIHlA?m@d5*HUXyV^Nq&%w$rreaW%o{~cF9KVOJWt75|Tk9>2 zw1&+pg2ID3Q+*=eaIe)}YlGW6_UM)<|{jo3gj zh1T}N*f=mKP_C$GQLa<Rv7*!b$oN|4%UPtQnv7a4uMbWovz3`(Bnf>V2ZB^SWNM|F z!%}Fv{K+JPU&;2`^L>1B(dN+KPEK=-m7+tIbg?6(e8*yF334aKH+yr)Vq zKxOWcr=lN0XJLL<9G#XGQuG1u-2kdz<#h#WYrn{_`h+!%hpi^#y!BQpHPLYmLph=B zC}GS8UsYZTn*6oBJzmM{EWCOsR+MmESb2`0F(TUMQfzLN;w6Y^X?290==PYzy9n#F&&CKSafLd z?1k>XHSb*2-f1nq-{Vb-fw28x9i!?XLUrUb(0O}3Ps8oR{EB?{Boz<^9%} z4%AajhKLv>Dw>*m;2DfN3_3bG5wO&_CP?`e5dRuFdZYn7!^8W}H&&#Y+@|+Y{WX*` z5YT=@_O!Em8}nPqUF~pw3PlPf@5er?n1faR=uhkmws>pqC`O&1y$OJh7)V7qu}X~% z1~T$k@%`T_)JrD@c>}{15n$nvF5rOG{_8XVN%zsoN#B27o?`v5XED*y-}-P+LW$j- zom;cLy;;r9KOTL|;Ui^YWpZ|Q76JD$YT~(ehK~`}?g+L#zS<%U?t+i_BPKz5T#>UI*>E^Z*kRvE8JYHjT zNcZ*OcX`7(@OF-fiZp!u`_tGF`q<$pbm~fhW10SdG75aNF}TddnDQsjQ@<~mKh@{d z^de4fOXb2`+d4miKc*!2t$4)cZ<@UL!S;r_Mls#l>A(kNs2WDdq55y3a|6vXtUC^C zd*FxFFjh@-WPQppsaC`r{ET_V={`Zf8O`&3_><04Nox*PC-=nG7^GBoAmfA%RJ^H* z60>|=50?&4WMPsBUZ(;i+!SY)PxtmL>tSl&FOQGr5b|0f*78E^9RhN(qDrD!tYtm? zMGwMd!nLo}L6p{0v_&>HWpy~8Mt9fT{7i|x&`7{iu?P`?M&rmS>0#rO>p5T+`y8oY zv+lC@KeIKt+7g_6+qKNNL0}K9`PnIU&G|USvY0jo2Rl<{+kF|v`V_5sDs8^ZchL%t zM7C{ORJRfQ1&ya_244@?7UDcH_H90;=iICHEIyV5&hBPsi_x4OxOhsBX@mqH1Q4oo za(YV(E`mSCu)!q_$4a%mBZWsGRPz z?@tJ8Dk+(l!GNHroZ)k!yGL_Tci?H13(SwsE*?ZSkt;+uaadwI$hBxB(z!OEb;^Ia zh47S=@H(V>&bJ!~lok{^ag>z>um`JbsF;i+JGa9qLA+w+&8q4MP zNPVFTdhY_jT-uu`SH&OC$qD^8%;2$6)#0gLA}r%RZ)Fb1AZYnxy;~KxgdZMFI!g5%d?O%bV9j^@L%2?av68Bb=A!RZgTB zpZn;J!4va-o65heM!2dK;6;NuXes2kaox!xX`kP0GD5RXUDQY>3Da%;Wwh+--tu zNcBs@4byUDJ+p?9CPVjWr630XK0+L1dUuqwxWN92^@^+VWSmn40;L@EN){1e4KPH} z+oRu4c(sNrXA;&5$yHys9>kTa#Rf|7W%2kwCf;I!wx)u)F#;-bx_25FI!mVb$5HAz zn0LWy9w@xQusQj$Cd~(C%^`8irQz@;O}9&iUAfTQxN{?yCEu>CkQy+^gB-;p?^N@i zO)&g9#AaGT$Iv?OF00rD`0loC^ULC=4Wt{f+YhKNEd}7V65_@Y4zk%~=O&2o-Fwk^ z?6(@))Oj>$;^;dIp9I1VR}Ukc$1g|gphm#ey!{*$sUj*5mvaP+25NL;{=UD^GZ8_ z|F0^qf{+|pgRB~H8Z?ApI3Dl)vOGSy_wsI>J)Z5J`DRGUaki}3EXU?JA3?7v>3M#Y83SvQ|P8Xf@+LRU35zuA= zniI2c*ikh#)d!bu5qxjcto$Y&LfbEddX3%6``=QO=Rbfl=OCa`i{k?uh=oglVTzj-}DMcTgjd!bvC9)Gp%XUwjal+AcY? z6TeyTZ`EcDpAmh)H}6?4Gk55IOhdQ453Z{dtJd)?^X7P~uC$7!0F^g2{TBcWp!84t zJBNQgIERVb3XrKar4NkW9v76{tvHe&P1- zNB#KlP+VG?mYfV={H^U&=OX^46jF?rd>XJx6ysv+v^CiV~77A zzHbUv!JUb|qQ2*_5#ZOQSMUku+Va&B1Bjz7d0IvB_2>F(BJxv=CdXiA`VZ6fy31dd zYKKCO2Wise6NOllDFO$6l+^v6kl{gr_b^!^iUHb#Xh|4kJ(~9GlrPr3g&KdN-&$9( zJTeyNWjSSYOR5{whyonHOQ(tzR-45`JGwe5Ufg#)LjDPwW)r%wl!$4H+xLAC8X6t7 zwXq4{d0t90Gde3cd)y8dMSz35&?+XkA~CPY7WUPg&)*q*P$hmR;Hx=J3%5FW_gk!B zd={W2)J7*y7|zu_pM~dTVGB=bSQTb2QcR!bs{x#ZJ*l08nfztgPY7(?OZ8;2&Qr5~ zt~xNs6Ur3aD^`Sa4UlUIXlR%V4@cI2a9+ky+LlfH1kt04md*n8-3t34*+{*5<45Bp z2ksk%_;yr%v(YeL;=zo{H3d82mOAZ)p!X-s^dhxo7R5Q*X)Ku0!xPZC)6qgTb7bRG zSoP(!TF4aL|MCD`-h63p)+ZgH>AC23*BIpDrkwEl|Crh zV%w$2%VBT- zbcEe;D%Yq^${4);6U#lmvEeQ`y8dq+9&S{0^M*@}7|-j~&vSIXv5RPE$rZ@R$fP0` z*s6?e`;p0&iS73x(3aw+#UB?gr5bh}MBa2w>rkIsu))ILQ6gEZ zHnVfP3c3?3%<79kWn(8Hbn-dxS}mblT&=PDF2an{zBX*D%`Gkh=|4p8*4Y6u+9 zTy#C83ky-JI$cHW`_pDa=`adX2pMGx3aMu<*{>3EXz;9*4KJ#KB0AT3u9(1RKI3q? z497lS7Y~M0h*J5_5nIRSY^b8Ph*NwhS#%vA=6$<nI{;{3=hAI(Lff_Y~)LN@^zaV_ie^v&{RYc)aJ0vxip-_C;z(qS0m>` zo9~p8|Dxs*YSZNyFbh1F5^-T+3R#HpoHSC9I~|gC9~>!+*VrV;T)?mx8Yv{8jg>B3 zgrb>`4qt06*EhS?Zu#L%?om)({^OXOXU``OGU+7xy2j2@f3yWXZlO~o)qzY2_~gUk^0>1 zXDm;g9_c=EoM)UA8RrB#{Jx5m#i?OVO1e#5L&U#K+{Y4=U#>a*`%Fjt?yk}7$0B|l zu16a%XHntU`EsYnnm2jmuX4+vQB40|tqy$~p+cb(Bh&TqtG2sh^zcX`=DfXAS z`Pc+f@paNBFPegf%zOexwpW)I!xNmkc|&>$#y zSAoWgr&i2<>Qt9qThhtk%c-J9%PJ`lzZMJf$f6dBkD`oKAST>S{DB@xeXLF(P)FHE zS>@!J&h#sqy6lxo_WYbrCB4K(hAff|lG0a4c3-#_6JsHDSFsqGpfW30=CGNaLYgID zM>W-v65%PqPr^<{Nh=Y@m*)2!@>iH&s;tJ_$uO=R-kYIH7H4Eh#a2^`u|B%G!m6OZ zfp8<+K(&1fh4kJWg$UtxOvy5l&D9H`=2mmW(&|#;N0oS|B^Vt{mrSLjjXG0aF*3tf z9!yRB@&IueEycEPL8g@ZPnpu@jCUJ9Help;jn1KS-> zqh(}52i70833Nv+)tCw;H;(@>r-w~D4bS(g7kFRp9H2?r+b^{yL?mS?=$E={+G2`>*W&OybM+>7~#r}48vC)!w( z0G|V8>Z>ce*TTq**ehZ9lDTK$cPZ56&lcD~|56F`FE(KA%g2N}=2imxu_@Iy60LT` z1>20Mpn@adgIzbGU#+tOWN9Lf@5m>cTK{nL6rq7}M6|p-CNg-8?Az!xuTzqWn!n-v z#FL&E$}KO~Y)fmB-=7vfTwu?=P^;(_q~8(5mo6$%zH+{9j~t($6y3vmyLwC%LGI}} zbkp>DiHB;L#a}^Dz?aVHf1m{@o%xmh!@WI+p2Qb&T=wCTn6r}e@ElTBo6+=IZyPx- zNEQ!O`8>Pod<(WagBTllf1|9n{($b|6bq}2)UW^A2OK}lH@G7!uK8K+Xg|!t{;bwI z-o;h(-zjQ^30C4r=enkn3_EqW@m0l!NU$HOA=18Uq)bUZiLSeVQFj#><*$+ms4YxQ zXD2xv*l?YVN2G_l6a4eDsOy3D+yaHyig&bv`A65S?-YB@c^%TamkrVTHaO9)Ze5s} zB`VL4wj?wPK8Ek9In^R}=8)RCFDb5ZER53GpLdVdH$MqQYRKcZk>EmSyGIa|b4A`~ z2Vszh5Q9yCNrH&e-k2J$i1r_gEc5Nz2n7YDy=`?n{^DmMov0|R*pb2dL(|RFF;ON5 zrA<#~F;<#;si5!&YvN|(oF0YyWj#v%-tR8jsvW5H;=4#Q!~`5R%nZoY)+W=<{(Z>( zOm+I{@Y;>kV|VX#uZpro#{Bvy2N2%DB6~Nuxv5^0K&};WCY+F!?A1=RozV%3eF|kV zc^!pVvtK6HS1jo;i98dhqCt)i;_&D5BT-$$3PzFnY+WKf2mxa0bJ4NrTuz#tn8(QO z=6?$L*jGGWfEW-~F{?W}*#Eo9+W24Ej)Q}Pit#GYY8ijq)N3J;@iM;?p2j-Ek@NFs zi_@jX(P6o-H(TXqp-j9Qm9B-}nh_)?sKKW|g7oQ3to{pUVCEfvGOwYV(}i=i;=8|9 ze}?gDU0o&~#q;k~Jt z%rD$ycKTakTO6jF7%g=f*~{8|ze?)5FDGT)+v&Bn^nPc5j7rg%d||iL0-Lld$lVFpZ(ou3=rQMpnFL89tc-K=zcSsUYLWY)*CT&&SyQT=run=? zB7Bw_3>WRh9GGm-Od7#dDhcC2M#69&JPuoBrODgql?bsKvTncFCu(h07;}JoL5xt; zaXP#l(i>nN_q-l2p|_e9#h#8)R%Wlcn(a6bvC>7{KlZqNrS{^p&rV_{kYRr~QnwoM z2Y1Q!)d)PuKfOI%&UX`DV7}c?zYQ%KW~DC1lR#T_JPd1!E#o{wRR2~nyiN(|j@SP^Ya>zW$Y@_4Z4SL^miuL!CNx6_3oJ z-wrZq@n%%f?xa*<0f+a1pJR>9V34MaY+^}8e|^OFRuau9phbgFBwj-}-|o7bx!&JL z*?H&m_jE1U!%fS@E|gyy!>t&vP}=J4ifxY!eo<@CSD!>T#OqcB&ixf}CCWx|;nwSo zUC>)&Ds22fflJHdW&=!iL+$l=_11QIx&C@bubvw~*|^KiHCyO$*`}=ZsyH;UAIkQ6 zo>$-UH}`TRlo%W=UHHFePF#}3@%JMnZslgxpZ)Uu5C(qpvun$4uVrmGQxZT)?eqKv zh7b*Lc-(|o$%@P5a^2(c+ED*tDh^{=yFOKwp=7$cGzqECn=E64HC_H}W3#ym z6EQ-xnmsLW$nvaPlHDLsGN~is(UpUr^k5&=u()BpxG7%uqNPy|LpaB!N9niLC1YLs?K`W755dDcA^fr38D=U&baQ%#>L+_$Tqg$;eKZtE$62Kx*a zi#Rb>W1h~RVE8WumcR6rWO2oRCJdT*V$S_pMur#2F7O~B4yBMU9S^n68Sp!yKu@BT zAI#`Dn5ic@0zs}xXtpWo_}m27x(K71l|{5#8uNmV)kgO9EB~6m*h)RBTfgvgr=^a~ z1=@069CK9_!GS&ys^73_W4)antt zZd#e_?e6z_570*R?1^y{AQQNK<~X>|TzEyeGt$#W5KA@WHhNF{rpW#j?6c&beDZz* zwnwqQPIWCAp5WU3b3-~2|9T5tC!kM~FsKN1&Bcdzxw^hj<4`hFKyt6a;I9Q?XJ)g( z3>&*@OWc3xzq0(+;%&;Yw4$WdWQqxk`5P1kbyl_WC{&@w6AeSnY@=ILW@Nw@$f2q+ znbUPM%my=3Q8^{2pRa1$nGcl%A>6)xH6se1mu5^>;ORm8%TGD*W62{zEFrNj(%1HT zdoAETn_@{tBXirDU1UMrK4Ie9Hw67qMxKHSzn3(93F-|qu z%AdNan8+9y{#yIK_?|!BI%j6CU1TY;1b_GumNcaP!f z8E__mOesq2CP(tFRh^E^yMTup8o7jyV;j~zt_B}arxa`BXWWQ9X|Mn>_r{;6>I(eT z%UjE)fNaCs`X4F=@0*Fd{;ugzrJ5{3REbqaM&Q~8>}cF3OO)u#K{wL&X6X;-Zd?(Z z@knIUydSQDl>JpaU*soG>;i1VW>+qwt&~bge{@;4<*jr3gmLd%8=4CudEIxxSe?vj zDCSe-zXu1SkkUSOxv95aH8a+>uU?*QnoXq)qOJJQuRm#*=oxOGFtSya{KZ}*8V!e5 zHg8Ci(1=*{T2nq2j-67gmOl4<;vrdVZGIL4Z;jfHBqL5djXRbFZG8_H$ib3~~U8*;&G2%R>m0oxPG7_+|8E-+*pxvEe8S@n&cMtIK_n@j7W#}I%$b~M$pC3LC zR*lURp6t?`C^#=d3;WH9$sH~KX&=GN)|~8ACPBaw!LFJl*ZN8LMVkazACY;i9-p7C zNiu(ZR99Em>M&sv-nLukV+az}=^7hGyYsig{kOoQXZlYl1g!n;0*O40t*j>E^E!C% z&7`FfiNK6x{&!w)!%~*38IlBgZ$0iCpIU}65%)cq>~lXYw*CHs=8htM1B=_PHe7$B z!rtrtC-1o>fuY|lJM5(Ub7f!thv^n8y#rIk9$W;wOHATLeSP|ux8xYTRKxO_6^tvK zF2walqW@pl&;bSRemDhIlCJ%2s~d|SnPHS5Q_*B1mMe{2;QY24Hw$y~`=S^omYVR} zm_u*Z#b4&|SF5S;5Pi-QwioTlZEt5nuKef=92?j<_tW8X#|1=9+Lv;xgQvK&b9$FA zn&nTgy5De$rrPx#tr@4DtGX0T78)aNs&_m08Ny;pqbr!$HEptVgxVeU_oseNWn$&& zLwQvq14v^kQ%YIZahPS&U*;L(H|q6 zrJ06oTLl@#$B)XFE(}+q3)kA2=o#mj8N9iR!5l~$(!o=P2C*-d!HIK&WHQ%JKcgVz zo&PcCa{)=Crlw}hL(KZ9XH9s!6ra#KU8l6DXiy|*G4={N*-L0iP>;ju%+sffx7U%MqivY+zbIuxjFip8;$JKV^&^7e*Iy}3-> z>xYvBE=$KrS8Ay5(=GW43|6JvO)5AErhiXf?j)l54Q$z&66?f{H;YLL zKZzJwgEUTJ`|B;Sk=*p%c4|={)Lwo8Pn${;QWwb|RPkv)YOm-z z<%vsW^M_Kdj96|xZ(dD~wV@YIXx= zZfom~tA<~SVya8R!rpfD!~2Ks*7-mP%q4tVk5A|4Rlz@CxThY=z4WHW4q4X?nEFkK zHQQZ;`gb-8E8Hoz3rq8I$vm!K?qv2lH5a344r`{=`2ZP*{szVk%M?C|!8G!haj0>9tFpJmjyJB_Y9x*`CyeGdvpc4z68YHZP)8D?J1z?p8Wfl_n)7Ad z|D%^fdb=;xQWCl8LkEfC&BDc-s%Rw%p9(B6If-iBskydv5y>R}z|cV>@K{&0Hy)kp z*rZl8X}w-Zoa>R4E=_ebQ-(B^!KCuK$b}~n>Juuh)ZM#=azLnUs|~~E@QaZX4-hF? zKije(o+l-hTQ}=tIN2@BJuPU%oGM<=GBc??9w#jXk#!q^m|AB_Nd-4(zID!U+>E}O zNY}CK&1&b&^bvEW>giZc${Frs%c^9a?a9qan@QbYs+lVnWH+m;MwE+ci!I(n@=exN z$~C&vk*-Rs@}>2p%_Y?NkJ0stv93yqUx#FehnF{2Gsx}UFRt0_$-2n#XP~j!C`L6& z*kBd%sf+f;XVJl|Bn{3q9-g(4<02Q5+Sey`3kqY@?WU+dM1j(~uO#i$(jW?V>Bc<>a~vV#caQm(tZcdT%$*^rNfFfrll zF9ME=3aUo^UzyVn3BqI89z`=fLt>jtV0MSkm*q@6&>2_>d160EjB->@e)n`gwIB#b zL4HfU0`SA+46y$I@?{B!azHPdo|VWyMqme-8+|vreV)A89>0SxY0F4Y678vk`S^`( zD=$(E$e1$6WdU@6N6;5bl$#B?A}jTGYXD66Cmoqf{6gaHcF58!CUdDF6|Q(M_O-=b z4oI$L0(Lp9dS6)lG$%Jb3&gR&Q9D|_|EP;$k47~eHzgbE)m9cP6{(_aeUu`=Lp3XS zRcgfW*qvbpce2ZS{^cvkxOc*qU9&y{eDK{j2D@-8`;bHa;zGewalEo-Dp^364h;>X z+o}YqW?w~;vt$~NBVk_$*&znvq}Ue5F`&bA&_kh{L#H2=#9!DzkN9Z=2P~)vCcUoQ zTd+8*ca)aMxuqMdva=J4MkKECCnNd!BFXlZkOMmAR&?_l`z4D3lpS+gPASGG+a0rG z*y~S2(dT1-&TM2~(T{3N4rY6gbR1I)$Kb%ea_s#v$97-Vr#1l8nRJOmoEFxpXagc2 z2G333K+fg}fR4b}U}$)6?#>7-6L?cMARmEyuDyM*#zV}{x6sryn!m8RSX0v~QUG>X8++~@C8)Zn5Vn}3KO=#3ln2eoVYBpp@stvr1(JI-V=hmNYjj*?E^mu7j=cXyl6Q1gQtu?=jKNtoc?6jm z?_eI3ldncKBJb_Z3vuhti_n@7khZ5DJM4bAGHRk|$`TiNy(Cc>G+{;MhoG{*|6g?k z5vGpygFioOlW+rjq-|ftGJn3M2|{!G^{=`IN0jn|-28i|*qX$US_k%7U8+W z8B~C#+~?X+FFRjFO|AQU1LzdCs<$GD_{O;yH|}7NiLEzXS{f3ClocopQxZ^6nxFy{ z+9+DhDhcs1d2af7%N9JP+p8R9`+&E(mac|cCI2FN-HMh5HN0GKvtY-4*K7%L-P5zG z6Ib_TG{4^L*+u?eiZ|ORX=9qf9yFfn3${-`TBL)d&laxdWnfo#^Tb#%*F^tF8!IE^ z&QK7M~wTk@Ca#Khq05Ae&@edX{loOh}Or32yK>R ztBbd=@D*%Vzl@gF5NWZZ#3FlcQ@nQUksxsar7HMNTIxm#Mv-_7WNT!qstU=CznY~^ zywR}ZFgFay+5(~pX4y@WHno)hT{5!x=6N6g zmBcUDl|lkG{X=kBT7@_M;<8pd2oLw9-26bqpxO?lC9y15U2RwwjeBf7QyI?UV*;0t zf+%Ldx0!M5U9SfFymm}M&7W{<+CDB)2Nk=z7HL&t z>B1*{;1G}$(*S?-hx95`u6%JM{nVn}R2Z@k0-WsxaDJj@&cjN>-TytUXpND#fISTU z=#*zIY}fsPbTll;t>amInn7_6sY#~N*8?3m@YWyxM_Rpg)I%Y(cW|hwu5Q#y^Uh36 z#Nq=tXCCL^Opm?KF32K21H~g`e`x=QA2^b&&QpQ?TL-Dwk=F$!shs--0cUH)Mg`@B3X?vq<9bpmp`HqV_%ycd zNJ#pwwiw9NN(xgv*^7JUNb^2mj;mNnSSlSogtFy6hlR;o*)&i43$AiAlaq!HunVxX zBd)n}IRzH%ai&5F@8~cQSFYibO1@eD}h);8WItGlI80RlbU4p*NGoFJthP1OnBNT>_jY?-VH1`i| z%&E#!L^;B<3P5IZ`}f%9laS;tice49fVm$50pWiDLy;{ppUQ8TzxPVAvYqkd>xk<> zFhyV_h#@3?f^%KHNql#Ld6`W8DQi<0@24pdZp!&kq1$6XHNl4*6YVfFLLd*k40T^@F0 zYlh}5fGiVfzQOEBW&-}5_`pQNkLsNQK0U!RvprbR7 znww6Fc{M_M-AKV>#JxYwocMyra>YZXG10-%I8+zs}5HE_=9El8@ub=&4bU&alkD>c?G63qg%Eu!JuB^O}=ju7!73I~P(U z&^q1v7ZLpj_;a%ley2x7{2(_`#m3~8Kw=Nh)9rJO+3c7x2=A_fme%r{O~E% z$wNQ75ftUbbqL`fOq??5syq7@zf$?)uci9$icScaCTla3_8P=@(;c5ub?&0`k35U4 zo3MX<#MSV=gkSbY_#zql6cvXz;zy~GA2Xd{4k@!b-_W*w*;1`F)rga=qg+Tfqr$ke z=^w$bI9{)gwvH~an-1br*5RvoA$mrpltUfS0c+H1R@ z*H+3~8^bkfRkWbK{7ozgFBR1)JbnbQedcJ!=g?PKyv@T*+xMS|iyG`3r195IkP$2N#Cy0%g~C@Pr&`(G;L ztJ#SGmKnz~k$CigA%(Kb@8W=j;5MJ)5-+vp;@`cuQLurJZZwX3p1~YIvF>~xR}!jokm%Ht;E}~5+@-b z*uSYgJ?78D!H#T^Q?Zf}g`avfO%VIKV(eW|g~0{pNiMK7e6P_7aOlGe?r$A|!TbrJ z{?OCV?0CY!!1)8XcHrb^sBxJQdA*_HSuQ5m$u!5q{dNUsVTyH~n!20|lLs$JXEb<_kG0uAp zXl3Mo>OwI1kcx?oYq!V%RJqHww}38Qo$Cd{^k9C_;Xg=8gtwr;f8{pp0*3D&T%Z0Y z=Wc$_4G`n-xg1X<;{0Hc+HaT4fQX){#TuiB;;Cm*lj|YCkS~8i)Fgk^^AG4@uP`w` zukH&0=Z`(ne7Gs^?P!5yFz7t`r4F5ZvUg*MaSI}L%A;S{bZ_L= zi$XoM#J1=ZD)Z)q1dAJxkSk(I{=+-L0bsr;YRM4<`BC_Ug$=ChFb(BIXqDB7v zHQTy+n}xR&m7Z^PgQ_JlTqeS`p`&7yoYd1@+@CUV_gw@4K8BcUOQyhFiTGa*_;z+> z@E;_8(P2o&CoH1&lfZ$_NlDrGKMkvcD%i+8_LCoY$SKM6Z8p9r$A@s{YAD*$jt|tA zIz;?RTgL(J_t^9@0^vKpr;{2W*76$_)#B0;oqGP|-2gO1UZ=ILSx8YQppc{r)`NwY zz}7<9+1#+P$w5>jV$EToyA?G#6cZq!=wP5!By;s)6)d?tJkUbq{R(|-M7d0xnr6N)iKtNt^8vzMBQ!6&M>uXr71bpa)aQ}iEG-)w%9@&hse+k@hqp&p zCL)|nAi~JVl`AEs8QS=Zn$wAgc8_)H? zzau3@qNQOD`ycK0?r^%Wr@Q-K4@Xqw=?)H_O38;50U5E>cB>AS?cm2%0^FtMYTM!L zx{VVuUhTl=;Ek0kw>VckGz|lc{G$sl4pvjjoi4=Hw2X6a{|xd}wqAkr(P@F%Sr!L+ zXF--oj3&P}+{;8h_7hBWeLwOx+v_p{+fp|q*Q=hLNxkrsEjIIA?l?*%3YtsBL+Y6Z zo80fL=DetB>-hiLP0N4nrg4as)t%dUn+P#-W6brw*6XidzeWLl6a`v&=I(P)A7+Q2 z9$Ro*86OnFoBWYwYGA;gSRK_`8K94Px#5p%I071mW!m;T^T76+|3hs6}L&*cl731Cd&#Ot6%`JOu^?oKGASeeB7~-=s zF#)z3Gv*laf`1Hy9cIC^*ZR+m_XKIFg9&tx?gov)rQufl*LUAtVnXGKo&xdl;@kEO z-sf-gDJ>Rbu*Cg+K(zFvOR&Cbc?zoZn9nRYNC`K`L#n$ge%u{64>mk9?9C%$lk7wR zoZ}Wpfh~xdn%aL`NUDWp9w00W)sK?bl9`xzL;Ns)VxM=Nvt{<%$RNjx%iHUVyP`?G z=waRyQjk3j@HMaR7auEkKE}1MdQs(iXL@brA@4k!Mf1{Fs+-iaoqJ2GXz&lN`C*n( z38xef?j(P-ANPLhu}PTpBmTSbq(hsnL4ZDk$uc)eO7Phl&j9aVAaE)U|9_qctZZyR zz@9Ato_nTCWXs;)P_JIKd9tP=ru>vpES?gP;4<9f*COKd8=|H5%St9KxlS;-juHYt zZn_D3Sy@?mbZ6_`#&roMQ*Yiy_jY9=DC?Fb2Oxf+wX3l;)~2rwIXei^YVrRF+y$3* z;K*9UtXTq4b*C8K;R}|U?S(2SxZZ6f2sGB?@0bm=aX~@rH|$xHg#FJd+0?i*j? z5fQO~TXfBQn`8P?+Baj`wi>muvC-JrxV5#_+}s=%76!m|<^$)^l*;+9y6`N31lNFv zw(U=VoOEL3-|U)U@nJR2$36|k%Da?n2Lr0~(txUfQerBD{NrIr-zvJrg`IL2!|*W0 zs^U04(=WXa$1P%`$ApyH`tTfkb5Apyq)*lAw(_fNJQ;wO2e~2~ifgN`7K$pXGJ@pcPwGjY|*=f&Z1{`7TAA*o)a!>r#=M#U}PjN4bZK6L6 zovs zFuhH$a&VD-l9EVV=6jt=#_%nW7d=dZ3OeQCybQCQnzBdVxkWeR%^O<$LPPCF3>}J9h{o;nOurDN#gfU?94LrqQ!c7%8rHSKo zW6#Dd|1dy;`z`NAu2v?q=^bL!1>t7cy_qTI$0BdswSQRxoa6rm3w*EYNQ7B$lBn*X zp)69kMH~+T=@jTI(moFsfrNxOm}O=@E+%V3evj*SVo=E2RWC`QVNsXCZ^kbb=38i7 zcRWA;1OSJSO)wiDpSsb0eF7hLnZ=u#W`@&!sG{I(wV#)QHP#~C!BwK27{?Eg>JsdRkG%FH}EG_>hy^TCsl zknmaY(9vFh_+iNw zGolcHS*&0{jOO6gK0Evk+cNW%Ha_%}->+j-e=$v7#=k^y9C7~OAwOrCErwDlpIZ0# z`vp?p5?5<*uxgIiIG!}73|>Y1W?W}MY-}n0Cvw(HR%>Y6^t+=03N$(`8`=W|_I*uu zMhQZ&UGRHA*pw};<6;aN7j&Dfg5vTBd5nUsk=pDu;&M8BwoeqKb?BPWj?a$9s{N&z zakx#2gN_p(+$Xt?p~EyPw!!LzLDqPUJX3lxmG0$wY^H6$FSq_Uq|$R`Rh;KrA0GKQ zo?dYHBi=Hc?Lkcxx4F=_7lE61!dGe5{!~cr1LNd-I8HWrHC%Wzu?w{T6KleMFP<{> zgFn0B+O!3L+qHtiG>~atPTu6yI$%u}nA3vNI zoL{0S&)D7LCmj+fjjm#xo7=RBMd=;Dd>4Fv=GQrKr-GWoDw!vyY-yw9c!$xDOvGxh z!ZwUnGUc3?5^u#D*cTLqiM9nn4UIPXYM9BhN>pMPyDouO@d2WUv3H=d*4a0A`jD96Z!BJ$xz01AEK zXmq}C4S@Y`kF`2Ckx>!e(57=9ufB}5#I=pEh<1O2u?gUo&+}C9C4Yx6(N=MhW zDzM&59IC8vMOI>xl+>&84_UrW94iLk1 zLv{^n9Pgd90VZc%RFWA^X6SD4|EZlo1o6|sWNu$yAHbjP6!w&{w)hcXNrqbm2(z_} z@C4Twvh@g`k2ZDe0w+)6)dG8++x?Em>t2@M-f2GfNW6WyU|`=~{(#z(EctCw*z-U! zr6yd*DjmMX@8kPHG<*u_G0qmWPd>&(4e_nrk z(Gn9A16aFI583;1@o{l<8gf$iulyx52^Hnk-wyE>S$tw66N-I!#3_4f0-D`rK4*5o zkvekZjy%R!0*_1j(HJz68{8FZu*0&AYv0=~6>I@RfkG|bk7#!n;sbhl+z5OZYW90( z9N~!-21t5p|1MmxQ0dcSC=<^8sus_V_xpc%#kRG}Ektpr*uZis|Ib?I|)=%Z6aKLKQzGoHksWM zbusP0%_iIt`!imTqkh4LiryN(wg zmii#Y_DCzd5YtkgLd`O>1|I5JJHlZw$>;mU+~?Dv4hBr#>akgaU6+90z@R=O&=27m zAG!Q^2SL}>)!yIPL{U&Sq%O&_%rY}G&LOVIwnVlq;aLSsiyg&Wih)0%w2KH(n174Q zBCjYaI*Cg_(JeK~qxRa&p+S+Np{4K=TU;FeJ3Z~glqN?>A*4^@=dUAZjZz3txx4$W z>#re!0_sxkhUP+wWpJ9PIB6ZsaYMjIb*cv?y`F+*_g+{*-y|eb7CAu*)K4z7L8UOe zdbT|!qi@YI2~^F_GeRzSNFT+h##oo)!hN1!tsHkFwj_isz5tU1K0irkJ?gKEvccoW z%s219k;;gnTKvld8iOg)t;3hM@Wvs0?m64F_M<4K$jF7a70rsu3=JUiYQ^|J7jP2l z%qs_5gEGJAtQdT)fZ()!2t-lw#7^ieNo@sHVWoabyBmXn&Hc}g@WqoAb(Px8fSG+2 zEMiC}xR_yRh_oPB;MCr6{Ch{19Ah5|SOs;(J&(5zU)Nf`HJrMI@p{&R!(7#fZ4XXHl?#sj#S(c7B^5MI zh;=m;O^Ks76Vq9#qjO88K6lZ|n4D3ARpN}?JE3#`x`p+*Vh8)TgbI> z0Sa+!vsvK4xxszCP>&$@3YXfQU|S zBJyWYz4 z^~|aEb)i8#m)_4>$6y3$l!$YOlZl0CQ&SVSr#5V)>bp1BbrszLU9zux1ibyoc^C%g zJG{6&_cnlY5S@6Esrh4p zHWwW{6Kt`&D~89;-ofX&Y(bGFPDVxsq$aZ44?#bVs6xcwT_VrXd;l2x1QmGnhkl@% z-`~v&%O6~%m75_D&9wuIa!~l}r*+YS6`T@L2N)obFAhdN!*vyG&)Xh$5`TbV6~-X1U5Pypd}eK z7BG^6Wfb{Puj7Nkt5>mOJr@WpzF%I%f5Zm_1TdFg3ht72b81G?6>*Q(gQX#EZ*CY2leI%yh9YK? z7QdosLq}>~lB}GGNek(^7r)m>f5ek1^ECSM!7hSx-tVtqj43}7+G?vRvNyzQUIXtToaXR5Enp59*ycylK(DLvQ=R@$g@V~~_SOWrCi~>(< zzKZ&{lRmXCJcR4>FKhcG?v0;n1^)t6fRRlHa2Cr>f^1ba)IG2+48r<)HQ5}{XUHwm9mu8KZx1g*cNGq}JmeF60ocsGHCl5= zUq(>dlx%*;N8HU{VZHTna#F3fC&TA~X5ZcAxTC#^vy&Jt|968&(^HP!T9bwP?P?GK z1R)xIx&AcmrxGPbRoGP$P&Ve?l3``@=jN2){B1XUG42xuaW&?Ywsdz1_2QX!W&1e} z7vyIe-Fj7Gdt;-lYM(cA4c!)IjDYDav(4z%sC+F3{)U9pxV>Lh+zgwR=eN==S22~sM8=VvFeKK#k`h;@ z1-sa`7g`GGOwYgTR_(9PL|%M*y16&`zVeFt8XE0)i7|;Ex+My;Q989-BgF2VZ*+Ar z2#%YB#q2Pq)fKM3ox2W?)aWps^7f35+X9TxJ|{s7AfV7uuyk+E9*6A*6V~d@X5za0)q~rARw=>17f;7HkPNN~_}QF(0E59u$x}N| zEquYtGf(6LGBtZFa3xElVaaWNWvPd z-M2;Bc&CTA=((wjWxj4beqH_PA0XI5#HmX^EG-HqdL-c;dv+vVcsBy^+! zgjqAC_N5Pt?_noaVCi#B`r`7s%f*`}Mmb*gj8O9Px&*ythh$P}ehcW-{UZKu6!djK zd+S&;Zk%(|>v^4vQgJhU0bu{!@x5*KVXfboXi0u?^V)+(m3F_}3SA!S$2?mcC#BCH zd@rp&rM|RCJnVofm!I=(@vR+;F(^zlW%p5Xi2Y*xRubD|H=ggjUizZ#`3Q40+DE+i zk}W1*A_Uo}4EX7=TF%-Kb5RQX=rEwGPmgH=*h`R z1_lP8c#Y)Xm5YNfdZYS3Bi2oC3I}P4V!k2uW41qe(KPZXnSIcZdUqOIAac>{b8Cd5 zXy_12^fvMquK>&aF{3vUfsb;zY4S#8O&_>O!o@rM`B6uZ9yolZe~TTjH#^SG>un<6SyVN>4YGJS5kZ+uI|^TtIsMH5->c994Y1#@Zu?90cFFdT z-3sQ{ zUq;UUxbi0yvw3XWuCj?67%-^RQ*<5_X+;*@Co|z_RZ0$$7 ztFWsNsyAUoOl<-!lZh`QgFu+spFbn#o--;}Pc{4nYe;;PaM)r6{57fO8NL7s_MOfL zZwY8s%+-6!MpZQhInpjgiBV1gsbFjj_vw!2NTwue@-5x$0wrc~p?)#6Akph*IUN%U ziekTNLmLbqaq+$8rAthv8oO2h{M|YirA-%?O-Gh8h6FZ0cDvGm-zOXIbPXiJ4$l0< zLu|D?zG{Zd@oS-NcYhAK6-r;4^zTPmXs$HH% z#vT5}j*2bR>N*t95Hl?GOBKf|j^hO4dK4m%U+=&k&wzP;R%$QxtU!{3`nRb=;N~i_ zuYzhQjZ2$Q!*78=Vw*6OT`Y%PB?U>czNo2}BxiJ6SiJVZ$BwacW+3xdEIQ2Mn-t+)=z!+m*7CfWI7+w9EdAd9e6|}1O3;vGxd8^vfGFK z>VmirG&l9IPK~TY0ncFsaC=_u%8Si9S3DQ*umrnEsh#iF3O^a=uQl22uK|VPd>sbv zQ~6-^K|smWy(m(ApCJQoMXS>`sPxTxm|Ta_0^`bXiKcKC=%bJ^8*)(2j+Z5z5(I3JXfE zsvKpYY_n*L8g@P-s&-F{Y|~avl^6T`TDE4NGa+_oxNx54&`bA@`gn@=xMV|dBSz;K zeN&p9UYs59N35Ce`)X6NVC&$6z zn)G;`1m^7)=(v2~-tiTK*^ty9#Ax$8F6(u#jR(tGD8ozMjOO2r&UrSL*r(p!p4QKo zJDk>A$P<6j4L#5~4QbGwPMtJ5eQ9(u*VA)7Z^M!kJa4;O0}v>u-#{@zPWm7&pXvQb8I`h#)ZQn;p>65J6sE8;l%xOixfP2ufnOP=BD ztY7}zg0+!R`a(i+_Rr^Rk0<7equx>OK^7+qe$S__?@g8Gz>}cL=tSm|;YXo#hAEJ2 z?mLWqx~00KBk}LijrJI!4!JvBc7oDstnG#8G2(W$I!x``R4=Ry33-wFQEp=npJJw) z<9@JnNb=ZFR1E)>)7Qm_RE6(4H84oo7pBYRFI%Vd6L)%<=G$E&FH4w4xl`r_iX>V_ zB6B2xotNvpl((i=e~r9T@mu0k$MZ>VvUfMXb#3XW_$9xd)O#4dd;Pnn9_YdMNHJ8( z5nk0#5H)_j$6OS^YGUn`-YK)`kiBm!zByAd^h|xHM%TjXY_07sL{r=F%Xbz(@;d@q zgyJ7wWu&asEc?)}51CK1=b+pgd3o<)ejF?ceI-V@j_UmyAh!+X^B}pubDb{aqXVkX zJW7~I8mEKvjfK0ByTkYiSEXA;*k80XYbEjWT1NKE#WVOqeW)tx@2aH!`>jZCbopl4 zT!K{PE@>-r9zdjRwa9Hp$T*O1t0>l)OqNNY$ZC}-EJIRu5*lEslXJg8*F*>>Ga8(7bwDH;5G z8}5Szhr;~xjw#-pId`q^FARoZyz6|UuZW9RB|o9kqw*sF#B0Xs;=vFjC{EXw=&i9hMTAmEvP~aJ`9EHbp^@ zVn*be&hF$M$>*SB3>8B>WBka7&p<`@hWY}34(BmyV<^7PQopY2)q zqMnK5xcmdcrRePsqGw6zkwogo`oz5Yz4S;tjEK%z$KO^o=8>Ax#c9= zTLd*#|6yKP+1haC_m`CnlFcEr9N_#WxMw}Dl0VN*{293506q1Qo%l^$2Q9Mz5iPr_ z0L8D9Yo+dOP+^^C+u?pk{vH<@#`e|fz`IX5=E$X$2x^UO##9SRj!L8tLU1K7J3A?9>_-u;4`?RR zI_U3hKHxUi{6g54H0n((WDlA(^=RvX@3b5W+zlk+&Dolkbr(4Xd;Sp^=5%;lET0+Z z!h!EJ|9z3FeS~tKA7aK!yp?mtUF-DtxPQ9_(snn*dg*147rlYYBIfa=qM-Nrl(8^2 zSlI9Jiu{%lfn{dP<{UqPq9)T2&MM+c!k3}}D)9YUuG z6BNw+YsEA*apfUW#w>z+vkLGPLk;*C#qudkWDMgKrGW6G;9JQ>ztsvh#4AdxUAFl z_Fvbl@5W9bA(c8Wo)ivcn!9Ri)kQ~$f#8RP_6kjt)l<5BVgWbsE%kJC_&kmib90Ha zk%OD&1%h|NBO(Itm$X6M$Da*Ak)&BT=dCNoL5AYu(DLB?G#jq$9bGR1n-J#QG?$By z8T*@Ov7zeN*QntF^3Yuu@#P!ZH5Aa3-Grm$euNE_qpZIt92$l}pvvA-)})47 z!zx%O>*CHaU;jB@PQfF*RnZ{bgb-_5t|sr@y3#`kU$wrf=U@)S(!p;V!d>%XgYysa zP|60wuyEOxt0rwkp)X)eG$k@JGJk)6HqYRv0U-C@7Q*VYE+U(V2)cC{YN!%?VS%WR z7{rP|4|6(BPTH!&05dAA%(Pr_M=*0v8Xi6$@@kxPJ2LV19!192;)N41ENQmEjtkyX zj6?d)rBL2SA+;cc&sJ_Ds;`7<9a=EuemH*^VqeqIM0meX>HN28qCfLCs$N<$!^hpx_cp6M?b z#8|U4LgL}IU)`JaeCx!Tl;h;&T(uTL*avduG-2&a!oMaWgg9W=yCPasBfvCn1p{@5 zS~Kd`MT81*VBG=3gow7{19cJwZ6E{K07^Uu#u^9%Ky%C{HBZkL5g4ctA^qi?v`h>H zn43vm9UWhlh{wN=foAak*8@<~atY9Ba`$(4u|Alyv$GJ}W*=E^Yj)svHwu6~Ve2z9 z=Oj14`zE__;ATA2$oVV}{-%xWE+`!NhJ9e6D$g8^L#+I-u4AkQHn=uxw# zCX8!sKR4ybYHe-JT%ZWnjT$mDjc8@h%gdYb)`B9L`f<(X+{&KN&H>SgIjf6E%&Fto zr3PeYoCb$ex3b^f-u|4F(=j7zBC(=&nKX}bM9EESh2Ud!BxcDF&`p%uN$efPt^LU)L6SbzK(`WfPlLDRFEcIIR4t95}jB(QHk*e|cK2(j0=R zhrRzUDIGO`33-l5yYf$;aV5)uZzTYHCGT(Mxc2FU< zB58o;5B&c1J&25I?tH^S3#u2gU?3;M_~R3BhV`FX<36-)XxfnKK?76$aN!s{063aM z685dx7++`pyrA0%3rJ84YJh){5dr-LsjSIJO+_X1anDC6e;W*w%f-w4XQ}QZ>~=|h zNypA3eERR_XVH@8mKMOiN=V%%ZNj<|J8n9DMt2LT2GQ#gfbMj`^)WHX&u>XDxy@Lj zcAujk-prw6zv`aIt_|uUGED>iJ9Be$V1%%<{a&}P3lYBt!l4E%_>9*u4(DK)VWcbU z_cpk=xC8z>%+K1#oTH9TPAoVO+rb9)m@lv$JFIrrKZKsZICyx=v$LR6&QrKmghm-E zEFW~YIjYkpAjgfK!Z9ZwQ$)l7o(ci6B(Sph&RJ7?#7pJ$X?-p>hxmrKb#M(}KVE%A z6INkE1EvQe-z2clXCSAlik>UVQUp?8kg+Hpl6H>DhgAZo05d(k7;-T0v6L7ljK}X` z-y2=T8tqBzT_OzMD^gTJh;HdXJXi;boM1dD-q458UkUq?1!?{rR)u?gtc52m-hb$H(}d zT-jf1onZ&u4BM}JvIaa(3o|Vzh~Sdj*3u%`hXCegOp>8ut9Ej?vbJ8yPNTy?(y}31 zSYLk*ur328WA=cF$+m+zF#dPIccsBU41NrWxoH6klU83bHZHDjxp?Hl!lV=14?^E{ z$AF1@YrX;f4?hA!{uh2E>Yh~B^+I7|11RADpQwxYq7NVmfD}+6G7x0|(f}}lF`6w} z^%pOI%Z)TD3}XMe4<4f_oqu({aQ8tb3JAPC=UsLB_nat*m5C@>PLzs1bL(wq+Gz#n z@+Cbvl;?^e?cqZs2hoki{)8B5vb9Xs;gab{MmU{&H=hFCZd;j8L}8>;1L#e)5}oxxp=d z-zphjL|HzKddTmfkShnf-)q4hiB|mSK6nVvwv6_h6k#qee;X7tELAoy7MD_ROtR_d z`cnFHXza-r6y;|PkM5T{bTR|3PS8N$r$N31}>x~Y4sOV)AK|?B-)-^zWrQMqL`kM}Ga01eWR4A*F73FUSdSz{fknq`7ka-!ln7lT% z#O*SH2o!Sgi1)9o&-g&kwzBs0^q9!O1~oJz{Isa~3iM~iGrYGx>34fpclxX8m-lFi za`2lo2B_*ylLLkboyDw|M0?-9-bmbgw$~#^f( zVSh=>mk;{zFZkRv%SwqDEg`Kc-wI7u4vuA=;4ej&zkq_olXrb7Lw%Pr;onWI=V3Fm}4-Y zr{XmVtuhTzW8F@T%!AzWDNFCGT$P*LORr%xA4nijCzX1TYbzEz0-k zjsv>X1OBm^If>z^urS>zou9yY%-nIHB}r8>Qq{RHjrJ5}7>%|=Y{`S$F&Sxl!J{-) z7d0R=Z^Kf)_M*U{iO4d^9_%`^_cKY2j9DK_fK0~>KQ9|)!>aXZ>F8U|oDu;@6RO62$CFvavNKBsZROL8$g z1upf5DqxB;o>Yk{7KypuPJp+2oh0qobs{XtRVi&?C#tx|YaOttw1qId(Mz?ll7~wv zYc{1Ga9P7jwe6$>^_vXs{o-*9x8w1!xGBse6Ad&=sDKtZvB=b98l5w%xlGw5O)e=K zN^yZ8l0vK9meyM%Q041PpB;TmVDx9>B6E z{`y|h53tzjs{{Zt1^Yg9e=50PNA1AQzM*ZN0kM)q;ddIUlSWcO^DaofQMBG3hN#(6 z2Dcbe$;eEa%<`bclKveTJV4F<8xqlAQh? zuf#G;iX3nl*izqr{STsm2nm;^PTUdyuL}|oP>BEiHjI=13u_b7<$eJPtAhT#wXqTw z@&^V60{fWk;rm;+vfgFY#98U*kQk?0N! z3q@cs6AKHPyaO!2L9(*`(l=dQU9h9Fq@<*Z3I+ny)eEq4?74O54D%dH-sv&`y!Gwv z4bUC|*=2UZAZ^fqtC%wZ&?A?)X?J~rMJlj(*t?tm>O^q%G3ak&}vJxu(tLN0|NpIVcVTA7k{tb z7pvgJ~#;2BgMl~ zB(+EM)JM2V8$TB>u-mm}4o3&iN@>Z(?0IAB}o-;`RX z^*??DtTsd#C?9k!MIiH?$8UFOpR*|0GC=9fS?%iL(tndrmXJzve}A9ZWj*b1e$qB# z6<8qo10{E)mF0F{92SM2?Mf8i{Djuz)s`?|yC?8Bj}0uLSHu3T8Kpcj!D{H0xy%EU zO=x+!m5~u?{ln;>@-$qA_|B3SAC)Q(9}h&bu(L~~m$!FLRu-c59If>aVd#GUdf15+ zh)k%jKbmHQ#nEpoM&JUs7uo4}#)A1O%E}@>ed@iNmru@Xta^7cR>4ZH!q7t}#9Xzw zx{8oYtDN8Mvim_zZGLf4!^7i_wjdxB4{iuZC)^hdWn+2;M>PaTwhDWO-~}%w;ZDt5 zvN41~>Tjlo*beE1KW%1%HQ}EfthdbHxtu{__Pf>@$uex=?pY{m24b$^n#!THM|tph zfeXn6!to>>=3z|tyEQxQz`Wb*^Zoj|9#>Q-sdR804jzv&PW?prvp1zHTyQjCCdVWv zV~t_npRFyf`Z(|qjoq)^T)*t222d&Q-AZMH_D^s>3KeSjsru-tA$9|vyWf4h-vhAs z-}?Ui`ZGI6!^Gr!7IhIrVfPM&5-Td)DZ@?|Yqx>+9=W|G9ugfL-Q;OOS%exZ%1jm* z!B?a&lJZcq2IL?_p3vmNZnh|>2Pok`D?zXLdX4q<7!x{&?4`*zlKq91mRIX?2)Zl8c7!4@G>Huf9Ppo;>%}9A;;cvMMnXo$CgD$ZHR=;@OH_hq?^##YabfXzC|QgdtJ| z6h5=(YSMNeJ`C=D{ro-fm!Yz4@Lq)~N;Nal&G}>7&=7bqSLQkALb&=&P@hlw| z{>v+1GL+TSpuUL36d@o(qlXmOu+TBZ!r5T*wayJfsOWIf51Y$S-}Nk>h;u|yw6HxQ zZ-+7Oyb9pT-mI!2f^2o0y9U|^Tagk^hlh#UmqoE|Ru}H{gu@04e+>-B0Sz_}EGUDM zj?}q$j!+Gs!iPPB@`C9yKap-2;0v2Yw8p(VPLFMxwf1muC`C*dDIfkspw@$hhc^Wq zH1`ln-PGQ$qk;h$H*5tzZ=PUXL{um>cVb^NxbuD$YP+N-7{}1uEPyKEyvaf>vQqm) zzM83ul-+Uo9ERb#M2Omn&??joiY4Z zKR-XcOrTYLz&k0ts0-`akg{_M3jP3LlaRRtCmfR3!mH~aBXj4;__(#Kf-ZcULoxVs zfslm+l_XQiz*(%Aeu*WD7@d%4CcsHl^{^W7FEHDoamB)620K()3Q~1!fmj70M1!+M zc%oSCFvQSrk(w|N4|8S^iHri+vYn7`(JlC^kjtX%^{n-*4#J~`73wNH9E!+4mTMUX&-^sE!I|eFNdaDkDMyU3L~h>03?7b zXIj|WigUz;NY?oTW5NnfgaFc4yKI{I($fRJg6r#R6TwPeT3Yxm9U!wh9$cgz9w)3Q zI)MpBcZT05s~^H89co(;>e~ks83TBUut=YJX&)?$H|cFtn~|}SC+ID~Y6%-b#;*vi!b>`1Jw_u$PIRryF>MkV z8p5y+L#`%hX%FC4BI6lHL#ajXoB>yTvFzd^UZYsS5XP-8SQ4UW#s&)l7}A9V>l7ir zFp1yf9DG2I9SwCIliNZ7%e%e>?}1kX;hMM0PgB&lDGluW3LR)U!of zWQbMW71v{z&1+%e;(D6BYnU+MouDk6$A%JyFzoTe^~5DkUtOmCVf(u~0{lH-S4B4{ zds|Dipa6CDXk>?-W*DD+S|1ANRwNY$M`R<=8u|X;1=xi@fagDj@Db?JjBq}-s@a;F z7Ik%X0V`Eq9Xc24e^`nH13(rW93~eQ)K5=vRd$Z(|C_1sgkCMuq{{u58MpU;F_HhV z`VjxmeS4_?!-oFf4aEOdbYAKm8QCR3lV-vO2E^E4W%D8c`m=8fT{bUO1qOS#yDtDK zq=EZ6-yU7r+1Rdr{jz2wKqnLK4*DbP#q|L&Bsc+Biwl)2+u1Q;LIvm;oIC`E0H9;( z5@ch;_)DN}0s!7t^0(STq@uL0e7S%tLiLoZ5$#wE{%>7clbk1B!zEo7?A$BJUmI6m!h3-h?{{@rN!(Hq(nl3dji8U{h7Psds!O} zJv;q!*ud|A4bzDDkL|H?0bc>fwd&icBh#pCEYpd_6~5@tBgC)gd2#p93!-`^)Dogd z_+`V(@mH$`YLa#Vs$%yb*a`pfS$O!I=ocu4PbUsMGL0irdJ}^}H~uzEG4_68>qP!8$veL_vfLv5Rg2$dE1(K zMx=+iW6>tbjldA4YUV|C#w<(f|P<7 zlSXnXW}mCoq0Vw02fU=M3&K;EP1hxKkrL%Jp_>fGHysS^WK2Hz%F{+oXJ1@SxHPr3 zaB;d1z~iNIP01uhC6XkRYGmi;Dgff|R0tsJ^ht;JC8-|D-;du&5)6EN85wHfppchpakfOj?yIgX+=#OC@Cla zZnRNxx?(4ge>W2Hs(4& z&+XYFLFisfzr@4VRT!8kG-Iwb<#piqgvSE`?EK%ms#NSKay`-Y?74$|qez%3N-npy zuDY#e5y$!sg$9jtLXRA$n80kGSIFw7n>)7`o*CM`ceC7@%+@#A8pSX0dF04#RbzZ{ zXZB1-*GxsvO3PeZS>BOJSRkmf;M?I9zXRMTNe(rd_lhMgj3kUSPD@yg3Zs}-(;L1E zV2-?h{~p*hqU!XDu zh{su#ZXSMlxOv^)A~4(0OwY+qEmijJy8CQSf71A)VqoIq_KH!^)=$er`@4+l2p9bt zk6*z{-%Q5NR*BIxWadX>WyuqL)V2|+5(}wQ?b~)Q&4usMhpKP`oFPlh&TKbxaiKf| zgDnFn^F8~|epbQ5m|~q8P_IKY%W3=Y(7c8QuI-}E-7V63cJ~ljV%aBjvWQ-{Zth;L zH+M)1a#iP9?-&*1u}8ZkSu(^3$I+4ErpFvfX|O(brhE-`t#z7KBHcYXxrd>_&({o% zydAYq158O;Zsh-&E0MB)r;XT-<<@^g%wI&m@nOrFytue%9~oR)!u=mug{XotTio78 z`v3<(@AS?Nh%bONr?r*m-*|F|nKTDrF!HkZ_XRuv#4i|K$3(z#laKoUW968UXK1kf zHqg*pYl>9B*lkLY&?1_1e3}cIa@=e9#mMCL#I$$S|BWw+#;tCMIZTl@_E#&HsmOSh z!|5?ufp2Iuo{jsrxAgIGhDoD9@t^%{5!61h!~pCI9lpaxRV4p}1dm3x-sD~P(y)+C zqxAOG+=B(45j6hd6Ij%@nZ){Vxo|V1P?bkOkZ<}vhxV2YPId|HCg|gzCUoIfvr9mE zghsMj=Q31M?PbBKPDV}%^I4mBl3?$)W0eMIvxbimu;4aM@~)p;L_{KTKnqT0m9*4^ z;480Xq&=vS9gQB%KZy@~I`uJ-L519CmaMmZ(c`r?WajLey_;7`J$2y?{0(t1`?3~K zhq_exQtry2$;kA;+t%0pTT8`#;Zch0DS^!}8H>>JNQ(oq zLLMP}T_rD8#C@^HAyf*sV4z*$@a#^8HL0^d#mxg0(KAhaTa#bDkl%0yz!4-X5V`~t z=R(SEQ(01p{hoo_l&zu^Pi`y?9rlL0}s1*EJSS3Yu!9b8Jg1?zY z18YdbNDwe*rSI6A>5vznstzab4uzr8hO(*daSw)kpZ)y(q@?_4aLP2$rd`)!%+u1Y zi;D7tA-)GscIW$I&3+JNpx(3G4!*cQ?Unz}>s-MvePE<#Kh8a=~I+X7K zKwbjp2?z=GbVQX$*hYIKpO*2#%u`d$1|%fnCF%@@Vy)U5o~g~vTsXL_ z+i?gkUc61I{PjO)M(XGU*D?(|LEbxIf!-}pa&S_d2DLUD>$Is!pJY7wp0pD(!!?#M zH;Cq;oIdXBi00;yR98lMc+M^_FVD|wX>>cKVr3<#lUe#+k!9S2C+}msU0PcqNePG3 z*9AJ)*R4Kfx7%Ev4QMJS!>Ls*OTMK{d|6MA&(G)6_E)#h+gR?f?6Da37%{2s1LiSl zeO+m3(%@;w zhWN2rSy|OXh=ByL*f=3hC^UN<(vN&=u*@sJ%*j8b`Wp^`;xtHdcZxpJcmzvaDlTYy zy5A}PJtQmT$p7U|V>8!K2n#9>t((G|x3wWKd*E{B%N<8z(l6&srxP1tN)L7V;pM)2T&gRd#IQ}JnK;Tko%M%}uL!Xx`iiJykM$&o|Dj?M!YC6SSV zJ}mr4u?^b{_s`w4{GX=+AYj&|M4~#v%e7y?(|#+xu$+#xRo?dS16Cljn(L*5B%1$F!6sqJJ>B&BcioZR)1 zLag{uz73UNFfjpvPV&wOSx`4XW3*(#*FwN1tYIt4ej3X^mcoy6A}R`8A0>9#+n-Ss zQ@-1xqua+MMsu~8_mWQI-(!buZH{B-DSt*uIVQfavFnVvsX`ZiR1OdN6Ld*$ACono z{Pdgk&$$T98r0j(OiH=w*OvqAW2h=BKP_8WQs>Su{L@#%7w=hLpI7!$Vs%VQi@S__ zUlLf+{=5a@e4W>iH2c0CHueq~1E%q|P^}8!%D-SuK7Yf$GGP5_1XBOpRI{H7)zp11 zw58|~R!#5mU{b%k%a}2Jye@$t%QzVq9fN_1S2>+1W`%KoZ{6R5bki)o|JOhZG?JpGHUxmP!w+=uu)~u8?ZgiZD2dU(PN>u(JH$|$E9UfM`@~tx_Ws> z<@Q*37+A?HRUh}E31wb=NmtHME`bz~8tI3J9eI2{%cCHwz6O4BwG(m0f}Qa0y-fss zc>A6o`IZaky%gFUA-XXFYwzUKoEI|yF{JGg zC!BL5PS7*d*49odPTX<1YY1H!@NJ36U&wggY4Vqt7Z_-$sTvX-hu-quRzf(19Vf<| z3jrJFgi3rlli0rE<{fFsYT5c z9T}xEbx% zMnB)`{pk|txKg$-E)2_Oc^d^UO*J8CJ*}$Cci?_GX$xImS#F%LmTwzkB(7~(Y zPof{K)S~)Ef4EykiI-r9ukr7Ce?Y$FnqPG>mX@}*9_fFCNgJ}@e5Y|UI?9wXAugQd zDw&Mz-UQR^aMb_Uzr&WqHDR#h+CFK!C!_7`EiFBBh2a|CG^!7Si#aO8q6Y7hDa^?s znO{tA#Subl!4UQp)@VuzCHN&iKACI7ep#tP$Zl1L zg-B!L`^LiD+}756HoirEnQTKtV2!*4g~%Ma%*nW|F`X_xLa1pHzoUOh;;)F~FVa^W|1kARhXxe_hW~3XTZH{{U3gIl$}wC6*3NK$eAd!`Uy^1hx^1ke zsGx*_(j`JiPXH1$7m5bs44~y({4h{)DjHI#2D8zO^6#~@fBA7E zw@TG*$pSWZzyz!KEkRmwW@H`%Ow6yf}ycd*{V_5bU>Xfosjq4|y zT7Iu@yVN~N#o6gjVdy!jvB-4^F|)|c%{>*z1jb^J^Y^2L*K2C*DnH~sqe3F5{HF1A zJW}BVWHyD2Y2)&2iOYqeZ0Z6Mw11pv8G?N?(Du}|cgJ^q67J0TEFh%z?uTO)*jwHZ zI;yKPzO}Y2t;y5Kn>CAmjy`*x;Tex_rM)w1tOK^**!qE&cbK~YvfuFQ_SB;-IMXXexp@i zZV<_A>U(F*Ix2|{O78MSzuw|2lL!PMJE*Cv_qpC?tJ+zto%V-5;7NXA_^zR%t*+Hq zR$63vfvNwV#m5eIcyRE=LfgwGw=4Qo3|5lAz-*R-Nj|u6V(%Q>;!OCZT3?`QyEAZ% zqXnGM{$(}>CRHwR3gRpJ8l;dXuz=mR4)rd_s?>-Olwr}S$8<}QW^@G)9^9nUc1v0` zfuLUwuJOK=VkJ*t<4GmUm{G!4A9oAs=$??fuQ!EoQCY&mABs{}DlQUDj=+jdnUwU$ zzz$f2q}be>wQa&oE`}Z!BqM*3&Steka)eaFoX6C^Yztni@ZL)*UY%9O()emM_dL<#`I@Y?gd8H|o!_Z}#Jl-xdE0%(dAr;FsIxISv?|5d;F8bX zG-Po}KRcfo3kwSeV-Fl8%_>0GRnsTPx}c+^Ke9gcmG#@ig5r0r-`%=a`CWS?Leq>r zz2uyWx+^Sn^fk6N9%x{#TZcoJKm*0^$FZyLY0D@CShcm#YQbRjnwk^RRZ~Y&%pB5` z2yj;jYH89J1V!cQ94V&@a&ky=@@HBWLA@|f?~k9jRkScjFky3lxz)FMv|H(I%Ud@5 z<%zTU#P+|2T6U(lCqW}BxgDIV)KqL#-;_33$Q$cBS_FpG56PmFNEA~Xq_pLVs}KDv zUbBgWxRYReD-}5iGtN2v;gQQSu@rLX%$!j0E8y2C6xEm8%`;Tttf=S*L*;T9JU85j zc*|;a>!U`Blg4`tQI#f)=U2XI#%zbAD4t#@v8VEXB*|D_eBb>g=yJ26E1{(>zQYwo@h8c@(u_kyE90{L6Hs8vASvqHHD81oC{3?;u|f#q`wp8iX^+ zX3JrX@X9Y=g=`{&XQ)IuVCVHJZP5KR$&jEoOBFq1mvuR}a^3xzhn#$PMb@dOq5)cn z2 z*gTBX+;v^f=Czplc>Ppi9B@~$BC^7P;qQlqB!ElY>$Mm5UK-cpPZj1O+Xv}OpDtaA zql3=z{A#!MWJE&AM|!n0awYrsd-SCq!Ly5`mUdo0mZQQx_dV|S{Ce{}R=ycn>bI7y zYM$N7B?Z6G_JHkphrSwryc-t$^Y~$unxqZz(KckYCgxN)n8`I3LmT9AIbshVPeNky zmP(6fR~_i4Dlkx)A?<&XKdhH5#@z9oW z9Ga-?WvJn@Fg#_)xVM$-m6&GB{kzfa{b{9n93=XkrM>bspsr}>DX-U^k%zHcYU=uz z&rYSgL|%_enodtKEz3&Zt$PT+W$LN8$rIu738PuGJeZDT?gKi10_lW#M3x*uRkF)U zm-}zhWP!~=zaUYY&Zc{_e0y=!3pscSjLGWG@ehobBbIx4IH|HjyY(GxS;fBKr3j4U z+o?IepJaj2Lb4moB+IkC(|$}zrcIQqR!GV=k9GNS)XZs3Z!cSxm7f)054*JEa?7|} z%Lhv9FD!`c_E}-x?sFsDXPvF^4~)0-rIqH2+@CVK6F`iY8Jsvl3K_jA=VF9~VBO&ZRT?>_B>DWXE?kh|#rf^8% zw=0}VbVr<7!oT(}&Z`Agmyqef@Z86S$yznD@(;WAsYx(goNDH#DC_>Quy>B0dkR|r zgmWKfR?ZW0+&xKZe{tIvcwVllWAvSl<9=#ZkK@|^&-HFa_H(6F(ye`FCE~J(y{#qg zmgHVj)r%amxFo!RjE0d_{qtqBfqXfft&p9&Q)$Z>OO;yG;u2nQ*h=RYT;<&2W(oVz z?5eDYkSMGyIyE6;a|*Q$naKJ~8~2n2O#v^RubLuW!Bb_d#p(r%HpFT%m8>IMNp^Ch zP$kq={gUU&9Kvm3a8~vf-zAiP{Mz$p$ZtBQdlK>}-LTCsr7Gg0G)jddHg3)(=AWylZZQuxlJNNBMQZ9UE0` z%My1rTwS$w9eLaCE{0l=w#Xx}or>%CW63Sok97&@>22;X&yZczH+$r5j~oMpHy;`)fwka64uk7f z;1H|8=$zc|ixBgb^VjR%x3}ppNJls`n@Dt7R4ow&THN>dQzwMBGs+8T{3n{4x+HPL zx1B}I;ykRM89}%@8S_rFy1PH`6ap&+D?0B7QbfnVm(2(yY_Xb}K zw3TS4XBRiO$jjm;%Wi|K-0>~Y^1G^#X0aA|94HkDReoU?@{ zR!)X5vVxnkU2aSkeWl!Yg&9Vct_C)`;`YMAcG+XjmKufuBEG8P@&LozJ2Dml!r@kh zlws+{uK{;}TDrWvoTnW`**7khG&r%!7lE5f{y_o4v$+R^GPb;^<%tyIL^#5dve)pm zKaLZi;_(6Z#urzy_&hCE3jJM2_J__Y%{h~WVd>Ms02B;bO~pJ1%H&(Zm}{dUMQAFx zjtSlw{cTL7>!9z5L}uxON>WOA$+@oW*kh_32U!n=LGFEE zy1=9aWt1aUBUW|%1DMHqk}kTJdAlxI#@ajW$r8`9B_`5s$3nH-ST~^%)og68F_q0; z@Vr_oy$#ji!%w(j+fYLz8Lv`}Vsxby|IvaQ1-YAVwpm-LxAb}vxa@2RAf30*oEVzL z7Id5VuRc^h4(Igm622krwtS3<=^m0yWZYV$DNKJ^6Tuzh& z;a`u_nG>KWCJEpN7mC%fgY$~ewX_6Cea|D^RSqx?o9<@t0ME7KLEj&&AAiJsPF^W1 z0`+9F{M^!umP6%lbW)?tzKZBXSR%2kh%;i*RjeQQfH3SZ+olDV{fUJmlqG%|-Y4E> z6^(FoltXoO!&8uWbblJepswllk9R_sV!3&4^xm#GZvojM)KpZ}=bLV>7|zP3 zCOIpz=Q;8;Q|pYiI^FeUm9S}TbgH*RFm%f?ogz`y;@ zez!F6#|1NNnf|z(c5@o{E9Xyt0lU&{J)M2;44(>oi{^L}v>H^mCsjkS(we+w!=-9D zxp4+Lsn%gX?-?Vub|5N$jO$xS-jDuwwQLA z{my2cHsgU82M)d};AZ$wfXm})+)oo$YHCM$?aO3LJ>{L}3RA=h>$JpzzsZf7K!4?MG`)B{$vW%r?_2;ibksFfV}?KE{o(o+zkurnA?c3aG4 zmZUW>aAY``hyK(u{sn~Fwf~vU#b-c}XpQ0U@Nh&1W)L}ulO4e#@IQC{S>K@Q;J;GI z$o~ijz-C7>Wf2h(7Z*+pY0=v+7=ZZ>or(RgJVtmP<=;3Z_P?TQQU4z2LHLgqeuGk$ zyifA-yv`xsV$3T?u2PQhj{G@8*#G?e7jWuDK>;Y>F@d#D$hPvGGzEvRP(zoX@H?2( z4?hU19Yd#fh1>YOg1jLosU$MasO!lH;)*B8lluCxQ4M~L38SV^k@i5cvOmH2%M z;@&T#PUy}nP=yu<6UgM?Wn&4@FT+$ZuTO(<<4_+4tv0%}Dj-^|k6Y_Qat@AMwGhuB zLDNd51iiJm*>mfkomSi5H4xDXW3l9k#BL*WdG&lg1Iq_l$zM6GUr}jU|&JtMYyOJ!p12$IotFZ zgKv9)U1UxrjI*`N)<$EpB6wckPYV$ueZ$!1;Vo#VYzY~U)Pb>pm5dLvl~Px4l(7j~ zH*LUJMNNk^71I8JY!ZHsV+VFSrmD7uW~+sYQ0GZv3nI95R@kSgW6&>zvp9xYkHA8a zNgq!Dq8qjY)X_Ur+)<1Q^P6G{-$A;h0j*dV8962!OR<=homXW!_ERB#xSH%FNAw~o zj0|%u#TxzKp#6}po#~Yxt%nYFy0Mv4q^?m#{URI^;|JqH6g>jT=8zmW@#KO9d>3_` z57Bc!*Nd_oN1ON|LZx?8ht~wMzf>M)o%}9aoXZ-$wIvY$p*Uw6&!9)hz_4sor0GaW zp=OKX+nwDKjWp_h7wu#xo)0N)7H?7Uc$|GwRhcQUK74?WevczKJ{ItBaM5&#Mqgv` z29@w#{WM26b?M=_%dR4kTBwCnfq$Oc!R6BORl@YA{*2WMhCxmRAC~j!a-NRYy&Szy~&< z3zPpzV1 zguPh|Djf=wd6cCDKC^0bN`;u|B76~1zi=h&B5Z50AKnQXJ!Dn;|77cL;ISiYHv<`2;lGM@RB1}$Sas81rhv6yCLHP4-M=zqxYg{ja zcU5#TvUH|D)y7|pMJ5_o%DDe%3QhG&yIoK(ssAdw1g!-HDa=5&pzMKld`6ogDz6BW z2K$;%)imUz4Ym-OHXQvXr@(uTMGc*#-5*XKhKKbHSz-1rg+sgAIJu26x2G!Egg?B z;UenQhhMO7ku+lLf4fpe>KJzvR}qQ9pn>VIG?P9NrVD`)3!0fJozY5HhgBxJvq6aq zBH1Z8?!&~fe0!aZ=@?vbT`1`=I~jdmXk)LX>E8~YOsyn3mT$zbFUAsv5vLU2-9Q&zo;sXI&UV?tO|U07A(n@Z(kNwTV;mR8m+tD-f2 z^G+V3Y<+5COL2wL5katny4xap>S*ONBZ2QKZF-7CIF5OJAJc-NNLBt|?#8M59WY%? z;N{Bhyq@z2C;|rX17rgs%iWIrmYA=Z!nxY4@oZ6Ez{-3}oZ?*jbC@<_H7>wtCE z$>6?5(1@Ce@g33uTQ+o1=lWjEUe6F~E!fGZ$|Ec7X5KC0w;4U4&Vls$$A=O|W)%Kz zyc_-WkBvBB{8Qa1{o91nDE6<2Am+boaQ}9roJj!3|LFlC3=4A)Z*LKwD~P{Bo`2g_ zDgZ(5eeEQi{AYGF1&) z&pFRI_s_kzey^vhR@Izq&iQ>~yrVLUy?R*x%LqsiRo89Ea6P?F2PQ>691H#Ly?Z)k zE@_evn)oWkrlqFDPiCxfu+i6E=_|}NI^DzGxw<0Nwr7`E+L&JjxjWR(H7>T;rD<a2i%{(MFuko@*3ZK-!Cb=R0p-dLgh5|J-E+GEpB_ryjrcTLF|F2IWED@=^zk_$0kt-2lkRy2# z(Mr|IQiLnT9cvJ{&n)rPQ9Q!)&-{5I$I2u_YdIEO_?zO$Geb4^ds>~c4t!M} zR_n7V2a@8m&nCEkYaP-0sLJTUDidD&l#~VREplVuF!sP8gQ!6hQNUX*LlBP8x{i{zKP5{Y} zF(Ce*7g+o(D=Pzu=a;_^JBRid{LjG(I)!M%KjVFF_XJ-N|F(s|`fZ?L1cCO?+9>+9zG19ssB!Ue0GKldSPL8&!(A!xGf-g97D1S_$49|QgBE0{i6X~hZnE10cC)w z9mvGCxw&aRnXag&1`;oQfJ|R|J3BWs;)M8oUiXI+Y5#yJGUSHb0@@Vkecj)zFDU; zQn#Yvo9QURtg2?Y4(`#|k3OWB5{=~agX$Jhx?et6z z&ZtWmi*Joe{9kWB-v`&0R8U4T$V^B}>ev+zuGj1XZW%iKXZooznI6HJk})rQ!1^I< z?QJ)SYU4%8leG1D9(S??^FH1WPORheOrX>i(x=R$f2RSfbZ_OW@HM|pkP;t?dB5Rm z9mEDn7^e{o?5Wl>g&^?epX03u+4?YfL`w+yxt%MNeC1b_mzDiT*ZSXW+m6on_6C7o zZEfC8PPLL9BMgat#4pUHOt3I8%ONVSVcct}$mMw@_NS-Y;PXl083kpPIGwTHaZU5u z=jCPhOMOXnygKWGv7Mb^ulTMEagit9TOZZ+B3PAUzZ`F`9o%oKo6CJTC|S*e9s}Mc zbbRIN^#d>|?aeGp-H)^!7UtF0p^XZ8h3ZPrB6`*4UK4B);_&@0d}MHs&Z?3uP`SP# z;|!h>R8|t4QgfX9kZ6Y$J3Ci=6ZHF~8xR$mxVeJ#>Br7nP{t@ZU;E)HDyqy@6?;-} z<)={!$LGE@N!0kO=Dx4#{REZ<3EDU+U_4##huVeP0k$;x`zW2QG^Qh#boVYMiZ@kVv* zYsM&+fJ$fD6t8b-(Sk}4dV2pp zu1Tu{1+T0tDyF8!2`#$Eqz+M-g&aIw`=W_wATxyxJHoUbe9J;r?540TJ0ONzQDx=j z$%!Y&Q)RNm>w$ci&qdo39uEFbcMvMaMuM6z-7=QZsnvO-#5dye%i0g{X^us+Avzw-BTct^4ECTS~X=ESeMYo^>UUbpX_DpOL?qurlOLeI34DehZatQHs z{r4{cxJPm6@9%L}zPC+L+M5k|4|eHY9=CV8_8&md?RQ`> zu5;E9P3I8p2GO^b`Co3wM?nkjZ+h-cv+V`7V*KznZ1isL9=~7p&hoFeUOE~=Jbv+5 zL^k(^K)AHZ;%WQbE!gUM0I4s5TMWRtB?H-DeAEa*6_HVT=9 zlwiRyiJdV_h6~@bilxuDJeu3cq}Yu2qc(3uyha#T=2o}oy98)-UB1z9%w^|yD~cf& z{Y$V8=+~#Kr0*2CN{FeCHR!URy6y2ah zeco{Cm@C6d9AY8HlE3W3DFv*%*Q?&KKCg>X4AJJ|cKJ_Ba2X=35+;Wde+MM_Skmgb z*$v$owSZ4e9SLcz%Y1a$#8z$N%rN`$na?WgT>bOby6<7Pxmfo|ij{D9sJySx)FR`##pb0)pEvP6%wVUBE<)0{c8$vA!zlOL{(s?Vh^NHUs_5D7lv=2s46mW)xk#QDMLdJ|_%0j8t-v?@&|;Zb({m5w=g>l z-(L;)RS~1LUtCw}Fik5+ddtL%R-R^rDDNkW(KtjQ%YKl2wn6{OR&2YyT_eOxW@klq4@q^ok%zqKv#Cnzh(Bw`j5i=)K!B_2Mce&||FO29jg z#Dk&LQPmi}fUWHrYDOa3;wq1raki;~nUz(-wV9L@MJyp-&1Z+M{wYpmE0~%%kGE*S z^lgeKhJC!i-|xEt%1gJ_RyQ3FO9FncJ4gC>{EoZFAHr>)H*MYo}GIbpl&b%)m#q0&Glw14&G;08wwlm(&kB`^X232W29u$qdEk_cP=0)o)?|0 z;ahJnwxOSgxUQ`|Ev702QPZTZSrxVxvVUcq$|aHitnmPI>*khA?O>97-E&lW%ZnH^ zx@>!bzK36Q#5+yb+t8)(TU;im<8#!M!25lif9HAHsnbI(fQ`N>ZMwthFko@<_f7$k z_1{GvNh4=2<516?#y5JXMh-8l4IO%&Bl@l-TCytdXbolTGasWa;mzUo^X1zW{7c@X zQfoP_8>z_A;1%kV>P zcw2(Dl5I*#bY|-;cHVw*_4KHSI#*j{O{Yg2%iCkeU0fVeW;fKe_E2TX>8dwR*7DKs zB|f$>Jv*qR5sE@is}!!*f<~F(NYD3|l$o%{&e!$xem3tOco1)WXqRF7SvNC`+OGNc zeeEpKUEJquL27BBy@7{`rlyx=)p3iAVu^`)RX)m$M4mI0pm#<2P3Q(oZVM+lAY{;! z-#mWmG`5?kb$#*a%Az|8w$mDAqVK9Ax#}vGP}8{=ZWp?dF%X0B6|#E zIC_CW34$|Jo`lh=gcJ7@tipXQ`S^%k8KqLH6wYJ-zYh`-3DHGeAFN>JaF zDo@z39dtxpG5A8LK!ZCLb4oll+;!UG-7cXhoq(B^^KQNd80`;(AMo^GbU*1c#E@z0 zC3IQi|B-y%35SMbxq!s>@O{c|-X|bX6TAJoFsokP^9~P~dMx&62`xJKvAZ#@!v8iq zUFML@*SAjIt$tAhI;;V-_9k^Ch5lbQX4P^k%!E znrR?KZ7AuHI*P-kFmaQo^RH-v{{aBUkr1|BK*#{F(XpM>aK?1BRdVICx#pT@{+?4E z;CHezi~PXOsEe|}$(s~Di7kssRuNJ+tzLvl(E5)8i14iircq>)8q&^2d}2QdKv+Dc88c<+*8(P&R0Z)f(Q>WFHlnz0xA`lIGSuV-eqque>OYdF(*euX-aZCs$1 z5wYm{(sV0zMiDA$Dw8B1EjHv+?+{1@l{r%D6uw*959XBKMK+E_v9*u zpq>2_T7!sA8?F%*qzx0{Rh8A`JXwLA<81yKR(tW3dHoA)tlGp|Fv(SHJzf<-qWnU* zHF|(JuE|{0jiUe(3%4YTJqF*1u_Y>7Ja0HAjBSITJlMP8k{SB~4?&iGAz z3YR}K%@}KfX0=d8c|g|#J1i<1il_0#a81wS&E}j-!-GX``7{Z4e*d9<&isHcHjXdR zIgg1Sn}z2>hUL{-FFu>R{?r?qW5Zxc%K>N@c)MdIufiB0#M#Hl)Cd(4B2-NRaW zIB9Ucy1=Spu5Q%oA!O7fcAHQ2hpoH-G(2BSBiR*PY+zPjRpO}uK0ZDHyv(eu(UFnh zQB>31Ahe%BRD3*gs8A0q-JKA~Jkj}930mQC^%gr+^=wDcjs>b4HMO)>S5{h@n**M< z?Lpv@W2fwxpPwDKqcordEEVd7wKZ?!C2An!79M`3*J0eJ!=%~f9+CE9yi_nC(+Vn_ zAqB&C;^VN05E@#NY?i1N?mIbMd=lV1CJzou9Ge{D>bMB=k;SjO9y2mu#p}5*`0aDo z0V9C&%Xb>-y>-)laBB&?OBuVrH661D!x-N)3lfj5sUHWKJm(2}=%uCqGHZ7bZ7qZ2 zSbeP?y^TX!h1Ibc?>>?ny~T8Zsu8Ux>^xF}3ZfsS=GG{Dw6oafQzt8!h4SPr3Hb$v z2ytIIHsPDqaX(5^)%7x(!&AyBEvlOy>A=kQIHLdg#6ffiNb>(2wMR;?iI%a=O4k1( zjS)U{O8GRawEPs8r04lIp?ic*7j^1Q$+v=tc>8&G)%AX*-*L}eyF^pjy?Y~^+Kk*Eq(QEM4I8#Z%O}A3nTGS5wp7G>-!M4+_f85!&L(4ErCy60`=}s zSC2T>d`i^Vg-DLa_pvSvF%WN?5OTiNXF(CB*fnvm^-!MKy<0EWXVf*u75$=i@?KT} zD`&5sq<=ln%gRhW&U+eFFj-!v{N6^-7`mK}qn%W&Uivkp<$`8E+aJ3=AG*3g6&lDG zFQB|X&#sm_4+&=ql3FS?1;~+h@#(STebse)o7MR|#+9``qdBU9vkMSZcvHzwdQZy& z-n7?B`;}#5d@YgHKo*8jPB10!Y;ynHviJYI9jo$ry!j+h;BOQx$#*(g|LDqi0l#0a z+`4SIr@u@wV7M+e?yvpQH`liLIX70-?!OIZOSpx>+`usWQwbPwkh&^N%fiI_cKGJ+ z_fqgAm&Gb&l{4uC72L0`cA`X85hrH##5(_e@0*YMQGeFmWBmD2pq#BzLbhni@cA;K zYi|GbFI)7)BnLb!Rj!^6AlU+z7RLS)w9YMw@THx;CW$6nW zwlBrtAc$n2{olC&3lFjOIz}DZQcFK!fni%w<2_W10S*&Wvq}q*IjDz|THaOZx40N1 zXE_?c7?*~dX0$*WI=(k3PiB+$M?(ywK${&y08lMoNmX9oICP|8&c5@8BELM=QAr?% zd*#6Mu)nCy?`}4n(APswRutF`wj?f1ZhnxU?^o_|4B*iBKPZs@+YmJRmW+B|BBAf{ z1$XV)Xy|JF+`y-FjOu0THw0GHg2@84Z9QMUl9LnjG`B|T6tuOSuI|Q^I5qIP4+#WW zSi7#hthlvOF8o=OolR8TZu?ciDUZN!;?*jja(D`EV}^m6&D-GS|?c% z;poyHfOJh438I>*h>@lp_JjzD`^notOH1PO7ed~~g$aZ!)bCr&98D6$>`P09iwLyz z#9`zwVeA~687X|-&7Z(0q7ibGw3<}KG4O!l)RPITQ>!2J{#?*sM7<%g#PTyTHNbap9#cJFDsp?{^WYwd;+zv2~dSAUhl ze1{ym7^I@13I0cpa<1W4tO9NumgFkzhGT1M3ku|1j0=s37?~2JuK7{YVY!H5iJp(DuVZ|)XKQJ>+d^*YC|BP_w7IhhCosSD^Z0~Ik#Aojwv^*a z3lo8ZA5Zw)kD)UC<#5Bqmi3pB9T#nglsH6PCiZcS4I~u1YtH%- zH;%os#>!38;M|t<$wJmC?JMf=rb)RkB@$;Blk)W~sCsNHy7-0Wxz;XyWgy7>6quKr zTQ)H#^*VE|L*x`nd{ePXYG&r;8m|GJo`!}8aREwuIc_b)3y2op9r(JSt`9Z?!TO!E zpB?bE&0dOnVw@2TEtlo=Ym=W@?0EfGY8`~}VVL_H$97-M0o9A;wYE)Iwd+k-KQ$I7Ov(w0V-SjLy&7uV*oAw6Gom0(pBx)wa<=e!yAK{XDL zJHzK?jAPU9DB1c?1>o=?ujs>bcDb?MyHcQckaL=%Fn*Y9qJeBh&-WzwmmJKEFl6+tx-J+Zl-a3(#cmMDp>Bd}Q+8 zf~qFi?6bcpbk1cIdI3#e^Ahw|Vp$$Eoyd=KbgKxI`xd}Be&;YR?OJ(1*pf|x`WBYK z51kWSG(6krS*+sYjlgbNj0Y}(#dC-?8xoXOAHr=kGbx6=I>+J~y9*87$B`*gBfIRL zmoxn>ey8{SPrnnidS-S7MI(=!S&+u{zBWNNhAI9sm2g?@J7m)x&iK$kE9J6UHpdeQ zyBMyO-)-6F^OnH-<1cHG)FztA-CZhC%$b?Z*3wOYTzos}l#Q^f-!Wu|40r+Qio)6) z8!z;YW~2&9BUEdehQ)CKqQePXkPZdJ+%snp9P+U3mNrBT>BiM*YireP)wrQk!d0j; z{mlVz?$6k{R!6}7$IMugp5H-J*DDgEN_VmdVvK6&6K=TJ(-f1GEjsJQ#Mc&9zqipW@4SeTee85wkm_m7WIx?zAYPyG=9yu?B^KF_`-5ZnF6jm75TkQPa6HAx$vQH%Dt{Jb$5mx&(M26;@I*x*kjc zWGJ(YGZ~5d{psqeXlMw%ByVv(#T@Y4hy00|Ded(mHYKKCP^qHqeaI@)(iVssG`BREP^>(Y1h#5@=7c`7pTzW7gI3)8#HpNUr z^uxn#14Dx`U}+v88>g)eFE%1kxpVZW~&Hu@$u1d2L)Ztekf zMf_DOTE48%RC8MBsI0_9gimjnzC@l z&TuA-crBF9GrTSIg2Kyie=|41$K>T&#igPV=%PYUz-9YK(qGdJ?u>_Y&kCX6X2H|f zuTBe)f_IPgjLZRKJT4V-lC~Gx1&J2E*pHWy-j9?TSgGJiPk1fGUK4GGiPA^JdK>K? zVk^Uwlaqs^a`HE+x!q-hz5dmRVK4OhK635`2HqZxeJV0-!i*T zZn{WWq^22NkMNNX#A9GI#$rfT@J-YVQ*mT$Cw{o_X{PmmrBL7cLQ^;Wao`Od9fyuV zvAo47W0lMJ_K!l}5`=fq{Mf5&`g<=UNJ$$*H(!;-<*>+F-|3~}#LL3jUwIgm{DnbX z8J~^ZHFzx36yl)#F{VKC&EdOT@+q{iv8A;y6n2OAq3{+E4Jq+j_j1NRKS70k$~H}+>Mbm zlmoFhzVnx8e4Zp}DmTHrxDUT$pyv|j*1p4K?gwfA#H@^elbgc|R>r_VZ2l`xD@_$S zVERPK#ZDBHcjxx%FyYUxr`lwNjY;CD?*1JHD8I(kCS(z{xa`L=Cg;kz_sL&f8Of!6 zaC^r}|JvD;kal;a(ypSkvO+r<=-@H11neXh`5YzjRWV#2hEWMLxkndmP_o9@wTj)> z>T<%l9wAz1aTH+2hH8C#+6?Y%j^pCBRq-8nliqP6rbl;aK|vMWoHX!YuF`QLcurZ3DM8RKw$){n zD!1ApdP49WBFA_}a+{NyM)L1*=p4T+f(OFLW)bUr2>0lxB57$BYXlyS4SRwd$s89i zVjYN9`gSkyS$~vKr`JM?20M&y%EbwUzg3tgk8y@(NDhHqfT3GL8`Q)h_zH*Ed&cm2 z`ssJ)Z-3sBjm5)G+Ad$5j0Ij@@=iS#^+S-IN*6C)2PI7~ixjmOo*gM3tv$3dY`(j# zEqeAFe*7U$Wvt%}-yLn`cBR%avQ#ef^gc6a)d^&WSn3%KENFt(K3*u4aco%!nfvv- z{5HC~f0ByrUCsG#^{w3XoI?}N@qa|WtgP)feO`q7*I712{Q9+=uJW4bY0tZHu()tm z1gW#sa-hWJceQ4pRM@K2aWNAE{uhsAkGqEO62cuuHC|9lBhlB&JSn^Js_PJOaD!b@ zj9qW3#<3*5>*=DeKs;IN6*H%lWYf20vw+-7-JDuYho(3;^18}C#dz;Ttf?|noCCJm z<+VPpqodY(mRfnZbAhU9&#PJg=`Uv*mQg5jh@72sw<7F3;xioUG$?yS;i2w^3`;KU z56Dm4GJbq2x{}}>yQ$J#YHOSCcbq+(p)P_Mw*VW)v&NQMLi6+}NFJBl%Y?Yxosoqz z<~C%R(M95~a`;{_x0>ixgHI>x_>oLSkR)&S=;*-fe>on%S0tCkU4)skF*}!xLg;ca z*dokaBsaRw>%2R+hZ9byO&zKNFVol{o^qlu;3s$4JU#<=G>LoKMpnP%WnG*dh2f+) zpwUP?sqi=&nm2SnpVe-9q|3+3%^`k5O?y4t>U{Yd?|N_efF=^L`8aYXWn_moqPIg* zNlmRIU~xtPw`FPyZ_fSt5nf;OTH|l!U+^t!_e#P)34EUW(W!~ego4R*s>GoCng$ zLG_kOv&(J%t!zp{ksKj+k$HyB9BU|VK_%Z|7 z;W;|m3&YvXFJ5ck%EHibz2R5%x_Ug9DmuPtg~#4FGB%fIN}HAy7&#Z9MYPO_d=`!a zV862~TnbbFGBRT$986P7frQ8Bf3j>l(ML$&5Q&b98;&09?{zy)O%b?kz+%3JI$l0 z%9Y-VzA&@j;FKo;{~b?#-F7Vb8@I86C$Do#`by4V?&MAhS6FdCpBorSOdp>0_=9sp zv)|q=GImNrEpvF~*7R)*wGBQ&;&Es!vY7sMt!eMNMKJ{T4`b>z5u}(h4ti~mHL|9r zLhSW<_v*;Y7cOQGCl^eJuf2AY`(Y zrKPP5weJ}21YQ4`4*x|alb5|7(eg73i*H1PufG2TW|#fGi~FCBosqk%jd3i^=Fg4U z`fY+;X=$V@hML(76WWaQDDSSc&qOs{zUvEKr;OKg4b#5|Ta$0D5^Xn4Fk8$~x9fmO zU$0mDBV%q(eg6)Pgxy2?{6u#6-a6LwqN)=c{CLJ#%3{+_GX%B6v#se70>WarCzreS zbB#W*R@4!#b9qNNHl;iKk4ycnDqi}h0dTxiBXui#>X+*i-9?0#m!7?A$&7{rzsJVM zLpds2gMuOEufM2OZ04dMG9=DNV&dwQ+IRj;b6)ShAg%EJ^Q@a1nwXfti{0j*T??bT z|EDzcx#Q4WUtfQEYPJ4FPKK=GefwZ}bJ^HwNYC%(K>zb~2?SEVJCH1Fv^oM(6VUp$ zogS`IqP!l8FRB=ayxnwRVKRz^(EAVRTQzhUp@O0-1K0VSLQi&Pzb5Dwayduc2~-dR z0>*O-x!wwf$oo}`jHd!f0b1UWugPczQ$xTSn&E-1PbCq7R1u=2rh{i4SggFyvo}Kj z{CW`_E*jk$d)-}#5)QP3!z2HZsy(nr_-0Upns0Bc6_mVX4qj--Zkx!<$Hya%3Zz0F zB*_}fpJ2iohSXue(ZPt~mrhRwtu%Nw3;-elWl;4;sLJc(^{lGqU)35)DmdTQzZ0*L z1aTlt2q;~7BPtM60PjVC@(;h}`##y({wMD{A!KP#Z8$Tf!)|{Bf+V?^VtGefm=x@9 zVx+{xPLg?*{MEDdR-faBJCBm70AYfpv~z~1P~nI7{@qy)XJE&G;Us5zT~<|swTP4_ zAy`Z7`%poFsF15sP+WnvgN4}VE)d!PjCgUPK9c<<$rowoR#dWh#jDMwK z&bdA|hM)dPpKstBa;2OkFiQH@PCWDJdylUS6^+u&3*tzW4X{ z7+)|BmC&XpZqxH6-?+Oku0|Q=-M*i61&!R@H|NlHqT}A_S6$FFt=p`#@;{U6-}J5@ z9Al0TKBG4G{ZF(k1kJZf8PLg9F+JN?r?w|Jwmg-)2|)#t15n0Y)#r0*xxQ3=ObHU> z(g!}w)U10xJPU)q{u``IH*fj`le|Q94A%F2Mhx?{yWS~$=a|}#Y`p!nc~Z(q5Pkc$ z90d#IDQm}cL*o^@ZmBDqHW&Tdb#|d0f%yA@pT+8 z!xBMF1!l685Z%9ZAt8X%^7eorrSGj`kLI-~K%oHXH+A{Gd&gs&fAMjc%F|;~(khb*JJN%@b}u7l^msS^(lQj0RV{qjsvnOMl~9sJlwBVl7FWJ zKHn>vHoZ;?lDa{qmAKDkP!cN$bG-!;n#D*K6kK7J{5>3p=V?GqnjA}q#N+WjICQ<6 z1smjeA_Vu%^Ludj2R=V*wy+SL6*i`*%Q!wg2W?wg@0Wu6*QE{97foeul$qdV=*VV} zyFEe=zkdXGv?0MoXYhI7wB|YvJ}>)}-7{>5IH*rj`vNz38@RbvH7u`I=8BT&;41UH zs_W;G-RHQw*_vEky9u0z%%h?aftR3G0y>+@z4cE8aESs`Cwu?)H?q?)&5P|wtDcA| zTSQK&z*R8+Kq#TA`AroR_@W6(^8Hx13Qa#R?xp~kE+-IaTU&CAF?68l0bbp!?PNGp zfRv`p>O@OnX^Ld>po=-PCp*dQIL0;1P~a|_q?a1Tn8Ar zZwTbsC3jQ6FQG$i!jxqiDm(*SYb==tHwO^xC`{q;W#DDvBLzF$?8u$_gc~5KPW%iT zlz9>5XUi@_zNb$#z`YXNabrT-oit;ZJQ$+~9aK`RtsLHaSA7^h@jn!o)04y~ETJ2h zkkY_K8in#KTK3XuLJXa`z34jMm8Yz>qR~jJRv&q4;&WV$7T!NEB&tIXQ5RHVz>w^} zT)$}gopvA5U>+=7=>hw|k`BD@>E^Ojw@V@5;nHVoqD!LTwQR9zhIa0>>umT)AmBn0 z`^JTOjn7`G`kcw_+=$42#cMY`^!BD6Veh>d`Vl`qJ|=dbuq2td?%tB6>s6eZQ4P6X{cw%OiwGBzl(QT-_R}jLHCdXl# zsm!wksGCJ|IB^rDc6&}r&n`|%qdC|e?pQhF5Lr5^%hfh{p+z9-mwt*bi!f>D84qkD5UR!FtWgL{u%*xB6YF00O zA6NQ%2mTBYH4W)(L`BhzjL6DyBms}3ATZloQ%6aJ+kF~ndwHyNiZgOE;&(rvcTl^}RC{2*bJ%alAhlNM{*ovNE zYGiaYnsG^qr7b7czSuDynLTHCYJcCaX!j9}2w}$ezz0`M+V?MmHI-G0xQSUIxfzso zCQpI2i6JIhgH6hU>b7CN_i4JBgPD=m4Gz+)Eqj6^4sG<)2X+`;&{beeUwj z5g?g*Jm<8Qwo;I0r-^ynX_7_RvHW6n9s3NNebIQ#;>wtA1JY9k$#qLKq?Et9uB@RR z0g4-32ZQOgD}smXOB?qp@j*q*@=AH`xre_c-*P|_YUY_1*8>3i$j079Xs)ETzLI)f zbb^61*Kgr8uH<`F*rWv* zg{zBiH3VAz%CUqtkBbQ$OH5M?Svz;hb;_3RQ>PxQkf9_3g{U9>Qvx+G_g6JQIi?GU zpJCH5eV*7Kux=$A&LXF+9Ra|6N6+uM_}nwoIEB}hMkZcr0bMh#!QZR>2p{0b5zN=F z)+)@-cX2?W9%y)bmG3V_P@OHhdGHa))>w<&DYh?9aEAnjHvr3&oIohdzOj*QQfLv_ z|8{HtjjDW??Tk4=_jXZompdo zG8js{TCrc}V+*Y^9^9EaY|znnHD|j{->7y{W2DGO(jc=X9;`rYLbZUpM$Yn`v_)1% zUNH+q_c}K{*P$Owx}iU2LLaNc8vR7*7wNmvJd2wt^-QQ1m|MNZiQ|7_^}>EH64w^9 z&M*CLh`LO4x&uqi-h^iixAx5#7^0=#z*8xAb_~BMA^N+lY|u5%tV_8leQ)fo$U|87 z1?-1E-yVvJ&K8rz@wg0}8|RM)F)7^Ujo@DiK#?B+=2a#Ij7w_=Gf)rHsyT=~5DrVD zJP1c(zLLzC;{aH6g>zy$sn7}u`UOTQ8RFdeU1zE^_cLW^enX9-uE%EF*^waSwG87I zcYu~@X-dMMmkF`eHQT=)pUA!Vepl3kH5}WbKMGuBo z10ODoXJ>$7Ac1BaH0Lk}Ie_zi<%a-*H@>PbAE`Bqv^0XUD&$fBZDML~wn+G0=@0Hi zwZzxdRISRLKym=dn1HiecKfoTptx#Z|MK{1&n(ta!POG0%#p)$$mVS7pXFC#e)GUB zyn^PdOFGhUlvQwFGs^479iBri$Fi#@h<0TC@IPKBpq_x$uHHb~+H!fD6qB~LbH*hB zcaqPxLmr0LCAdWtW0 zi(JxE7lSuVW0xyzi-=b_JA;Ips_q0zL~CZ`?g3AgR9C!`wl+WnY4M3^Bqn0XZoQ?V z%w+%4=<4t&+wZ>G+Q`(@vA$~PB`pZ*#KLOzm7J*PPVGAYP@h?tzRNn@H70-b;JJnDg6p-@E#fuOw{JH{*KW5?)3UY~-Id>=%aQT2 z4M^w^JH2PRSI0*uS0&`-$9h*tnle@|>^)8<8}6tvPGudJtDhOR$Ev32vS#M1n#ArrS_M5XgR|p)RKs zA08su2x(;gp`dr%#wVEhWXXFRyf&3iLIe3Y zSTg1_ocShW?cVp5DkHM~E;mRLKhf=jZ0`=1Y{D?6*K*<5!S72tutB36zoxN{_t8 zc3@!LR={ji@>U)Rk8^FZ!*KPeE~ur&%`308b%+cq7ap!}xNSHaj1yj>Y^&Da>8@>ctP2)dehD$9dcqravn zC)SPxwMBJz>N{)ofGWa<3IFZzcbITy9xjzFMk!r2Ic=8TnS95F3rwt>KR8Dlxlj!K z#cVn^K@-3GXfH7_(bhxrNzL;CtMD%X06MRLc-EqXNofE;!CrY?RL7auy(`Er1q$Y{ z$hR?+$f?C93i>x zi{QLV^5mD4ncMmK)g@_VHzBqnrvolKPHP&JkTDXyvT`1rvqC5u;7L@`U1nxiIH~<3 zWlV28anp^m^rAv!&|&O&RIZbo@N-!g%ptcFqHQw_?OqSlkDnZacqmd*A>W1y&;&+) zdXa(nRkVu)B^E4A7OOCEH~71#VL-{>uWZK{wQA`c`u|!~-mf82WHv!63wr=aISz@o z0E%&O+bHBl_;>cP^q@Uwmdss)70VtACJaoRcSwM{?rn= z#4T|?ntGeU;nrFU#&e}(duZbh{9t4Ge0>ZrC>Y5}{VRbhF79nD-d86@O}z7x5PgN& zmBV%*+U&ja)6>^jIAg7e#7a`1&X2)tbcUm)-0A>BJi1548#N`bDkIKvFF=Fw$6Z1$ zE5aq`>MHkUi}PF$N1<(qR1T|%R|^j*4-dB%E@jzR=Vzr&b=w0v9S1ae53ohC8DBBw zBeho1^D??zN$H%aO*YWhhGs-sd4(!qUy2)N{S z?k{2DYHli5-(_y0VC4!N#!67YCDdM1#oP(*+fu!ys)}_RIXOp9S2d7%a69tccb%(t zhQ~9IQfMw~Y;7fD`cc5kwmk4n1(LdyzL<8jA^zpso;fL+R5@+PGF=lRr=4+e0M*<& z3h8#L#J=!4p2BO|>#Y=&v=kVH*x1w4m=o%`&}|?pA|fUx7E)v`Wo4zdQToGXp1Gol zkparyI?CB8LY9s~W+HdTq`EjJG*Mm7m)`k38lAt=@7K_dQtFxWd+_htO!}J8gRdA$ zYP>FGXQJulF){W(7$M!OG6@MGN0zm~bJ!`0zQ~X=F)?vAr8m}`Dt#Nf+nbP0kqEZ6 z4K`+OdmTK2j1AOK@KT<*XBhVJQyC)Z^!%!!_boQT*1>A!`0p~{WVi73jePyu)u9J6 zsRK#y?QxaFlq9?>Gov1X1XT(X6S=74!!i;1 z{LsQ;B3;q<{&kCr3cFH?CrZ5Bn(sSIbLxvqIO@}5WQ#-MucR6KCs~=wGa47J2j^fZ zdmQP$aNbm)179tsnO9nww2@Ia7L1#d)Aa=H7%kOk^f%Yufx<>)5&2FM+M&^&NouSj zulw{2NX~LlJlr66YMHfj|3>#pnAmEV8oMO+=0xs|AaQ7DFdjw= zc0U&jF|qP@3o=gAJl||M(e~b8&a*RLT0$L~zqG@KAg^piu{F6AWQ zS5B5E@~g#|+qv03`@%b0)ZlxSi)w9!k20R&m95X+Tj8xk>52{rUzsGrZ{gPtM%A2Z zSN3w`(cbAVw<7yYZXf8!#^;?^!|pdt9ViR6_kHe26wb18D=W>S6>ipV5NK0Ciso`$ zGSDVYZG$#oUQ|Zu^Lj(Ks^d0IzsvbG*>LcC(j?&a#=V^z<|xMqg?-cb!0kWUCm+lm)?>CzW4O;a%tJCsz+EbPnhq4daJ24Q7g2K+bLD{zeHTT+Dq6 z;KC%c|8FL^3OlUw5_o2=+d;@Dt=sGFQ+>xgfuy->yYjo1>meS3lZlP<%fowv0|9Ll zl;Y*85>bEcqC79FtV&mMC;qIhb3!Al8Y5WNERGF*oC}xzW?emX;P?3Dgam9G|9i4d zr(7l({lVUK%4R?_2_A?tzrA2>zJZz+E-7;&>k(qwBxQtg868n)DTAEjn-A~*pu5-I zUP(M}s~FlUk%vm-D@V`(I-{QuqlBNf-JZu1I!4l8WF1y&S81frkiA0G7^|zG-*C|Z ztu^G}n;hAaT;+&mW!%G)$Fx^l_nUHK!PNZj8oCc2e_$K*>@W}KA!Ej#d9LO^Mfzwj zr`xuz{;jE~D#rCf<_ZqZw=(xMbg$aSDLpkk3Mhu73m5$h=RBkLo&9$*rlo=3Q@J<2 zw_j$)ncw2z1i$%!xg>{726%7!8w_)+Me~6Mm zfGW8vM`fKZ%-!{jdQ}Djjwq~Lme*i}P&yP~AVn{@KC2q-sYS}kjrJqAAoc++9`26Z zA<;S1%tb%5{EGngTi6kTA^}tTfLt@Z6DB4W>nN?I7fuOf|F^c#o*EiV^qb*pGsPFv z!my@uNOyl22i_ZVV126`N&@q5{8QU!=$CD)92M{fwYJeu!7!)5SL!la zPT9V}3G#{v^PjpNw%#IL$bb<(zmLaMCf_P3iLpS-Na;kt z?>&xh9b}gdGXS>vzCDKJqvTO84oFK=IHOra7m(|@8%0OG4n#HCZ@5mSHgkMt>)&Sn%6)IxLS7Q z=XJWf0*47^_JM6Wx8*yQRotljBvW2-S-Nq|vYqIW5Q-cT>sGn(bj9~&_gGu1!M{Cf zw8CYv7Z^TgX{GmJ7rPK8E#T9^ifWt_;*MlV0^#^@!Kc>H7Tj|Yg}H!$hf<~~y~W=@ zZY$iaNbOeeSop_)(-x$ki#G%H+98;6c|`p2=yebaqzYEvEhySS8p5JuO>+JuJ`NrG zCVA8>lnoJMU8(+z1Du# z1H4B`X(~(;_&=iw_G)OE1yPlDl&+|sC@3N?2Wq$LNR?kvE$SkE#ZY>jmcOu2E+2+iu{-@EOV@s-{p3t0hkRR4hx?n5ZzoFzpw9s~MOWhU5oo{z8wJ1;zerkV2L8;_2?FTp#nqS0xEoMYlG1RP;Qr@Dp6T z6-sK1t=hTV- zVP;{iz$JQgoLO{hJF7z1)vzdaeKGa8ghkTkqxR{(KW?HdQDhux+7>=kdN-DiCoHaZc% zg7f-F;efL)@QeZi0E`%K5(Enq*?*Fpfb#M2apTpD$^+C$j`6^`%h`~cDry9vt%sw5d27TGVA-X`bR_?-zV@8Q{Z=$tzld#`3DLw6y@ zTKs8!uX}W{BAMDqeAcO$BR+0+!LGFR%!@OUBW#7WOKwgZ*{zr z2fVjsX-!dgP>`6Jw2h6ds*OeAJX)Jj4)q9JNoU3z7AGD76B{)X+s3rkG2;|D4XWD# zXi}@$lt(2jJ|EDQnfk&xNar{31qtp69&1s03hHHJaTr=3T$T(=< zDXJ@=A@;Z;cjAD2$6DEzb1=~zZOS~ zS<%VgS;&s0gaWNEj$)Ytr6?=_*X20vr#AJ#P zrcFZNmX585Ju$rDeefv4 z6Bnv*u%|d3>*A^N{#cDqF(%T+07mvV;m=#rq72NeF3N($6|$QqZXzYgib$A6c}?pLhHqJ;As+(rg^4X2q*i^Kf?CL|;TmaU#@U}Ye{&ZJ&I zWSbdWac7BUpdB&xZUk^rwnDEB46qQC;S>sMXzzq!p!=rh&v0-*M7W$TV!g znE3$$Zje(ndvcPJMlhN`Eeq2p{hM6jXoXw;DekczedU52o@S56fbm_ zjAnX9fGe*4Hx6qSHRRekgK8(`vKim~~9D?cUVI;wg=y7ESG~8e z8A!Uj*it!^SbYLw7r&N~^b%J&k-bQ7(A(G)`|yeKQ)F;U!3StGd&8(YKUP0(E-8#(oBUncQ`}KBk(=-d z4Hn{b{{dLQb^dDxLRVM!2^%aC{IHH^`PlNP2hy=~LuUqeGhkoQ!|fTlNQivFm^@z# z88kuCgFKMzn`Krj{a2{*D*2KO5_&S;jS1!BuB#fkRYg}<0yS@EHsg2(;ev|FfXdTd zvZ@r2`H?pj-AG>YG#jZFpHAfJ_f_NOUgZ9T)Y zl;k-9Z~t?RbGtz@p)(p2jC4l_J{oL5Op_TDaB(#@85ldN5QF|VzmLU*mgoN8 z2;3bCgtyOsx?6gd$#6Y$Py{bTwrC>O^!T^dcf!l?@nFP3!OLrtndJ_xow{R#5lYyY ze!$6}QYI2cx9Guj8-um~GngLy>-T>L)6@z|d>5N=dN-tRp!rY~=60c8_ssO?Lvt}u zF@rf&k?>=Z)Mr_Ptk&daU7L#FMXw4vo|0SJ`VPltop0ZIMyObGl_AL+R2_=%kuHrDn)@KnrtB(`#$e3e%h< zB_2+>%^d`05%Tbo)&BzmE^Kda|BU?K1c1~+(kd;G{slCII#yr@32YynA`gKK-{z_Q zN(9fx+oZ9gxtInBezw-OmPPRw&5{j=h_<_z9LN1!+iA@bO^~Jw;n)H?I%cM*sj4n+ zE%LEv8kf4ts*Eyo{`{qTKu5%OT_z}vmV(CijKU6QWwhNrG}PSOoDMYq8JqH(>h7Kz z(ySz6O_|P{3C*%*aSMWQb4!Yf5}KcvCJW)**jQLxT2fb<*H!@rcFHR$2O2FiBSy(a zNKfO8U99LEn$yQM{X3eL`3e8b7BzL_#{D&6ru1zG*oL+*EOW~o+jY>GpBIXXN^*l} z!(=g61-8GJ{~Sh)>Exl@Gs4GWAs3aMqoSuHxK{!@#-i5NWQp>skcFWKV3>QFTT&)~ z5$Mk@k4~&?0ML22fBor0eyiq?^);b~^_^?U@kjRIq1bK^L2fM8S;AN%7ZnMMvu4=% z*}p3)A5?+n%_@%1mF0e?9F>_r5CcSU{=o+9G$KSz)x~lN*fwLtUR_yMTK_5oxXV_) zBJe0J_}R>=&z@)>ghvD6n9xcGJS!*!FuQn7JuD?k=2m4%BYP@u5SxPm#)DrR&+ zc-Vy*y#WyZ)41itXlZG+068gIhe@TByP#nv0xmRtaX*BA&hP^l>2TFa(E2$!n}-IQ zWAJalJ(wZbbLqrV+*NXPqx>g;zO60QGF9R$m#op5asBN2Y%31JxGK%uMz!QCA3MX^ z{xCVIOiTBj#?7Xf_v(misM#|Cww9m!W0xQMwx6!m>h6Wz%zdm8!U|wU_(NBAiW76-yT}F)jzDLNzW;26khc~Y%bi1Iwz{9SPmtL}e z;-%Bv%+l-RQRYc7y(Oc1wN0qnj2`-|N%2Ms!`$0TN44>J5w1GFuDx6Ko)omhWOre% zlOh4o=pXb+Z5uc1%jfsuSy{rkIwo^}a9GN~7{HZenrCa_u-0S;9O^$EK}?rMW=6-w zZKW>>w!ohFWqj8Z~j{AziMP82ERILqnA z+hm;2pfk1#l`MJ!HSN5_ELrKj;?+NEElY~4>N%mm7WQcZ2!1z9{yN$2y;_otVPZrF zY0XcbZ7Q&TFV~Sa5p^tnoJGC5O==R^>!M$R^GcX!zL*~`cJJvhaz>4mW{%Pcs6@o= zH+DiPR`08s{a44UO28}Jm6@g8_W``%JY{xuRsGY2p{YF&MVCi5eLwm@0&_a|x!_~E zr@|mhReh0XPE+F~TIsu@)6)0!G{QgZZ>M8D2>o;5X9pzkl=+`hmWhe!e@a=&g+x0) z;fAFUagw*UH=utV5W@zh2B4#(hm-cAKqt#pHbPIaWa_EQ{abeNh7kj0Z}m+TjbVJ4 z6ph~@*iKX?3fuBm3|)zdsxwlgH!LI@>z!X5Sr}RwSeTq+Y^Yik8nY^e%3m3N}$K799fF%8TkRRRcW%J4C>P zvK2*FFI^RFUwac3)#<^~#_?PvC}*!OG+MMBpM8{jA%z1*qkMYxta%AY$zfNlO)U|Y zy9P1@c#r8W=C77beK>isSPF3|p-L%jX0TQ3e9J@XbtE4)CC~NWkw5Dw50rzs2AZQJkY(>d_60LU>U!>zdeF z+CW0kxLoj4rpAQ>TtB>x3MeKOd{pR-=_xA?Mrx&|zZDa)*+aP?&wGB^8B);w`!_NH z?Ud|S);@s&90x3){u;#-PWate7d)YCi>d@A#01AA)PK_2T3Q&D;cmptx&;@?G;US? zOs%E0Yzqo|)^LCnbpwN_K}S=Gfh&HFF?3OlSXr77Gv9Mw2khWpJmI+^Y5zBZ{C_VN z)G074YZI6bL-GdC4lK%S-!CSL_H(`aP{u|^OK!C=iIVHzq&P6SHN7`KLRLQCpL+>b zT^*DZ!vwM;+wY?D^3((k_}nT16!ddDa;DmSU>ES*@G-es+p;dF>wB3+G`RBfzxV{}4*>A<0{x}#2R^0pQPMMpRx z)yb;8d1Ghq#JKUreaNjzAw#8uY;eBJl<02T1iQL}pDqV4XI;)~3@tTol?^k~t2)Ds z7O!->pv7f@>Ip5nyhSKDs%%mgHQ{O;A9n_59pz5~P6!Flwgk?kTG{o?ssQS%OssRu z=L8<7DRFX=mSVCEtt&Y!7q_HI!-L-ZPW6v8Y6Tgip)rl3q#&qPs&#Sj=XLZFqh>>)LilhryE)vA1`efx;=&S_+3m{}6%f0|Vzw6>1w{)lLd zK5Y}S@xC+~h);Ak6(ccpp6w}{b&NW)?Xh!Ug9JyO`u;T3@I`MA`a`z{g5W3uIhniZokVulW zj7Cr>TZli`H}F)R?r^iPD#rxISM?9E&U3=66*G+4IVwi3-yu{)pKd8c$en;Z zKCyY^@R;u%XD+{l&Qx)tXUkp#(8Jk!75nFgg>;u1N^QdSfFTVBmcBs#L3;x$+`ywX| zjg_O~sKFVVAAC!;M;Y<=7)Xt`t|#s#oM~T8tJKD>?C@d_DT!|}^2d>9Ey(S(2p!T*CHnZj%z|+JC9yUv_v~`b^(w1+ebv#` zrPZ^kWg0WcA^-{wN-_}I(b4ffuo;R9006Q^NcMRXK>TS9?p5UE$WTfBe)Jc6PjhpZ zRiCwNyLXho%K@BKqzp7v1q?*C7ico1a8E2Jgrtj(je+77rd1qHm)s7F3#lyQX+*{3!CLS?(sje6jjESV@Cu6kRUsJoz>Qj6c*<`guS&`Wb9gDEn^dOxg04d}FxQ2sV#Y$=GD?Uh2od8d zPqyDQA9j{*?yP^?32N$WeaE!Yc{ z+~SU(a$=h+YZ_)zkAS+kq?U0SaY^0l)(S%rg9gfoVtzm4#ce@@vG98?#;%W6f_NP? z%%Uo=d4Kh==9Pzw#=9j%ZYg0-;+Z+Cb_)|xlkC&bs>VY9Xuruo zS>`FZ(~BB~Aj~r-4>17?O-XC6WD3q24qIo`BAOVqwb+?wU(06G**7v{V+_`2**J}j zK{yffap>-ri_xiT_y2^Cbe~*y>TKyvSn|?(dVD})IUCz@@ubOMAK8gqfjlugySk8& zp`#+q`!PYd_F~kMc{HWT$8~5irpM$@Kz^!ypZy05bzc&d%@gx7hyKMgD}m*kJR&)Q zkB3R%Q_%U#xa$11yPOvq^Al>uZI0`#P_Zk6%EA7V()YfULL}CA2OLGrJC$D?hX*z) z({0^8tkSsm_r9!ZRrhLdw@{`@whQ)m0Fy*ldeWQ}msOD0Ds0W78*y`x4VFLJs_{n+ zAxYF#n}27Ttx{Su!o?osT!yM4pIANF(_t-lhpPbc%6AhnSM-*&d4V~U><5C7(`6g3 zk|-}W4N>{PBe@k!F3>T`&SRfsW?L&kGPdN0L2lJQ2_4D16+++0^msYr-<|7RTKzoRrZ$ow<1Q?nf5CF`(WNaPf zcx10alJIH$4!PO7AufsOd_BtWdFjVzB~9WUU88LnETC}?sr#MvvZ*0o;t(N&-$ZIqt*t#U9u`or#DolTG(nZkr#0-h?AGdg-#)nCJDNlFg_^nemm4iL|fuBJLS5CK9eJ7JA zFLit?QJ*A{23q4|HDq5yu!`OAS2d>Mlu6gRN=b>@eY<n zQFW_*G1sK|&N!bK^|n5FLmkQj*S7?|V(tqCKPUfb2Ae~#ASxrrO17M9JadWJD7(l{ zy+(hpCff>J`1B?J;KV?hH=`H&UXi{7s)2zk=%h5Rp@Z*5QFbUVHPky?+I+;R)%8FR zzncnE(XRjqq7*^7o#?U5sxdG!GBeh*&dfE`0c0%67}Ylf^bb?;NNgYLj zwuC3w{wYWZ3)-;4esJ{cWW{o_pbT6nqU z3Ds@o=%MK|=!GVHXwh_*@xh#?YGsn^V48;L>G)~8^=#%ushpj zvOT&RvfYYo4c@j6IqWGxJ|wZ( z1khvTAL^226*;wZZ4WjLgXhx)H_HREw=@tlM934$lo|cR|Lup7phOYIasowH0(r4F zuH1fnXe=SrG}5F<9fn<1xW5|r(r@=)Oz3GLpe(QZ@L*RkG>Rexh~q-_`H1`k4gD>V zsFEI(-Z|hwgL?lG!-?6eD^tOw4(&_)qDlzr)Je}eWTZ4g*@KD`E}*Tl41$kOHD;m! z#|nT*#7yb`I~U4~9zSg`i|ND|HE0k^$!sB)nL~R+)gAPw|K#VAnj-*~;_7%AgabZn z5(SM|8y)pRvY5sZ3?~$g~(pwlWpVPd9W|O#Z zRN=h1X&$7kxuh)a%9tc=XvfMeCQY|}C&{MnWMytp*xyUM6%;Vineu7!Z@S~C? zQ~MjfnsXDo8DWYhL6Q(DRx>x*Tv)WDr8z&K$=1FmSM=N|YLHc;AfEEWTZF*(@*j~y zCkBKaCOAfa7JDW33lt)ucm&k?$$v-@0?MQ&!igbJ3H0I0!B5il`LxbY;>YLxSfO{h z+Hia@nvmmpH%b=b{Jn`f$7^l0MsJ-OGLkrv=c8o+kmP65?9>|+b|Fc}rx_D;Od z<``F*K`BF10{=l5Q^Syd?wYhE z?I)8h{8qP~j!gWm&~|;8IO%m=&Z_?RiQFHXwzN$?Y^SUnxr#cy&nJ_D&%$K&Xm zHsrfXGe?P=>wO7Q46c#^;pcs|1g;zBT~)le>Lr1=3SK|m(W63?R*m4*D=)471wJZf zUcv<+QCsm?*$FP1Qx(HuadR)cOiy0hskP?z)bXm$z-@V~U;6p$v#_i~sx5;wl1bT3DFi&ffcx?#iCpyc`&3KrVIk(JX`tdE3<$}gg%WZr6<((WrP z3!1XsQ*1O045JFq#oomecVgpmnv-1rqOKIR(vXbq)3yKsQl(!+XXK{A%(2#8=ar_C z&W5%Uc`17#K3{7TfO?NV^lP(1$MHh;S;KJ!&3I4cSd#y!J7V{iMyr2pCZrS_kXo1{G!`oZ23rmKtU5 z>R45C)M5KKn8vBPXA$(Ky~Q;;pc=9g*s9(J7UHYKfViewXRwUjvBs#>_|yE9;~heT zG%)xDbKM+wUTV}Kfv0}V!Btr_^)$ODXUX9wOn8{wO})$fB3Dhyvczvnz575SMao)4 zHu-wamTo{jkdbSfg5L86V~@xBWTJ=bLOsFE?X$MAP*I4VR@pi5c|Ol8p@NX#z_srI zRetZlkFb}I>KT>fOvJjcBB(7KS+e0Ht3{W?0kcg!r;PH~TBWg)-Y;1B(8=i(2Lcj% zWGyUsvpzRtM8DDrsF0kR8dkiTr(eKT!s4|1)vIo0K<{`ft$kVO;%+*hZiLqyeG2TAD6c8#}hYSKByDUy~li-rjD5>~Qp zyhU%%FfqZ1shyA^iPDV@g= z8~dnh?-fZzZ2J4CLfh;9j^!`*3M4QM-e%*ywd)QNzb>JqfXO+U9%# zrmw&#N@O$VqQ>kxNP0Nf=*fS~oL$W3)bsIV1_v!J|^ZjePdzN)2Ud<8` z>Hsc*dTREpHisd~0>5(7JrSEi4yC=xzd>}JV19&{<*`@Pwa8n znly74o?S2C)jNdNbpi3e4gyFLN8jlppvAK)P|Gh4WD{pTrvxdAfB6oi1qsE=_2b6? z`+TBAJV$SHi;Qz0f~zF`%0J1RTL5l2DFNqpfz9AvIx129CJ;#l++?k-vd!pgt?b%P zlD`jU*)J@nmGG|K{ABzkO2{)nA2)eq-BjtL$UswGklsIiSRN}$5ocWk-%9Psi+U_g z5%;n79!Mu9W%{+qITlW5PwvH>yDEi1yTjFRWs9J*)GRER$jFn^DK zDvn5R_pM%GAU&HgBrYNX3OmF_3xnTh6l{}nAfe=0aeeKtv*g-Qc=`OA<-#W5= z)bl-aUuB68l4n&uji?m+)7tz-(WemGzk@iV|4Mv@`)~Q*Uy6T5_h(!SU}TdGdhM5~ zeX*gonC>dh`DuQ-3o)XcU)~xl6u5hX|2Ii)P^QnAUW-)l8+GghPff$y3cK zyUO_eR*Ep5GnlNU7Hi&N(!o2092?5hlB0qsNwVs;zH!%N{A1y>Qk@T^PJ%IcY)NDMOi&Gmr<>E}=*s;o>mPFu$Wczqb89?tLBqRmMxJeg~PhHT}QcOBo|zUup;}H{AQu z9n_t6c30kXws#`p#Bd1VQo@PRv^Z5=FOG>5VGXLkT`cn33Zdpokj{N_7sF$cte%3evoV^JptkU6N)>nOMMfTj8|vaMqU;;h5{v6xy<;H1MGZ}_D`B#q9v! zLREDbAhQLZ%+k$nhMl}%QcFhfh)*pNQHz9@g+yN8dF7USX93G*ffXL{=+GlWBX!`= zIdWhA9Xo{Xmw99EX|+9M%N%Pe(?0R5eIB}rxQ2&^S`S6WO}K!Cm{Ri3p{;RpiUzkr z8l$f2x^kIt68n8zXLA<~>)b(silM=b9PO zXYT{G8GPoHKL$bvKGb~Xn=NM}UD+LS=e)f7HHQO#_K%Fto6i%X0TI{SxZX68N9eH6 zDu~9QvX+YfT=uuer(6$M=l7k>Zlx!VVfP%vM5 zSt++e?u359W=uQGjW9)XZ!yI4V7?b2AK+2@$AQMI64nv|FiD9I_P_tj_Cp?o0cWX8 zM>i~8(>^1R?*(iV4Yv$oZS=B)tukZ$X!qTsnqyUu$MJ35ivr`9lU0FZgy^Wh0V)bq zkJ~j9iQ~1O*S0uyYHJYM!t-A0Nw);zkOO(N=lkYtfJYJ<&H0!IB{Noa3-_Yp?!Z>S zd(ZmwW!!lBP-;Fex2-*d+~ZjYh9 zh{iJThr5Vis()$4OE#vR297IM@2)}wC=cxwMGFxE88)@xLvzqdPX8!RPOY$tXg8L( zL^g>4PRZkWyS1oHK>CeovUIQND?aybma+zyNKw4qCp%Hr_+bp+V~o9GGAw?UsG0-O zf-0F?4*P)~iwN@Pn@7V$Jv%(8OCC= zwKKDdYz%*x!A{IHC@9|-9BiiOoG>`ebzXaFV#+cwQ+;t>E7TT~5c-L+pj)mc>1m`N z)JXKDCnu!gCl+ExD}qJPrDuDNHwoE}gV#D%eDBINHL=tZ_s&X=UAJrg7$0FJsBt?8 z?ev3s{n?zAzT2@>WT35VYlC=G7I276o)TdqCT@tRcZmLi!7T_(OB*8~=aMoqWnvOy z(RdBG?s5D>KtaY$HiWhrO5o%A9Fo)hx~S5$XE3!HJ~JPW(ar9yDiw>V#K1_TYk5#P z`Jc9;1*KbNAK1~7T-(~KvmuJbCBh?n9t&pVI~hT|xVM3VCZI~bEv3b_SNxlt6c{25 z8Y#GifW}>4i{G`V@UYn?+~N-+yhv9AA{#LK;duEOhkybCpk+8KQTs7gN*g35)hInAvNiayAu zHj!O|42FD5p`$2m)f#r%D;1i|YkyjU#j-ei({yi#g;Yc1R*dhovSxkpY;UR}qZvHC zP|+dP@zRm%g7cU*zhn}>%0pxe#&YL6`<;FY%q2TnT`hG_QbTZB9(wK2X|=+oL;^B9djQ-!I1K{0{nE#{k(ul3?Tp3n}ZV6XgmqljtF?8eW|)P&zOPsA_cSY2Z0d)#*-H`7VSU6We_u!3XZLI&p%(A4`nom_i ze?7-7KIClD3YA7tN?CDoes)fMT29FhL7KSGqMGDUwzhJL`TP7l1M`gC9Xq%gUJ0XQ zWou|gp>`p7iKqmX_q{eb(4O{onTr~cRTwKFNLOUpC={;SJ<%OvF4yWzRRkrgpD^-jGgX8F8U zZU{(P_03|ce2w`&8XJNeuotraA!n}r=RUGhhgH;N^*f2<;8XswqB0or>Ca^66{}O;)7ewa6)L&Rqs0Y?^+mn&x`@IJn-Lw}>?n%Q1f;BsP=X2;~jA~y#4jW6;*5br3;A#^>w#4yI+quYyR4Axc`xKsqn8m zeVF%SaJ&co0@U@pqKnZ+BK!SkmCwc@d62+BvQ_;X_JUaxHp&sQ&hN$HI5#$6Sb76YD*0H&QHi;m4~SFdoa+ z`yRWy186X$xBV8!eLr=TSc}buuvf{C&5){dKh50B-q<%-l!?2uu#oGL}nYy)Sv+U-N<)* zM>bLNp37YQnb?3aEd&vFt-&-VJ3HH@>eV>FaxjgKOAaM(KJmGG0_>{;ZDKHrmjtvSpv2RPY|&o*ONM|ATHLv$QCjF-Ao( z${7fW{)`Z3n;#@^#shP@MO6=(RM3#?{x9)uaGCGpsIhW_RKr)sOm^_0%Y$vmGK-lT zwVZ0LJiP%z(Y*fO2KmUaHiccgke>r5?i#H)-GnThr}N7LkHYftI&6@yKr5eF_u z^^saCS9H6dWKluM*1O5Jh8;ht#_CKa9%xh!`B82-lpFhlbg**+w-QV1~ssO9xTc_t+>J8*ME%U(42YctBB?&=>`fNI~P&6fqTM_IvpLx09!3@YwsB z?s9zj`ue=T(=!DY*)j_>ISqRK1*CkA!C`L8I$>dypuyzcct4GkwQRWVo(Nn`D+qMW zi#C-h(a?mt$@T30*ikAKYz$>5fwiZ{42&h-#GjOv^PMEsMJbRJI}3oyg-XZ*1%{zi zEcVO{M%9a7nVP2<*GT5+$p|B-_X;foAJ5YEfU*W@t5$VO-0v;kZEqnLCyruc4-Z#BPS&qyOxur<0$qPW+myN+nMm{k`>W&+6t8IE8FD~649-#&@qhP<=m_y=e4I&Ja^0=6-AUcb*wj$7oIW;f9Modba1 z(0?7D&5zB^&HtLdj!u+xqBwDN8khZpDy^3POu~A;5AVjWF=JbnFQF?(fRQ@^eJXQVO~2 z^-cG<)W-VuKD)?-trm|;BFmw6#z`G8FXsl68HZ=B4{gv7`ayWu`2A6P35loCeKVAs zogPx?*64rSE$_cFm2-JKH2+=>7tACLL{Ry7j8udR4x!G!tEGJBV?6h9O`JJ*={ zE=z|(OZj+H{z3MTDa>hjU?L%0Jrd%@YJnA!t~O<=GK{wQaEB7lWuid$z^6O1@nF~y|8YRECq`CO13701O}>9aFQ zMn*|0o56TtI5{<=K~gtZ$B2YIeiZi6eFxVUq82#x=43jwaZ8zDl#Y1m6ttslJb5K? z2#w6!U}ZU#Ldaa$c+n>}olh?avnz@$_H^@dV)8oEX$^C8FjG@G+A3E+HOy+z90aGsuuZEuBvVgUnY1i4&%fDeP(K$HaY%WG>_MRWj}#YFK(lhcbpp z)xsf6B3g9qTcDQ%=>llieyj!T`eMBa>!uE-sp&u4Z7GD*=n|(x2rLOn;u1BDDJB-j z%#ddJKyrjl6elYmwZN{~y8aRSsqC&w6SpynvMRVbO01}&w`P&lY|bITS!H_Fp<Rnh1M@)9|76Hg2Xd^u=iLr)88<#(2MnL7PFIDPy6yvxzkdxWFIT+cp!p+}Ny zdE4oeB?fwk8Li5w%M#RBh#=evvX9u<*BrepUP0?h1@K#o8dcXN$b2c%x;FQJZxi9vBoGW zyxe`7t<%}rWzcrD3>a1{3=A#y(50zqCi|je5paDGYaDQ)yNeq`a?fl715K#MzTBGX z`cd#HaM6*PM_>zcMvhh*Ua!zFn?JOzqGb^H;lg*Y4wRW)_NUYxtzylJ)l4k8bUWAP z(z*Bl|1<;eAAbemL!503)b=z4MjXK@@N%;SLZGq`AJk_Co6|Sql~FuF)Rve=|1zXz zPCgwRPte#VPa4&#TU}M2sG|$efrGAw{jd4p7yZ%GO9=kI(e*T}U^YGAYQvyTJ=fIV zd;AA(@aTqTeOXyqdHI=rp`y3BwV0aqKE8z z{fr48V|qZn;+nUkw3wRQ{vpE0>uxjToxbdx@`_LY^vrm7*Wq-mZL{O~YTHXfhqREn zg|p_*lEt+t2CdU!p)B6&=irtQ3Ks0vazGN__G69D$LD%Qd9^~7bM|nwJLJk3H8y5W zJuT5qt2SQV$Wv!Wgq9J;86G(3>urN0kU6=8uxg&G2;)^kcEXwgrotyjm1Myaebs<4 zdHLJe!S#SwyQtwnA!cBKpB}8N=KDFOrssaE1pLwaH~jBsOG*f5DceH3tsVI6{zI9hl;L)|_b2ri<+9cyimkcjn@(rS zFl7s`tv@4Vb=IdHgwWu3hNk~>@|@ zW?@>Fh6KM`-chHiP52bk z#Vly4ttzQyCUtl;rqUH*ULq?fB$_@h8sj(2+jjbj>9EdlfQuLTzpDS^FDP&xatO>8 z2bv1vdp*RRVA%oXS2aDi?wY!5fcI`LrxPS?u&baWOsS$%^RqN214_znU|RUvTKD5) zcZuw4u`(i21BoJ3$+_2bu7szaWq8&{OU=jWb4};nX&5TrYTABjkw~f1z#Dsml5N-f z5jF6_G@xgml^TzTk$pd{*q!|Ab&T5f>r@Wv@KA+>H0z(=zg^iZn2MZY#bGAmfA%s= zAv5&T!`KZx2XdZoW7Iw0^VHj86-A9pPm8LsZ~>sM%$VwYSxIJZn_)gzZ&#)E4qY{c z|BhF~jvm+-*`nQ4RiMdqvWcQg(msXw7(1F`a)N;fsOofK?c;k+9EAk?34hqV1 zk&rQt_xBAcRtN@06!^T1o}QjdPjA=Qp&%f7vx9lFPrD|9f>=sukWjPhlu-(Oz~K){ zAkCzxDYR=RtTD3ce*)u};DPtu?(^-frk3&>@qCM}23WqpR|f`2sHnTuYSG;@qeUviE5 zQ0n3DZ@hYgjOPg9jC8HTE&S>rK6;W3+5}JnphZNo02JauCc#p~(%W%&wmO!3w#ZkG zV~#p#vfi#QxMiuTOB)+i?M}--P=gBbkg|iaomg1JB1RHnjM|Gtu4+TdB`4@g3lW_Q zWQl*=_7@y+u4vD4Re5xo?uNX>0XTG!4Mf|^sdhycg19~?86+krt(OJp7;TGJK#Nd- zvr!l~fvaFq`6qA+C{Sf)HPHw;A*koE;y+a(o#g zBq~kEk7Bl>oVdr4V(9*;p3KzVNSj8+jqH)ndPOIcQ%eEfw)Bt3g6&QZjxK+@@J`cqMk& zVQ(+R?;4m{{XIcGK#q;qkNN{%#?(R--cTI425AN>1Sz8n z?r&?JEuYNDQ!4d&UElJ)iO|R6cKQ;~>#Lm^0(1*x+xBhr_xGRd^gW|(buTZ#XO?Ow5SsSqSwJ?w^Nhh!2LzrSbpwb^d`Y>@cPh5vhguJ*ie z*J6>4O=H*N{vhS^i8&kSGC0TJb5o!4c{gYCs1ezk+x>YGE7x@sQlR6QEvP?Eg5y(7 zIP!cLHd_0G?+vX_L`_vD#vrkxeK+{;e^B5r1e|8&{P?gW#a>s9F^osodHg#(}!Oke4eE)Axb_@Bx z4ZTXmzaJ3a`}%)i9a>iuJn#vS9N0(<>`6ImwEfXV#ncT9izLKHB*y(5M4 zd-4u~D_p%wqg}t;I=vu=2Mh`h#lJ$R>qYfz^|sXCFEFd$aZXC%o0eK&$Mk0%V>UXM9|YK78wMk97_ zDyATB7v0kGvBS95BOD1w+VGF;owYLx&lgs9A5`PAV$Ml9)kXTs7E`H(Fm!v2KI0iX z@-Rh{m+!0#i`8xJ5X%UWv1%&FV95VzvrF(fa`v4d4EkH&0iuC%-^t*iZhN5#TiV(# zx4QKKGM1|9y=(VtWreWC9Ko_&Q zz$d1ddJx{q+UCxjbet4v7;>mmMcrZlGQEy3HMVPo|6>$a|FPra^R3V}Hu|7;v_p>Y zD;;6+$cs5aCie!O^Ci#n({7z)F9PLVZeJc6q2}WYHnVh%IqAw?RN;+!w8qMbq-J3V zMl|tjMF~;%$L+p_fUEF~7L@PUFrlkp$-U;7E z7S6#(|5BXeYijYt)2wnqx1@q0Xs2Er>c5jw;EHL!>+$2~RVK8%`9$lS!{JFuOSgz* zcWU*}qCu6{kf)w>n%vjYQ-KL%{7Nu$Cl_5p zn&(L*gFfu(iHkGbRQCjX7>9&geoJE15FheI_6Ev>|8my7=Rphow*}%Yd+ox4%q7Nm za(N#7{1vQ_2zx^oRyog9^MdyH^nh{2(O7Okl4;Qvq04Q;<>LFC#Hh6&fyEZy$HQI> zqSScH@S>gBL@k=Dr@FPZIr@RCfZI_NkR^`l#%FAlw@%a2drI`u83RdEJIVclu|F_P z&MIbhSsO!jLV%%h6af6JG4@$J=e^^Pi^cxCosLiy9&^;l+syz1FytocspG0IM4ZcS zQ<5zy2BV@x^=g7vCsXz8T%R{7*|>4@aRaAEFP=Ncm2QJ(;t5M-<&^8O)*hX^VM^|{Z}GYvxOR%$0(T7 ztxQRF!({bex{e*DyACr@GjHcnrKb={pk1Z@tv*KEJ@nZi3k#E}-ZmJbQjZC$* z;lR!@dv3nJ5)gKW=FBK)JCXWNbX9M?KHW2*q2EGrx>5_v)2yBjV<=!AUTu*zzd){8 z9Jh&zvwlgILDmMgn0-5x@$tm|+Enh58n{1x=HyejT3s<2Qw7|CA_UcIQQvq(bm(N# zuan8#n!T-4JLlB#4hgHu$^lYuK;PxqYEzR{CnX8B;0V94w004Tan_JN$fANNf^{15 zVyGEK<%kgreB3ljDoN+IJZw$b9G7C;7Pr5JD3BaTB&COGp{2raT5%A#ZXL6K1ru_v zR|4)XH2!|Bdgolck^Rhadl^Qx(hhi;`Vay>sc-lQ%ghv0ZcDl$TazGR@qB( zcC;0@wDI4Zh2Dxoyba-;;)lr4mX<7UZ~lzl&l>@iH-glq=8$YI&J_SvY;oo%RsM(u_T(QsVRpO2O3e7r}wvz>~_SK z<%I=b?QH;bTS&LmqbfO8=i(Pad))1>>Zt9wmXW_f_VF`WD9iYoPe!O&NE zb`Edt3!aX$+IAR=kS;EL%4@%fgP+*X*x=s>yJ(5y>dd(qT2Bzq>6oDl2O(j8eQp8W zT8D~mc{Xp?NG&&&!5xmAyU-=_U-hX63)tA$U!*!pQ*>D=m2@KAhm^wn`+vwuc~B&( z%E7hY(7N7f)g*+Rt|^(jxZL45sIyOC?cc1_;~}Js9{`g3+b;p+NJ7edvL`e&^;@4W zLdDzRpngsox1i{@9o#Cfry<>f&(G67P)~cq&~ndgJIr@vbi$R)9)iSBKPq~*WyfnG z;feGipuxtds2V&9X*E-7S!F~M{q#GD!tgK`dWl*>gimx2R0Fab+uIA|H!4D>JHZc} z<=Ue!*PVOIdFxFYYjTwAoKsOH_|!yEM4{DHlaJkHm`hB;{o%3Fp(JDShk4IVc^7B) z!pADoPX8LT_uHNh$Dlkh;PwtC!3p!ieSoOW@c#WE6!6exE`etwhy5&#PZ#oFfLxB? z%B5&LOJo|VRxxWO@tou|gtAAw+nJsabdO(Vl6*`r<%gBu7VxmL)4@b!3$T2z=M{a9 zEDUOKD=Q=ZAlw)^lHEclinaa;WGQa&?mMFNtVhujMtNP%SAgcSQBhIO<4)?w1u2AG zzf$crc$C)r`h>N#JOKW!7Sh>qVQw7zh(37qa!MwKSy5S8wJDksr+b96ZDZGt42Q%s zzK`^`1m+%%)P6QLvb8b`vr_JmCk&@Y6q}qN1*~@}&8}02wL+0U?XJj+h4#;r@((&H zsvTvpc471-y<6?BhIO+d!=znx6|Fz(Eqmy$?FMH{s~#TcINTpGR1f)-es%Ejw6_iH4S#hz@TZ z>69dwJ)43oRXAUa_^FO!M6IK!z*$^oXoQ@uy5zSvS!cd~*#aVg>MnKw2U{i;PVtid zFgn=j{7l@dF5r2a6!VzbO$Pp;q%hN9cTa^w;tE+AFE!o+o9!}D=e~a_%0n|5!5t1O z&aO^Bl2zZOw!|~IeUr+P*p-K*+`Oyh{dd;RomZzYBe^|8-wsZ;=BrKwl*3<=ikNaT z7xovk%Db}amGwovB7>FckIm`ghOMc`7)m#*QN!jjL?V zQT;8>SeWNBKssRW+5R!n>LqFFNL^VbYhI zdklSBTnyJRiB*5L!dT{$GVBkLiZvYtvc->ATUY1jX#GDn)(?_q(Bi)1;p1;`x}Pmo z0)nM8GYYFXtIa32K0UA7wu#-HIMnyYy;yEHHA-eKOD^g1hzmOxMR&St980cvUH zCPls-eGl86DnVzf8mK>gec-T7)T<{wg*D#ndL@^aTUy6`W|@gCMi^O9K2O)ZUk}}M zlk4-MA_R)!$SLcGb}e1G`pLzH+8=Sgi5@LAs}G5JVqI<8X3y}hCKz90?3ZUpNsN1K zonE1AGoXIm#}nX6!%0cBO5qHq07bNsy+?n>B6wG#s;W*Qak9KAjgPOjtce*~K8o7) zDi6=IUMk zH4S=Xi9cU3+n~TA;ocf3hjbD&g=VY@U0>2rdIjiTiAg2Z6HqX+o0_-GnniWzPg04b zn6RI1_757{gZ5$C)j|&NxKafq(I3eJe5C!aum>6cS7Jql+IkP<)Oz3D9hjQ2abYKy zprnFc&C$>wvRiJH3Yo97__DfSr0J{8m!OM6ShUf@Ioim-nbPRMg%djbl4T<6iKKCr zc{xWkTBg(clH9bg&S07>EYGmD-IBM9G!g;^-MRc)C(j`Vt}PCWiajhuNYihCdmS|P zVByhX;9)mTK!?&=dATV%-{dGzA)of|@y+^^taxZ2AlzQUFNb_X4}FS6iynYDM5w{U zSh^FIdAgA%9~y9zuvZckRPgnkdAd7CK*{_H-CO}`?a@(8L`4e`rlw-zzL>LJxekCZ zg+!fvWeq}=H5~M&pIHCeAXEKL!8=4lF+)YdS5#OG{w2@?ks(T0J&rIOXtJ~jGt?1~ zngCTk$D+(KUk)W%f3B${p=vIzd^9jO&Ub2Hsw_=4a*z@%IFJnNCqV>WerzC(zw@h!g z$G`8*{tTSAx5XNS*=bbq@9~Fi7ZXzCr0`HBH17H9HG>aVooy!~LGvjK#NXdQ^5jH9 zpaK_6a}q#K$l$p%E)UaCaIW+(EiG@d<^EtKos#ZXkXD@SSt2Pafgd&mV%SgRTW5KB zN3p?jb#!ZMbo_+fs-xw_1JCC~fX!i|{OTDrTG(e1-b9S-od2Fc#4$g~#mn<&)!%k) zhM%f5Aw8}<-PhK@z#sYkF_mX-ah_%Z`ICoSio{3C92vgAkL@0Fj`8m6n`H!avs;?O<2l(s&~#?2#) z%~B*8yz?hstCQNVk>R8y!R(1re5}IS@m-z7p(s5H(gLLx2?+%vMAL!5M+)3a2Qr6( zyq*4UW-G`_F!|5-SD#l~*&j#s3?L~7Roq7^-1r}_=9Z5YMSfFNzapQjHaw8sm!&K% z;rfK}zPemFk6h6_&d)YBz=oa-*r$qG1qBVDLwjLPiz+S#g)_o@w$+XqG)fPpAKI)o zHZB%6nwz9drKW511Vg7@yk|rzifeOZP2rAEJ#t{6E%8{FTB9q6@A)8Vq?A}3*xFoO z9=P0y1kGfnG5wV6sBHfjyyo6X%%E8yNar2<{P;|*4OWx`tr5-WrO-*9xv7)9&`Fp2 zb;84j5weO09&KqHv|u*b7ct?mI#HVSq5$q?jVg9E_XD=dwoNLbbp_^xp9$;N7S<@d^@A9$A{YMF|A6NB`!-4Wi z8i8H30|^9Vam5|&crDs|_|N?oVebTuGmSJqP#;hM$Q z;YXCeRt%l_;!*?{C+}HR1_PmjTxexkYwBPv)3qE4sB%@bZr)5TB#V)b4P|Aqf;LPi zc$FDe0jyo(Q}j8b!&a*DIzwPER{4TF1kuhi9tn%WQjE-{6Sin z)=xHrSv@Une`!O55H-L0jok52>Da(fcWg~Bm$uV)&(6(|ylRd;IGG+>*@)8#hQtKe zjk5{}AVx;)z_nC*IH#!fU$B|D{_YNA%cOk@{G!*0u)N6S*kL8)aWHqh)&5Gwud|Gp-tFVf1 zd41`o;%E-{9|hyYu;#8hP^C2i#uf2#dM0WrmsPZNFpgx*heyN)SH{@dYXoX5iuh3$ zG5(a#x5kDrXQ|@ji7npE{q57eJf)L{zlFEK(L#P7UHlJif2H`BY(VSEHTCPTFHlSv)w))LlS@U>4GEop|Vsp?;YA@)a=@GPvKbZI(%<~@ZzBU`%7a`mw8M|W_Eufn1 z-$USq6LGXgtf*T(EG`dEOO~vHN%WCaFU!wJ+MSYxuG9eOy%^tT9#)6hZqrxQBZ^9! zucaI3ynO355!xTs%v%D*(BofV>1b!*u-zgJD2PW8j)obMvVPxZ_gc{;K-Tnr*yXFt$_qJV?1=$%d!nKFk6dgB3~@J?7jwM~TT$mz_^vuYwL zV-rWIbJjh5`I@ftX@lfSfa4%t@y07>;w{r%3n7YNss-CU0&@VD9jny7;zu-#A{?%L zjI(7K<-|hI_kftV1apn~g-XvyjBD_q+TLSv{^Z^hu6OC|CwY$IZ#-Y>{NbRXp0;)b zT38|`nI0R2*>Sj@L)dZ?Ag!z{e%Q3N-gxZq+CNL?nn!J~^nr@L@U_(YPQn~yVAR5| zexXbv_{yB(YU=E6>9|}lqFrkp#L23X9R(93Wu2P3vY(J(x{VG2rkM?dw*jLHloCT@ zV^uXZwKc5*QzJAqG=EN5sR+Sr8>*-k4pom(&0Dt0^R3L$Z1GmfCkZkw_rcZIZ@O@m z6i+B=KPqsEIc}B$xeH(LD$iV7Vitn7rgx;q!Qkb5Eb-Pkqz^HVWMmp3pqu}+4Qg_& z?wJ{;*8Z(B{8X95J^JHb!#I}xglpE&3Mo~0f$Ydr+;_>d&%@&Ge&IUuJ+(MQs$cel z_+YDTr_Z_vMo%@Xyl?dJ;ZuaV2wii}l?Nm!=U{E40y+X#DAL)969|03=Bh z_0Y%sd~^~TEn-<=)W0z{JIc%M+Lm8Enn9!Csu@2%`|v5W2j(Ysk5CAei!*&P8A&%RHuH z@8})M#m%3W8b57|{R53?E3-*COJ#j$^_zSmuQkS3)oXH2>b62+b25m>@_V%E3zTLQ z*~E{nZ^?xXia&_1wlt0%+J9o~#51{R*T5Kiw6Ko8=|f>ZX|DA<7tFn7LP~Y%+x^th zakJUo#c77Cs3Mb|=dm*Vd|_o-Io0I(*?t0=WNPgc)6cTAVNkEg8RYVE z^o(pmTx{&KeO0i$<~a6)8MhTnJ-OOA^GeR%BGqlFId(%>F!z^#35LK>&JJI|0SET? zv7$AVIN}s}?KJ2a8LL3wHn;?#*dz*3O7Ig#(Ox=8sA>i!D3cVRBpnrHX{VJuoDp9y z-zE6$g_c`X^>y}|1itZomws7^W6)1<(0ANnH;P&p^$C-&97ie*tgz3ps;&Y$|Dl|t zrfV*R50Yw~gaid;JVo#RR-i%DU!I}B_+-Oo1kRY1@{f9I>T0UcEkhV;2*@MWaZOqe zrOt+&KQrv2*17H!zHFBmYObYN%Xop^(zN@_{r+-lk#%^)0!7&hWsAL!kyrgrbXG%J zFbCD&7S@k?&sEynn`$8V(?U_5r;eT>;7?LU5*juh9&U-*Siu)0_9N|%Ha%@Eqz{#SZpNNAOoCp=9y=Kq) z!P8jv5KdNLXQVT5pB_v_ft{FneoCv&YqQ#OO%@=Vm1_1qDjGx^McGknEhM?qKYtqj z5yLNl*xOfk&SAZFB(JHQHX*o8>(s#kHX@w4uTScf2UlC$;prX@PL8fDJ5^InU`;{Y zSeJ=0C{nJk2{`w#!|%B{Q8?F76xDgU1-G=l>=_NINMGKE_kAbj(>&peKg?>?)fk$~ zYZ~9v(V3lDLdkXdsJX*t>rPE4W)9(ss4SI?5Fu&CY8ztpWKmRZ$o+wwJq~3;!O>X2 z1X1@DunaN^0NODS*AE(J6eB-%&UdAuF$?tpr9EP#1Rx?j}DU({736Be9-4{0h zmS(ez5=%pW{qWHLskk?^*WM0?uO6EFb-CrBfkUDd-)EdRfw^5L_iYB5wxc`B5zJoSjX7laS*5IbW@tmtHJJ`0h-aj4vXcVxHf6 za%emTQ-{DKObtop^^uU>MP??N?bE2wkUMo7yA8()(vo+LExqUCi9Q!7yXdLR!rIwt z+Ezw8@-S0w0fSyu_gWw~*7CIU!}KI@6$~6)ljq}nkp@Xaixqu2xcp1vFWG5E%6tot zWM&~sdB$J&vAPQJ#SujtXo}H>C0da@ozV z)0iJl26U7yb;@TcB{(zFIKfoNE_UHG0jR8_1Epw`@?xpX%uF)=ZG^;F#nlZClJ9bI z;$mXflGIUhDCzCuIInhMURIMeiuX^WdsFzsla}$)6o;3vDx*+;@?)Yf#2`=1zgwD9 zn}Zr9si+t&Drdkn+wy|Eh$}xZWM8DrD=mU(wiO-Hrv}!s|NUQ;OX>U#r#Rh(#s)dd zW2oW7=qN)TD5m1gr^^F33Ypk`uc2Ybj)wiP*j$yE6~r+&`_ME zdTkZ1y+o}c{Ilt(aY&cvr$zqLA6{E>lNXBuwSEj{bQP8ch;EXA zR#W4V>+`uuPX2+?t)M63BqC}p$nP#J?I7D+pWa#n+)i3p0p4GFBmCX|QPir%^oW2uZ+A|iYQ5bJI z0>u|81niv@BSYx3;TQHY{ybZ?#gt)_`ET6IQ7mb})pCl;_Dl{=&WP~Wb&hPEPd9o; zX1P=gM_#6d(dB7hs3AkAsjqZ&nh?O;+y3)k!z5o^zRu3)XGnj)KjWhl6Bah+I}RKi zb7pk#?^-0)x0oj(f-Y?;V=^v}^_)MiQdc!Jmo;z z^h%D8#Qz@a;NLP=+gda2GGsik9-L$@w>AGM6YwXBLT7jjGTJ4ycYq++Ad zd~PCr5mTzr(wqMhp=`{1d40%^b}FwRgIIpQC3NWdx7C0%139ELTzf(Iht0WY*1YLj zvdc13ieo%#B>G3oGP&940%J6r&bGs-knSWuAT`!iRy!iHjI@{C@xl4+i;?zfs}c-7 zG1#j4+fyM*hHzHe@nu?GU90~naw|N$b6&CM&)^9Ig)c1N8y9SB&TMQzM>JV{@Jvz& zsFeOx9BeCVi?UL4vy1bzf?D$g(g4&wWwd=b&iw$+*v?d)z|LeUiWV&<$%KFl>mD^( z5nU12Pu8TN!@n!=YZDqip0fCqy7O~O9Q=~TH$6$R8ZEh{U7kjfV?TWB@{*y8iYTq< z1H|#quBxgnOG?d832=yM9Rr23a4f4!C1}CZwRj|ou^7M=!(>`)e9&WA~m zhT7Y;dw!f+t_>HBM5-oW5G4<{r$d=)jO;qWgMo6au?qjRkL_G8`Pha?;+~Bfa1Ul& z{U&m^ik007yjM+WpWPnc4$3{{KKERK8LGl$oL#0U>11p_SpZ=8{l! z7+Zvh2jqWX27-li7wgTCCzZE({Hg#V{<;*!NMd$=KA_j&Hvt?AOFgC#wQLkyLC`q$ zak?kB=gTX!#=5q4iC$#&2C8F_uf)AcSat96d z<|Y;$-9Bb+EyazEK#$v>M!$X)bT>Cz8(_)j&%>}Nwr?T81>9^(_7SRX*=7en*N?kJedW;iMQU;yP{WE9!6Yc22msZ{#* zJv#Ev*$Muud~EWeN1iOOc_O+;Rf(0#gMqb0dPp8R&HDK*h^Fd+rZB#|PFysAsE(+H zWq$j6JstsM#Kp<6VD#KjHGha4CRA~CqqEUZ4+o1NV}<;a(GM3|zsVoBW(8rTVSeVY z%tk=#0uU53oQ$bnL_`qJP|dCcBl-|fEd&=kyPEFq?n*B-`OI{zi&Ic&n=>=~9=RD# zX*ejL(_$P^JSR>FD;py(KYIYJNkG#m|M}Ajrwt%bE*3DpKSNOi?(ew3#?9Bi?-2Ju zdj}gKVF3XIX`Rx$mHswAvOY(`0v87_OHR2)21*FOP{N$@ z&yhlun90=BQ+da~%!yo0K37NC*)2Jj3GBkTk2kiT^jTrKLtCBB!ix-Cg*6q_qdb3f zn?M$ zGB(QYuhZygmvvVEm9%bGv4bfai$qjlW8p46$29r47l;CPolXz*Qh_<+0sNdsB&{mE{4Aq`qt4wd8VAg zgpKV@kT-2GBf&fpVoo3t!wuzui+y4tJ^EtOfQaM)b`LRIv+=5KJ-*U6QCIfoyC)A# z<3<*FLZ!FAhP8s1%t)icUZ-tl&7JfVtHnXw&=A#wg zloMvgA#a2F*GsSR@i!NAkS)Cx9KeqIQHi<7sd-L4v&kc}iMLSVeVngLKd`CHDI})l zm6!XhB1H@h-McIDv#`?6pDC|v3;uxzG`rq$Upq(pFHQBa4nXliKL{JrXKR^I z!r-GRDLeV^G7uf0Z9G(K!ElcHxCulbX$S7#W7+R!h%?+)3gl*66%{U#iRM+MJMW*N zEuzIpIXM0MnN6qwpbx%ll!cAwTd{6LJ&)W*Mn0R-b0E2%<+}Tp9!_9PB7^b_)s_Y)V!B%3iqfs=gHC7JJfw-lHGUB0) z3?2hHiWzAkQfRO*-?Kd*FK>8OG2%zI7#1|hPmRniN-mc5*U(hjX&5#>F!h~tZM&jL z^jpCtYaLub8W_{tuV%935x4BzNeiRJ@QZd#amL00d&W4rXY{(FhDSF?-rlQDx4L1E0&L=Nz_|-sKovKj3GUCG=z3Ld46DpR$q=&}v!R0`*B z%JkUpwcF)S?%?XGZR&AdJ~4DT{c(wuRdX#d?leyWk|}+Ja@h6?LPezc(99D$s+#$x z8AcUF;F;q%UEc0qCHTq%vze5 zxrFoAT~IW{7_7m_OagcSjv(G{;$h2wk9K0)D~hk zpEQ@N@u1EvOIQK#CPQl;1Wk6dJzje!6b8{(ZT}FR}3* zSs8xQAnsGhJz{)JTrY!X1^_Dv%r|d(3rrBjfOV8SIx?|?H*S8XhFrb$oSZ3*XB0e` zR0)AvAMGqn;9uIOaR|^Krs1e2oBa-JaP1bC*K-cbunC-V3g;x>8@;N8q^05}h4wmv4;p3Z*Msin2OOuH~2{i5o**wgqMq+nXcS-d80(^7(uCK(Mrh*_0@ z>?S=+(az+ngMm)xBbDUUez@Ntw!~@&TTFY$%e-o;Xn?H?KJQ1Ah^)K7f#U24H3OW( z>T6q@qcNOAyajc9CpmfNnV2*Bei{gU0FM|oC=*1%95}xUlxcRPvhyub`o47wVlz1z`oBX92!BNj zQ4;=S5LCO#=#4Lrq6XZsJ2NVES0Jgf+DCX1o|l(CZGOPXF?shU;j?tgwr+xsrR>8q ze)y$c8w8Z26q6yBI@w+d$sU`NYrn66oxXcE7ir}=S<_8aWOguN$r#D}B6o@IWG(UX z{^7@}fro2SSzYX~IMBylnjj&Lkq2pmMn+YhwgTn$V#tW_pjQR@K!>*3SvE6|a^#}h zVug=~e2i*gw;veU2MKQ4ylp3wgE+K3vWe=Fe4`s^48V$U)%ADtD~!#~!dLppOfZ{c z3I1dd+Fmc$sxQtp^ceWRGfg>A|8*f?s(dpm(CoPP+lLgPi&2OyZY+L@b47$2XxdH- zRhRCCfvas&5%|3Shsv(#B9Y<$?b$;xaSPut&r#z5Edh<@;Nf_!xCS)wQOsbw;8tR_V2 z-od?4|Au=Me^aaAA0m=@T-qmp`iqF05WBp>4QUgxO|&7&UiLunVZY5ELc)3g7fw;I ze1{+hAJ$U4XKh4MUwFnr$^TVRktfABu{9AvQ7ok{WnQwFVdEN2-uGjO zDVQ9D2KJ(FM8@y$s3<7H@ibB#$S$9PpMf2L`**Mf;w8ksHC@NY<%48#gQ8QWR-!G{ z3}z-UqswmzXX~EG*(vCH{mdC+gtpW0bhZR|WJLXCCGUkl3f}`pKqv_^Sot(FQjqaN zAxL?7DY(9|=DYu@!yZuBUIa3JIM#HMGJ*(r$iEd8c}7K{2*T=KTFT3}^z7+a>%D(R zpTCZn)tFC=UWP};ei^6?T!~+DA&CeA7{$G1eG;VnTZ`2hFOcAUY<9%ueSp|2s+#3s>7;4?1V(t%@`6We`^ZR}h7 zOCMmz%g08$_rm*dX(Er4D49E?FYbQ3PnWaX>4Df<6aPbO?k2%6CA2`1anAp{I3jbj``3~Oa)v(H~4q4In9_d-=RVK>HRMpQ%Zk%h6+8X&)| zdoW4Wpsix!H#sg#r!C_e5Oj)>kl^T;K!Z47`m9VoRn-6S^Y0$v(tAt8a4W7f;nSDv zYzF>#_NK85o7KKy2TP`Tz9jRGt8V@8TI7YirIp3twS`O^QmUk_U*+@R*oBB<8&@@z zO558r`b_PNeoecFoDD{qp@d|tz4bK+yw%v9UH;nRyoy)egFa#jm3Z6TC?%uieA@`#ApC zxs`sFSL&{^*zLJ<_ztO-(EJV=b``6GTq>I0DM|atb+@D1+)%O8I7GP7T|c8c!z#36 zy4g8-GOF})qNNsG3&R4@$4S>E5aH`c$ zeRe~msb|9A;BH-g|K4`x7+$68aWr?Sfb~+@sd{^+=puXl20B(Inb^N%S4*}MJ3w!t z+3b^f&gL5XLE~Xd->D{vtG^VeBcyR=l&{ZRTtT4&uz~arO!BJ?)zvWwwD*nTRHVsofBy=4-2U(Z z6$-%v1%)Vxxkg_I`f%(If1Tk5sO3cn-1yWPP3eLE z=$z+*J;q2n@V#sbv76iskt!&VW~3x>U&{WmJ9&Je1wH_@#}|mY_kZOR`WHZ%3%D&P zpwsmq1LR1mu&RolK85DrV33)`-2a#%mH$IwNRomKK`J1OXy5u2-0>0+ZFRie6lnp$ z6Mg%Ce^>zX2U7Bo5V<#0OQ>_U&y6wPQO1QJmN-ifpDo@&I1MT;SAw;O(^B2o(BC+I>XAO}bdd^`RO zhIG#W?;HRx6)jXcIy%ZGqm0FeTyp^E(}MM&eZo)hChG|~%9X3D?BXlvekvaERm9>- zFuL-0BR(G=&xP{@i?mL3a4tS!TdHZ({J&J03x2My8LdO44CYQp!cWJV(asv%6C;hp z5Kty1`zpcwb^8LCI5gtn;UU0kK-9X*76@cXC6kwzpzdia%Uyd(-L7s zsME(w-lD@+x>YGa$rK~7w8ia@JEp<-04O>FHZI93)b#ZHUM~%Sfq_Jwcz{*JK(9G4 zV!_X_mb8EZKu6p41Q`m)$*JJMpIdHwU-|et0cFZw3S{pNrP2ApId-O5)xNS{v7En8 ztZ+|?uF%fiRhUZyd-He>a<2}6+mxx zM_#2;GXM4K4bb5J2c89LC2tT?J~A=Vxke4fWyOsBpy z(bxH@j7?2_+;gw2ujd@rnw!H?tUAT7^bJf^>oMMBhcUz%Qcv1nz}6WDD|R+#brA<%}m^CU{ zKp?UCwBIi8QkvE}wB+Q>h9;9Mg{NUD#M5>FBETl2L<=XnQj|{u5N-tLL6-<^Fvqkx<6r8YL#tK#RKChLK9KA1 zeSBc&AGf7{lsOP3MZYfH8@G;0WgNE@HpIEF_SX z&p~sdAy|xYP&~F}FU=}@tMZ8$QBiqh;hNu%`mon+)^|e~JJ-JORK0aQdG_ZfC zuD%{pn>bd&uL+L`A#ekxL2rf}2tI*wj*hp64Hp9gqAJvUlFLAt0+tS$Kun|m3A@6@ zIAHFFAn5+|8;BkY0DtYD$DLnXpyQppgHV6@M{8a6dvp6Yk+L##N~&@|=rN$X_$4E& z7tUit3#1ec2?>dia5@NBR|p{m!$Fe3_rr-gol8{8G`<6KB|%_JlbNx;5(4t!qJe<= zxZuAa4g3R92l?Oh{=pzLG5^~U01R5erT@jq1BS#p`~7>^e`Aew|6hk5NCGvB$*SsV z+y8Y(uxF;ZnVH!1^p{kn(t?5kjQ_bB8pJ3@5G3sS%m4Y)3ICtBo<`u#%*x2ffLgT? zR1va*RMg9EZRP59h>N|*&&|yRDho)v_pSDOLmTa`kgtMGFuVlW+1b+uj1Y>Ol0BDi ztQyrkz&hmaf)pl-ikbj8KnNlszb`Knpw|FOBB`v5DvCa!hIDYhBmZunB1#fBY6QC< zmX?(zCoivmm5_$+3rB1AK#Ktf<;Sz{RL57z+!J^+#y@}V_9F_sp%P+aWA`o< zPe;%s2__Pds!h{Ooq-n4Ma*RmRvuIUJ++YRg?I~5!bBY$9KiSnvSNVhY+9No&_o!} zBq)?l@dg;PIM~?tcXt|^nt-5!C&2sPUL#w%1$v+;mDbb%@>pO|-wd|8ya0-{e@8J4 zr^NK3Amy|!br`!MlBvRbNeQLUCbvQD3dg1!c+1xhsLGd{wcB)i@mJ(yPXD`kXsJTe z`OIYqJWN&sJ4uKrP_kJUNG(#c1T#N2_aQzfX<%~5m;=hxVVk^aWWC+hoex^p)^x{2 zK#vDA&>JDE!nq+#(e2ag>+2PONY;-`5mZqUYDV9ZoQvBVZQxpCEVg6%ix?xMSgHqf zMn@u&@J?%hI9oV3lvz8Z^ub^_Z-QllwjU&Ha)L$iNO{Y z7jxIu8(b3UGSPa{?e*rFiTL>mG?L@uK$}JG;B7DgQ_Q&R0L{Vn9Rm44;(OiRntYu3 zn!d^cB}E?ELX@QxHh!>c*HUjf-8FUuSf-Vwr6F?~Jw5%uMb!JDKKuPd-e+ub5_03I zFh%d>X)op*1qFmBzwLk;HP8+W2!5gr2KqY?J6kNc{yX2L)ef}P*3Wt=R{64uyBrk z#LgXYsK|u`>$%_jKfdUsH1FI4+viGth z>OZegC^fPI0Dcx0Agc&>cXv%>Nj*XT>bv-LvSj4s0H%VCmG#R*ATJZ3E5oDn@48N_ znM~lMz{}I~Squlr+7YjR4LvoT7qe0RTX)rus}507&^8;Tod*R0lh*|FLUYPyrrl_sh$Lo~ zFN#YYirjPRJSH7IBTheE2lhLptBj3@dd48eP4)W@e!{M3{!haSMcB$~{yFlZ`qlS7 zwB9&0hQFZTyDQ@(T`HwJ3n>Ii!Ao>anSORJSAFK^<8;;0Me5)8ea^#CplF{GQIZMa z!FjD;eMTB_uYNw|Z0{UPOIX?P^FC4%109#08rg1=5@EAqm-?K}Tz46j3EI{=o-q_L zh-aIQp_g3RZ6VKQZ@P47G**!7MZu+f0-~~-l#HuB3x9QEQ9R~N8WPJ+dgzKX15dQ! z;}x~ppBE2KYSi-BCPx~mDczR70f}&DQ*?~j0PcTSsX6v}Maj2!%klKkEGI6nR%zUM z-hgaU*kNzh@AJ|TDLDVFmdfr|x=OhLxtqPb)%6^)B|^+GUTGo(%Bv~*x2jdP>M8gI zW;oZyG_EvSM=+N)j1QEj!_Gy;OOBm zn&>H?zFVbvP9StzB{#%!`e5T65W2J1e|l`yuddfV?1B2I=@h{$-lsZjv>XXAXcumI z6r9QUxRPxNX`LMx2WO2ekCh|7Z$RjMxGw*a5eS6*Ls2Y?-w^A*)9ps;hrpM?BwhEf z`R->c2S7;CeYB6mL5xh z;YOS6x=L06WhBtzP0oyprtuGNdic+=ZaS6!#2=Ciy#LDl%%O^j5rc!~N&&yHkNXOWSbKnbC=Rz`VA>JSEYF z9$u-~wtBCt29f$1vo5#kZBRvxb`i{aM0{-fdA3k zIZNzb1t${h**XBC>{>swMmO zuW}{prYEp3q*$T{HzAhpc5cY=cHv5hZHm+6ACs5g8FO+mon`$=fme|ZJ?}EwH-um( z(IwL%8Ahnp?v}0fvd|&x)Y7U=ODAm0Z>uYiaW?_7saW4M{st5i=LZuEX=jhW!1QO- zNSoUr1evTVkmtB#DQZHEtJk=_ZD)B1X68IBl;k&hshsUAM<8wHni35Fnkn1~uDLPW zeT=^3r;|_cSdgO!U_kf&coNshI=>fj3Oek~x1SEqhY>(q^Z8VvX=-rNLv8rI*_Rus zALFB1=`RN=JxwoopC1Xs7+-3!mAt zQ*zIEorFZYo>p)-c_Qe4mZ7ir-qtZi?0$P?SD1GHV5+wkcXXTVRBU=HL}%JBFD2u5 zuLCu%deUzj5irhssIYO(vj>z$K@pM=F5KE6@n(|+95Zb!-kp@`<2|F-O9_a7Xq14w zp|W>)%KMg#St5D*G(m?PXXArB=zKggIRHX}xilG7Nt*=@zPWzJm)se|Wyv7U*Wj56$(A zWaW?dm#sNDOJ?=yK?2J-&}7^MM)zl-5-sJTH|_jJ;q6{E|poi>{+6GfTf#8?Sv27oifhMtJYD zVBlq>=i%YIE^^Li*FnzE1frx)_8$y1j!%*aq1eJwbR&`i- zyzPKDWR52!)`)yEzNc1-IOZk8-5iRsTsxw(V&Y!x^t~iQ^blwLc24>8*W)%}Oa5)%*2LmnO0TrDQT);3Y5McuYyvZO^l|O#r8y}#U~lg9 zd?p><@T323dvm9CFtiIA>yw7A)vK}@zd^~pIhNIxImm4?F;ZpVtYgMtZd$vAepEP0 zP|iel=sG`{!<`5HI(hcw4S9MY! zjn>ZuzdFUZTLP6S?cDTlvGRg0=v7c75v=Ay1M;6hSiH~PcpG8ee(de|Stg@Q@OoTV zT(#M!+k`Z7i+iL1f$}$nSO^W$l0er<5ZVqMqk21SVJ_iI2@n)vk=vL?%K-30%*EOw zkeo;40b%{uQZQuCHE)--bHIf$Ceh^Psb*(z4YXbW|pkoCfSBTC3 zO`tZWLkv@w0NLS9czDUX*+>COdjSa|;}_2QH{RQUZa=-aC)RR$B2sjr*~@|&mw>rh zakQj7l68lHi~!(t-c1WdbSVg6wpngm0vfWM>tO6)E=)faj%1!R7SXXo@N4sMBmsgy zpLquVJE?}(J4=sZkP4ycw{r|a{Xk!f5n%2?PdqY)9PNNcAFHX^bSK4`Ba@x)aG^_c zrt=HSECF%$+z+#FK<6%}%Yt}WLCkwvfzG9ox9rbhyt|?~zObS|bF{2c2DOm%o&cv0k+n~R!hseD|;9eNeOji%TACz2pZ%0aL z7RrR}e7dn_@fM^(FYAJ|{#w5KW2A^BlAxwDS@sR@NG~DuU}JwIp<7I`*8kCKNX*VzQJrz12!@hfHjGAUiCTVflLI2%Ex2NH+pTV+ zS~%S=el5I^*VSTSLcQ!EuLM*Ks`}DGM+);k&;dTiV=|%SC+3<24po3HWzR3 zOAfNf2*tAx>YQypa})dK3p2X3qBVDaY`w{>ZG6?R4ZSkD)x0Gx?C)Ao5Wp^ zc^+EMKKLukV1{;h>sv~y9&dm;{z!?0z!tRdbOvJ*eyK*83+hjk~j2lY~)j| zy;3!qynXC)e7`JK8g}86Zm!3#P304gh?9o>0Ty7c^L1pr1#yeJ5S;Z<1!oXyu)iaz z;7~$W=G1>dT)U}2+V|C087ZUm6%*ZKmg1f%qbhxxcGWL7Jm785EWfTewUA#V>?TMX zo>32Cop4*b&gH7{`Fv~F1jw+ZEU&S^N+)%#hGXY;N=N!OVtX;RNXiHPX_AVdv{lzejkTVvcWE4 zh~(VBxS7bDWD4iueqR4+c3^^*xSGU{I{xg>T$dnLXi;US+haIc0C)6<8;o9=nFzbf-5XLTc$%5n4<$t8s3Hi<+p65hbF^%pB_T4sccKT-K z@xVhFY2W!dwfuQ>;`7t`y4_r`P1YdybHwFy3Od&2p75}jlMjOj6bmLI0!e^Q19lXR zR=oIe%MJ>QCmtaXW#+4w>SX|zLJSM;QPFQvfg`PWJO&(sRq@x4iy_2hK`lyzj-;eW z09LlT4^yEf-L3IxXN)>4nv}gI!lNZE^n;8c-m+Ec6Qi=JfUq zyB?QrE1%#}jkdTig=xP~KC$uX{4-8^@V34O|cg}T>hOaMG1Zb#V3@vR93OTrrrhj#i_LoK1wn+9v6oWesh|ii^XT^S@oFejo>S#I8BBL2Z(uRX!2ELL19?X^6f8)CA){hnq=(deYA)$EidL}2bEbZDP1sRD}Y z#5FH9nuU@8&4^N}!_vZL#NE4RuT4W+YXg~_#B^`=m{V2Rp?vc>sVW+6OsgF!6v&eI zs=lOl2}1SP$@5g+5q^V7j=QD`%S{4c?iqer$ER)wKbLvjHb;JZ>#h%&N4)a1*aTr^ zB_63{F;)|3kfu3$r}U%vvK$LxrK2i-@6S>IFb{TUy&H!ihn+c+*86_Tpo04_rN_;Z ziRtl~_qY)jU!>j6T$T~;gZ^m^)=y2UDSc_XBadw2%#(1AHq3+b>x>yWcBgVzt?Zhx zQ7<81V^ORVpvi4EH#Hqk?%r=Dh{+IZUAWcs>r5iZ2%KV=fzw2?5LPCC+;c>kcGauX z!gX|g^eBtA{3ICu!c}Iq>dTAl2c7EA!b|unjr3(pp*5YsBLb7!h7(lfXYYQ+vRtXx zcm#go$StQ%S+ZD6@1=3LY|X@t=n6K`%9uI-f;h@D%EGHU<8!Wc z>vs27DMa&S=F;nmXspT~7l8T?>~<6nE%TM6o|TJthFV%s7bUxCA}$PFEmag|R=kf* z8hf#2HhSdRVP@%8JZh!A|9CsmlFYV}&eJH3A;kiTno;k8r??27y6#N7-Of4N!vCx` z`qcT%;yb66_IKNp7PXs+z9PBCMys==70AP>SHXF_jamZj{o~1{`{U3Gr{PIAO`||6 zVy+bj*Pg_(%&EwYo$aQO0YI2G{)^(tMwtKR%Om>0KjzVkz(sQZSHw$0)nDcyRTpOH znT=cmco*tFcsGh7^y)tAdQ?sixu_*yy0iSb)MuyOQE~biwiYv1myse8?D+v6_ z^AtA!v6Igqw&35B#3a!?#BGkUBA(8?kCIW&^F@{KXnboN95poR-PrWiQqFSZw=abG z$&#k3p4g$6A+Ot`9xkdQ%SF4*vFs!3uC*Z>>N2J2omW4nSGH}+wMrmsf=dWv?g}f# z5K8}N(2ERHQ-01>H`osQ(XJA!9&Cr@DW$EsYb)0pe#@(2J-!%h2N?_~&8q}mZY&xb zHpPoxE4ka@nTe(6afO<4jtAY>ShH!Q+5WP%JE=+Xz4kGirrX%ZWs%GP;@Fk-LR3OC zE12DROke%E#vKa-rq#g7p2AZUbgsL$eYZKweATIs%4+Hoz}|HR#AU}jD<}Gjb4IT@MQ5VtP}wMOQ?ByQgEGg^D^ZrUx{mI@ zVWxP)h}ZeIN_y6V%dB%|r|k6#2mS=6z^OP62`3Sf(=uP!D!UlRo|->RO>bo`HC-Re zhS5Wo#N8C2#GvuGby`ND2HT0agMITaESkyKThCvstEB4S^1lq{AZ81BU1%h&^d-gr zd?WmuCJnGXhFa+d_o@-Uk^92_7jVWL~k-f|wH7A1zzk#FT6gynxS3=-Zv zR(q7x8(7oy1I6KrRe<^!@MUUGRj0ms`G^z4wzCu0PJEsi*w^_6m}T%=s}sbi9E%?6(6dgZF2ZWmSN3qd^0aLn5a| zS!a_1!&xttb<20iT3MN57Yq${?{WoIrRAebA*IX9zRdK6lHaL|OnH1aMy8!xijEd? zA&t4*h%q!O2R7)o*C#spbJ`g);*!E|cCFpHD%ePqa(tx0Qs=N(y{Gb^*cM?>bXMLO z`<#foMax+|9NSOMvU&n>shaL%2+i%0xslV5z*x*=uz4cBMlL&;>cl%h2Gcb%4Q~=I zcxepVdInQ$e-GyjC@6AB(U+UCbJYp3(5h?-k#fcAX1!IOYdD3qXO{0$A~KWGn7U2m zcoJbtH+jp(^p{8Is&7`PYp&ccZ4?#-Fu!qWyxeYG6M#~GBr zEJpWte?!MHD*0|H2}7dk-8GU8kFw0WWKzd5U(3t%Z4qI1(6zI(eUWixA5?Fa=^V#; zDVpcNHPV%1_EqAhGJL6^%5@y$F?A7VjdeK7_!v3SW22r<5H+OD#~tT4_9OKqR&GUr znB}-zL8PuSWIQp_*vBvZKEeHjPb+0$P5-6Ii)-bM;kf0+NkA>b-{mpiOOU!b>lPIl zU(lo|7$j}wFQnFx;B{x2plsUsUGV<9<#}dgmnTwl82z~maZzl{v%y<&y z2}u0Wz!I-O3HsaRqTByU?N$@6x*+MVHQB>WIBo0ozum9AyD0FQvv%zMC|OCu ze(9a!^`>1*!b5{kGe0Sw=vcX~-&iiho}MW_VfZ4^{6P7ksvqg5Q7A5Qa(!NZS!ASwMzrn(a)9f7n2+(6Z@2Qvb1s< z%_d8<|Ef2E4HC$WY79GzV}r2%3nTP#8!;{bD*6LfidcI7e@R&X{xFH>e^MiYS&tOuDNDKsw&H2ppv4#dGiKCL0($@%^QTcH*a89krDq`#9iLz zzIj9aMnPIa1C({LhUBBa;3@Dz#V;O2jdIq(l!)7qR`$vB{pDAR1-j3bF@p|szf-d4 zUmGJ|?ZqPJTAkHLlrjWT$pG$0(r)DXl%z&_{7ky~wC|$4AqWZZ;J~{qG;vt*1b8MV z-Khl$`M_?G{dMojmOIhARTpW1$C+yowj?r5$Ui^MNtdrH4Ymu4`@#R1{`zy6_56BH zMG82VPW``|{;_knMVMA*90LE{6ggd{-)Y%O80+5+B`tBd#9el9{ykKSvZAy3zYR3& z{mN0~c>gwC(B>SX|99_(-|?PHGU773cg`bYCgq5T-sFTsSjIASSlBd+Y1eh!JoY$P0|P9~P`+ z)ro8P;23B?kM+yzzs5#MM7a^%6Ny#P%o-?q9E+G4H1oUlVYK)Xu?A;!E)Mp9F5(F` z0>}?$?l#}MAe8GLQR7CcCbzu-+mZbDYNVkc#66tjSBab+2plEir3C8}R!K@~kiRuU z2^&X5*N;h1u$V6WIgN$YdsZv;PFs>bbz5-)A*))1!>6mIjUYHo0`WDy!rnQeCfIU{$I@JXX+JNGM!L z$={r6>LFZglU+Q~QzDHm;^tIbw^f43QHjBBEcvp~+1<&djnGwH*Jm)sfx>q8k~`<- zAUr;C%A0uWde+qO&&(VUw^7iYS!1Mn!qc555r&`HBh>Q<(!A>z6&2uH1? zCXITkYr5fMRVmhIwlYnfNNM`jX4Bm8i6MrZ@jUrP6KJ-fu25sT9ebn;jqbb1F}p?4 zxm+X~MwhD9$^kUG0-kE1XIfRmf++98C0PXEoZbtSu44RSA-h$*mw?xE<_AkDLu!}U z3J1heIammp1YapLmU|iA1MALa|@#3$gZ)l?3}oePv_uAzE6QZa5QQo5Q5 z;^x!PL5i`a#HklkyL4K+$R>%sH1blnT-Dp<*5{?+{xeT%1BJ(1rQd39r$)T)(3537 z)`mg<>%#E>+Y8llki815cTTqTR8=Hm;-1a)=N~IpXM2H2Vt4j!MwaCsaDXeHU@%hd za@6J8uZ6MsKnAr|o+%3HY}*Hn`tj36UD8b~pmlo#d0WNWnDaY#d!ZJD2)vNIEFE&@=QG2f4Rc|kdSJM2 znYjo(q6-UVVbbWV+8*EqjXWcYC=&8`AwH?j`yd1t(+HAdZnfpdL^?k7IN+ys20mYp zJBrttJ}FvJg3jjv-Ra&_bd0i0)f(Qr`!Wpg-G6&^(ZI`n*jVI%C)n5X^ZnT#a0&=y z$Ys5Kg);)VV?FipG&h#6Qh?k%oHuttY>*|9fyL)wrdU#y=p|L6Ve-09WFgbe0mIG{ zF9JGBzPKxUe!u<+N8D(v#+^Rnn_!RWZ~pGWia@86Jttw)TJ#;sk0g3eE2fPZreNI} zzUkPgM&{c#nFIbcs{^@D`VHqz)8}Nb+;@~fb%Q7YSm|Kkjy&ZxFv$P(u4=LGrPJ#8 zKK^+D{=#!Z4(dx~iq#Cx#-b zqdTSEfnFb$b+XOb%-ex6#G+d!o8W*U{RP!@+lP*@6e3E#^=D>3)q__C$a>vW2vL6#jUAep@H=MnrZw^93;YxI5$sgl#|YZ5Nb$En77O;{}7Xs=U((N7t0S z&(l+{vc7Tmn(5&ewA91{&IX=VK&)0*cEVb9ktkhOJpgt+Snfnu!(ihT{ov`5*51`b}xs4ON^uTtHpCYk!GRZ>Aw_tpH2E-62w5pp$J@ z4mzAj=PY>G8i6Q5zm6dTeq)4Tl#4EG#=W($b|jsB_%U6+myK5z)mX-=fuZXcK0_z1gYGEL1^c>-K{;t0B>+HmE%!G-*K;L$4 zE5m>b#z!2D)o(})K3>M2UYZERRO+BCP_i@Qk};;@C#U>Hfa?BPww4#dFHx$?sbJg1 z00yjN11kQ2nuUta_}Tq4(99iV3V7IX5)86ArcCu|P)Tqeiv~9Dr43y)#@{twqZ@Cc zRR7WloZ6}9++YDU_lb!UgGfX>u3`7KsB<=SN&AHrO$>d#O82&6<;sUJ*)NRzJOOHY zCqz!!<`26tr&Zq2+u)`n7Ge?0QvmN^gO5ntP>EcT?K{8j`JSc)2i5o!B+WQk(l$(x zVqTm|0ej4e{ZX#b=Ceovdn~phV3Wk`cYve#H#Tp%(#(duyHi(31|tv5O$B$w#TUs~ zZ*&Ng!$Jp&$S>dU3hc%Y7j(pY4#50N(VkP>gKs=$D}Td`&I5;Hg&hak^`4z{R8kiK ze8D}u;|n8|*bX-A=zg8_7W}5)mEx|TdQJsOs$yDUR@{x1OMB=_;cEy)?3|)Kb#YK^p~GQEdwyk^b^lme`OxW(in59$wEdm_72(AQU=k)fS^xngca z^1(OKVTFjCVD@UoBR5axLn(bwJ$XcHX(yooSqAmE_c3@2FR?t zr>t(L!D?QIld;fN@9zcpfU9bxvC9xHu3M7|D{>uE`KUJ{(QvoYx7T0R2ss5AfUQ%b zy;s0!I?5%gDoUkd^3X<1(0IQe#n|F$_cf{a#w0<$bQvT_kv3SpT>Q?2!wb>N zl#`6>UE+=jePAZrmn)iUIWwd5+UOB zjW0UD1L-|55TIi6xp(Y*Ose*nbHA8Ab*3k%v*bMQ(p-IIzao{xz`3<(!~q_LO8$;#ona9WgkZYfdK45iyg&Fn4%eS@%4dD_Ic$cT^;){q zc8lJ}V=QS=)hW6y8fsBEbT*VAcfEe;Kkns&hcUPcIv?!gWB+tG3EZGTxxa4^bp+jD zfAU{BPVmBFFf4V#TT(Z`3j=&yS=u?PpGN(~5O^%XoQcah zR^aE@+08ID}0JDujU8?wX-=l=;g8dN;+z_Iy`FcXRG%`DTlQCqe5i7;ipP<3*VjJe zT)Y1bJ+UtbxR<3tJOsd;KW=kKDK&5w&^KtLwJ`R%!FfS!-V$qupfkM zI{!x%A_v8@i1K`vY?lO5cpuK{A~PNR&=qD7d}`Yci79Lmmp2z`sWNB|Gxi~x1#@8v@$tp)*~XwcLi3ddryI<`<7`v z7A|z^F@|Q0D!XgGj?V+B(QxGI(Obw}`$^Xf>$b(!Oi;#co8IWiC;E~@-$*S`ksAfhFWUnGJ&c943c8wT0rV2*UK z-ArQ8<8-YUG>HZcI&kx~%clHr=bcX=@hg}yjVHb4z6-eq5TzuK@Z=+Q~$R1>{1(bnlSth z`@;Zs1phB;Y&=tw&mKZ#4Z^v z8_QvBd1UU*fa41vZpqT7_}cbM@uaaec}h^tCGf;R5OBNmSLPIV=a;Q0)H%buU%)Z% zUf}iNZ{Mn;h!;@qH^@Ows5!QlFn7#(bEQ#pJf|Wi0;U|A!BHEIP>~4|CPXbk=gx#z z&m>l_AjYjgPNm_=(9clQG>$dxfN>8dSfel${OFDep%RPmi0g{ad7-p;`<+ITg6ka% z-wJ(ahP`FqEr|fuPAnKOv8U&!;8fhj{!^S-UHBY?@SAj5`JZ(%fK{Rwo3~}(d7$F3 z9>17UTxfmIaJh9*YF%kmi;EixKe1--6hV#+`w9i?HACKj9N+~-#Ij0l%kTzeQzcp9 zW3>sZ#lP#}wKkm7E6UcJ+oV3raFR8~Yg68T>s+~DeqSxp=Zmefdn*0;!l7MQf4lb2 z26`)K^u#A!xEpu6d9|oJ8g7u6J~=4868TU1olZcHFQ_$4pwo6uh`-C;oo9;dUb6O_ zcF`K!RxpeUh9`A{_x?{l);pViWbsdoOAxY=H2<%x8u`HtZ%~kuoILB$=buOUA74&?2O8HQ z$Km2j`uSg+M!NSO`~R0EQQiFZ@7p7={yTX`zK{s~Zze>P(Mj>2$NKBeek6oAlz*bg zU);uhUN_gjud%6S(G^;6^p?7Ai52?2`vM;) zQo8p8E9PpMK5e3Sk-Cyg^}pL$`0#2V{Pzg>g7p9FlD}GR2g45i`&!cH|9+a^@m`}S zvo+nUOKoJD7TU`1S>IZHrxEx<%$Iv3X_$;?9|V6p$b1TqymO1!iy{$w z=rIV4cv;Xs-xbI-I23fMK;X{v_BG48HBUFA0g6VekVMsUvrv zs4~XFuN(lKQg7(#v06VW;)aOA(H`of9?Z&~YQ6d|uK?Cs9PnIs=AF=J_%OE9T4a zS3EJ{RX_Q7uG>cx7$Ri z%`fApZ^FJfUuKgMin$RL=~zN`2Y}O&FMHhAgOyTx^|++@iZSXX6k1v#HcqWFQJnU~ z+q;;q6G!}jWLXwlyw9(DvyZs{A=ez}zw+76L&x?eG8xWO#sn`bh|Z}to>AQW&tWjz zUn$qUAtG5P$vuh5al2~T7o&LLCOXN12U(`B6ie|NKBtzyQrVAF_Hm8DkDXX)L< zj{AW|$Tm^9XgA<#W9W%BzQo4Mgad>GQ8SrRC4jS(H`+tkF1s!tt^#iu8~sH z@uWNOhl2)VwDX6fn}e{9GdlA1SHjNcVw|Q8u9zJ$(J=3WR4xuJdROOM9mPU|h9ZXAJEUBRN1`#D5-n=G-iOPLt}#vyvtBe3DJsM^%pGn0 zSH!m47ZQI#r#DYatyIw8A2qD!&7Ca)<$ka9w;f+F9|335Fdy_qw>n>du{*4>hNa4E zA@l+iW#y{X!Cm4vP>Oc9e6rX{>D5k71m;Fu+8G^hm)0wCRG8b{Hma?{_;M57WkTu-chnxD|DEwb)-8UhR5l|S;zE{QEJV*?L2J?YTSOYw{o)Rg8QioQ<|Nv z|NI!s)OZ6{u;5Y^+uOH9kE1YDKp{eG_YB`gD5_au$+v$mYJLRzhsNpS`F%?hF$ASF+?s?77mAs>9#f z{OnzE#;+ILMlTBj2`|eFwL!jSW)CV->tXOduL&5JIybCF9+bPx{lQ|7V$HibDLRA* z5&dSvKe-|_411AyvO5$mYW58U@AlKckaL$sJ17JB{Tb?8YfA`aIEq?RJ9UDWhn8EosxGO2@i?K1?xI zUjxnk63b;Z%uv531)ke}nCY9=j%)J2=jx^OhL4VhW9y{AD2d-X%{?1XxaGK-9Xel} zj|JI%n*IHQo0&`6>>aPOg1lm!%xJ`ZpRKbOq)o8)j(C#AqC3M!n(rVXW8{?|xp2LX za?JEIFy5u>84vTQ4d)h1B@eoleLuQqwwhRjsi6D`Av)2w8QnK+OzpNx=G)YU`Gajc zvy_|?&ir!~xoK2|;3JjXG?j5gdpM-K+?wU-rzZLRA>?A@koo7}u2kDu#r;Fy)r|j% z72|1qI32{)&bY|kfAYA^2G09f30e;%5NZjfS-0FNfT zx<>{VIEl_@0Rx^(DrS5hXq7WaRbPlU20Z46#0$}Pua51+WCm#1nGl%tAa@ZpGJW)BO7NMTxw{ABKOIWpI(oXyp%ghuT1B+j-*x zY?h85mw#CkfATo-rS#a(mOsRynIVk(32{JLNkKlWzFtq;!eo?T0dF(xA`9r7k~LtU z;VpLw=#mH+uFY7eSfsm7BBQR9SvV9zfrBXfRW0iRWf!B%u4 z-@z-nVH^N{pc%iOzh#x>F-uzyzR?F|-(Kt9I`rv?7+Y&`sEfLR3i7p7G)rqYVgjx!z^NR!^c&tY0tK;JAX3OTRKmKA>#XpAX^?v9c(iFet3ZR;+A*y;z1EfWtE)MB z%REITky4E8iN>8*2?!q?(^lnkHD}@eieo875Z8I>0=*Q<8G0Rbyvvb=dy0GY9@S@fPK&X^=Xf-pGiyL`lw7w?Z7#?PjZf#2rN4&>a@1owTNbBvBN z;10o%z&K$8;cFoq-N0>_nm;aY)zyK~noK|8d)LK%2>Ww@x#AE6w4w-3trB2B+b-Dbi?$T2D77X}~ee~g2it-4`=>aJYH4Lk{Q7O8a4D4t;pdo^E=NQR6QhHZ6B2)53Uiu zX@8599J69{sN2}dF6itcsqj)2JL5)h_Hi#Te zqS{)U9kV7!Jee%hx2>27=xmg|9(!kf0-R>=C%l`Xs+dVuSI+3hWYz9fr)b#f*}#dW_J&osJ)Ji zl!(_3s%k=E=yN}f#?Pk0UkC4Zpn)Dv%@QzfuB__yq#>bom$^;EXwjgS=-~Pm5>2DA zw#heFP8e}rT9FcJufdn7N)uRn#KY`s6 zGRjpavG~t!A7TXI_L|A@!;VdlTB71@wi7zOzhNP~M~EHzK$o1Hn7}a6$Gr3D;L+`X zlax!)L{`cWmTYWh2 zvEzqZ%0Cr6Hq{k{zcay)j$cLMCO9$c^Ur#jzG>Le&{7Mq5=F`&43oKVN{M7B=XNg@ z5=|Rkqw^EEN*O#5dL45+L`QI^U42nellnEW4HViraNt4X)3+FMk zFQv=(##f1_mCd<(pU6aspm4}e($EtQ@kgJkdp=C0omEl)XUP`Y7?j|S2}VFW)eP&Q zX=4{lB^X&hHyj^bvbV8T&{xEv&6|aiN!_Hmi8L2_CUrpg%Hy!&!$GNFE481#;JhK` z8xr--Zl&ajXa+nw?e*PedC~m=`?PGMXAg<8w`qYsI8B=xlcMCrddeVPbEPZnNouXf z5IKSLPaH*{7{sg}fsqLzoZZ!8Rla&5@6yH#^{fz(AkRg!x5Y#E)mCfR|M-)aL+o!p_17;;yX7cYh zMhJZ$b?{c}73ri_XKb8%BZ#g7u_Jh6BQE_Mj~B&SU16u)6HZ!p9|R9zGa=cI)beI*51)cg_wB<5 z$IfUOJTFJQR9KJZRIsDKVp zd&g|9ZRTsoimTaIN(HVp8NJdOvhW)x^Uh@$D4`bSCJ830m^M#Gx=67>k47?)j~x7! z^o!UaG5+z0P`>hEcq#&8fbeqLzjI5^s^aq-do3n|yJ?IA+vXU&E`OpMnKox{ngpjK z#*A{6ZO}^LFooK{pe+EeIKPA8KkUuw2|bCRCDB=QS4f-x6Av)wNJK-1$kpE5w+3;7 zFPriC>XXmoOw)N;zgu7%Q#L} zOh=P7NvceW@$nk(+E*U5e0$2?vX2aTUFLAhV;oX!dSUueU)DTti-QMzQ1;^l)r7BE zT$wC-E#%7&;O$P`sLfu?ep4{X?Em7<;w9|$D@QwwMw|ZlF1P~<%n;bmt1f!e(qu&o zVEf5)ex2X2jV=28G*zp;*p+!+1QClU>Fk8Ru$QBepj_EIlvmk0bO+xwkI&QLDUhu~ zWMrh&nz1uUjl-%BMe8vKpOh+jwMfiXWVZCy%l(a_J|T?I7&U><-zS8(bzQyg#Dy=I z#ZIXb+%Vojk6d91;atyJ;g9m#z_Cr3hVE!yRYfUEfA-b z=>4G)66#%~c4E|2%Fam0Hb}puE5GQ01fsZ9@IVzjsa+wjT})0GlfjO*ofg!}){05n zkD#WX+4=MbDSa?b-C|46=4eKQX58rrxjxJ4^eJx@ZKP~ZcIgFI)>|_! zy`bJOVvY7o;salRM*dJ03>48{gJghg*+loe7dj5=*_N_N#sKvl|H^uo_?@Hp~DOpQJic7I) z@=t?GswsC8gcR{bC?t%poA}F}OcK6UxCOXZoQ_7NWTWEyWKf?2#uxkDF(-;oE7KdA z;dl@-)yt)gt&e5IxQ)5$X=|b1MBS~4FV3e}ts#FW&H^0@h;feaxlYFwi}%o*$eZ7$ zf3Qt`(*=2QBe4*PFKD|;`@*>nZ{kncsiPK|Y(M@MVFBJ~#qZt_f1?ifL+HrjTh%}5 zp`=zsXFInmS#@6Z18#=x!e--Bnn_X_N%p6cjz$`CaLwQj*jXOSEqn*(DNRMbG>jAu zrVk}wq3>guV(m=`YhszHsrHkVUuen38(M9s2wSy7}k zvPi4rTIxRe)~P}lgYV}zM8g0(h7d+RuxdD8VfiYgP$_qNE-B+(i=!N| zs10*#JXCy46YOrm)%ZLl$M^^mFnXCoyI<~6x)0ZGG#8>5ZrQcNi7r6ujE78c^i)Bf z5sf?V7&~t(x_W~>6fFw+A~#h~D*KJ0LmUa$VqLNdOQP+bduk^ZWUBnH{P?+EXkRa1 z2goMw@>_4o7M=X#jz{1lQD>V4Ei}$#%-0Zk*(POHBf!i-@^sPwg#uOT&%Y2${pMo# z25m}H!{`d{Z4;P(e}m-wyg8WZV^sBt_?_|^;iQ?zK07C!6xV!$UYV^OlyjD3U86G8 z9(u9(jZW@&VEoJqViso+od7pdX#SZKxetB*yhFEf*R{*)smNzX3(ln5zbV$?>&zf4 zx1j0tcL=hR;Otqt=%L;ZLB)nytJI<0-)}obggwBC6Ml%e!QiO>?ake|b->#po z8^2y_9m4RvkW(`9TMlBD+v2LZRuoN2I2|(|lFXeCLgo*<2(W8jp?}yFTj{`|$K6&( z6G!*Oxs(nG0b&)XU3kJ9GGFVpw@kG+$ zjEDWZxSqL%oD$P8or&45MFcdeuH@&A#wvvUVmrfK2K2Gx5|vm zwKR>GDS~cb3|}vvu=47>AKR$!_pADWT3d7}JH8upVTUHE$1|Uhi7va1!IjlaaBGkA{xeKUR{PlPwu622^8m~)V)#)_BRh8F2`-h620DTav)gt=DH#p`Kqt87H;0v3Ztkt7=c!Es=>GUlfhxbekf!Rltkue%ln(kIc$eJ}`h)F@uwW;wCGMTWrGJ zb8*qA9NAn+ui;TAQWA%EWQV(Qmx$U(AZyopu{=qlgYch>e5U)_I%;hCSkwl1PO0p56qt&03p7=Zax5c*!T9OX^)*7V|3ruk7p zM7i^x-0uqz9r;+=yJlqVcrKUlXqfT4rFQ=B8{=BE=C1B}O$423tpu zmC7|=Z+gXg(r5jOr%{@Wu{qqs6X99<>K^^YP%ilU>1{xC}CKaKnN3V5oJWgvG#?5xfsiBCBN~}2xlJX1Yu^`lX*IuZx??_| z^NnbeWm!ks=KCkiO3yh`M7iM0}I0Qttq zY|ZPdHgw^Z+_(A`yvblT9qz=c&}qvow>U+lUv{W3e7xTm^gSW3)(cn7{2D!=M%o`P z9AIrH<1&EY)BH*rpI&? zhI^i(a~BDh`;+gIc(!jv75C+nkBAY>>31(-B*rPaxRD-mmfs1|)(MG4vP(58;&rDq zrMO>l$Y#Rp(Q*75@7_AC7)HD&K5Z8MMT?V}8omAW#rdfF1E_(P6sce?@oN`+lZal( zPn=w;n$xTozQ5J1t3GdS=PMu5CNc$7Hd*?nn=t#><0Y0`i+XkZW^KU&EGP4(t{Ok0 zJ8oDKQ_3V3IiGx*h(CMO$TVsNTf8(k^@pY68Jd-JpJ931!*I-< zS7AeJy5z~~|1hi?P9wxaDnjtfy0ThYbBx-{HIcEs0{enli1wt9n3%gjmZ2|f!nijI zolig9^!hN|sca(3%|q;MI}yb!%Ryvvtf1*yzdBQa%d9ETg#?2j&ADt0zQa|N((}l) zaxy~l5A%aTH0FFDMRD2LNPuvmCQsIYUR39%LFcK4$V#+2M&>F`q#MzOdWB8X8g-jP z&wG9Or8X!fn3M5)J~BCyQB%Omr#^0rqFS*W4kMkHA(PS{7K=ke zg5LQC^iw*%QEVIMGanc_l8_8{a1+~XP!%p@Mnd^~+~ss?T!zk^j=qe{APVrLJe`QO zPLz?POp2eFxfmudS}Xkl7G7tQvC-fsbkq+AYRyaXEG&UmT-$Fb9H|sc9Id;Tn)I=o z*kRdj8m!NfB{RD)<9(kg@nzoUVI!5xtwX@v_|=kT>iswTl|{j)xlR_9qcVEssJPi4 zZ507}bb)=GZ}vx$1UF{FWbNtI>1Jz1S)$n-QS@_QeED*2-=R3i2`9Hh*+pwCpF|yK zzAS8n4iVXga_LG9bs3IHlmjj)6G^eG^aX^Kb9+DE)(s?t=~HzQHPwtueBnF|OQwQr zZwkcBX854`UwaOK}LwY5Ekr{qc`9r z8;|ub4;GS-Cw9!OGcWCf1y4lqOc1i_wISFNTF{ED!s1i}53#uE)b1&7btEUOJ6{?b zhk6@7E<9U&mkp;86@sl|P%i9jKyhQ^7hH7D_P3?n)-gP2(IUddv9;~B;`k*gq!KFe zfyl=84~ec?4fnU6;{L~y-Tm(*73$>{mlBtSYD1oED#`ZqfUhZrF<3pWZeo}n-sGaI4#FQNqQxAN9%b z>L2wAH`)ctk4x~@NSD;$^K-2<1MMdXe6!>^(M-DZcfH&TdG{AO(0#VxGY{H?grw+7 z*I(qe{a+JXE{%XUZNHE+Yb1Kd(Hq|*r~iqQ)rQdwewnC;P|t{x$n(FcNFED^0fS+s zUOow}`Ha}%jKj(VT?xwUK*bk5?m3|rwXNy5mgY05C+U;OG#2yf;>C(RK@&_o*?-G( zhLz%ko&HAE|LO7nL34vmKU7gu6TaqnLde0Qx{bd48|6mWHNw%_bS61EJXW%bTk&E-zF@xL^Pw? z+ktQ2z8!aUM^4v_k)>M)?OXmb$Cmy!kpt-ao=ovTcdmSK7DdvQ92I^fF9g1)4sIb5spEOmxnQhGSHcmD zSxxQyu3}R4P}mXM1&M-hof5v`-d@vg7qnSgXt=3tayn4f++U~kKPPTyTB6fT>V-`` z%CRYMV#kv~7FGk}uJgzbl6bU(?{yF8hg<|ttQ{fZ78>{(Cv6LG1LqIfuTDQ+Gf2ry zxzj_NiiJUT;N|HOGD)cq4C90>{bo1-n2)sldcn#4#PV-wy}_wNZgS>4PoKp(Uec}Y@spF#e|n>1>Mb?$*1Bd(cCR~l)Z!^EsAN8stX<9R1*A}5 zYgfOQm6W{4C?Z3z8-OjG>2FNKSUxDV?aMuH|2A%!Un%p0yI6JDk&%LBrAx|A7xwN2 z+t1C>w#5K5MV;olG}p$5wdut#yH+gg#KO2o*{k>0mgHj{Mh)5@2PMu3bL7UUAo8Ia zS#tk6@_mPcTHfbXXZ29Tro)Zo&u&Ik}{xG1Ze0BNRYO3(KX)_9WC0 zT&dPNmvm^EJ$p z%CfW;vt{1g$;SKj^^LuPcG8M5T7vQRj>jhZv6kOUicp8j4yR{lg9_#1QSDL1x|H9) z4@%Dd5a!_~@wjAF`@`JI{ypmC5C4VRTU2wV8lw)q#TN?)Ct}^~rvq&AN;`~(2Gi0a z5;J#SYRFko1O=mHQ>fj@3l*R2C)72}#0F)tVh7Vc}{E({FS^ zyp^m|YilPNZQ4`wze2{ZrR7U%mEQigB;;i7hgkm+(BH#*;$@S^=bm5T#p2HoU&1x| z)}y^CIqnl#>yXp~g1&1oV-pbxeCjhlxJJxsRSn*|WlznKMvhU?)x)t#!LBFgCC)eP z8XAK4Aj&m6TS3chuVp}{JV^rad0Nt z?;jp7?FWNXe4m9=(_n6MF2mr4fQ%z^iJk~F5AOR3rkMSE{ONP>`2(RD6&_2Fb3D*^)z8@2n2_jZlS;c zDw?1oD1gmNVd7%-AKc$@k49p*pDcA4@90ha&+9=Xo1ZW2yHOE;+jU*sS(0w}2SbZV z+7>h8GSLgSb}hf9tROdd=?!HNjlyFYMH%e2m6QIS>)Pv-xw!~I@dY_{GGD=jC7xE6*&R1ZB$Ef}&uJVZiNH8$q>*)Woo2AUN4b#hOk zxcN=H_5hjShq`Q|HqevnNvuUN=5~_O)!nVIq=`uCWc9QY;2>e6&e|4+{M>?C6Aotw z`1$iE3SJk%cy4%qKfFOzCGPsZO7W$6l24Q)^lGG6Iaide{k~y$o=rbtVwn&CkR!FT z551kHA=U*HMMeZfX7hAB>}B>&$oR20xu5Fw4-P7Sekn%fkZPa9FvjYP_1sT8e4mzE zbF~v2R3t=kxa=y7o+B1qE%1WO)Fm4o7ZzsdFL;WHo@N{Z?!>gAl-DZ9PEDhltDMkV-cWj{FBO$99fgb>;rnH*L3Hh^r_j;Uo%Ts5D$&TVxIc62EqW=0 zOe)bf`awr{N;D9{bz)y~On>ru^qP>G9h=I^>V0*>kV8hP3aFwIlfSvSS?m4{QqC_a z+E<>p4%uWD)7|b+T~e4yq#LUByjqKh`3axRZj1=o{Zq1lh5q{GqTWmDxjyWAgSlD9 zqYZYRpsh6eit!FWto5^gdv1}MS@(o6 z_yq?|`HX7=`00h;_6YiIPpWJ`DAXfisb5_`oQwj+Z5niEmS&g?LeAGoff3_(B2!k( zT|Kx0BJuOc0s@P|SJBjd*n0w?R_~{fXy2(=%q`2XVZKQrEQ3pP`d75bR4c9F)VWZZ}DTN>z5?!_G$L8P|Mh5?*TVXgTTcJqwAk+Zn~Jp5u&V zFIHAo6E|rgdkHtAR1O1Hyd&JMvcAyJa1;R?Pt~M_{HP^o!hwIZ08tgJjz4U9zI(X3 z)}E%s$_Q}!yeR^R94f=tq(M5mjFI)c&hu^rIy)(HQ<4!0+IRUYjl*w_7bYKFJNSO= zT+1~2gW4XZgYVD+kzemXn<204^_dP(+9%oNvGn%>37zXk8rlZZQl|*_tQid(sG5Qf z9mi@0RW{PLw&BxSSGU=@fJ<}gsj=>E?Dxu9gH>b>ff*D}K@+)2*;7I%sR`9+Gw{6PTHpYst4=bL+G7T^1o z1mn%YXc9XTyiN5e$GuH3kT=~cmifUj6_D)gHDoL-IZ2<@iipZi+Q^!YC6m6+6s zcixY?w}ytCVDnNP!CY5Vn8y`|4g%dwft}#XFYPan$M%l8D>n%3%_hGkgtRX!|s_S@rCtSq8!ZWRGAWNk0NSN0d zg%AEYu|Gcx4<6{}IC(Ji3TS{aV`&p5CGDS%oKjs_4S`Z@gmcqS(vF;I#VEXe{kR&A}5#^7Zsk;fKF6nBx8T2>9gD8oiJ6s^#`L9)b3vWIoGa&`Te7h zRqO`Au?52$%y6ZHK(~YG@Wp25j_EmOVy|q>iP&G(_U*uJM<{h#a&q8!JFT>J{qU4> z@5bu{e<}VK_pNsXm?0!(;De*F-ly=Xyo!y0f}rudD?j^YlxF20vVg;@J?yZ!S`;EJ zsS^`oHuz$Cs%{aF)H`)D%OOF4qAUw(XujA0Z?=+plKgFt-0O18b#VXl*J9XmjWhb!6smZD#$7Xs+Hxw#=a>Ab!_Jb0S?KYjwl zw>9tK#~-WZ@84)Zl;go2{@5JvDKF%JrLXJP2`73&z`C_X=po2Y1ce^z`T?Y*rU=2) zuFfvDe=O4yIOaDeT3gx?%hC#G`-0cC-ac18&FE zUvK_>9*i9t91`|F?{UxZ8!q8t;lhOn51w`R^a<(kp69%0GJhH&B{gZvPLc!RfvVcN z2BCcLb)QK*eVz{<#LmgigeHiaQXxrKA{O>P-``eYNFT9q!$Y_U$9rE%L_&a*|69-M zFuyUv%l3_KFG_cM(wzt%wA}v0SA7DMJU{&Xty?z3dWUt4Z(ql6e9VP(y_r}W#M^fs zkbwJg+5f$|`bN~%xq9PyY}~LODJjWwF5N(SyP7dH(16uzl8}(V$|@_9{G!@wF|%X$ z0ABp{E{J3ih)+mFdRjX6o!y7cn>Pzjo2_5J9tnww*!#!Vgd6O|#VZjPJGtK9gnZFm z8^X(vR3Z{yeCRpP&}XO5m7%<%QW)y(y$=p!&63=Z2afCN8-$lisbc4iu|g-06DLjz zfyL-(E#?=@M_X%~&;f*>_a-MLhBSR|yxou1XrSUfZ`<2pZ*2w33>4knh$|?7gtd*F zT&YBAS{gQJwK#kBtZ>ZW=eTnXe-g91yN4a~Z9?Z0R{*&c?H!#$P%tMab4sqw+t{{k zVf)l`PU5-w!PDj)UKTDWn3CS*z3;z^&OiPSq--B2Jp3ra7c7886M5~1jZ_we*sb?M zqEey%_)*k+?>or(*>1=t`81KYq4qX3eRv4=rg~v07!f-s6T0|I`Fe_6!}poG;9%F* z=E_P`ImO8O=C`1kH}8hio+^W$C!rm#z_5v3)|o6$7|rZualg!-UdOH>EIcEL8iviT z!1*j=VQpQ>XQj}_Bq1j+7qLm~npCcUf}P`OW1`tQhGEELfNqdolbZ&Gp-BlLp%?JT zb0d@ET?^g?(VLa0lbM|ZZEPIucB{~9xbo^%SC7OX_4l@+ue%xv@eV{q$%S!?*(n%A z?BvF7HKVqv22OUNot8Nd(b{;#MEO4A+p8PI(a$fVv)3Rzvf*$9e?OJ4p(j}Ex+%6~3SONsfXw@;q>>9|&jvmI((p9zYj@yCLXJDHJ>Ri8tS_ z{Dez*AFf9R6-tFLJ{td>2Qs^QdWFyP|9Egxr3!;Od}6&zJUw-Vp0Q3oV1Ku8qRLOU z`TOc{wXl5tcitn6pM>@HxGwhj=fc9L=}{V|Qy6PnuNx57T^PQ@WW=yxSjZFaMZ(Lb zXQ&nap3uX9<(u~co@`NZ4P9dsmZu-k3qL)NetO;)hOV%?hRM(mxQ5B#y^wi+r}J^; zzP^5;_qb<&&h)Sup6$=`)7sYV8Y5gg^*x|@o#1sx6`>N!gOC^ZfBb@i|D9h%@cP8t zYLUscFZ>@K5MGF^9 zXfiuq_T}sxgy(?=Ol87N;Djkp*Bd{!`}a8Xe=i{+PPh>#9LL@G6I3^1rqT_B-$;~- zZAeX33Fj;#r=6W!Ibdclk=?>BMy=> zxjAVRI3{Eio+k*}dTlsXX2LK#{V`fxkCj`jb||F|d}~V-3iC6eA2bNV+wpUxa~I2n zbGK0AdEw{hg9GfGU9T6~VSbZe2r9DU5$^=SgT_7GJ!n;{rz~*1ckf=IZMl2H2FU8` zA$sX0NZQ&U;_VAtf63Xi{81bpT^4S$@gQ?{LIS?>m9JpmzI`}$?3nQ0?YG}PCHV`r zZgzdp+uJ8Rq30Rm(C)Cihs86y0`;{{q@^Yc`y*5u8k>aSviJ~se3&eLPQuSccsbxh zEB3SVy++3cGsGrc;#cxN7| z0&ShW&>788HL&v$sTG=Nb}keV1ziVgi+Z|XGMlh^)l%VFpAZsy0RzW3GCAHv@PA~^Y$BnKkVC@n7_tUl?6AUaw!zfbhMrD#;A0mr zYSy@T9szPXT|bA+A}lS;z~X{T*2s!bm^*wzs-etUz zb58I8=sgi$e?L2sFiBY2Cblday1V#s&ovPq4^&%BHt70>*#0yMy%Ts$-fZDxGTWy0 zt|C7P;XT>;$)}zjoP?gaI-T&7UjR!&F_67`OgSMv9(a*BuT4-G85t?`YUROO&z*W< zI0W{e*<^x#nB@t5!pScWl1yY^eeVGLuzS2dI}Z|jg3SDVo(E4^m=3NJ z2)i)+fp9{~{^KX({DOd&K^~yu6LIljVoW9rI@n1ZUl0B_wL^``pQJg3nZWsS`11IA zC-R9VlyadQ@JAte&wIWt`2OMBh@Y&w0?CdLof?jh_weZH?Gwh6^9+wMFgPeYn(0~% zr+Zj--w7A_HjHN{yL>F@VDYizy1KiCn{(bbOaqVQ4Z!d}1l^32bo>HMDQmSc+Y;+pZp@!wfcExw zG&eU3y&*lv^=BZPO;4I(3S*VZ#$l-2$7X4-Mz)&|_i8Q1`oHsT|SS%aEa! zL+yE@*1^tabPXtP=t19*>ysjh49es}~{?dk<<;t`ggi$oaO1R?sU>gI(q_HNZ5kxi^?J@3Ic;Oqt5)* zVGzgBzcVtZGcMyOGYZN8DhkMe0a4jQ2txLyJKae-z3*%7d;RXYuU@6P(_3{_btiDY zd>)m4_3GXG-n;MKbH4Z7?_qW&e7!i)+>L=TFQk!yCVXrtUtWRyTqPny{b)PdjuEO7 z|DK)Gnup@W)vVl6^c)>U#FB;V3TF4p=XG?Vt*Z}h1E*yTboq-=R>Xd1)x^#;iq0dg z=p$P$u};=w6VEB9OKKv)R?k2q%7WSYNoNzK*Xx zXl`l8!6OYR&##j$Hp*jXjX``h78{RitMcetEZjxUr9CJ0X@CcNLN%0V|5Ki-+3E@hYliV&06TJbF+u#M0mcgPH@MV{4v(%l?FD(G21*! z`VKVa#r%4%Ys~85X+4Ghojak*$%SRnqLl7IxD{V%q;M#pifgbYQ5fsXqs*yQ zO3O@Qq_HC8gC^p{lEP7hI(!)F?}Do*!p4CxC$eae9&rNMh0E~qkA6C->x&nS1mZY6 zIdL2(joBbX1R_P4@uf#G5?PAQPOe-z5uTbkP;Qq>N`z;2^UwaiFf%g4tP}MzhjR>G z=G=utN~p9%#%ZKTQ|6e5!hv~T;y9B&*_}3_0=R5}%_S z1wuNtCf0tFA&yBBk%>)Ye8v$6~7hq?H0RDMs%vO?Z+Xc@cA3 zXWM_}&T>g9In3ldQ{O`y?-y8^e!l?&%qF4pWTM=OXlXfxzP^4=JTF;Xd&a)nMKye4 ziTX7@Ihe34(r(X{5`LaTz{%#z5^KEqM&4AeeL)6a(GSZwZ zfOc&$D(pIF+20{YA37V3qOseFQE!-Qpei+bSoGB>%k^OBWD`!dMv+zff0ICjG^ z*oq@>oIp-d4Lkib#4(lO8bD|32^>G!hasmA(uhVs2*OfT2wQFh?!guue)S#n7Z$>( zQ$fRQJ+)~70}2xiOC30Q;1p0?hUyACEEGlP>_z{HV>s5)k5*>a>G}K5-us~t++JqK zRu!Nqo6Phfv>n)oW4#{uY*v`n(s3@811`^EXw~KHIN>Ot%aCm!lR=59LMbl`MFR%p z$iPqpM^1V8`*zkRm?e9keV3?rE3ca6#Oo|pgPsi_ePPm! zrZJBo+lGW_Y$dO}QjaE9Y1I*tW2q9y)SlYgJNf;RNMl<(*N6lqm&Z`$tGLZeEAtF& zoJoZ^mJ;FZMgLPzLYtk+c(%2#n!)Qsgm_#*{FeRz4;K_&5g!(EG|OFfFP* z>xg4Hc#7J}@#ZEp9Dfm)mGnWuhK69|5@-}PJi3@RzQ`>qubf`!iq8zHVptJ{#%M-F z%|=Q#25OkwKFUpzLPo( zMo6~66F0up8V#3Gm<_0!aiS|cxjxxM(wGy*36aNgg1}_JkB^c@Zy~&%2r8=-ShMc* zb0Q<_#Xt1m;E`^O3?4(4r5rh?0;rks>Ge5y4uC_S2;@#JohB7bRlmF!&8{igECu}*AboLmk^`0^}Mo(ac~ALqxGmz5$rduGE( zo*3XnVmQo=E+VF#E+;prx$zY}o%lpAZA)0wvra`4Tc%`}_NOeaJASXU54=r7{g=PgAQ{B0SOy zrDwxQV~i(nN-R7^PONf%M>{FOT!bai#1 zsrfjGW^m_K)@i4e12plGmuth;3${$TVuI>97r86yH~R=@ zHa8A823T7#Bgpo5cX!9fy6kK-ZvE&b_{-i#W}+zggaajorTV|K^JU~%O*sF8WR{Fm ze`rPZ#>=pHc_k{*1Luj|_~{FK&|a|x+4dsX-Ggu*e+R$&ixz9I+m1_W3o)LW?!eIG zC!g(IK$Oa8dKjG96yLxgIe6OwG!%uRaX*70c88oQuBeaFn;r<3oak)4_Sk8`ba83vfYBr zuL=5H_{g?AT(Zglvr!)>7gGffsxX@3{XBgJm@hRlI>PHl$+ij$3t0cE=R`8S?=*=? zcD5>miSY<-X7@Ob9)PFVzu)0j6#{j z##>son5hJSQBL@U;>0{JC-JeyR!$-&IY8eLdF+qL&doK6wA{awy+L_eDAIU5X)Hm- zrTp|f;Ww{iG;+G0Ng_h4iT1sR_U}9ZeR&1fE;cS*1|{>sBJBQ$SbH0I{#m$>H6qMx z4JGs2OiPwRMFBst=c^DG^@V_(XU?DG^@C>qKCb`6FQWMQ`QA za@6Z)_4dLa_Q1(HSqpnsifLAhN(sToCY`XbSS&oiC==k*iIH&J$ILRU#fq}qI5F<` zYS{S1>;)xFJVd!}x*Wu$P?A5GoNS_-*=nKSnfl>6J@X$8nUP@hGhcqhHG%-Nti5QU z4{G2X>BeC92!cMEbknlyGUI5=0H1h^E{mY5w1{2X!se?H5O_ap+kb$ILqmMja`=9Cjlkl{;9>$ow@j1zLY2|SuDAW1e5K|u*2D8V2} zDa@8QmI=jR?EcdA$o>^_y8OulqxIvLX9P?#A%uplpinghw zLU?p?iqD6BKUG36Dp#%pVtU9_N4kG>e=<1{PLX?*2#*R$j5Ll3Mw}64%%j(1&o1%1 zq$?RcGdey#c@)Jsry)*aD`MX%B*}utre>Zn&zd0_Azqb)&X}GFJsWDz^v=+`MDL5m zY~f=BJuBKM@!_%NW-O^)#QzrMp1tKxhw7>-ncXlMitjSXB*hWA%lR^;U5@b_iM zju&zAWXq(#uc@iVhd+FM(&f_mDYA|xuIajI^#(16uBxm=metHj;s5);=hI&9WT5_A zHz9&o-beRh<%;Ff#C3RlL|dv$Bp0gOsldw!F$Yl-#c(fsE<<6MO$scn^rLeCIDGgp ze_nQ*4oj=d*t9YTt-^%1UM*j_MkEupYjc(jdShzQaWI&mE~`Y9x((90As=feBRJON zLH$*iU`dG$=@;@zp^WStmP`)JkI7}{GSC|$Q2Ws9q0u?-SYUbAL7hIjX% zqnm9g!I{$mvE#OGgzv2;X0tTo(27dbGjl>KeB^Tyd^IF{rz`R`_`T!)k*j^!;# zzDr1wvoPqCoJ2Mnv`FXN@#(x4k~|WPGnCYr`kKv~Hln1sh#x~ML-rpy#FJZ7gseRc zNy=ud8|nO$-A<$%k#@8iEB0NK#=tcA5j%J8#9epYb;f?0;C=47=lEwPKvGccon72V zJi{kUAdO`iD=CP;%YM_zb>+zxoO8Jyo!sW2b52JD^MDhzhTF$O!y|kwDxE_z)}bBG zVc>U9!BEL;j9YGnX>lEoD5i$2BD>#agZ-*&q0}4TJg^UaPyYrbx8DUlvjHL$1mto; zZ7`thx*MP`O0IlYch~fZ@EH2F1L!gJ!Vnq3qPAM7T_HqWZj72dXj;#jo^la3-12wG zUw!eE<#x6_zaJCv@WT&hP;Z;r1)kQ)!(P%V#a|ay4Et==fKh9 zXl?7l$e0rW9(>21NeIxf=c!|D#$YeNK(7aXJoO%i1_rVH!gZ*vNbiKYfWQYC+?EYb zh?Gq&IUZs9mR+ z6|4-Uq@BtMAlAXs62#yzdV1VwcNTC1ZT43gjVD*5*=U-jZ($Cttam()ERGSF^f zqEhD^aU7A7Wzgng1Ha$T45_G&6XR}A5MwSsMoH5+qClY~4@15__?gia43e`FMARST zdeZZyaqJHSd4v=t*&yfF&I~`UY0Lg2Nd(H`ONr@d$(1n`=Qlw{z~PEXErcY(mJDB7 z4o*qy$S9`gMUagpiiV}6fo_s580eq9ghVWwSdMC-2n`~iDau(UAxVQtZ_vlvb|{u9 znRJ9{Ir!dv2Y3>vOk^uQT~8?y7mt9Cgrtngu_$DUu%P$BR9P-bH?X!7jMZN`4e2{u z(C=j_20E|P<%uUD9OxfFOKWR9YJ!ut3Mo37CpXNXoC-ytmzETvtGk!C5tTy4>l(#r zZR~N8#<8|V1ahJwKNrMTSMXj*!K02T;uNu4J|>2Hgw|g6+yiRlScA+_^Rd>dYnY&b*=uWarFHb6Q5o?ZQ}V3wn)alv3hI|0o~p+k?ee zS!jk;uR_{m@L3t|IhNrc9>nlK9|l-kUPDQO;}_yZc&rPpgC^v!rM9j~AeNQT+Dc&0 z>BUHA588TwqDgNXJI=t~NfUFLm7^GRu;-PzdBhJqWNEqSChB++(^xX-WFZH(^bUvc z`XMh*j_3B%Qfyj%6+vM(P?Dp>NXK8$-*o~?wI0P4i&0l%#>+4L9;&b#n>TMx^ z;y9`}En6k~7;?~pY>QHRq-R5utErS5RZos;001BWNklf7J`Hg97YLo7&1_BBnqrC5}IE40k54tNeA+p-L67Jmwr zIntyQsYcOUu0~zRCHzB?*~?a3ck3NIchsMs|80EV?VrC78!!4$Ca#P}!q-+6!frF7 zYjG+1hMe&Dg6JC*h9$;$j6VOAFH?i76oPLC2KI z@rZPzfp;#+@unkxC9*imIZGbp8J=yC_-40vY=y(CL>hCs##B9$a-+}tSNF?y3Z1UEJr%iJ4DO;WCKqwhX@#|14)N8 zH8-QOq9SFzvZ+9%Y*Ar8zgAgpAsk!MM0GG2<%o4j^H*MNpksBkSWJA`&s;#iqu)Cn z4t_paQ<$E!iWz29ZhoFU9`VZ^7L`Oa6LB`zC3v#|MZpspMo~VLkc5-vG2&XjFY)^n zIUOOKNE|DYv9=Q+CjjKdQN(d18Yk-Gj+;suC(~s)9A4+#9A58C-5YvN=Gep*{hKe7 zXXRFumvIejDwiU~X`dtZT)7rAy9U}%M)O=&5hPPCIdzoKrLdrYCv2OqauctYGLX~z zMB1~NESDTRioT^|iV6$4z98*4nantKs+IR6Im{_ZHCfF>P@hHhpa}}H0Z7L?Q5vIu z`7#vbPd;Aev3Ghdke0-%xC{%GOZ}nS?c%E=GFh$+8V~56QeRE?lioFQ&J*`h-%Vsb zjp-DLJ#iT{MQbPfEM`+K-IEh1PO^KX=FeZA(4+o{j?F|nh>xet&Tu<{p)nPE-xR3G z4?^J$U`2TZrC9;^eG%jsqo}b5U}UyMvB?dOjg5isVK@g|D9$hA(cn3`dCArQl*F$8 z#6ftS?Kq_jafyuDHPtA}F+m^d$1uD9E`L(!2(Ny*B}n6z4pqt@uDePJ~PL9ocj8=4dQ&Hw`6O zMkOeYK&Oeqpaq}QHtB-sZa;zU6AkEWX@Ds!2c=buk(;H(sgun(ke7$@iW-!b%sncW z>{%t0@u*hn_sh#mx$R>~NXAJ7OhrXG^1WVe`(`px=S3G?gszSb>>D1&rjLIdrl+2Q zl9J@PTu_jF!F%sfCO=~4`0-?S4-XCD)mLBT&t&Dwl{``2Y*18Ggj;U8g|C$O`OkmO zHJtCh`)*u)_0<`>J_6ap4x3R zmN0EHBnD9s$Zna-I5T?UIM)}}*zK^aTm`iyYtl$@6?@0@6_qgb^kD2S?_lJuH=)k5 z!r$3}2pbP`uaqK^lYzUt8)MDK0FtI;z8XcT%d08nM0gI(0Cc7yc26SE8>|RLUGM}P z2xx;aRt1=!>SOoGhlYKxqNsvaCQnWr(_{s;8Io}N+0TB)SKWN(GoRsYD_K4z8E_q7 z%B7dIBg)C3WTe1XZP>yS%ai@F z`_-3l?Z!4NC5e$!xp{+9;{Ugjy7z)8L>fnhT z)ocuPv3A|i)WiC+J-Br1I+PaW!yq(|1q4#Ul*#cZ(kPYWcxUcQ9DJe(a}HO^=1H51 zb#jXM^6w zN8M=X@T0M-7F$;>hP`0+OJ8`zW-PjxFXLgBo-u0VoSupo@-|EQmyA zO;XCB&OJa`#sfq&MA6yhMq_gTE_OYmw6xjl;{$|6t71-8fIFoj9tBI0#$E*Z(o_Gu zB*!C?aF}Z`I{4Bmnv5W$h>UBB!X@oY(nuR)oxe59LfMQ`Dv$0bB|1yIzlq5)rkS7qRozR2<=`Qog0agbh%4M>e$fBc1 z8@XXvRaME}xAYs~)cz=HZRYEV#5LY1vW?_EvQi+k$#|jPkFfLTV#)UC{CRdV@|Bzb znu-LP4@iW1K|G^1Mb8jnOMmNP&LN**N$9`ih-3m?PqKPtbbM}Z0`aRjt!XUFQt*it za#mwn;9S~-^)IABNA=A#B>iVE*L;`s$@P4hstj^iG9i;On{tUzB*%rGS7l{+TH4QC zuD9`66YpzCw|lNy)3YhJkX>I#dnb2Bh!`cZoF>`&2L{p9)XX*cmn^AGJ8?|+xT>lG z9i5%*I!`aTq~kSbD7KIBy41l2;@Djv|t2Vu9X^ zbhiU;w^4LiAi|t8>I?PA&kmt9#|Ph77+V%IJAzhGg(6V0aZRUW_J$__i_(J{Q$M^q z4;sT-)Gxb`zpKelj8aD%gln(|F5eIa)Ov(X6}Wsu1@g0W&<52Y{#+ek4l>Di88RT% zpgOY*rOydx|0$d}K8WGYC>H7M&{<8;(z=l_v%z}W5g1lMqqHHnvM1v8JXfsq337F1ze9JoW2e924j_U-`;c_+(sdZ7puQ?Y7KaTnuDuQvgL*SC1rD6$y>Y zaUlnL$oX;P$ab8wx^JO!;zW$)F<>#s?xZAwaEyYxfIzvbgem+kCq$8f_@p6pKH z@$v{&(4;TbfueMo|7Ip%&=rN(qePaK*;R{eXw~_k4@LMyj?+a=O^NcVdK4Cy&sgTC zKJ_VHZ_1rRZE8Lc<#LTu^1DE22t&>WWT|MSX(2q6RB><=$73dv!o-eaL$XTaVPjMB z5?|+Sy_EG4CT@fN)tA4KMB>}jKw8GM5y}g#s3^-ud-pIJn)=`z^|N*wn?=~lIL;4IOs!&4G`A-CW$XkR(1{>D$qXF2ck+_8MC~YY?#Lh;M;y<(MERPDP@+gx8o+hXXhZOL zBk=m7T=d@OS205{$iMe`$k3G}D#C2QSHc6cj*Wgg(lN`tm*Mibr6_FnjC@3B2ZAtK zr3hRu6;N8r4ZV{sC%I9Q3g~{*Jw0&X0FSJmh@zrm*m7*#SfWG_L;%P{uT1h%RCF>4 z8s(&T^jl6uv-9!j@|Y|{I3md{n9L?l7|Mp99BoeJk<(A-cyG^MzJJ}iH7VVPxj?>V zDt}~T7-X>$v9C{)Zl-)L(#xashsuiM@)em#@RlrytfTr+6f3n+zOS-~yK%i*K>}=_M(abVoXr{}hcZQa}A8kAqccy|| zxlO{^z8IgAH?b(Mdn>WUZymXdJpmWl9G?uirckuU={@%NH zKVRjbi6xTD1SlEf^Uv>q(|NjYCi3qypSc}7ckV*-@e{K;&$ewBVB6MN<_=h(a;0QY zbRQ)tDI#bm+eh`NuU|UrYe`qRiS2;wtDM+a*3r?)#~DAfchcPs6@$!*1 z*np$2y@@?7OR;f@1|?ZiWNx;z1s#Kah??;cI|)2EyW zk|wW+JeEmgn&ipN&E*lviKJUHAU~;dFob8`cJst|w0bf>TZIDs073)rp{C5n30w+H zId+q2V-sdc>Tg)e}7XndMHwt)h(su8?C}N+ch6X5>ErVj)HbnpTe>wT*W$)Fg)=s?s z-Vro6_n@{mi|wA9?efiUelyKiF+Hfw&}1#OC-RwOdqWOhi2E5apM}PSbmcdozHe}F zfd89(BS{YFbo-?V4U!|GM5ttQ%++RBF&`){FEN|rbeu{f5zGn& z>&IrP&NvY()@|h5Lc(Usf{nfFcB>Tu_G}Ly>6O0Vk@*x1rp8OJ?Bh*NwMi)w<_QR- zfJuqtRFdPx$AVZ;o-9W(o-mHalhw)lc)7|s}*=X5VhU2|v7)@;OHL`&%O!=$B zU|tL-j7gRv%nk|#B*%sv9LMk&x;y;n9Vy1TD=vb`n&ixFOsXPLb4p%DM47}%Gk5v2 z<)~Ry!w38mCr-qd8pSoMIO&{Z#4#Jh{XF4akS7vqY2Skr?eE6PKe5pzi4Ch%fh&H!_BZ%udGOm!&G?WQUwIPKYFzBum0v z2a+~ z&5XdFz5(uFS=cj6Rh}eWpvVhag4uGa4R!ziZK#<;g3o%%e$=HmB_QFw_E}}_YE7?;?SX^ypQVZAK=%?^~c$^dezEV zttOZYOze7Z|MYF+lCV*kwEwEBuE1rp?6dVrE-PJ#a!Ib{-S_r#d8PBu+rXo(C)<~9 z%(h&*{&{Z)6piRtU|>YU>X*Y@W@ATs zSl`))qert)S($^JTpbL3-PnJq18cUHLdV`aUr!hM+q=-7Q;9V;HH=eoFxgX-k=nIr zv}IVi<~_W8_#h}|-MG0HMN-TpPVPU79={dF#fw1ko@WxmX+4VqH>{d)m2w)wkR6r`LSw z=~>Oj=xlU$o*U7HH1^llR-^gENmh4ByO^(BWj3jtGe-_`;Ym{Km$SBzd~&*ppmWjK zaqL(Vm*}9fNTNfMkCRAa@|k*idU&AAV%8_+&ruSp~=6AoCqU5jZ?Maj^40VPlWW7g>Wo)-#f zD;>9D9Z+7w?oHMuu;9lFTj?~QAlHg3x2@!TR^zcg)+b664@8Qa%!SzXmnObad;5j! zQCpE2n^{2M{f4!Tfy}`l~5_BPpUT===c6W6r)ZR z`&6L1Fo;~88wfb11SFg=mZT{{JR-)=BaJ;SH%|10(B#O5#!|~1oBE`6y5h<4KR|lQ0oEZ#;PJVcQQ<&Nwh>F}mLfkt z2Pa!PnA60J!9a*d9EU@F?4J9XL1;r!app51pRTLq_{-72+}LIYsgkt|ia>5@Y2kXM zg9C#oX2wb?kR!6DYP)0rQ1p}{b}T&)S*un$K>CPc_FCI~nPMo&qXv00zL;)sqLcwW zdvZ94bV`&dk>aAFT)Kk@LLQ}((KI7dgX&098e@(zDJq=Rm6j={Lq|8VV+W$&`WCET z_&bcS_l)ink?3@(Id^;-;kr7g{{7z({_>ZJMSF>yx>tLJw1J_Z?R{z9@CZEa;gp+(!fpB`l=pMdMavlD4)w$%%_(%B6@|S^kR4Bh5oQa4>VK zxjl+X>o7v6-a}WYlMQS{by5Uegl9IVMH>E~l5c?!bFzIZH1sovO;v=8FS&x*Ls@fL zy*3`~y7e|#ikD+;^&8AFY-U~L609sQLdoiF*m~#?THa|#<1S`PLIbrf7nK{ke{E&rOn319O&!o<9+48;2_?4`%P>*e>K-cpAOWI&@t8Q9G#kO z9<3aVt<<9kX8N9_lBi!H(m3_^ckZBQ@3m{!;?BG8#!D}}fT!Pl6Utq?BwHRlM2Ok; zYK)B<*>ka?vN9i?owRBzif5i_VfDA-_Sd08nZ@Vk3@_&6x%&5?s! z$TnZGVmX&=N=JV$w}YyxN}i~EXn1H`R5AB)SO-saSzKGg^J~mCkU&k*_-wpzA8*3o zi!UJO(#tp@te9X^hMW#K_wU8%+q)1U-?@NYYffr12r639#m=E9E=IJw1ChZYNJh4j zYaK_~^+hT1ZjKY4#Zi%6GA8`~4^^o&S}gv&HbJ6M03I zSY!Sq>qjm_h`C$K>I>L?4nU(H!SYysKC6+vJ1$_%UkHz4lm~R3%TTjtnQJxUlJl2B zqf&Ey>^;%IF*Xdh#~Zh|1q1|=$F#}uXqHh=FWJOaYWK`lm8t_ z&@`6G)44<(dwdG?ji`~Oc0w_73}Yib7z>fue~3rq27;ssMbUdiGSg>-U0(=I{Yngl z@=?9?Jnra`22OH?$brmzZtX#vF24R{lCM{ncRV(XOg=Kx?QD7iUVlB5_uV&neXqTi z*44$!(|zn?xRX6sJo@O=^_}ItAOpj?Z7ZBN-3;?nzeVKXhoQXdt{H!q36Qi0kz?cZ zkmm{HB<9$%(M<^*qu_=XY2D`L+A>;~>B=Q7VbXe)GmmSdTK>G`#ERt1%r)9;rt9Ss zeX%5?^iI>H4^8+ebW%hR_3^ZXIN32|w)dHn;=b{uI5{&kPR}*F`E2V)%adsmNrpZ~ zknqV-);6cp8$OrH+y%#-^?xvD!851HxfeCQav_o z*pRdiyaWx@+5*&^zY6LiE3EWtDYa0W*}heE@DG|`)~VSsCg=)kuxyzd=x|`zO{0Jw z8eJZW^7PPaX@aK!MODBWFFV95WsgUW1=hSG)KunzVkxJi#gwcJ(-~#Z@@Fj!Ws6a2 zH^Zp%A(T^wB^wPeu*w?7b(3^<8%mZ}Bbp^CU@MerXmcx3z1#<7M<3dUPitixikG0W zgw;8VE;0rBMXOzM_@FWQM0HPM~)o9=*S3yfe`a^9Guu9xwopSDxQ<3qoYldoR}rD zt=6~=%E@E)pE{`Kl3FB>HJ>Y;rh}c?aF<+i3BUg@z4Q{=+uJ8xr<(Q21?-s^neC)T zeSIE|9dok#HGp6K@(}ZjG`QxP#r*SZ22B#v`Rw$95pFb`^?p$D8x*WdtHjKRSDwOP6vNoItZC<`a-cm3b z<-*yw7o)p&BII%+_sVOMPJ}lVbnN}e|Iif}eEwO48jb+WCsmL=$Lc{5$6YojyfqUW@z>nxKD`|7&n)1eNnr%glg+ZAuGsuwi8-?>mn)c4K5j3P4zRQA7cOb02)< z(M{00O-FLP$)Yx?6lvLqlt@((RY(H$v|>c9kaXyhBvCnW>R1M54P-@_ala&i>>(?^jpAq9FzBd``_hZdfWwr2Z#?;m_ z35xuth(tGg4x|T1x=)kMuiCP+d4$7kK(p`kJZVWW8G0n~K>EtkviT4<>goCOcIx&_ zd#>Oly3Df$k*#Nd+8x`kdgvi2rb!M$f)EHihAWD;1hWeblAo(+`O zT*EgR@;Q`W{VKwjUyd<{i_3GUClD<1`H29JJoj9jI8G#r`S}w_<>-L}{Ik8Z6wwDC zL`_Z28TH|WdcyA$>ogVQryqIb5xz}@neJ^WAR^M3Aqj$+K+c)np2H)2HP+ux1^|3H#n%+C^bg=()tj*4)FQ4gpi5QS0ZK&On6GanD^xo_AIzE9! z$%2wi7&x2zOavlH7o0lP#s^VOT(aw=2-JqgV|+|0FE8Wzi0KC1%L^~uHtBb?oVB8& zA|u4YLX=ArH6-;w&bc9$2x{U!awc=qtn)eBa?Q+vr*_caKgfxm`Dh2$>>QMqS0fVk zz!i+bpIr&BK9)bh?y`5#001BWNkl>FulB!ia zS>W8DgGN_`r5BF>y+Wmhv3xz&C*~%aY~MJr?`>tM-NLprz9R#S650(*nc5S+QCsZD zW@DjMubRBvaWEk(&xHDmDku4lh+{h{*PI!Nt}m!V9c@#cHsQCEompW1!S!epY{Ycs zY3S`6KzC0cj<=kO@6!^o6>{@Faoe_SJi558tqlRc7cS=*vTahEs;;i)eF71x$$}>7 zXrhuLOKC+5PvFb?*W477Ri_&yQFX-?SMYz!xnvR%i5OU)WXABY4i<|SJv~15Z#Uk1 zuZxY1$6S-u2klY>lC38tgmkgw2vNm2W+5ed+H*3TBP#KKq`st4` z{K}ts@>N4+CF@_+++QNHc;vNL5Mnl7*2c{!m_s7Gsi4oxN742VA;`weQT84M$How0 zerX6!gnT|6D{&&XP>V%5Ms^PrXzv)pn70sqAM;y7tH`HMQxGOLs7_dotKp6V&lg3NnN81S}twP&f>%% zk)m{6Hk%F6>?jB8&V#P`;-hHQ=xhetZ zvPd(y6uq5(>^OBC!H|z_%!x4;BODrvCBj>nWoATv8T1A?R1Q8KyFf0 z0d1KE8Kd@G8;~oJKH_97k;LJ@{_AnyrApdP7uhTTJ|RXEKRhC74#|Gf zT`oo1=$KQxXYYRAk5*Mzpddeet0<-_mzIyxmWY$gxo>T4gH~rk{qm)AjH;ZzTmmgc zK611%PAV3#cZQ;ZhS(TQV_0+ZaZY5{&0}9m*tzp96c!aGmGtgxE|=O=y=7EeQMWaW zySr;~r+9EJrMSCWad&rz;_ihOcbDJ}EyX3cy9MXVGw!|bz2EwgjB!Rra(2$PHP_s8 z{?XJn65Z`}H*ei%mj>u`nz4a4K~y)t2o;@rLIy|u<_fP8THaCY_0*$UEVC&|;b+*& z^gAW0R82uZDS^MsJdS-UHsT@E!4tx43<*!7P4MNz@H%~+7(s!%B3A0T-tNDb)Gs5pXPX;Ph+xZO%m>c#bi}WV$UGI`$gl zIr>s;p#FxU5%8vO^FAO#T2qvSRK$U3go~6Mr33n-Ahe2S$6$;TS2$57PE8Cb*CYra@`RTu0T(KAe7jG&&8My zhfTZwF?FxQ;n%)9S8S>kLIy!^3ofHJd^!yW{{Pqwsbkg{>{GJf`rBu1N`xadV1N9` zVi~h#VPiTVG5M=jrxSmF{9*c9_y^fo#{5v;5o)4|)cHQ0xBYGhu#>H0d@=>4G5Tshg+!-kWyq$ALzPVXd{k)P$21%b; z5r~TQxWE)HJ*}6eis8@Ln|vO#oRE?<+|o?=145RQ%;8esO5}=?fWlf=CX|x_RF18U z!*4=~$E;p7V+{}iw!JDswe$I(ESY4F|0zQ-5b<)!C!)3)Vlia%<~%7wNz0!c=u28s zPa4|f)tqmwBes-tS9ji&>U4_44-v_hFOH2^xG2MOC!sDbm`*o-ReGlnr4Q3!<{POj zTmO8zShK75jAvg8IZOJS>v$;ibmw$}8Lgq{nO=!j;O-#vCg@bEUxOh0xP>n~k%iNM z%jiAgNQf(LjrwJ+{Xs17(;Jsd39aPwZT7wHq+=&Mowjitl6+yx8Qz*#2OmmH!6pmc zY?nrhC|qhe6dnGd>EO@YqNT4==g%y*nsY0F1{!CQG|tN$R63FGy!WN@Ut^Gwkm3=8 z!X$BdwAAGj8Q8XSPSxaP{&q$P^@KQ~LU(GpZt~bJ=HwukZJYDiJ$bf3Uo?D7b8RbpPfbS-IiBbRO_#PjDIjd6od!&254 z&?YYZS6n=vPE4=k-k_~m$~#~qq=-j)$j3oj4^WRGt~ZTUuCz*T1}2OxD;4CMuv8c|Rd&t_i3q(vB!B&Ykz|DNW+xdr%wY`; z{;%kFS9!@+wa5}DtH>c!-g<+Mb!KK_5~LlFFfrwvzs(}bR)9OyNa-FArHMTD7uH>O zn^j~^;36)m>tlZleB%+?K`wKIWMSnXa)9SS2R+slx1_R2M5MM6u#@RRfg3EIv6>uX zXH-FCIz5{XwD3NT^bUeYDj`S0no0K*ugai{;b|z-Fxf8RCrZiB_obO~Gkl;nEb@B_ zq@Vv~T>gF^##s6(S#-)O4?_k@&Sau)RtRn&m~Xpf3_=1@05MZhaek$e<@lP}dFf?kmw7OA4m0K}I+)R=_>%H>sNldOf z8Oc-w8A!VCfL157{A0iDZ;AEhB@L$~jXY;gf|?U)YWV$ouEe;XSWEmKu6$iW^Bm^i zA6TRQPcw=Pi==yDU}EMDEd~o{#}eF4R~ju*4I|=9Dl3ojj*Q`F9H)4cs?u;=)-SR~ zzm`L?6FF51QY$VbwhpjlmEau`jN55IwvHujaL@qsXX9o*Stl?u)}qnEW!j(|O-} zq3{V;Fe&pj#HACZXVK62O@!DLptU;ozdsEF;})Sr=kT8ksL)Deg#rr*NixWmH&2w1 zhR>Mc>9WpYV3at4MB5LO9oGJVFmc?9EVADiloLOG%z%e*8Q)$Hv3pOL-QSPouIrf1 zq)(+|Vx@n0UR`u;_g+b+t=c1fTzIJ@#G61?72r|0t1G1s9D?V!%UFCyi$f0qGNR5~ zB|LH=xY18bnj{#soVo!F9kqewIF6p^sT8*(r1c+X)@u37d@g-)3)VI{+>qP)-;D!~B8NP8GY6lmx3;?~glh(dCd@qx*rRlf92D zF+~-xv9HI7vQ7bX*a!8}6(n)bAm$^Rk48&dnN{C+?Ieb1t%&~NCGQ9L$h+trTe@)V z8Z~^$0ljAg@frAS5PRTbVPR#lbsJ&QY}bDg|IcjjpQsNmDhtr7@hq;QrgC1CG&GqV zZhT%~Y^NHnT_jL+1fGr)Taa)YjNm7-Xf})ZjZE zDY&F+&V#MMeJuEIp$-}yU1j~2-`cP8>mx78;2i8ilU|2e$qMsUVmNDHAc=P@{~n_U%$ z#Wg?ePSNEnYrv+o0-EX&Uol4~|eP`T`di%m?H)_ZxH z->{B^-7CMy1;NaOxi*QjK4p_F30u9y3?=aKO5n55-dqg|KatZdrKW62N1!Z+6kqrH6Gzy8bzkTAy9+~L6*coD%pif{3`^K(}z|6vh zU5K`y?{#xzFJnla_E}oLv`zb&l{N2O0Q&zQAz*3&mumGS%nH;fh|D_CmcE2U2vs8d zjG)RIU5KChK<_u)pX0$N)?F8!*_i%?p{XNbVZtRk2q~R-yoy6yGL*O-0P-UNC2j`j zSiYY&M?Z_1=L2$x02kOmpo2+h8p3z7X8ej*;sb*H1XW zxj8I`rpX?8lyyt4u|NR#IOd?DVVu6m@GB05*M_(8D9#y9uDE!<>EHX0rzb!83m? zyX{&x5`Ld5yedZJFZx-Mb?MeA{8(r#nq=4J1pJZH_>cXD6?h@b@hm&oZaROA)Y%i2 z%f%@i$+FzS0Vi3ErPR_|TFEI!u_8BHxGJHmD{p{9hlR9r^anvhQ#qq?XYnl=1v6ZaDsVfAYX!(_Z4uTU{OZbac|B zMenoG=Df040>oHg-S4u8nB&x*QCs|f!=#wAZu~k=iBMKnZu{OxP_Ra=s#xVWCyy|U zn42rh#G%qEb2^Gec7m{E=dlH%EIE6%fgWt`0vg+zSJ^Qh%UX;FOD5G)27HZdLKr#& zr|?O?PgN#02Lq|l#@*h4#pK>w2$koh!%*We{@H7ycSqgXYLv%)3z6B&o~u{)D<5Bt z{>)_BWWaO8lFRnbg-X_R9OrTclF|UG@Kg~9L)BR*%qWUWON{yUM1lXh?-2KH%0rLM zPwQ?fY8(6n!5fCubBKLm19^DRu*b9<7qc!iwveXTr)}2L)!8LoLZ?&|6O;<`>g>V0*>Zs`w zfxNB{T8OKvg8Ti$=mQ}rYDc&#^Vs;fgrlRQ-br)r{rHBgoa^1{zhhO=IbW1L8U8$6erp6_yyH~is@K+=p-fZJp(H=knp>L zqK=k6F#oks_?d_KD@sG!n*-mp$TOQR7SNOj=cy`uZ9g*30nb)x*05By>ER%B@L1Z# z1)Bk)!g6s*89cZxZflE-a&uceOSPgX-9p!fL~?#?(`r8R&ygR9BGGF(}%hRCOx`#8(<<`;-@BPLgY@@F_9olhUh~0Nw!{cS2V-f=H5i z*yz>2Wp(f7ch&ejk`OcTkc8g}w#vUx!7mNgvlOpe5tln-CmVAbupiIH#!^NNn?bosp{o_(Z7dDUcq4?Nf&vFR{LH?^L>>6S^6RGdFWaHUX-<6 zg@rI3LQJrtlF0Ul$k>SaND>%1IFcx}H8qFxr=+5i%r;gR@(jMU8dOZieLNmJT`#p6 zCdKj99K1xzj$GA!JQ4MJgQwdqCK05w)I|>5w{k&2c*dQF=IvH5R)OnVS33TngZq1? zbW*EcU*!+R_x-4(ZG|9@&+MDs2r15K>8A&l{uiIywr=A1Bucf)G%hTheM%p%6IJ8k zr-Ic`>x?5fM7a?_DxZ5__~RNnHY0b0S!z3rDEglJGF?v5*BX3%(3@|Y<8w2V`d&6E zs&$)C=;(&?)~T#t&NnVi1|vPH71OQ*pj(}m*1B9aBkwDJR|}X^zVYEA!9%2p8gU&* zM|WQSk&rW=v<+Ca3~K2lNLFwMt_LMRyeEaC(_12T6G@K)5PR4VKdZ?>heXKA%gY-` z((7XV$wjgGalOvVi9%wN-ooLUd3b6JGcqXHG7m9Jj7>Mz`&5 zfzIo}idB5&Y;rJ$Zg%=Cj=j6GaD6MNy9B?Xnz(vDhwF>^e=hL8l3#b8M)#-bY^g!# z4?Ot%2!zF~4_Fef$bGS(O^<6jd}yN>xKA zOG9^&6_=tN>}a8{EO%*Tt$Q{2@qt>e%l3F1h`EXw+WvCG`g&yi4(W&ruL943JG~tl zYjYQ)xOE6u93PK@8U*^+XOx>mI+x{$^YZ=G7 zC-jHCXdp~!Y3Z`}yU%jq@vyKNrwhn(jU(ID_-E0dqXwIeeaUQHnvrpgY>uI?}?A*F$w?aPP|{5KJ*|BHx44 z_xuZ1Q4Z#DG3ng<6++W{PK#J z!7ddtK?#jJ26+265ZZpIbAL$RhYj)~TWd*GQ~GJ@-@j(Q1SBo74qx5f z(TjSlv8poIau#|DSiXRAZ~zI32|x=Tpba<8o?9zG0~=xxNatUu#8giTmwxry*uHsrz`kNI6hysFisTabeBA{ZF&fWEZP^eKw#NW zhBjf3*gA~tQ@EL{D^6Ad)SH_F`UUYm^au^_?T9w#-Gox_+iCS`<;jD~XWWlB&|ETw zAgR>9r>9pPk|YvR(kG(Nn)ysj^eNR4yNqzH+|}^e;t>M0zAi+<7QPX%Dl_1({=+Zc zWnHbPxK?9M$9Q>!b8`DB9+LJ}b`jLyFBWS=r`GZWpYSkDr?$5O>Q*ccs(jQU{FN!W z#li_ujKrPPIj$@phV||35MWlI(P}6ptA65Jl3Ugj+cPOXs!DcVer&JVyj)4x@JSb$ zWEOG4oP2LhZ|Y6WM&2Z2SS0~mX-Od=I(4Ccjg{nJmz9%(UBB#!V$*M(`n67I{0?2) zRfBuVf4Ur?-FW>4x$QHA6yv<}w@Q(b6mLJ0pEB5;z?jm5YLI~*W4tPp3RBq>{s>Qh(Bf9L3 zV-y6nHe;Ob-hrqeK;+B}VRuL)A)GDaT2VYuX=!AuYN!PtZn{X7@|rAHN!9Cz824R- zbD#CM=%b{vXZEMwoZCT8m9vnUE5V8A>F`J>`D>(Q?EJo$h45MG9W?ob0BcV@bY^K- zNRiH!zi^=+Sf?^rDW39dlik+EILA`gnKZvL4#Y11_#VOI!Z{fbHudM{kdLM1v2m=U z#bM8VskW3klX(AOm1ksZqL6)NI zIwS`!?RmmltTl+`y^otW5`&;HG<$*TlcE8eFpO@svJxSv0Rc(oUgmh_&rl_coUUh{ zj4MC)bB;;w?(VkomyDx)50&;d+%T)FtU!G~QPc=2Vgowo{T)ffZ1H8iwD}9|)61Dk zQWzojM)6~ zt?G!|FxN#7!+l(7y5Hiw2HMj%CK+^H2%&R?j$atNIxZ@fD-Z>$r$U4FzgDvM;CbJv zGIDgGp+nTf|L|`HKNUy)_-e(#Fi@rIgQU;SyZuWpfBAtLHZKt=hdi+Rw+k&eNQ1M1 z>x5kAY7uXLrwg=y_%bFZ8k&=nQ&wmEzsZldNpZ^Jo;RMnurT*P>A0(_+pdBJQ_jz} zwoEz6lzD|A9_)#|FDX(A;ASPlK{}T>hh-0Ol_b6rRR3M9y$?iyKL~wY7sSnRJv1>8$Pa3~P*PI;D$O(E?wS zZQ2g$Ta;_ml&dbYQ7ZF4=EdG{KfFF{h(x3UyVp1eJ~lg3TGDMOI}to-OWr6%0}g{| z#VRl#c9{3Hoq&I|D79)=LrLp8@(HoxMTlMFDR(G6z_VZxZf z%Si^tx17r;^ig6^7ICeZuvJMJ_F|Bv!)z97-FXy9=1QTe>xz6wovuGAN3MT#k{TXs zAuQtddjFx^YrK6eclA%7T?b8WZslC6w;T=h8WjYz76SwqnTlX|{We)%ikjVYClx-O zm6|U3uB4`>@c|U^s}FT(-_M9&n7za_zua_uUs)BJz};3&bHOYt^Tu^Kau$;;&|0h@ zt~ZmBP_w+2ZYniLdW7|7-EUOpVlt$@bf*hEkK(6GgSNIfGo42 zHi;Pef4BhW#>=u#P<>;qid)qk72{zHOCrb)RT&IZYh{~5rTwYU(~e+5ck>1ON$d+) zSFy&Of!C- zl9LeEp4tHadg$!Ow3)pj-8jDgQ>m8!`89QOyv-IFdA|=Y^y}#1$)N^2WSQSe)UO@T zem|#ncYmq(*f6V1!wC})M-~B8EyRlWJbX{F+6D&72T{#(luo?wAP`cW$ z2*c=BWede%VJC0XB{MnO| z0Ip|rFoZ2(_*{*}i5#7r?FD^oUA`l)9yy{VLalK?D8x~@&f~Hs#xI1|N0gT_l;B;C znjsmxGvYds?cC6C;44U*Qc8JWD-WCwaM>txV^1aLUjtc@lscpLBo=Pox#{%2^V;{h zpz{4BAQFVmxAA$wd@SrTlDKb5+M=xz`g3gA8;Wj`Y` zw-ObQv>p-^P)qnCL_79-BmUm&6-%t61_7RcZWZK<*B5vMx_TS5)VYl?-T~@snV6TS zNQz=R-|cXGc+kGD+-tW#cPek4E-n7Nl@zTny56GA?Mv!Gml4>!_Ng^}{im+n@O~L| zwZ{<@Yz@}g8j$kds!bnj{Mv*ey%?|`f>`edc4Rc)RqVum4m#UFG{Mt+N4&ax$g$_^ z0W0AkeJTdi%V59mmTVs9zl+@07ne|JmV-B?6p@mXWqqA;75Vhv zZ>>`6ZIi>rgI@x!I=Y%Z-)>G_%vc589)RPmEG#um7OM+8E*nVTWJozzbc36ATCGJ- zI&9BKPxdq0N*j-$=oL{$ZuY_AHNES0kKb9>{i^FLu_Qz8{n8D`O(#7?6k+Fe5i5D! zgJ@0BB`Xfgb`Nt3uZ_<9wmkW+aI}{Nn$HYKUvl*SG#4AJ%%qFCTJm2R&UwvQ9~ZaJ z-9z6VOl60uc9fb3T81R+D_t3w=LxSod!c?LeB|9X6V)-j%{I;6FfdQQJPca!Kr0Ia zE0#fdh4uXmgsU*RxJ%S4njSS6xx4DMY%c({by+I~?5g(9%SqiP{lq@-YZ9 zwEc!rdX2Ebok-6QGO&JRl%V5ty8p7KOU_0AKvkN3tNpR|I@6N@yk5rCLrfsZCeD5} zr=%=AI9&b$K9eIoh3~SRrw`O~cjtM&KOOzZvWR$F?#uE_x%4?ZJY4%Fq&wFFG}#N1 zS>(@pS_f8Jo1_Yso~sz=hBfDru=;b7=;cxrvldOj^s^pKI8GZL786% z$GZDJREQ#7sa*9G=n893oF8jj0d|~>jl@mr$&$W3gpIHF_!1LPCM(EX-MfxH#jSk# z${`CfSvok>6*VXDuB)jUy-}1as;U{?a~Zq>MP0~s6vG7xcvHR;^Ev76oO(ajS3;7?2Yca!v#YOV$_AQSGH?zXz6QoZM2Iw0XmH+^6aaX=mu=D}&5Q;=+I)*?3mjb# zvkUb_^YTNg^rv)wCUN%0tu*Q+YT-zedR?(jb_OY*abV8x4A*~Rkh(dkI)4yi`0pO9 zAJH=EQl&$7+VU?SXs@%mGgYmCgpR%+mSMSX>CaIJ@n?L0YHsEUbpEusn}set)ZW>7 zlccM>*EDWToi6`mRIgVfRdLFjTO$&rd$m}?FTsoragG)@9(|irk1bAi?lZ=1o|9RV zs`?R}OTHjPOKD=2pL2RLtuiLVnbYa1>*RMo67~B!ig*+0UKME5TvVXXPwHKtXct$S z4+lszhLD>dnvnp+8m{D!^fyS_k zr>KI`L-Ug(xOfykx5}0||cQ5y|6p>kR|Y+)Hq1>My`) z3AC1ViZQm}q&Lx{Z`SqiZ}1EG!F6Q_GQ=wauj=&A(`4bL zLUzHwnO_8E96vZbJ4BO+uLG}s3q{jf&zS1k;vH-QJ_%0Cdb`6QtR2#v9+CL#@SvcM z$d>du9sY&Ar}xB%0u(f*hA1+4>zV(uT280mAV*7T*iB65m`3hDw1c}s(J;9fntYlz z%p-HYY(`FY9?ke*eaBb}d}T??u;x0f1rm|5A10Brvi-exzWe86FXoPCRLpB&y2cSI z>44Z_I2vNGSPV)85b*ztYrm`zA{sufM-rmcvtP}~Au+sdZ7}zP0Mf>K=A+Zkoxbk? zzPJ}hc6Rpd-b@`7RNUv$hf{Z`Ohc|uPnw~BjUkDy3$9TxuZRqkHiZrE=NG-Pg9+_~ zTbI%C6VPwfLbas+QCNU~U2{}Rt}=(JPV~S(jmpvzDqH){Yj%o$Id9bS&(CF3C>LK` zZlLf4t-1U*h2NbLYVSNf-Q7dOM#!@x(C1k9R=LysB3cX#fm`aDNF7qy!7rcXc{}hz z-%g8O^09W>KnUPbRMt{i;NLb5p{1m}|28poG!hXKpdiIlrcb@;QQ*ZO5j~`N;hGE` zMMI^kr|e{n2rVq66su{k%)n|+N96Q56F(Enfnz}Q6R_nK$jStTh$@$C6Ba0>McUbkntdtLV+<>XNRgOnX<_&G@yEue!`hbaDPuP6u}d0Pu{9Ue+HE?(Hs?o2@Ym(M*2TR$Y_`nYLwke?@4vG(&&)V$#8TN~H(*IJ zs)_GjAOSjXJg0ACNDo=0WKG#rwlFyOt*I`t9-NjjTk=t9LN}=9t#|&dT8>fVKxx_| z?eL-$8AY89g0?hzu@}C|RmSg+ZS-PSL_X3iDj@w*gRRLW?0ziLp>XxemqzL9wGnWe zJaC=7=urug4596A2b%_1iYmEWu2r4Ot5;bXTA*`&dW$U7DyK2sV)VX44YPJZPy@3A z7ZnH?*A2GmxJs*k;+--6bB`@!|3G8U6O3fDo@ggjM?3Gg8KQ^l*R76RHcBY^DP`ot z#XLFbvM5M2Pp*;NZr2VjB{^ZfAUZt3K#YhE;z%T=DMa`0)17!vITPkP zSB8{;P!1+*E5=--x!7dK%mF#K#h1)b&(`JZhOz;uQg&3|2v}x2y#siR8}PssV6=3` zWS|Y?A5n7}6pDm^WF0@$Ute1YbzU8R=ATz761mEto?FonI9lR+A&|lm5h#UbkRN`u zG>d2|5y+OY;0AKBJ=Xp5b$X|lzsn0B{-wYQ`113gnvahUTP@a(8(D5OL*#Od5CMNa#*DPei;ddhw30GJ!xqA%Yea-EXcLg7z!#p=n8$Aycg!B-hOGJSk zED?s_(Xlxgg-K(ahTg>hz0Z1)+?KhP#J+AvipfZ?d-%txUP(Q1EaK^~ywdm#4Os1i zB`X8WE5Mj1H11bZpWp99{x3V^J*z*ZVY~95%$8lmj=oN^JQ|hjA+mi)J?xFAzTTcS zs(b!o6k`_7mHV{kSG_=b@>C=>-!Hf#6Y<(<09a8-NFbXHL~Ekb(Y2)037)plqGDkn z^k^tvcM#Q%!UZ+)ANw=Qq9@2OgG+lB2hq<4{-%x}a=CsX1L1bC_*NOoPM!bfICVU~ zw3+%QJ=xsh?l!iv$?b&Xkq3G-N-8b$CVaXFzIV`J(j2iJ78}L@&moabi)8ytbyR9Q zhJ3|jvbIY2A1Sjs9Z)zj?j!c`%IWjNn$xYIY*%xgju3{USUps5uhMLxfypmXog`^5 zey`rPPPOvzu*HzVOS5MgM@-~Lg&N)dn4TmEwe=BfWvk1?ujnoXGx{uqzv$?LRZ@It z$}t^Qho|B)Y=FLZ06oec-~a1w#l*+mDUU=a50TpJ(Z5?b2VUht%DVRe%kV&RC8F)xV=SQEHT(wm-7{u)!b zIb0;f@G}%m^nYXdN@G0O4rsrBIw*Gj$jrLysNa~J=CBJcUTE~{DBE7|1YhOOt+!WG zSP~ODTdc7E+j#n1P=FWW4Ggq5Y=!AFt_%C+q8NFjFeciAddiOvy; zt9nMp>Mt=_mrl%0R!p>eoa7iT%omiYGLj z4wbU*=?SVWBosUcqV`uT3!O4DqVsJmW*cVR)YNbq8yg?ZW#;i=4S@)itiO3mN`7M$ zvIAmsLe0mf>g9S=(fBigufl<~IHH*WMRg2;AIm+JwKb!4ESYAzPV_|Z%mP#L;>l6r zeJ7@(#U)n_HF=Z6%kM|O^>9PZyf8PALrFeLM;dew z<85BZNVMlM`C5$49B}P#Ow(GA=)b~ly3=AY^Wku`7@G>-O zEb#Tn!GfVVYHa(ncL}LQGNZ8@u!#Vk_H8HM6nlcXFa5_Zpy9YL%J<*nw|ga@`dw0g z+Qwc73m0RwOtwn!yka0p(+D`MMFz92Ifwf7{Lfg|TDYhiy}(G+R#S_Wl1sb^TemE; z7B{YnD(s^iNg!S7HX;x=f$mRhVp3tO$t-T9jIa;xhTu3?w+SR%WJZQaD2)Yu2p4jn zCmDn}`F>yuG*Y`?bhxp8Nco;TZZArN!AZVuHy~2&{+#Z$YvfhsfSCQYVH*Uxdjix6O8 z^s4)_IU5}!T5&71d%8F%%~fmgGTvB zswv?7FZx$0`r{>u-~|!2bc9T-`Ell9l@rwW)9Kf7xQ;vDd$Rk8J}<12LEV2pd-D%< zcN}R?PSIZFQJYlYLY4;*y8(K}l7%{-;*sFX)}PIGvFj8i0yPD{>ZnAEeG8`+nkuZy z%$H`~Sqy-YYs;xGJ#*NLkuh-*EMJ86I&iy>jaabr<=OrrW-IUq_lbEum{Fs&tVk zz1}41yx3?r9AJ#?j z0+$rnjAJY6=JGM0L`85m96dY+$lUD@(%Ok)0}@@YFGZU&DA&Ft9C@5Q5|EKiff3#y zlXFd>!v!oJ9^Me*k0eU5M2OVNRmaT=Si(z<5~2t>7~8Y3-c?6{UXDo3lMXw=ZBfPq z5eYYawf5K!n2E-0sa*paC4h|rW0fVE&!XsbZqIWovHcUhC~re@wP5}v9E}-H1km5= ziZ|5{>c+<1sHhuyINUqG*39p%#SkH(wq_zUA=zTJzvD)h?@lUNMQX^zd*- z-|Yq1|23+w`=geR9K%G%sQZlles_oKFS>t`0{~MG4Kr+Qi>)JGC)ukA$K9*gG-D(( zsDvt;nsPaVNORjejolCuYs1HY&^utzXnk3e_hrRC5m)nRPyYW5TdO~gcQsvMyAb0~ zv!VLpS4;rk7&&CW?wi+8L^a5+Z*|O}^9;>biRo8xFKZ=|YnYesa)@`DG+BF4#&eqq z%4s(nnegb^I@v*zOAyg=S`Gn;xKd`+>S0nUV|x2^njTMhcpqaX?T#*-ZcQuRUf=XL z@}6D|%qI=n_xc+0OZCKSnMWya1`-qoa)dR3Wrc;y5po|yLmBvHBPA-s%;i5_RQh65 zTu6QkxRa~Y^gUZY2y^N!fJ?|nxO{z@ePvVda-pr~WIa6|f%$e8P^9+z(d2K$Kh)@R z!pVxyrXn-C@}jv@U?uCGW1TwL48Hx>r`u`4Bv{y2Yzl(KT?f`WzOAGWrBLZ@q|_qI zqSGeDIFo9Qu*`X@N4bEo^Kqvw4OIbYwK}a^;;a1wR*1*=)oQ5-Xhg{rws*g7bd-Yw z_$>8n3>+VFx(6~}NR6bZ4kst1aakH*NO6`6x?6yfOdd2=c-hbkGZ66L z)xIl`A<_|&#IoTYj?#b29#478k{F}ze6a40hE%!b36kvg=Yt6esMxvvV`@UU+?D`n zeDfg#EK-bSOpgoDJt2^4t{Xh7?VXehxW0;}EwJ@lH+63v?_);LqyR*1wk}+Kg4wMJ zy=-_ARni%^F89Zc<(;ccMx7ROv&w5%x_v%lP>N1bPU>!DZCEoomXwrqig1zxfJdx# zBTZn0?aPv=6qoP3-%sd}Vu*$m=dTJi1K3__ZJu-k0)h6+RThiTx1xQNGzyc@w~mNs zU9HD2KOpKYGv{@`4;o;F)T-)aj2tN%IXvnrJ`bv)I;^*2-x}v8<#zx=Hb0(|gwaQ4Q-)UNoZ=M@h|nlCJoa$bVLMelVo$>?^10tL}8jHkVbzeNvb;iaaOl0`p+4?5bnBfuX% z)AzWNNdMWAesS7`9c|RwIO+rlP;^-={!xv~suUgLU<_9)-{Ekugw1J40qLsDjsJ=H zxL!@`9T;ATQ5G!H@D$B-wPUpmZvY}mg~105NIkYrmf^%x@DWKC;~~SE6{|5naoeuj zAj#OTLY?xY?B$MkU$PX?XezXXOG0by#2D&3dW~^9&!sD5Rfa_B*Yh z8I_fl-#@{FQn?tjFj@V)eXlZ2v^BMLIXVb}A@+ik#yFtc4uy1AE{cM^FgpF%8B{!c3qKh6x zhoJbNFA;Mw_;bJVimy^@2 z4og4L;=goQ_vqFA{R^c*Cg&Q9>t0+C?a3O-{=wNRN*XEghG4E^z}TG+_(~4M$b%*l z{-|@#)flMok7yuhze0V_-iZlrS8W$Fg73Lt4b){7ADHS=)hmg7&&>ZqA%Ifc9&Ffm zRQx~^()A()9jCoxzwRzQp5FcxHPRHQTtCY~N|tmFC*pR1M#*UfTZ>LElqTjgmU!IS zV+1(Ol;Rc0XOot1!4h*AALx$ReAFUDx*975t2VJ2GmlWH*E` z)n&a37aalP|F92Ue%O^1<~+ieei^;rJ21A|*+ld)TGa1>S;R$QTUa<&)l&QC|Do5g zTX7DidkM50RZo9DVSv%CeYC5|HDtP5eO=mWpTw>b)whI<7`NI_!OHr7f{cT@ZyR*ESjs3n;njKWbP9XENN} z-ujxv{r7@V28Qg5T&h6#iebCQ?n3W!dg>S3GbUn20RaJzlg(9j-yv(_;76sUnAVC= zmErt8Zr8wc1mpwj2ydFq(!6rS_0D6%P<4_UCP@CKlW2K_8>c3lAy${CfiYp zQy!g<(So&3JC4{`g?8i+{(zp=XSt|>IZpDZS!WNcY9Kkb=X#PM^$D79+0PT`CL+fZ zpJ25F=#&7?%Ai8W1-F`Iz9t~{{QNw1M)cF$zp~$rCyKpj= z=54rld`*7Qjf`{@saX$24(@;Hum~6by}fESQvZd?3T@u(3#FXnjHq)G;%~cKKpqGC zt1KOv2@s;X`?$32ze!+kWQ%!QiJV155gce9I#=f-+B%C?b3i&iy_6r)ftSqm%4wlR z`KfR{BEh(fW_}4B#e+z8mKaHlAF~~WUBcNLU-V-S3LI)hUGWVwGcn_yU#f00YTV>I z1OAZai9=I0!i-S}k-!S696viynJ~Y8zMMpmsoX@4>|I6M8wYWgZd?2-HTa1WDxD$4 zo+5s^NFY2GwWEUHY$K2sK})-Y&jGWwzK2zPfX-1!R)(i}73_#aE(l$$n0mqz{Ps(S z9!1Vw18=7#{mVuZo<3RtCq%1vgNn?^?a zr&STM4Psj4+&DeP^z4^OgHbbg^xzV+O@bhK5MPKGmv&Y<-0W$+*h&nYdJ8l&0Vca$ zed0tU!iB=UYbR1zamXy#z({L~{BXjr8@+Y;-5S)OJ&;%^V!1b#;(zHn?})n?*hY{w zsJM=RrbH6|^yik#d?cQts){#*CgLq%pjO%?DOy|*tf`%o9!<3~oukX#*(V`OEHtgE~K@u#FjQbSvFaA5)d+GS%_WI3lN zAB7s)=u1x)LL6}daIF?`Xx)(K%K7xQ$f-xu$&Qt%T4U^b!4+0^^ZN513i-|Kr>)oQ z2LH|3zV~gT_g4P#GPPcQUwH8D+TX{zQo~`G$!dObzmJ851qu30m$izmFd9KYLH}4A zg32YETIIf}Y+8{bk2#a!KytN4^ee4&lTEmwJJdh!cD)6I0|k2CG7(Z2+tAj%Qse+I zZhR$I$d?sw2*;Rm=uiJP5qU{uiOlH0!vX2obcJn8@1n<-4mv|@0Re=s%IIfL>WXS# z(nW~`UR3j@jAG6iTFp0X`IiCN*sfkd-rjP>g?=d96By zQbxA!6NkI!9hAaoCU#To=QSdYW(@Lr6l5{2WR~^OqA)lRjWGEzdHl|7f~92&I)=g9 zqR|)}?GNgwx?8du46H?MwMv&F93)S5D(>eR^reW3h`1I^)WtNewF9(Hk|xaY$CXFc5!FI~FB%F25s?<0lxY(^+ zXs8Gr?LR}VgyP_9Zf|d>1pNs1dDVE*@S#Nn5X`hZ=^rjuHeLlFi1y}-l(Wr?#Cv(I zKjG1fy)dY$!?xFSP?qQY+#+Dg^^O$ne82er)#}1bR;Rky#NOJ`xMQ$ritn`vPl+ek z0ak6Bo10hH*T-7VlWco-3L^WS}Xn&!^6SYOoNo3FyI zAiTh>E`4lNBr;+5aLTeo^uWDJ4{;S|s)uv2=#!K0r%-+u7evC|CQ+w4U7l?e5fWX_ zl_JS(w)?(tdyM?e3ibPE%!cVIN8+J||tY zY-|aXWS?nhc4BWuKICyeI?R@>Cmx!He>NTF3X4utqW<&{D?A^LBW!S3+c50c|Ov3uUMJE6-S{wg4Z~f!(uP!U^zp@xyU)BWaz(7$D>=WqY-75(# ze2F+FCPt^(Mm5gX#l^+@xIDAgX9K+H$5A-iQSthEJ9~aXm~mNnuVHmg|3CG9WKuW# z?STla+%@9tX-{Wi&*SSBXX~)XZ!HL%nucU|iS7xIn(pBv#cqz#g{eQA4rXom<4=lX z7}2*F4QAk02y%U|aote+0}5|+m?;jeqK?2ev-Q^%ELQYpY^Q|R6lF=`{fFe zYyTbIJ206D{?vG65=6J7@||u9UG2hqKgti(hYCB`?HIG(zjtDkLmFy*(faceI|hzT zRR8R@b*E->rJmgP*p1)(FH$`5>POBZFwxWa*dQA%qE&=FXkbZm z#CzbM=zG7fBbfL7o-6u%MB9D8s4vpUJ~COQ`2W%MmO*tbP1q<7!8R_z-JKx8o#5^+ z!Ciy9YXZT8ySux)yR&g8xZnML-^t0jx9YARR8ecMwPt!|db*$Pe#X`1|61g5%@lQb z-Y4fARqo{F}L^GTh;W-qkVEaP>ylWL>=Ins{<#=IIH?ckx zyN6Zjitl78YqV>1HOQIDBVw2Lhp#{4=wIdS3c)OUlme?}w3qIArIj7Ysyh`c)CGS+ zwEy2BLNS`R-Fnc186*peJ9i3Fzd`A67R6+TFt)XhidZTtD%zSIc9w8UBKzm(!b8zi z4a%h}GN<9)S8zwNa&mH0<`s*?E)A@hEA6RSoYg;a=`UEN z@r3@5qXPO9H`-@AA!kEb!&_s`Zl60nRER{ZrYq|r=rMV@-COQvKE*BU0X53UZ$6c^ zVJjYceRI=SXEE#1iu-R9WDD0-F!{K-2>&k}|IcL89(5tYkNsyW`#)bBDh~$W9~|gG z(0_#sPWYJ&%XgaHLoo$9;zhqR;pdBz6#_j&ui-m~mr&T+#IrE)mARLJ<)sHY1;x#;_ z;k`08k9H7g+G*Agp&%5;A9U2zTL}NOcP*-Hni5>=MuR+Pjr7o1`k&W<`cVPNZ%>Z_ zM{O@N#2`83YkO4tpPL?7L|j;x?{F5wjJNnX{9Xv$%3pV8<}}YH&}$Dd-|lYoH#*{F z$)XQ`{O6&H&;b?9IpD)rw1?g#`}Iah>;pdk9TKw2Z{8axYFGK@OE`Ix8JkCYILKW;^&uKYtlph-=rGZw z!s&xQ_QU^V3JY@Ng~8Q>+Sh+-uXI7zD)M^K&k%XNq%O|m=V9KAoy^qn3t=w~1}yHe zyehI@y6Z0_E~mb**Hg3J+xW)m*wkY_nZ706UdmG8KUEz$yb}%VP&t2P2KVpBK~HiRb6MnwUeE})8xvLoY#j) zxZ|a%dE7d6v661%SEN{rju_Ycd-fSg}+J@HnU`hV~OF< zG=(GC-8VwQZ~US<-Ia)luUkV%HEBwcnK{51doOw#g?mVZ3CCpWR?-@Tu*yivq>lI= z8q!_pP_C;S{Zzt!`r0WH7o8T?W!t#7(l^=J_~=vaOPr8$Bp3_5Remz${y@{wcrkwf zCCsk}6*@au$yGV}>&(jnuo|+fj#ZzW1Z`#2LyG!bNY(TVnM&8T!ojh(Zu8nPlI9BF z_0{#ClHU+HX7jCo>GmGi9>vv-~w(AKPKuqi81m=$Zq#p=&8n!8j#rK32k7>Q{v~rd0y2+b zeNch)&N>r!Q3}R~uZKg^5HZ&Uc;XtAO^O{iyefnY^wQ9yZ0PDqOj6^rAg5eob-lN~ z|Mmx-+sJDNAfM}h(K04(;G@?Vl~VSsRAXBGRp9dZV)erpv2Tqla~^tFTxwtSf~LEx z`)_J1>4n!`JRi3j&s_UH!5mDsKZsYlmGJr85Yvu~PEk=}xjboEYrZ4gtd%#$5{bJ| z*ssw}(K$Hig`%k$*&*Gc;sgoXQG7mLCgE{G-I(2|Tx38@v(;Y0Fn7sszn5hOj#N9^;NmeTPF1`6mwjTiSJ zX96DX*gEPCUZm}^DA{Y2Z|mTm^zyxr5zMyR%J>M9o1M(g zYeIRxKLrJObO|-Sr_CF&wI)2TaRG>sRRzI<&^}=N`sGF3e0-{zK)}DoYQHwOoa}-B z4`c<>6>%qJ)q~a05b-v#z=4k1fB~=?1vq~d7-@GzQubTs5AgABj(i-Qmk9Jg3du6L zuCNd2EM_g(9?lpcA0;;Nbje-N-HmF-ueEmc$hW{4I>;p8Umbg;5FvKQ zPV+JubH7J_!%{B>I)1YK?hSKsyUq>vrQ@wmI`Fx8GIP&PGuA}S`hHXv^`i|U%5^5R z|I}AUY<(wN&B*cIW2XcAw{}rTs+q|4gpG2BEHR* zrKX_WzYq-q#hO2G_KU^C(TQxBk0Ct-d%)tL&iha9Yy?3_E=O&Iec_&hIA*vN^ej|E)oP+k& z?dSQz@yVmtK>N2_Kq^sdrS1fF2z2C+_ghn^^;e>l;F1mpNncw-Gmh&P%M~LMB0*c+ zvGb7=GYd04V^vJ04KH+mc|PdZeCZ+G_74rtvD-5Ma_BT%3u+dK<# zK)WHtyKYIO)AEPe7$F=x;%%{VBSVI8iFj5c8iivAkmjObY<)13<*re7jIWV^-lQ@{ zof|~(M+3Jk8QE&~5n#kZ3XPnhBxhiDe4iA2nx-eG%oO)m=3t~QiOY1x0>8TNW~zaT z$kEYRG7I&&7AGa;K=Ge&tXdnLM*}QHCMq;Pb&ZcB$sOZ$0-B;< zZFJ;Z_;I^^ee;z^KcB6PB+-4*e&BF6^xnE2H$zeXNp=ul$OQWZn!c%2Ec0MrL`lze z{%J&9wku!am+)hl!wYc8jL2$ZqXRI$Rd@s$U~f5`%CYLU9qoJBcy9GGd$X5qwXTwr zJ%7U-wMh(nR;-S#RFX0Dd3QL@(_OGkt=D1*W%vEb>N&E}qZ1B_FHtk?uQ3%jTIO%; z+T7Y@&6aYZKC&K0{IfV~#(X;~4s0SGhm{=*_01z8Zjhj_vQ`l;%sh6SuTDnAL zhb1Px#z~VE0^|6*NGOO=mL-h|)z>RQ-_G-Xb(6!Y)n?V2C-i>tefy;2;Wv+$Uz7d* ztCvM{2%dz#cI5cUA~A>qfHD_#wBs4=)BOC4Gv(2o!|8H0G})ls=^8xr!Yra}p~cdc zJ0qDykLiuM3I)|QD7q9yfPmik_TBqgYnRKG)83n{{qa9j&nB0}eyydDURtILLWdD9 ziYSO*p5HH?u_4kltB&Sb$mvoIyjTXgUM=)^#RDfA3l8ztoEb+UdxlhnBtVqBY0daM zKy8%d$7-*cAg?f?2i%WW8`!4SAm?xtCFn+eUEmYcg6jvoK)VI}mUbd8+X<-Y{*7L1 zZH>wG-oE_jzZHYSYyNcX3|eD*x7MzseJ@4cj;B_cVI^^U}qN+MLjH>Vi7^wND2#_U2QS zZ2O4Qu)S_AB9d0&sF3F>n2+bZ_WWXkO16cT^7`2ak3t(gVESODQ2&s_*+ue+=*eLa zKtOxuCHa=o=Q&YeyLU3FtAD=zgwFc*&L9v-!KAaa<8XC%M!>XTTLS-AEW#c?KiRKQ zW-TRzH(mMg91*96Hlwpc{{oNpg)%z#MjOn0$9t>IA)Hs}r7>YX_cmgEnS&qt2pRG6 z4ozx{3qVZfKyMbX>1uJi=uMB+tl5cgx{rosHp&vvAqz2DbCS>5qOkS0YPuDZ6I~0^ zboUWuHxf79E=-&>d|!rTv3=4R!`tF38I?uArh@B!oJ<(E%8n+yTPjHN!i()*iOSItpr1r~1B zJ;CywR_kFgtHe#h&(^=Kb&AhQ>aJgG_KL3TwXeLLc$PU5Vw-c+tA`DW}U zHtJBljV@=bd=He>oh!W;aky;T{qp-g?)`y?anTAr?zC#~3iFp$<)DLdYuX%i2>S$CRZ1uD+2+J5 zz0g6c?^Su_w3PDA?k#`)sNuPav&qxrDt{GfaY{sE>aNy<4QBB_ny_46$BtP8Hm%hb zoElOlL?_R7Gpu)Sz6y^Yyq5|P@@|81(Xz7TF59hcVZrj=MoRGknTO-be<>YX-!6u1 z0UAok`vopjUV{iV_`B!6Oqwq>;%K=)IN7?KaohSx3bgvS#$p8XS5HZ z9pF`SbI#us{k4$58{5wKZ3wBq|7Q;*B%ffQZm~=au*wY{aX|d)JDhl;B4S6UaVgQk ze0J7%K#oH`rMtQ?i-Po^Kyq z`@FmCcHD%Fr*^~YYFbPt{<1oz89TOF*Mqf9dFnz@iT<@@3)qV}$6FTkDBn>3eWSw9 ztlMj&{(R9q%9m(2xKRgDPk?cq+58lhp|^e382fitNnW6*jqj&%WS*W$#yi5~{ANwq zU`qnbteoE-v!HL+yzua2ip`#61EN9Z`%KTvz5#3N{4EjOm;SxSrJ6G5#MuaZP#wd2k&AXnIlA&$%iQNrOtW=_AvQd8XC1(b8PBvj z(bllPQquth6uXVr(d)J#evQm;Totx8&Y3MF_C1h2{8`zu`cAu_|1+p^lxX@#QS93ARr;Lr_DWT8G_T!F-`FA*w`xXETC&ts8lzN@19KLjfQlXQ<=mV7SW9R zs}MjXTAd=^GXB1~bS3Qb34cks%}-1QNb}6V|IEa*gv#D}uHO17>0- zCO{g8O%I5%1cW&KeP=}}-e!H%r%2RKxB`Niomj3UZV*qTO&(3TTxNJRfPG^39!`{S z4K_U3^IH4&6b6(qb7BEUD^Lb_(|-2}qi#!(a-rN+`+tmZxaJKHK6@RX->S(-xC-9@ zA!7Pt*tH#ScdUGl@W{Zy*slir=$pc(2V;|!((~Eox~N`+_x?*2i)r$bg;j*TWzN`p zZ2zFj{}VK)lJV~Cz`YSWr%Dd%Bc#R{bX-v#O4kw&7vql9hZ@Hc1r6*la5AD`m4cll zP{CMms`2Ndd{=56MYzH%xwvN?ZFxCiTd1E0pp=oOpL>556Z(C63yKBw%+FwCNDBRDaUN{MSSIGoxs9O&6@h&{xqMr(-mVq$Me|J z=}QiwvaT^XUXTs%LQ%Zb!2-MD{{asEw;x{r;eQ(UnArszgLjkB8KhTO8my;}kUQ<( z|CpyllOTn;>!_J_AoJukw{I&RID=sH0~JDqX3T|xc|I|_sS00WCc!@XW9(KI%}|F5 z6xEN9iJqmzY(oYY*0A1&1kUxJO^7B!xk z%mc1kN#yK*hEMG+RR^yETG-QbIe0k-UjjU4Ft9l z)7DzE6Ey=(^NyFE-bUCFUSL*N7supqI&2TWEz5#02jMg-vb`Hd?~DR;Mh7?^U@=$0 z8!%C5Sw-c-a7sKF6#)(hcORlu9@J5UoHWC4RW}Gu0V6rm3kZ zFwbZh5VEhHE>GNrIjad5Y{bvU(^m{C|YzW_t4} zxZ()-)?!L1IV!?X72%^@c5N19#Rj6?O=WZ4;vm1(L8Ucg9?M#L2X0+_jZMw$=(>wg z(fIj75Xx3)tRqZL_4{H#?)F-(bvo7K^)%%&SUeWeOAt%0ICnU~4(i4BLXi0G-=;W=-IccHTx_V>~3 z6cr{CH+F*9Z{ zsPsWXl|Sa~6&L@b1JS-5PSDY71;ZuC1O_GT{4ctM&+Q0BH{hr|TO#*h!3Vw}Y5J3iJIqhY`__3G32)fc>%(~XG; z`4BR;z#4=F;=q5Q`7U=pP*Go~z~jW5o`)vcmp{bsfl=tY9F5+J!;11J7hq4TsTK0~ z6QT*>a_Ex>c9Q@*7|F3$p7my=m#=MTOpHhnH9@#E$IeavN0o3Dg%m3idftHXFM(Sa zvtZs6Lio$|1lnveD75nmAA%KzOya(fGgF(!!HHH4VR-qNH&;W{V$cA zH6xKVgH<;>A@&_yvU+5_87v4WYJ&c^lf3S#&A0FK+J+ajEB zkUmgQ3&|`1HN^cy=X${x0)+OHGPTK1U!_cufu~Vla{aO=WvjjHlb?VH3Vc3nhZ0qJ z+*-a}Rp_=7Z{Hy30^xGDv$( z3F%?zFi1*F=Y!LEMsqUhG1MUE_#tNTbMid0Lf`n{sk3;53a?FSzs zq$TyU{)pHl_fA26E^sIc(VO3yz?dnBN9f`7grVBl|f;*yE5U(zp!&T2wGeDmbkZR8pzK0}*@T}6ON6f|uZcm@VdHJC3aqZ_76#S2G^5MMoLQ7_|#f7eIY zJZ5M}l0WW0Ce2XvLV1^iNFaFOcc-h13%Q1G6Wwwli$0lPKZa8aa@yMPL7Zw{=V}~9 zzuMdR*gwjqS&)#BsF%%JR~sBW!k>Prl*nqu+jw}R*J~NX7I`u!!GQm~{M+(y$WQkJo=goAkq0i zP=rdpqeEy=N03=52T)eTs*y2s*b3a-?tI7av&)!4Z8|}o>pNDAD-qW0r5;P$2j81d zEkg>qUJ}@DtX5AQM)J>|NPbyk2iX(N$@O+TjiAEhj%IHkxSJ2+n{Z}bd62)I6crY+ z@AwVFjPL-Ur2!Q84(AIY#i*$U@L87>8G&CprJR>8&|X18to=3QbTF|OI7ILF{}$|-HNemx+5I|22vq7$IOxj3 z{eysjAU-Y*tXO5_J_`dr*ee#eFk7)73gSYkK__K=q!2mslLmqQ8vAE>n6Q0_7_)b>6j-xl{nTaMP*7q3&RnlGzNt=)F@9agSzh1P zqxABy%0IXAoI6$&};F!+!J?7}D0te%4CHQ9~F~({y9~auTVunmo)^v}a zE`)WYgvp!7Om z4Kja(*?3AZ8)T6+4q-wZsB#x^bt2fExpdd@JU6m&5h{m7l)$Hd)(+4-k5QP1wF_d+lt6Wqsi388)c^xvv72BXJ~jEXKFGVo#);+sj||}j?@3IZxe^?LI({R^gnS>1An05L{50>R zDkTs!2)(8B_5uIxR5=*}+`r~kD2l& zB}fVj5o#<|hR_olLe^-+$>Dv4+acxbCqo-#We(Bv984y73cfj|lrE_gtvaKX@C1jd z?SV4d07YtTV9pZ=WPxB;!OZ!+B<1Baji@OvqMY^Zc+(;rAILaPXV)>axk{ z!;3P8C$4{lj80r%j{F0dXw5{$H;&PvwJk!l2nV;*?#WW0F8Kr9s?ZFsDyKkNa`1aZ zxPdI5UWGOuf&Qn+86oE)$OP9r`}<+Rol1R?B!Q1VV1h_D^k-`;G5_w` zBzY3f-1hW|!v^dh71h*S`yZho!21@NtJF=xnDkS<+IH|KzN+Pv4S-2F@x8sx8F2CF zcnh|V?kZTWqcRgC5?ZpDCA_8S)1KPH${2qBOBv^2t0Qk47Y);vTGz@CP#*ZgsfoY`t{SQ8Q=2Nuxvd( zB*cTPv15>Vk8pv1!A1kJv5Gj1PbYg%AFbi1LR2y*UgBo?zzn9q7OamJb3r>hqR61A zleTUUJU>q@zEUw9S~Wr&src48ww1#+lfcfBIDu=8YV*DSbrYCObd30ou9Jdh4Pw9k zYXp&;rZ$J<0=Cw@;USP9DyW#&Hf_PcxSfo5eU0Y79_)~;)a7aIq*j4kMnqSaAU_cc zUYT_9sryg^$TKCQpnwJubgJuAH^u^tjEqolQ0)63TXx2oVnGbHXl1X1L4?`|^`(&X z&sV;)_g&1ygk<_@5#XG4Z=x@E15&3O#=;Nk7eF67!TGbX`GyFE_*TFL;#%O)BvJom zF$>&z`1~7yB}ImsmNr1GbdP9paZ%qiJO&d3!(j3kpQN1J!0B==Dk^GsX4@Be`2*OL zgi)qU(f>cRqw|C>MnvR)iAbaOpF7a7{5q80cFx_6#Gx!tDs?W9%$UKb06SUYhyYFo z9gkK%zWg#M7phnT<2XFwv&5{9?!N{KC`sqgaVr@*(DO6#nx?H>yRu!Y^N}Q91NLag za=5gZDGG8*=o_TS_S))Miy9_XwOg;8wO&$Kn-<&C#xo)*#G1h-=uU7o;S(q`^L=u| zdr-n*;}P=RdK&Aj;= zZ8R98y~B0BG%!$*Y&0tbK@R?1;iAYcB_$(eb4+pwf}A9REQ;UGows$8_j-)2^~AU1 z?dch(zI!rp^PWf{sAhZ}>n;l=+j(1Y;r; zBcFIW*E@UvI(@>#pJEI~+Zioqwzm4Er8qf#i{Cqt?=#t#?+Q9PQ4taFH+Ofx?!7#Y z5ZXb5^M5bzm9hXmOaF;qbm+@TraNg#-nLQL-(xHmt}=gX$^p&!0XK{wh7~(j^xB^r1VSP z97RM#1g!h`^z)~trB(aB`;bMZg#B|J&fcXIJLssYnp%$}#lpqc{EdGMo3Q6hlD6vvyA$5_O;R1o{ArtWLm6SCRoNml ztzIQIR-|cJlF*-9qRzu?RPM%u9!R-LT3Qhx#$l%xwfD{EP|L0NJNduAN}ZG`j(B-_ zahl*_+-SwM8FwkXHIt(kT!PkE^Ot!qU>CnszZ%;SeLp=RsSQ zV(IF06&DD+X)4R+{u4?GNx^Y!-}VdZt^YndiBD!$2vhOTqWYN-Sn_95v`<%#=hl{|=Mb2;A!zA&0U>2ei)3 zSV88nxSKDOb-mln5Un5%JxFiR$y?jo+f}Qf$j`-x2vDs(vi2*oRM64m*YN}-gnG8kbwEskfr!hZa?QTEbxJJZ>-M%;#wo>Ih>X#N#2yoBsRcJBs_0HTiL9y=@te045}(EJGIb&RT3CEo!ZZ-m_-nwa)lY94*7Ipz z!#*01`yPXMVIi{Nta7Km({=y>Q*W2i(O^FSQS_rfkhtaK&hS}TpvM^2t`Fc_^)Va~ zAN`MLGWy_Np@W=C30^F?9e0bWarLydPr`tpQhWvGcCcklO%Z?sxR`34Z_rJhW%6yA zDW5sLG&A%Hcs0Tmp+H6IjQ2`@M;5N{>hU=O|Giy~TLbQ-x20l-DTB{@mxoFFox~dJ zdZf&vy)nC<}>um5_2##CBEkxI~(`p}20d!$ees$VaMac z4~L-02Qqk_7X91JODp|uw?pI9cg6cQkHY_`pfG;vsIF?NHI9W7u5jvzOHt9TliL_B zIe9STU}3VDX~-T+NpKT3;edd<20i=>Rx%1Tp&-=Yx|?|pH3skc==!UHPmXXA9F3q7 z^in#ow44~DJ%%DWe!pnnC8RMZWC9yePfxNK^~IdBLU7Nwlarp{zsZ9;z!7~<1GXD5<27{Z_>%bcmL%1h(nWun3TIokRKmq_NGE?Mw95*G zLnM_*+3CC<_pP0p6=BeQ5}mj_pzn$Hlqo%G)QBwJz@fVUDUzTm8_=zXN1lmfdqUWD zSH1~s&v`8>weCVq0?2Z1M0y_dbrJCTttSfM-^li#NfVgU&b~t*ita67S6>UBZmzgS*FtH(am{Y`VB!$C#&2;zTBF3|h=c~=9h7IWnmk%#l!)qA zJvhcJ_lbSX+EI&NjjI|M>#}aTP({f-w@`UV*fD^?W(A~FM_PT~Jms71FdSvqwKg3R zI;xOiwJ3%-5X#;@*QsCv+h>IHcAM&-&96^RYN3dsw5usit6BoT~OQm1CutgOkCeL^O;9xN6KySGI=ukP?NG<;4nl9O@#>?UEXzj>p(e)@)z z2?u3GJH0f6h?3Rs zqfhsC1w{n6lhb*yZJrAC-gq$_%~^Sqy=w`iXRSx?bK`u6MSKyl_r5_C$_0Y%ZUE%D zmF=`dh<59c<+Y%h`#W=e5uBahFGcP?RF-I!0rrfE(tj5eB;(=TSM2X4w1-z8%x$kT zUF85B1>{XImH_GRL4w3!jjJ~J4C2gl0e3NS2|qb=3JPEpzeL8zZ}$Uy9vMLeY%Er9 z@a}vh&c!NtX-cd~5#=CBg&Sx*uRHD7@I{dMHb%PEwU+^lD zF@kp&%Bf3idm>NpE}QGD^Cp{-7W4G|iw94pRvQ4>o|_VT)uj&BEr_1Wwl8PRQYP<~ zNFDZ?5Z{mWd$cF{L+=d+_Q?2rB%j+Roy%2X+KJA4Vjx|0?lRv)L*eV@?cQ15-1NCQ z5LXJP^=lDUH?>1M30+7W&&wb7e>00N$y^45C8=(XO@ZpPN2-n2Ip#bIh#ejs$HHz5 z24aast%hsO$26jv-@OEEB~ge8H~q`CEm5U10+*erz{w3tH< zey29t?AChOk$;xw!QQI|w(4iVYM#?6Pft(#L&72(Oy`IV6nMnP$AjjEps6W^p7*UP zKCk=KA&=Js^UluBC5Qt62!bHR&whz}9mH#TryT?btdNAo5fkUZMhAoC8KAV%1{|_` zGJoPWOrVSPTj#)(-Y+0y9N@l*I}fDxc#VBn5s}Z)@TA-Mxb~V+xix(;CUzHxeW7CfNbB zl+6C1F!~-M@Umm!busB_IESfLxD9UXy;7e8%P`v+R7r17_UWU&*ks>aziiW8%B_9W z%|mW;LpkPIjF-mOuR9Gr9XlAmDAWzl2NHm!`Q+VjMW8)wv{H91^Knhx?(q)RZL3wl_oKX>%s_^K2YPV) z%7uO2r2n6FdB}E}gM@$L$d-GxUO6F9zG=zQ4SdRDbdr%l+@HumXkE88K|fg@03A`= zo7DMY+N8tCd)Wn9R9eagF}V3K!1+I*m~2YNT^)w_F+1c2(OA(+NHSmp0wvG~-|kq@ zCJ^b@7*`*~SDhx<$mEEl(l?~Z2_GErL)<~surCoJyij3gZ4cJuq^#$9UKh>J%sdm( z=Ix{V!WyFNJ02U|Oum``mNOFGMjj&E3|03F&&eJamUAp@Hq`h?qV9X!7RbE?TW437 z+>Wn29Q;?T5P-HI--V9rw!UqwjTpfT3HL|0=j!}NunpI5m)eC<3RMX6(Ov#T_=ABU zI#yWh7hMpK;Xl`5j_Wii-&E6ozKoRH_V7iGZ&l-HvueV!z6W@PQ`!6MrZPG_+zpHs zux;A_1?xfe_RLlb^w#Swm~Lwhu;CCvs^eqD3`gVqp`2iSU1Vv z<1_U9>c)meDuC%4y7r#B$)|kvTK1#C2>7jQ_M%$bsh=D!%p$@&Wlw*kTVAUzCGVnq6z*&mObQFt;Qcc69hO_-du)0+5fCh43ey8Vu1>9L1et9>?d!83I8mle`INzH z>$`4Oyf+bbc+Zd0RZQ&2g&OdCjPGuh(}i{UhMtVf8Csx zBAq&aV=+Y(_+W8-r<{Q+`-2;9=YqHO!yEqB+i<7$^)vJDF+yk}T0cl4;6;VRnQ??A zVxt1b<(kl);(oH=Do#5bJdnr3-Mh!dX@Rt`K%l`WW|QkzD4fCA>rL{s~_L1$y-q?-)=RXPaR3-H6x8bdEXXDtfAYoFNVkq+KNNPoNoqp zzHHwgj=|_y;vzS~c^{~LIOL8Zu=5Ujvi-1q=#No0xV@yBoXHO!-rY|9xdxADvCnX| zbaE@J_QK3M_KVO=-D4B4=jBDu2W@xceIGe1sur)oDYcI=vd?~W*z%$!S}~B?Zbqd_ zVXzme!Ko|i4o&WC8!MUH2|B_+)XIu3hJYsoR6hqy zRM%sf(C6XvTgBo*Nsxh)#DWs7y<5ro#O4(My(deu#wCD#R9u{^(+oLLcDIp_;ystwPGLEO;w@nDxF#?8u!1pvjnCuPEHmW{&jn?R#K%RCWU~DCYp@Bx< zj&SO=;jO@2sOt7cUJ7lpv)tHg0Z`~fLcffkmf+8g1mK!1&iv=oKSTA9Tz0Pl)Bg_&xQgw{HYBGslU zgo@aV6y@xv!;2*MM=c%{?@jpKW;AApJ+(R8qn>Vp#KR$3(dCx)xC7p(x^IyzR8KfL z{0CjY)tD?F%g>Z-_WxoQNyM|cvHT^+AZ=7epQ~oCp|K>`99mt|Sp=6)k#BBegX^H9 z2# z3jiq!1_}m+q!Qd$^vkhprkxV2iq|^A+uG436f<_y^3EKDp>z1naRxhc z@zWfk!9i6S_QC)q|FsYrZeD?mBT>LFKPXA~7|x>dX>Z0%3TL@@x%p}zmd!FhS>j$S z*ABwrpWKWAG3nH{rX`5_*SH0OdI@1P6{9?crQQ{pOdWC%#l^oa1ba74^0vb}q3S(7 z*;RcV6-xN!YztoTJVWrXmV`xSr(kC@J-F0tMi8^R8Q#Q97xFgnN7siP8aXJ!#Pnv! z}#(}j=S#o|MBj1cNs^zu7Y!t)|#Hr zTjh_RXOcSD#Y>x24*h{9GR^y6WpIDD0cy>c6UZP?>6Ppw@QC|l%7230scqQqN2_YhFi)1-VKxM>AE5YL7C1Rad@4uMfUTbN32lNFZ2cr6upAYLbW@-T!{I!s{+r##hnetm2f?1^qHlO&aOl1WV zX5m|>q6WU7XFoz;zp2LGJt7bS~0+RIxjBs`SGjwp18kj ze1^bG9Exx!s^ruOpD*@1nSD~rpa~mk!G6EqX!je=d*=hxbG4W&0rsiVQ;V)mBc7Bga;5RxgGCDigSyhGr@abxd z^03p0?@duovQ28ioP4L2Fn(JxfSF6E-iRF8)oh7S;|O|cBk}&y}tW)-K;Q+m;t_G#i-7XLHuN1y^FxsABmxe zi9d*8606%&f{>Q;Tu@b&EGSQBm;N21Ljeb=u^kz9VR%!sS(N7(-7}?O5KIq`}|g;%8Q~xa-t=P4a{w+Z$~xH;R=&sED?){Et>BXI&On9?xNF_Z4?@VNukS3P+I zB;9!te)KnHxUgAwW_Tz0G#D&XNe=WkiN$dN?I_UTB$|Y;IU?&QpGU3~Ras{$u1MW1 zX#@P#$kn}re#bzEx$tb&yKcMR+FHBse7gx*4|n&aQqhM@1=Q!3k$^*6aAp%XW2$;` zY-M0elY}i2=W~V`$V1aMq)boaMbo56$DI*+0l}d3p%e; zY-q>2awFDIjJacpiTNs3BWfa(1*R+cB2c^+r#6%g5oz!N4r+=M(#4M4qs4)@U7EY&LWp9ftbU1R%E{8sb(W4k&Qab z!GZi%>8yX)Ip9j&+uJI05O%cSzOoYilN2GPOe>!J+Aj!m$ z-sgRahyC_NZXvwayIja_f7&vX2hmTK?x%tqju*a<57UYC4F zy_bQGrza0GK9`?ZBvy7_9ux@C5MOO}q6+W_8=-~PC{r^jr1n!RAca%KdI}uy2!{u+ z!C?>R7vJJqYNYv90vjVnOdiW`k8f@#CNk|hblnliWrs+*9Waj<`XY?_-tmuzkIH+DVbTeCx$b3U=R7Up@=liNd;Zh$~m>=(fWawauiS2juy8GEfHgN3%} zOU=6-`@n{ZC{(N&)xd=aJXrz3m?fcFL^p5)jzLhlQq7imp<`q~Q zD=`T-*1lv>dU~kSCy8AGOK)5a=600ppZnk(;M6){&@6lA$LE5jlfmgrlDn19jBmTn z-KR1A-q%LrubThHF`^|vQlk$irTofuncy!2eb(lYk+|u%s*;=Z5we8mI+WLQr0D!h;Gr z3sI(;9(4`iXD(+;`YhP9H8x?Fhl?&*wT0-gBQd~+KJza1m{eN2>fZ#(vVp3h{}HF@jjD6Y3!C`k#C!EBV>o^>#lt~V6Wu~H@&ycNKz zJLjxjW@b*js^<=b++8q4qW?yHseI%5NYGi3wX;gNRx)O5(b zZpG$re5}|^vZQIr?&NmN%Z~x*Z=H_MrH0dDwmBu&87rQ!Du`qI-6~K{?p#bpG(zx3 zO(=SfMGoU{&-(a^BS_|>A4f)+a* zQ^1%$qPeLF_P#tN%@PQAyYC7torxEu;%Q*BqI+k7~?{XFC;$2+5Cj4quyBin5m8^mw&V4_$&ZMo z4kWNHGW270=hPdW*2QR)OXk$4*!U4U&Dx93-h1mg?eeccAS zr`~a{mqfSX=900#8dgi$IDz}ZCa3KWCZ?vOl$3qc{b)o)0yBsAQ^$+?A=Q%~YwPM_ zxfs~lQDA-{eJb-65Iw(k+Z{(3N}|*Xfxt8*qxd5K zGB5hgKZ>YO9t$AzhPc z>V4)jli-sanh&d93Rig*nbqeD9@xIEzPrQu&-0kRewS3Y>I$XnJy$!=b;xyX%J(r| z{WK<~YX@!S1h^0T@uqn6^z;(GHW?%_KP3A1!GrlKJul6GJTCAh>J=OZHirZpYHDiu z1ROlT*uW}?WA}#t58?j+_g?a2jdiAy6Z6udp^(OROkcJmX8v^I(&X@qP@k>(%Qdo5 z>pq02rWzVcY&E*d=j%7cxya3{Iv<@b_OR_(P!5_mb0zu`O5x;CGfakaXYzPuGYtu%cXh6tI}W|sV&lDV z%>;KAz=o87(`8+F(7|r~f#+3#rH|3iP(7m8lb=Yzs}J1FDSR>|VL*wGkRI#r8cSUR zxp%N`aUP4`4~q=D7D+i-3x-V`k4e5d317It;CX@-ME^xrF4*Ind^?8w%i~Y+k95w|6{V_sVv{yy@|2Fp(_)|8OP2rtp!A3~?#y5NA>He^*X#)tYXdpUiXtOYXEgtT(p`wb zC|z9m=3CJJMd{R0PBUqnp(3Ozs!1dqGmzdPP-b~|;RyG1QPSd))=>Cq;${6NF@nr5 zMYoaXlvecXbSI_yr=rIvWz;1$Vi^kF)>RM_%9Rd!94s5Ech$V^VM(q#;W>k+mnSb_|v(J``2@PHZ zEl6VR7CNrq7G$bQA3}>Y>fC^)5392)Lkrg8 z*42)nn=TI&@!qXe8A)O;HL;K&+rko_h!I9Xkn7@*L$>H)eHc_KrwB+76fuCNbz9L% z+*ffeQN5Iu+rgS!~VU{_xbX2!XhGD zgH*$ivQFa`T#iYQT8TMQK{Jq_#LHlyDka@x{muiuT(Dp8^xL0y9R$uKm(H89Jb1JZ zzxWC*4{0pEnVN!>7waIbfd=qj!!7BoiErfyuGev{^xyj3^CZ8l%VW+-`pf(kDKfAx z1BU8FjR=tl2pT@~rsT1Ut>yq8UY-DS$o{BOT*(?~=ISUA3x?OY#spM9M2d)C8O)oq zqFg}K-fXNNwTQm8eMu;l5r>4jW+MTLr29s&U|Y~!g+R1+xo*I3JVSV-U-Fv#LJJ@b zAaNvDe6V~ z+iUIAE>w4qaJlOV#o~QMe{#lt%Ef@rmRyX)Rb)iXAmrR8I=?Js)%0=T;@iNKOw=n_ zEdKM?^tFgRww)@y4h?0vI)Ho9M#uU>;{B*cE02XTe_}2>0wvh7!xk81;rL3#c0wzc zbH%9%FNAnca!{ANtt8Vk&iqgtIpces?cR)xuW7+L^U@V-gL=Fwl7E*&OQM z^A0wk5*`E^`U{B+IfAF-A*N1jCMv1UB1HGbeB+w!(C~fRYQO~lWylmbVphY^7qqgX zcbtywuNX)jYEXakxiCN}H&@Vt4hAGtwV?mCYk*@WO|M*pmnuwUAjs1ClVGG3|{vWAttn*bwqUR60G^b ziw+5oVmhH|85LZ15X^uC($(i;_yY(N+ZYNF%)n1R*nyjN#|sIRQ!*@0we^|naJluy zta=SEA09>0R=&yiA03`_g5z6wiDhQ#;?*p#N*+Z12c1ZhIk5omX2TIdx9y&G{FL8% zjJB)sDz!!`Q^W?G2Dos*;AFnWoFHv@duPXLw@jk1YUNhA+tB2D*e6Wd8*}_a2*cL$ zs?`AwwO#}Nj=5PJwwYBKFGbA&iYWLfN~sI#k}$Dv-D&8d+?tGr_UE%q(|D10d+V^? zYf)Mu4}Omo8hp$cgQ%QK6OK}|nPrUgbJ2Tu@I4B9T)(SN?C#jpN+}?M0R;X30Ens2*Pv52uMUkdrkTd&lR$3pH$Xi7^3BNMsz*a? zsMjzcI4iuY0TvFejsdornmAFfL~uzyt4NfoOZ1OE63Z?zx^_O;m**{ilBL@?jXD#W z{65QFO!U3EU?{@GHRfci(06qBmdZ%X)=fC6<;ql-WGrfdrO9h$>H>WUj3W|Z{bA+g zy<93vAwL^u$rQYa*-vNP~wOr6tL)%oSkoj`aGGl;i6#%5-gx&VTAwNske2R35@9B8*aF9!<=c0 znFQzwR~m6r_T84j?1i%OqQi90R^ax8-bufWSNlPH+V%kbyg?`Nv4Jo{@^($b9eT&t zj)f-JWxT4R>vITq45R`dz;3U;IF6QBYU%Hi#L&V zmN%X~K42S`ayk0chZT7c0h`U+D4vg-aK!7I zpq5xyAy9L}Vl-&wbNR$u%RoEaP01!nW_nMu`KNEY|^80N2&J{7$ZOj2b2Zf%UoqAz4^cyWU8TkV0E%(dE*u3&W%7IC6#Pnh$*-+-dM-f6ubv;_k0?bK(XHct=^;Q zJM67tp`-^N$bQwi+k4{kE&qzn@-1jFtIHHQhz941?nmp>(B1s^0~cZ4R(ND&OWLs; zx15GDp3n?KSs;~yo8ax0(APJe)dYqT0zO;Rs9!$kl$HJQ#EL9aIBfA*SXsje^LEh{ z(!R!ogbXA;j6e=ozfq=!rxs2zIi`lm{vce2pjbOg%AB2n*oD6Aid_;H!0UxT}U)J*b8M{BgFfFFozJ`>q zZdt%0H6jO!h>Pp)3Pq9t)|;Q|fnzLjxLj%`FqDZ1*fmxrm;~E@e95R4NUh6mOvE=% zZ;JPV$?ofnSFNF+_H0Umd9AR4d3vqV57xpd%MjtB6@%%ZM^D>HBz?=7=WKiBbs-ML8d&_*aceRm|A&Xr3Kd@3Es`2pP~-00^! zXEqL<=!2O-DG(p3{*&F~c9C4+5eiv=$~T47$dc2aV*UD=UFXsz@rj%;%2!(^zMy`A zj>P7ph{0Ilw#B$$Mk3)OU-ul6-cXG+;{G@+!&_@cLuDwmq`;~9S%a1B*^O$j8C{BI zXY`9`l}sCtv_Ur0=J&6u`31wnh4G0}OIYuu-(59W2aYdgzd% zqK&JLR_M5_v?o;Y#I8_k0_zlVj4vFlM|(fBE?1`Cv|LtR1pXfAVYcyi!ohFSnpk(s z&L>sU)+hZoVxMhss+8mkX}FF~-LQSAkx$Pv?@Oc)_g6zrm@hS;0JE}Dy;{#VMF+A{ zqC$fq`}0zTl0Ua)S4mIsP^73xA7b7^^+6QgD;*56BwtTrimWPOKYj`lh!8m|<=p0# z)8HzdkRJHJ7X|iNYTa+L^O~W(Uz)IaV_nEBlngH1g{N3^WtLM^?jcrAQewr+U1TFK zEe_A~T>ES0yw(t9V+X?Ox8XUS4f(6foAL0@%?jChtIU7#lrAfShvhhDM-NZw&X7;~~D034kX#vw2*;J_8I-tz$3bJN7K|Xy*gmnoMQyjeM!9 z;fHo~Bh3|Yg9kNNp5(O_axK6rdqCR=J@ic#eD;fIwys)ETz^?boY)M8UIvVEjJ(^8&8wQq_ zCZe+cxW;El#h6JYMND`7#hk8~wLdi5_NfFU>FY#t*78d!5 ze|y|^VqW}06T$-x{`s&Pt3dk(4PSdXA^T@`_|ehnnVC@C<~S1j(O~NI7~78{VT=tv^)lj1W=>6S|q>mp5!{@xAmhS!ZsD z%|73T`>nX5G&~XUGp)jsx(QHL_&~o@^}rt8zxTub8Z%7rWvxoJ=F=M9>gl&^hYi&UazW$H7_wqp0m9EWYidId;5NHa!Dn4v~f~$GT4fDSv0$y zi2V;%h{n9qv#VS z!Ph;jQ(aShFavt6(LDaN36lPt^KCfnc1HZuNoq7q`vT}w3F7w%Nwq>uVpacp3AvKL zxd7-gb|ZaPE-)y)!TGkd!rSo0ZNK+(xswy1tA?-I?55buw}QOyM{Fop-5G0RNCQs&SC_p zaaS$X&shj8@t*|{ST9-wdI1y#(i;#CWv<6&Ox|KL7T} zoRVLl(oNv0_RDJYC#uG(EDik_kMZYH)z-hgO-yD%`c{ zfK+@uF8K`%NEA|Ka8^B21W{xZg>d{{2WqIR}yR1Ag(t zN2XspA|@dLZtO%SbG+vxRNzs)Rd!jXEUo^l{8oQG-gYn z!wn;JQ!DZAwMJE#D5D_6r&Kwv_uoqTja3OS>H2rUso97)X1BIK&B1ecYM9>DVJwDe z*}Ky(#7-MMOd#tJ+cR^F{9?_Qqda!5Pj>=rCZRClSXnl{pd{LNeDUWX;7qpbZKHpQDS1)oNdPmd%{w0P{2yD=UWFKgvmBhOj2YBRN6z}a zf+BR9tc$Q5wdKnd-THG-y;lbp%};pouH$Eu-P(ZxYH|;JJ3uG8S+g0Eh^JMmSqNGGka;k*y!}AigY{e37E+KW zji&PHde<-t;%LW>?F(D?ZbnSWX)7}K!r9rcQ=V_@vp~VF%N@%x@1L>m)$p}MUHMO{ zh1QqC7Oo@2p_oJ`4guxc<&X$^^4OPcvW@ZMqmEg#+#0EcH$*Q*g!HgY_ z>IK9oPK-S#TF|@%V9owf4o@F0AZ>8W&Px3HhQw+8NvGICRh7ZoTtsUy84ZZ zeTR&{ROS%Nakgd|HjJ&=?v!eVk6*`{!Uj$x8=gc6#(DM$ml|CYJB@=dwymDEfR-E4nPGCqdcT+FIP}D%T*A^h+H% zIk~wO&zdUX&4cNZ_%C0~ZRRvIH6y`U2A%5;$T29;kaLxW!HyJvAuW$KI60r79j_le zDN*dh2Sf^KAUNW360mrTf78;v--S}Y0`;CkI39~!1043#BjBb8CkemT8!)?Np!TetxfFu zdV5ivr}wW|up{5^<9K<#f-5oO9UC{3<}K+26BFcD?g$-ZzR9uaK|MG)$draBL-qHO zbI(CalfoZ9d{9(YW}O*&RbXWJ%EMelVyjGJR@;&yuZwRIfP*RfM@M4z_NV_Rm;%q) zPyTmZG9IO35!F5qJRCT?*nd$T7qU$a)R=P?2Gsuq^@W0)4fUe9hpsx9qvp;n!4LK8 z9@d+dPk8gcQ$Bt6ZEi zzhkfH3Hy&&WrKURjJ?d_!e*mW3fA+l&me{aE^AXW!2k1eV5Xp}t84TCpPM4*!h)Id zTUvbjhJ;5045ezQbiBcgmZ&XZ?5un4f(^$9>5>IO%;T0~&hMuw3CS>DsEm@_kA%&A zu|5d$1!x`X7Pik~e~!3Y@=W0*1-czFtrpCM&3xqnQlCg{BzQ{2Rd@T^A;XO7wF;oUO7U}t`kn8q=7NUAtj z!bQC2^yb~o0pwPJSch$Wx}Rk>(Mwhb z=D>S}JD04@x9-_LP~lLgvJ0BMm%wSzzf*Ya89qcsOJz^8e&yX*G0iify zHaP&$jwOH4Moc@y_Dtmv#I`|`@$lW2J7W~Mcc(T%>ih3;Hu&k`M;*geonD)t>+8Q@ zl-u8N6E%8cm8YgL|Fm_kTFXa#ye+`QwN=BtPMrJt*QtpZ_0n3KOWojF-o5K_t*r+S z%t499p~rV$0e5m5KfDAHa;d!slX9`voyM(taNHQZEB7Qu=!rbZh~npk&KsYwTr)9< zGl@TMjPGC1J+GwA)fgkOI3qevT$IRfT=87%lhe6TrOV^!#A>EAUn$?sC_GGDl`LDd znL=ponvt9~EFv?dAXjF2Bka6h88!$}yneNZeSv-|1`LGm{ST6MD~{{a#z!ly+9kex zMBqx0FJd!QL?2az^%dSo`tX<(^sHa(p~podY1tZ!PqC}*THg*}AhN!@u0wbZgqO{U zXj&MAj+LzLOw|ng3CgN;3d2-x3clH!C?XvTAt;)IFkOnbhYrie=~Wa zgYp!s&SXI!>iw*$k?ikMluYko97l}ufmGn7$m!eFaZibYeNXwl{1qvT+pTBA`N2A_UvLB6xwzdqDk12iAqD(l~a5zyBSsgaMRtfzN0H?zSm|1=o#3e zSa#R4!u(jG!fUuLENF-{7RND=JV@0aa|awGvt^PB&}vaV6TFmVeItt*mBhM8fyg~* zF*|XsgOMpmOkU1PUzMZ3`U(29wmJ~{5Ldj+8sk1rz7uKyu6$r!Ky_O?UTuqTsPMy7YAiYq(f}gvu>{6>wU_Z(^(-P*@8s*ow#C_F2vl8 z7Pak`N6*)WDu|OVv|KqZ@COas)M-aDy*DXu*o+J@JUJc6-QiUuezhAtp0POR5?ROf zdLZv_{m!}fDbq-`02#*DRC5OZVBUt~ShZrd8{A?O4PGc}5I#H*ELaAL!jkP+^Oh{7 z_h>E?!a|W&-j<=DZR!mt+;a_$Cl*NQ)~dQ+ar~h7iY!+eP9Ff@lo@GbB%orn>|4+_ z`uy%>PJ7}61#x5$wJUeG>o)eMXrXX)en4KQJ>EH}vj?f`BB$}Rd%XyADUbFS%gC(n z`60zEH$&Xp`#^E(`wC!7!HsKQWB4@`VGT`+9N<5FN|)bbyz_p%?*o3Deu8*u>V{a| zXg+_i*Nvt7f)3kyl9c%>L=gg>yDn>7_#kk%I#$2SUH<;oFB{cs;qJPHFflM$W8uCJ zH-`I@-{;!>1()nN`G^2Ne9s`da+pxvut{iO3?kh-3u|)7sE~O@w9L*GGY}{E7<1cz zD7cbcpK=X*x(sbf0G;8G!=ocSy;K;2qw@pu?&Q7XZSLJhnbBC$(VsG{`2D=L`Bci6 zgF4D-Z2Chra-ZvqH$QrS0i&uT{NzeE7oGZgtN#Pb^X@7NlaTPzhS=SL>Y4twD$an~ ztX%(aZ{vZ07YR9mrmgjOyCYItqJHG64+pU&YWI7Af7aD^a&*6=YTymSi2LSAyQaeu zuS6aZYMN3Sc?8LM5Dbz5ORA!tUb!g&0Z4)_rTvY4y$bp4H1q&05aDZlCS`ZX8<+FK zWW!QZJQ>3>x=?uR=xj$i3=uY9NJR|*WJ}2vH5nhT%k^6l;g)Q&1@82CtQRsG>b)IF zz9|Vot@*^E#Ngw!y3up4?jC4%Gt!*kQy|s&C$IN3GEtwt$8{2Oigwa0-6+hi1%3Z6 zI&ydf4N=51yeI=AmF{Gw*PU8>M>qhNSa6qB&Sl!z4j zgS0v{VncJpL_d+CA5RAL<)A%2libuo_`O3C_jHce*I^!{+Lw3;ygi$-*Av^S=4H;~ zBA(9|V9Poaz;QC$CM`HbJJ8n*=bVU}vUXO~Ni7$!23)ORnj9>mGn(kn@?I$2}QWRhN^2#I$+xz+bHlav-3YtC=jX6T8K|;k9Di;isbjkJ`QxEFc@37QahLpMrb4?yx3b@ zD-1xFK1-=t!9RgYGhN@?IN#D%RBwD=K3%KR!0|Cfz2@wL+{%i>!dlIHcZuP=LkHSZb!b6Kk#*Il)TrFNZKpIl|F}9IoV|b1=U@ z-`N!GZ(h(q{mIyb?f(3r;9!etz)7+5ouq~h=e-(K%sq3T&F_JM_Z{Cumpuv{n5&g1 znK0Yjx=%D?7#|OHEqoi zW^aZ50u^QP?B}}&?I`B%wK9&yR6kz!eaQUZg}GRjK)F^hC_%hw&Phw4NT()xC2SKI2~&4t+ur_nlldxQ7uNJA1~7@hiEB zo}o6(CC_5qhl~q)l=`>&QeVs_gwRDBePI#$|ifU{m0v^7>#rl6Z_Q+ZVrl!z{@K1z(KqW8G=I zr#K&K*Q(}S9-qi8=!U?ku&cuW%@a>vCCP-Gf7-cN@-?*}*BO~LHZfwy!>(St#FbC? zmip&;Hl3htlKV#Yi*CECV5Vjbk$ee}VC$}Rq9EPtb7v%8)!7TWHjOdaMi|)1%a7JB ziza1{7ggk}ksMfAPeI_(kAU{}1t9Y}vvpxxiK^-Ha$7Ko;&22X=Y#id0rJP9ukUI? zQ%>;mLRulcBQLE1W0(TWvn-J57S@?T!Z-30+YChF^5=pWGL4@p_LDGcqb_@umdV z^7{d)>kh;EPBUktz8IF4t3GTUpLLxiOrMtdDf29NqZ|g6c31d5?wa_|r(x5pL4CT5 zj@f{S_W|`5s2|Kmg;U-4Vpr}*3i+qP`t&+%IE)t%i&dr4ce{l)6>shF&x zEThn`1aW#1K&nP&c)EhxV^mhS>hng9-towLP2foX-qPoq<@$2Y9Udhd)5PyaSz`@i z_+IUJC8w%ns!GD=ZVvU19+rCFajLxz<>35N(;j811{)w6QQ<5V^{D^HwRY9{veq3P zwn>FX;1&O|R0cB=3@wh~4|2q-)4q~18*lLkN*+Qm<*e3w5eHQj=!D@7{);_j?T5AoLhkw`%$?M^M&8?Y4 znpvtEx?m*Kt{s3ai7fF;QAks5<82%P;74we87+~wEv?88ww~()PiJRCW)J4MDTH=l z$mBAtvLp`ABYF=OuSgqZEys0kjyIZb73|e9+r~wseoxC1>Xf}^v^vpZWJkeR@Z`#O z0Vx2F*TXpR$FZ5oh;B((^q8Am+aX>L^SqcSTEWnH26Qg$TgpBL^?v-S&3URSR-<6Q zb7YM}>j^BYz8Ok5%xh%N)XPuSgvWtmS1knBr=^`?>h8vyowz_vSY)mzjh6zRt{0&%u>LIJlE0m6vkt_J zonxL{MOe+@Bq{K7%gqw_t8FJN`#T&H6soy1>4qXC^0aQMJg|&6@a<)BzM#j^;=)5u z%*=!(OtOHZ`CWGPo!d@%MMZd?q2DVtjz5`Le5XkooC2H_E6)lBU5C1_hZ6fBer{yY z0Ofk?;@l@|jyLWZHndTG?WOM)FFL67%5Tj2jrVN0O%fFEHC4J8Qs8$*!%^o0t7&P} z=_f`gzsGPV;ODK3I(gK5cHujQ3==|p=f0E-;EEy6J>EhMU&yEX2EIA^{H_3}h1oUz z_TOx%_9I<0(L3uqK@%sDkdq887iR<(vdxHDzk6@bzkeiNm|X(de}$c($*1;(zx%Nf zC+G=t-s~6r;yPrdV|4e%JL}1ODL+xs$K`uU1$y}EGrQk~B8r!pKf1e56SRJMRuF_V zUobU313Alhc)spp)oz`6)tP;HMh_t1uR`9tGIDOA$TD%}1EV;Az?~2hV%Aa0EM>Rh zN5*D?(08m#`s%?kF*!RPgc-Wj)C`iB>pak~Pl_7>bO2MJLP|eUy$f{X*fZKKpC)Lz zEa!Yz5-#Alz03Wig$PH_gVpZg#V@?>z`?^q1e@g}ZIzKD1Kp1D$R0!I`kCFrv*z0q!NRrU&U>%AvxZ@KHZHXRe*6%)ly#3T`HNmCny zL@S4An(@Sb*h`prfx17X8V+ABMc*Sq<-taGg!*)Dj%rxCFZ3z@qd5?M%b;)77d0zW z3HHm1|4)TiH||Q>xX%$|qJaSy*^kT{Ts#Brt8Mk2ddaSShVE3%7+o{GkirU^z@VB7 z4H;Qv0uLS3JIzkcl(IaYstYf14IhH(sxxr_z6^uGNiFjlKD}5Pj)RCgDTE@06?m%j zQ2k>l*Q84yL)rO>Ohz<=Xp={JA4TeuL-?x7mL0ruE58GU>lLP))xx#X#ut2{>-vXz zgGMt^f!O9sMnb20Q&Z-oxm!6*_A%eZf1}&ev^+IW{8Ef=EjuWifcL7m?bOr1RV+fh zcAjZI9G0iPR1s{CTl3gha7q0GHFb`kG3@kT< z(&Gn;hr1Io=(#|Q4%Kwpa9u0@Ynw&|!t0mL_jcwJo}yFB4)3(+>JSpN;h+*hM@YyG zrhSJLYzR}8QVNq&M^ck4&D$vlyEw6;5;yX|Q)}-UX0(-G(0R;K{E$yxQb`O~GHbjn z@pelD%4}gtYKS|co475Mv*~(o*%>VZJ=LadiS(WR&Ts*INdm|Ng}qK07}TUvj(d>>SwdC2z&EEzLPphUl@AQkC=b_Drw)z zOyv?33{WSiUn}aj-J?Yn<#9p-`5JzU;HIQ1y}@fJEkv=m^M!hX8sQTBPS_g0Fka@D zsg=z&9$4P@q;XkJ-3Ea>9uVdQlQZ>MBNI>9W|#M_@)u-53xIXz#vp6H)HK?=bp@+^ zYU*z;0K)T|zX~Nno)PxHWrFFpY z*2hdq#3^y>cjSM`ymUDPl7v%R3$y=XxE(59c~_?4B??T__r$dZ+^mi7+I2HlG(+l- z`osGBY|!%=XGOQ9W0baVAr-kPU35ZvN8uFBBkCO3r^(B7(2Gwj$!;B$cKvE^0#sBy zGds2Y0Dc*3hnEXKIO||M?If~Y#7ZF;>nc8)`sRK43IAB=Ha6U0tO9_VakALn-}M=% zuq3wko1Syk{mr4`<+%R&5Zq}eWdRhH`$`y_D6}~2bvi8I=mg2};Z`u(-R~JO({B^K zMZlTTOxK%S4aZg@a0s%56ITCPzVu-tu~11pCQ{Y@jzi#fd$Ee873bIxZzb9NY^CW- z<&z}|KR;pn!}95;v^3s{tT+Gc+xKR0Z;Z`ZU3bC{GBR}u@VS1a)bS1s3ysbNYGfi) zIGM5DrJC(fAD5!ik08a2Ft!?q5(dJsGzT1)70Fxjls3dFJq$YH!ik@;P99EH4SpxU zP}Ro+Md|SSgs9zII-qMt5KBg&MRfu(FUT=f^{>rRhSj*}h1i%P9ApDaS*-#cYf#4* zflLG@1BR~r?@@!hQESwAHEhtqjFyPh$97iUwQBrn-7Vu=Rev1Nfis?~*R@`-*C{rb ziYFG=e#S_@&0t)+Q1P_*Is#KN5B)0=qwzbF$alWqt@BnM%} zmLtWWI`xwk!8U&e5v6yO7a^~WV}1wAfsw?XtpxqDABLS3rG9Z^E<0|w_G=L8_8+?ac=CjrqyM~0POIl zjss7Z*r(P`4qjN@F>X;|G8i8xTMyWK`~MndG9D!6pj4BW=O+s*E1u2&#Rz~8%!!ii zKO&X)4a}Qdkrp~Q$gpE~{I4%3LLNq0Kk*OpZGA@TQnDPr-8|>Qd{^E^9Si6KXWFaEL5E;_sTS_hbfT1$5rp@<$heJI{bl~lj~&bvp#I?sem|>IdH*LxQPt;|Fgf{g zYimn(kzWh}F#{Do9Fj{zABhmNwvHojcDBrvGNn4Y6q?u4LT0nTQmqmbUy5nYdY-c8H+IsU@->^ z6H@?D7Jyk=!mF5ofziMGXIz6 z>*}K@rH<*}va^MT)-q@&EL4y%q7Cdt%*^s{Xdqh=$k4!(1;T?njFm9)99_$VNU}`{ z#=f#6f!iQgF4$--Z{_EAQ!_A#nrf0>Tq3Sr%IqDTbU(fP?toTUiS0YKK7Xia0Zr}_ zca0!TDmg9qDgW=EM(%tEJ|i85*(CP#G=EMovb6^UkoaqtZmf<$t03 zKON#ffByVOfq+|bqr=0FFaH8XMSZx&yCJ2jhgJ)RLoFd8iRt7MbeCXBtN z@VlV?p%tkygY*QipCA)Ae^l5nf#$b=Youdx321`JJBAFqLT){Kd&VUqPKx*Wdf>tz zoTeskgCG3{m=N0@z-o*vlO-<1_Y0v<#3uoD+h{?A*Ic<3oz3CD6yv?IXllsLPM1U6 z^*vA+?GZb^BJLR-7uqI{V-1Vl?Cy}Q!iIQjkGmD(PotpsBr&136iAAP5u_HeG#&g{ z`}{!MzjiExMnD(d$n;j%max$OMyciT<_*~lSBo&COR!MAS8mtlD0L=X$W80v`N@5K z<@rX6c!H2rT6fTMiG42k2~K_UFJI5xV)S9eF>hmZ^G5ZwLHc};fj8F%<6)W4 z5J$y+1bT5;FOSFD-IqQB#Nc5+RVITN$ExY#Y=<&2p0+GDlz4981meA{j+NySC6;tw zH(lL`g#8@3zYV&nBEZifAGg=l+j9Wxp%)$v%Gr%v~V&uTwVnA=GN zPf3T&5`?Rok_B71%81o(S29%&gOtel#p82`126{~Bl_pfFP@Ns{%%woh-gO{fsF5t z4VlM!FM7qL6zU+Jp5P^x_jpbj9!EY>ffH7TTG5=3H9+uTKU}@E#>Z83uh42YcpP5A#TE5UQUsARGI2}kka&R1v+sa z5-Ij1Ubd&_bK!lu1TL~sMiC?HE1BxTVDybX5`G}8d;Ptxa#AW20hUT~Q{9kBOxI?} zjjLwh+mCcCKrW875h)p&UmsK=NUAL+zwlwlyF`3&q&|onF{ma7A_~P4fDtGVKH9HRt?5q;Z|ZX1G@zy z=VEf}Mc=3qjiig(vA)j_3|;|QIpWvK3pIh^dP7~;x3`^U?qrzpBt@GH_NcJp9U2L> z2G#H^)-nn-ZgkaQ4--mt=mZ-Npq7%dp z9*y8u6po(iFGkW;s5|%o9lYZ`+r_XE#`=y)z!Y&Z>h^7C zIHbJ*k0%(#%p4mwh%5jYP6xrv9UC#g)n~HNN10;7Jusjf5VL3Pao~S2v9J)=a#`MS zeY+GG%Al0t0n5Y-=lXZr4Gq{;XU!$9$*?8?SZU$Y>-hy(JlE5?MCdYydMiElO|{h#st&Q0LCzvxA! zHp(~}KMQ}ez8tP>RQ{CkzS|P*9UDv4UTj5n`!2xaO7OIM*`LTONaoZJ-hHX3gZb|v zPna+{q?;6{ZGz{2D=_Yc)_leo zbIdu3$XZtg-__{HvCZvO@^@!YJp;TDk4JBqZ+vh^8(;)fBM3RrJm?4Lgxz+?mICiB z2!+aXH++KYK}1t`s0R8E)aTx-Y^j56gt2UX$|3^8aRU_}m%;5Co=z~DFBT1=)(vlw zS?*R7;*-BT8Nk4_gSwCZG3bHccl`5awG1@FGc)bF!9a^y0Dv^;l{;_J_#Lf8SlJq) z(u$~uOJKpQ=2`a~t4j1F(NKag$l6C5(AaeCoXn?tKNXmxXDrvoxqHAe58<8@uh~~c zn0J%;P@ie?j>#hUzbD=y0x6a0EXu}K^3Bgm|A~c#@&6nJNUPBWZfYI-9@bjblareE zn4?DyV2h7GB?`Moynp_zelN;_*>gREv-odi;gBK#$FKR)*A&;u)_Z3D`lV;iCIIVD z=Y2@dOwV{~sI! zmQo6QLU`DVl>p6UkgRZsz;h^cKS8AZeaeAd@nQd?Dz!Axk^9_)un{M;8^Xny>x46Z zLxPiF7&tcau;vkR*!;g!3|>G9DBLHL=4VVzJQRM2yBdiB8<2<=^>W%yc35*Sw;lR> zpG5q1HEi4ekdx}_>Vkc;m7%udA<=#FruJBcA+o$&sjRI^06rR$ zQxW*27Cmmd!JXjY>L)Q*o!hJRf0MtXI=`3-*jb+jJFU*QuNn-WfQ}G?&xdatMNvI+ zc-ghN8%Fa@?!3uZ6MBxo8IAJtXdoTk%3)Wi=RM-`q1D&ysYTgV*63wz;TxqCD^|a_ z+v9Sdwx(?_kw1&ei3B`u+RlbomG-M6IdSxD!L@*_qpm)QqE@rmQ|WSJTm8qApY4%L8dHV&N4Z0H*JNcF$$B z%RJzMVNw+>x+em`RSY1H2p)^->D(t75KkJzeOA&9EPH64F!{!;!cwBy(P`4 zUs<@^T~P}}m?1EX{n46rl$=cYn54r1n9FV!Ftl0vWDJ$*(@VOAA_NXK^@K%9!WLoN z$clO{QZPDvchQRm>bjU}bF3dRS}sm7A}8Oj=Jlm{65+Eb3M^H9s`R;bULGWx@9*BlGQctn4U-RAdrzyN5&5-B zN%RM(0y-6fn}Ep9h`>nqE8|_di!{K48B2$=ddz1=D-zY<{N$nT`Ch<*s!;o6#5)~v z1w(;YabdrmW=Z2Cj~{Jc5LksSD4$McML4}j_pTcx+)GxCJ+0*9mCl%`f5fw!f#l5k z3YRy!)DYGoP2M;w{D0lU?J4~HEQ3`x6YBZNFlKY=vg;?jTNTEh zJxU&RYSiBFfaWkNp<9$|-@Ck4tA$#8$M$o45y-AgyHa+CYWGt>1UbGNg~?f-wO96MgShDywIIu5 z(yRJ*kx$rOXGCU;8an@fV@=`XCSJ+gt(B;&WLk13+d z6Fd|&^p82gNY@vu`M!_HZw69K*F{Bw2n_wOltmw8{Wh!Baee8I`Nwo<%ktrQAE1Fb zs|%jWm#V*GjED!If>EUpHtLl#+Q##?IQa7hT=((p+djS}6@C!kEA}U0bYKd&yG%hF zKE3vvCBkPlh)qu?-e;zw$Rs?SHJgs**u&sOd1(P|dw8pfAjt*Y-4X~6UUlIjFPBy_ zV2{o%)1sdD0{spHnYNQ1t_iSszZj zd!MNPA6|9=E>>Jngy&&>n@S-6)>i@wUYKG2;Bt8_unAKp|AO?SnGz4NK#kKAN8{Rq<7?axy4(u&k7X)5(vDO76`U zH%1$lHm}ah3rj%a@=}7Ufn{XuGQ~l^h}V1ndmj_>iG&w93w<0s4%KExh*9mxtj^U% zq%(zMWI+pL?V;)lGOem_2>tL`OxuK+YTGDjRYl5Z!c3YEHx$H6K^!BQ1RfzFWz!Zy zl14|8!Ih#lFY4}*n%QF`>2%`te~Y>6D3Lq} zFEG1KaOF&2RJ9W^`nBt~&Udy8e_)r_u4orLLu;=l(W7gQdngQ*f4?_l5WEikR zKF2q=coU+P-pVK8zrs(cJCibn*14IPeO{KhG=TU!zW|?;{bXvcDy$J}K1-gjf4sMRAMV;_QW*9WWar=8Tk>Ow4tLaHQISbo@*l z#NU83x2W1azYrqUkHO_75|{B3MJ1J3((|Ng$nS%ukE&ZG!r|k(`DgVKOOpA71;nyQ z3zm)~Y$6L#XC1wvnD4O*vxp;4w9Ce7bcUUm!=vvs;f}0TG7iEQJbu??Q<-qQ1NOWn z%lgh8oBi6n8g#Lpp-e3E~ zP0f7$$d`)Y#f6BF<6`K=D>EAU?@qA;sbm#D;Q#wskEZ?7sd{>PMz-DPv%Qkget}qw zh^{WvPdcq)zKUcxfEkr3j^b%ISY2A#lIgXpMeaY;7hemYzDb(n+DW++yzz3*ujm}m zeu5iJ;2j<>4DPO>kFk%pR!EIZS|%1l(hZc&WY!kKXaYD8C0?LzXb-{Y%G7n8npzOC zznb{S=s2s-t+2Q>P8K&WHNp0<0fW0e5C!w@j-_S8#pFWkKrEdyn(AJKAFXdys}{r` zGFQ1?VS7BX$TQud)39N9&~uHavqKg!;^_YMeHKcDM;ixo(+b^r#1Y&<>n4kzVXI&` z2js5VaXH>mzx04X_fBV7?!0r|`77X?-C^m{c)X&nS-9pDI**AsekWjRl~8-N5$($B zlHWg4Nd$CRhP*V*kWfTr$mFO{ubTOfOOKPD!O7YNZ?vBx+$5?9Z&f24O* z#s)>=Ip3nWokOu=EG6T2a@=GicJFM0R=xbNVb*Ah*X7zb=)LS`5^9WUI!uB_je=Kv zv11J|A#?=QZ3e-#fu#@F-cK?po%2Y%Q5|}<0zGNljNGVuoRdZ;zYnkNiZ)^xUKyha z(8A?CzPQ`_22^nDHvX0UUr8#e^rdiHcTm5$oq9iDMW1!{A8WUp-0$p-tWwB z=bbwl{=5)ug24l+-0Y@FXwS-9{TR;l30o|Y#~A*1=oYE*M80rSVWyGAOQg-vM*773 zIp?$CP^7-0#cF9Le)cqovGXUkG&|FdgG<|rZ`^UvF{edu-N`C11a?EXX6dLHvnaH! zW18+h(&)9b=D4sgfCcy|i!pOee z#(DP9n7V6?$SI!%szrVU!Y>e5mWQuOyZG$|P(74~F$vKx3OJVkk;=rzG#(TC*~~6v z0^QSw&gHf2fotNJcA8MZ7-4U#eF3+;C8WqF8Bi=*MJ4Ew64C1vq2)a zutAP*P3%vzD7(#N`3G9e-#b3-7egkOb!{o0H?@$D_sH^ooydL4G4FS1p4UPz(YbJy zQ;Tt~;ae%W>tw0w*ho~b?+MSMpNdIvgH^c!KKV{tNs!+u=q|s)g)#a>c?+c4Bn@XM zeT|^%A@Lzd4&!-(B>-~hg*}<6RD?JHK6U0>^&qzjp)z6y*k`0ra`zWHj-(zR>WpRD z>a6#lC`Tcz912~>uftaMLwOpFW= z3s4MyRIC{m8o?%T>D^E%SpHq)>Uo^O zm86gos_6_XGv4ey=kFRck?uG%U)SKh==*twPNSN7f*Hgqhtm6=DJ6SNN|9P(Ara_I zuDW80|Ab?=Y^f&v{oz>R0DA2&>7dXSlS&-UPC6Wd^fnqYKg!{cLrW~R9c2bS&Z4Mx zs$X;)FWQZ<@LVg)VjeA0f^(E+^Mr8Io2+Cw+PEj<O_Xk5efYP!!bSR@y!CHQ2^(8nBXK(eDS(b9#cPXD70Ney zXvwcbMaaB^8S|3s`^yhqgo7>UBsFiHsEV@s1eAuT@C{?C z!cT`t9thz} z%jSLoju%J}bA*`XV}^VxsS!SYQ*Aiqp1b3x`4Uu2S|6OA!7NnmAkyQ^v`4wVs+p|n z16obnH?1d|UR2Y3oP9Ra71g+^XL8VYntU+JeW$l-EB?a}KLv@a{b=FP#x&}yk4ag& z>cd`4`rx0{rv}1Sr88+(oRsE)Hu_H)1miF%wpv#y{1drV5iBb_@rh&NVOpFHlf+i0 z1FU?O-hM(ddAN=qcaG}#B0(2Hv@d$Zgsngd4IflsQ_8ad8eMrZR zJpTk>Y-p2GYcu=SVRf8cq~=FOkKz==Y@evwVtT%_^7ZH&T<>r9$`Hao?gM80{?EZp zpSsDS!4zZ(K=GlKZDdZ>l>uaCVj}G942{9rJsa}%kX)*3#o`AqNG2K@MN(l9)Y$^T zag^X1jMG{)0TcDCrO74p{EkL5GJ#E)Y*~Ody5i(DdqCMAjW5JQ9H+ai12N~xsJ*<_p= z%jIYJoE9br5EEQnT<{cY?w4lF%g0SvwIeQjzOx5ip{tMesyBC%4c_7c3PXK61RS5` z;5r_V(0~(PMi^}`;@`1LXuvD`Pk{#skg->*Hn6vUv9q(Yyt@sQBsn;cJ-5^X7gajV zdxPP^ij4P;y;M|Hg8=6IlK|IBd@K9FVc<2?1`{Nv>A-I1!3)+DHhHbbWSF}slTP=; zUN=GX@oi)jL!s9v0e&OvOucg#DDiA`YT!mB-OiF6%YdhB6j1MyT0gphvqo|*7 z8xAmTPkORC9uW}{uxwmk!yjGV8gmh?Tr`Z1jl~8BKjm9s={9S{XHGW9Vz>BlMU8Ee zD}GjY{*^?7;xzA1b6)|BUsu^EpRmcQJ_j5iW8>oq-;4~Jjd?j<>o+(BY#*iexy8#+ z)9We2#YtzGs?K(rRN3stcR zxib-LuYAyJq=0q8!jH+BMGf7^(OwGj2f77cW<1?OfnoIKWWPOm<18;S(tIj!x1b+W z!gJ2^g|tXJ?oCRviG?OyRxMC}Jul*p#y9;VuB}be9fCgx8{u@6aGB>m!`-m5>fPXG zu@i|&5!$w4v*+!PUgz=Dn5ZwylM!F+U30;~lM z6pT)O)l$VMFP!YyIvqThBZPa&C1vCl;h64Ijj~35d@4kiH=LbDwepk$ETGH z(7eH&rAHJV#}8Ga>jHZ2Jyz^?qvjPb7Ez;Mv&u?&)GoJw3T(22iugD`>&vl@Z8pqdJjF8_`QUG6V+K7s zQeWD-wS`zDqnM5`(ZIk6G;>a-k;yS2+guJGhe<9H8@!rUsa+N+Ke9tff4(m0t-wU= zQ2`|ntV3>WpM6_VJ|J$eX6p5jD0>9U=lpOaMNWkw_!IR3^Wn^~QBLsc*~59+6Onnf zxUKbpQK>*gi3pxG#$nQ{cF&4Vbb_B97B^d)>UB4PYZ?7r z4b<}(ft$Wp>pO+2hF{RQT{(?qpH#0PHAT0F-v+Q@zKqeW+FZ|5d^jM_`}S!p%D+M= zh}&@ze7+%je5APZWd`b~_ixz^5Y4XScnCm)Q$`{kWPE2;HYd#&fv+k6)^;qS(8RY)aeer9%=hAy$$BSCUv4U-b z*|B7NT{x*3rpRCc0f9D*Au!)T*_X*2wP_q zSiiSu-o^nJEIP>d+X@lopKOQz=q zO3;pbUzOJ)@Jh-o>VuVq0MtO%WLMMfYRp?Zw7%-R@A*&l;hvHvEWaQT(acf30l$M!N4sxH zkMu$^hEU0G{Wc{Vb`O@;=o8vt7yLG+M-}{99=kwZ^R87c-*8>a+tl>#aA)f>mh7L9 zp3pXUyCdI;g#U3qaW%5>4ROo@mIw`16*A`)oT*9O!$bd{8Xxe&oVTNO8}u=zbH&EF zb~&-Ihf~?RboDdSV!X15V&r+Ylt@;i;AVBx6ScIXhsqtigjh<=dPb8a85o|2Op%D` zaziwrU0_=_sW>y`ComPHN`gk7%_|o-E4-q0=j2;&yI@WOh8Ec`Uk$vegx7Zw4tV?t z^KP{0uKJFLKup5H(;(4(_Q$E}L~BSJNrSE5RwpM+@gx zmwLf(9+wJL$OJ=E0x!6tgVWykl-Tq7ZGcEU=EOYtW!~rZ@mL*E5;~c$Sh-WsD)A7K8v-L8SPA@lD2Qb^YU*;(X+FZ_li z&qSU`Vx`UVF6$wB0oa!nsX^091V1i>y(|tfAamZhQ#4DxFA?3Pv{<^iwFbqFyIxKg z@f(kapL`{?TKGcX_~_ZWN7hUVx?V$ zMhBEsKRjHH7vh2&C^j3aa_80R6_ojwPi{sQX5z)z2pHw7zQ6t{)sI#G)D*AUM2v%X zcTCcs#!%$s)U}GCl4w}ynE6Mz-Ur)^qoHz1KAT0~oL7@tdSQ3L`be#}xDQ*O!V(l2 zyC5e)3R00A&+?11cDoLGg}u&|m8o^J5CrOsJ!R1*JB=9;iW^~e>&eA+Cv$vkRo*1` z=H{R^17l;2QJZvm*9I-$EL$(cx00glC^gRtJV_XikPATFS@I)ewTa0YlB23Ubr-r0 z;Vv@pK#tzfGVQ&lo%THAhTNX#d3k6A)t(5{+X;LxRDyn(rwsV?=e)u}3t3~%TL2BO zIBBCF(#Y?SHy=lzLi{gM*`{wx1fIpvk1URbT3M6&%n}chTrVSkq)2|9Yf~vTP5AY}w-WwALRKaUh%&k9PLz;JC?k=-F^^*IEESHoXiTDzpN^X3i z#Q?i@1+KlU7Y(D%Vm!UN*7mwqyqXkM4#O;U-v46QSwVjPq74`T>Nn2XsqsakZ`iZL z+_Q80nDWCX)OPO8MazDstYCP8!>;|u2kATG8Lgv_!_3_pP*Q@P*nUyC!MpZ_z+-g3 zbC|D9yXb};ih=hUeije!+ExB!evx}TcFXFCwG92a0b>|eoJ^T+Q$TxQ%O*DqkK>|W z?}pb7Ji%GJN882h+o`#u3z;8>3o+T*2QUf!{ln1tMpt(K*&3Jx-;=O76?9gGn10G{ zC~g@z)ewns7*dZdfpz?!oRB-bZWH2*EXLA~?5^Fg z{_SAS{LVCju;DU^sC)`}1ieJIyP;S6rlchwq^g@q*e&5k-w}vRQAjxR$7gFlU660& z4ZFBr{^;HyJrnzu#9@6}@5yN^>szOQ5x;z@g^4IHj<}kY(82YfVUR1l>&m%+(fhGT z&w|?xyNGc*vKL`)$|O<?$; zQr0+@(9rli{w-H|@gTVCQ^Xj~WB9XgElyo&)K910D}|2ZNGatuo+ps@KGYj@nm(TR zwm7s2;(x-YAk+yOe%R{LeuhrPJ1j(h$aU(RWx|3_@3->QRdCR|je@Fe*;&#f1@oZ= zCG*S*O1c@^pAym%4fI{{jj-fdY*G?72abNn;6 z;Q-t3syQY0QtEdKBhu>GehiEATiMx|KcYq4l5TKqmq$N;7T#f`9eo9{mi(gX)COf>`IuJ(nabef#Ct*41pv z{_VnT1vYZZH0K*UR@dlwxbaMk=_J?i0qO*>%!bz*03 zc$H9@PSw?`==hbmnfz)YK?A2_%%6iD>YVevhK~Ktj|_`aY6W zIQE|8QUc;Qc_X9WAtd#DmrZai>RwPV2kul=MI&5d_#GL244TG{SeI?Ya;9cT3z*F% zqMq7}2)JZr&22t-t@qHAuofaMd20~AEz#mn`mhO9D4ZoM^_r6#1euSn82sDg zgDwfUx5LF&MBj@8aarHnx6qHt$;KN4X#h6k+h?b`%Hjn22f^pAiB^8A+{U)EA!fTA z8EEw?lN-S!YP!~aueKqJ{WP(hazF$zXzTgB%M|8ukPepm)syCaR7ZyB%6c@ztLu*= z`XX1Z5l-^Iqaqbpgh;mVmbGBA~%B&DUrsTUO{nc7O~(TusW>heM3r>O$PEhhn$ zbnbZ8A7CuyCIehbiS~Wp@USf4rFxup-L0b#CGPCx*SI$Yrdfp2$io`+KNmDUn_%Hl zpU&wRQL8L&4XT>%nn$BW*5~16L{?M~Q_Oh75$>hMnYo><>h&BC{Gn$K(_UIgFK7(4 zAP*a{@tk*-huo>a9QcVzkj}3;{|sW51K_^;%%-OOQ|=7SlUivYT!Mud|re93%tt7FSscUjlUIn*l` zR8>7e)QJ_JmWPZ8XRjS;ZH_`X_+EUW+lt4agO`?h{e^k9!z@96+Z!{@?! zwX>|<4UR6M{CI$F@4kSbGdhZsV)O+DW~mCV)os@ayqrK=vc&WnBs1Es!p`oFH7KbxGU@zeUGr^&h5H6J@2^5oX&Wl zOonGLep?s5NBOk$WK7v*FsyF+amxOC7V~v{QC+qHL3n|;ARc|S7y&~ZV$9mrw5GY^ zJ6=|4#awcw=G2!=P3gBo{;urh_hW_5P)~=TZ2yDIr#~>vXa9W`%3sei-ByVHc%6Yh zxf{eQL(GFT-37Y@drov^0!)S>8z4-{QZy0f%+uJD{e_r$xSa`KRbY z%Ci0&DX0{sg#{LM2RwNjp@)6qVt;?gy{_%_OaIc=wrY)+qPm}AVAvwotmE*vzkk5t;g8J8esQ0&qIZ%~kTdB31_db)wI z-v(;=ukD?yjn4g77bnK(vB$P1@RP9X+_hdvfhR0SPR7(IH(okK?7cuv;h*dlb7!cJ_6Xmmb)Q9M`TZS$ccsI-!U0k z@9FHF^wjlYZ*F{Ajyh3c$q1rkurOp1gk<2L6)lrUI!csSDbHdW2M28(P)wYOjvJ!A zILzVunjCUGvA&F6K1QD}YEZ8QGa+)GqP%L~qVv0-*rXIW{AMcYt$B6(U zuzFs)gIu_H_!3Dt!-ukbyq7hfd|O2HeAdz5;j#If#%iqrc?ntlcI4+LV$h~<|8XOfa5!$kvfCcUV4{v_y zm1?zPXSqo0jgcfmg?lh(gC zJi#nBaGv777XepUkRKvvD%LqJ#rO919%mzDQFoJ5N_jyTfcLZRLYele^YAjkYGC{4 zlJD=WX=TSA^!>G}sxiEqRG#>U)MtYP(j!co$T0{};P4AMsP^Wc(e=H=043aZYiiGC z9<}N#S7p|uhsgVQ2BRWz>2v_T{<~Co2(S{WYp>z44@QjRmf*rd-0C3Pp-U5zp=%Ralrw1WNFWcB(W!#{QF?QKaa7B_gwxO z^q;4i{&%Dc-E%q>o$uejhcAE}r!LU9cC3W2(?5=@Iyi7$o29QsonWulYBTP6G*kAU zMD}v5GyQ(>$X*oSai~6!*xYMtXgK8<3nmF8E?4&$*I#BkiUs8sjLszCJF19;tsI-t z*x*>=P##6Kn^F_~@v0M}0$3jyR`ezxo+_~~XIK@FNU**&YL$xj1RTIeN;S=CMCh?q z9a^vfYh{mDYqK!P$MMJ=yH<`f0KiWivS0ACzBbR=7t!z3GM8;DcsQ40Vj`OQ+}HUl zFRbhHygtk(#CtSqdd;sMdDf@Ka*J#(1Ax#RPEkqW*GBi0cvO*p zBm6C4jA{dWt?H`q(S)=5>3p$Tp{}p00fi)-2i2XR^SV_y-_nR1XnH9sBu<~+ui%Y2 zJQ@H?g&uRx4M0nR1(yhY{^p1qEV^NhFouCG&99lAO^ z$-3@6A4m?;jwR>suP;|ZzMzJmxW~RL>S{(#2)s1_W&2Z zSy~16i?H%?i-z~85$B*R$EAexjJYb>N@By73!wp))2=l$()lki{}Q56DQ@c!(<&cM zQBm^o0>xc&--nO(eKBy(i+jcQrU3d7D0k~A))vnmCBf}fF%ChHRPHE9%SZ}URD8N& z!N9oX^0etgC|#W!NCAMbQPt#uZ=PBO}5vst+=3f+ybsv({~l{x2d4x%N{sE$7|iUO$za6OYn|iI{rDPoego zR(f5oNrn731DE@*^S3a5fLlsX*85$KKJ(M*3!svcO$Y@R@+z^h!ZacW&LtgZ z!uFL#qM_t-;rJ7oA-Lk-GFhzpOO95k)@r_FLH>?1C2F3288nbot%+yKeUk;dJPakq ztx7ZrtjH9az7|gfRe8SJI9bL=sZ`c`r@<_!Jb6Q0H(+Dx8q&CJ1E7<0gkF>J^|og^ zijtacRyQh|Nxg{*4p3Okw#eWUmw^n`kj%Xu_#35`n?8Y-qZZVZhdblDn~sR%BTND# z83V-0az`9xdxvu?*2br$j`z<4fEv%ruOQb9(_v3d4+G-EzQbx@a@Zrv`@bh-^EV=RGIL^xwIlt^&S~BJZu8=xuNl z%wFBK{f;46aryG?t6sN@Ja>0(ag)1wq#|y;Cey0z2#x$?erw6=_fVkYfwnmlJ}^FT zq1lrf7e!~TAdcjnQhrsbc<|ss_XjHUkugnbAxS*Nqk&dD?3bE2LRIFSriuzWiYI17 zDm4IB<45|Lo$#iu^{L<|Ka|})0hfmZ89m+UOXoRNw~M{r8$h3dof3%)^o&mGU)USg0zhY9oA*A=V}`)J!bpMq-U7=kvhJ&o@s^ zt7iE|NeE-uzk$?fimK7%tHdWFs;}l?nwf&PGD(gJ$_tNX3ltj;3HTWvh7eV319ryL zi*$(;EcFwZ+I_qaQ~6#9z~^gVok|xrdas-}3~sua=}*OEz9kQ+@UH2C$rz4!r^wyT zKnh4qTCU3jjkvslw%j{Z0Y9}3Uy=FY)gs+`Cfp&q#2dQ`{l*^YMRcA{kmpBD=**cP zEn6SE#<5Ra{|m91zr#f;0&T1Se9g>UebESmC!S#Uv4HIdE`@@c_L~w`E~SepZv5OT zi?CjR+vvhUXP=dZPY;mmR}!C!9>MT^*gWcM4TD&VlN z!L@wF*e@y0kat6v5nl!JL=QOkDWu3_scwGc!?t~Y7&WU`Dn-u%u zGu20)cduf6ZAQ2!P%_8UQIl+Bdvd;rA%a+V{rCeKNO`6Qi^D7of>5PR+i!+fb|3M> zF6YR5+@}HwS!7X29PUZ{E>bo)qtpoe;K=W;;u>~|30f#cTO1HGC-Y{EzI?KVpiQ8P zMz%i~^VS8d-d=Sa`i{_Ilxl~r?zRUJJi<8L4w?egzJXzqDxh6T-=ykwYkiQ3V@R_U z6+8HUaF<2%`Q)3p(uy|XiHQkKWP~cPD%Y~Wl>PJ(&ko5>Vk8t%hy@g71Xu}DMf`6V zMU}gKkD7f0qTQ-VqBAAt{m2vCsqtg-=8*V9c;a-F#d88 zc-rH*?AU&FErg_T-oUq344@>mXyk5f%8VzoQ( zdnjlaIhP?P?@KYF$LZ!is@IA;(8jiyGhqhzRD`{T>_9?y+!*iJ$!7&kT9u5wJtmn? zJ;hs(4>3somOg4N>K*SmNcjg7K6iq@h+*J(^GYm$3ZlZ}(9zMgt4yQ=iSPgw&v<{f zcJfa%YOA8j3PVwEEzs1fQgLx{7#c?5W#@pvCo4_|)}ohQ{$5LnqHsD%kdL|1v&{nP zs_M4u)nk{s6Wz~E_iLuoRC#URae8);BIV^g_nR;3A{8sDB+iAbf%py7f8u7JJoi=$ znX&9TK*KN@Xer>0PAXwgqOJcq{}|GxQu*(MLq&B!?TQcW0$502A~jGz7AZv)(iT6y zEupx-H=0eBMg8}o1zxF<7qoN-AS$<6l#FBnzkx+qB~oI~cjKyPFB(&{gg>Yq0*JgE z_Oo2TXs7r~t}Rd^053aDDaV(UelU=IOXU&!hVwg`fJeUq*!^OEZghH@?;q?=1VVy? z=uQP&2{8tnjrzIJn5MD)X;fkbVFL(;rl!R&f)VuBcMdjj%9IXufsntvSJhQ_1; zoIep&Wxrh^m1Yp}hWo|g?$@Au`arq^)2)c3u`liQ2kv&SLZRV!R5A98s~V}c4wjRl z;aZkfHsh=79M;z z;=C5F7_7+4tHFVpWIR5`_Jb=&ZluSeZSo@*m%IeSm~ac?H^ZpiwrZplc@MZ~81gyN zY;KOhsHv~VBm|M9 z8yoaT8GW6p51x6l$6*(464uMZZEipEdV?OB&<7U)^TUtM72!zE$ay{2 zFN<utv!-HG>MWpvadrG(v>vZ*$q6bpF6Wa$B{rCg3sFP>r?5)vTa3EiAf?ye z5nVodpvI>=cAYLJ^tjrv7j`pQ*g3HOsPM(e@Z>QuM02_hPJL)gFg^Z2fpXWCiINri z_h$0)%cuWA@eUnw%T`ZP%)Y*$yU=o_>wT;ImU-oWMb<{nNfR-F0K0O&S zsn2S(|32_*{~HW2`+hJlJtl!-J4|g4TD)w3arzo#G+^N{-H#CL<-q&>4RK8Z(wkjs zM#=U&yt2zyW6mWKxdLfz#0Gt6TlOn8K~(_?wdZ1RK2+T}=5So6LJKNJ_4&qAW~Izw ziZ46aE}M|z*J<3ao?Vvl;Frdi0iZhLaw>N_uQ90x*|9w%qVFzYwY;`IuVvfV@77h> zWOG)irMd_=rKxTu%JELvAoX(iYT2^_m?=q4)Z?qx3*6?lU)%fiMRfPr{6Dj3tsuWp zp_ivJ$-&LO%&z;(X3VTALJuB@xIkpEoH^qeE9UZ; z?0>ru#TZ7MlW#muLs-(txD8O831o(kW^qN45il*;=gwN+h=hW9rNjq9)zGX>YVQejpt!?ALEBT>S-3d}N zM=qg~d@U6fJ9?+;meX2_J}8ULM*rk&@9SbX!F5t7e0QoF^<5W+-VD-TOlGT< zBb{`Hu4QOQsWcprOrKF!Ft8`;P%;As{fSMm@uFNWA=&RV&ZxGjQ)Yf$9e#d({+ckl zfb1{vvQn#$tKnt-YieQ~^S^{kYyg7*#$DNe^7}(rX&YYPq1tx~%MSk+b&FZbQgQPNs^@c##nVMHMQ2adI^bALz%@I69jU`UuAZEwe!kfJDwhp=(ta zU8FdH%fCfyD&m&_R>yywH-s$XzUi&8Zl$HI4rzR4<=ONxdy?A?7X5sGdTPY^L>N+r z%qny*xFxeBJjkw3aES-wa(KV_!ob?06oLJe?ngx+f~UU+dI|YGxgH=AY6P_<)NqZQ zpdCESej4T8bo4r|+^av4Dz4dA^UG>p(|6@@%wFd5Ca4-U5VTww? z0y=5{z*Np3;kA_|G?;}jTpQiyi3dDS*Sz}7{Od`C7w}!lTnX|L-c;>GCU+zOKV27&hyZ~ zHf&Q2LNUCBj$&L?DIStrXf!Tmlo_fh|J3ID9RspH_M4~anW4$ilJdP+yL@o6Hn^Ig zj7xY7(|&SKibS<&a1Z=e#j8ZCuNNt^m4(itO~L^`SzCyic288(-;2$)-A|tkkmVro zjesP!Aw;RhZA$I;a0Vs3m(kt*q^(FGj=2Do|hSV?mmVLHf2NM%tHI zaWWG`PFFJ4|qQ zx50u8?%dhmJ=r_w{Nb60p6;%xRjXFjTZU&KeZsD8;j$H(Q}9B>b`qUuG$TRCv0rS5 zN_O5NgOR!t4YIKUcQ2euK7f95IW~X5`#`!2g5tLmh@zhV`B?9fX-5juhQCb3Bi|rD z1TxsL81zq9KRRGGkPfDcljI zl&m&-R&w9G^^@oztT*kXsDBS*vaf1C`hOukvC`5?Q6;a}!!Cox>_b=z4V)5^bh*bG zqsI@2;cw*2na9hYuqmP0=2qD-i0D8bG>hy@v@!-WKbY&;oG}Q^M2u)GYz*gWu61Qa zStj#dCz9Xnp*gTywPSO zkfe5BQRp*hV^woxm3r@pmDza->Df2^;Rzg%w_{pnDM{W+CZpih$9Z0*COLY0Tmxsw zPLk{-|}klZ2O6)4c1^j=?1I=+f1l+NJX@xi7@Y zfr#O6CC*+FWMuG|2^r-Kl~%sM00C}0uz;1%RUb42ir;FsR$*i!iw=Ds#B`>y2_ArC1X#lS0+~f1OT%K@ zl;+#{;>%#3Gm7UjE`2rZmiJfo4Ho4%4Z?(&{Kf~NB*qvEqc-ddg zd7V$43C85DWrQ_6D15#}96jwiRi0IzH|(LGLXhWuNjk)?zj@}$wi)1ky-;huHS@iT zs>dBG^H#POH?a+zW$^@Vze7`HDEYo}^2T{d^Moesjs0)}jcQ%(j~|$2 z&;jPERD-EEwqm~O;2M8{h#p-&`Jrl!)G9NIjwt zA(3+e;fizue=Ft`D8^FO{7@m>@gD<;emV$|DX*2AHM%9J+6rjHfPfQngx>XLs#%s?lMoF+p2h`+y;8&fH?7Kn%)?ob3*tR3bt_rdbAD90TnSO5DF zq4VbUB*kG4&wlCRvO3#5sx!nP7J}EPmP9TX7F6GLU>KZB4K{E8=M^vSq5^Pm-ZE7? z`vzRUfcGh|C9I#%Tu#*O>A%2+b*ujx89DBfaHx4-M@p!SadDGWTrFZ$(1b1SXHK8G zHH2VQ;9!@r!=|k9dH zgW7qcW$gn-Xm7aWQI<;!hY?>_(sK$l{L2an`zL2Z#6Uv;HzWx!6axhgK!9bi){T6S ziYlse(=-EUU|R1F!;4a!9MU%A z9XL}tJACTcGUmWCwoSpQzVuvA1u|Y^EndagFLVnX{XQC`mcH za^)6JYCSGmun6n^#oKc+cy7T=*&^KlkXM+aH;DDKlnuGrqOR z4;VXMREO^Q_2p?y$1ha0=?VGPZ%Yphs!S& z5mTsE1J+loJ_f&67w;D&J(B)WlYAo`bKc1a;;Tw(T*CD??>q`Vji^leR1-w3p!o^I z`%>7~cVe|lN`6s_{X$dCtNn|nMA&x{p-M@cDFh&j&`dWHyW`Srv+$9+ZOWw?|HMMb z32w`25#zjdYlumtk}kY*u(H!j4BaszR62J@Xg;Mc{pWNvdFb*~hE$(spN(6Jo;gAx zv~fNrOTBABfA(FH0v9F8R;(Jmvp|u$pYj2uwT>nofECiqv2QRW1h!ngrWY}VRSc`6 z!D>O%>t8%JN3+ZKc~{3lTS+PC>4`6Y=J0I{mMoYo?%*F_+FSkl#fntgqS*3m_?x%_ zDP084)ey)^K}LfGC?4kCI*eDhKZ?IQx^^Cds31^u?#wFU{Dt}0hcUuzH*?F=<5R`R z$OotHlbGDUY{_P1siyr=R9mjgT62y&+{vQ}R z8R9RgqDA5yLI(AU{V&Kmqkg-&>E+bohz3~{l(oc52vBGPsh5B}w2aA$ywzFPo8_+yj{aFCaexn?zT|IZjb%->X>HO2{; zGqztg1S2d-UzbEF93lT?`nD)bT^4G2x1|F?<*BjBUR^E32qPFKhn+;lt#d z747MJX={2}sHx5R%RZnH^Mw)dx^DiHZ}bfhl0)y;D!(K1lQ33PDS`2b%4ECSxo4>A;a69%t*baQzihEgib9FU@45l`>wG}WDmHbz1;&@D) z_%PDL{m8OtSXs2g#d=E#(&G>&#e^hxB)|WxsHjj?PeqWHY_nJqBN$2WZt#3ye=+Ice-w z!pMzaX0Ow9t&I*}_=6>i%~~z?fafc;99C?aa@yLw*!D%wSTNE}QwPH5fVojYkf*^a zrEZrLW%e@pf+OR+*Z#c~tG7CEr)k5N;C9ssjo4!s!)lL8R@)k|aNIv3FaA`syY6*1 z@O--wWBl1;aOdA;qAG=CZ)6N-@_U^h>%D&Hx*xOqrmf9~>y&$o4!N*OX!jA~oCDoD zFNt>d_6#7C_~0R3S{~L1UIDGGt#Xeo>KG8$#@g!Nw)9uJ1dxRv{;=x%c;bGuWCpYp zxFR001td#RY+ifjSS;rg5PWfJhqU%yb)J!(AKsy>Y|iak9r*S%BlwJ!=>ftovmOi= zi`CK91qi<0Pdx1){|VzqM+#FzYK(1~w?YWckIJe5d)^29kfM}6JHYLjo$rjMk09a3 z>&q=T+3!BN=*b!))9!a$p>bJRg5_3!pb3oV+3cVlp^yIZK1WI^JT6D?c`dt!O4&a&v8_XLWJf4erG3x5HtJql1ZAz4AX;~AD4Kmv3H%@cB z#n<*ENU6%%7q&XA{XYwWk#QVCL>MYU3TZ174bnCzOfTimEPmzvf3K;ku0H3#3;(x# zBD%{Uu{7HW?mz1uV=7#(Wm~=c7xq}I*qWN`Oo$H{>s7W%`FRdVPsF&P1oK~P zkunsRkl}f%zqpqM#UMSyea{9aqW)|~^YRRALQW2j?HV9)ok;x@e2Lg6>fRwZV)t%M z2O1Gx9^NqjgfXxu5J1cyvGIKBW_Eqnk%ISnEBc4kXTkA-JLYT=iF9fJAmryOD=VwN zH7iUAT#WpvVh!OLn^*d$u3JcP{0=|NAF_FX8a?1tcB_9Rcsn<-tlEA{gkG1B_{<|3 zzb5wz3?yl~fwo?6_h>H?5>2@O3G?pl*E9~BbhCe7yANpx;=7;WR_<3yGRD-ueVHsW z6T0#KxAg)Z#+?>WRSywMZiS(`zcyIOM7MFh6D zw}Uf>Q>I4s>LINl#KC;RCi{d$BC@UPGCIe zU;aLJl!4)fHa2NMH!A1Mi3ptk-LIV{EVtT=KFe(OJ?N4KbjfC;T65w6V}rso%;c(n z8$?Q|V+S~s%DwpbjeREgNs}l*n_8QZcRWeJ1fq??1`LA`3F3z+Amw21q<=tq92l^p zVv8|*9ZZr!D!|0@6d*;WQP=gMVk#=L3k#4A$EOKB4rXT5%PT7t4{QGfI;}8zBa8-| zj(Dl#Wh&b z%M`WL_dPYXPP$ZFvMy#*ZBPcqg{D$PHKC3 z`KxeMXY^X0-mqlKYaL#kz8CRX*)=s7ZtEV@NlbdSK2*KK|LDKPMjHa#cCdsuh&8Lm z_XR7!z4D)$x2CRV24jsuNa_?!>?}w_7A6{fc@8Nh^9;x&}?Fa6Hz1bZPM`g`t zosZQPGgPZC3py#BcDk=-kV!Rq57Wuz=hxxXncV;)-t#kzFKcsE{tyY;xTugdqDZg+n_=2rRN!*ZM_2oa#;3M1Y_JX%T}N_NRBMLF3%6JE*N&h;&AaA4!SJI(8+ zY8+>eP>co|qkMjL7BUk3$`54E^-Wb3wrj&Ku||plbBAjthuizES|w04p%~(IG!BZD zpn%hJp(P>O^csl%XFbSxma+qlLS@A#GrG&aaDF&)6Ky&Z69y~XdB5Flt%5@qbS^{4 zG&sSLZThfVk{Td39rEyun5lMTFoSENGspL)ViEiV``dyqqH&$~rxrA;D!us0EE%@D z#A^T?naGY$Rq5ij8BR$8z~6FQksZDKT_CHARIO#F+SvYd`9o`Isql=-9q6W0&f0C~ z{8$J`MXl;B3=P~awaEA6nX0YAVY$?yDs{ehiq%pM-p;+KX8ST9tf##30GN=6Ags~>QrDF-@ydjbL_gp z8Mv8LW(rMA!CGsyVN`5Y&k0Rf{Ib78La!VWwRc4)Z6n%AB#Kl-C6mITi;-`7r$!hr zS5%P-ETS5>0tSo`RPWmp4*8SlN}f>%(2}IDcY6^NX4#Ghd92T1^f>f2j&bDdT(y)A^p4%O|?=c+ozw-A9 zn`3bl?Kj6|L!YS)R9XN1!p8Rrze6T_@q7aJo!4!UpD$_*jcbDUGnD#ATgy6I7>B)@ zgE1=5`h2d@TE^%00@yD}E9c`e?4vJ@uwGI@6eY3BC=Pw7{7g|k{KEA|A67HDO50ho zOQ29Sg4;QnF5XE14jfC045ISs$HUdvKuz9rN6txPCSQ z00ZMF(h=Lk!^55@W8RgPI0g=K=6+&gYU-Vz;Y>uzZFa>SP8yZ8G5-zXe{VPr={q=| zUKehLJwccG=se-YlXwaGsf98PepdH;Rc)T=LRV?n`!w-#9CDvQ{HQdv_|*BIT5cdM z=Th}b2Bo4lZbV1Jo%*lr4J?PQho-`$q018wzM7p0yvb`F|9 z;?8g^`V-tN19mb&<($49ZPFaz&bB34SI+B|U6&ux@mvnWgAA4LwG9dIcv2YAX^U@l zB~6B(Pl<3SNGHSezi-_y1?BUajq}@_nh*oVOX%m`xiY)4e3ukXIYByT0lrQ{+SL28 zM2g((6r@h;FoD;*?1B@kn|v7QDm#BnR8EjRrI&h|`cxp=d3VMXn@s8;;b^Umy3Yn1 zy0T856^?NWm5m2d3jp%%p%(IwYf@3JkfD`k%+37DP=Q*p$u_22L9k?^6=n#Ps5L9h z6cU(rZ2G(t*WiWA3BifF34vpzT2#A_oN-!q9XM%YHzmu;a$4~kTKkK}pEGXKIgnZ) zv2xDKyQeAB-36zopuPmvrb$yYU}nlls|U;CXvn2IG3j@75%~ZAkAR1gW~re&RY6~4 z?0ZRisAtBbW5krUb6UmeAZhqM&LIvS!g5@gI>wl{*Rd-TIB(k-@oXe-l`K^*;aLn$ z%k#GvZBy}l0pdtbErzDM)V0pRhUb%5Y7^aC`d>MqZd#z;lk0S94Ek7Z@iGLUe-N>Z z3jaCv%%;q)puP4*ttu@$TfcUi5PRaVfO|}ub&ZYKq2?nmexygU$67O-=BLLyQO((> zu?XTI{)B{8_uo`I^$bdJ@$sV4(g-jxFzxrCv{k>?XK2{WPLG_Mr*JH4?|?lm+m?YQ zjrD#{iwfH8ma2e@9CsUYOJZqrkyt?&7gSS4H*C3JHXJAe;o#y~eV&eo6|VdU@7fx3GC^+1%6f&w-!`JkYyBJSx)v9#>yz``!4 z{f=U5(DmKLgGDVjw|n(ZqtIjfHol?^k)oL-#>vO|p1BqscOITYWdh)}^qd7IWL^|0 z6BAnU$iP1k#LQtjvyQK?z~k-Nt&bmMT3-gGeK~$l?4d`i7+C!F8HU@e>(0UUnE2HW!}5xpgKexz&@oS!efyj7n78KZ5ifeVg!}b0?+8 zf5pDKV#Xu3^+prf6HAve9#q*iIk_aPvb1T5)uI~q%?Y)^g0!z(+VL#=MoeJNMx2nj zgvl7@RijMj7hq2<~gk;vGa^o>~_03Zv?=gBE2!<3;B z@SUgJSgfa9ovDiWcm4=>_wOs_z;cO~y9XA`9~J!)6pCK8$=l1sxTdgo^F{&#VN-;1 z!;osT1+JTUB`w9_(~QvS{_;Ug!)`X&89>8FOL=)T2!LU>N-u{*55Ye&O`O^dIC?ST z86(&M6Uv~vxu!DUSd5?EFDL>t`@Z4#xxG(BPEhWA3~Zc-hqG$a^M)7KMN_uai)DcC ztgmI^|H%wGUIEPsDo6!3nHzxc!l%K)Ik`Rs5WW>vBzplYX>flk8yshxn|7Pwl&;L< z07l~bJW-sOxd-ER&quGjSYHV^=XKr2ub+}Wb$(d)HS|w(lej#;K`)KDy(~iU9Oi?K zqS0>%ShL+eU8!rSB#&-PvK3g@LuI5+c?XXao?Tl-lrc51yy7@_Wu}qVebkL>NX>En z>DtA1n;xBwsBMRZ3rSNelZ>2vr#x-I!sr@~L*!UEn55z*pY->skDk4k}H z$wmcN&du5Rn~I7H!0a&Fytz^yNTrhNs06*Jzf&Dif#BdJ*0=kQe z@=Y^+oWx%*cdR8Ex}Y4O-Ad1*U3+=RrK+_g`8UM&@Q-;rC;GU2R80R;(Tw!3P(WQK zSq7rf6n4A;ec?kZ)vgaiT0g#2=bn>%IX|fwTxMa zJG$8{Odb!R`Y=4|oLBtnGNV1;Eo4uqq*0(+wSa+ZK)z2K{IM-9UW*_5c`6e8!b1ib zJ25{sR{|3Qm&|B>a@teI`6Di_Kd>Din)@BM?poBq0VRh3e4fD*-yCEeha1Mgza{8( z@gmmc%-6Lsp>(j_T&9eWdV}$*ief53a-+|T*D8poz72peo$v0m`{Qb?fLxo{ChvPk zNX6m!gx`x3vHRv*2;8&fC8u@i4w-HV>6{lvDU)P>(y)-Zqp{jNINK+lwH%^DB+={r z%;8^`htx!Q&|Y!dZaGJbO3e4`bgk_^>-C=G6oLxfoUV;D+N^{{L~H|iPrJA5ziDX6 zE6{wG;5nzoZ9o%sNNY8>a=kbW9qa6TnzjjthDkrEFzhu)BxUCfPn!OW=%%JXfbKtp zDLweZnT+17?Ceee?>{j&e7Gm#Iz1-QKW^j~Jthows^wdCTRjPWn7?DOI3@_`nh6}_ zJv=!EvNH=%6f^9h%YYi_!qH^N!S#A4Zs@5g12}H@2r;#o#)JY%J=?rN(l=wBDAW$? zgbDC@sqwiwrzwDVfyp`0tnk>FIe+L&PM0jXCVw;*OP0Q*a?W*S{EC)_Vc}djaSmsn@~~H*-O)Dvt4UN zn7Kl8FJ>Uv?5pxT9J0+Gor;{n{S`6bKtIfOZyMTp>x*$+@m${J!qOH~U+r^DTKNlc zt5d61O4?a_Q!}HozJ9ieMcdZ))ERFNYi46(qSNQmTiDQsf5!>@te3SZWr4>LN)$vB zyNnAJ0gNJ_9I0)QcsWgS8oBl6(bBUNcBot8qvBd$Ss8)A&^~&>|D6>nr4ac3jx(H{ zcC}~l825oV87gu~=!l-6q)JrQ2bUDQQggCSR8{5_vNvOX_WZBv&6>#u`5wNd13gZ%*b8eW|1xF>)*V*lrHzRmkvj4 zs&iMsej7kF4RD^+(&}4jyO~)6^_z0W^N~l{dD{xe;PuBRQLLo;EPLqK61T9YA6Lfu zz4?!F^kgOkLit|fX)G)v|20En32$_MAE^5J?~@B<6%N)EWVErxDIdxDPShFjh}^&C;zwcwl7@3Vn9Yi)w;J<2^q!3 zTSQNWg$;Z!@Q8@1r)1vS$gof>Ec;bV<+%LEsuCGZPvglWIZXd?wSPcda1G`!Qbph$ z9OAnFGV35h#UiIwYPdhH!bx59#$()b{=_J}4D8H6@#6`KWRLvHttF z2s}#?G~mCV3)v!3qya{MlZ|e4hs$Yee$soaQrJfS_pPLbQ{6&cXJt(G+L|*WT_gMz zFqnT|XX$7sPX6a|lw8qERoeK)e>6irrI_--?(}zd*XS1UQ`po0=U6~~0joGCt$n$8 zoXOz-Vzl;pNMAp>jLOIVP2rvLR10kOX7R%u``!XA6_zomSZ}Q8V&>3C56+D6`2Re_ z`{?S{=x*eAa*pMC0TyOQIxT$M8lO8qzJT^`8n%^AtB{W$dVBMX`tp)XCj$qKIDs>T z?0D7Jp?><00V1>#{P8|3UG`%U1G|G?U57DIyWFE{Ka32NK)g~FUklP1Z^A1}GK78J|e`Z{6d-M+djnHDedX7V^jVl~G z$E?vKk!S};E$1HoJRL-j02SHA#7`%9{P)TfrDD5S?53) z5%oC0^n<_?g1jq4M0hNx=Ak+jF5( zc6fTUizfdZb9P*txbW4+1)ja)^O2;N0H-UA43?h9-}{ zpAqP&PbMkaRi|k%ICeizvib$zc>fM~Qozf7zFl>ndbA&OC8aJ=|j^O|iSR-N?lFH%b9=24TYC31ue z{vh+?10xRP9=TM(MQIH?{t&3M95nXqtax$N^s(3RzkDPS?QLgc(+QIuo!hC^#cm`& z&t*I=3C;oh%AK9!qlrQPHzJT;JCF!-fRUHxhYDWT^vpA;MWwegj)TO zsYXC*fEvkRt-sRtXl|?fC2u79HfqmHkN<|7@9Y$GH|(+SubCmo-jca`B+9X?|^+kO!!n1IUpU0 z;`B<0*BOEHqDXZ}Aq(~Tsh=6rUmJwcqOVLSDrOAQ9wLJ;Z%QdJV{b1(@EThpH0W1Z z)gUjk5Tvk7`3Vv?a=&lJ2R=9i7(GJ=7!l3wcGdjE+wc^5)=gt+OA7UE4O~L1K=%H| z)m*av?W4Nj)q5Z7E58Q^L9g_+^t+juPigm`%Fc9v(cyD$+dY4B0j}B3o*2+NOURuM zem_i!TQcP~u1cFYu`NyU==EIpO=yVL^qa*cgN~cESg-4rf(`mCbd`5Sc?Y_t3 zHvG(g*8S1-JW(D!W5h{R5N>Mu==teTug@;)i3%fe;v!8DxAt-(ZK&;t(UGe|H|hyn zemd~@*Q3k(b>6JLmja-Ay(~bRO`pIaXi?~gB;Eo;OBI-vK>+}4jvdsj=qX%lzG3<83J;tU&K}_;M0+E9- zort?fYSQ&ia;*e^rqh_H84lod)hCvF_LY)_1=}cv;Bgg(o^=kB1=E5=4<&dDf21`| z@w4-2x$5VP>dB9RfmEMHQZ6h;%->HQ!$Gye=3!g|bGjWV99RO3tA@y#yF*xvP)lkW z>UTLO7xP_3?hZWDBOs{X_}++;-Fsx(vY#L7L;nV)zP~rJF9@q~nA|dYQKXV89pjLD z9ae)M9i{lljuSNCIEW97ib0X@R1R)Dtx3%OWvmFI|48llCfze);}OM$o#Cqahn&h+ zKg%!I7C?!Mg&4#}&)E;$hqiSX`n8aWvy(qZ-v^4oE6n_q)DgBPM9nhD=IB@K$^ms91!~wh%=kNiKE4}^t zyx3indY>`|zDn2h6)q|uMvk>)wYZM3Yk>A_GeYD5uk#Z6x*O+og*J zuH`2gzcG`6F=-RbrezELU2WgX0LwF~M6+?w?ZD*o%s>-tJs*1}u&E zj7qXNQaWcrZjTvGPqDKgWP>4+tV&8=|$?Cex=Sx`7Y!{V znPs0(e{{?7HR=5{ZnHN^(Z$Hz>YtUvC z0ijzMZ;VOkCBn)^#MN!do)tWjOd{YKZA%L0=@)hMz7rd0bJ$TybNyY_BspJ&uip zU*LR7f}vBr0H0;WBR_B;>oa!E-kg^wx~)y%9>Sj59aC&??^7qiC%y)vio`p=KAk&Il%yD2Mk6C{4% zz8=U~I+MEud%gA1Py!djY;+#L%@&(g{}|0adX)Bj5}0)h#W9DBA%Dq)$Xy??|6WqtxRz_5!FG?z zcOaAh|8iWmYx9g|6>+37-hP_VB>ekT=ra{ncJ`GuXYyqpxkQ_Pdm19zs(g9#T#QUi zK*;$G5xOUNJcFL2^$D+u$KL^e31L??48aLJAUz_&g^0MfE zz6?qF42+73ipz@5%hGOjrWr|QB6-?6ZIcA3@n4Px(`5W%2AC$1>&WR!t?OaVf*yib zhmG`fcl)0?bgEaVI`gdknt<5oIXOA`g@q7N>DUIJv;519uU`fJ(N4{=4-XFqXJ>+T z_t6tFe(R2Z+q&=$(y{;7$NoP)q9O9mt~6JJL8koYx+H7;=fQ^6MzSX?+WCUqU?bjj z(@UAOrTU^?Hwup-Ov0q4T?%9HFLJuUd|SGuo}PuykzCSk!%SlCmXv)>lU=8`*cq!~M0B;Ha3#Bt zpyF~7^~UcG^R>-SkdpGSzp5>?jgwx#j}XXRz*`nz+aUegy^!S{Lj*hq@+I;a_)wp2 zgfE*MF&e-6etuZCq!GO1kneb*zlY&>UP`JKssM7%d5V=x5J)ICPOY^k3wobYw{z~e z&X??LI_(SwbR9CTa)tGM)=mP+9nF0xU~EoWA!!S3k$j2FYIje0Hqn7DVElMHZg+9l zpa8vsY{s>vfz(&zN?31gc1fZO`iXb@jm6O(!HT#wx=o-dU4tBmxKwk`t?LP5`du<< z+jB_Ya!72e^k{QW4Hh7wS)aJ?8#%k!&KzU`<|VC;HxQid#N|ACY{}^Dw=nSD$!s+v zn^qXyKeXNT*wk^kWo^G)KXz`~@%RA)UT@L5ops*RuSi`+_*%$r2Z#)cLP$mt8%)2$NHatkUV(5h50Cl8c zHh^Fyc~1NwX`5+n&_L<)46eA^orvu?s&bZjQJW#!02~x>w#jmZ~O;|#WgvOoAn*@2bcKF8|2_EC0^FtaykR0ReXUQXN$SMS9~wyB(rD|p^GYBoXh(YmAMs!OeML4 zSTg;i!TCyGWEEgs7?Eyfok2_~vJ}gbgSx4uGBn%@Uln9Sna(yhe^QJ|Q*)C${*KDn z-bv>w1kF_7vap4Fut@N%Xcix`U?nz0?UlTBPHsQj@X#tPuKctsW`e>_v<$cKZQHDn zg_l3`yA&(bxF*1MNv4J7U1R~8m7n04j|06fvJ16ki4&kI)X#GmRbc@mipGo_ZJn(T zPw42A;IGO9DxQwGBFx70&2um&YGR{4GaSYT!|rTB{_|jezpRUo&J&m^LP2pEO^wECyAQylaoAo zjkqbS91k>~%MrIw$5b;I!eGI|+JjJAt0#58qus$G26_2-MV}MH86F;ylYWpU}H= zmqsm{HL$t9McKA{&Afg-evj|>=tc~Qy9;I)cLx8uQT+VAy*s#QjGUh?d1>oqujs2o zySnzAGA@pS`f4<}8TW`;Ar_H=VijdkS7lvmSnjjrq8?tK_I2vFcHZ=Ego|71wO}H+ zqvou{!HZ}a4;wwkI*_qbU)0-+4bSL4=|~M1QN+RZPZ3BRrJ@fV_HT%<5y2awO zB=9;~cedJ0l`L$>@_mkfCowHPw$`26QmyUNsjq|qY>8j78@`$Yr)!fvAD{X3Y&gFF zp#08A{s$Rwpn{~_ES|V-@9Y#kEjy(YV@ahfeMx!X{%sukKstnk0;gv>f|TZw=YR`P zdF@^U*kHG}#T!-X=h`+SNRC^J$ZlGHBK4bSv-Z98d8sWLP1ds9=D}U7&7=z|r;kPu zk(F?JHn{10L}u!!4I-Bfu*{`vF_WMJBFfj+Q700-xT1O>aCA*rnR5wGJu;oIdbKSn z6=WDtT~=j|$Tn5>_==DI77U!epsl!W2emy1)Q(%is?J9Y(Xp>b zKU}oi4EQD55;Y8j^BhldjyB<*jsm*&O*k$ZWc7CHlu!u09p*kBVf<>t00B{os!Ue``xMAe8^DCl7o6lmu63rmK+-S=M(&9uGV z??HRnqfTRi4T+EAX?^ZJu(rx;$$ejmmZjM0lv^CMviFhC13%}Q*z@5*VYQ=qn6s{o zJ9!jFrp3)=Sn2}1q2kn<)@?P8+Q z(1};3v~>X~@z*z?;h@gOg)cuEUPe|i1!%L`qaZ zD^0~sOuSCq-kD$fotIUGFlW!?aY|xty-GLd4+gkqS7lVT#_#T)!du+3%*Kx~l6o z7+rAYo)`70!|#8r?|ygUn9!so+;!ha8$&}w^$t(=oE)V`*=Z+uLQW-(WoZvmiV8JW zW+4!fAV?5YVLDXDWPkhW_3n1;7L4ZiYVyKefmPO-*2u%$-zO>0Cu-r&L-%?u{zB(z zKlVXi~d)v{W9YUO=f z$aUS$Bl5(@^iyLr`U!3NmFoL}`GyAf)iLj)OMf3y&uen%zV29Fmq)^K=tcp#6N=iJ zKvrneOGH~2TGs1$Ov{v`e@FzT>q(G`%v_8G)+j}~RDYtIlgdKf75_bx_s$mC#hg*e z0)Ic0n?Sc&rB1o)^0(em-n(hP)j=J!)6ISm$wk&6tD6i6MQ=BYxI>S@scV_B&HV}J zm&@-#$+_;cCzTr02+EV!=he6UNp zKLqS)IO19aB29Qp=`DVExfyyj)vfnLwVd^R^n1GUPt!T9Q7S&;*|xp6%WPNZDf`;4 z8X{LDX~z68IG2rTiPq7}s^|4Ri!eAPabt5Tv}!wmPCj^mjLfKbNwx2$kHo=kP;-0d z_|u&^mLDY18FR;S1KH;UFOs}cJ7~wP>U3%?_)Gyz$Jek!{RPNZRk( z+zO{7zt_y?=eF3;{grRLDUw<3aRXgzBEAZgC9l`jRVNKirSnxGQ+3(YV@$@DI|VHP z^KuPis6Jn}%H%Iod34iD7919!^gvS+@e=A*6Q?vn3u{X@}C4IliE;^RsOFrN8qh(It$&?rPK#9b*!}9eMc&axUFmx_LZE ziY~-y6vYJ9oUE2L?w9e^(fv4YXA_7&l&pJhcwW(xFIwhIgToD+dh7T zd90T;bcUoP!?{bpvsu;oXIC(4@$>WZ-S5WNH#8_{YJPzv*Q4=YO(tBN)7g7_1N|;9 zBFv^hB}d_ujBYGym0j^^+pvBNIz_AoY#$J0vW9ZI+J3w?v!-!N8$fII&0X1Auj?X5 zpE)wyQ%!|CwR|3oGI0;8PoY=*0hr>pkM)^bKo3u?dNsE0WPI=tz5b zK(oVQ6>gz9gh-EBqa_ zXX{TQ$Wc!dJMQ0O{%xf{YN?6ipr4haPwk1}n2&?67571|bHwe{fo{;H$^PK#3%*|?Ehl(=lsURHm487^yAO-QZ4Q{`Fj zBX79pZQGL{6Cp@QW8u3v(w7YRQ=*OCH1af0?y#Zt?he5*eHRaMuUosK%{x?IoDV%4 zs5WE;X+8u^Rqik|R)RZ?D=$cq1zBM~k(lx0H4^eSiH5Zn<`GNie!aAHZ4uNp=!K)^ zS#6}T5%7GnoQY#z>K8U?_L)#>MPNJih%@uMH*@vffPD@(F7HTXKUQ^A0qOhE>M}*h z6?H7hdsWEs7tS2dDp|Skc8|PXVQaY(nmw&+GDnv09edpIF8s(ilYB+xJ$`g+Mu&}} z3Oe)DXM4}0LEouA{rz>2RoXXmUCu?_C;9AwTX$8~1^dh+-l$+o-R?;*^Ii^HIL9)L z!$rx%o41A~C~b#*E+gN5L9Q{Ovjk$k9pk9;bZ+j&qB%IGG$%7#k zX(9e^UX#eL=(xgMHMe;7>}iiUp32HNqD`lC(w>JCoT^rIH+g2^6bBee{5@?Mj zxFyKv#V0Ij_m_^+on#)`s0#i0ruTvBMO3Ev2=I}npo;^ilFg4NYKwj3TY0cylcv4F zvXGV=E~~zRgThrjsLLydYC!)UjQ&mLNdajscw{tEu3{9ejY(3$BLW-cM`jxsHN7ke zPZ<)dnhGV;`Zk2s1#H!K{@i8@~1Pp{3;A%b^sgP)CFR95qoSnbC* zspJiYdS<;>!*c`^ej?x4%yqtd(59i--;0YExSP&wbaU^h37Y;PSBXH9S+FM5#QLGC zQSP!h+#R}PXPwov{2^`J?_h_w;;uT-u?(8nkmg zJ|0d5WBqLZ9%`%8SNiivo#Wc^s$+qMOQS!|gHFA`l&Is5*cM59JYB+j1ZL9LUly)n zRBGZQ=l{pmTSmpP1?|GY-QC?naQ6fV5*!lTJ-9mz?k>SygS)#8?(S}byA52hk_zaDV=!S42yEVF~7A3M}|{<=3D{Ecm777Ou~Zb4v^24}$TF z>K`k2l=ZZ_D?5JOerMiV(K^>Z9{cK%Ho|+mL+Zk@|5w###)qUS3`2j zO$Mc&k8soj1&Mb3>#?9!w3(vF!5|CeKtn=hxahqa&EG?k6aCFWDV(1Tj43L$!!=KA zsQxJUYxdBj*8THKQZlyq+uRj}9_D{b3OoOjY?8XIG+#G$I&#~Ah~G<98b0s^e#XW< zPSX&rdB-FBB@e~tw&Tml%+#WYVZ-3(p-$5hFS^D{gUo1oTUrFM->o3a<5?}%lQ{^X zdeTDOMKRluIQhE9>1}<>5W4UB%E0ex328R>Q^D>y7DOdyM7$PZ@PJvl@A?kRH!2s~ z(?tHinU=?7Cav=eE?F-M3NB-xv+Rv4DZmvx$DcWC55=J!O+#L|J*_HMCPO4Y^RD4{ z<17XlatE_N3{oFtof$JXpcu`+32{olXU)Dep*6LIoZDQM!kktJfBS7fwEnDkpq(k} zOZIdu$4#t)&jJq9C@6H9UN@oO))r~5F|j3sy7RuB^MuDw^C0DVkk~9TvaBbo2gsKB z{IT$auVX)qUUnPXbi(r@9$Q%W7On=G?TJe>ZI6l@)2h60popxPBpx_Ey9M{H>g%(8 zBY|_(R^9#DX7dy6h?R~yMmt1PGu`~is#s=v;V*u<)_j=J&%I>Dg`7T;R3Hw~41zVE zsLXGoyB-26%iFArx3h{BU|b&^!)dg^u+FG-j*U>oe_Vh%3pFZhsuk2$?}r$15yw`q zm&NRt-o4`@?*AP-RDX=i`6z%39yT_d$l&`2jQ=R0ymL%kZBp9!Agc}!5Ay;1c8eKKfWXy4|FIq>p4u>B}r~%F04}{pAVgpc}X7MSH0bW^rMn)d##@ zY{Ipo>(11XTN-*+XHR{RmTbY@)SZ*gkx6d{qI<{j$=_!`0R`xehR zkqjAX>5a47qSA=h*4!LZiehhHMb79RYF~yB!XbC0ev~PROq~$WTj$hOq^~rpe%5lv z?;yQvnCGl_nJ#j(yK|Y=)DicVBwS#nTBvKxz{M1v@DzE1`t^sJovhU_NLq~SoL}Z| z1bh!}vfROuhtpl@Q?iogrW{XUBF?u^4rDDw_-Sc_P88qg&rR0{9O=srb3NC#o0497 zG*L9br^`EuR!yvVv^So=f7yp8miiB7`d;13U_iaO*2iBgRyF$xb)RYDEslM;y4V1tiQXQLIsuXEcW2&>rjxh9%ZWkWx|)fxMx= zMhQJ(2(%ifHJh_L;z;9(HE%02M>;G-vQG<`zGUT%*v#yh$<=fwFuFhJ+?N{lHXFla zQ8Ov3O%9_qsvO7ytI5xQiaN{AHPkCFPRmux_gFY9-xvso)5Pr2P_2?;#1ThJpDm{4 zi4lVwkx>FvZ=rgOp)(1k7}TuD_w`wVegWrr9`${<_M#o0p&W;Y;(3AuTl=IyZK$%j!KsVye;@rQdq6a*F^0_bLw4;t`$5KFs&Up}m?ZGDHVgMoGgK z=cJi#|K-J3WQPam=~;Ct9cd;e6dle1>Y1s1T7L7>?m=W7T^f*S$B7bM7ch&Q5H&u;)lcxgFceBtX_R(5tN2(+2q~!bBw$MQv(EQ=A z%0o;~x4o?;4bz#<99~Qt83P-1P+$V~!J(;DvgZ4p!0>5P#gTCN?Ey z=&Wf|USFU5>gwuae)#4L&iMHFo7wG>Q49l1`=$T&<8BONI*+Yta7$&g;hw= zjZ7^1lz9CXtGsYOixYS-*th4J>|l=BA(3v9bU*v+nRMqk&l$}+(0U88zuEN$v!Ctr zT7TWJXi@BpwhiG@k~Z@Hd`YeDBi3nwN~+B-KM6sOY^2xcR-GB$O0B z%8_KhrL>mhnY8F*x4Ff88P!!d@(g&XxgMDGQPm*gQ;_ZeH~p}7e82{QB!xaRCXpz- ze|_4K^1(GZZv`lIzFYVyZ{KJ9aMQ25zJ=mpaBOHT-E~^7g-gutwEN0n<;0k!G~7l|8 zCr6Ew9icJ((EY?XyQZ|+8-^gMr^4d^y7ZYue-ZtLz}RS6chYjPyH%xd$0n8-?N zz#ZHO-eCLW`~%QZ0Je&#(&jtEd(^eU;sHH_g+Th)pExJnIwcLSi!KI{7q_3mhh>0} z)AuL25uu3rHxlQKuyZmvpBg21{bT3{sypF!`&*RtF4Y#N=f%mF-h$&IUewor;e%%L z$Two9k8HKqjEARZ(*6BCTg+jWr~Fe7nokZV4^Ir=#==5ThM>E$`|Y%3(gy`TH#KkT_!miI{D%CNOJ4tPF`U8_^)_~ z0Di_%-Z<$=US*E|-~w|i5T+1{Dj_snhML>%ap;rIO4a!S&&(8evv=$|shqkt=l1ls zNNN>F3+oSWtTC)nI3SH4+3byFc_kx|?he(*PUSXnLSRZ$-r1YO*&2L=BEi+hn|CVT z$`5yRr5W}EHMc7#Q8hXJty`*BR4m27^3d)#5aM1hG;bG%)!k^tPP!JwjvF*&_UnhG6+DcDN`D1U#*Q8<#w?&MG+!G zDL72r&Xysb=Ui-*S6dwR+FiahviAD-g{cuqq(=(zPM5}za#_oLL#gOX-wlF!TQntXu`NcowGFHV>^+f=+9_2i3&VK3xwm#f?M3M{domu@3&_WZ6 z=5?5*VoeuRDXAiZox5%*+qWeB)v4$#J0MCeJS)pzSI%m%R6ao+5F4W`et)lZSx%%sH%)GiCe&uPEU zP8M;IfP$rRZG@%2%};a2-40wDLnO-1Fe@5IAMZ54TW0SwznuR(*rMALFo>7XE#8kg zJ^bCRk|qHp6%XneCqDZ`ARD!sm9rS-^; z@c@`}w85n@uv8Yd^hv)rt7ZFi2`YdE3RWjyfCRI@9|lW!*(LF&$dZ4&KYQw>d|6NY zFV&3~GM$|t)#f5+B>l0=wNd}2MUcG==T%h5fz8>!I^7<>q`C`|T3A?oG)C#RY0AED z|C6j+^xy^8p4)$tg{RjUy zb@VFi8YbGg_3x|veGuF3h?aLuNKqU4|6XCAI*m&#u9SGp9P*#Ae^Rue5rICfNaX)< zPX58lcXlZMzbt-qBdIO*|3T6JUD%I5c+BjJzB9Aua6di27R@jto;(}4Zbd^qB)C3+ zxg$7x4{tX+KjlAaK7dUuIz{7c*0FZN_&-9DSyJu41U`z-5i@U3#(2kA1K*PYFJRC1 z#tMtp2i?tEd3r=zfon^Q8q-TZ@N=1ICUhq9{wxoz#v304Jj{V|0PprtU4{gdh1 z@B^vNXl=$4g5JE#HT_GL_eUuRF z9k~U^#9sf<@sRC))kt=Uy=(#WRdv;*h3c=?C#pQ|dPS94c(mjEG5T71;dFKDGWEFe@c5P;GnL>Y z06KSz)iRTF{Y%TC^Kes_*%WlL`?A#Wq_eTno}6$J_c%bL-eeDD`Nzb*6o|CkvJa!{ zb53%vY7QvO=-ENZHrWk+`ZDT};Ue)~C1&l!bFmwv=jLC*VWTqXNrJ{K^C+%m#IIwu zXl8HUvQ}xCJh6%P&yJJnBY*@3vx)4FhilyV;~A~AxFqoy#V94@2*La%0D;nRDB2_avzZ`xT1K7i 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 literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/config1.png b/bsp/gd32/docs/figures/config1.png new file mode 100644 index 0000000000000000000000000000000000000000..c41344bd0a829de4c1bf46c1e09a052f84807127 GIT binary patch literal 52454 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 IhSSsk0X;qYIRF3v literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/config2.png b/bsp/gd32/docs/figures/config2.png new file mode 100644 index 0000000000000000000000000000000000000000..5bbcf7e0bbca038551dd7c14b207b504747fcd7d GIT binary patch literal 48578 zcmb5WXIPU@&^L+=te_$yQWcS2q$7m#SEpJKDz_r|Ec4v3WZ)axnR!>Lm()pX`X=rFJX{bLmprJW4 zKtprt^jX^DI|;Ja8)#^_Xfz(G7zO66&RSAfHpWlNBcq})W4cPI_w0KfT3@5NGPS#FS%0*&)2_H@3e3EG6#De3y2z)6lXBP` zpO9hu-uN}~C!ev!b>6`?j>n80Up55z5iG}V(tMfXt7KQFLM0t44NjO2OC2ftEXO_z zcek8zQL8+vHmm#4@!{m3Z)n7bLpuY$EKGj4{@$Q@bM*!2Z(I2hw;ui9cG=U@11J8r znc|e?{x%CfT;Zep+cuIsiTT@n9xXkC_+p%H&D8f_6dHBCFXZn78om_&0;@Cqvq$)V zQ|4t^%$@(IGyaW#ino9>Mf2&|&{=w+BZ_ zKD3tpL%raYk+Cr~D=aWjw&>j}-D-S1yS&3>mAQH8Y^zV{P#&O-4{xFOYsBFbLA4

    AI;5&j%64Kh*UgzNbEiMXVI7 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

    yIan>4I7TYeG#O^OTBYo4Wuq*c-{|6|F Bi!cBH literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/debug.png b/bsp/gd32/docs/figures/debug.png new file mode 100644 index 0000000000000000000000000000000000000000..d70ae160f7be8e31c8d62524596e515d42ecc7ef GIT binary patch literal 125348 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 z zk8XLTw~vT})qNKHP+b4v+o@!96@dURwdK!vTz%rxzhk(fSTLO1z#D(BV<#S7J7B3N`)*TlwYW$4qKCh^dPz8ObW|tk-Qk;Z zH&rVKW@PzOj78n+@h=(AflDPCA)MTHh1IAB-+6jLWbRRLB%gP)xtA)|0y%z$XABwPj8O8`s~D$C1dDEema`Q!-h7L#*z&m> z3oE}}r-wkNGl(J3XxU-4N{brlu@S>Ah&~VPjj3Pw+fKxbTvugwshmH{If{)1ZArr& z;Y%*-i7#MPQkHzzt~#A7fU6Wz)qyr7jO2s7X-)KL^GXc}0S;0$rv5YAYUr^06{z%+4vkpUMJ#m7(F9x&Jec>dSdovu zUs_p-85udVoN~shQjMR<|1^xXC1#b(CC!wzWf*TxTi#|=1p_1Nz-QtiM^h~=Q)|g- zisI%TH#qnN8pc6VPG0I#8(buJEX$Cv(4k`NSk_gH!iG?tq_L`znKp(oipqi}r{}K; zRs))rQ^C|h(jvQR%Mxub7YlSS4(4UGc#G5WXP+56;MB;f?ug9iduWB5Lw$4ygl?#u8aL!=mah08>|ng+}AtT`c}k$0uIV=T%LPw8vH^HM98P#;uhSQ zt5fcJc>mDbv0iiJ~Cvm?|+WUWMZ99EwtMM`RYVyyxTU$_k-@uIc;BmjU zAyf~itN%z{a%Zl2*}Mb1IAX{>IxdGfw-9>x(S=-vYmW^Lg*{^X^E8)HR*167G%r-w zz{gi#ob0wx5~y4GVz5z!!oT{nunqhslv2LzCRrZoCRWlR0{yWR1>s+o!!Ds`#BoMV zjEOkwTbXH6hH&a4-asr-`sInfoJQ(H) zf^SGkKP1RHay_KJfY4u>$b2(JCn+eKlVjCOhGH6QetP=lv8MvaXGzahk{>lcXCvXG zh62$71nA#&O6VA|smvAbtM-^i8{d&`-deyw$H(T98nP03bc~N){Z5WS2**g{o5Gp* z@5|{;eb#?-zxB>U9z$xB14h*Pdtwpc;o3SNbhI)#WoG3dIzZxs2?CG8X2UTGKgb76 z*DBD>?!eqbUuo*-+B!OfutCp64Yn*G2pplmnSYNlg;kPs)PPCiPq{XmzrFB2iyH6^ zpTA#0MSc>BuY{;WeO+(V?w|`0Li`le%d=N*j->(br+FWQa)A$^K$9{vBL%HTm0eue zX#x+w3k-^YbUjGEIWB{Zt5E_}@Ut3wVvTodr5T^Up?%4}C+f7x}F)xG@vy<`;nk8x zSC4;HQ8&S0m>GXa5!b0iO-+EcIfD>s`5I8QVh6LxB0{#R zUrQaJ00}e)Gfm0l-aek3`2zwTK1~Yc=iCCA=v@1_nadD)?T{M?GY=cktsH+=^(x zCndvzkm64f6*RiD8By8~x0~;W&R;zbLn3jM<>mP?2qM2J*u~*1yd`E*uU?0Xil#^% zAYo03X~=44X4=e8c6SFs5INvm{&4zOr-mq#i=%A(QNeMyXGy@UEtWoSamU(=zEoK6^O9y&SeYI?=}X;!9I4#R%-iHkF16#UG}{969?#0qmki_+rm0`8HL&DcZ(!;b1Lg}d4l^#QJbQ_(Bj+)HBchUCQq@j* zhPOlz)F~PG$FeGtk`F3&bjOG)yJ&Ih*MRrIxAdd*<@phev`Nl$9 zpxdZn(lP$Kfv%wEr^DPUesN2-YB~9m%b12KqV<)4D&_zFu{jVtL^|xh6@m8o8T;RN zh#HjP+TSanblBuID7i8>5CbL@t*vQQCC7TE~Q2eFq1rJq+w=;mHbPHI_vr0O5p1KFGJGu@(8Zw*wDDz^z`)K9!tVw zV%`Ce_Fux&T=VjTpZt(NJ>mT=f4=6$?%o(OOyx&sZMgB2$v%E1ub+tS_r-Lzv=pV{ z&9?JZm;xg8BnYv(->>jMs(&UN>{hy-0z=19iyb__E%7H|t2Z8nb0l2)z1|&6X7;W) zYw$b8TayEUGZmK&ofz<8$Ybz|oEmzXo3KzA$HHf_e-$k{n&TB12FVx9b%+8sW zGZGG08z?aT2Bn&jk#UjVd9usfrtfgq_yywYN|)EL@txnv`r(%@!Ra%hUm}fRJt@xD zBi}UJwKWy~MOKuvcfahr zdVWu$VJ7*NwTJw0+kCURJ`fu&s7p~0ySGQNai1niNlcHpnW-lsF`|vdn;{+RVK#ut zxs4`oA`0U3{F_%?ynhWU7Zj!}TAgMtBSb;?ZedSMq1Y{9LZuC|wb5Iv3ttWBT7nVY zbM}E?$YSr){k=Aq`O85@K;mrH1XTsVI?M?JI6+`8wK(!eX8Ey)*FjT1P!I(n#;kM) zM^13h+p=F|hrEj-rBcqJ>q^Sk7pS^>W1kk-y}T3-qf>0z;%qN>lsvgk558xWi_h(- zs+v&jkGV2tPHen(<`(8D8dopA@63>#+{kGK4dDw+5do%)OOpiP5$&Q>bT$oI=1f~t z)=(WmJ@;kP^3qcGDeIF2T<33s_V{C@I%7QETik0CK_)STpBIv0HdW#}KKu4n*Qs2e z-khx3aL49O+kZB-9DQg`0(Ki%l6zHbSBhv_dS=0({{fIRZ?d!IXcp~W9NMF!cR9Z_ z(rWVhi=W?LwQj9qds1Vvb4tw0!F5UfabqBkm%2Vh;Hs&annJdL5rzK^4aV?}DthsX zWCzK(QYa1C@EkCt0Zr@Q04hlrgMb|0qH}-*DZ(ZOSz;0f7?3c&;m1 zSW|Pmyb8+-a-WkXS?w3?3AfAzCYbgw^MWw+og4>h#Q>bj+S5~8RuHTYF8`mW@KgpEeGO4I8(wmW5(#Wn*&Xx~B8ZljW zn|%|6xyP-z*PQ6JrtwAQB9W<wUs4 z6Rw52j8WQbfxH4@d#sSEb8U7%IDr9`DQMJFk zi&Y7Fn(q7a=U5|P1y;0+VQg>Wf*fN^IAJOH_-W8KNYW{VANu-Z=PP-ah0t$|LLa6~ zqfm+>3zfwr$jGvUI3@;Uh2*NLDweOjZYP+yQae3rU&@cMqGzA2P1AZ}9*4c?Mu1w5 zGi}sz8;ggh&Kdn}#^aEzA2M;|s@OY))6>o%_^6T5L~2u0(>`#KHabN%0gamVV_e9s zIE9E==Z}s}zM;>$r#MZN1nK;aN92}8i1m?Sx;T{9deF!+oV3e|NsEZ;@fzl0KXT1Q zknoE9yg9X@3G`JohXclq&3`{aL3ONAxT&402_MYI7~v3YdCzJ0ob&n$!#Cl5t4OMG zA&(QM&W(pam`d6QS1$kji>eU9^E!o(>e%X_!jp^>MOov^^FUKdm#<(nD>q0kcO6*-ngCm2;lNLUroZ=qi-{;_S5*SM}d|F&Z_jISxViSx%@46Ti80z??E&WNqvN$x@%WWf@5qtWN=s(PIIo)N0 zo)+P(!C~z@45m)3bTLlj7UcbyS{2b{W$3tG@`7Y^4*B(Acmd}wQB$dh_;IygD>;@0 z7lsg8$5swS5x!i7wHJxL?ynURV@{u{ZTIVjYIE4Hr2$k5q4sNFsX2Y_RiR5;3=9<| zw0oBn)A{0M8eKrXi<1-hm-~9-tWyGg;#t;K$`QCUnxHBQcJp%xKm;rCK62zw7j;#$ zBNjD$Wyq7mV(*-;mFr#{m{y1sjTdQjA-`?jp%0KhDovm8#G&k#KL1(c0LFiRfH^>y z{eF-+Zn#aLk)7I?R16=1Y1t10RmF_b9hoz*Bm5N+H|E*Z=w z3${xboR4q$k>@Xrm+jSlId@`gE=Wz8Tah7|d03Eih?KOKa?dI<19A1#2%wk6evKv;6ntJrWskXr9Xo^*6Qu&n_&C%p! zSa-W_S6Oj92P~Gw-#^>%DYEq(+;y*+tOcl5B6>ki0r|gYj0hmNwI-7+I&fe5{{5rYId@eWsO4@PUSEg@QISc9MTW7qmXJc!+s*w)&@yHE$ zXqt0d-x`Ov?TONteTRS3u;jPck8Mj7*{(~Ba>~SwS4&JH@*?@JpJeUj2>P^)Jsu7o zUkaXa1m(S01QnT@XF+XvFpD{8ZZbRfY6{ENeHNb zLPG$?uksdn6&!93xX9Jy+^x?S8z&JF0iCjU^Zvb}_ApM0)799|1is?tcaId6jxid< z?e7_-OtM>TPW@bbjm-j9LtbQG(a9<({yvNWc;7Lb0gdnbnC=P$cy;v2c~C|&o@po( z8rpjl`Q_g{w|d->)5fC-re@oN?rO$A_-V~Jb$CG#f9>yg!#u`QSR`H%E~5A$Epl-h z?zOd(!NlxLbDprCh@bJ?o6$WSL^Kok%M%E9W`?O5HUtPUnMx^M^aTp<2M;aPu1(R@ z$rpn=J3BMWyQ1jl_Gu+=2r-bj!G;~ zN!*!umJdbHOW6}&(BTMTIL$-!%mGtxhfR)gMl#e0C|)F!lH#oBu+GFx9ScG0w*P~% zw~C4*+S)}45+q0$fX`?U=s1;rbBSWgsAyi6r}Nw)1#%%kF%0QO?XcUXAfBQ$6HSvjLDZj_zcS z`x)Z1ek!p1>8$`&*6wvz$ZB4iQu=t$Daa{8j<9y=Ru8_wnxOM>x6fWa=H&q{b28-( z6E3Tg!zWjL{mGqTlOV1bi2=<-o;3+zIF8PiBg{}mx=kqILa9lz(tc5^D0I7zhmo{~ zTe20mE`Gth&`eu@b%VCC?{yAeO{i4lk3QZK9_yAn=I49I-fQ6M35?98i>?n(1`aLB ziqcmEED=;x3Kqzg3+xe8E=4G0D`N5BOto6AuUSKOv7^Xb0j+zxVVe)86tmbss(PsK zHIhQLxF-_wA7ymdC9-@1hyto6ViYK!NM2ua_2)+5ZEg+(#fDi4h}i1 zTqFHs_pko(|GysmHz6I5p6l!B3F!LV#(n}R z&HJ!$8Kn02M+*`ATf)_b4peY#V(RJXX?U?fmLrz0Z3NMCqog+HVC&>+YQ@2#1mX%4(;!GtnRzjbtTI z>VfusstVP6MiOZ$R22$jVY?!y20`PoT(Uglt6_&zwJ3{%w9-Pv68vp9_q)wm{%8rm z@_+pVsW1+S$bo?%P@nMD+eeY287WCg3l1$kJz{KjNIh_#dRvLgfFL6yBe{#;`|)!) z>`&2|J zOpq3OHb8*qU$jH|7w!I)Bxy5wLEz%zY%w*WAHj?t7#SJgzwaC#hLm6=4?rv-`PGma zie;CUmfT55OA(^UATOW=2fm=;_djtkoM}YF#E}DGAF7Kn27`qDe$v#vL`=?gA*gsgY;J&4OTY@v33pq{w8kjCqgKkCsRvF&^$Q|!Dk{w=?!D8RUEoZ7 z$X$SicQJ`|JLUG7NvLT{!!88JhS}kE=P7~NLs5)#ZNKrv)58IpeA^ocqBMBvHRe=@ zWWgBr!7D+?anZMu3{D@tSGLB{^soxDiW}(bU6;onAEYv}5L9~}MVQ>`M%Oq^1p~5h z>*_oB{+99vs{cBD#2=9K;#l`=EJok;m!k*+T)8&MUvrM9dOAdrOcfDSTGfpy->JMT z-llQ5b2dZ8IhWQBH|Ob`8%SyZd5GySWozqg`_s8zq4vQ@U$M%heoMG%PwA?YiK2%C z5+nf_-?glB_w+rUo^}GoIb9Af3%P`roqM(>JO5s1n!u+W=hPfMaS0(2;NQ^T4h<5r z+|=_nTs<8$j$kT!XtaSPTPb`lfLCDhghgrH*mS_j^arO~s^UZHD!$hSzsJ`bugFL2 zx;!k0oA&s+w%W_qKa;Zy3WxQo%^lZ+DH!2WNQ@0ae_tihjJi_3Fi}wSu}L3l@YKJJ zBF^os2zl=bnOhY)OKO0YnTFxtUx(q@TJ=5(0O-GmM!Gh;%RSet>#Z~GO!VLjV4d8f-`X!l!!4wdZowpw7qV=0 zJCEx}mktAAH`qX;^rDs`(HQN?up|x0Uu;wHe1)d(aV9R$ht-(AyZgobwb%zSxvwDt zlZ1z~^(YT=cT4z!P9i43r@E1yPe~6A!`T9mg~&$oeU+z|a}=q`9bU-$AVS~z=lRV< zC!Mi!klI~*jWcL?Z0syGw+MdeRESGSajds{{Pz9`MqP_HY~1_3{%6f`2hjlei7FF) zDg2YvtU6D?o>3j^EGr<6N2C2HJt?k3PwfS2YxPGS7Z7B6ugewMMW3ZY<>VKZ*7>Ot zyeUp_vkBeCU>5SnT=^Qv?bKlwFKBF85QV*p!U=3HB#th8e3Cja0om&=8sp0V*L^5S zd0BWErC#F30$GG|wQsk?U`c55lE+zPn@i&x7Gf$fW5CnM*u}#`AqVti2UHkL>2CS8 zJnQ}YdlvA`i>{Bb?Vp&&Gv^UuEaV^E1swAW3*R9CO$!{y{{%jMH+7uQK%1ts^2#!6 zb93`za-Xrl=`3%X0YQ-IuSy}IFQ3m`mRGwMs0xuYCd0(dJ8N7$M=~mzp8**&v=>&& znVFMFWlouZxgyvnoS-Xk&3Dc_rla1GVf1L`zXrqUulB?p(_+Tsm-)0XbjrRhH3vFh z;tJM1)FnmkPGiJAxTJ7R=pu$AFqTaWFb3m#ABM!G#ERZSnKFD^SzYqEP}h3?bVg%c1URGhvlDW z3k-<`vd}?;X*(U_XUVO;3zUpU=|k09F^KbzN~)przu4b32YZo0P4M}14ukS9k-RG( zjEz)LP=^jwG<5bCFJ~2@+(9;GBf4*keCuss&u|EHO}nZFH8D_&I%y7%j^@I7zseUa zPJXy?UuFoZgv5KrNPgFfaGK|7zCepNO`Zg==rqh&)|PEii>T1r!JpcUv4p6l^NgsgOI?+wwmtdIMJN#ZGw%IM>NeFy!58&71=xp zW18cVnU$&ZO8-?4%bL7zp{!;&TpeVVtgFThN9VOFu@_`ZP*p>XW6hVOih-SHqhMEz zVpbhT=(?~;noLg3xGvjs`?$j8l|s1uh>#&q_7%ialF1QC|A$dZ=48?k{;S7KAtH8d zqJiasv-I?*CT;$mtXeQO+6NG{2vb@vnN)}*-yqQ_ALY@~+M0US(ZjnC^H&6qum73O zrW6C1LooRSGbQ0Xx6N(AO=Z5fx|%cL4gP^R349j8+xVt4B;NV^`Tfi*$}8SEx1WOt zNa(wDnV6BZ7l%LO4iX$rYqZ;FmKR-M4(m3#1RoFA@;ABRs5LN7?R2I+0M=UQiqO{* zoV*^mRvI!BFH>S;M-B4E_}uJxe979}v$^`7c7NEu?A-!h;M+wFS>yz85B ztEr_?^zQxz>P8KL)?<0jNwO(eMb)fW8>Cn@m5||ezji%(Tt41X&4gJm+Q&ZjpI@ijw zivqt*5Kw=gl=*R(JEZ4tT^mtsg^#k8fp{7rPe5e{<))#X=LiL;mKS(XbSL3wWpT zFDRKd&Tl70#EnS({j|yU_puQ}E+RHJ#4z)GAD-X(s+cCDNHk&b3kO>Yze3t3g8k_+ z8;=YT2~AWK`=WKu*V3*QRVwNXB;+7b^D;!Qt*Qa^n*x@DRhwIxof0Lg!5!1J5{%s| zXh;vt6_WmA!$Epri;(nR6Z2pD3LetFQvTPzB7(H9B(4^LLmL|#p4f{kT3N`MkEmhe z*C53FZHhrDNS8vG>LiJ#BOrXcx+J!>mG2S9uly-b%HZ}Nmfh>&+^__}R*$6p_2NPB z^|8=z%bTml2vT(YU?^Af{M=vow;1plli-sp%ZAg4*TvgGpHTblz1M{13$)w>k>CP&?Q@RI(O3CXGHx_=2=B+sH2V&Zx4VU| zZPIMn14V0ev7h#X&jauTv{rPuhXi2SbU`20af(v68tTLOqnV;8-H{QL7*(pogQnD% z{+KYEip)-j*IUcqWkFlVm)7cN-_m)$C}|=gPc2L9>ML&Du2T#bR$O#E{qpkET-+0j z#W0scpfb8ngA53|LUuM28ni?qrI=M+e0(uhlhDE7_&B;$mkJb5$hVUz-4OrT-m}+{ z#FQ@Nd*6WAysF>FTHLEjPl@Ki-i>cw06e-Z4aJCOX$;r7bVh-K6!lxwfc) z=uM-Jn7-UNc@GK?Kv$#IUDcvPDdV$`yY0~xTeEkzX?kV~!R6MF&(DOZ>O}nEWysQc{11SbxC2xBLAS z)F6ii%7Eyd182)y^jCORnL49Ri^#85!N1pbJFT}r8#W!C}Z)1^?&b~7+E;ii-KCQ>nslLWh7Cm3}-~ zPy9XGOVWG2$!f%GOk7>8|D-Xl$MRB1^tc(12~#G~?$`)4{?o{gM&DY)Ry0{AIqGEN z55QW1H|KPu3o$nR{U}?8JNHJS-=e9+LSFdQW($>Eu0$m`E5V#INkTb+LR?-ulA_Ai zs7cq3L~}CQJ50Jf^MYhHOM_mK^Lu z#c}qI+-&&eyOyR>pkbVqn?6aPQpj!~Iby63sarl&A02@)eTBiWUxPLHf_PlyX;;of^+harz3qauHcMo07CKRzDt+Z12B`8&1b z1U>q-N8)!LVZ34$e~^U$H=5RN;kl;iMDzJ;*4h)Hlen%05UgFYi$$vPlVg9E86W zNbfsw)ZRmt-=x-61_#^YKm=|<8{`a+%Spq5bpWXZ=5>z&=vgXa$nZp4r_4U>nx@t% zd^(y~Uvh%8-rZ}@wvWuq+nb*5c*Ze#FcM)((%EY|3wLAE$ZrVNrO2<3gU3i0m7VmQ z=b+D(eR_I&BvoMD$t7ZhuSHpOUH!R=v5&4dZpsdQ8`XK!$2kDFw(!6=`sDSXH~9c3 zh9p@tdnYQLeiNgsE%eMaZT?+R8@{PAEA8KR>LH*sSRzlYbiWl+w zJGfTv-&#ennJREkV4XUU;P(EaiLfla>a@u5$!DYYb9h|rUo4jV`|Haw>?a+&`X#te z%bpHN#AyK56gedwD3&ko*Rh*^U4zC_ghV<;4EhOw?m|&Wg&@w^dBRlT#$BCpW#mRj zn=O0QkjQsr_ymUa0RO9k@j)V9I5eaRcKZLW6F{zP`YEr{zP}#T1=c4f0*Q~+IDL*VnKU} zht&&ndggF%H6l|QZ~SL{NfAA-<+Vvp;}alp?Z`NqaXxEp6C9fVrjn00CTT~$>R<&_ z1{I!%%eJyMD!UMSqg%z8KF!h`)>!TtGQD16r7Y>(@Gw$iEZyT@2Zf{30oOxo`jNAI zb`f!id8x~}P!+3WYU@?|x`U+ljkYph=_tLhHGcVc3ASh4@oCM7R6HsZ?~W z>FTFPP%a>J-D=-}^V>n@mn$sVH~GB$rG}P4^9;%K$WF5Fn$(DONWXwK7vGCas`5?` z9UC>h5*oqn1=FHfBgE7Ztg+*BwY;IKXP=>bSgaWN#Tv=M@jN$MAQ~E)_i$I*jhiO4 zCN&64+P)q@;V2b`+Fm$6Q9Bkh{axk9>x0mEM`%8u7U)xb?TL0{&eye=^>Wwa^nuf{ zgFZ)?;h#h%?8N~AYl$y&s_^jeLnEG~WQ$7y`g5>9t$z%Z$^Mao`vNulH^n>?-P^r> zZRQV?ZB?(}sIE3el_RC-vS53#7P?_!sr3$V);I3jgP%_b!64j=ic)KA<*6N8TWq2& zaOsIs$Z2ROl*u4{y&&IwGq*|?UwLcSgOQb^h_|<|uy9*vX?={QlF+Xe{V&EQ*g zt^~o#xEICNW~w3uN$WDUdo@TfGoDTHl%;_c6)L*AFn^Qr+w_VCy{mKv&;M%Z?)0^wq$ORSQ+R$ui=_E_YfM9)$f@Mz)YJ3U6-u7lUiKD>hfe%{ z^i@aJFFGZrqQXUmor3P&E}}D_qQbi8bJDu1p>fb{()c#V?&AqQZr`k&^`wRM=~^tM zw&_4e^fhH_O0W0!W1Hkv zl?r(G@DQP_ps48J7mi-?oAdd4C4-cwQ3X98A=_{^D9G0qG=4@0yMrLf_H};e4Ta{0 zPx9G%x{IL+>#vfOeA6ZOpd(OLceej)dipGKrta_f zCasfY{B`6(+l(=QxPvGZ|pQ!aeVboj(sje2o1 z$!DkWOKrr^`NX$TUz9nOU$UE1o@_6z?P1v3-uIa?CpLY@%qRiPc~ojY6^mQh@<`W2 zip3S)ms}v@-TRwv_@WN8?Mp71J=W46&e^;ali#r)TfxQ;#N>l#otvs(|BTI7-$#61 zyAiRaDHmKEXlI!aA809U-`b~|L0w(i+0{P(#&qGto_JL1D)4l

    Nj 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 literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/disable_net.png b/bsp/gd32/docs/figures/disable_net.png new file mode 100644 index 0000000000000000000000000000000000000000..6e318fa8efc8c293bd72d0c94ec8a3aabb448331 GIT binary patch literal 24065 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 literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/disable_socket.png b/bsp/gd32/docs/figures/disable_socket.png new file mode 100644 index 0000000000000000000000000000000000000000..c5bd4e2985260f4041ca8c1417d6e180621f4d1b GIT binary patch literal 24021 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 B4pIOB literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/dowmload.png b/bsp/gd32/docs/figures/dowmload.png new file mode 100644 index 0000000000000000000000000000000000000000..012077f45f48227a10409650ac07b6c4bd5f4b93 GIT binary patch literal 14487 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 literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/download_success.png b/bsp/gd32/docs/figures/download_success.png new file mode 100644 index 0000000000000000000000000000000000000000..4001329c0f82ffeb8015e745a9669950ead97c05 GIT binary patch literal 8078 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�+jM9sc;v1InI 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 IfA!D*0MQkDKL7v# literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/gdlink_debug.png b/bsp/gd32/docs/figures/gdlink_debug.png new file mode 100644 index 0000000000000000000000000000000000000000..b2f82ea215a3c1ec0820e843372a03cfd82ed448 GIT binary patch literal 285698 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 literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/gdlink_download.png b/bsp/gd32/docs/figures/gdlink_download.png new file mode 100644 index 0000000000000000000000000000000000000000..d2e931537968b711eb6363b12d6d09f46ae899b9 GIT binary patch literal 13625 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

    tlkhdaCDSMNb?Vyw6nT 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

    IL4c9t4XE6NVGwY9x_ctZQRX(7Ft z)GF}O>Y5r|ef`!u8}sHkM$MLHC=c)kP{$4*K5%w!I*@mK45l(1S~3?m6S~`TYlKQr zr5Yu~pcur%68%KHTQs3Avwdc`(V!~C zMMYsJ%j{cq$QGqGP#1z`B?PQKu*7?!M!)AipjJ6;{iu$KiHWJI?y_gWHLt!tR3s*0 z`&u;~#7AuW7%EbJw2Pr89=3QJ&#@;|C z;a1;2IzP=}*SV7AJ<{y9yR|Yyq>vXfz>1E`uff*?J$XP2iU)oU^6x}@OpFNdogyV1 z3C=$s?GJbDp-2JVB$Ezz@I2Ei|EUWMqUeLIiA=VoE|IW4b_~OH7lo zjVDpmlGAX1-F6r2mI~IvNo5(M(Tm4@DYaE6cXxN^X>qU@TRY(k#|EFChmH|8Ha;G- zB~m{24I&cTKeF5JCHjq@YoQXHdL87R0t4_N;vOFj~|C>T5S``5RatVC6jPPjuL#Za2m@F_)&iSOr8?k+AR zrKP2xpJ~jyR$p!g;Fyv^C#)B%Axv|Cf#kRFS+4lFejLwbvR)DzKsvod#Ujv}pVGg< z4X4Wlu9xCUtyB+2ov90$PN@ek|K<;}^BYt?N<;s)25TdU81u4JS>h z+?beeul?)DL=7FQT92oSA#i~`a^Q0k1vPXpftiAL+8&^7xt9_Qj0ti|QBq5MvB2CO zRogg@?=817!+;J!sIUl!QoJcAylp=VglTwj=S@vBv$6``fOc{I{CVBf#)3$OTyQtQ zqnEf)@)>Z@%QtD#;|?aYLw$WqpsP(BSmzP&nC;gbJTY=dn-)JRlvL^%$r}o@Ma$sy z>7&I$ji5ALG4eP?Yx=pSmm2347ta?|=~1jz$rtO4FMpaCk2;Z9gnanHLRO*!m-L z!OSNN)TVXB$h;O)>)@0Q1J{D56Eqt-eKr`QM*9`AH@_+r2m(I~+l4->9fmOe6TKhz z7R7%@Ln;UI6wcf~bYoNNAA?m5Hp;V44DIB7 zJc|fc%l%w$3x)Bfq{L&HNUHsNAV)s8tegp9R^wu4-vBE$B0QWY!8$57HdFpGy(&zf zSm9yP%IEuF*;7c^joE=hK*WH}@?nb2bUr@=nkJxNm?imoajaDU2U*7L)@R@63E@;B zj^$hl7zZruz`uK&?dJ@VE`P7}Y~1_((9~5wzLlcNq~wKc*k07j$V)#W;>ohpINy6{Q3lsqe9^f>*$z&mc@|Qgv&TpN)-n9L%Q<$6nI-?}->0o+4Eo zomQdYeSBACE?WG}@CRry;$8m$p-lzc!r@RhE@~PY8Qa$-98Y>rGNK^4Mls<{(SqBC z@YjAs2q2Y5pxVqQ3TlHwRRBZ#rVs!cKw!K@>@Y_7)%>bWJ$`g`8K5CYhGOPtn*_Bs zXK}RAb`TVRNoUnl-y!`F3jVvku5K<3C^#vuP{XFtsh~B3*89Rmu`gXtI~2xHl&seR z0V_`<95V?n;&l0nQX%NfLb1Fj&e3jvcuEE{F>;aR@R@Ww^6G*YgoEz2Z2 z?Zx2cBkiG&)ml12PD&^z3t~CZ3%`CH2_BECd0%coaoW+& z7<;H&UmAKklm>??htkEw#*GPiL7Ik3yxRo@hmzuY*Z_PN9s*1dd`6QFl^zcR{&Rw-EnM1&1@vt zz3^GPl8M2;Ht<5Iq(!~9iQ97QO#KnsS^OIf`n-O}&< zr*r*7uK$BXsWPA-m$ALKIZ8uKO*DJ#@f^?tjOV12Cr<*|Jj*rQ8(@+xc-H{%!huinZoH|rRa;_zCM6Aj1ZxiX<^5@fDOq8CWX6DN}~KOhhU?x%Kx-*yFrx=bw8*#&j1+%9B0 z_qHyKf%sM7EG#U1FF85!u*;VUr2C~yIF74CVp%nxBC)ByRYgUm^~j+^hm@3jfVhBc zzXRlYx;OxWwVOVCu6G6C}U;_ZQyWzz_7qlD!EPo=Q4r+B>gs|JkThJJcnHO z3vH8DqDKMg4|^CIVp(}5ZUC;X|Niz5`)lv>+98HBk+pyCf#S=R4_lx|91U<)!7R$- zy6(j>7TiTM0({@f(F_5nBS^62O$2tn=JpS0mIt`AoD}ifXS`a1R(`$(7ntBFL=#H0 z&GHpuoh(d;uwYDTT)fC5L`{){W%nTsc|l$D=IQvBAT)%C6kqQw*5$#qseoSy&~LM^ zwjzr#(akMsbO8m4YK7+_73n)BK6mRAxut$c%%Rj4fXl&kfaKy zN$wkNeiytg?3ReM8j_j~vrO6}5}C*Dq6#A2QR8?S*_I&HWZ^(KIo*^RWYiaAIMBtX zREC{jzF2NlAne%F{|CZM&kiNlHhxPBy}fg*gIX){fFqFbka7?tnh6@{_jXeFQ0LE4 zNG7fCmWEXkH?IDSK76{GqBedNRQ;J6);oY|$g=e0YiZA*8(;2!aQ~(4@eFxc@1|G& zmr71~4q=9-V;FRXo`1@%WW5zpG-qsKHd#L#CirkiCadJe?JplEOT9mRjAKJC4@jQs z938bib(|n`E$8F)trDpV>(*_--yEgFU4lIwqy{cMSh>L0RpMWAPGqjD+Va_MEz|NF zFDZkBWI~d1fi?6keCPgeQ=%@LQ`d50x2B#{n^k!)ZRf_Q$QxY7$bM+Nk~Y99VnW z6oP}Jk#lP!${5+RmQN)mI~B9aLu2Ec-=$A|HP!Sxg|bdGT@zB+#8m{zfAMIl-Sdc* zAj(>w^OZ6->2PSSiA{Z1q4}{KuPyo^sQvMS*m8UW@4#X43=nd^o#U5WV6(bXaD3>+ zQ<-}M^{qD~ZEw!ee`xc(k53fjsP;PUXD(%6D>(CkPA_TjKGG%An)Y@l@l5tqa;w#- zc#h}*ckyGA&f9_u+IA|)*r4k3vHWDgbn#&AIrxt>rGIO}}i8w_f z|J1w)TzIJwO}($oQo)4!eIfW-yaV+$m4p)4h9lR`r3U>@=(fCR{pN(WR6j<+E=fX> zhvS{nWJ{vZgP#>7#{7llnfNG%sWuJEGpA2qEW2*VdEe#bxi&GrvYWOZCgu;qIUc!u zdO|S!laDg4ETNktUm37U%sq&=Ds?*lC!}4vRp|3;+U4#$5~gO$pG>0FI#ZmqA0vI@ zh9>&d(mz38oZ=4?=a{t`^XEVhjtU2DyfW%)2)irwU#`C_2aA>h4%(8%#?Oe*#60>5 zk_ZP(lW7UT0x`iG0`OV`cUL0bu%iWaX)Je0<)lQRxDx*+0!Y4kAJw3Q3JipA2*9^7 zEl7IF%!NUV4|IJ+#Uex5t~vdpfvSsEsQ66Er&3S>Vu-=v&_xsWDpO&>wga4x?|5ocE0vIC=b#P{d3 z>7KNh_tG-;%UYnR+)rl8xClrn6e1Fvb073$y_&^SbPNP_KB{$HkOJXglcJ`gL9C5Q zNXUi;HJP9u02yR)c6SkuGoaYQI)`C7)z3Cg;l7$nng092uu>gnmJ!F~uN zJRz&LF!$k!NfqD>#os{CK$|q6dXpxTFaYs_95eL<4vb-%wEyZ=LyB|k!L3P9e~2e?BbDtw6#J;1ONKNgR%=cdS|ib2M8Rz$F9?E z7pB>`ySr;i-P!!^E#Nzw3%d$WG5sk@9G4n=*;7Gv5H?) z*40f$*4n{wnYMRfj6?0@KyU+^Vt^%Ki;|XkhaMigapeSufeju)NDYK?2V!{NgQHi8 zW=LNf1Ur@1oO0Rc4r(&26$n*OmU2MjEdr%zLcAOyAB+*=qt&9vRQ%TTa%@f(IW7Ag za&VE;gAnqTYoSDagkQPcmeM%C+rUhMQ6( zph^i^qy#J`(SyS2%f|q81THtDHkU?Acdj=H#t=v`x{LWL*B`|q3zmi8`k&yqRDY)& zhyn|Q6&he&LJk7|w0h-^CXC$jw7~>QnwNW%I#I++!vJ#hSkV?N$FRNzL|2hcGz33C zKS1jTsKkonbG1NuXs!5UtuP6)R){mw2gHksO8eFWC4?lT+kxtLn!BvrUc+-zm#SH! zLdd~n>OmmGXDNDsG@(pmVGQn-qM;N^jLpMDt&kG`#P0-+il#0oIFJ9i;Qnv*3ilaQ z3#*@C|5`p6n1e`SvU>}Jrur|MnkJK13qwFPZ4%?ybIAaV!j7gSn(J?VJKhC}j*r%8 z!5R|$9?uB)>}@1ObzrV@T9N@2Bv+hucZY)ug=35=1Q7*xeSoPYzRPywS8(qCksZj? z{Ncki;Mz}})dWTOJw&v*>OAIxA7aoHl+Ao{J+UiN2CdBU`0T^O=3r(d{BtB4 z=o;Jqdq4iaU622vooj{@h(NSP=>&D@ps8yEj$*Scacrj87-L|(QG$+=qsKXh4~4RE zS41OWuF(BA(CeSs13yBL2hNg(@joN9q)GyDd90bTsRk(|2+OJrf^8VH2LuslfzS^m zFd&dd%%YfoE)e{>Lb3geD9cO?nm?+%9tED@FHH+^n37}!IkU0d+(1QZ;BZ1}!gier7@%h8{N zWw=3;>0kgBX@UytCUyRCELn-VTqCsf^&dl8D=v%y)%bG@Y~?v%OA-n7cjTfe3xvWPIrktz_@&Of^aW)bNQlD^ zJR#!GuP6Z-|9=jW%|3vT7L zEm(A7n+Me`?p}*PDhwgbTc*5JFX$jI&jfzzwAinK!XAj(z5MvZNFNTLR14%$5iGK~ z4RklkT~MaUA(1e)xCp9)mpC;@k*(MsL^r#BfL{ zf^uYI)tbqv`geB?_KCvOHHNXM=Js}E&=rtD@?HZ&o2f^XkA-pCGzF&-Naypzo;>oU zpNFl=vSbtb9;;gog`ZwcAt8DHTr=c=So_4S@3k*0Y-+*qk_#0qWJwO3x+2vS@N;tV z=-j*Y}!%9nKXm3k#op8mOUCJ;w z5SkjfEn1G~v7zmzw4Q{^;bJ8JYS{cVrF|6e=NdVZ`g7IhuWu*}N5MFP3eSPR8XoN_ zl#1b$UieapI>AP8p)4Ox|UXO zRn-ZnOg4R`EE{r=DY^Otc1R4ar%XI7f&f7V1Is`!Cjc;n;>2^!VdMF^Il9x31T9FV zDAFQx8oJ`HY51QT3PvW_dY12rH=F}Pr%>Lkn2M+=q*wEZjn)rPoZsl6yDe5J6;F@- zZ>s%2_}G6m1^5<*PaMfYpD%-kIWbH&5x)E;v*clg?!^OCR8+4doZ+Bg^r#2gOu<}& z12AzyuouD=N!&23(wCqHl1+xGV<=-?3yDy}0c_w=ctxfju;y@iVEc#qU-3qIds#Tt z6*FZ)pHuOU%^!@^kBpv$L7%nK9xBD9<_FHPIuk|3U)`G+b{Hg^Ky8PxKnf15NeT}J zH8tWQ#AiL2i_a|_yFNGzmZDQ&;9n@KrkgNKRzr{nWT^{>neIR+dUxw8FMPpxr^krW~8*s(PsEa=n8*AbkrEGQ^g zX7}dtTA;OD;VZ&wGN&lWGdQcZb06dhnES;8;nSn3zn={QAYm#f7c`9cqFhpF0Zq*|Geop?LhOa)h;R z_Vl+nfY$*VLl)&8fb8z(&qCs=%%b?hI}iwXD6@9gBswMoGUBj;`5u-$p9vmZei4Us zW;D14+<|e3gEkWEY&mJ^b92hE$U}iOt%O8aJ_jN0DhCE%YFVkr(TK%>LOWFL=D1=D zmOJ3d@)fO{0|j(atLKp{v4k>^g24;ZwgDdyfNk5CShs|J$dx_~7Ix4i5I+Ci8~uC4 zx>i9+$?|&l$riBI_SdriIv_9x7tzP%UBxd=FEVFfMXBRp-$F#I-@F`MRIN zs|v5`mFmXec?j;mS>SJ$HaIg9uyeC89oX0Q>3ByfugVC1Uo_qED@9lgDCU%W-z%3d z&}IcW?9^onLxkF>xlGn!FuWa+Hiu&a@w)s^^|*qZQ-#qIcCgCtU+^pX73 z7bM}2vY8-Dq1n$0_BZ8%CF5*pm`nX_69fA^g-I?W!a3qoOsl-tm7~W}C{(!}6@i7e^>VvSj1^Om2t}cL-a_YcG}l z(a;$YY{W6bp^040RJfK*s7R=)s`~Yzu*+ZL-}*rCuJj#_t|iLG(f9eJ2&Ft&TM+76 z!|>l-ki(r+Rh`0Wmp1(7iC^`jwOoGHXRKXazL%f#0I)58Cn))oQAS^WP=*dxup4dU z-2~(GNbpJ~85a~rS+Fg1>Za@%2Cp#0sMtY}ba!KZCs`!{sRc(&+|_tO@gM?0J!6R- z)k*8)0rV%psPI0ViXPPHvf6yA`qG^0I2g7b8KdLr;5tn@fmQnymhJ zx6<4uXLAs1X+>EjJSa%Jv$bVsp5K+p*~P6(u?USX1Ezy#!1A@~Rze+OD@PqXj0Y$0 z9_MIOy*C4?_a|+^a0&+=^_|?roht{A*h4!*C@f8-4>Lv64$rKe)3(j8<+lSbrYtT8 ztwB+|%XjP@6*{R&1iV@#r-R&TFz~kVbX^-+SOJGy7j=CKX>icE5PAUw0U&Ev?^bDd z_Y>);&?!x+rU^|HMN>$>8}{x(X|6plrtRSAuMqNseYHrH83KX@Qx@BPR_Xxyx;Hnb z)?-fSh%m=kkv*X5NW8{gykQm!Z(GerYqShzSe2%NpU zLVrQltc2y+jFGzKcVR>~hTmrjiyOVWbh1WVRxKpf%73thkttQ$Gz7q^R{Nh54pgc4 zMwX4hlWaC5*@e=yQIpA%O9h5cbKkI>lHxk9pf6pAqb1 z7qkrBbYTljONvFMNSH%IqX%qBg^XkZ5dih%yB?7K=Z^&d73vDNqijmFGyc3Z4AvjD zxezjTmNoVc-%Up<8yU9oK~@aW%LLvtg=F*niwa+XM$#m~4)f7I=NtrEQlh2~%>0l! zZIhT_V570<=q|`XOG|5~O=Bop6S}J!N{T&oYFo$InVj6^Zz$bHt<~j^_L z8Fi1zY!5a#2$-?VKnejT*x?3_3?P+fwvB2RwqVnPK}k%EtP{lw@0>tMTwJPI177ye#HE*wKWrDfc7D*@d}LvY@aU4hz*zfcCBllq2FIl|iCl1A)^BLQG@e0J;CA21h#^>)9)Jz6 z{1eHX22zRp&uki?`uHA+CD&^>P*R%XUqCWw3kH8*3wG*M(yP$?Nh0Jw#5 zc+B$hvTP?cniZ3y#V_ZebEO;)(fbM|jz~mBB(m!;Uidsfl&MD@!H_YbylD_ejUAcL zmndkr0ygC$f2Tq2eZ{K)3 zK{;ACmui8~g|@af1b*Pkq=@$xmG}NT8VQg5pUmu3ooc?|gMw0Gv!vq0!SF$Os{onmP zp@@ixpEhamR#7@#)KA^VTacCXFz$80nnNszp37uG-Dzl79qWKP<1PV*t@t*jq2X;bq zDR2CQR-#VAv?8g>Z$WI=;ZmK~vs_A=moq&hLt-AnPH{_@&pwbx7Ije%LIg%q+7X)3hZJzIfm3l)DzTl}{9~n`4;`VM znhfirp`e!|KKR1j7s~%pks3?D<0IQTI)pN~vfwSE?xFRhnyeq7!xKtGUWB;8c6+mL zINv8~VN*mGn%4P3fKM|-bS>FY&GlQ)9H^+D*VU=~Nnnprprx3qi6=CViDLAm5VQ6i z<#wP$<pETmmb*`k zvh{9(@_vIIlk+AFzYG+R@ocVgs>mR0bT(13=jN#|Z$sd~o|4jYO>tUrob9(46&0;3 zN9ZO?+MjJfQ9Dq@f<6=$+s5w?kHB?lX6Eobh;4FXGv5@x5%Aj4n6^YM#HzXU@a^1t z6H(t#J|+zRys{G<2osZNbHN>12P%0Z7IyZ_ZPcWGcxM)tM2Vi?t`9lwZnQfz(Wem* zu{s)Nq?ZvKq?=M2T}`G6SB@Vz$I&>248I(4G zTN3DYaOnEV|EliG!=dc^zQ?|eQkG1TL1hVHvZoM|HiT#$OG8<*OX~{|-Q(1aH=XKrp@jlOUJoo(`&-34V9mjPPM`h-m^Zb3k-_Q2N6vkY_ zEv~dVrRQPRg6yL^;nL%gzv)!Wymd>dWHGSS4PCIe*Dyxc_QqW z#mg5KS6BV?-*#eY%*4B(E=K!$%<=I{tN?TSabM%z4E-+5{zUp6gmF)!Zwv+tt5$RNXH5j6}4P-=%O1zBu!2 zv2eZ>7X%)f$B^UrD&~f4qt9;eaN&A&J7}@8xQg~*pjvgj7kE1o^YGx2SiWYf13l$m z1mtt+i3h-W+a~Ljs(VMLp0h0hKZako9wTR$?MM z^waKU95{ZKZ07!Yi9#ntEX3KZOg(>|$bDEMd;0Wg9Oba5n2Csqoyk>DNC-+6bG?0r z5zPlUzC7%O)mD;M0Q&foRoewVE-EI4@>;6dJoD`{*PEW187PH63pkvK#q1dw0p58% zzSXAZxgCqEQI%Vwhy)zX7@EC`g|zm#V!%6Yp^7!^-|d6sVrpp3v4pgD`z}TE>1&0| z;t=27!0lYkZU1xhDr$E@ESWD%T7*-n<<1OV{{Dn_&$P@5k{s1? zZQ_-ROKfSDXRBuIx&tOg^S*Kq3MPsQm{~FCErSkf&7qumr^J$VCIfNfxy$`$eE*+! zOhq*cvaci=VI_yZfB1sobjH>#C1J#qiwv=VK}h_;1t0&bTl-LCDSKNN!4?*xJo{=n5wVe<&@KSW@|W_(Ou{;APIIp z66=kUZv8NMw250lKwzGBEFXYXBF`tR8m2lXg2Hnii2J{s&hyk~oZg85ECxNc?k^YQaHHZ-(6?x5dH zQ_V=4and|C{S#BPS)!9Ba$?YNq0@w1dawQl=!~Akqb>M&e<7jq_AoEoZV}P~GB2C< zp%0QFu`QT5ge!nVfZ{qylG4}-u-!%wW%T>EZ*D-I8ZojsE|}kokI$r0ZKJid_HiF_ zSPjB1B&DSIDHiyCP)JDQo2EnM2$6^*WCUl=iZ7g}BN8AXg02R1m*QUpz_TDKA;<@O zuk)UdYGCjStn7kcz_CBwo4nYZk%UTBD0>w8*F~;1V7cgF5bKLoJF5ivj=`idj zv|ptC9Q3)lD)%!+2#8RbDSNnn_${eTMs9 z+>lLh?W_u}z(+3z{egO#8v5!mGhH_>%|AEdQoXn7@bWBw7Bkv(qH1W|&GcfelgZae z;;WOzRN@v|bve6%d*g8VGy}a4sO{!(CuaVq?Ihe4Xt#Ps-W!FunPP4n@w#7vcBGLz zdFtSyLv8As=mkAO!sTI&jkh%{ILF7tpJ`%<-h6(Yj$lqVOhG%f$D>F4s8Wq1pM;&PcldD*oS0<@$3!b$1e6(vcErY6a z*~fY1K7U*^SKfQ_CZ3_Kd{w)bR%n~}ZSc3%zSh3+fYFO9-7I<^^=vkD-dUm(FcRl+ z$I?swUiikx>jf+3ewmzHcd*)acv*?^!xKi2$V{nI9d#*==?O?H;JKK%yLac-7@xK2 z-Ab}EY7g_=pPr_bd73SJ!5NxkQuf-bcmFH-S6u9xBf_Fvw~Vv}q|PbK*=WfbHwfAm zyX9oTaNF~1y3XD)+Ch(8@4WD~9G%eM=^lAtdX;bCkgvyZUfaHj_Pv38Gs#aqVz2Mo zr<->*^(xyS>B4Va$=l+4k1dY+l{}X0u)J(ng->8);*`jrxb@7`^NQnYwB}X0+jGu2 z*4;Q0(Eh4fEy($NG2PeZ+@{pAtc_j@ZfBnA%y1}Kw6Q|d#^?4j!Vc|&u45OTQC9A8 z$Trwpbk!xlU_Ip}+rHW6nVsU=Z5#&8d8JqF@AE5-WgTAm-iy2TOj35ox~TH>81-O@ zt53Vn2HS_0`rL^aI{WV3haAdQ4>idj;SYb?cO;HgXy@ppI2(%I#ulx#C}*7F*eP)z*7iBUVRx6AN}>{!K1 zFH?h8HGcLQ6GrZz?26hKl~ye(^=|aFIGlH*YhUeR%BkgwWxI<11k5uV_n3bAT1k`F zA#v@vA?*pb%}J|$Ea#k5FOMX3uC|wTaeX)5#oaAT-Cy9@(JEU)PdIz`REyGD(L(Wz zq;ZBaZQE^ws0Lacr8PKreJR6tcL8gX99`K!>a|xjHfh`Iw$*3*wk^jke4iHa`E!DJ zZ@nq{J=eHy{l=*Cg)@Pwk2%7Uj;pU0w%H_S^lF@6=XmbyKJn+0V`m$de)K3&Da}u8 z-}JQO@u8_$#mJs*KVNO&8(mnsHiQ;2B@`%lZ=0sQxS3#!cuC*v(ls{L6LdzR5_O*D z1=9z2DqmC(&sczxXND;r|5QtSm6#(+GUt2z&uVr1VRtyOYyFO_k3Y>-zQxUIO@{a!>3H+O-XS z==KU3{JSqhKV0+l)vGDg3o&SLqE$CHy?C)LhO_a4p^lD@L)c&d%|`sA(9YMmTG&u3?dt8>@_uLRW_{+NxRWQx~7w!4Rou~yx{ zpu5Pmbj9wfgHghgJ9q8+VLh=AKF5fNI$#wA->2PbBZWS!hdB)#eu~QBTl=30OXBCx z04V`3y&9%2U{H>GyLmEKZYPzsJWo;CN?(D>ws3)nwvhk*(jeg#Ga@Uhm?Iz^9j_ z9s!N6wUC>?wRsIxdaS+RDU|dH2M?lxYc`XAf&7@Sw{wo_#K#wpo5`fzNrVLe z`0}lA4MT}*2yZYo#lsQ?p_Dy`7|fX|G|gSke52x!FL^LB!ZUWZkcS>$y1BV1!e`?` zz4Aw#emHUskY)_THSx>F^DEb^dBtwvp66v( z9n{PkWAO72afqB~05bvZ?zyUutR`qY>-mbbdAujUatr;Q=nZ|{(9p2&$Di3u;>;La zFsVQzbq!oRI^oP46eccn=Mm#sHGsEQO1h^Z&Txq(kXPLX+~IGk@X78Hu;{u)@Y;gS za|v3`d!k&jarFz_SKbG^w%K%EUV944%Ak+W)%Ep%mSu!@Hnf2f+tJye;Q$^2ob|#> z1+*>{sfLn`MO!ip@Hxw!L} zKU%k$xogpI8w_+&FRXOV&#@DACn-1RTPc=L6SA_zW=G)>7b&^z&+N6QXPCL(?ZFgQSaA-`mW z%fD^4{?#dc(Ssic)-k9`e`iSJ;&`o1$+#EY#IWQi3B*Z!P6V~7}ON5yaDiD#IS6d zW|n;PJM;_C%tA~eW z3s+jH45QnH>~6KTb_pQ(A-lZh#VNS7krL!_3&v+KsKtjf*bj?C;0c5)D znGGVO{6@Uo0X11Kghyi@i{}v7N0zcQF3ojZGPa^hg%5+;h9N4F_E)LqyL9B(V-ibJ z)&6I7J;c9p96ACZ%2*$mH*bEztw~LTv?4{#*>3TTgM-aUgi|lG*!vF%1El)?!~v;( zu^$#qlegQIMqSWz_4Y!}8iOB|s=)k4Sn8lF#trYd%vh40Ng*sse&diaLnxIi_*Xw} z_qpW{r+Qjq2#)^H@t*E1O8SNcYEHxv7A9Pp%T3ykBO*KJJ37 z^F#Jxj?nvqzkmLu#+UmIoXG2kCI~}(@wIE$@+=u_zkyny`KoZRmv>=?pZ>V#5BN&K)QLY}h%-ww~DB^z50WRF(u~t&L4$ zubm6TY7Yw(+mM8$T}ZSuRx9c~?;q83Td4y+QX-4`v~-g)|;Ac)R5 zG&u)(7DS|<^%f7@vrrC%To6KEz-@u&ftX=b%>OZ>{EO#?``>q0|KcwPWc}3}<>uA= zqgV1hOMzbJC((rst|p)|4AD&}w$B)s=H2)Bccat)?sX0NF#M1%F^4h?*$l+pF<>_} z5jE&fi;j;UdwT6Lp6}G%UHZsm1y}-qSL#I>VnhUHf!iK(g4pP2o9C~R5)(C%6$Bhk z*;olFnMB&-?wb&4EcZ&|fI@(Z%DO^n399(wRZfQc5Dc&3kmUnN0C#ZENT&)*+{`NJ z{o;EbPayj8wzqBv{qKoGCe_Z~Aar~uewwVTEZReaZcL6m^TJ_**pCnR_fvJm`{Q~< zYH^2pb>+7j?QaVpGAD803YA!{f__+!RlNA9aA&tJD3Yh4=u3> z6SlhqAZP_xkzvCQsQFZA=@f&fLCz^^-N?`zD-o5FJ`6TI{*(q_TGzmOaPtNGEJbbmEx|e1OK}W+@K5RL3go;&indZa0yIM1uX~eyB6H?QU4rI# z#N$aibT87PsK(1txUTJo&K9M@<#cT9S_ZR_8Nz2^ zMes{JYC{|n>*P1kq>Tx(%e8UBs(hu<4i05_pi-V3G_hYI3;-!k8q#a z*b;G(Z_A{oem@?r9)O%LAtt6^`|X0N9rsZK&=d>s^P4S(bPw4;x!dfrzazLrL{QN4 z<*i|y-K%_i^o!Rv2+Be8pSiR|)PCJu+xkbyrSwece12@WK>lC=ILo# z$QL{<*|)%1Hy^ec85(lTF&E+p`x7Y{$o$Y`D$id+GZDzW#9bDqvT4(%hK-sduAe4< z{P2Nn(qNtWyu0zLu+tD{>%g*Yrm**9p}v@?=w@)K;XDPag!r47JjPcIS~cU$RrVzz z&tC~N9&&!kRS$jzx2LtU>b;sC{D^5^N1)#CI?-~JWm2lY;b146wBOJk-;&zow3oke zk2nX{hsz*}IU9Xu7or~_##w$qzQ>fov|G<-uA?1+9FWU5Mog`R&zGRl6$X806ZU~_ z?Wy#o2|)|`z8Id6=b-EmyQ|<<-FsP@D`amWhnPf&*{lKM z+RfuL%NNih5);L~3x^JPQjQ`Y&d1JfzOLDKu5*hPF5I8O9hctAAyMjZC-*Zq&3Scw zP?+B?=BQpNhqR+VUCV7yg0v#W;SI8V@)1@g-D`4D%j>zCyQXr<^-9>d0~ySXn@7eW z>neEGG$$Lr^zHWEuZFG?sz6+_4tpH04P3qH27y)?9x;}OufxzHT<{#CSc zGq`+*$47ZS1A5-QY*29y@m($Dl)ne|uY&*mr2hY?Wj$9oD8qwRmI?|A_Rfd$zi3ux z&8JXQd=~cjZ)L!S-k$R1bJR{H$SV(dLFjcZD=W)lAM7P53$2ty2iw;XtpFj~cih?w zI%2Q3%QNkfi~9cD6KuBT-iM;zH$Q+u3VH0scXytg+|86Y=@*$gxI>51{QK(b%^es# zSujoXhY(1736bf?(vkP_AWHOL7(+}}mdMW8mS;2Y@#ce&4a8cY$E&A`R!s>|*|i^F z#^1l0g5C$qL@;1G-q?9Mb2N}StsvE*S++MSOt^N<12V^z%Yz3LSZ(^>6UXta;J+Ut|G&KJel7+P1Y%g%U z{u?5%SF5dF3Rj)@g9HsY>7F9u)V}^_e-%WG=U0(ma)3@~(i$l5al@WfWxGHfh(3c* zX#`z`k_uTT?f?VqwQyoHzOJHGPsGWJ_&*;xZOsUQumYt5btc_`26l=mI~j)9TidG* zu}K2`x)LERWcIp+laqqKU+TW;r_Ocab`0KDUQe6%oAPR>kPxj zSM$q11_uP#J#UCbiD%^(QILLc_mp?zMA+#QNfc_Zn8^5 zJkVl#@iwBiPsu@Vv8`cQVvfs{gaFlbI z2Mc2HvN$%0QoU8}>jw)bWE!a!xbx?n*V5*BJJ0&7`BJBV-%Rsd(~eFA8>Ofy9yCq5 zRU;qE$p&)bcktu&JEH|?2l6VeWpItp@z-MzvtjHOl<@(k%uOIyJ$!HY?_eP5`hiH# zT#a#wfwZ)=ldU`<%+_+ymF2e^t_Hv2kS5RR%TD`WiMxybJN2%Z-!}ohx6ZK`R#tXm z_&34ra|Q=n>?Xl`BjC3S5DG$Uk-(T)uFzAn;SmI*W&{(&+UqWVXq`3&BSK&H`=GMl zd*M@~9{dDt9;2@lV)Sk58|h9b?1G1oc|4e3pG>h*Vm*iJB4_7{T??_r>DcBdcYdoN zbVWk9amB1&=6bdyFC{ErOsPZ#0?7(MhsTnwbYDYLw#|wBF53K7A)Z63yCM8ArRMq{ z^hDQh=y_e;aw(zx;D^hnK>5bE+dPjWnq3M1ukVd{6eZbq?^HO6OC>c6yNcvN1aX_v+cM|zA!J-iSFf=3+g+KW0)Yj$+6Q&J9ce5dhYdrafHL>); zF@D7Akux3j!9msU+$Re9Ooic^gjwj2Zy+o6h>6rE3Np^;TS)tjMq`_a^dRw|V3Wd- z9n{gza0h5DJk4#=M{VRZ_fC=nc$1lk+os+t+t7i-*8-rj;p&g^;L`VP4B z1Fj?zpxK!UvZlcY4jdRXgqBufob7MmNtrA!*ICz&{VaZpv1vYkPWtfqh7=1Zws&L2 zf~u?03k}OARa&~H3-=;mI%m?7vb}rCZMUPBpMlKwi5Ygd^n(oV!)QdLZFh0UuaTp! zGfm|{ zwbP9e7}PKed|o*l*@^A}D8?JebK7@(oxJPgfXWlK#IP@E?8SZ{Z-mapI^`*6gVlZTD8bBSKIorp!Hfa zGb(&aE;4CS-s?AQvY6n}3tLlHv`~GA&eGnl2ge`WqAz&0TYg*g(={pz@O}ED3bW)Y%V1X6Hv*8up$!a&aEW-Gp1+hxb+^E4Y#fd|Q*&h;1sT=M z%K=s&MDy5aoq!h?u^oh}$#dkvpP8E_x(5=@E|lwpCZ#~$}16HdF$$fIr1ua^9*bz zfAH{Ow`Epas?j}hUYj?2L0z{JU`!orl9 zH}>LJBf>KX-R`OxE#D$|mrj zK14zH%Z$Ftrqqdtj@VgjM%374oK#LaQPN84fIea-1*o3lLcdzl|&8g2V7tnPNiI!&z`GvL1C2y%Nk+_Cg$6;`BmZN-=^pTTu^ zrdjb!v)(A^r72k6E=wGKfH`TyI%sD-u^VT$<0k=F?eQ{s?^2`OB1j)(NlZ?nH%{7< ziO8#E8a1u0t*ad2;%QtRnFiN@o_n*Hlg)x_iF+qyf3xoC&7x85q+57iH23sI>0TX+*vn5HI z^|fvt8YWuj@#(j6Ht3>$BmcZ$=({)}ojYo|50Pyt!JW!M*iU1OXd=gZX2IV_aF&JB z81u9v@NoPA;$OC=Vc_lCD+TcjqiUK0K2J<&V6mbdr6Py00Gz{UCNV@?R4-ojYbdiU z!xW{VQ*!qE+2Tc{t7!v7#!sC%ciOf6UY*KWUU2+3_a*K)f)c>)ukz$w7dX5IZ5sO2 zjW;ic7dEme8C*ABPOD~jK6*rmR2uuq*r|z+xR8g6Pn4CuJ<^%Hyo$8yS&!)@ z3e_4XI8+@S$;=r7U+$HluOLkB^C+clWU&Hd45&Ns*4y~6HLpv9@@XfOQ(-T*YxDdP zH4meQQ*s3zH{JH_-JUw!b>D+|?*S^(*NFOV4w?6@F;8>z+$R*?t#8$5IDItFzA6J> zQQMDzcFTFa&z4JdEhUy?qFX<8@B~`l>J#Rs!x_{E;mQZ(sVX%IQR+4ta`g9glJc~~ zOKWwtc}Cyhy4Y$oduX<@?Ob8G*@iFdjY28s{D(=8bESp)Z6KAWYqbfeH4(#4a6*~Err zA4h5twr?RPmenSAW4x~Ye7;~Ya_%EPL1_WJV*wu};wRlh^4Z9y6IpoIb~Eux0xdC` zQS745(}mlbew#H?Gr|W&n>!M-n;*whONlHx_M{>WXVuB)SqXqJneKcWw%pE($l$qy zhm?L-!63G!&+WF5eAvT#ZDh92!_tUSaAULcStS%wURRDcjfZyuZw(IJhnb%V7&$)l zn*Z99;u#mfoJ5}{LV-aqCQ+o%*pkZMj{{J)3&Nui*@>{b1(|6WK9g=?L@8gIJjKXs zPQ-br&cdrGtZTjVOs<0Vh>Yb7k)=$`6vl9l~B6tj2E_u7lBun6Jsi!$KAkD$b;&AD5*>bYI`0M-IUG-~J1pn9-}{ zN8SpY40iy5REe5I^q7;hB{WUz;-yz4c;-+t#C6p-E-5X=t1RWqk8tO2tdlH0ejIRF z;{i7j*z;=`H&Zr(2%-~9RQU%l?&bfWWXHwIEeuPdAdiFVoB1W{9a_JRqm_j;Szgkn z;he_lLz5Zd6%vY7m`89#>@=F^Sf_B#FLXg(zZ?)=P-Bh znj8M&RWQr^NvijMdsE2I(NQ+iV${&Oy?ExWp+b>rsY+_SnF_@ra!LM)R?a~q*~vGq zyaC7E8gP=_|1*2o-{d8in$g;)Qa74d$5R43ukY0c3Z)L?U9SCVC1sYSr7QFBR)Y%;D!RM8Z`iFwz>=0L zPg=ZGriSkq?B=7oy_L|@#O}&oTb?$ybg(FUIOoPs9&f9mBNpk}dt*`*7HFNzxv{Fr z)ZV-0WXvkd0@B;va`Y7o+)&V3g<`l$MEyxtr&AmRb{NHhJ#Gk@MQI&JcGh)y6^uhN zRqp&}+eNep$iTDgIB zSwj16?!)uCI@-P2+0-~mHOJwF@=NxVugj?MpCahg8p}~_P>DJ|DihgXPfmelo0=){^h|yMq*ah=(~6Ck`qpy zTIcGTqguHY3(&$o_nV?4gp~o?h>?BDdY_n*l7fdg|KoZktm}~UFwgSYfXx8#Ai)R$ z;$d;};|#*XN_)Ht%am5Gkv(t#{`ltaI#Hj4YJ&2bynH^~qz?X;etq!GU~`|U@dd;S6IIHZ5P*%# z^C{3U7uen1jCp$M$46qf8~8H4-5!l`6hh+X28KtvICd=&AqM)4u-ZrtH{c)hf4Tdki8%IE{zA>YjJMz6mv*-nFbh4Y0}caL zfrdy{j%e?yaY)S_3huz>#LXP0Q0W46GPV z;4lQ3q<&;=uyS^{2el=k;TB55FM}!M(=DFSl0AU#F-pdFzyOWe0P#0O z-i7Pvlgo7g8SdS?S6t&3$8PetKoA~z(COGM0L8kv4I`1&JR%!5vbvf4`=jz2y*r3f z^2Hn!nnl67!(23Y1?qZtpfABYYi%Y2cl`}zPocKn9l#9=G*FX-1DA+WvCI-NcnXLf z^$-t%MIurGdp`D^0+4+XByY{u&y$m(%o+Hgp?1Bn zkey;-V>6lf}|A6fLhd8r_1KAg*)hNUr zM5-7jBqTujjCY8fYIFjSKHJ75T)Olc6)xw>75S$6dVDwnb25wv#1QPrxwPgF2qo|X z$lD6RVstPzW6P9*JcHlGf~}&C9}C>@!9$6Xd`uWQ6Ysyjmsy`b=9Ud+Obb|f(gOAE zw-Aq%#0LToB|pC`2uV3oxZcy_Pr>!!k(ZN{T&h|Q@DYa(-rsfA58&}##r$@8s>7k= zo4yhpOC})npaTF=z{Wk1v7yiM@$zzzO01)`_aO`ch{ul8GF92l{qs>Z;}RaKIjHeE zdV6DVW^Uf0*@c`kAg*>L>uhXnFhyuprW_l#gM|t*tP5FL_NRh+dV5*hqz5q}$0K2O z6c@Z7CwQVeZ5*E3W;Q z@odn!3YL3W+VCk}IiIfm4$Zi8k+oSg7ma5F#810)HJScGWO99319Y* z|7Lkn$Jv9QNXd~8SvXqM^xZ?9yYlcKc=h*|p0m3(lr}5#m{c>*Xz%k3uFaPvWCK;% zzyv`fLcD&3Z)ZMYG;8KWwywA5x^l|d)t#T{voZX){)+Tr&^IgcjxL8>-E+^dfj|b= zZb8&LL;aFQ@0S@7p6&!pHb(Fjnex>de+ol2RgB8@b3M~tK$fx=c;7DTVPpD+)H z#yUN}h}f&SGF`uH8hja4dg;0L=AzCl;q+&OGX3e{gVB7f@<--5Okes7+lX>TD^_l} ze`?z8+12h+^+uYjkVERfe;h_q1;r+9y{J`lRj3~z37qy^so4p3!lkaRvq>;}Q~n8Y zmj^YcM|Gn{95e4ZHy9V*HJdxPvW?i4+MaC}q`8YF^>tN-5Wm&iC!$sE$&~)D4dRvA zRX?~ByIcy~5sL=N5X-E^f_Gs!zUpSq7J8NGQPk@?05{zRlIyE~YAH=V)8( zyjrA~l9Tp4Q8b-jddJ4?EDv6#y?`{vYdO>%8R6JJ z0EfU9l1fz%@K8-eEc>X3k3auJ$(ERktda@eBvIg?N@5pMJ_%z6rLzxyarL$+5MQw3 z%`ACJVH7uRNw?d= z$kI0a73JH9Eb1wf*{FTpP*rAT!oKme-dUTcu&Rc{a@52(v?LPk5Q;WN*}USE4ny9p-nW z#y95s+uyyIoqeEeQw9O-+^FMJ9|O;6zNkKlGix4iTX#SD!rW(o%|m+91~v;CMfTi~ zr)hqg(H9BH=V_)jj*sdH>2O&ON$$W`lZAwyk}Yae%V ze<~&Waa&uPbeOHrhIguLp#e$LoBiI?K7GCnW}mAsokR@Fo7Ugq`z~;E^={X~dvZ#( zDv2`Ptz?`1$6~GQ!!GelAO3@5%zwY&!3LI~dm1JC{mbRoB65k=48UyTY&<1Oye8UR zFmw5`HFv{19aps*hi$8qD&$mqTK^7f%HVp=_p(0NJZmr?z z#5YmDMyc2Z8%I&ui3BxF-q9 z+9liMUMQoWUP*dtE^X9{rN$o?D*on4V#rSZ~ggIVCbFYmuEdsy| zmc9{M?+-NIJ$v>D=BS>D%N_2)$PCzx05>sF+t;u*peg$C{kwURDZpQFZ;&UZteY?) zbP$Lk+roMUn*060fd8ZK5<>1Y@On{)5H?!uehT`!+BLD_gpfXzNB1gTwfD%XY=_?)gd1Tz%nP}N6=(fVjtVf`l0I!tq%z2 zUcH*b&svWF|pig`3Mxu$%tR(guVkPER@3N1kHZu6d8hQKc`EG z*(#Tymh5PI&TWE7s1X~(t`#p3mw?6|Q{i4~fmhSu+x(kWd=jVAkc6eVJ+XCnAC3Kx z{3ONjY{Ho{b5{)nVjt3Iz2#QV?iVi>Y;rMb3Iid5sMX)gSFb*X-pdcr+65zQ3fYe& zC+q9Snhig4Ocuutym_M#Ts%{G_il{R*Nd1hHaz+uePd3W{>@GcxoXTQPzcbgkSo4Y zgDPjY%>w=F2l|fsMwi=r(rbp2_c2H!Ax%e`$|jr1Y;nw(;&+C+RGT>3dGKIO$cM9rputU4e9I4HQo44};;d}lgvUTM7_%L$WD&YZ z4{(Xxi|!6CzxtEv>UCU778ZqTl(Qd#62l%9VgxnKKaAz!fedP|*bm6NLPJ6gu9IETyYgB(u`PyQ3d`>Rtc0 zC+)-I21!O*qjngDZyG{Lp5`p?QPBTa2Wm7&&!YThm(EKUmQBrXH zx9!1oHu6@d_?!mEgx&eEeZ+IqXovlC16&8OWLY+s%5+0on7A-a|j;u5h9TQXgGq3xs(EdfIPlF01_oCr^Cf!YvgEA$NJAAt6 z;QaOP(Y51I0b?kK?MrxWcvA(Djt)%j8)_i*SI5L6Ax+wHgT^|dxOj$DnRW`s+k9pVSecj@)yXivr2j2hWGkau?J%}pFoDZjH%LpuZ?5#%Pp zO~F1bu^c+8BZP+5?SM4*VD2nPsWrLp!Jn=U)?+-i4N+}x-n_AQ?qfqb%i(49$P%wM z>U2*l8N>4ExPay|C8gy{FJxzD<5rqUMH0QVYq9DhA%tOK5`y6NYR9L9s%COu*n3$4 zfm0ZjRA)L^5RJ4KF$9hu|Fdp!m^)4|>n%!n9@kz=3DSIt%Oj*axAlSBS3MeZb-`d1 z2ubISYY_*kzMOQppIZ4H@;-P*tt*U(<5*a{BAv2m&9OyB-=Us@Fk!A@`Q^QOdU{K^ zzS^wR61HSew=5Hvl&Q+=8e_`{bz#BHLj5Rd!aaHEyRHYn7^f}N1cd18qm#Y3^yt47 zD{lis_IXwg0Y8}=Fn0?^N)(y0lM;=@k&+Xeqr%& zTYI~0#`qla!SIJD=PzD73ua&x2N?PWP1n45r7tfHMNs}F6^R@e z7eWiKlGAgP!F=`f$&)7#L@M~XeLA=9I(NM*0yOZE+J&l zYP#47e-YaA0qxd|8gLF%U@cu9EFcm{jh(WfuM{RC6~VcsgP!2lkZY+ybJ~A(qao0U z+S@1+EfdC>i)<5VJR8?g3<;&lab*70)YQO-brAQMrb|ER$7!XD)l~WtTh-g7-LcRz zz#W}U$VWSfMBl|nzqbQ5*Cxamw&Sa5)i+M>5(v%1J%H_Gj*c@e!w6OEYSDh>7(YpV z!ew8dMwZNkFklr0CoO>7AbJJswreV`j^{qrqo;_x;K7;MJ9 z!O0ZURfVKu&z{$WhRhmM=R|;tg(_1~;U}~riIi-WF0KG>35XvhU#*$XJ(@uB2%l$x zI&LvR4U3r8;hHkc`P_Siss<9K{$Q?Gj2AKbGUf!uKu1m3T*_pTA1sp{C(px=9*7i#?;R%&Kb4lrm@QpXs zD8`h*BG&b2vn~lv-Kn?%hv!!yR&$$QbF$h0IDCHm_1kI<4tboPI5KN_X*|o*DP2(+ zHNAxY&MuwKphr0{{IFdGhL+nF7h!kMqLsV-{dj|b2FN4$yPggM0i*$I86?BAaTsns zfBE8k%QI==rW_jd0DsE_Tkum*nZ^FAY4?8y(bptXkh9JwOthLY+RXyT5D5QApl$7p V$sZlkJre#~Z?W0@h8g|D{{hCb`Gx=h literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/mdk_keil.png b/bsp/gd32/docs/figures/mdk_keil.png new file mode 100644 index 0000000000000000000000000000000000000000..4ea47c3d21bf68ad6a9b486cb073ff3c10fcc611 GIT binary patch literal 60061 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 z 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%0DR%{p8xf$bgt9oYb+ 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 literal 0 HcmV?d00001 diff --git a/bsp/gd32/docs/figures/install_pack.png b/bsp/gd32/docs/figures/install_pack.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa3b5253be73ddecd6e8a4d3298ad32a9906f97 GIT binary patch literal 37297 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