From c87f279beaae55eda15c574ce59b79eda4be7bb4 Mon Sep 17 00:00:00 2001 From: Jianping Wu Date: Wed, 12 Nov 2025 17:58:12 +0800 Subject: [PATCH] modules: hal_gigadevice: add gd32c2x1 support Add gd32c2x1 initial support for zephyr hal_gigadevice. Signed-off-by: Jianping Wu --- common_include/gd32_adc.h | 2 + common_include/gd32_cmp.h | 2 + common_include/gd32_crc.h | 2 + common_include/gd32_dbg.h | 2 + common_include/gd32_dma.h | 2 + common_include/gd32_exti.h | 2 + common_include/gd32_fmc.h | 2 + common_include/gd32_fwdgt.h | 2 + common_include/gd32_gpio.h | 2 + common_include/gd32_i2c.h | 2 + common_include/gd32_misc.h | 2 + common_include/gd32_pmu.h | 2 + common_include/gd32_rcu.h | 2 + common_include/gd32_rtc.h | 2 + common_include/gd32_spi.h | 2 + common_include/gd32_syscfg.h | 2 + common_include/gd32_timer.h | 2 + common_include/gd32_usart.h | 2 + common_include/gd32_wwdgt.h | 2 + gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1.h | 221 ++ .../gd/gd32c2x1/include/gd32c2x1_err_report.h | 93 + .../gd/gd32c2x1/include/system_gd32c2x1.h | 66 + .../gd/gd32c2x1/source/gd32c2x1_err_report.c | 77 + .../gd/gd32c2x1/source/system_gd32c2x1.c | 354 +++ .../include/gd32c2x1_adc.h | 441 +++ .../include/gd32c2x1_cmp.h | 145 + .../include/gd32c2x1_crc.h | 119 + .../include/gd32c2x1_dbg.h | 116 + .../include/gd32c2x1_dma.h | 569 ++++ .../include/gd32c2x1_exti.h | 282 ++ .../include/gd32c2x1_fmc.h | 461 +++ .../include/gd32c2x1_fwdgt.h | 123 + .../include/gd32c2x1_gpio.h | 393 +++ .../include/gd32c2x1_i2c.h | 403 +++ .../include/gd32c2x1_libopt.h | 59 + .../include/gd32c2x1_misc.h | 82 + .../include/gd32c2x1_pmu.h | 155 + .../include/gd32c2x1_rcu.h | 716 +++++ .../include/gd32c2x1_rtc.h | 504 ++++ .../include/gd32c2x1_spi.h | 432 +++ .../include/gd32c2x1_syscfg.h | 316 +++ .../include/gd32c2x1_timer.h | 842 ++++++ .../include/gd32c2x1_usart.h | 618 ++++ .../include/gd32c2x1_wwdgt.h | 107 + .../standard_peripheral/source/gd32c2x1_adc.c | 964 +++++++ .../standard_peripheral/source/gd32c2x1_cmp.c | 378 +++ .../standard_peripheral/source/gd32c2x1_crc.c | 258 ++ .../standard_peripheral/source/gd32c2x1_dbg.c | 135 + .../standard_peripheral/source/gd32c2x1_dma.c | 1149 ++++++++ .../source/gd32c2x1_exti.c | 260 ++ .../standard_peripheral/source/gd32c2x1_fmc.c | 1249 ++++++++ .../source/gd32c2x1_fwdgt.c | 242 ++ .../source/gd32c2x1_gpio.c | 421 +++ .../standard_peripheral/source/gd32c2x1_i2c.c | 976 +++++++ .../source/gd32c2x1_misc.c | 142 + .../standard_peripheral/source/gd32c2x1_pmu.c | 345 +++ .../standard_peripheral/source/gd32c2x1_rcu.c | 1116 ++++++++ .../standard_peripheral/source/gd32c2x1_rtc.c | 977 +++++++ .../standard_peripheral/source/gd32c2x1_spi.c | 1046 +++++++ .../source/gd32c2x1_syscfg.c | 309 ++ .../source/gd32c2x1_timer.c | 2526 +++++++++++++++++ .../source/gd32c2x1_usart.c | 1354 +++++++++ .../source/gd32c2x1_wwdgt.c | 186 ++ .../pinctrl/gd32c231c(6-8)xx-pinctrl.h | 819 ++++++ .../pinctrl/gd32c231f(6-8)xx-pinctrl.h | 519 ++++ .../pinctrl/gd32c231g(6-8)xx-pinctrl.h | 635 +++++ .../pinctrl/gd32c231k(6-8)xx-pinctrl.h | 689 +++++ pinconfigs/gd32c231xx.yml | 507 ++++ 68 files changed, 24934 insertions(+) create mode 100644 gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1.h create mode 100644 gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1_err_report.h create mode 100644 gd32c2x1/cmsis/gd/gd32c2x1/include/system_gd32c2x1.h create mode 100644 gd32c2x1/cmsis/gd/gd32c2x1/source/gd32c2x1_err_report.c create mode 100644 gd32c2x1/cmsis/gd/gd32c2x1/source/system_gd32c2x1.c create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_adc.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_cmp.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_crc.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_dbg.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_dma.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_exti.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_fmc.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_fwdgt.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_gpio.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_i2c.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_libopt.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_misc.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_pmu.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_rcu.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_rtc.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_spi.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_syscfg.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_timer.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_usart.h create mode 100644 gd32c2x1/standard_peripheral/include/gd32c2x1_wwdgt.h create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_adc.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_cmp.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_crc.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_dbg.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_dma.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_exti.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_fmc.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_fwdgt.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_gpio.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_i2c.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_misc.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_pmu.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_rcu.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_rtc.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_spi.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_syscfg.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_timer.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_usart.c create mode 100644 gd32c2x1/standard_peripheral/source/gd32c2x1_wwdgt.c create mode 100644 include/dt-bindings/pinctrl/gd32c231c(6-8)xx-pinctrl.h create mode 100644 include/dt-bindings/pinctrl/gd32c231f(6-8)xx-pinctrl.h create mode 100644 include/dt-bindings/pinctrl/gd32c231g(6-8)xx-pinctrl.h create mode 100644 include/dt-bindings/pinctrl/gd32c231k(6-8)xx-pinctrl.h create mode 100644 pinconfigs/gd32c231xx.yml diff --git a/common_include/gd32_adc.h b/common_include/gd32_adc.h index 3aa3983..6d655d5 100644 --- a/common_include/gd32_adc.h +++ b/common_include/gd32_adc.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_cmp.h b/common_include/gd32_cmp.h index 45356e6..f5506b1 100644 --- a/common_include/gd32_cmp.h +++ b/common_include/gd32_cmp.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include #elif defined(CONFIG_SOC_SERIES_GD32F3X0) diff --git a/common_include/gd32_crc.h b/common_include/gd32_crc.h index 6da4361..0beaecc 100644 --- a/common_include/gd32_crc.h +++ b/common_include/gd32_crc.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_dbg.h b/common_include/gd32_dbg.h index 4a639da..a026dcc 100644 --- a/common_include/gd32_dbg.h +++ b/common_include/gd32_dbg.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_dma.h b/common_include/gd32_dma.h index ef4446f..7d2a75e 100644 --- a/common_include/gd32_dma.h +++ b/common_include/gd32_dma.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_exti.h b/common_include/gd32_exti.h index fbf9b67..f13deef 100644 --- a/common_include/gd32_exti.h +++ b/common_include/gd32_exti.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_fmc.h b/common_include/gd32_fmc.h index a626a17..01c1f40 100644 --- a/common_include/gd32_fmc.h +++ b/common_include/gd32_fmc.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_fwdgt.h b/common_include/gd32_fwdgt.h index b319122..b243310 100644 --- a/common_include/gd32_fwdgt.h +++ b/common_include/gd32_fwdgt.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_gpio.h b/common_include/gd32_gpio.h index 977ffe6..7da9f26 100644 --- a/common_include/gd32_gpio.h +++ b/common_include/gd32_gpio.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_i2c.h b/common_include/gd32_i2c.h index 7921659..54a5972 100644 --- a/common_include/gd32_i2c.h +++ b/common_include/gd32_i2c.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_misc.h b/common_include/gd32_misc.h index 059fa66..4756f8c 100644 --- a/common_include/gd32_misc.h +++ b/common_include/gd32_misc.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_pmu.h b/common_include/gd32_pmu.h index dd5b605..4373916 100644 --- a/common_include/gd32_pmu.h +++ b/common_include/gd32_pmu.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_rcu.h b/common_include/gd32_rcu.h index b14342b..fa85703 100644 --- a/common_include/gd32_rcu.h +++ b/common_include/gd32_rcu.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_rtc.h b/common_include/gd32_rtc.h index 4f015a0..e56c865 100644 --- a/common_include/gd32_rtc.h +++ b/common_include/gd32_rtc.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_spi.h b/common_include/gd32_spi.h index 0f61fc6..1438503 100644 --- a/common_include/gd32_spi.h +++ b/common_include/gd32_spi.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_syscfg.h b/common_include/gd32_syscfg.h index 89c5284..4bbd2f9 100644 --- a/common_include/gd32_syscfg.h +++ b/common_include/gd32_syscfg.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32F3X0) #include #elif defined(CONFIG_SOC_SERIES_GD32F4XX) diff --git a/common_include/gd32_timer.h b/common_include/gd32_timer.h index be74a7c..7d99a28 100644 --- a/common_include/gd32_timer.h +++ b/common_include/gd32_timer.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_usart.h b/common_include/gd32_usart.h index 121ac55..52be1ba 100644 --- a/common_include/gd32_usart.h +++ b/common_include/gd32_usart.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/common_include/gd32_wwdgt.h b/common_include/gd32_wwdgt.h index d8e49b8..25d1ea1 100644 --- a/common_include/gd32_wwdgt.h +++ b/common_include/gd32_wwdgt.h @@ -6,6 +6,8 @@ #if defined(CONFIG_SOC_SERIES_GD32A50X) #include +#elif defined(CONFIG_SOC_SERIES_GD32C2X1) +#include #elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) diff --git a/gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1.h b/gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1.h new file mode 100644 index 0000000..487b537 --- /dev/null +++ b/gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1.h @@ -0,0 +1,221 @@ +/*! + \file gd32c2x1.h + \brief general definitions for gd32c2x1 + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_H +#define GD32C2X1_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* define GD32C2x1 */ +#if !defined (GD32C2x1) +#define GD32C2x1 +#endif /* define GD32C2x1 */ +#if !defined (GD32C2x1) +#error "Please select the target gd32c2x1 device used in your application (in gd32c2x1.h file)" +#endif /* undefine GD32C2x1 tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined (HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)8000000) +#endif /* high speed crystal oscillator value */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0FFFF) +#endif /* high speed crystal oscillator startup timeout */ + +/* define value of internal 48MHz RC oscillator (IRC48M) in Hz */ +#if !defined (IRC48M_VALUE) +#define IRC48M_VALUE ((uint32_t)48000000) +#endif /* internal 48MHz RC oscillator value */ + +/* define startup timeout value of internal 48MHz RC oscillator (IRC48M) */ +#if !defined (IRC48M_STARTUP_TIMEOUT) +#define IRC48M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 48MHz RC oscillator startup timeout */ + +#if !defined (IRC48M_VALUE) +#define IRC48M_VALUE ((uint32_t)48000000) +#endif /* IRC48M_VALUE */ + +/* 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 */ + +/* gd32c2x1 firmware library version number V1.0 */ +#define __GD32C2X1_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __GD32C2X1_STDPERIPH_VERSION_SUB1 (0x01) /*!< [23:16] sub1 version */ +#define __GD32C2X1_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32C2X1_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32C2X1_STDPERIPH_VERSION ((__GD32C2X1_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32C2X1_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32C2X1_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32C2X1_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M23 processor and core peripherals */ +#define __CM23_REV 0x0100U /*!< Core revision r1p0 */ +#define __SAUREGION_PRESENT 0U /*!< SAU regions are not present */ +#define __MPU_PRESENT 0U /*!< MPU is present */ +#define __VTOR_PRESENT 1U /*!< VTOR is present */ +#define __NVIC_PRIO_BITS 2U /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ + +/* define interrupt number */ +typedef enum IRQn { + /* Cortex-M23 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< non maskable interrupt */ + HardFault_IRQn = -13, /*!< hardfault interrupt */ + SVCall_IRQn = -5, /*!< sv call interrupt */ + PendSV_IRQn = -2, /*!< pend sv interrupt */ + SysTick_IRQn = -1, /*!< system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + TIMESTAMP_IRQn = 1, /*!< RTC TimeStamp interrupt */ + FMC_IRQn = 3, /*!< FMC interrupt */ + RCU_IRQn = 4, /*!< RCU interrupt */ + EXTI0_IRQn = 5, /*!< EXTI line 0 interrupts */ + EXTI1_IRQn = 6, /*!< EXTI line 1 interrupts */ + EXTI2_IRQn = 7, /*!< EXTI line 2 interrupts */ + EXTI3_IRQn = 8, /*!< EXTI line 3 interrupts */ + EXTI4_IRQn = 9, /*!< EXTI line 4 interrupts */ + DMA_Channel0_IRQn = 10, /*!< DMA channel 0 interrupt */ + DMA_Channel1_IRQn = 11, /*!< DMA channel 1 interrupt */ + DMA_Channel2_IRQn = 12, /*!< DMA channel 2 interrupt */ + ADC_IRQn = 13, /*!< ADC interrupts */ + USART0_IRQn = 14, /*!< USART0 interrupt */ + USART1_IRQn = 15, /*!< USART1 interrupt */ + USART2_IRQn = 16, /*!< USART2 interrupt */ + I2C0_EV_IRQn = 17, /*!< I2C0 event interrupt */ + I2C0_ER_IRQn = 18, /*!< I2C0 error interrupt */ + I2C1_EV_IRQn = 19, /*!< I2C1 event interrupt */ + I2C1_ER_IRQn = 20, /*!< I2C1 error interrupt */ + SPI0_IRQn = 21, /*!< SPI0 interrupt */ + SPI1_IRQn = 22, /*!< SPI1 interrupt */ + RTC_Alarm_IRQn = 23, /*!< RTC Alarm interrupt */ + EXTI5_9_IRQn = 24, /*!< EXTI line 5 to 9 interrupts */ + TIMER0_TRG_CMT_UP_BRK_IRQn = 25, /*!< TIMER0 Trigger, commutation, Update, Break interrupt */ + TIMER0_Channel_IRQn = 26, /*!< TIMER0 capture compare interrupt */ + TIMER2_IRQn = 27, /*!< TIMER2 interrupt */ + TIMER13_IRQn = 28, /*!< TIMER13 interrupt */ + TIMER15_IRQn = 29, /*!< TIMER15 interrupt */ + TIMER16_IRQn = 30, /*!< TIMER16 interrupt */ + EXTI10_15_IRQn = 31, /*!< EXTI line 10 to 15 interrupts */ + DMAMUX_IRQn = 33, /*!< DMAMUX interrupt */ + CMP0_IRQn = 34, /*!< Comparator 0 interrupt */ + CMP1_IRQn = 35, /*!< Comparator 1 interrupt */ + I2C0_WKUP_IRQn = 36, /*!< I2C0 Wakeup interrupt */ + I2C1_WKUP_IRQn = 37, /*!< I2C1 Wakeup interrupt */ + USART0_WKUP_IRQn = 38, /*!< USART0 Wakeup interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm23.h" +#include "system_gd32c2x1.h" +#include +#ifdef FW_DEBUG_ERR_REPORT +#include "gd32c2x1_err_report.h" +#endif /* FW_DEBUG_ERR_REPORT */ + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG64(addr) (*(volatile uint64_t *)(uint32_t)(addr)) +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#ifndef BIT +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) +#endif +#define BITS(start, end) ((0xFFFFFFFFUL << (uint8_t)(start)) & (0xFFFFFFFFUL >> (31U - (uint8_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM base address */ +/* peripheral memory map */ +#define APB_BUS_BASE ((uint32_t)0x40000000U) /*!< apb base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */ +/* advanced peripheral bus 2 memory map */ +#define SYSCFG_BASE (APB_BUS_BASE + 0x00010000U) /*!< SYSCFG base address */ +#define EXTI_BASE (APB_BUS_BASE + 0x00010400U) /*!< EXTI base address */ +#define TIMER_BASE (APB_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define ADC_BASE (APB_BUS_BASE + 0x00012400U) /*!< ADC base address */ +#define SPI_BASE (APB_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define USART_BASE (APB_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define RTC_BASE (APB_BUS_BASE + 0x00002800U) /*!< RTC base address */ +#define WWDGT_BASE (APB_BUS_BASE + 0x00002C00U) /*!< WWDGT base address */ +#define FWDGT_BASE (APB_BUS_BASE + 0x00003000U) /*!< FWDGT base address */ +#define I2C_BASE (APB_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define PMU_BASE (APB_BUS_BASE + 0x00007000U) /*!< PMU base address */ +#define CMP_BASE (APB_BUS_BASE + 0x00017C00U) /*!< CMP base address */ +/* advanced high performance bus 1 memory map */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ +#define DMA_CHANNEL_BASE (DMA_BASE + 0x00000008U) /*!< DMA channel base address */ +#define DMAMUX_BASE (AHB1_BUS_BASE + 0x00000800U) /*!< DMA base address */ +#define RCU_BASE (AHB1_BUS_BASE + 0x00001000U) /*!< RCU base address */ +#define FMC_BASE (AHB1_BUS_BASE + 0x00002000U) /*!< FMC base address */ +#define CRC_BASE (AHB1_BUS_BASE + 0x00003000U) /*!< CRC base address */ +/* advanced high performance bus 2 memory map */ +#define GPIO_BASE (AHB2_BUS_BASE + 0x00000000U) /*!< GPIO base address */ +/* option byte and debug memory map */ +#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */ +#define DBG_BASE ((uint32_t)0x40015800U) /*!< DBG base address */ + +#define VREF_BASE ((uint32_t)0x40010030U) /*!< VREF base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32c2x1_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef __cplusplus +} +#endif + +#endif /* gd32c2x1_H */ diff --git a/gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1_err_report.h b/gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1_err_report.h new file mode 100644 index 0000000..ac02f29 --- /dev/null +++ b/gd32c2x1/cmsis/gd/gd32c2x1/include/gd32c2x1_err_report.h @@ -0,0 +1,93 @@ +/*! + \file gd32c2x1_report_err.h + \brief Reporting Error driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 ERR_REPORT_H +#define ERR_REPORT_H + +#include "gd32c2x1.h" + +/* define the size of the error report buffer */ +#define ERR_REPORT_BUFFER_SIZE 2U + +/* define the unique identifier of peripherals */ +#define SYSCFG_MODULE_ID ((uint8_t)0x01U) /*!< SYSCFG module ID */ +#define FMC_MODULE_ID ((uint8_t)0x02U) /*!< FMC module ID */ +#define PMU_MODULE_ID ((uint8_t)0x03U) /*!< PMU module ID */ +#define RCU_MODULE_ID ((uint8_t)0x04U) /*!< RCU module ID */ +#define EXTI_MODULE_ID ((uint8_t)0x05U) /*!< EXTI module ID */ +#define GPIO_MODULE_ID ((uint8_t)0x06U) /*!< GPIO module ID */ +#define CRC_MODULE_ID ((uint8_t)0x07U) /*!< CRC module ID */ +#define DMA_DMAMUX_MODULE_ID ((uint8_t)0x08U) /*!< DMA and DMAMUX module ID */ +#define DBG_MODULE_ID ((uint8_t)0x09U) /*!< DBG module ID */ +#define ADC_MODULE_ID ((uint8_t)0x0AU) /*!< ADC module ID */ +#define FWDGT_MODULE_ID ((uint8_t)0x0BU) /*!< FDGT module ID */ +#define WWDGT_MODULE_ID ((uint8_t)0x0CU) /*!< WDGT module ID */ +#define RTC_MODULE_ID ((uint8_t)0x0DU) /*!< RTC module ID */ +#define TIMER_MODULE_ID ((uint8_t)0x0EU) /*!< TIMER module ID */ +#define USART_MODULE_ID ((uint8_t)0x0FU) /*!< USART module ID */ +#define I2C_MODULE_ID ((uint8_t)0x10U) /*!< I2C module ID */ +#define SPI_MODULE_ID ((uint8_t)0x11U) /*!< SPI module ID */ +#define CMP_MODULE_ID ((uint8_t)0x12U) /*!< CMP module ID */ +#define MISC_MODULE_ID ((uint8_t)0x13U) /*!< MISC module ID */ + +/* define the unique identifier of error type */ +#define ERR_PERIPH ((uint8_t)0x01U) /*!< peripheral error */ +#define ERR_PARAM_POINTER ((uint8_t)0x02U) /*!< invalid pointer */ +#define ERR_PARAM_OUT_OF_RANGE ((uint8_t)0x03U) /*!< out of range */ +#define ERR_PARAM_INVALID ((uint8_t)0x04U) /*!< invalid parameter */ + +/* define the unique identifier of API */ +#define API_ID(x) ((uint16_t)(x)) /*!< API ID */ + +/* check the invalid pointer */ +#define NOT_VALID_POINTER(x) ((void *) 0 == (x)) /*!< check the invalid pointer */ +#define PARAM_CHECK_ERR_RETURN(type) ((type)0) /*!< the return value of parameter check */ + +/* defining the structure to store the parameters of Report Error function */ +typedef struct { + /* module ID where the error occurred */ + uint16_t moduleid; + /* API ID associated with the error */ + uint16_t apiid; + /* error ID indicating the specific error type */ + uint8_t errid; +} err_report_struct; +/* declare external arrays and variables for error reporting */ +extern err_report_struct err_report_buffer[]; +/* index to track the next available position in the error report buffer */ +extern uint8_t err_report_buff_index; + +/* reporting errors in debug mode */ +void fw_debug_report_err(uint16_t moduleid, uint16_t apiid, uint8_t errid); + +#endif /* ERR_REPORT_H */ \ No newline at end of file diff --git a/gd32c2x1/cmsis/gd/gd32c2x1/include/system_gd32c2x1.h b/gd32c2x1/cmsis/gd/gd32c2x1/include/system_gd32c2x1.h new file mode 100644 index 0000000..156e64a --- /dev/null +++ b/gd32c2x1/cmsis/gd/gd32c2x1/include/system_gd32c2x1.h @@ -0,0 +1,66 @@ +/*! + \file system_gd32c2x1.h + \brief CMSIS Cortex-M23 Device Peripheral Access Layer Header File for + gd32c2x1 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_GD32C2x1_H +#define SYSTEM_GD32C2x1_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* firmware version can be aquired by uncommenting the macro */ +#define __FIRMWARE_VERSION_DEFINE + +/* 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 __FIRMWARE_VERSION_DEFINE +/* get firmware version */ +extern uint32_t gd32c2x1_firmware_version_get(void); +#endif /* __FIRMWARE_VERSION_DEFINE */ + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_GD32C2x1_H */ diff --git a/gd32c2x1/cmsis/gd/gd32c2x1/source/gd32c2x1_err_report.c b/gd32c2x1/cmsis/gd/gd32c2x1/source/gd32c2x1_err_report.c new file mode 100644 index 0000000..def66ea --- /dev/null +++ b/gd32c2x1/cmsis/gd/gd32c2x1/source/gd32c2x1_err_report.c @@ -0,0 +1,77 @@ +/*! + \file gd32xxx_report_err.c + \brief Reporting Error driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_err_report.h" + +#define ERROR_HANDLE(s) do{}while(1) + +__WEAK void fw_error_notification(void); + +/* initialize the error report buffer and index */ +err_report_struct err_report_buffer[ERR_REPORT_BUFFER_SIZE]; + +uint8_t err_report_buff_index = 0x00U; + +/*! + \brief reporting error in debug mode + \param[in] moduleid: module ID where the error occurred + \param[in] apiid: API ID associated with the error + \param[in] errid: error ID indicating the specific error type + \param[out] err_report_buffer: stores the id of the error type + \retval none +*/ +void fw_debug_report_err(uint16_t moduleid, uint16_t apiid, uint8_t errid) +{ + err_report_struct *debug_report_err_buffer; + + if(err_report_buff_index < ERR_REPORT_BUFFER_SIZE) { + debug_report_err_buffer = &err_report_buffer[err_report_buff_index++]; + debug_report_err_buffer->moduleid = moduleid; + debug_report_err_buffer->apiid = apiid; + debug_report_err_buffer->errid = errid; + } else { + /* illegal parameters */ + } + fw_error_notification(); +} + +/*! + \brief the notification of parameter check + \param[in] none + \param[out] none + \retval none +*/ +__WEAK void fw_error_notification(void){ + ERROR_HANDLE("Parameter Check Error!"); +} diff --git a/gd32c2x1/cmsis/gd/gd32c2x1/source/system_gd32c2x1.c b/gd32c2x1/cmsis/gd/gd32c2x1/source/system_gd32c2x1.c new file mode 100644 index 0000000..ff7c501 --- /dev/null +++ b/gd32c2x1/cmsis/gd/gd32c2x1/source/system_gd32c2x1.c @@ -0,0 +1,354 @@ +/*! + \file system_gd32c2x1.c + \brief CMSIS Cortex-M23 Device Peripheral Access Layer Source File for + gd32c2x1 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 "gd32c2x1.h" + +/* system frequency define */ +#define __IRC48M (IRC48M_VALUE) /* internal 48 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __LXTAL (LXTAL_VALUE) /* low speed crystal oscillator frequency */ +#define __IRC32K (IRC32K_VALUE) /* internal 32 KHz RC oscillator frequency */ +#define __SYS_OSC_CLK (__IRC48M) /* main oscillator frequency */ + +#define VECT_TAB_OFFSET (uint32_t)0x00000000U /* vector table base offset */ + +/* select a system clock by uncommenting the following line */ +#define __SYSTEM_CLOCK_IRC48M (__IRC48M) +//#define __SYSTEM_CLOCK_HXTAL (__HXTAL) + +//#define __SYSTEM_CLOCK_LXTAL (__LXTAL) +//#define __SYSTEM_CLOCK_IRC32K (__IRC32K) + +#define SEL_IRC48MDIV 0x00 +#define SEL_HXTAL 0x01 +#define SEL_IRC32K 0x02 +#define SEL_LXTAL 0x03 +#define SEL_HXTALBPS 0x04 + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_HXTAL +uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL; +static void system_clock_hxtal(void); + +#elif defined (__SYSTEM_CLOCK_IRC48M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC48M; +static void system_clock_irc48m(void); + +#elif defined (__SYSTEM_CLOCK_LXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_LXTAL; +static void system_clock_lxtal(void); + +#elif defined (__SYSTEM_CLOCK_IRC32K) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC32K; +static void system_clock_IRC32K(void); +#endif /* __SYSTEM_CLOCK_HXTAL */ + +/* 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 + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. +*/ +void SystemInit(void) +{ + /* enable IRC48M */ + RCU_CTL0 |= RCU_CTL0_IRC48MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC48MSTB)) { + } + RCU_CFG0 &= ~RCU_CFG0_SCS; + /* reset CTL register */ + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_HXTALBPS ); + /* reset RCU */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APBPSC | \ + RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV ); + + + RCU_CFG1 &= ~(RCU_CFG1_ADCPSC | RCU_CFG1_USART0SEL | RCU_CFG1_ADCSEL); + + RCU_INT = 0x00000000U; + + /* configure system clock */ + 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_HXTAL + system_clock_hxtal(); +#elif defined (__SYSTEM_CLOCK_IRC48M) + system_clock_irc48m(); +#elif defined (__SYSTEM_CLOCK_LXTAL) + system_clock_lxtal(); +#elif defined (__SYSTEM_CLOCK_IRC32K) + system_clock_IRC32K(); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ +} + +#ifdef __SYSTEM_CLOCK_HXTAL +/*! + \brief configure the system clock to 8M by HXTAL + \param[in] none + \param[out] none + \retval none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. +*/ +static void system_clock_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + if((HXTAL_VALUE > 24000000U) && (HXTAL_VALUE <= 48000000U)) { + FMC_WS =(FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_1; + } + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)) { + while(1) { + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB = AHB */ + RCU_CFG0 |= RCU_APB_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_HXTAL) { + } +} + +#elif defined (__SYSTEM_CLOCK_IRC48M) +/*! + \brief configure the system clock to IRC48M + \param[in] none + \param[out] none + \retval none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. +*/ +static void system_clock_irc48m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + FMC_WS =(FMC_WS & (~FMC_WS_WSCNT)) | FMC_WAIT_STATE_1; + + /* enable IRC48M */ + RCU_CTL0 |= RCU_CTL0_IRC48MEN; + /* IRC48M divide by 1 */ + rcu_irc48mdiv_sys_clock_config(RCU_IRC48MDIV_SYS_1); + + /* wait until IRC48M is stable or the startup time is longer than IRC48M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_IRC48MSTB); + } while((0U == stab_flag) && (IRC48M_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_IRC48MSTB)) { + while(1) { + } + } + + /* IRC48M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB = AHB */ + RCU_CFG0 |= RCU_APB_CKAHB_DIV1; + + /* select IRC48M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC48MDIV_SYS; + + /* wait until IRC48M is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_IRC48MDIV) { + } +} + +#elif defined (__SYSTEM_CLOCK_LXTAL) +/*! + \brief configure the system clock to LXTAL + \param[in] none + \param[out] none + \retval none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. +*/ +static void system_clock_lxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + rcu_periph_clock_enable(RCU_PMU); + pmu_backup_write_enable(); + + /* enable LXTAL */ + RCU_CTL1 |= RCU_CTL1_LXTALEN; + + /* if fail */ + while(0U == (RCU_CTL1 & RCU_CTL1_LXTALSTB)) { + } + + /* LXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB = AHB */ + RCU_CFG0 |= RCU_APB_CKAHB_DIV1; + + /* select LXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_LXTAL; + + /* wait until LXTAL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_LXTAL) { + } +} + +#else +/*! + \brief configure the system clock to IRC32K + \param[in] none + \param[out] none + \retval none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. +*/ +static void system_clock_IRC32K(void) +{ + + /* enable IRC32K */ + RCU_RSTSCK |= RCU_RSTSCK_IRC32KEN; + + /* if fail */ + while(0U == (RCU_RSTSCK & RCU_RSTSCK_IRC32KSTB)) { + } + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB = AHB */ + RCU_CFG0 |= RCU_APB_CKAHB_DIV1; + + + /* select IRC32K as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC32K; + + /* wait until IRC48M is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_IRC32K) { + } +} + +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/*! + \brief update the SystemCoreClock with current core clock retrieved from cpu registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate(void) +{ + uint32_t sws = 0U; + uint32_t idx = 0U, clk_exp = 0U; + uint32_t irc48mdiv_sys = 0U; + /* exponent of AHB 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) { + /* IRC48M is selected as CK_SYS */ + case SEL_IRC48MDIV: + irc48mdiv_sys = GET_BITS(RCU_CTL0, 29, 31); + SystemCoreClock = IRC48M_VALUE / (1 << irc48mdiv_sys); + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* IRC32K is selected as CK_SYS */ + case SEL_IRC32K: + SystemCoreClock = IRC32K_VALUE; + break; + /* IRC32K is selected as CK_SYS */ + case SEL_LXTAL: + SystemCoreClock = LXTAL_VALUE; + break; + /* IRC48M is selected as CK_SYS */ + default: + SystemCoreClock = IRC48M_VALUE/4; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + SystemCoreClock >>= clk_exp; +} + +#ifdef __FIRMWARE_VERSION_DEFINE +/*! + \brief get firmware version + \param[in] none + \param[out] none + \retval firmware version +*/ +uint32_t gd32c2x1_firmware_version_get(void) +{ + return __GD32C2X1_STDPERIPH_VERSION; +} +#endif /* __FIRMWARE_VERSION_DEFINE */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_adc.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_adc.h new file mode 100644 index 0000000..3bdadcc --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_adc.h @@ -0,0 +1,441 @@ +/*! + \file gd32c2x1_adc.h + \brief definitions for the ADC + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_ADC_H +#define GD32C2X1_ADC_H + +#include "gd32c2x1.h" + +/* ADC definitions */ +#define ADC ADC_BASE /*!< ADC base address */ + +/* registers definitions */ +#define ADC_STAT REG32(ADC + 0x00000000U) /*!< ADC status register */ +#define ADC_CTL0 REG32(ADC + 0x00000004U) /*!< ADC control register 0 */ +#define ADC_CTL1 REG32(ADC + 0x00000008U) /*!< ADC control register 1 */ +#define ADC_SAMPT0 REG32(ADC + 0x0000000CU) /*!< ADC sample time register 0 */ +#define ADC_SAMPT1 REG32(ADC + 0x00000010U) /*!< ADC sample time register 1 */ +#define ADC_IOFF0 REG32(ADC + 0x00000014U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1 REG32(ADC + 0x00000018U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2 REG32(ADC + 0x0000001CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3 REG32(ADC + 0x00000020U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WD0HT REG32(ADC + 0x00000024U) /*!< ADC watchdog 0 high threshold register */ +#define ADC_WD0LT REG32(ADC + 0x00000028U) /*!< ADC watchdog 0 low threshold register */ +#define ADC_RSQ0 REG32(ADC + 0x0000002CU) /*!< ADC routine sequence register 0 */ +#define ADC_RSQ1 REG32(ADC + 0x00000030U) /*!< ADC routine sequence register 1 */ +#define ADC_RSQ2 REG32(ADC + 0x00000034U) /*!< ADC routine sequence register 2 */ +#define ADC_ISQ REG32(ADC + 0x00000038U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0 REG32(ADC + 0x0000003CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1 REG32(ADC + 0x00000040U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2 REG32(ADC + 0x00000044U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3 REG32(ADC + 0x00000048U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA REG32(ADC + 0x0000004CU) /*!< ADC routine data register */ +#define ADC_WD1SR REG32(ADC + 0x00000050U) /*!< ADC watchdog 1 channel selection register */ +#define ADC_WD2SR REG32(ADC + 0x00000054U) /*!< ADC watchdog 2 channel selection register */ +#define ADC_WD1HT REG32(ADC + 0x00000058U) /*!< ADC watchdog 1 high threshold register */ +#define ADC_WD1LT REG32(ADC + 0x0000005CU) /*!< ADC watchdog 1 low threshold register */ +#define ADC_WD2HT REG32(ADC + 0x00000060U) /*!< ADC watchdog 2 high threshold register */ +#define ADC_WD2LT REG32(ADC + 0x00000064U) /*!< ADC watchdog 2 low threshold register */ +#define ADC_OVSAMPCTL REG32(ADC + 0x00000080U) /*!< ADC oversample control register */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WD0E BIT(0) /*!< analog watchdog 0 event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of sequence conversion */ +#define ADC_STAT_EOIC BIT(2) /*!< end of inserted sequence conversion */ +#define ADC_STAT_STIC BIT(3) /*!< inserted sequence start flag */ +#define ADC_STAT_STRC BIT(4) /*!< routine sequence start flag */ +#define ADC_STAT_WD1E BIT(30) /*!< analog watchdog 1 event flag */ +#define ADC_STAT_WD2E BIT(31) /*!< analog watchdog 2 event flag */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WD0CHSEL BITS(0, 3) /*!< analog watchdog 0 channel select */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WD0EIE BIT(6) /*!< analog watchdog 0 interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for EOIC */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WD0SC BIT(9) /*!< when in scan mode, analog watchdog 0 is effective on a single channel */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted sequence conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on routine channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13, 15) /*!< discontinuous mode channel number */ +#define ADC_CTL0_IWD0EN BIT(22) /*!< analog watchdog 0 enable on inserted channels */ +#define ADC_CTL0_RWD0EN BIT(23) /*!< analog watchdog 0 enable on routine channels */ +#define ADC_CTL0_DRES BITS(24, 25) /*!< ADC resolution */ +#define ADC_CTL0_WD1EIE BIT(30) /*!< analog watchdog 1 interrupt enable */ +#define ADC_CTL0_WD2EIE BIT(31) /*!< analog watchdog 2 interrupt enable */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous mode */ +#define ADC_CTL1_DMA BIT(8) /*!< dma request enable */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BITS(12, 14) /*!< external trigger select for inserted channel */ +#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger enable for inserted channel */ +#define ADC_CTL1_ETSRC BITS(17, 19) /*!< external trigger select for routine channel */ +#define ADC_CTL1_ETERC BIT(20) /*!< external trigger enable for routine channel */ +#define ADC_CTL1_SWICST BIT(21) /*!< software start on inserted channels */ +#define ADC_CTL1_SWRCST BIT(22) /*!< software start on routine channels */ +#define ADC_CTL1_TSVEN BIT(23) /*!< channel 13(temperature sensor)enable of ADC */ +#define ADC_CTL1_INREFEN BIT(24) /*!< channel 14(internal reference voltage)enable of ADC */ + +/* ADC_SAMPTx x=0..1 */ +#define ADC_SAMPTX_SPTN BITS(0, 2) /*!< channel n(n=0..10 or 0..15) sampling time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0, 11) /*!< data offset for inserted channel x */ + +/* ADC_WD0HT */ +#define ADC_WD0HT_WD0HT BITS(0, 11) /*!< high threshold for analog watchdog 0 */ + +/* ADC_WD0LT */ +#define ADC_WD0LT_WD0LT BITS(0, 11) /*!< low threshold for analog watchdog 0 */ + +/* ADC_RSQx x=0..2 */ +#define ADC_RSQX_RSQN BITS(0, 3) /*!< nth(n=0..10 or 0..15) conversion in routine sequence */ +#define ADC_RSQ0_RL BITS(20, 23) /*!< routine sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0, 3) /*!< nth(n = 0..3) conversion in inserted sequence */ +#define ADC_ISQ_IL BITS(20, 21) /*!< inserted sequence length */ + +/* ADC_IDATAx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0, 15) /*!< inserted channel x conversion data */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0, 15) /*!< routine channel data */ + +/* ADC_WD1SR */ +#define ADC_WD1SR_AWD1CS BITS(0, 15) /*!< analog watchdog 1 channel selection */ +/* ADC_WD2SR */ +#define ADC_WD2SR_AWD2CS BITS(0, 15) /*!< analog watchdog 2 channel selection */ + +/* ADC_WD1HT */ +#define ADC_WD1HT_WD1HT BITS(0, 11) /*!< high threshold for analog watchdog 1 */ + +/* ADC_WD1LT */ +#define ADC_WD1LT_WD1LT BITS(0, 11) /*!< low threshold for analog watchdog 1 */ + +/* ADC_WD2HT */ +#define ADC_WD2HT_WD2HT BITS(0, 11) /*!< high threshold for analog watchdog 2 */ + +/* ADC_WD2LT */ +#define ADC_WD2LT_WD2LT BITS(0, 11) /*!< low threshold for analog watchdog 2 */ + +/* 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 */ + +/* constants definitions */ +/* ADC_CTL0 register value */ +#define CTL0_DISNUM(regval) (BITS(13, 15) & ((uint32_t)(regval) << 13)) /*!< write value to ADC_CTL0_DISNUM bit field */ + +/* ADC resolution configure */ +#define CTL0_DRES(regval) (BITS(24, 25) & ((uint32_t)(regval) << 24)) +#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 */ + +/* ADC special function definitions */ +#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ +#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted sequence convert automatically */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ + +/* temperature sensor channel, internal reference voltage channel */ +#define ADC_CHANNEL_INTERNAL_TEMPSENSOR ADC_CTL1_TSVEN /*!< temperature channel */ +#define ADC_CHANNEL_INTERNAL_VREFINT ADC_CTL1_INREFEN /*!< internal vrefint channel */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< LSB alignment */ +#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< MSB alignment */ + +/* ADC external trigger select for routine sequence */ +#define CTL1_ETSRC(regval) (BITS(17, 19) & ((uint32_t)(regval) << 17)) +#define ADC_EXTTRIG_ROUTINE_T2_CH1 CTL1_ETSRC(0) /*!< TIMER2 CH1 event select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH2 CTL1_ETSRC(1) /*!< TIMER0 CH2 event select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH1 CTL1_ETSRC(2) /*!< TIMER0 CH1 event select */ +#define ADC_EXTTRIG_ROUTINE_T2_TRGO CTL1_ETSRC(3) /*!< TIMER2 TRGO event select */ +#define ADC_EXTTRIG_ROUTINE_T0_CH0 CTL1_ETSRC(4) /*!< TIMER0 CH0 event select */ +#define ADC_EXTTRIG_ROUTINE_T2_CH0 CTL1_ETSRC(5) /*!< TIMER2 CH0 event select */ +#define ADC_EXTTRIG_ROUTINE_EXTI_11 CTL1_ETSRC(6) /*!< external interrupt line 11 select */ +#define ADC_EXTTRIG_ROUTINE_NONE CTL1_ETSRC(7) /*!< software trigger select */ + +/* ADC external trigger select for inserted sequence */ +#define CTL1_ETSIC(regval) (BITS(12, 14) & ((uint32_t)(regval) << 12)) +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< TIMER0 TRGO event select */ +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< TIMER0 CH3 event select */ +#define ADC_EXTTRIG_INSERTED_T13_CH0 CTL1_ETSIC(2) /*!< TIMER13 CH0 event select */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(3) /*!< TIMER2 CH3 event select */ +#define ADC_EXTTRIG_INSERTED_T2_CH2 CTL1_ETSIC(4) /*!< TIMER2 CH2 event select */ +#define ADC_EXTTRIG_INSERTED_T15_CH0 CTL1_ETSIC(5) /*!< TIMER15 CH0 event select */ +#define ADC_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(6) /*!< external interrupt line 15 */ +#define ADC_EXTTRIG_INSERTED_NONE CTL1_ETSIC(7) /*!< software trigger select */ + +/* 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_2POINT5 SAMPTX_SPT(0) /*!< 2.5 sampling cycles */ +#define ADC_SAMPLETIME_3POINT5 SAMPTX_SPT(1) /*!< 3.5 sampling cycles */ +#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(2) /*!< 7.5 sampling cycles */ +#define ADC_SAMPLETIME_12POINT5 SAMPTX_SPT(3) /*!< 12.5 sampling cycles */ +#define ADC_SAMPLETIME_19POINT5 SAMPTX_SPT(4) /*!< 19.5 sampling cycles */ +#define ADC_SAMPLETIME_39POINT5 SAMPTX_SPT(5) /*!< 39.5 sampling cycles */ +#define ADC_SAMPLETIME_79POINT5 SAMPTX_SPT(6) /*!< 79.5 sampling cycles */ +#define ADC_SAMPLETIME_160POINT5 SAMPTX_SPT(7) /*!< 160.5 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 high threshold for analog watchdog 0 */ +#define WD0HT_WD0HT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WD0HT_WD0HT bit field */ + +/* ADC low threshold for analog watchdog 0 */ +#define WD0LT_WD0LT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WD0LT_WD0LT bit field */ + +/* ADC high threshold for analog watchdog 1 */ +#define WD1HT_WD1HT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WD1HT_WD1HT bit field */ + +/* ADC low threshold for analog watchdog 1 */ +#define WD1LT_WD1LT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WD1LT_WD1LT bit field */ + +/* ADC high threshold for analog watchdog 2 */ +#define WD2HT_WD2HT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WD2HT_WD2HT bit field */ + +/* ADC low threshold for analog watchdog 2 */ +#define WD2LT_WD2LT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to ADC_WD2LT_WD2LT 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 */ +/* oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5, 8) & ((uint32_t)(regval) << 5)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */ +#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */ + +/* oversampling ratio */ +#define OVSAMPCTL_OVSR(regval) (BITS(2, 4) & ((uint32_t)(regval) << 2)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */ +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ + +/* triggered oversampling */ +#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC channel sequence definitions */ +#define ADC_ROUTINE_CHANNEL ((uint8_t)0x01U) /*!< ADC routine sequence */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< ADC inserted sequence */ +#define ADC_ROUTINE_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both routine and inserted sequence */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of routine & inserted sequence */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC inserted channel 3 */ + +/* ADC channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ +#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ +#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ +#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ +#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ +#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ +#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ + +/* analog watchdog 1/2 channel selection for channel n(n=0..10 or 0..15) */ +#define ADC_AWD1_2_SELECTION_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 analog watchdog 1/2 selection */ +#define ADC_AWD1_2_SELECTION_CHANNEL_ALL ((uint32_t)0x0000FFFFU) /*!< all ADC channels analog watchdog 1/2 selection */ + +/* ADC flag definitions */ +#define ADC_FLAG_WD0E ADC_STAT_WD0E /*!< analog watchdog 0 event flag */ +#define ADC_FLAG_WD1E ADC_STAT_WD1E /*!< analog watchdog 1 event flag */ +#define ADC_FLAG_WD2E ADC_STAT_WD2E /*!< analog watchdog 2 event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted sequence start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< routine sequence start flag */ + +/* ADC interrupt definitions */ +#define ADC_INT_WD0E ADC_CTL0_WD0EIE /*!< analog watchdog 0 event interrupt */ +#define ADC_INT_WD1E ADC_CTL0_WD1EIE /*!< analog watchdog 1 event interrupt */ +#define ADC_INT_WD2E ADC_CTL0_WD2EIE /*!< analog watchdog 2 event interrupt */ +#define ADC_INT_EOC ADC_CTL0_EOCIE /*!< end of sequence conversion interrupt */ +#define ADC_INT_EOIC ADC_CTL0_EOICIE /*!< end of inserted sequence conversion interrupt */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WD0E ADC_STAT_WD0E /*!< analog watchdog 0 event interrupt */ +#define ADC_INT_FLAG_WD1E ADC_STAT_WD1E /*!< analog watchdog 1 event interrupt */ +#define ADC_INT_FLAG_WD2E ADC_STAT_WD2E /*!< analog watchdog 2 event interrupt */ +#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of sequence conversion interrupt */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted sequence conversion interrupt */ + +/* function declarations */ +/* ADC deinitialization and initialization functions */ +/* reset ADC */ +void adc_deinit(void); +/* enable ADC interface */ +void adc_enable(void); +/* disable ADC interface */ +void adc_disable(void); + +/* ADC DMA functions */ +/* enable DMA request */ +void adc_dma_mode_enable(void); +/* disable DMA request */ +void adc_dma_mode_disable(void); + +/* ADC special function functions */ +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint8_t adc_sequence, uint8_t length); +/* configure ADC special function */ +void adc_special_function_config(uint32_t function, ControlStatus newvalue); +/* enable or disable ADC internal channels */ +void adc_internal_channel_config(uint32_t internal_channel, ControlStatus newvalue); + +/* ADC channel configuration functions */ +/* configure ADC data alignment */ +void adc_data_alignment_config(uint32_t data_alignment); +/* configure the channel length of routine sequence or inserted sequence */ +void adc_channel_length_config(uint8_t adc_sequence, uint32_t length); +/* configure ADC routine channel */ +void adc_routine_channel_config(uint8_t rank, uint8_t adc_channel, uint32_t sample_time); +/* configure ADC inserted channel */ +void adc_inserted_channel_config(uint8_t rank, uint8_t adc_channel, uint32_t sample_time); +/* configure ADC inserted channel offset */ +void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset); + +/* ADC external trigger functions */ +/* configure ADC external trigger */ +void adc_external_trigger_config(uint8_t adc_sequence, ControlStatus newvalue); +/* configure ADC external trigger source */ +void adc_external_trigger_source_config(uint8_t adc_sequence, uint32_t external_trigger_source); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint8_t adc_sequence); + +/* ADC data read functions */ +/* read ADC routine sequence data register */ +uint16_t adc_routine_data_read(void); +/* read ADC inserted sequence data register */ +uint16_t adc_inserted_data_read(uint8_t inserted_channel); + +/* ADC analog watchdog functions */ +/* enable ADC analog watchdog 0 single channel */ +void adc_watchdog0_single_channel_enable(uint8_t adc_channel); +/* enable ADC analog watchdog 0 sequence channel */ +void adc_watchdog0_sequence_channel_enable(uint8_t adc_sequence); +/* disable ADC analog watchdog 0 */ +void adc_watchdog0_disable(void); +/* configure ADC analog watchdog 1 channel */ +void adc_watchdog1_channel_config(uint32_t selection_channel, ControlStatus newvalue); +/* configure ADC analog watchdog 2 channel */ +void adc_watchdog2_channel_config(uint32_t selection_channel, ControlStatus newvalue); +/* disable ADC analog watchdog 1 */ +void adc_watchdog1_disable(void); +/* disable ADC analog watchdog 2 */ +void adc_watchdog2_disable(void); +/* configure ADC analog watchdog 0 threshold */ +void adc_watchdog0_threshold_config( uint32_t low_threshold, uint32_t high_threshold); +/* configure ADC analog watchdog 1 threshold */ +void adc_watchdog1_threshold_config(uint32_t low_threshold, uint32_t high_threshold); +/* configure ADC analog watchdog 2 threshold */ +void adc_watchdog2_threshold_config(uint32_t low_threshold, uint32_t high_threshold); + +/* ADC resolution and oversample functions */ +/* configure ADC resolution */ +void adc_resolution_config(uint32_t resolution); +/* configure ADC oversample mode */ +void adc_oversample_mode_config(uint32_t mode, uint16_t shift, uint8_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(void); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(void); + +/* flag and interrupt functions */ +/* get ADC flag */ +FlagStatus adc_flag_get(uint32_t flag); +/* clear ADC flag */ +void adc_flag_clear(uint32_t flag); +/* enable ADC interrupt */ +void adc_interrupt_enable(uint32_t interrupt); +/* disable ADC interrupt */ +void adc_interrupt_disable(uint32_t interrupt); +/* get ADC interrupt flag */ +FlagStatus adc_interrupt_flag_get(uint32_t int_flag); +/* clear ADC interrupt flag */ +void adc_interrupt_flag_clear(uint32_t int_flag); + +#endif /* GD32C23X_ADC_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_cmp.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_cmp.h new file mode 100644 index 0000000..e696f7b --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_cmp.h @@ -0,0 +1,145 @@ +/*! + \file gd32c2x1_cmp.h + \brief definitions for the CMP + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_CMP_H +#define GD32C2X1_CMP_H + +#include "gd32c2x1.h" + +/* CMP definitions */ +#define CMP CMP_BASE /*!< CMP base address */ + +/* registers definitions */ +#define CMP0_CS REG32((CMP) + 0x00000000U) /*!< CMP0 control and status register */ +#define CMP1_CS REG32((CMP) + 0x00000004U) /*!< CMP1 control and status register */ + +/* bits definitions */ +/* CMPx_CS */ +#define CMP_CS_CMPXEN BIT(0) /*!< CMPx enable */ +#define CMP_CS_CMPXM BITS(2,3) /*!< CMPx mode */ +#define CMP_CS_CMPXMSEL BITS(4,6) /*!< CMP_IM input selection */ +#define CMP_CS_CMPXSW BIT(11) /*!< CMPx switch mode enable */ +#define CMP_CS_CMPXPL BIT(15) /*!< CMPx output polarity */ +#define CMP_CS_CMPXHST BITS(16,17) /*!< CMPx hysteresis */ +#define CMP_CS_CMPXBLK BITS(18,20) /*!< CMPx output blanking source */ +#define CMP_CS_CMPXBEN BIT(22) /*!< CMPx scaler bridge enable bit */ +#define CMP_CS_CMPXSEN BIT(23) /*!< CMPx voltage input scaler */ +#define CMP_CS_CMPXO BIT(30) /*!< CMPx output state bit */ +#define CMP_CS_CMPXLK BIT(31) /*!< CMPx lock */ + +/* constants definitions */ +/* CMP units */ +typedef enum{ + CMP0, /*!< comparator 0 */ + CMP1 /*!< comparator 1 */ +}cmp_enum; + +/* CMP operating mode */ +#define CS_CMPXM(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) +#define CMP_MODE_HIGHSPEED CS_CMPXM(0) /*!< CMP mode high speed */ +#define CMP_MODE_MIDDLESPEED CS_CMPXM(1) /*!< CMP mode middle speed */ +#define CMP_MODE_LOWSPEED CS_CMPXM(2) /*!< CMP mode low speed */ +#define CMP_MODE_VERYLOWSPEED CS_CMPXM(3) /*!< CMP mode very low speed */ + +/* CMP hysteresis */ +#define CS_CMPXHST(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define CMP_HYSTERESIS_NO CS_CMPXHST(0) /*!< CMP output no hysteresis */ +#define CMP_HYSTERESIS_LOW CS_CMPXHST(1) /*!< CMP output low hysteresis */ +#define CMP_HYSTERESIS_MIDDLE CS_CMPXHST(2) /*!< CMP output middle hysteresis */ +#define CMP_HYSTERESIS_HIGH CS_CMPXHST(3) /*!< CMP output high hysteresis */ + +/* CMP inverting input */ +#define CS_CMPXMSEL(regval) (BITS(4,6) & ((uint32_t)(regval) << 4U)) +#define CMP_INVERTING_INPUT_1_4VREFINT CS_CMPXMSEL(0) /*!< CMP inverting input 1/4 Vrefint */ +#define CMP_INVERTING_INPUT_1_2VREFINT CS_CMPXMSEL(1) /*!< CMP inverting input 1/2 Vrefint */ +#define CMP_INVERTING_INPUT_3_4VREFINT CS_CMPXMSEL(2) /*!< CMP inverting input 3/4 Vrefint */ +#define CMP_INVERTING_INPUT_VREFINT CS_CMPXMSEL(3) /*!< CMP inverting input Vrefint */ +#define CMP_INVERTING_INPUT_PB2_PB6 CS_CMPXMSEL(4) /*!< CMP inverting input PB2 for CMP0 or PB6 for CMP1 */ +#define CMP_INVERTING_INPUT_PA0_PA2 CS_CMPXMSEL(5) /*!< CMP inverting input PA0 for CMP0 or PA2 for CMP1 */ +#define CMP_INVERTING_INPUT_PB1_PB3 CS_CMPXMSEL(6) /*!< CMP inverting input PB1 for CMP0 or PB3 for CMP1 */ +#define CMP_INVERTING_INPUT_VSSA_PB4 CS_CMPXMSEL(7) /*!< CMP inverting input VSSA for CMP0 or PB4 for CMP1 */ + +/* CMP output polarity*/ +#define CS_CMPXPL(regval) (BIT(15) & ((uint32_t)(regval) << 15U)) +#define CMP_OUTPUT_POLARITY_NONINVERTED CS_CMPXPL(0) /*!< CMP output not inverted */ +#define CMP_OUTPUT_POLARITY_INVERTED CS_CMPXPL(1) /*!< CMP output inverted */ + +/* CMP blanking suorce */ +#define CS_CMPXBLK(regval) (BITS(18,20) & ((uint32_t)(regval) << 18U)) +#define CMP_BLANKING_NONE CS_CMPXBLK(0) /*!< CMP no blanking source */ +#define CMP_BLANKING_TIMER0_OC1 CS_CMPXBLK(1) /*!< CMP TIMER0_CH1 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER2_OC1 CS_CMPXBLK(2) /*!< CMP TIMER2_CH1 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER13_OC0 CS_CMPXBLK(4) /*!< CMP TIMER13_CH0 output compare signal selected as blanking source */ +#define CMP_BLANKING_TIMER15_OC0 CS_CMPXBLK(5) /*!< CMP TIMER15_CH0 output compare signal selected as blanking source */ + +/* CMP output level */ +#define CMP_OUTPUTLEVEL_HIGH ((uint32_t)0x00000001U) /*!< CMP output high */ +#define CMP_OUTPUTLEVEL_LOW ((uint32_t)0x00000000U) /*!< CMP output low */ + +/* function declarations */ +/* initialization functions */ +/* CMP deinit */ +void cmp_deinit(cmp_enum cmp_periph); +/* CMP mode init */ +void cmp_mode_init(cmp_enum cmp_periph, uint32_t operating_mode, uint32_t inverting_input, uint32_t output_hysteresis); +/* CMP output init */ +void cmp_output_init(cmp_enum cmp_periph, uint32_t output_polarity); +/* CMP output blanking function init */ +void cmp_blanking_init(cmp_enum cmp_periph,uint32_t blanking_source_selection); + +/* enable functions */ +/* enable CMP */ +void cmp_enable(cmp_enum cmp_periph); +/* disable CMP */ +void cmp_disable(cmp_enum cmp_periph); +/* enable CMP switch */ +void cmp_switch_enable(cmp_enum cmp_periph); +/* disable CMP switch */ +void cmp_switch_disable(cmp_enum cmp_periph); +/* lock the CMP */ +void cmp_lock_enable(cmp_enum cmp_periph); +/* enable the voltage scaler */ +void cmp_voltage_scaler_enable(cmp_enum cmp_periph); +/* disable the voltage scaler */ +void cmp_voltage_scaler_disable(cmp_enum cmp_periph); +/* enable the scaler bridge */ +void cmp_scaler_bridge_enable(cmp_enum cmp_periph); +/* disable the scaler bridge */ +void cmp_scaler_bridge_disable(cmp_enum cmp_periph); + +/* get state related functions */ +/* get output level */ +uint32_t cmp_output_level_get(cmp_enum cmp_periph); + +#endif /* GD32C23X_CMP_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_crc.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_crc.h new file mode 100644 index 0000000..11d04b5 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_crc.h @@ -0,0 +1,119 @@ +/*! + \file gd32c2x1_crc.h + \brief definitions for the CRC + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_CRC_H +#define GD32C2X1_CRC_H + +#include "gd32c2x1.h" + +/* CRC definitions */ +#define CRC CRC_BASE /*!< CRC bsae address */ + +/* registers definitions */ +#define CRC_DATA REG32((CRC) + 0x00000000U) /*!< CRC data register */ +#define CRC_FDATA REG32((CRC) + 0x00000004U) /*!< CRC free data register */ +#define CRC_CTL REG32((CRC) + 0x00000008U) /*!< CRC control register */ +#define CRC_IDATA REG32((CRC) + 0x00000010U) /*!< CRC initialization data register */ +#define CRC_POLY REG32((CRC) + 0x00000014U) /*!< CRC polynomial register */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0, 31) /*!< CRC data bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0, 7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset bit */ +#define CRC_CTL_PS BITS(3, 4) /*!< size of polynomial function bits */ +#define CRC_CTL_REV_I BITS(5, 6) /*!< input data reverse function bits */ +#define CRC_CTL_REV_O BIT(7) /*!< output data reverse function bit */ + +/* CRC_INIT */ +#define CRC_IDATA_IDATA BITS(0, 31) /*!< CRC initialization data bits */ + +/* CRC_POLY */ +#define CRC_POLY_POLY BITS(0, 31) /*!< CRC polynomial value bits */ + +/* constants definitions */ +/* size of polynomial function */ +#define CTL_PS(regval) (BITS(3, 4) & ((uint32_t)(regval) << 3)) +#define CRC_CTL_PS_32 ((uint8_t)CTL_PS(0)) /*!< 32-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_16 ((uint8_t)CTL_PS(1)) /*!< 16-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_8 ((uint8_t)CTL_PS(2)) /*!< 8-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_7 ((uint8_t)CTL_PS(3)) /*!< 7-bit polynomial for CRC calculation */ + +/* input data reverse function */ +#define CTL_REV_I(regval) (BITS(5, 6) & ((uint32_t)(regval) << 5)) +#define CRC_INPUT_DATA_NOT ((uint8_t)CTL_REV_I(0)) /*!< input data not reverse */ +#define CRC_INPUT_DATA_BYTE ((uint8_t)CTL_REV_I(1)) /*!< input data reversed by byte type */ +#define CRC_INPUT_DATA_HALFWORD ((uint8_t)CTL_REV_I(2)) /*!< input data reversed by half-word type */ +#define CRC_INPUT_DATA_WORD ((uint8_t)CTL_REV_I(3)) /*!< input data reversed by word type */ + +/* input data format */ +#define INPUT_FORMAT_WORD 0U /*!< input data in word format */ +#define INPUT_FORMAT_HALFWORD 1U /*!< input data in half-word format */ +#define INPUT_FORMAT_BYTE 2U /*!< input data in byte format */ + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); +/* write the initial value register */ +void crc_init_data_register_write(uint32_t init_data); +/* read the data register */ +uint32_t crc_data_register_read(void); +/* read the free data register */ +uint8_t crc_free_data_register_read(void); +/* write the free data register */ +void crc_free_data_register_write(uint8_t free_data); +/* disable the reverse operation of output data */ +void crc_reverse_output_data_disable(void); +/* enable the reverse operation of output data */ +void crc_reverse_output_data_enable(void); +/* configure the CRC input data function */ +void crc_input_data_reverse_config(uint32_t data_reverse); +/* reset data register to the value of initialization data register */ +void crc_data_register_reset(void); + +/* configure the CRC size of polynomial function */ +void crc_polynomial_size_set(uint32_t poly_size); +/* configure the CRC polynomial value function */ +void crc_polynomial_set(uint32_t poly); + +/* CRC calculate single data */ +uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format); +/* CRC calculate a data array */ +uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format); + +#endif /* GD32C2X1_CRC_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_dbg.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_dbg.h new file mode 100644 index 0000000..34fbb7a --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_dbg.h @@ -0,0 +1,116 @@ +/*! + \file gd32c2x1_dbg.h + \brief definitions for the DBG + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_DBG_H +#define GD32C2X1_DBG_H + +#include "gd32c2x1.h" + +/* DBG definitions */ +#define DBG DBG_BASE /*!< DBG base address */ + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00000000U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x00000004U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x00000008U) /*!< DBG control register 1 */ + +/* 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_FWDGT_HOLD BIT(8) /*!< hold FWDGT counter when core is halted */ +#define DBG_CTL0_WWDGT_HOLD BIT(9) /*!< hold WWDGT counter when core is halted */ +#define DBG_CTL0_TIMER0_HOLD BIT(11) /*!< hold TIMER0 counter when core is halted */ +#define DBG_CTL0_TIMER2_HOLD BIT(12) /*!< hold TIMER2 counter when core is halted */ +#define DBG_CTL0_TIMER13_HOLD BIT(13) /*!< hold TIMER13 counter when core is halted */ +#define DBG_CTL0_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL0_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL0_TIMER15_HOLD BIT(20) /*!< hold TIMER15 counter when core is halted */ +#define DBG_CTL0_TIMER16_HOLD BIT(21) /*!< hold TIMER16 counter when core is halted */ + +/* DBG_CTL1 */ +#define DBG_CTL1_RTC_HOLD BIT(10) /*!< hold RTC calendar and wakeup counter when core is halted */ + +/* constants definitions */ +/* keep debugger connection */ +#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, +}; + +/* peripherals hold bit */ +typedef enum { + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 8U), /*!< FWDGT hold bit */ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 9U), /*!< WWDGT hold bit */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 11U), /*!< TIMER0 hold bit */ + DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 12U), /*!< TIMER2 hold bit */ + DBG_TIMER13_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 13U), /*!< TIMER13 hold bit */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 15U), /*!< I2C0 hold bit */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 16U), /*!< I2C1 hold bit */ + DBG_TIMER15_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 20U), /*!< TIMER15 hold bit */ + DBG_TIMER16_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 21U), /*!< TIMER16 hold bit */ + DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U), /*!< RTC hold bit */ +} dbg_periph_enum; + +/* 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); + +#endif /* gd32c2x1_DBG_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_dma.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_dma.h new file mode 100644 index 0000000..56aec8f --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_dma.h @@ -0,0 +1,569 @@ +/*! + \file gd32c2x1_dma.h + \brief definitions for the DMA + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_DMA_H +#define GD32C2X1_DMA_H + +#include "gd32c2x1.h" + +/* DMA definitions */ +#define DMA DMA_BASE /*!< DMA base address */ +#define DMAMUX DMAMUX_BASE /*!< DMAMUX base address */ + +/* registers definitions */ +#define DMA_INTF REG32(DMA + 0x00000000U) /*!< DMA interrupt flag register */ +#define DMA_INTC REG32(DMA + 0x00000004U) /*!< DMA interrupt flag clear register */ + +#define DMA_CH0CTL REG32(DMA + 0x00000008U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT REG32(DMA + 0x0000000CU) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR REG32(DMA + 0x00000010U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0MADDR REG32(DMA + 0x00000014U) /*!< DMA channel 0 memory base address register */ + +#define DMA_CH1CTL REG32(DMA + 0x0000001CU) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT REG32(DMA + 0x00000020U) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR REG32(DMA + 0x00000024U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1MADDR REG32(DMA + 0x00000028U) /*!< DMA channel 1 memory base address register */ + +#define DMA_CH2CTL REG32(DMA + 0x00000030U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT REG32(DMA + 0x00000034U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR REG32(DMA + 0x00000038U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2MADDR REG32(DMA + 0x0000003CU) /*!< DMA channel 2 memory base address register */ + +#define DMAMUX_RM_CH0CFG REG32(DMAMUX + 0x00000000U) /*!< DMAMUX request multiplexer channel 0 configuration register */ +#define DMAMUX_RM_CH1CFG REG32(DMAMUX + 0x00000004U) /*!< DMAMUX request multiplexer channel 1 configuration register */ +#define DMAMUX_RM_CH2CFG REG32(DMAMUX + 0x00000008U) /*!< DMAMUX request multiplexer channel 2 configuration register */ +#define DMAMUX_RM_INTF REG32(DMAMUX + 0x00000080U) /*!< DMAMUX request multiplexer channel interrupt flag register */ +#define DMAMUX_RM_INTC REG32(DMAMUX + 0x00000084U) /*!< DMAMUX request multiplexer channel interrupt flag clear register */ +#define DMAMUX_RG_CH0CFG REG32(DMAMUX + 0x00000100U) /*!< DMAMUX generator channel 0 configuration register */ +#define DMAMUX_RG_CH1CFG REG32(DMAMUX + 0x00000104U) /*!< DMAMUX generator channel 1 configuration register */ +#define DMAMUX_RG_CH2CFG REG32(DMAMUX + 0x00000108U) /*!< DMAMUX generator channel 2 configuration register */ +#define DMAMUX_RG_CH3CFG REG32(DMAMUX + 0x0000010CU) /*!< DMAMUX generator channel 3 configuration register */ +#define DMAMUX_RG_INTF REG32(DMAMUX + 0x00000140U) /*!< DMAMUX generator channel interrupt flag register */ +#define DMAMUX_RG_INTC REG32(DMAMUX + 0x00000144U) /*!< DMAMUX rgenerator channel interrupt flag clear register */ + +/* bits definitions */ +/* DMA_INTF */ +#define DMA_INTF_GIF BIT(0) /*!< global interrupt flag of channel */ +#define DMA_INTF_FTFIF BIT(1) /*!< full transfer finish flag of channel */ +#define DMA_INTF_HTFIF BIT(2) /*!< half transfer finish flag of channel */ +#define DMA_INTF_ERRIF BIT(3) /*!< error flag of channel */ + +/* DMA_INTC */ +#define DMA_INTC_GIFC BIT(0) /*!< clear global interrupt flag of channel */ +#define DMA_INTC_FTFIFC BIT(1) /*!< clear transfer finish flag of channel */ +#define DMA_INTC_HTFIFC BIT(2) /*!< clear half transfer finish flag of channel */ +#define DMA_INTC_ERRIFC BIT(3) /*!< clear error flag of channel */ + +/* DMA_CHxCTL, x=0..2 */ +#define DMA_CHXCTL_CHEN BIT(0) /*!< channel x enable */ +#define DMA_CHXCTL_FTFIE BIT(1) /*!< enable bit for channel x transfer complete interrupt */ +#define DMA_CHXCTL_HTFIE BIT(2) /*!< enable bit for channel x transfer half complete interrupt */ +#define DMA_CHXCTL_ERRIE BIT(3) /*!< enable bit for channel x error interrupt */ +#define DMA_CHXCTL_DIR BIT(4) /*!< direction of the data transfer on the channel */ +#define DMA_CHXCTL_CMEN BIT(5) /*!< circulation mode */ +#define DMA_CHXCTL_PNAGA BIT(6) /*!< next address generation algorithm of peripheral */ +#define DMA_CHXCTL_MNAGA BIT(7) /*!< next address generation algorithm of memory */ +#define DMA_CHXCTL_PWIDTH BITS(8,9) /*!< transfer data size of peripheral */ +#define DMA_CHXCTL_MWIDTH BITS(10,11) /*!< transfer data size of memory */ +#define DMA_CHXCTL_PRIO BITS(12,13) /*!< priority level of channelx */ +#define DMA_CHXCTL_M2M BIT(14) /*!< memory to memory mode */ + +/* DMA_CHxCNT, x=0..2 */ +#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */ + +/* DMA_CHxPADDR, x=0..2 */ +#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */ + +/* DMA_CHxMADDR, x=0..2 */ +#define DMA_CHXMADDR_MADDR BITS(0,31) /*!< memory base address */ + +/* DMAMUX_RM_CHxCFG, x=0..2 */ +#define DMAMUX_RM_CHXCFG_MUXID BITS(0,5) /*!< multiplexer input identification */ +#define DMAMUX_RM_CHXCFG_SOIE BIT(8) /*!< synchronization overrun interrupt enable */ +#define DMAMUX_RM_CHXCFG_EVGEN BIT(9) /*!< event generation enable */ +#define DMAMUX_RM_CHXCFG_SYNCEN BIT(16) /*!< synchronization enable */ +#define DMAMUX_RM_CHXCFG_SYNCP BITS(17,18) /*!< synchronization input polarity */ +#define DMAMUX_RM_CHXCFG_NBR BITS(19,23) /*!< number of DMA requests to forward */ +#define DMAMUX_RM_CHXCFG_SYNCID BITS(24,28) /*!< synchronization input identification */ + +/* DMAMUX_RM_INTF */ +#define DMAMUX_RM_INTF_SOIF0 BIT(0) /*!< synchronization overrun event flag of request multiplexer channel 0 */ +#define DMAMUX_RM_INTF_SOIF1 BIT(1) /*!< synchronization overrun event flag of request multiplexer channel 1 */ +#define DMAMUX_RM_INTF_SOIF2 BIT(2) /*!< synchronization overrun event flag of request multiplexer channel 2 */ + +/* DMAMUX_RM_INTC */ +#define DMAMUX_RM_INTF_SOIFC0 BIT(0) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 0 */ +#define DMAMUX_RM_INTF_SOIFC1 BIT(1) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 1 */ +#define DMAMUX_RM_INTF_SOIFC2 BIT(2) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 2 */ + +/* DMAMUX_RG_CHxCFG, x=0..3 */ +#define DMAMUX_RG_CHXCFG_TID BITS(0,4) /*!< trigger input identification */ +#define DMAMUX_RG_CHXCFG_TOIE BIT(8) /*!< trigger overrun interrupt enable */ +#define DMAMUX_RG_CHXCFG_RGEN BIT(16) /*!< DMA request generator channel x enable */ +#define DMAMUX_RG_CHXCFG_RGTP BITS(17,18) /*!< DMA request generator trigger polarity */ +#define DMAMUX_RG_CHXCFG_NBRG BITS(19,23) /*!< number of DMA requests to be generated */ + +/* DMAMUX_RG_INTF */ +#define DMAMUX_RG_INTF_TOIF0 BIT(0) /*!< trigger overrun event flag of request generator channel 0 */ +#define DMAMUX_RG_INTF_TOIF1 BIT(1) /*!< trigger overrun event flag of request generator channel 1 */ +#define DMAMUX_RG_INTF_TOIF2 BIT(2) /*!< trigger overrun event flag of request generator channel 2 */ +#define DMAMUX_RG_INTF_TOIF3 BIT(3) /*!< trigger overrun event flag of request generator channel 3 */ + +/* DMAMUX_RG_INTC */ +#define DMAMUX_RG_INTF_TOIFC0 BIT(0) /*!< clear bit for trigger overrun event flag of request generator channel 0 */ +#define DMAMUX_RG_INTF_TOIFC1 BIT(1) /*!< clear bit for trigger overrun event flag of request generator channel 1 */ +#define DMAMUX_RG_INTF_TOIFC2 BIT(2) /*!< clear bit for trigger overrun event flag of request generator channel 2 */ +#define DMAMUX_RG_INTF_TOIFC3 BIT(3) /*!< clear bit for trigger overrun event flag of request generator channel 3 */ + +/* constants definitions */ +/* define the DMAMUX bit position and its register index offset */ +#define DMAMUX_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define DMAMUX_REG_VAL(offset) (REG32(DMAMUX + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define DMAMUX_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define DMAMUX_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16) \ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define DMAMUX_REG_VAL2(offset) (REG32(DMAMUX + ((uint32_t)(offset) >> 22))) +#define DMAMUX_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) +#define DMAMUX_REG_VAL3(offset) (REG32(DMAMUX + (((uint32_t)(offset) & 0x0000FFFFU) >> 6) + 0x4U)) + +/* register offset */ +#define DMAMUX_RM_CH0CFG_REG_OFFSET 0x00000000U /*!< DMAMUX_RM_CH0CFG register offset */ +#define DMAMUX_RM_CH1CFG_REG_OFFSET 0x00000004U /*!< DMAMUX_RM_CH1CFG register offset */ +#define DMAMUX_RM_CH2CFG_REG_OFFSET 0x00000008U /*!< DMAMUX_RM_CH2CFG register offset */ +#define DMAMUX_RG_CH0CFG_REG_OFFSET 0x00000100U /*!< DMAMUX_RG_CH0CFG register offset */ +#define DMAMUX_RG_CH1CFG_REG_OFFSET 0x00000104U /*!< DMAMUX_RG_CH1CFG register offset */ +#define DMAMUX_RG_CH2CFG_REG_OFFSET 0x00000108U /*!< DMAMUX_RG_CH2CFG register offset */ +#define DMAMUX_RG_CH3CFG_REG_OFFSET 0x0000010CU /*!< DMAMUX_RG_CH3CFG register offset */ +#define DMAMUX_RM_INTF_REG_OFFSET 0x00000080U /*!< DMAMUX_RM_INTF register offset */ +#define DMAMUX_RG_INTF_REG_OFFSET 0x00000140U /*!< DMAMUX_RG_INTF register offset */ + +/* DMAMUX interrupt enable or disable */ +typedef enum { + /* interrupts in CHxCFG register */ + DMAMUX_INT_MUXCH0_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH1_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH2_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun interrupt */ + DMAMUX_INT_GENCH0_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 0 trigger overrun interrupt */ + DMAMUX_INT_GENCH1_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 1 trigger overrun interrupt */ + DMAMUX_INT_GENCH2_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 2 trigger overrun interrupt */ + DMAMUX_INT_GENCH3_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 3 trigger overrun interrupt */ +} dmamux_interrupt_enum; + +/* DMAMUX flags */ +typedef enum { + /* flags in INTF register */ + DMAMUX_FLAG_MUXCH0_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 0U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH1_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 1U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH2_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 2U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun flag */ + DMAMUX_FLAG_GENCH0_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 0U), /*!< DMAMUX request generator channel 0 trigger overrun flag */ + DMAMUX_FLAG_GENCH1_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 1U), /*!< DMAMUX request generator channel 1 trigger overrun flag */ + DMAMUX_FLAG_GENCH2_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 2U), /*!< DMAMUX request generator channel 2 trigger overrun flag */ + DMAMUX_FLAG_GENCH3_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_INTF_REG_OFFSET, 3U), /*!< DMAMUX request generator channel 3 trigger overrun flag */ +} dmamux_flag_enum; + +/* DMAMUX interrupt flags */ +typedef enum { + /* interrupt flags in INTF register */ + DMAMUX_INT_FLAG_MUXCH0_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 0U, DMAMUX_RM_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH1_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 1U, DMAMUX_RM_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH2_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 2U, DMAMUX_RM_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH0_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 0U, DMAMUX_RG_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 0 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH1_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 1U, DMAMUX_RG_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 1 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH2_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 2U, DMAMUX_RG_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 2 trigger overrun interrupt flag */ + DMAMUX_INT_FLAG_GENCH3_TO = DMAMUX_REGIDX_BIT2(DMAMUX_RG_INTF_REG_OFFSET, 3U, DMAMUX_RG_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 3 trigger overrun interrupt flag */ +} dmamux_interrupt_flag_enum; + +/* DMA channel selection */ +typedef enum { + DMA_CH0 = 0U, /*!< DMA Channel 0 */ + DMA_CH1, /*!< DMA Channel 1 */ + DMA_CH2, /*!< DMA Channel 2 */ +} dma_channel_enum; + +/* DMAMUX request multiplexer channel */ +typedef enum { + DMAMUX_MUXCH0 = 0U, /*!< DMAMUX request multiplexer Channel0 */ + DMAMUX_MUXCH1, /*!< DMAMUX request multiplexer Channel1 */ + DMAMUX_MUXCH2, /*!< DMAMUX request multiplexer Channel2 */ +} dmamux_multiplexer_channel_enum; + +/* DMAMUX request generator channel */ +typedef enum { + DMAMUX_GENCH0 = 0U, /*!< DMAMUX request generator Channel0 */ + DMAMUX_GENCH1, /*!< DMAMUX request generator Channel1 */ + DMAMUX_GENCH2, /*!< DMAMUX request generator Channel2 */ + DMAMUX_GENCH3, /*!< DMAMUX request generator Channel3 */ +} dmamux_generator_channel_enum; + +/* DMA initialization structure */ +typedef struct { + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_width; /*!< transfer data size of peripheral */ + uint32_t memory_addr; /*!< memory base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ + uint8_t periph_inc; /*!< peripheral increasing mode */ + uint8_t memory_inc; /*!< memory increasing mode */ + uint8_t direction; /*!< channel data transfer direction */ + uint32_t request; /*!< channel input identification */ +} dma_parameter_struct; + +/* DMAMUX request multiplexer synchronization configuration structure */ +typedef struct { + uint32_t sync_id; /*!< synchronization input identification */ + uint32_t sync_polarity; /*!< synchronization input polarity */ + uint32_t request_number; /*!< number of DMA requests to forward */ +} dmamux_sync_parameter_struct; + +/* DMAMUX request generator trigger configuration structure */ +typedef struct { + uint32_t trigger_id; /*!< trigger input identification */ + uint32_t trigger_polarity; /*!< DMAMUX request generator trigger polarity */ + uint32_t request_number; /*!< number of DMA requests to be generated */ +} dmamux_gen_parameter_struct; + +/* DMA 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 (DMA_INTF_GIF | DMA_INTF_FTFIF | \ + DMA_INTF_HTFIF | DMA_INTF_ERRIF) /*!< clear DMA channel DMA_INTF register */ + +#define DMA_FLAG_ADD(flag,shift) ((flag) << ((uint32_t)(shift) * 4U)) /*!< DMA channel flag shift */ + +/* DMA_CHCTL base address */ +#define DMA_CHXCTL_BASE (DMA + 0x00000008U) /*!< the base address of DMA channel CHXCTL register */ +#define DMA_CHXCNT_BASE (DMA + 0x0000000CU) /*!< the base address of DMA channel CHXCNT register */ +#define DMA_CHXPADDR_BASE (DMA + 0x00000010U) /*!< the base address of DMA channel CHXPADDR register */ +#define DMA_CHXMADDR_BASE (DMA + 0x00000014U) /*!< the base address of DMA channel CHXMADDR register */ + +/* DMA channel shift bit */ +#define DMA_CHCTL(channel) REG32(DMA_CHXCTL_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(channel) REG32(DMA_CHXCNT_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(channel) REG32(DMA_CHXPADDR_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHMADDR(channel) REG32(DMA_CHXMADDR_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* DMAMUX_RM_CHxCFG base address */ +#define DMAMUX_RM_CHXCFG_BASE (DMAMUX) /*!< the base address of DMAMUX request multiplexer channel CHxCFG register */ + +/* DMAMUX request multiplexer channel shift bit */ +#define DMAMUX_RM_CHXCFG(channel) REG32(DMAMUX_RM_CHXCFG_BASE + 0x04U * (uint32_t)(channel)) /*!< the address of DMAMUX request multiplexer channel CHxCFG register */ + +/* DMAMUX_RG_CHxCFG base address */ +#define DMAMUX_RG_CHXCFG_BASE (DMAMUX + 0x00000100U) /*!< the base address of DMAMUX channel request generator CHxCFG register */ + +/* DMAMUX request generator channel shift bit */ +#define DMAMUX_RG_CHXCFG(channel) REG32(DMAMUX_RG_CHXCFG_BASE + 0x04U * (uint32_t)(channel)) /*!< the address of DMAMUX channel request generator CHxCFG register */ + +/* DMA interrupt flag bits */ +#define DMA_INT_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of DMA channel */ +#define DMA_INT_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish interrupt flag of DMA channel */ +#define DMA_INT_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish interrupt flag of DMA channel */ +#define DMA_INT_FLAG_ERR DMA_INTF_ERRIF /*!< error interrupt flag of DMA channel */ + +/* DMA flag bits */ +#define DMA_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of DMA channel */ +#define DMA_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish flag of DMA channel */ +#define DMA_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish flag of DMA channel */ +#define DMA_FLAG_ERR DMA_INTF_ERRIF /*!< error flag of DMA channel */ + +/* DMA interrupt enable bits */ +#define DMA_INT_FTF DMA_CHXCTL_FTFIE /*!< enable bit for DMA channel full transfer finish interrupt */ +#define DMA_INT_HTF DMA_CHXCTL_HTFIE /*!< enable bit for DMA channel half transfer finish interrupt */ +#define DMA_INT_ERR DMA_CHXCTL_ERRIE /*!< enable bit for DMA channel error interrupt */ + +/* DMA transfer direction */ +#define DMA_PERIPHERAL_TO_MEMORY ((uint8_t)0x00U) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPHERAL ((uint8_t)0x01U) /*!< read from memory and write to peripheral */ + +/* DMA peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint8_t)0x00U) /*!< next address of peripheral is fixed address mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint8_t)0x01U) /*!< next address of peripheral is increasing address mode */ + +/* DMA memory increasing mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint8_t)0x00U) /*!< next address of memory is fixed address mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint8_t)0x01U) /*!< next address of memory is increasing address mode */ + +/* DMA transfer data size of peripheral */ +#define CHCTL_PWIDTH(regval) (BITS(8,9) & ((regval) << 8)) /*!< transfer data size of peripheral */ +#define DMA_PERIPHERAL_WIDTH_8BIT CHCTL_PWIDTH(0U) /*!< transfer data size of peripheral is 8-bit */ +#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PWIDTH(1U) /*!< transfer data size of peripheral is 16-bit */ +#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PWIDTH(2U) /*!< transfer data size of peripheral is 32-bit */ + +/* DMA transfer data size of memory */ +#define CHCTL_MWIDTH(regval) (BITS(10,11) & ((regval) << 10)) /*!< transfer data size of memory */ +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MWIDTH(0U) /*!< transfer data size of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1U) /*!< transfer data size of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2U) /*!< transfer data size of memory is 32-bit */ + +/* DMA channel priority level */ +#define CHCTL_PRIO(regval) (BITS(12,13) & ((regval) << 12)) /*!< DMA channel priority level */ +#define DMA_PRIORITY_LOW CHCTL_PRIO(0U) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1U) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2U) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3U) /*!< ultra high priority */ + +/* DMA transfer counter */ +#define DMA_CHANNEL_CNT_MASK DMA_CHXCNT_CNT /*!< transfer counter mask */ + +/* DMAMUX request multiplexer channel input identification */ +#define RM_CHXCFG_MUXID(regval) (BITS(0,5) & ((regval) << 0)) /*!< multiplexer input identification */ +#define DMA_REQUEST_M2M RM_CHXCFG_MUXID(0U) /*!< memory to memory transfer */ +#define DMA_REQUEST_GENERATOR0 RM_CHXCFG_MUXID(1U) /*!< DMAMUX request generator 0 */ +#define DMA_REQUEST_GENERATOR1 RM_CHXCFG_MUXID(2U) /*!< DMAMUX request generator 1 */ +#define DMA_REQUEST_GENERATOR2 RM_CHXCFG_MUXID(3U) /*!< DMAMUX request generator 2 */ +#define DMA_REQUEST_GENERATOR3 RM_CHXCFG_MUXID(4U) /*!< DMAMUX request generator 3 */ +#define DMA_REQUEST_ADC RM_CHXCFG_MUXID(5U) /*!< DMAMUX ADC request */ +#define DMA_REQUEST_I2C0_RX RM_CHXCFG_MUXID(10U) /*!< DMAMUX I2C0 RX request */ +#define DMA_REQUEST_I2C0_TX RM_CHXCFG_MUXID(11U) /*!< DMAMUX I2C0 TX request */ +#define DMA_REQUEST_I2C1_RX RM_CHXCFG_MUXID(12U) /*!< DMAMUX I2C1 RX request */ +#define DMA_REQUEST_I2C1_TX RM_CHXCFG_MUXID(13U) /*!< DMAMUX I2C1 TX request */ +#define DMA_REQUEST_SPI0_RX RM_CHXCFG_MUXID(16U) /*!< DMAMUX SPI0 RX request */ +#define DMA_REQUEST_SPI0_TX RM_CHXCFG_MUXID(17U) /*!< DMAMUX SPI0 TX request */ +#define DMA_REQUEST_SPI1_RX RM_CHXCFG_MUXID(18U) /*!< DMAMUX SPI1 RX request */ +#define DMA_REQUEST_SPI1_TX RM_CHXCFG_MUXID(19U) /*!< DMAMUX SPI1 TX request */ +#define DMA_REQUEST_TIMER0_CH0 RM_CHXCFG_MUXID(20U) /*!< DMAMUX TIMER0 CH0 request */ +#define DMA_REQUEST_TIMER0_CH1 RM_CHXCFG_MUXID(21U) /*!< DMAMUX TIMER0 CH1 request */ +#define DMA_REQUEST_TIMER0_CH2 RM_CHXCFG_MUXID(22U) /*!< DMAMUX TIMER0 CH2 request */ +#define DMA_REQUEST_TIMER0_CH3 RM_CHXCFG_MUXID(23U) /*!< DMAMUX TIMER0 CH3 request */ +#define DMA_REQUEST_TIMER0_TRIG RM_CHXCFG_MUXID(24U) /*!< DMAMUX TIMER0 TRIG request */ +#define DMA_REQUEST_TIMER0_UP RM_CHXCFG_MUXID(25U) /*!< DMAMUX TIMER0 UP request */ +#define DMA_REQUEST_TIMER0_COM RM_CHXCFG_MUXID(26U) /*!< DMAMUX TIMER0 COM request */ +#define DMA_REQUEST_TIMER2_CH0 RM_CHXCFG_MUXID(32U) /*!< DMAMUX TIMER2 CH0 request */ +#define DMA_REQUEST_TIMER2_CH1 RM_CHXCFG_MUXID(33U) /*!< DMAMUX TIMER2 CH1 request */ +#define DMA_REQUEST_TIMER2_CH2 RM_CHXCFG_MUXID(34U) /*!< DMAMUX TIMER2 CH2 request */ +#define DMA_REQUEST_TIMER2_CH3 RM_CHXCFG_MUXID(35U) /*!< DMAMUX TIMER2 CH3 request */ +#define DMA_REQUEST_TIMER2_TRIG RM_CHXCFG_MUXID(36U) /*!< DMAMUX TIMER2 TRIG request */ +#define DMA_REQUEST_TIMER2_UP RM_CHXCFG_MUXID(37U) /*!< DMAMUX TIMER2 UP request */ +#define DMA_REQUEST_TIMER15_CH0 RM_CHXCFG_MUXID(44U) /*!< DMAMUX TIMER15 CH0 request */ +#define DMA_REQUEST_TIMER15_UP RM_CHXCFG_MUXID(46U) /*!< DMAMUX TIMER15 UP request */ +#define DMA_REQUEST_TIMER16_CH0 RM_CHXCFG_MUXID(47U) /*!< DMAMUX TIMER16 CH0 request */ +#define DMA_REQUEST_TIMER16_UP RM_CHXCFG_MUXID(49U) /*!< DMAMUX TIMER16 UP request */ +#define DMA_REQUEST_USART0_RX RM_CHXCFG_MUXID(50U) /*!< DMAMUX USART0 RX request */ +#define DMA_REQUEST_USART0_TX RM_CHXCFG_MUXID(51U) /*!< DMAMUX USART0 TX request */ +#define DMA_REQUEST_USART1_RX RM_CHXCFG_MUXID(52U) /*!< DMAMUX USART1 RX request */ +#define DMA_REQUEST_USART1_TX RM_CHXCFG_MUXID(53U) /*!< DMAMUX USART1 TX request */ +#define DMA_REQUEST_USART2_RX RM_CHXCFG_MUXID(54U) /*!< DMAMUX USART3 RX request */ +#define DMA_REQUEST_USART2_TX RM_CHXCFG_MUXID(55U) /*!< DMAMUX USART3 TX request */ + +/* DMAMUX request generator trigger input identification */ +#define RG_CHXCFG_TID(regval) (BITS(0,4) & ((regval) << 0)) /*!< trigger input identification */ +#define DMAMUX_TRIGGER_EXTI0 RG_CHXCFG_TID(0U) /*!< trigger input is EXTI0 */ +#define DMAMUX_TRIGGER_EXTI1 RG_CHXCFG_TID(1U) /*!< trigger input is EXTI1 */ +#define DMAMUX_TRIGGER_EXTI2 RG_CHXCFG_TID(2U) /*!< trigger input is EXTI2 */ +#define DMAMUX_TRIGGER_EXTI3 RG_CHXCFG_TID(3U) /*!< trigger input is EXTI3 */ +#define DMAMUX_TRIGGER_EXTI4 RG_CHXCFG_TID(4U) /*!< trigger input is EXTI4 */ +#define DMAMUX_TRIGGER_EXTI5 RG_CHXCFG_TID(5U) /*!< trigger input is EXTI5 */ +#define DMAMUX_TRIGGER_EXTI6 RG_CHXCFG_TID(6U) /*!< trigger input is EXTI6 */ +#define DMAMUX_TRIGGER_EXTI7 RG_CHXCFG_TID(7U) /*!< trigger input is EXTI7 */ +#define DMAMUX_TRIGGER_EXTI8 RG_CHXCFG_TID(8U) /*!< trigger input is EXTI8 */ +#define DMAMUX_TRIGGER_EXTI9 RG_CHXCFG_TID(9U) /*!< trigger input is EXTI9 */ +#define DMAMUX_TRIGGER_EXTI10 RG_CHXCFG_TID(10U) /*!< trigger input is EXTI10 */ +#define DMAMUX_TRIGGER_EXTI11 RG_CHXCFG_TID(11U) /*!< trigger input is EXTI11 */ +#define DMAMUX_TRIGGER_EXTI12 RG_CHXCFG_TID(12U) /*!< trigger input is EXTI12 */ +#define DMAMUX_TRIGGER_EXTI13 RG_CHXCFG_TID(13U) /*!< trigger input is EXTI13 */ +#define DMAMUX_TRIGGER_EXTI14 RG_CHXCFG_TID(14U) /*!< trigger input is EXTI14 */ +#define DMAMUX_TRIGGER_EXTI15 RG_CHXCFG_TID(15U) /*!< trigger input is EXTI15 */ +#define DMAMUX_TRIGGER_EVT0_OUT RG_CHXCFG_TID(16U) /*!< trigger input is Evt0_out */ +#define DMAMUX_TRIGGER_EVT1_OUT RG_CHXCFG_TID(17U) /*!< trigger input is Evt1_out */ +#define DMAMUX_TRIGGER_EVT2_OUT RG_CHXCFG_TID(18U) /*!< trigger input is Evt2_out */ +#define DMAMUX_TRIGGER_TIMER13_O RG_CHXCFG_TID(21U) /*!< trigger input is TIMER13 O */ + +/* DMAMUX request generator trigger polarity */ +#define RG_CHXCFG_RGTP(regval) (BITS(17,18) & ((regval) << 17)) /*!< DMA request generator trigger polarity */ +#define DMAMUX_GEN_NO_EVENT RG_CHXCFG_RGTP(0U) /*!< no event detection */ +#define DMAMUX_GEN_RISING RG_CHXCFG_RGTP(1U) /*!< rising edge */ +#define DMAMUX_GEN_FALLING RG_CHXCFG_RGTP(2U) /*!< falling edge */ +#define DMAMUX_GEN_RISING_FALLING RG_CHXCFG_RGTP(3U) /*!< rising and falling edges */ + +/* number of DMA requests to be generated */ +#define RG_CHXCFG_NBRG(regval) (BITS(19,23) & ((regval) << 19)) /*!< number of DMA requests to be generated */ + +/* DMAMUX request multiplexer channel synchronization input identification */ +#define RM_CHXCFG_SYNCID(regval) (BITS(24,28) & ((regval) << 24)) /*!< synchronization input identification */ +#define DMAMUX_SYNC_EXTI0 RM_CHXCFG_SYNCID(0U) /*!< synchronization input is EXTI0 */ +#define DMAMUX_SYNC_EXTI1 RM_CHXCFG_SYNCID(1U) /*!< synchronization input is EXTI1 */ +#define DMAMUX_SYNC_EXTI2 RM_CHXCFG_SYNCID(2U) /*!< synchronization input is EXTI2 */ +#define DMAMUX_SYNC_EXTI3 RM_CHXCFG_SYNCID(3U) /*!< synchronization input is EXTI3 */ +#define DMAMUX_SYNC_EXTI4 RM_CHXCFG_SYNCID(4U) /*!< synchronization input is EXTI4 */ +#define DMAMUX_SYNC_EXTI5 RM_CHXCFG_SYNCID(5U) /*!< synchronization input is EXTI5 */ +#define DMAMUX_SYNC_EXTI6 RM_CHXCFG_SYNCID(6U) /*!< synchronization input is EXTI6 */ +#define DMAMUX_SYNC_EXTI7 RM_CHXCFG_SYNCID(7U) /*!< synchronization input is EXTI7 */ +#define DMAMUX_SYNC_EXTI8 RM_CHXCFG_SYNCID(8U) /*!< synchronization input is EXTI8 */ +#define DMAMUX_SYNC_EXTI9 RM_CHXCFG_SYNCID(9U) /*!< synchronization input is EXTI9 */ +#define DMAMUX_SYNC_EXTI10 RM_CHXCFG_SYNCID(10U) /*!< synchronization input is EXTI10 */ +#define DMAMUX_SYNC_EXTI11 RM_CHXCFG_SYNCID(11U) /*!< synchronization input is EXTI11 */ +#define DMAMUX_SYNC_EXTI12 RM_CHXCFG_SYNCID(12U) /*!< synchronization input is EXTI12 */ +#define DMAMUX_SYNC_EXTI13 RM_CHXCFG_SYNCID(13U) /*!< synchronization input is EXTI13 */ +#define DMAMUX_SYNC_EXTI14 RM_CHXCFG_SYNCID(14U) /*!< synchronization input is EXTI14 */ +#define DMAMUX_SYNC_EXTI15 RM_CHXCFG_SYNCID(15U) /*!< synchronization input is EXTI15 */ +#define DMAMUX_SYNC_EVT0_OUT RM_CHXCFG_SYNCID(16U) /*!< synchronization input is Evt0_out */ +#define DMAMUX_SYNC_EVT1_OUT RM_CHXCFG_SYNCID(17U) /*!< synchronization input is Evt1_out */ +#define DMAMUX_SYNC_EVT2_OUT RM_CHXCFG_SYNCID(18U) /*!< synchronization input is Evt2_out */ +#define DMAMUX_SYNC_TIMER13_O RM_CHXCFG_SYNCID(21U) /*!< synchronization input is TIMER13 O */ + +/* DMAMUX request multiplexer synchronization input polarity */ +#define RM_CHXCFG_SYNCP(regval) (BITS(17,18) & ((regval) << 17)) /*!< synchronization input polarity */ +#define DMAMUX_SYNC_NO_EVENT RM_CHXCFG_SYNCP(0U) /*!< no event detection */ +#define DMAMUX_SYNC_RISING RM_CHXCFG_SYNCP(1U) /*!< rising edge */ +#define DMAMUX_SYNC_FALLING RM_CHXCFG_SYNCP(2U) /*!< falling edge */ +#define DMAMUX_SYNC_RISING_FALLING RM_CHXCFG_SYNCP(3U) /*!< rising and falling edges */ + +/* number of DMA requests to forward */ +#define RM_CHXCFG_NBR(regval) (BITS(19,23) & ((regval) << 19)) /*!< number of DMA requests to forward */ + +/* function declarations */ +/* DMA functions */ +/* DMA initialization functions */ +/* deinitialize DMA a channel registers */ +void dma_deinit(dma_channel_enum channelx); +/* initialize the parameters of DMA structure with the default values */ +void dma_struct_para_init(dma_parameter_struct *init_struct); +/* initialize DMA channel */ +void dma_init(dma_channel_enum channelx, dma_parameter_struct *init_struct); +/* enable DMA circulation mode */ +void dma_circulation_enable(dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(dma_channel_enum channelx); +/* enable memory to memory mode */ +void dma_memory_to_memory_enable(dma_channel_enum channelx); +/* disable memory to memory mode */ +void dma_memory_to_memory_disable(dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(dma_channel_enum channelx); + +/* DMA configuration functions */ +/* set DMA peripheral base address */ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address); +/* set DMA memory base address */ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address); +/* set the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(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(dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority); +/* configure transfer data size of memory */ +void dma_memory_width_config(dma_channel_enum channelx, uint32_t mwidth); +/* configure transfer data size of peripheral */ +void dma_periph_width_config(dma_channel_enum channelx, uint32_t pwidth); +/* enable next address increasement algorithm of memory */ +void dma_memory_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of memory */ +void dma_memory_increase_disable(dma_channel_enum channelx); +/* enable next address increasement algorithm of peripheral */ +void dma_periph_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of peripheral */ +void dma_periph_increase_disable(dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction); + +/* DMA interrupt and flag functions */ +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear a DMA channel flag */ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source); +/* check DMA flag and interrupt enable bit is set or not */ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t int_flag); +/* clear a DMA channel interrupt flag */ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t int_flag); + +/* DMAMUX functions */ +/* DMAMUX request multiplexer functions */ +/* initialize the parameters of DMAMUX synchronization mode structure with the default values */ +void dmamux_sync_struct_para_init(dmamux_sync_parameter_struct *init_struct); +/* initialize DMAMUX request multiplexer channel synchronization mode */ +void dmamux_synchronization_init(dmamux_multiplexer_channel_enum channelx, + dmamux_sync_parameter_struct *init_struct); +/* enable synchronization mode */ +void dmamux_synchronization_enable(dmamux_multiplexer_channel_enum channelx); +/* disable synchronization mode */ +void dmamux_synchronization_disable(dmamux_multiplexer_channel_enum channelx); +/* enable event generation */ +void dmamux_event_generation_enable(dmamux_multiplexer_channel_enum channelx); +/* disable event generation */ +void dmamux_event_generation_disable(dmamux_multiplexer_channel_enum channelx); + +/* DMAMUX request generator functions */ +/* initialize the parameters of DMAMUX request generator structure with the default values */ +void dmamux_gen_struct_para_init(dmamux_gen_parameter_struct *init_struct); +/* initialize DMAMUX request generator channel */ +void dmamux_request_generator_init(dmamux_generator_channel_enum channelx, + dmamux_gen_parameter_struct *init_struct); +/* enable DMAMUX request generator channel */ +void dmamux_request_generator_channel_enable(dmamux_generator_channel_enum channelx); +/* disable DMAMUX request generator channel */ +void dmamux_request_generator_channel_disable(dmamux_generator_channel_enum channelx); + +/* DMAMUX configuration functions */ +/* configure synchronization input polarity */ +void dmamux_synchronization_polarity_config(dmamux_multiplexer_channel_enum channelx, + uint32_t polarity); +/* configure number of DMA requests to forward */ +void dmamux_request_forward_number_config(dmamux_multiplexer_channel_enum channelx, + uint32_t number); +/* configure synchronization input identification */ +void dmamux_sync_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id); +/* configure multiplexer input identification */ +void dmamux_request_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id); +/* configure trigger input polarity */ +void dmamux_trigger_polarity_config(dmamux_generator_channel_enum channelx, uint32_t polarity); +/* configure number of DMA requests to be generated */ +void dmamux_request_generate_number_config(dmamux_generator_channel_enum channelx, uint32_t number); +/* configure trigger input identification */ +void dmamux_trigger_id_config(dmamux_generator_channel_enum channelx, uint32_t id); + +/* DMAMUX interrupt and flag functions */ +/* get DMAMUX flag */ +FlagStatus dmamux_flag_get(dmamux_flag_enum flag); +/* clear DMAMUX flag */ +void dmamux_flag_clear(dmamux_flag_enum flag); +/* enable DMAMUX interrupt */ +void dmamux_interrupt_enable(dmamux_interrupt_enum interrupt); +/* disable DMAMUX interrupt */ +void dmamux_interrupt_disable(dmamux_interrupt_enum interrupt); +/* get DMAMUX interrupt flag */ +FlagStatus dmamux_interrupt_flag_get(dmamux_interrupt_flag_enum int_flag); +/* clear DMAMUX interrupt flag */ +void dmamux_interrupt_flag_clear(dmamux_interrupt_flag_enum int_flag); + +#endif /* GD32C2X1_DMA_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_exti.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_exti.h new file mode 100644 index 0000000..3122e72 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_exti.h @@ -0,0 +1,282 @@ +/*! + \file gd32c2x1_exti.h + \brief definitions for the EXTI + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_EXTI_H +#define GD32C2X1_EXTI_H + +#include "gd32c2x1.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 */ +#define EXTI_INTEN_INTEN23 BIT(23) /*!< interrupt from line 23 */ + +/* 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 */ +#define EXTI_EVEN_EVEN23 BIT(23) /*!< event from line 23 */ + +/* 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 */ +#define EXTI_RTEN_RTEN23 BIT(23) /*!< rising edge from line 23 */ + +/* 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 */ +#define EXTI_FTEN_FTEN23 BIT(23) /*!< falling edge from line 23 */ + +/* 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 */ +#define EXTI_SWIEV_SWIEV23 BIT(23) /*!< software interrupt/event request from line 23 */ + +/* EXTI_PD */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt pending status from line 17 */ +#define EXTI_PD_PD18 BIT(18) /*!< interrupt pending status from line 18 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt pending status from line 19 */ +#define EXTI_PD_PD20 BIT(20) /*!< interrupt pending status from line 20 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt pending status from line 21 */ +#define EXTI_PD_PD22 BIT(22) /*!< interrupt pending status from line 22 */ +#define EXTI_PD_PD23 BIT(23) /*!< interrupt pending status from line 23 */ + +/* 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_23 = BIT(23) /*!< EXTI line 23 */ +} 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 /*!< without rising edge or falling edge trigger */ +} exti_trig_type_enum; + + +/* function declarations */ +/* interrupt and event configuration functions */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* initialize the EXTI, 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); +/* enable EXTI software interrupt event */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* disable EXTI software interrupt event */ +void exti_software_interrupt_disable(exti_line_enum linex); + +/* interrupt and flag functions */ +/* get EXTI line x interrupt pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI line x interrupt pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI line x interrupt pending flag */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI line x interrupt pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); + +#endif /* gd32c2x1_EXTI_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_fmc.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_fmc.h new file mode 100644 index 0000000..3942736 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_fmc.h @@ -0,0 +1,461 @@ +/*! + \file gd32c2x1_fmc.h + \brief definitions for the FMC + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_FMC_H +#define GD32C2X1_FMC_H + +#include "gd32c2x1.h" + +/* FMC and option bytes definition */ +#define FMC FMC_BASE /*!< FMC base address */ + +/* registers definitions */ +#define FMC_WS REG32(FMC + 0x00000000U) /*!< FMC wait state register */ +#define FMC_KEY REG32(FMC + 0x00000008U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32(FMC + 0x0000000CU) /*!< FMC option bytes unlock key register */ +#define FMC_STAT REG32(FMC + 0x00000010U) /*!< FMC status register */ +#define FMC_CTL REG32(FMC + 0x00000014U) /*!< FMC control register */ +#define FMC_OBCTL REG32(FMC + 0x00000020U) /*!< FMC option byte register */ +#define FMC_DCRP_SADDR0 REG32(FMC + 0x00000024U) /*!< FMC DCRP area 0 start address register */ +#define FMC_DCRP_EADDR0 REG32(FMC + 0x00000028U) /*!< FMC DCRP area 0 end address register */ +#define FMC_WP0 REG32(FMC + 0x0000002CU) /*!< FMC erase/program protection area 0 register */ +#define FMC_WP1 REG32(FMC + 0x00000030U) /*!< FMC erase/program protection area 1 register */ +#define FMC_DCRP_SADDR1 REG32(FMC + 0x00000034U) /*!< FMC DCRP area 1 start address register */ +#define FMC_DCRP_EADDR1 REG32(FMC + 0x00000038U) /*!< FMC DCRP area 1 end address register */ +#define FMC_SCR REG32(FMC + 0x00000080U) /*!< FMC securable area register */ +#define FMC_PID REG32(FMC + 0x00000110U) /*!< FMC product ID register */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */ +#define FMC_WS_PFEN BIT(8) /*!< pre-fetch enable */ +#define FMC_WS_ICEN BIT(9) /*!< IBUS cache enable */ +#define FMC_WS_ICRST BIT(11) /*!< IBUS cache reset */ +#define FMC_WS_MFPE BIT(16) /*!< main flash programmed or empty flag */ +#define FMC_WS_DBGEN BIT(18) /*!< enable/disable the debugger by software */ + +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC_CTL unlock key */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key */ + +/* FMC_STAT */ +#define FMC_STAT_ENDF BIT(0) /*!< end of operation flag */ +#define FMC_STAT_OPRERR BIT(1) /*!< operation error flag bit */ +#define FMC_STAT_PGERR BIT(3) /*!< program error flag */ +#define FMC_STAT_WPERR BIT(4) /*!< erase/program protection error flag bit */ +#define FMC_STAT_PGAERR BIT(5) /*!< program alignment error flag */ +#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_FSTPERR BIT(9) /*!< fast programming error flag bit */ +#define FMC_STAT_RPERR BIT(14) /*!< read protection error flag bit */ +#define FMC_STAT_OBERR BIT(15) /*!< option byte read error bit */ +#define FMC_STAT_BUSY BIT(16) /*!< flash busy flag */ + +/* FMC_CTL */ +#define FMC_CTL_PG BIT(0) /*!< main flash page program command bit */ +#define FMC_CTL_PER BIT(1) /*!< main flash page erase command bit */ +#define FMC_CTL_MER BIT(2) /*!< main flash mass erase command bit */ +#define FMC_CTL_PN BITS(3,8) /*!< page number to erase */ +#define FMC_CTL_START BIT(16) /*!< send erase command to FMC bit */ +#define FMC_CTL_OBSTART BIT(17) /*!< option byte change command */ +#define FMC_CTL_FSTPG BIT(18) /*!< send option byte change command to FMC bit */ +#define FMC_CTL_ENDIE BIT(24) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_ERRIE BIT(25) /*!< operation error interrupt enable bit */ +#define FMC_CTL_RPERRIE BIT(26) /*!< read protection error interrupt enable bit */ +#define FMC_CTL_OBRLD BIT(27) /*!< option byte reload bit */ +#define FMC_CTL_SCR BIT(28) /*!< security protection enable bit */ +#define FMC_CTL_OBLK BIT(30) /*!< FMC_OBCTL lock bit */ +#define FMC_CTL_LK BIT(31) /*!< FMC_CTL lock bit */ + +/* FMC_OBCTL */ +#define FMC_OBCTL_SPC BITS(0,7) /*!< security protection value */ +#define FMC_OBCTL_BORST_EN BIT(8) /*!< brown out reset enable */ +#define FMC_OBCTL_BORR_TH BITS(9,10) /*!< BOR threshold at rising VDD supply */ +#define FMC_OBCTL_BORF_TH BITS(11,12) /*!< BOR threshold at falling VDD supply */ +#define FMC_OBCTL_NRST_STDBY BIT(14) /*!< option byte standby reset value bit */ +#define FMC_OBCTL_HXTAL_REMAP BIT(21) /*!< HXTAL remapping bit */ +#define FMC_OBCTL_SRAM_ECC_EN BIT(22) /*!< SRAM ECC disable bit */ +#define FMC_OBCTL_NRST_DPSLP BIT(13) /*!< option byte deepsleep reset value bit */ +#define FMC_OBCTL_NFWDG_HW BIT(16) /*!< free watchdog configuration bit */ +#define FMC_OBCTL_NWWDG_HW BIT(19) /*!< window watchdog configuration bit */ +#define FMC_OBCTL_SWBT0 BIT(24) /*!< software BOOT0 bit */ +#define FMC_OBCTL_NBOOT1 BIT(25) /*!< NBOOT1 option bit */ +#define FMC_OBCTL_NBOOT0 BIT(26) /*!< NBOOT0 option bit */ +#define FMC_OBCTL_NRST_MDSEL BITS(27,28) /*!< NRST pin mode bit */ + +/* FMC_DCRP_SADDR0 */ +#define FMC_DCRP_SADDR0_DCRP0_SADDR BITS(0,6) /*!< start offset of DCRP area 0 */ + +/* FMC_DCRP_EADDR0 */ +#define FMC_DCRP_EADDR0_DCRP0_EADDR BITS(0,6) /*!< end offset DCRP area0 */ +#define FMC_DCRP_EADDR0_DCRP_EREN BIT(31) /*!< DCRP area erase enable configuration bit */ + +/* FMC_WP0 */ +#define FMC_WP0_WP0_SADDR BITS(0,5) /*!< start offset of write protection area 0 */ +#define FMC_WP0_WP0_EADDR BITS(16,21) /*!< end offset of write protection area 0 */ + +/* FMC_WP1 */ +#define FMC_WP1_WP1_SADDR BITS(0,5) /*!< start offset of write protection area 1 */ +#define FMC_WP1_WP1_EADDR BITS(16,21) /*!< end offset of write protection area 1 */ + +/* FMC_DCRP_SADDR1 */ +#define FMC_DCRP_SADDR1_DCRP1_SADDR BITS(0,6) /*!< start offset of DCRP area1 */ + +/* FMC_DCRP_EADDR1 */ +#define FMC_DCRP_EADDR1_DCRP1_EADDR BITS(0,6) /*!< end offset DCRP area 1 */ + +/* FMC_SCR */ +#define FMC_SCR_SCR_PAGE_CNT BITS(0,6) /*!< configure the number of pages of securable area */ +#define FMC_SCR_BOOTLK BIT(16) /*!< this bit is set to force boot from user flash area */ + +/* FMC_PID */ +#define FMC_PID_PID BITS(0,31) /*!< product ID bits */ + +/* constants definitions */ +/* FMC_CTL unlock key */ +#define FMC_UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< FMC_CTL unlock key 0 */ +#define FMC_UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< FMC_CTL unlock key 1 */ + +/* FMC_CTL_OBLK unlock key */ +#define OB_UNLOCK_KEY0 ((uint32_t)0x08192A3B) /*!< FMC_CTL_OBLK unlock key 0 */ +#define OB_UNLOCK_KEY1 ((uint32_t)0x4C5D6E7F) /*!< FMC_CTL_OBLK unlock key 1 */ + +/* FMC wait state added */ +#define WS_WSCNT(regval) (BITS(0,2) & ((uint32_t)(regval))) +#define FMC_WAIT_STATE_0 WS_WSCNT(0) /*!< 0 wait state added */ +#define FMC_WAIT_STATE_1 WS_WSCNT(1) /*!< 1 wait state added */ + +/* FMC first location empty check status */ +#define WS_MFPE(regval) (BIT(16) & ((uint32_t)(regval))) +#define FMC_WS_MFPE_PROGRAMMED WS_MFPE(0) /*!< the first location of main flash is programmed */ +#define FMC_WS_MFPE_EMPTY WS_MFPE(1) /*!< the first location of main flash is empty */ + +/* option byte security protection configuration */ +#define FMC_NSPC ((uint8_t)0xA5U) /*!< no protection */ +#define FMC_LSPC ((uint8_t)0xBBU) /*!< protection level low */ +#define FMC_HSPC ((uint8_t)0xCCU) /*!< protection level high */ + +/* option byte BOR threshold value at rising VDD supply */ +#define OBCTL_BORR_TH(regval) (BITS(9,10) & ((uint32_t)(regval) << 9U)) +#define OB_BORR_TH_VALUE0 OBCTL_BORR_TH(0) /*!< BOR rising level 1 */ +#define OB_BORR_TH_VALUE1 OBCTL_BORR_TH(1) /*!< BOR rising level 2 */ +#define OB_BORR_TH_VALUE2 OBCTL_BORR_TH(2) /*!< BOR rising level 3 */ +#define OB_BORR_TH_VALUE3 OBCTL_BORR_TH(3) /*!< BOR rising level 4 */ + +/* option byte BOR threshold value at falling VDD supply */ +#define OBCTL_BORF_TH(regval) (BITS(11,12) & ((uint32_t)(regval) << 11U)) +#define OB_BORF_TH_VALUE0 OBCTL_BORF_TH(0) /*!< BOR falling level 1 */ +#define OB_BORF_TH_VALUE1 OBCTL_BORF_TH(1) /*!< BOR falling level 2 */ +#define OB_BORF_TH_VALUE2 OBCTL_BORF_TH(2) /*!< BOR falling level 3 */ +#define OB_BORF_TH_VALUE3 OBCTL_BORF_TH(3) /*!< BOR falling level 4 */ + +/* option byte BOR reset configuration */ +#define OBCTL_BORST(regval) (BIT(8) & ((uint32_t)(regval) << 8U)) +#define OB_BORST_DISABLE (OBCTL_BORST(0)) /*!< Brown out reset disable, power-on reset defined by POR/PDR levels */ +#define OB_BORST_ENABLE (OBCTL_BORST(1)) /*!< Brown out reset enable, values of BORR_TH and BORF_TH taken into account */ + +/* option byte reset or not entering deep sleep mode */ +#define OBCTL_NRST_DPSLP(regval) (BIT(13) & ((uint32_t)(regval) << 13U)) +#define OB_DEEPSLEEP_RST OBCTL_NRST_DPSLP(0) /*!< generate a reset instead of entering deepsleep mode */ +#define OB_DEEPSLEEP_NRST OBCTL_NRST_DPSLP(1) /*!< no reset when entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OBCTL_NRST_STDBY(regval) (BIT(14) & ((uint32_t)(regval) << 14U)) +#define OB_STDBY_RST OBCTL_NRST_STDBY(0) /*!< generate a reset instead of entering standby mode */ +#define OB_STDBY_NRST OBCTL_NRST_STDBY(1) /*!< no reset when entering deepsleep mode */ + +/* option byte software/hardware free watchdog timer */ +#define OBCTL_NFWDG_HW(regval) (BIT(16) & ((uint32_t)(regval) << 16U)) +#define OB_FWDGT_HW OBCTL_NFWDG_HW(0) /*!< hardware free watchdog */ +#define OB_FWDGT_SW OBCTL_NFWDG_HW(1) /*!< software free watchdog */ + +/* option byte software/hardware window watchdog timer */ +#define OBCTL_NWWDG_HW(regval) (BIT(19) & ((uint32_t)(regval) << 19U)) +#define OB_WWDGT_HW OBCTL_NWWDG_HW(0) /*!< hardware window watchdog */ +#define OB_WWDGT_SW OBCTL_NWWDG_HW(1) /*!< software window watchdog */ + +/* option byte software boot0 */ +#define OBCTL_SWBT0(regval) (BIT(24) & ((uint32_t)(regval) << 24U)) +#define OB_SWBOOT0_FROM_OB_BOOT0 OBCTL_SWBT0(1) /*!< BOOT0 taken from the option bit nBOOT0 */ +#define OB_SWBOOT0_FROM_PIN OBCTL_SWBT0(0) /*!< BOOT0 taken from PB8/BOOT0 pin */ + +/* option byte boot1 configuration */ +#define OBCTL_NBOOT1(regval) (BIT(25) & ((uint32_t)(regval) << 25U)) +#define OB_NBOOT1_VALUE_0 OBCTL_NBOOT1(0) /*!< option byte NBOOT1 is value 0 */ +#define OB_NBOOT1_VALUE_1 OBCTL_NBOOT1(1) /*!< option byte NBOOT1 is value 1 */ + +/* option byte boot0 configuration */ +#define OBCTL_NBOOT0(regval) (BIT(26) & ((uint32_t)(regval) << 26U)) +#define OB_NBOOT0_VALUE_0 OBCTL_NBOOT0(0) /*!< option byte NBOOT0 is value 0 */ +#define OB_NBOOT0_VALUE_1 OBCTL_NBOOT0(1) /*!< option byte NBOOT0 is value 1 */ + +/* option byte reset pin mode */ +#define OBCTL_NRST_MDSEL(regval) (BITS(27,28) & ((uint32_t)(regval) << 27U)) +#define OB_NRST_PIN_INPUT_MODE OBCTL_NRST_MDSEL(1) /*!< a low level on the NRST pin can reset system, internal reset can not drive NRST pin */ +#define OB_NRST_PIN_NORMAL_GPIO OBCTL_NRST_MDSEL(2) /*!< NRST pin function as normal GPIO */ +#define OB_NRST_PIN_INPUT_OUTPUT_MODE OBCTL_NRST_MDSEL(3) /*!< NRST pin configure as input/output mode */ + +/* option byte DCRP erase enable configuration */ +#define OB_DCRP_EADDR_DCRP_EREN(regval) (BIT(31) & ((uint32_t)(regval) << 31U)) +#define OB_DCRP_AREA_ERASE_DISABLE OB_DCRP_EADDR_DCRP_EREN(0) /*!< DCRP is not erased when a SPC value is decreased from value 1 to value 0 */ +#define OB_DCRP_AREA_ERASE_ENABLE OB_DCRP_EADDR_DCRP_EREN(1) /*!< DCRP is erased when a SPC value is decreased from value 1 to value 0 */ + +/* option byte boot lock */ +#define OB_SCR_BOOTLK(regval) (BIT(16) & ((uint32_t)(regval) << 16U)) +#define OB_BOOT_UNLOCK OB_SCR_BOOTLK(0) /*!< unlock boot */ +#define OB_BOOT_LOCK_FROM_MAIN_FLASH OB_SCR_BOOTLK(1) /*!< boot from main flash */ + +/* option byte HXTAL remapping */ +#define OB_HXTAL_REMAP(regval) (BIT(21) & ((uint32_t)(regval) << 21U)) +#define OB_HXTAL_REMAP_ENABLE OB_HXTAL_REMAP(0) /*!< HXTAL remapping enable */ +#define OB_HXTAL_REMAP_DISABLE OB_HXTAL_REMAP(1) /*!< HXTAL remapping disable */ + +/* option byte SRAM ECC disable */ +#define OB_SRAM_ECC_EN(regval) (BIT(22) & ((uint32_t)(regval) << 22U)) +#define OB_SRAM_ECC_ENABLE OB_SRAM_ECC_EN(0) /*!< SRAM ECC check enable */ +#define OB_SRAM_ECC_DISABLE OB_SRAM_ECC_EN(1) /*!< SRAM ECC check disable */ + +/* FMC interrupt enable */ +#define FMC_INT_END FMC_CTL_ENDIE /*!< FMC end of operation interrupt enable */ +#define FMC_INT_ERR FMC_CTL_ERRIE /*!< FMC error interrupt enable */ +#define FMC_INT_RPERR FMC_CTL_RPERRIE /*!< read protection error interrupt enable */ + +/* FMC flags */ +#define FMC_FLAG_BUSY FMC_STAT_BUSY /*!< FMC busy flag */ +#define FMC_FLAG_ENDF FMC_STAT_ENDF /*!< FMC end of operation flag */ +#define FMC_FLAG_OBERR FMC_STAT_OBERR /*!< option byte read error */ +#define FMC_FLAG_RPERR FMC_STAT_RPERR /*!< read protection error */ +#define FMC_FLAG_FSTPERR FMC_STAT_FSTPERR /*!< fast programming error */ +#define FMC_FLAG_PGSERR FMC_STAT_PGSERR /*!< program sequence error */ +#define FMC_FLAG_PGMERR FMC_STAT_PGMERR /*!< program size error*/ +#define FMC_FLAG_PGAERR FMC_STAT_PGAERR /*!< program alignment error */ +#define FMC_FLAG_WPERR FMC_STAT_WPERR /*!< erase/program protection error */ +#define FMC_FLAG_PGERR FMC_STAT_PGERR /*!< program error */ +#define FMC_FLAG_OPRERR FMC_STAT_OPRERR /*!< operation error */ + +/* FMC interrupt flags */ +#define FMC_INT_FLAG_RPERR FMC_STAT_RPERR /*!< read protection error interrupt flag */ +#define FMC_INT_FLAG_OPRERR FMC_STAT_OPRERR /*!< operation error interrupt flag */ +#define FMC_INT_FLAG_END FMC_STAT_ENDF /*!< end of operation interrupt flag */ + +#define OBCTL_SPC_OFFSET (0U) /*!< bit offset of SPC offset in FMC_OBCTL register */ +#define OBCTL_USER_OFFSET (8U) /*!< bit offset of USER offset in FMC_OBCTL register */ +#define CTL_PN_OFFSET (3U) /*!< bit offset of PNSEL offset in FMC_CTL register */ +#define SCR_PAGE_CNT_OFFSET (0U) /*!< bit offset of SCR_PAGE_CNT in FMC_SCR */ +#define DCRP_SADDR_OFFSET (0U) /*!< bit offset of DCRP0_SADDR/DCRP1_SADDR in FMC_DCRP_SADDR0/FMC_DCRP_SADDR1 */ +#define DCRP_EADDR_OFFSET (0U) /*!< bit offset of DCRP0_EADDR/DCRP1_EADDR in FMC_DCRP_EADDR0/FMC_DCRP_EADDR1 */ +#define DCRP_EREN_OFFSET (31U) /*!< bit offset of DCRP_EREN in FMC_DCRP_EADDR */ +#define WP_SADDR_OFFSET (0U) /*!< bit offset of WP0_SADDR/WP1_SADDR in FMC_WP0/FMC_WP1 */ +#define WP_EADDR_OFFSET (16U) /*!< bit offset of WP0_EADDR/WP1_EADDR in FMC_WP0/FMC_WP1 */ + +#define MAIN_FLASH_BASE_ADDRESS ((uint32_t)0x08000000U) /*!< main flash base address */ +#define MAIN_FLASH_SIZE ((uint32_t)0x00010000U) /*!< main flash size */ +#define MAIN_FLASH_PAGE_SIZE ((uint32_t)0x00000400U) /*!< main flash sub page size */ +#define MAIN_FLASH_PAGE_TOTAL_NUM ((uint32_t)0x00000040U) /*!< main flash page total number */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0xFFFFFFFFU) /*!< count to judge FMC timeout */ +#define DOUBLEWORD_CNT_IN_ROW ((uint8_t)8U) +#define DCRP_AREA_SUBPAGE_SIZE ((uint32_t)0x00000200U) /*!< DCRP area subpage size */ +#define DCRP_AREA_SUBPAGE_MAX_INDEX ((MAIN_FLASH_SIZE / DCRP_AREA_SUBPAGE_SIZE) - 1U)/*!< DCRP area subpage max index */ +#define WP_AREA_SUBPAGE_SIZE ((uint32_t)0x00000400U) /*!< write protection area subpage size */ + +#define INVLD_RETURN_VALUE ((uint32_t)0x00000000U) /*!< the return value is invalid */ +#define VLD_RETURN_VALUE ((uint32_t)0x00000001U) /*!< the return value is valid */ + +/* DCRP area definition */ +#define DCRP_AREA_0 ((uint32_t)0x00000000U) /*!< DCRP area 0 */ +#define DCRP_AREA_1 ((uint32_t)0x00000001U) /*!< DCRP area 1 */ +/* write protection area definition */ +#define WP_AREA_0 ((uint32_t)0x00000000U) /*!< write protection area 0 */ +#define WP_AREA_1 ((uint32_t)0x00000001U) /*!< write protection area 1 */ + +/* fmc state */ +typedef enum { + FMC_READY = 0, /*!< the operation has been completed */ + FMC_BUSY, /*!< the operation is in progress */ + FMC_OBERR, /*!< option byte read error */ + FMC_RPERR, /*!< read protection error */ + FMC_FSTPERR, /*!< fast programming error */ + FMC_PGSERR, /*!< program sequence error */ + FMC_PGMERR, /*!< program size error*/ + FMC_PGAERR, /*!< program alignment error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_PGERR, /*!< program error */ + FMC_OPRERR, /*!< operation error */ + FMC_TOERR, /*!< timeout error */ + FMC_OB_HSPC, /*!< high security protection */ + FMC_UNDEFINEDERR /*!< undefined error for function input parameter checking */ +} fmc_state_enum; + +/* user data extract infomation */ +typedef enum { + OBCTL_USER_DATA_BORST_EN = FMC_OBCTL_BORST_EN | 8U, /*!< brown out reset enable mask and it's start bit position */ + OBCTL_USER_DATA_BORR_TH = FMC_OBCTL_BORR_TH | 9U, /*!< BOR threshold at rising VDD supply mask and it's start bit position */ + OBCTL_USER_DATA_BORF_TH = FMC_OBCTL_BORF_TH | 11U, /*!< BOR threshold at falling VDD supply mask and it's start bit position */ + OBCTL_USER_DATA_NRST_STDBY = FMC_OBCTL_NRST_STDBY | 14U, /*!< option byte standby reset value bit mask and it's start bit position */ + OBCTL_USER_DATA_HXTAL_REMAP = FMC_OBCTL_HXTAL_REMAP | 21U, /*!< HXTAL remapping bit mask and it's start bit position */ + OBCTL_USER_DATA_SRAM_ECC_EN = FMC_OBCTL_SRAM_ECC_EN | 22U, /*!< SRAM ECC enable bit mask and it's start bit position */ + OBCTL_USER_DATA_NRST_DPSLP = FMC_OBCTL_NRST_DPSLP | 13U, /*!< option byte deepsleep reset value bit mask and it's start bit position */ + OBCTL_USER_DATA_NFWDG_HW = FMC_OBCTL_NFWDG_HW | 16U, /*!< free watchdog configuration bit mask and it's start bit position */ + OBCTL_USER_DATA_NWWDG_HW = FMC_OBCTL_NWWDG_HW | 19U, /*!< window watchdog configuration bit mask and it's start bit position */ + OBCTL_USER_DATA_SWBT0 = FMC_OBCTL_SWBT0 | 24U, /*!< software BOOT0 bit mask and it's start bit position */ + OBCTL_USER_DATA_NBOOT1 = FMC_OBCTL_NBOOT1 | 25U, /*!< NBOOT1 option bit mask and it's start bit position */ + OBCTL_USER_DATA_NBOOT0 = FMC_OBCTL_NBOOT0 | 26U, /*!< NBOOT0 option bit mask and it's start bit position */ + OBCTL_USER_DATA_NRST_MDSEL = FMC_OBCTL_NRST_MDSEL | 27U /*!< NRST pin mode bit mask and it's start bit position */ +} ob_user_data_extract_info_enum; + +/* parameter check definitions */ +#ifdef FW_DEBUG_ERR_REPORT +/* check FMC empty check status */ +#define NOT_FMC_EMPTY_CHECK_STATUS(empty_check_status) ((empty_check_status) & (~FMC_WS_MFPE)) + +/* check FMC wait state configuration */ +#define NOT_FMC_WAIT_STATE(wscnt) ((wscnt) > FMC_WAIT_STATE_1) + +/* check FMC option byte USER mask */ +#define NOT_FMC_OB_USER_MASK(ob_user_mask) ((ob_user_mask) & ~(FMC_OBCTL_BORST_EN | FMC_OBCTL_BORR_TH | FMC_OBCTL_BORF_TH | FMC_OBCTL_NRST_DPSLP | \ + FMC_OBCTL_NRST_STDBY | FMC_OBCTL_NFWDG_HW | FMC_OBCTL_NWWDG_HW | FMC_OBCTL_HXTAL_REMAP | \ + FMC_OBCTL_SRAM_ECC_EN | FMC_OBCTL_SWBT0 | FMC_OBCTL_NBOOT1 | FMC_OBCTL_NBOOT0 | \ + FMC_OBCTL_NRST_MDSEL )) + +/* check FMC DCRP area configuration */ +#define NOT_FMC_DCRP_AREA_VALID_CFG(dcrp_area,dcrp_eren,dcrp_start,dcrp_end) ((((dcrp_area) != DCRP_AREA_0) && ((dcrp_area) != DCRP_AREA_1)) || \ + (0U != ((dcrp_eren) & (~FMC_DCRP_EADDR0_DCRP_EREN))) || \ + ((dcrp_start) > DCRP_AREA_SUBPAGE_MAX_INDEX) || \ + ((dcrp_end) > DCRP_AREA_SUBPAGE_MAX_INDEX) || \ + ((dcrp_end) < (dcrp_start))) + +/* check FMC WP area configuration */ +#define NOT_FMC_WP_AREA_VALID_CFG(wp_area,wp_start,wp_end) ((((wp_area) != WP_AREA_0) && ((wp_area) != WP_AREA_1)) || \ + ((wp_start) > (MAIN_FLASH_PAGE_TOTAL_NUM - 1U)) || \ + ((wp_end) > (MAIN_FLASH_PAGE_TOTAL_NUM - 1U)) || \ + ((wp_end) < (wp_start))) + +/* check FMC data flash page number */ +#define NOT_FMC_VALID_DATA_FLASH_PAGE(page_num) ((page_num) > (DATA_FLASH_PAGE_TOTAL_NUM - 1U)) +#endif + +/* function declarations */ +/* FMC main flash operation functions */ +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(void); +/* get the main flash empty check status */ +FlagStatus fmc_main_flash_empty_stat_get(void); +/* modify the main flash empty check status */ +void fmc_main_flash_empty_stat_modify(uint32_t empty_check_status); +/* set the wait state */ +void fmc_wscnt_set(uint32_t wscnt); +/* enable pre-fetch */ +void fmc_prefetch_enable(void); +/* disable pre-fetch */ +void fmc_prefetch_disable(void); +/* enable IBUS cache */ +void fmc_icache_enable(void); +/* disable IBUS cache */ +void fmc_icache_disable(void); +/* reset IBUS cache */ +void fmc_icache_reset(void); +/* erase page */ +fmc_state_enum fmc_page_erase(uint32_t page_number); +/* erase whole chip */ +fmc_state_enum fmc_mass_erase(void); +/* program a doubleword at the given address in main flash */ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data); +/* fast program a row at the corresponding address */ +fmc_state_enum fmc_fast_program(uint32_t address, uint32_t data_buf); +/* enable debugger */ +void fmc_debugger_enable(void); +/* disable debugger */ +void fmc_debugger_disable(void); +/* enable secure area protection */ +void fmc_scr_area_enable(void); + +/* FMC option bytes operation functions */ +/* unlock the option bytes operation */ +void ob_unlock(void); +/* lock the option bytes operation */ +void ob_lock(void); +/* reload the option bytes operation */ +void ob_reload(void); +/* program the option bytes USER */ +fmc_state_enum ob_user_write(uint32_t ob_user, uint32_t ob_user_mask); +/* configure security protection level*/ +fmc_state_enum ob_security_protection_level_config(uint8_t ob_spc); +/* configure the option bytes DCRP area */ +fmc_state_enum ob_dcrp_area_config(uint32_t dcrp_area, uint32_t dcrp_eren, uint32_t dcrp_start, + uint32_t dcrp_end); +/* configure the option bytes write protection area */ +fmc_state_enum ob_write_protection_area_config(uint32_t wp_area, uint32_t wp_start, + uint32_t wp_end); +/* configure the option bytes secure area */ +fmc_state_enum ob_scr_area_config(uint32_t secure_size); +/* configure the option bytes boot lock */ +fmc_state_enum ob_boot_lock_config(uint32_t boot_config); +/* get the value of option bytes USER */ +uint32_t ob_user_get(ob_user_data_extract_info_enum user_data_extract_info, uint8_t * ob_user_data); +/* get the value of option bytes security protection level in FMC_OBCTL register */ +uint8_t ob_security_protection_level_get(void); +/* get configuration of DCRP area*/ +uint32_t ob_dcrp_area_get(uint32_t dcrp_area, uint32_t *dcrp_erase_option, + uint32_t *dcrp_start, uint32_t *dcrp_end); +/* get address of write protection area */ +uint32_t ob_write_protection_area_get(uint32_t wp_area, uint32_t *wp_start, + uint32_t *wp_end); +/* get size of secure area */ +uint32_t ob_scr_area_get(uint32_t *scr_area_byte_cnt); +/* get boot lock configuration */ +uint32_t ob_boot_lock_get(void); + +/* FMC interrupts and flags management functions */ +/* get FMC flag status */ +FlagStatus fmc_flag_get(uint32_t flag); +/* clear the FMC flag */ +void fmc_flag_clear(uint32_t flag); +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t interrupt); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t interrupt); +/* get FMC interrupt flag */ +FlagStatus fmc_interrupt_flag_get(uint32_t flag); +/* clear FMC interrupt flag */ +void fmc_interrupt_flag_clear(uint32_t flag); +/* get the FMC state*/ +fmc_state_enum fmc_state_get(void); +/* check whether FMC is ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t timeout); + +#endif /* GD32C2X1_FMC_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_fwdgt.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_fwdgt.h new file mode 100644 index 0000000..d9027a1 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_fwdgt.h @@ -0,0 +1,123 @@ +/*! + \file gd32c2x1_fwdgt.h + \brief definitions for the FWDGT + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_FWDGT_H +#define GD32C2X1_FWDGT_H + +#include "gd32c2x1.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00000000U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x00000004U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x00000008U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0000000CU) /*!< FWDGT status register */ +#define FWDGT_WND REG32((FWDGT) + 0x00000010U) /*!< FWDGT window register */ + +/* bits definitions */ +/* FWDGT_CTL */ +#define FWDGT_CTL_CMD BITS(0,15) /*!< FWDGT command value */ + +/* FWDGT_PSC */ +#define FWDGT_PSC_PSC BITS(0,2) /*!< FWDGT prescaler divider value */ + +/* FWDGT_RLD */ +#define FWDGT_RLD_RLD BITS(0,11) /*!< FWDGT counter reload value */ + +/* FWDGT_STAT */ +#define FWDGT_STAT_PUD BIT(0) /*!< FWDGT prescaler divider value update */ +#define FWDGT_STAT_RUD BIT(1) /*!< FWDGT counter reload value update */ +#define FWDGT_STAT_WUD BIT(2) /*!< FWDGT counter window value update */ + +/* FWDGT_WND */ +#define FWDGT_WND_WND BITS(0,11) /*!< FWDGT counter window value */ + +/* constants definitions */ +/* FWDGT_PSC register value */ +#define PSC_PSC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define FWDGT_PSC_DIV4 ((uint8_t)PSC_PSC(0)) /*!< FWDGT prescaler set to 4 */ +#define FWDGT_PSC_DIV8 ((uint8_t)PSC_PSC(1)) /*!< FWDGT prescaler set to 8 */ +#define FWDGT_PSC_DIV16 ((uint8_t)PSC_PSC(2)) /*!< FWDGT prescaler set to 16 */ +#define FWDGT_PSC_DIV32 ((uint8_t)PSC_PSC(3)) /*!< FWDGT prescaler set to 32 */ +#define FWDGT_PSC_DIV64 ((uint8_t)PSC_PSC(4)) /*!< FWDGT prescaler set to 64 */ +#define FWDGT_PSC_DIV128 ((uint8_t)PSC_PSC(5)) /*!< FWDGT prescaler set to 128 */ +#define FWDGT_PSC_DIV256 ((uint8_t)PSC_PSC(6)) /*!< FWDGT prescaler set to 256 */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x5555U) /*!< FWDGT_CTL bits write access enable value */ +#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x0000U) /*!< FWDGT_CTL bits write access disable value */ +#define FWDGT_KEY_RELOAD ((uint16_t)0xAAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */ +#define FWDGT_KEY_ENABLE ((uint16_t)0xCCCCU) /*!< FWDGT_CTL bits fwdgt counter enable value */ + +/* FWDGT timeout value */ +#define FWDGT_WND_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_WND register write operation state flag timeout */ +#define FWDGT_PSC_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_PSC register write operation state flag timeout */ +#define FWDGT_RLD_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_RLD register write operation state flag timeout */ + +/* FWDGT flag definitions */ +#define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< a write operation to FWDGT_PSC register is on going */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< a write operation to FWDGT_RLD register is on going */ +#define FWDGT_FLAG_WUD FWDGT_STAT_WUD /*!< a write operation to FWDGT_WND register is on going */ + +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) +/* write value to FWDGT_WND_WND bit field */ +#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) + +/* function declarations */ +/* enable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_enable(void); +/* disable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_disable(void); +/* start the FWDGT counter */ +void fwdgt_enable(void); + +/* configure the FWDGT counter prescaler value */ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value); +/* configure the FWDGT counter reload value */ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value); +/* configure the FWDGT counter window value */ +ErrStatus fwdgt_window_value_config(uint16_t window_value); +/* reload the counter of FWDGT */ +void fwdgt_counter_reload(void); +/* configure counter reload value, and prescaler divider value */ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div); + +/* get flag state of FWDGT */ +FlagStatus fwdgt_flag_get(uint16_t flag); + +#endif /* gd32c2x1_FWDGT_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_gpio.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_gpio.h new file mode 100644 index 0000000..cc841e1 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_gpio.h @@ -0,0 +1,393 @@ +/*! + \file gd32c2x1_gpio.h + \brief definitions for the GPIO + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_GPIO_H +#define GD32C2X1_GPIO_H + +#include "gd32c2x1.h" + +/* GPIOx(x=A,B,C,D,F) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) /*!< GPIOA base address */ +#define GPIOB (GPIO_BASE + 0x00000400U) /*!< GPIOB base address */ +#define GPIOC (GPIO_BASE + 0x00000800U) /*!< GPIOC base address */ +#define GPIOD (GPIO_BASE + 0x00000C00U) /*!< GPIOD base address */ +#define GPIOF (GPIO_BASE + 0x00001400U) /*!< GPIOF base address */ + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00000000U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x00000004U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x00000008U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0000000CU) /*!< GPIO port pull-up/pull-down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x00000010U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x00000014U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x00000018U) /*!< GPIO port bit operation register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x0000001CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x00000020U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x00000024U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x00000028U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x0000002CU) /*!< GPIO port bit toggle register */ + +/* 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 BIT(0) /*!< pin 0 output max speed bit */ +#define GPIO_OSPD_OSPD1 BIT(1) /*!< pin 1 output max speed bit */ +#define GPIO_OSPD_OSPD2 BIT(2) /*!< pin 2 output max speed bit */ +#define GPIO_OSPD_OSPD3 BIT(3) /*!< pin 3 output max speed bit */ +#define GPIO_OSPD_OSPD4 BIT(4) /*!< pin 4 output max speed bit */ +#define GPIO_OSPD_OSPD5 BIT(5) /*!< pin 5 output max speed bit */ +#define GPIO_OSPD_OSPD6 BIT(6) /*!< pin 6 output max speed bit */ +#define GPIO_OSPD_OSPD7 BIT(7) /*!< pin 7 output max speed bit */ +#define GPIO_OSPD_OSPD8 BIT(8) /*!< pin 8 output max speed bit */ +#define GPIO_OSPD_OSPD9 BIT(9) /*!< pin 9 output max speed bit */ +#define GPIO_OSPD_OSPD10 BIT(10) /*!< pin 10 output max speed bit */ +#define GPIO_OSPD_OSPD11 BIT(11) /*!< pin 11 output max speed bit */ +#define GPIO_OSPD_OSPD12 BIT(12) /*!< pin 12 output max speed bit */ +#define GPIO_OSPD_OSPD13 BIT(13) /*!< pin 13 output max speed bit */ +#define GPIO_OSPD_OSPD14 BIT(14) /*!< pin 14 output max speed bit */ +#define GPIO_OSPD_OSPD15 BIT(15) /*!< pin 15 output max speed bit */ + +/* 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) << (n))) +#define GPIO_OSPEED_MASK(n) (0x1U << (n)) + +/* GPIO output type */ +#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */ + +/* GPIO output max speed value */ +#define GPIO_OSPEED_LEVEL_0 ((uint32_t)0x00000000U) /*!< output speed level 0 */ +#define GPIO_OSPEED_LEVEL_1 ((uint32_t)0x00000001U) /*!< output speed level 1 */ + +/* 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 /* gd32c2x1_GPIO_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_i2c.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_i2c.h new file mode 100644 index 0000000..e9ef703 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_i2c.h @@ -0,0 +1,403 @@ +/*! + \file gd32c2x1_i2c.h + \brief definitions for the I2C + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_I2C_H +#define GD32C2X1_I2C_H + +#include "gd32c2x1.h" + +/* I2Cx(x=0,1) definitions */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE + 0x00000400U) /*!< I2C1 base address */ + +/* registers definitions */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00000000U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x00000004U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x00000008U) /*!< I2C slave address register 0*/ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0000000CU) /*!< I2C slave address register 1*/ +#define I2C_TIMING(i2cx) REG32((i2cx) + 0x00000010U) /*!< I2C timing register */ +#define I2C_TIMEOUT(i2cx) REG32((i2cx) + 0x00000014U) /*!< I2C timeout register */ +#define I2C_STAT(i2cx) REG32((i2cx) + 0x00000018U) /*!< I2C status register */ +#define I2C_STATC(i2cx) REG32((i2cx) + 0x0000001CU) /*!< I2C status clear register */ +#define I2C_PEC(i2cx) REG32((i2cx) + 0x00000020U) /*!< I2C PEC register */ +#define I2C_RDATA(i2cx) REG32((i2cx) + 0x00000024U) /*!< I2C receive data register */ +#define I2C_TDATA(i2cx) REG32((i2cx) + 0x00000028U) /*!< I2C transmit data register */ +#define I2C_CTL2(i2cx) REG32((i2cx) + 0x00000090U) /*!< I2C control register 2 */ + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< I2C peripheral enable */ +#define I2C_CTL0_TIE BIT(1) /*!< transmit interrupt enable */ +#define I2C_CTL0_RBNEIE BIT(2) /*!< receive interrupt enable */ +#define I2C_CTL0_ADDMIE BIT(3) /*!< address match interrupt enable in slave mode */ +#define I2C_CTL0_NACKIE BIT(4) /*!< not acknowledge received interrupt enable */ +#define I2C_CTL0_STPDETIE BIT(5) /*!< stop detection interrupt enable */ +#define I2C_CTL0_TCIE BIT(6) /*!< transfer complete interrupt enable */ +#define I2C_CTL0_ERRIE BIT(7) /*!< error interrupt enable */ +#define I2C_CTL0_DNF BITS(8,11) /*!< digital noise filter */ +#define I2C_CTL0_ANOFF BIT(12) /*!< analog noise filter */ +#define I2C_CTL0_DENT BIT(14) /*!< DMA enable for transmission */ +#define I2C_CTL0_DENR BIT(15) /*!< DMA enable for reception */ +#define I2C_CTL0_SBCTL BIT(16) /*!< slave byte control */ +#define I2C_CTL0_SS BIT(17) /*!< whether to stretch SCL low when data is not ready in slave mode */ +#define I2C_CTL0_WUEN BIT(18) /*!< wakeup from deep-sleep mode enable */ +#define I2C_CTL0_GCEN BIT(19) /*!< whether or not to response to a general call (0x00) */ +#define I2C_CTL0_SMBHAEN BIT(20) /*!< SMBus host address enable */ +#define I2C_CTL0_SMBDAEN BIT(21) /*!< SMBus device default address enable */ +#define I2C_CTL0_SMBALTEN BIT(22) /*!< SMBus alert enable */ +#define I2C_CTL0_PECEN BIT(23) /*!< PEC calculation switch */ + +/* I2Cx_CTL1 */ +#define I2C_CTL1_SADDRESS BITS(0,9) /*!< received slave address */ +#define I2C_CTL1_TRDIR BIT(10) /*!< transfer direction in master mode */ +#define I2C_CTL1_ADD10EN BIT(11) /*!< 10-bit addressing mode enable in master mode */ +#define I2C_CTL1_HEAD10R BIT(12) /*!< 10-bit address header executes read direction only in master receive mode */ +#define I2C_CTL1_START BIT(13) /*!< generate a START condition on I2C bus */ +#define I2C_CTL1_STOP BIT(14) /*!< generate a STOP condition on I2C bus */ +#define I2C_CTL1_NACKEN BIT(15) /*!< generate NACK in slave mode */ +#define I2C_CTL1_BYTENUM BITS(16,23) /*!< number of bytes to be transferred */ +#define I2C_CTL1_RELOAD BIT(24) /*!< reload mode enable */ +#define I2C_CTL1_AUTOEND BIT(25) /*!< automatic end mode in master mode */ +#define I2C_CTL1_PECTRANS BIT(26) /*!< PEC transfer */ + +/* I2Cx_SADDR0 */ +#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ +#define I2C_SADDR0_ADDFORMAT BIT(10) /*!< address mode for the I2C slave */ +#define I2C_SADDR0_ADDRESSEN BIT(15) /*!< I2C address enable */ + +/* I2Cx_SADDR1 */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave */ +#define I2C_SADDR1_ADDMSK2 BITS(8,10) /*!< ADDRESS2[7:1] mask */ +#define I2C_SADDR1_ADDRESS2EN BIT(15) /*!< second I2C address enable */ + +/* I2Cx_TIMING */ +#define I2C_TIMING_SCLL BITS(0,7) /*!< SCL low period */ +#define I2C_TIMING_SCLH BITS(8,15) /*!< SCL high period */ +#define I2C_TIMING_SDADELY BITS(16,19) /*!< data hold time */ +#define I2C_TIMING_SCLDELY BITS(20,23) /*!< data setup time */ +#define I2C_TIMING_PSC BITS(28,31) /*!< timing prescaler */ + +/* I2Cx_TIMEOUT */ +#define I2C_TIMEOUT_BUSTOA BITS(0,11) /*!< bus timeout A */ +#define I2C_TIMEOUT_TOIDLE BIT(12) /*!< idle clock timeout detection */ +#define I2C_TIMEOUT_TOEN BIT(15) /*!< clock timeout detection enable */ +#define I2C_TIMEOUT_BUSTOB BITS(16,27) /*!< bus timeout B */ +#define I2C_TIMEOUT_EXTOEN BIT(31) /*!< extended clock timeout detection enable */ + +/* I2Cx_STAT */ +#define I2C_STAT_TBE BIT(0) /*!< I2C_TDATA is empty during transmitting */ +#define I2C_STAT_TI BIT(1) /*!< transmit interrupt */ +#define I2C_STAT_RBNE BIT(2) /*!< I2C_RDATA is not empty during receiving */ +#define I2C_STAT_ADDSEND BIT(3) /*!< address received matches in slave mode */ +#define I2C_STAT_NACK BIT(4) /*!< not acknowledge flag */ +#define I2C_STAT_STPDET BIT(5) /*!< STOP condition detected in slave mode */ +#define I2C_STAT_TC BIT(6) /*!< transfer complete in master mode */ +#define I2C_STAT_TCR BIT(7) /*!< transfer complete reload */ +#define I2C_STAT_BERR BIT(8) /*!< bus error */ +#define I2C_STAT_LOSTARB BIT(9) /*!< arbitration lost */ +#define I2C_STAT_OUERR BIT(10) /*!< overrun/underrun error in slave mode */ +#define I2C_STAT_PECERR BIT(11) /*!< PEC error */ +#define I2C_STAT_TIMEOUT BIT(12) /*!< timeout flag */ +#define I2C_STAT_SMBALT BIT(13) /*!< SMBus alert */ +#define I2C_STAT_I2CBSY BIT(15) /*!< busy flag */ +#define I2C_STAT_TR BIT(16) /*!< whether the I2C is a transmitter or a receiver in slave mode */ +#define I2C_STAT_READDR BITS(17,23) /*!< received match address in slave mode */ + +/* I2Cx_STATC */ +#define I2C_STATC_ADDSENDC BIT(3) /*!< ADDSEND flag clear */ +#define I2C_STATC_NACKC BIT(4) /*!< not acknowledge flag clear */ +#define I2C_STATC_STPDETC BIT(5) /*!< STPDET flag clear */ +#define I2C_STATC_BERRC BIT(8) /*!< bus error flag clear */ +#define I2C_STATC_LOSTARBC BIT(9) /*!< arbitration Lost flag clear */ +#define I2C_STATC_OUERRC BIT(10) /*!< overrun/underrun flag clear */ +#define I2C_STATC_PECERRC BIT(11) /*!< PEC error flag clear */ +#define I2C_STATC_TIMEOUTC BIT(12) /*!< TIMEOUT flag clear */ +#define I2C_STATC_SMBALTC BIT(13) /*!< SMBus alert flag clear */ + +/* I2Cx_PEC */ +#define I2C_PEC_PECV BITS(0,7) /*!< Packet Error Checking Value that calculated by hardware when PEC is enabled */ + +/* I2Cx_RDATA */ +#define I2C_RDATA_RDATA BITS(0,7) /*!< receive data value */ + +/* I2Cx_TDATA */ +#define I2C_TDATA_TDATA BITS(0,7) /*!< transmit data value */ + +/* I2Cx_CTL2 */ +#define I2C_CTL2_ADDM BITS(9,15) /*!< address bit compare select */ + +/* constants definitions */ +/* define the I2C bit position and its register index offset */ +#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22))) +#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define I2C_CTL0_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define I2C_STAT_REG_OFFSET ((uint32_t)0x00000018U) /*!< STAT register offset */ + +/* I2C interrupt flags */ +typedef enum { + I2C_INT_FLAG_TI = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 1U, I2C_STAT_REG_OFFSET, 1U), /*!< transmit interrupt flag */ + I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 2U, I2C_STAT_REG_OFFSET, 2U), /*!< I2C_RDATA is not empty during receiving interrupt flag */ + I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 3U, I2C_STAT_REG_OFFSET, 3U), /*!< address received matches in slave mode interrupt flag */ + I2C_INT_FLAG_NACK = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 4U, I2C_STAT_REG_OFFSET, 4U), /*!< not acknowledge interrupt flag */ + I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 5U, I2C_STAT_REG_OFFSET, 5U), /*!< stop condition detected in slave mode interrupt flag */ + I2C_INT_FLAG_TC = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 6U, I2C_STAT_REG_OFFSET, 6U), /*!< transfer complete in master mode interrupt flag */ + I2C_INT_FLAG_TCR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 6U, I2C_STAT_REG_OFFSET, 7U), /*!< transfer complete reload interrupt flag */ + I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 8U), /*!< bus error interrupt flag */ + I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 9U), /*!< arbitration lost interrupt flag */ + I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 10U), /*!< overrun/underrun error in slave mode interrupt flag */ + I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 11U), /*!< PEC error interrupt flag */ + I2C_INT_FLAG_TIMEOUT = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 12U), /*!< timeout interrupt flag */ + I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 13U) /*!< SMBus Alert interrupt flag */ +} i2c_interrupt_flag_enum; + +/* I2C DMA constants definitions */ +#define I2C_DMA_TRANSMIT ((uint32_t)0x00000000U) /*!< I2C transmit data use DMA */ +#define I2C_DMA_RECEIVE ((uint32_t)0x00000001U) /*!< I2C receive data use DMA */ + +/* I2C transfer direction in master mode */ +#define I2C_MASTER_TRANSMIT ((uint32_t)0x00000000U) /*!< I2C master transmit */ +#define I2C_MASTER_RECEIVE I2C_CTL1_TRDIR /*!< I2C master receive */ + +/* address mode for the I2C slave */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address format: 7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address format: 10 bits */ + +/* the length of filter spikes */ +#define FILTER_DISABLE ((uint32_t)0x00000000U) /*!< digital filter is disabled */ +#define FILTER_LENGTH_1 ((uint32_t)0x00000001U) /*!< digital filter is enabled and filter spikes with a length of up to 1 tI2CCLK */ +#define FILTER_LENGTH_2 ((uint32_t)0x00000002U) /*!< digital filter is enabled and filter spikes with a length of up to 2 tI2CCLK */ +#define FILTER_LENGTH_3 ((uint32_t)0x00000003U) /*!< digital filter is enabled and filter spikes with a length of up to 3 tI2CCLK */ +#define FILTER_LENGTH_4 ((uint32_t)0x00000004U) /*!< digital filter is enabled and filter spikes with a length of up to 4 tI2CCLK */ +#define FILTER_LENGTH_5 ((uint32_t)0x00000005U) /*!< digital filter is enabled and filter spikes with a length of up to 5 tI2CCLK */ +#define FILTER_LENGTH_6 ((uint32_t)0x00000006U) /*!< digital filter is enabled and filter spikes with a length of up to 6 tI2CCLK */ +#define FILTER_LENGTH_7 ((uint32_t)0x00000007U) /*!< digital filter is enabled and filter spikes with a length of up to 7 tI2CCLK */ +#define FILTER_LENGTH_8 ((uint32_t)0x00000008U) /*!< digital filter is enabled and filter spikes with a length of up to 8 tI2CCLK */ +#define FILTER_LENGTH_9 ((uint32_t)0x00000009U) /*!< digital filter is enabled and filter spikes with a length of up to 9 tI2CCLK */ +#define FILTER_LENGTH_10 ((uint32_t)0x0000000AU) /*!< digital filter is enabled and filter spikes with a length of up to 10 tI2CCLK */ +#define FILTER_LENGTH_11 ((uint32_t)0x0000000BU) /*!< digital filter is enabled and filter spikes with a length of up to 11 tI2CCLK */ +#define FILTER_LENGTH_12 ((uint32_t)0x0000000CU) /*!< digital filter is enabled and filter spikes with a length of up to 12 tI2CCLK */ +#define FILTER_LENGTH_13 ((uint32_t)0x0000000DU) /*!< digital filter is enabled and filter spikes with a length of up to 13 tI2CCLK */ +#define FILTER_LENGTH_14 ((uint32_t)0x0000000EU) /*!< digital filter is enabled and filter spikes with a length of up to 14 tI2CCLK */ +#define FILTER_LENGTH_15 ((uint32_t)0x0000000FU) /*!< digital filter is enabled and filter spikes with a length of up to 15 tI2CCLK */ + +/* defines which bits of register ADDRESS[7:1] are compared with an incoming address byte */ +#define ADDRESS_BIT1_COMPARE ((uint32_t)0x00000001U) /*!< address bit1 needs compare */ +#define ADDRESS_BIT2_COMPARE ((uint32_t)0x00000002U) /*!< address bit2 needs compare */ +#define ADDRESS_BIT3_COMPARE ((uint32_t)0x00000004U) /*!< address bit3 needs compare */ +#define ADDRESS_BIT4_COMPARE ((uint32_t)0x00000008U) /*!< address bit4 needs compare */ +#define ADDRESS_BIT5_COMPARE ((uint32_t)0x00000010U) /*!< address bit5 needs compare */ +#define ADDRESS_BIT6_COMPARE ((uint32_t)0x00000020U) /*!< address bit6 needs compare */ +#define ADDRESS_BIT7_COMPARE ((uint32_t)0x00000040U) /*!< address bit7 needs compare */ + +/* defines which bits of ADDRESS2[7:1] are compared with an incoming address byte, and which bits are masked (do not care) */ +#define ADDRESS2_NO_MASK ((uint32_t)0x00000000U) /*!< no mask, all the bits must be compared */ +#define ADDRESS2_MASK_BIT1 ((uint32_t)0x00000001U) /*!< ADDRESS2[1] is masked, only ADDRESS2[7:2] are compared */ +#define ADDRESS2_MASK_BIT1_2 ((uint32_t)0x00000002U) /*!< ADDRESS2[2:1] is masked, only ADDRESS2[7:3] are compared */ +#define ADDRESS2_MASK_BIT1_3 ((uint32_t)0x00000003U) /*!< ADDRESS2[3:1] is masked, only ADDRESS2[7:4] are compared */ +#define ADDRESS2_MASK_BIT1_4 ((uint32_t)0x00000004U) /*!< ADDRESS2[4:1] is masked, only ADDRESS2[7:5] are compared */ +#define ADDRESS2_MASK_BIT1_5 ((uint32_t)0x00000005U) /*!< ADDRESS2[5:1] is masked, only ADDRESS2[7:6] are compared */ +#define ADDRESS2_MASK_BIT1_6 ((uint32_t)0x00000006U) /*!< ADDRESS2[6:1] is masked, only ADDRESS2[7] are compared */ +#define ADDRESS2_MASK_ALL ((uint32_t)0x00000007U) /*!< all the ADDRESS2[7:1] bits are masked */ + +/* idle clock timeout detection */ +#define BUSTOA_DETECT_SCL_LOW ((uint32_t)0x00000000U) /*!< BUSTOA is used to detect SCL low timeout */ +#define BUSTOA_DETECT_IDLE I2C_TIMEOUT_TOIDLE /*!< BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle */ + +/* I2C flag definitions */ +#define I2C_FLAG_TBE I2C_STAT_TBE /*!< I2C_TDATA is empty during transmitting */ +#define I2C_FLAG_TI I2C_STAT_TI /*!< transmit interrupt */ +#define I2C_FLAG_RBNE I2C_STAT_RBNE /*!< I2C_RDATA is not empty during receiving */ +#define I2C_FLAG_ADDSEND I2C_STAT_ADDSEND /*!< address received matches in slave mode */ +#define I2C_FLAG_NACK I2C_STAT_NACK /*!< not acknowledge flag */ +#define I2C_FLAG_STPDET I2C_STAT_STPDET /*!< STOP condition detected in slave mode */ +#define I2C_FLAG_TC I2C_STAT_TC /*!< transfer complete in master mode */ +#define I2C_FLAG_TCR I2C_STAT_TCR /*!< transfer complete reload */ +#define I2C_FLAG_BERR I2C_STAT_BERR /*!< bus error */ +#define I2C_FLAG_LOSTARB I2C_STAT_LOSTARB /*!< arbitration lost */ +#define I2C_FLAG_OUERR I2C_STAT_OUERR /*!< overrun/underrun error in slave mode */ +#define I2C_FLAG_PECERR I2C_STAT_PECERR /*!< PEC error */ +#define I2C_FLAG_TIMEOUT I2C_STAT_TIMEOUT /*!< timeout flag */ +#define I2C_FLAG_SMBALT I2C_STAT_SMBALT /*!< SMBus alert */ +#define I2C_FLAG_I2CBSY I2C_STAT_I2CBSY /*!< busy flag */ +#define I2C_FLAG_TR I2C_STAT_TR /*!< whether the I2C is a transmitter or a receiver in slave mode */ + +/* I2C interrupt enable or disable */ +#define I2C_INT_ERR I2C_CTL0_ERRIE /*!< error interrupt enable */ +#define I2C_INT_TC I2C_CTL0_TCIE /*!< transfer complete interrupt enable */ +#define I2C_INT_STPDET I2C_CTL0_STPDETIE /*!< stop detection interrupt enable */ +#define I2C_INT_NACK I2C_CTL0_NACKIE /*!< not acknowledge received interrupt enable */ +#define I2C_INT_ADDM I2C_CTL0_ADDMIE /*!< address match interrupt enable */ +#define I2C_INT_RBNE I2C_CTL0_RBNEIE /*!< receive interrupt enable */ +#define I2C_INT_TI I2C_CTL0_TIE /*!< transmit interrupt enable */ + +/* function declarations */ +/* initialization functions */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure the timing parameters */ +void i2c_timing_config(uint32_t i2c_periph, uint32_t psc, uint32_t scl_dely, uint32_t sda_dely); +/* configure digital noise filter */ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, uint32_t filter_length); +/* enable analog noise filter */ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph); +/* disable analog noise filter */ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph); +/* configure the SCL high and low period of clock in master mode */ +void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll); +/* configure I2C slave address and transfer direction in master mode */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction); + +/* application function declarations */ +/* 10-bit address header executes read direction only in master receive mode */ +void i2c_address10_header_enable(uint32_t i2c_periph); +/* 10-bit address header executes complete sequence in master receive mode */ +void i2c_address10_header_disable(uint32_t i2c_periph); +/* enable 10-bit addressing mode in master mode */ +void i2c_address10_enable(uint32_t i2c_periph); +/* disable 10-bit addressing mode in master mode */ +void i2c_address10_disable(uint32_t i2c_periph); +/* enable I2C automatic end mode in master mode */ +void i2c_automatic_end_enable(uint32_t i2c_periph); +/* disable I2C automatic end mode in master mode */ +void i2c_automatic_end_disable(uint32_t i2c_periph); +/* enable the response to a general call */ +void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph); +/* disable the response to a general call */ +void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph); +/* enable to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_enable(uint32_t i2c_periph); +/* disable to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_disable(uint32_t i2c_periph); +/* configure I2C slave address */ +void i2c_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_format); +/* define which bits of ADDRESS[7:1] need to compare with the incoming address byte */ +void i2c_address_bit_compare_config(uint32_t i2c_periph, uint32_t compare_bits); +/* disable I2C address in slave mode */ +void i2c_address_disable(uint32_t i2c_periph); +/* configure I2C second slave address */ +void i2c_second_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_mask); +/* disable I2C second address in slave mode */ +void i2c_second_address_disable(uint32_t i2c_periph); +/* get received match address in slave mode */ +uint32_t i2c_received_address_get(uint32_t i2c_periph); +/* enable slave byte control */ +void i2c_slave_byte_control_enable(uint32_t i2c_periph); +/* disable slave byte control */ +void i2c_slave_byte_control_disable(uint32_t i2c_periph); +/* generate a NACK in slave mode */ +void i2c_nack_enable(uint32_t i2c_periph); +/* enable wakeup from deep-sleep mode */ +void i2c_wakeup_from_deepsleep_enable(uint32_t i2c_periph); +/* disable wakeup from deep-sleep mode */ +void i2c_wakeup_from_deepsleep_disable(uint32_t i2c_periph); +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); +/* I2C receive data */ +uint8_t i2c_data_receive(uint32_t i2c_periph); +/* enable I2C reload mode */ +void i2c_reload_enable(uint32_t i2c_periph); +/* disable I2C reload mode */ +void i2c_reload_disable(uint32_t i2c_periph); +/* configure number of bytes to be transferred */ +void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint8_t byte_number); +/* enable I2C DMA for transmission or reception */ +void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma); +/* disable I2C DMA for transmission or reception */ +void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma); +/* I2C transfers PEC value */ +void i2c_pec_transfer(uint32_t i2c_periph); +/* enable I2C PEC calculation */ +void i2c_pec_enable(uint32_t i2c_periph); +/* disable I2C PEC calculation */ +void i2c_pec_disable(uint32_t i2c_periph); +/* get packet error checking value */ +uint32_t i2c_pec_value_get(uint32_t i2c_periph); +/* enable SMBus alert */ +void i2c_smbus_alert_enable(uint32_t i2c_periph); +/* disable SMBus alert */ +void i2c_smbus_alert_disable(uint32_t i2c_periph); +/* enable SMBus device default address */ +void i2c_smbus_default_addr_enable(uint32_t i2c_periph); +/* disable SMBus device default address */ +void i2c_smbus_default_addr_disable(uint32_t i2c_periph); +/* enable SMBus host address */ +void i2c_smbus_host_addr_enable(uint32_t i2c_periph); +/* disable SMBus host address */ +void i2c_smbus_host_addr_disable(uint32_t i2c_periph); +/* enable extended clock timeout detection */ +void i2c_extended_clock_timeout_enable(uint32_t i2c_periph); +/* disable extended clock timeout detection */ +void i2c_extended_clock_timeout_disable(uint32_t i2c_periph); +/* enable clock timeout detection */ +void i2c_clock_timeout_enable(uint32_t i2c_periph); +/* disable clock timeout detection */ +void i2c_clock_timeout_disable(uint32_t i2c_periph); +/* configure bus timeout B */ +void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout); +/* configure bus timeout A */ +void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout); +/* configure idle clock timeout detection */ +void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout); + +/* interrupt & flag functions */ +/* get I2C flag status */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag); +/* clear I2C flag status */ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t interrupt); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t interrupt); +/* get I2C interrupt flag status */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); +/* clear I2C interrupt flag status */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); + +#endif /* gd32c2x1_I2C_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_libopt.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_libopt.h new file mode 100644 index 0000000..e3b0d86 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_libopt.h @@ -0,0 +1,59 @@ +/*! + \file gd32c2x1_libopt.h + \brief library optional for gd32c2x1 + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_LIBOPT_H +#define GD32C2X1_LIBOPT_H + +#include "gd32c2x1_adc.h" +#include "gd32c2x1_cmp.h" +#include "gd32c2x1_crc.h" +#include "gd32c2x1_dbg.h" +#include "gd32c2x1_dma.h" +#include "gd32c2x1_exti.h" +#include "gd32c2x1_fmc.h" +#include "gd32c2x1_fwdgt.h" +#include "gd32c2x1_gpio.h" +#include "gd32c2x1_i2c.h" +#include "gd32c2x1_misc.h" +#include "gd32c2x1_pmu.h" +#include "gd32c2x1_rcu.h" +#include "gd32c2x1_rtc.h" +#include "gd32c2x1_spi.h" +#include "gd32c2x1_syscfg.h" +#include "gd32c2x1_timer.h" +#include "gd32c2x1_usart.h" +#include "gd32c2x1_wwdgt.h" +#include "gd32c2x1_err_report.h" + +#endif /* gd32c2x1_LIBOPT_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_misc.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_misc.h new file mode 100644 index 0000000..6ced1e4 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_misc.h @@ -0,0 +1,82 @@ +/*! + \file gd32c2x1_misc.h + \brief definitions for the MISC + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_MISC_H +#define GD32C2X1_MISC_H + +#include "gd32c2x1.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) /*!< NVIC vector table offset mask */ + +/* 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) /*!< NVIC VECTKEY mask */ + +/* choose the method to enter or exit the low power 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 /*!< low power mode by exiting from ISR */ +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP /*!< DEEPSLEEP mode or SLEEP mode */ +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND /*!< wakeup by all interrupt */ + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_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 */ +/* enable NVIC request */ +void nvic_irq_enable(IRQn_Type nvic_irq, uint8_t nvic_irq_priority); +/* disable NVIC request */ +void nvic_irq_disable(IRQn_Type nvic_irq); +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); +/* initiates a system reset request to reset the MCU */ +void nvic_system_reset(void); + +/* 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 /* gd32c2x1_MISC_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_pmu.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_pmu.h new file mode 100644 index 0000000..de1258f --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_pmu.h @@ -0,0 +1,155 @@ +/*! + \file gd32c2x1_pmu.h + \brief definitions for the PMU + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_PMU_H +#define GD32C2X1_PMU_H + +#include "gd32c2x1.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL0 REG32(PMU + 0x00000000U) /*!< PMU control register 0 */ +#define PMU_CS REG32(PMU + 0x00000004U) /*!< PMU control and status register */ +#define PMU_CTL1 REG32(PMU + 0x00000008U) /*!< PMU control register 1 */ +#define PMU_STAT REG32(PMU + 0x0000000CU) /*!< PMU status register */ +#define PMU_PAR REG32(PMU + 0x00000010U) /*!< PMU parameter register */ + +/* bits definitions */ +/* PMU_CTL0 */ +#define PMU_CTL0_LPMOD BITS(0,1) /*!< select the low-power mode to enter */ +#define PMU_CTL0_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL0_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL0_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL0_DSMODVS BITS(12,13) /*!< Deep-sleep mode voltage selection */ +#define PMU_CTL0_LPLDOEN BIT(18) /*!< Low power LDO enable */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_WUPEN0 BIT(8) /*!< wakeup pin0 enable */ +#define PMU_CS_WUPEN1 BIT(9) /*!< wakeup pin1 enable */ +#define PMU_CS_WUPEN2 BIT(10) /*!< wakeup pin2 enable */ +#define PMU_CS_WUPEN3 BIT(11) /*!< wakeup pin3 enable */ +#define PMU_CS_WUPEN5 BIT(13) /*!< wakeup pin5 enable */ +#define PMU_CS_LDOVSRF BIT(14) /*!< LDO voltage select ready flag */ +#define PMU_CS_NPRDY BIT(16) /*!< NPLDO ready flag */ + +/* PMU_CTL1 */ +#define PMU_CTL1_EFPSLEEP BIT(4) /*!< eflash domain power-off when enter run/run1 */ +#define PMU_CTL1_EFDSPSLEEP BIT(5) /*!< eflash domain power-off when enter deepsleep/deepsleep1 */ + +/* PMU_STAT */ +#define PMU_STAT_EFLASHPS_SLEEP BIT(4) /*!< EFLASH domain is power-off */ +#define PMU_STAT_EFLASHPS_ACTIVE BIT(5) /*!< EFLASH domain is in active state */ + +/* PMU_PAR */ +#define PMU_PAR_TSW_IRC48MCNT BITS(16,20) /*!< wait the IRC48M COUNTER and then set Deep-sleep signal */ +#define PMU_PAR_TWK_EFLASH BITS(21,28) /*!< EFLASH wake up from Deep-sleep/Deep-sleep1 state counter */ + +/* constants definitions */ +/* select the low-power mode to enter */ +#define CTL0_LPMOD(regval) (BITS(0,1)&((uint32_t)(regval)<<0)) +#define PMU_DEEPSLEEP CTL0_LPMOD(0) /*!< Deep-sleep mode */ +#define PMU_DEEPSLEEP1 CTL0_LPMOD(1) /*!< Deep-sleep mode 1 */ +#define PMU_STANDBY CTL0_LPMOD(3) /*!< standby mode */ + +/* select the deep-sleep voltage */ +#define CTL0_DSMODVS(regval) (BITS(12,13)&((uint32_t)(regval)<<12)) +#define PMU_DSV_0 CTL0_DSMODVS(0) /*!< 0.9V */ +#define PMU_DSV_1 CTL0_DSMODVS(1) /*!< 1.0V */ +#define PMU_DSV_2 CTL0_DSMODVS(2) /*!< 1.1V */ +#define PMU_DSV_3 CTL0_DSMODVS(3) /*!< 1.2V */ + +/* PMU wakeup pin definitions */ +#define PMU_WAKEUP_PIN0 PMU_CS_WUPEN0 /*!< WKUP Pin 0 (PA0) */ +#define PMU_WAKEUP_PIN1 PMU_CS_WUPEN1 /*!< WKUP Pin 1 (PC13/PA4) */ +#define PMU_WAKEUP_PIN2 PMU_CS_WUPEN2 /*!< WKUP Pin 2 (PB6) */ +#define PMU_WAKEUP_PIN3 PMU_CS_WUPEN3 /*!< WKUP Pin 3 (PA2) */ +#define PMU_WAKEUP_PIN5 PMU_CS_WUPEN5 /*!< WKUP Pin 5 (PB5) */ + +/* 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_LDOVSRF PMU_CS_LDOVSRF /*!< LDO voltage select ready flag */ +#define PMU_FLAG_NPRDY PMU_CS_NPRDY /*!< normal-power LDO ready flag */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ + +/* function declarations */ +/* reset PMU registers */ +void pmu_deinit(void); +/* select deepsleep mode voltage */ +void pmu_deepsleep_voltage_select(uint32_t dsv_n); +/* enable low power LDO */ +void pmu_low_power_ldo_enable(void); +/* disable low power LDO */ +void pmu_low_power_ldo_disable(void); +/* PMU work in Sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work in Deep-sleep mode */ +void pmu_to_deepsleepmode(uint8_t deepsleepmodecmd, uint8_t deepsleepmode); +/* PMU work in standby mode */ +void pmu_to_standbymode(void); +/* enable PMU wakeup pin */ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin); +/* disable PMU wakeup pin */ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin); + +/* backup related functions */ +/* enable write access to the backup registers in RTC */ +void pmu_backup_write_enable(void); +/* disable write access to the backup registers in RTC */ +void pmu_backup_write_disable(void); + +/* configure power state of eflash domain in run/run1 mode */ +void pmu_eflash_run_power_config(ControlStatus state); +/* configure power state of eflash domain when enter deepsleep/deepsleep1 */ +void pmu_eflash_deepsleep_power_config(ControlStatus state); + +/* configure eflash wakeup time, using IRC48M counter */ +void pmu_eflash_wakeup_time_config(uint32_t wakeup_time); +/* configure IRC48M counter before enter Deepsleep/Deepsleep1 mode */ +void pmu_deepsleep_wait_time_config(uint32_t wait_time); + +/* flag functions */ +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag); + +#endif /* GD32C2X1_PMU_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_rcu.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_rcu.h new file mode 100644 index 0000000..ace9922 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_rcu.h @@ -0,0 +1,716 @@ +/*! + \file gd32c2x1_rcu.h + \brief definitions for the RCU + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_RCU_H +#define GD32C2X1_RCU_H + +#include "gd32c2x1.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL0 REG32(RCU + 0x00000000U) /*!< control 0 register */ +#define RCU_CFG0 REG32(RCU + 0x00000008U) /*!< configuration register 0 */ +#define RCU_INT REG32(RCU + 0x0000000CU) /*!< interrupt register */ +#define RCU_AHB1RST REG32(RCU + 0x00000010U) /*!< AHB1 reset register */ +#define RCU_AHB2RST REG32(RCU + 0x00000014U) /*!< AHB1 reset register */ +#define RCU_APBRST REG32(RCU + 0x00000024U) /*!< APB reset register */ +#define RCU_AHB1EN REG32(RCU + 0x00000030U) /*!< AHB1 enable register */ +#define RCU_AHB2EN REG32(RCU + 0x00000034U) /*!< AHB2 enable register */ +#define RCU_APBEN REG32(RCU + 0x00000044U) /*!< APB enable register */ +#define RCU_AHB1SPDPEN REG32(RCU + 0x00000050U) /*!< AHB1 sleep and deep sleep mode enable register */ +#define RCU_AHB2SPDPEN REG32(RCU + 0x00000054U) /*!< AHB2 sleep and deep sleep mode enable register */ +#define RCU_APBSPDPEN REG32(RCU + 0x00000064U) /*!< APB sleep and deep sleep mode enable register */ +#define RCU_CTL1 REG32(RCU + 0x00000070U) /*!< control 1 register */ +#define RCU_RSTSCK REG32(RCU + 0x00000074U) /*!< reset source /clock register */ +#define RCU_CFG1 REG32(RCU + 0x0000008CU) /*!< configuration register 1 */ + +/* bits definitions */ +/* RCU_CTL0 */ +#define RCU_CTL0_IRC48MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL0_IRC48MSTB BIT(1) /*!< IRC48M high speed internal oscillator stabilization flag */ +#define RCU_CTL0_IRC48MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL0_IRC48MCALIB BITS(8,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL0_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL0_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL0_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL0_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL0_IRC48MDIV_PER BITS(25,27) /*!< IRC48M clock divider factor for peripheral clock */ +#define RCU_CTL0_IRC48M_PEREN BIT(28) /*!< IRC48M always-enable for peripheral */ +#define RCU_CTL0_IRC48MDIV_SYS BITS(29,31) /*!< IRC48M clock divider factor for system 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_APBPSC BITS(11,13) /*!< APB prescaler selection */ +#define RCU_CFG0_CKOUT1SEL BITS(16,18) /*!< CK_OUT1 clock source selection */ +#define RCU_CFG0_CKOUT1DIV BITS(20,22) /*!< CK_OUT1 divider which the CK_OUT frequency can be reduced */ +#define RCU_CFG0_CKOUT0SEL BITS(24,26) /*!< CK_OUT0 clock source selection */ +#define RCU_CFG0_CKOUT0DIV BITS(28,30) /*!< CK_OUT0 divider which the CK_OUT frequency can be reduced */ + +/* 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_IRC48MSTBIF BIT(2) /*!< IRC48MM stabilization interrupt flag */ +#define RCU_INT_LCKMIF BIT(6) /*!< LXTAL 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_IRC48MSTBIE BIT(10) /*!< IRC48M 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_IRC48MSTBIC BIT(18) /*!< IRC48M stabilization interrupt clear */ +#define RCU_INT_LCKMIC BIT(22) /*!< LXTAL clock stuck interrupt clear */ +#define RCU_INT_HXTALSTBIF BIT(3) /*!< HXTAL stabilization interrupt flag */ +#define RCU_INT_CKMIF BIT(7) /*!< HXTAL clock stuck interrupt flag */ +#define RCU_INT_HXTALSTBIE BIT(11) /*!< HXTAL stabilization interrupt enable */ +#define RCU_INT_HXTALSTBIC BIT(19) /*!< HXTAL stabilization interrupt clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL clock stuck interrupt clear */ + +/* RCU_AHB1RST */ +#define RCU_AHB1RST_CRCRST BIT(12) /*!< CRC */ +#define RCU_AHB1RST_DMARST BIT(21) /*!< DMA reset */ +#define RCU_AHB1RST_DMAMUXRST BIT(23) /*!< DMAMUX reset */ + +/* RCU_AHB2RST */ +#define RCU_AHB2RST_PARST BIT(17) /*!< PA reset */ +#define RCU_AHB2RST_PBRST BIT(18) /*!< PB reset */ +#define RCU_AHB2RST_PCRST BIT(19) /*!< PC reset */ +#define RCU_AHB2RST_PDRST BIT(20) /*!< PD reset */ +#define RCU_AHB2RST_PFRST BIT(22) /*!< PF reset */ + +/* RCU_APBRST */ +#define RCU_APBRST_SYSCFGRST BIT(0) /*!< system configuration reset */ +#define RCU_APBRST_CMPRST BIT(1) /*!< comparator reset */ +#define RCU_APBRST_WWDGTRST BIT(8) /*!< comparator reset */ +#define RCU_APBRST_ADCRST BIT(9) /*!< ADC reset */ +#define RCU_APBRST_TIMER0RST BIT(10) /*!< TIMER0 reset */ +#define RCU_APBRST_TIMER2RST BIT(11) /*!< TIMER2 reset */ +#define RCU_APBRST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APBRST_SPI1RST BIT(13) /*!< SPI1 reset */ +#define RCU_APBRST_USART0RST BIT(14) /*!< USART0 reset */ +#define RCU_APBRST_USART1RST BIT(15) /*!< USART1 reset */ +#define RCU_APBRST_TIMER13RST BIT(16) /*!< TIMER13 reset */ +#define RCU_APBRST_TIMER15RST BIT(17) /*!< TIMER15 reset */ +#define RCU_APBRST_TIMER16RST BIT(18) /*!< TIMER16 reset */ +#define RCU_APBRST_USART2RST BIT(19) /*!< USART2 reset */ +#define RCU_APBRST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APBRST_I2C1RST BIT(22) /*!< I2C1 reset */ +#define RCU_APBRST_PMURST BIT(28) /*!< PMU reset */ + +/* RCU_AHB1EN */ +#define RCU_AHB1EN_FMCEN BIT(4) /*!< FMC enable */ +#define RCU_AHB1EN_CRCEN BIT(12) /*!< CRC enable*/ +#define RCU_AHB1EN_DMAEN BIT(21) /*!< DMA enable */ +#define RCU_AHB1EN_DMAMUXEN BIT(23) /*!< DMAMUX enable */ + +/* RCU_AHB2EN */ +#define RCU_AHB2EN_PAEN BIT(17) /*!< PA enable */ +#define RCU_AHB2EN_PBEN BIT(18) /*!< PB enable */ +#define RCU_AHB2EN_PCEN BIT(19) /*!< PC enable */ +#define RCU_AHB2EN_PDEN BIT(20) /*!< PD enable */ +#define RCU_AHB2EN_PFEN BIT(22) /*!< PF enable */ + +/* RCU_APBEN */ +#define RCU_APBEN_SYSCFGEN BIT(0) /*!< system configuration enable */ +#define RCU_APBEN_CMPEN BIT(1) /*!< comparator enable */ +#define RCU_APBEN_WWDGTEN BIT(8) /*!< comparator enable */ +#define RCU_APBEN_ADCEN BIT(9) /*!< ADC enable */ +#define RCU_APBEN_TIMER0EN BIT(10) /*!< TIMER0 enable */ +#define RCU_APBEN_TIMER2EN BIT(11) /*!< TIMER2 enable */ +#define RCU_APBEN_SPI0EN BIT(12) /*!< SPI0 enable */ +#define RCU_APBEN_SPI1EN BIT(13) /*!< SPI0 enable */ +#define RCU_APBEN_USART0EN BIT(14) /*!< USART0 enable */ +#define RCU_APBEN_USART1EN BIT(15) /*!< USART1 enable */ +#define RCU_APBEN_TIMER13EN BIT(16) /*!< TIMER13 enable */ +#define RCU_APBEN_TIMER15EN BIT(17) /*!< TIMER15 enable */ +#define RCU_APBEN_TIMER16EN BIT(18) /*!< TIMER16 enable */ +#define RCU_APBEN_USART2EN BIT(19) /*!< USART2 enable */ +#define RCU_APBEN_I2C0EN BIT(21) /*!< I2C0 enable */ +#define RCU_APBEN_I2C1EN BIT(22) /*!< I2C1 enable */ +#define RCU_APBEN_DBGEN BIT(27) /*!< DBG enable */ +#define RCU_APBEN_PMUEN BIT(28) /*!< PMU enable */ + +/* RCU_AHB1SPDPEN */ +#define RCU_AHB1SPDPEN_SRAMEN BIT(2) /*!< SRAM enable */ +#define RCU_AHB1SPDPEN_FMCEN BIT(4) /*!< FMC enable */ +#define RCU_AHB1SPDPEN_CRCEN BIT(12) /*!< CRC enable*/ +#define RCU_AHB1SPDPEN_DMAEN BIT(21) /*!< DMA enable */ +#define RCU_AHB1SPDPEN_DMAMUXEN BIT(23) /*!< DMAMUX enable */ + +/* RCU_AHB2SPDPEN */ +#define RCU_AHB2SPDPEN_PAEN BIT(17) /*!< PA enable */ +#define RCU_AHB2SPDPEN_PBEN BIT(18) /*!< PB enable */ +#define RCU_AHB2SPDPEN_PCEN BIT(19) /*!< PC enable */ +#define RCU_AHB2SPDPEN_PDEN BIT(20) /*!< PD enable */ +#define RCU_AHB2SPDPEN_PFEN BIT(22) /*!< PF enable */ + +/* RCU_APBSPDPEN */ +#define RCU_APBSPDPEN_SYSCFGEN BIT(0) /*!< system configuration enable */ +#define RCU_APBSPDPEN_CMPEN BIT(1) /*!< comparator enable */ +#define RCU_APBSPDPEN_WWDGTEN BIT(8) /*!< comparator enable */ +#define RCU_APBSPDPEN_ADCEN BIT(9) /*!< ADC enable */ +#define RCU_APBSPDPEN_TIMER0EN BIT(10) /*!< TIMER0 enable */ +#define RCU_APBSPDPEN_TIMER2EN BIT(11) /*!< TIMER2 enable */ +#define RCU_APBSPDPEN_SPI0EN BIT(12) /*!< SPI0 enable */ +#define RCU_APBSPDPEN_SPI1EN BIT(13) /*!< SPI1 enable */ +#define RCU_APBSPDPEN_USART0EN BIT(14) /*!< USART0 enable */ +#define RCU_APBSPDPEN_USART1EN BIT(15) /*!< USART1 enable */ +#define RCU_APBSPDPEN_TIMER13EN BIT(16) /*!< TIMER13 enable */ +#define RCU_APBSPDPEN_TIMER15EN BIT(17) /*!< TIMER15 enable */ +#define RCU_APBSPDPEN_TIMER16EN BIT(18) /*!< TIMER16 enable */ +#define RCU_APBSPDPEN_USART2EN BIT(19) /*!< USART2 enable */ +#define RCU_APBSPDPEN_I2C0EN BIT(21) /*!< I2C0 enable */ +#define RCU_APBSPDPEN_I2C1EN BIT(22) /*!< I2C1 enable */ +#define RCU_APBSPDPEN_PMUEN BIT(28) /*!< PMU enable */ + +/* RCU_CTL1 */ +#define RCU_CTL1_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_CTL1_LXTALSTB BIT(1) /*!< external low-speed oscillator stabilization */ +#define RCU_CTL1_LXTALBPS BIT(2) /*!< LXTAL bypass mode enable */ +#define RCU_CTL1_LXTALDRI BIT(3) /*!< LXTAL drive capability */ +#define RCU_CTL1_LCKMEN BIT(5) /*!< LXTAL clock monitor enable */ +#define RCU_CTL1_LCKMD BIT(6) /*!< LXTAL clock failure detection */ +#define RCU_CTL1_LXTALSTBRST BIT(7) /*!< external low-speed oscillator stabilization reset*/ +#define RCU_CTL1_RTCSRC BITS(8,9) /*!< RTC clock entry selection */ +#define RCU_CTL1_RTCEN BIT(15) /*!< RTC clock enable */ +#define RCU_CTL1_BKPRST BIT(16) /*!< backup domain reset */ +#define RCU_CTL1_LSCKOUTEN BIT(24) /*!< Low speed clock output enable */ +#define RCU_CTL1_LSCKOUTSEL BIT(25) /*!< Low speed clock output selection */ + +/* RCU_RSTSCK */ +#define RCU_RSTSCK_IRC32KEN BIT(0) /*!< IRC32K enable */ +#define RCU_RSTSCK_IRC32KSTB BIT(1) /*!< IRC32K stabilization */ +#define RCU_RSTSCK_OBLRSTF BIT(23) /*!< option byte loader reset flag */ +#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */ +#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_CFG1 */ +#define RCU_CFG1_USART0SEL BITS(0,1) /*!< CK_USART0 clock source selection */ +#define RCU_CFG1_I2C0SEL BITS(2,3) /*!< CK_I2C0 clock source selection */ +#define RCU_CFG1_I2C1SEL BITS(4,5) /*!< CK_I2C1 clock source selection */ +#define RCU_CFG1_ADCSEL BITS(7,8) /*!< CK_ADC clock source selection */ +#define RCU_CFG1_ADCPSC BITS(9,12) /*!< ADC clock prescaler selection */ +#define RCU_CFG1_I2SSEL BITS(14,15) /*!< I2S clock source selection */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx)<<6) | (uint32_t)(bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph)>>6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register index */ +/* peripherals enable */ +#define AHB1EN_REG_OFFSET 0x30U /*!< AHB1 enable register offset */ +#define AHB2EN_REG_OFFSET 0x34U /*!< AHB2 enable register offset */ +#define APBEN_REG_OFFSET 0x44U /*!< APB enable register offset */ + +/* peripherals reset */ +#define AHB1RST_REG_OFFSET 0x10U /*!< AHB1 reset register offset */ +#define AHB2RST_REG_OFFSET 0x14U /*!< AHB2 reset register offset */ +#define APBRST_REG_OFFSET 0x24U /*!< APB reset register offset */ + +/* peripherals sleep mode and deepsleep mode enable */ +#define AHB1SPDPEN_REG_OFFSET 0x50U /*!< AHB1 reset register offset */ +#define AHB2SPDPEN_REG_OFFSET 0x54U /*!< AHB2 reset register offset */ +#define APBSPDPEN_REG_OFFSET 0x64U /*!< APB reset register offset */ + +/* reset source and clock */ +#define RSTSCK_REG_OFFSET 0x74U /*!< reset source/clock register offset */ + +/* clock control */ +#define CTL0_REG_OFFSET 0x00U /*!< control register 0 offset */ +#define CTL1_REG_OFFSET 0x70U /*!< control register 1 offset */ + +/* clock stabilization and stuck interrupt */ +#define INT_REG_OFFSET 0x0CU /*!< clock interrupt register offset */ + +/* configuration register */ +#define CFG0_REG_OFFSET 0x08U /*!< clock configuration register 0 offset */ +#define CFG1_REG_OFFSET 0x8CU /*!< clock configuration register 1 offset */ + +/* peripheral clock enable */ +typedef enum { + /* AHB1 peripherals */ + RCU_FMC = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 4U), /*!< FMC clock */ + RCU_CRC = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 12U), /*!< CRC clock */ + RCU_DMA = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 21U), /*!< DMA clock */ + RCU_DMAMUX = RCU_REGIDX_BIT(AHB1EN_REG_OFFSET, 23U), /*!< DMAMUX clock */ + + /* AHB2 peripherals */ + RCU_GPIOA = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 17U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 18U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 19U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 20U), /*!< GPIOD clock */ + RCU_GPIOF = RCU_REGIDX_BIT(AHB2EN_REG_OFFSET, 22U), /*!< GPIOF clock */ + + /* APB peripherals */ + RCU_SYSCFG = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 0U), /*!< SYSCFG clock */ + RCU_CMP = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 1U), /*!< CMP clock */ + RCU_WWDGT = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 8U), /*!< WWDGT clock */ + RCU_ADC = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 9U), /*!< ADC clock */ + RCU_TIMER0 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 10U), /*!< TIMER0 clock */ + RCU_TIMER2 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 11U), /*!< TIMER2 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI1 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 13U), /*!< SPI1 clock */ + RCU_USART0 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 14U), /*!< USART0 clock */ + RCU_USART1 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 15U), /*!< USART1 clock */ + RCU_TIMER13 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 16U), /*!< TIMER13 clock */ + RCU_TIMER15 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 17U), /*!< TIMER15 clock */ + RCU_TIMER16 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 18U), /*!< TIMER16 clock */ + RCU_USART2 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 19U), /*!< USART2 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_DBGMCU = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 27U), /*!< DBGMCU clock */ + RCU_PMU = RCU_REGIDX_BIT(APBEN_REG_OFFSET, 28U), /*!< PMU clock */ + + /* control register 1(RCU_CTL1) */ + RCU_RTC = RCU_REGIDX_BIT(CTL1_REG_OFFSET, 15U) /*!< RTC clock */ +} rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum { + /* AHB1 peripherals */ + RCU_SRAM_SLP = RCU_REGIDX_BIT(AHB1SPDPEN_REG_OFFSET, 2U), /*!< SRAM clock */ + RCU_FMC_SLP = RCU_REGIDX_BIT(AHB1SPDPEN_REG_OFFSET, 4U), /*!< FMC clock */ + RCU_CRC_SLP = RCU_REGIDX_BIT(AHB1SPDPEN_REG_OFFSET, 12U), /*!< CRC clock */ + RCU_DMA_SLP = RCU_REGIDX_BIT(AHB1SPDPEN_REG_OFFSET, 21U), /*!< DMA clock */ + RCU_DMAMUX_SLP = RCU_REGIDX_BIT(AHB1SPDPEN_REG_OFFSET, 23U), /*!< DMAMUX clock */ + + /* AHB2 peripherals */ + RCU_GPIOA_SLP = RCU_REGIDX_BIT(AHB2SPDPEN_REG_OFFSET, 17U), /*!< GPIOA clock */ + RCU_GPIOB_SLP = RCU_REGIDX_BIT(AHB2SPDPEN_REG_OFFSET, 18U), /*!< GPIOB clock */ + RCU_GPIOC_SLP = RCU_REGIDX_BIT(AHB2SPDPEN_REG_OFFSET, 19U), /*!< GPIOC clock */ + RCU_GPIOD_SLP = RCU_REGIDX_BIT(AHB2SPDPEN_REG_OFFSET, 20U), /*!< GPIOD clock */ + RCU_GPIOF_SLP = RCU_REGIDX_BIT(AHB2SPDPEN_REG_OFFSET, 22U), /*!< GPIOF clock */ + + /* APB peripherals */ + RCU_SYSCFG_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 0U), /*!< SYSCFG clock */ + RCU_CMP_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 1U), /*!< CMP clock */ + RCU_WWDGT_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 8U), /*!< WWDGT clock */ + RCU_ADC_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 9U), /*!< ADC clock */ + RCU_TIMER0_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 10U), /*!< TIMER0 clock */ + RCU_TIMER2_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 11U), /*!< TIMER2 clock */ + RCU_SPI0_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI1_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 13U), /*!< SPI1 clock */ + RCU_USART0_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 14U), /*!< USART0 clock */ + RCU_USART1_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 15U), /*!< USART1 clock */ + RCU_TIMER13_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 16U), /*!< TIMER13 clock */ + RCU_TIMER15_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 17U), /*!< TIMER15 clock */ + RCU_TIMER16_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 18U), /*!< TIMER16 clock */ + RCU_USART2_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 19U), /*!< USART2 clock */ + RCU_I2C0_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_PMU_SLP = RCU_REGIDX_BIT(APBSPDPEN_REG_OFFSET, 28U), /*!< PMU clock */ +} rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum { + /* AHB1 peripherals */ + RCU_CRCRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 12U), /*!< CRC clock */ + RCU_DMARST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 21U), /*!< DMA clock */ + RCU_DMAMUXRST = RCU_REGIDX_BIT(AHB1RST_REG_OFFSET, 23U), /*!< DMA clock */ + + /* AHB2 peripherals */ + RCU_GPIOARST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 17U), /*!< GPIOA clock */ + RCU_GPIOBRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 18U), /*!< GPIOB clock */ + RCU_GPIOCRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 19U), /*!< GPIOC clock */ + RCU_GPIODRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 20U), /*!< GPIOD clock */ + RCU_GPIOFRST = RCU_REGIDX_BIT(AHB2RST_REG_OFFSET, 22U), /*!< GPIOF clock */ + + /* APB peripherals */ + RCU_SYSCFGRST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 0U), /*!< SYSCFG clock */ + RCU_CMPRST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 1U), /*!< CMP clock */ + RCU_WWDGTRST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 8U), /*!< WWDGT clock */ + RCU_ADCRST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 9U), /*!< ADC clock */ + RCU_TIMER0RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 10U), /*!< TIMER0 clock */ + RCU_TIMER2RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 11U), /*!< TIMER2 clock */ + RCU_SPI0RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_SPI1RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 13U), /*!< SPI1 clock */ + RCU_USART0RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 14U), /*!< USART0 clock */ + RCU_USART1RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 15U), /*!< USART1 clock */ + RCU_TIMER13RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 16U), /*!< TIMER13 clock */ + RCU_TIMER15RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 17U), /*!< TIMER15 clock */ + RCU_TIMER16RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 18U), /*!< TIMER16 clock */ + RCU_USART2RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 19U), /*!< USART2 clock */ + RCU_I2C0RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1RST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_PMURST = RCU_REGIDX_BIT(APBRST_REG_OFFSET, 28U), /*!< PMU clock */ +} rcu_periph_reset_enum; + +/* clock stabilization, peripheral reset and clock dection flags */ +typedef enum { + /* clock stabilization flags */ + RCU_FLAG_IRC32KSTB = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 1U), /*!< IRC32K stabilization flag */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(CTL1_REG_OFFSET, 1U), /*!< LXTAL stabilization flag */ + RCU_FLAG_IRC48MSTB = RCU_REGIDX_BIT(CTL0_REG_OFFSET, 1U), /*!< IRC48M stabilization flag */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(CTL0_REG_OFFSET, 17U), /*!< HXTAL stabilization flag */ + + /* reset source flags */ + RCU_FLAG_OBLRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 23U), /*!< option byte loader reset flag */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 26U), /*!< External PIN reset flag */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 27U), /*!< power reset flag */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 28U), /*!< SW reset flag */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 29U), /*!< FWDGT reset flag */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 30U), /*!< WWDGT reset flag */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 31U), /*!< low-power reset flag */ + /* clock failure flag */ + RCU_FLAG_LCKCMD = RCU_REGIDX_BIT(CTL1_REG_OFFSET, 6U) /*!< LXTAL clock failure detection flag */ +} 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_IRC48MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 2U), /*!< IRC48M stabilization interrupt flag */ + RCU_INT_FLAG_LXTALCKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U), /*!< LXTAL clock stuck interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 7U), /*!< CKM 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_IRC48MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U), /*!< IRC48M stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALCKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U), /*!< LXTAL clock stuck interrupt flag clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 19U), /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 23U), /*!< CKM interrupt flags 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_IRC48MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 10U), /*!< IRC48M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 11U), /*!< HXTAL stabilization interrupt */ +} rcu_int_enum; + +/* oscillator types */ +typedef enum { + RCU_HXTAL = RCU_REGIDX_BIT(CTL0_REG_OFFSET, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(CTL1_REG_OFFSET, 0U), /*!< LXTAL */ + RCU_IRC48M = RCU_REGIDX_BIT(CTL0_REG_OFFSET, 0U), /*!< IRC48M */ + RCU_IRC32K = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U), /*!< IRC32K */ +} rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum { + CK_SYS = 0U, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB, /*!< APB clock */ + CK_ADC, /*!< ADC clock */ + CK_USART0, /*!< USART0 clock */ + CK_I2C0, /*!< I2C0 clock */ + CK_I2C1, /*!< I2C1 clock */ + CK_I2C2, /*!< I2C2 clock */ + CK_USART1, /*!< USART1 clock */ +} rcu_clock_freq_enum; + +typedef enum { + IDX_USART0 = 0U, /*!< index of USART0 */ + IDX_USART1 /*!< index of USART1 */ +} usart_idx_enum; + +typedef enum { + IDX_I2C0 = 0U, /*!< index of I2C0 */ + IDX_I2C1, /*!< index of I2C1 */ +} i2c_idx_enum; + +/* IRC48MDIV_SYS clock source selection */ +#define CTL_IRC48MDIV_SYS_SEL(regval) (BITS(29,31) & ((uint32_t)(regval) << 29U)) +#define RCU_IRC48MDIV_SYS_1 CTL_IRC48MDIV_SYS_SEL(0) /*!< CK_IRC48MDIV_SYS select CK_IRC48M */ +#define RCU_IRC48MDIV_SYS_2 CTL_IRC48MDIV_SYS_SEL(1) /*!< CK_IRC48MDIV_SYS select CK_IRC48M divided by 2 */ +#define RCU_IRC48MDIV_SYS_4 CTL_IRC48MDIV_SYS_SEL(2) /*!< CK_IRC48MDIV_SYS select CK_IRC48M divided by 4 */ +#define RCU_IRC48MDIV_SYS_8 CTL_IRC48MDIV_SYS_SEL(3) /*!< CK_IRC48MDIV_SYS select CK_IRC48M divided by 8 */ +#define RCU_IRC48MDIV_SYS_16 CTL_IRC48MDIV_SYS_SEL(4) /*!< CK_IRC48MDIV_SYS select CK_IRC48M divided by 16 */ +#define RCU_IRC48MDIV_SYS_32 CTL_IRC48MDIV_SYS_SEL(5) /*!< CK_IRC48MDIV_SYS select CK_IRC48M divided by 32 */ +#define RCU_IRC48MDIV_SYS_64 CTL_IRC48MDIV_SYS_SEL(6) /*!< CK_IRC48MDIV_SYS select CK_IRC48M divided by 64 */ +#define RCU_IRC48MDIV_SYS_128 CTL_IRC48MDIV_SYS_SEL(7) /*!< CK_IRC48MDIV_SYS select CK_IRC48M divided by 128 */ + +/* IRC48MDIV_PER clock source selection */ +#define CTL_IRC48MDIV_PER_SEL(regval) (BITS(25,27) & ((uint32_t)(regval) << 25U)) +#define RCU_IRC48MDIV_PER_1 CTL_IRC48MDIV_PER_SEL(0) /*!< CK_IRC48MDIV_PER select CK_IRC48M */ +#define RCU_IRC48MDIV_PER_2 CTL_IRC48MDIV_PER_SEL(1) /*!< CK_IRC48MDIV_PER select CK_IRC48M divided by 2 */ +#define RCU_IRC48MDIV_PER_3 CTL_IRC48MDIV_PER_SEL(2) /*!< CK_IRC48MDIV_PER select CK_IRC48M divided by 3 */ +#define RCU_IRC48MDIV_PER_4 CTL_IRC48MDIV_PER_SEL(3) /*!< CK_IRC48MDIV_PER select CK_IRC48M divided by 4 */ +#define RCU_IRC48MDIV_PER_5 CTL_IRC48MDIV_PER_SEL(4) /*!< CK_IRC48MDIV_PER select CK_IRC48M divided by 5 */ +#define RCU_IRC48MDIV_PER_6 CTL_IRC48MDIV_PER_SEL(5) /*!< CK_IRC48MDIV_PER select CK_IRC48M divided by 6 */ +#define RCU_IRC48MDIV_PER_7 CTL_IRC48MDIV_PER_SEL(6) /*!< CK_IRC48MDIV_PER select CK_IRC48M divided by 7 */ +#define RCU_IRC48MDIV_PER_8 CTL_IRC48MDIV_PER_SEL(7) /*!< CK_IRC48MDIV_PER select CK_IRC48M divided by 8 */ + +/* system clock source select */ +#define CFG0_SCS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define RCU_CKSYSSRC_IRC48MDIV_SYS CFG0_SCS(0) /*!< system clock source select CK_IRC48MDIV_SYS */ +#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */ +#define RCU_CKSYSSRC_IRC32K CFG0_SCS(2) /*!< system clock source select IRC32K */ +#define RCU_CKSYSSRC_LXTAL CFG0_SCS(3) /*!< system clock source select LXTAL */ + +/* system clock source select status */ +#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) +#define RCU_SCSS_IRC48MDIV CFG0_SCSS(0) /*!< system clock source select IRC48M */ +#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select HXTAL */ +#define RCU_SCSS_IRC32K CFG0_SCSS(2) /*!< system clock source select IRC32K */ +#define RCU_SCSS_LXTAL CFG0_SCSS(3) /*!< system clock source select LXTAL */ + +/* AHB prescaler selection */ +#define CFG0_AHBPSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4U)) +#define RCU_AHB_CKSYS_DIV1 CFG0_AHBPSC(0) /*!< AHB prescaler select CK_SYS */ +#define RCU_AHB_CKSYS_DIV2 CFG0_AHBPSC(8) /*!< AHB prescaler select CK_SYS/2 */ +#define RCU_AHB_CKSYS_DIV4 CFG0_AHBPSC(9) /*!< AHB prescaler select CK_SYS/4 */ +#define RCU_AHB_CKSYS_DIV8 CFG0_AHBPSC(10) /*!< AHB prescaler select CK_SYS/8 */ +#define RCU_AHB_CKSYS_DIV16 CFG0_AHBPSC(11) /*!< AHB prescaler select CK_SYS/16 */ +#define RCU_AHB_CKSYS_DIV64 CFG0_AHBPSC(12) /*!< AHB prescaler select CK_SYS/64 */ +#define RCU_AHB_CKSYS_DIV128 CFG0_AHBPSC(13) /*!< AHB prescaler select CK_SYS/128 */ +#define RCU_AHB_CKSYS_DIV256 CFG0_AHBPSC(14) /*!< AHB prescaler select CK_SYS/256 */ +#define RCU_AHB_CKSYS_DIV512 CFG0_AHBPSC(15) /*!< AHB prescaler select CK_SYS/512 */ + +/* APB prescaler selection */ +#define CFG0_APBPSC(regval) (BITS(11,13) & ((uint32_t)(regval) << 11U)) +#define RCU_APB_CKAHB_DIV1 CFG0_APBPSC(0) /*!< APB prescaler select CK_AHB */ +#define RCU_APB_CKAHB_DIV2 CFG0_APBPSC(4) /*!< APB prescaler select CK_AHB/2 */ +#define RCU_APB_CKAHB_DIV4 CFG0_APBPSC(5) /*!< APB prescaler select CK_AHB/4 */ +#define RCU_APB_CKAHB_DIV8 CFG0_APBPSC(6) /*!< APB prescaler select CK_AHB/8 */ +#define RCU_APB_CKAHB_DIV16 CFG0_APBPSC(7) /*!< APB prescaler select CK_AHB/16 */ + +/* CK_OUT0 clock source selection */ +#define CFG0_CKOUT0SEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24U)) +#define RCU_CKOUT0SRC_NONE CFG0_CKOUT0SEL(0) /*!< no clock selected */ +#define RCU_CKOUT0SRC_CKSYS CFG0_CKOUT0SEL(1) /*!< CK_OUT0 clock source select CKSYS */ +#define RCU_CKOUT0SRC_IRC48M CFG0_CKOUT0SEL(3) /*!< CK_OUT0 clock source select IRC48M */ +#define RCU_CKOUT0SRC_HXTAL CFG0_CKOUT0SEL(4) /*!< CK_OUT0 clock source select HXTAL */ +#define RCU_CKOUT0SRC_IRC32K CFG0_CKOUT0SEL(6) /*!< CK_OUT0 clock source select IRC32K */ +#define RCU_CKOUT0SRC_LXTAL CFG0_CKOUT0SEL(7) /*!< CK_OUT0 clock source select LXTAL */ + +/* CK_OUT0 divider */ +#define CFG0_CKOUT0DIV(regval) (BITS(28,30) & ((uint32_t)(regval) << 28U)) +#define RCU_CKOUT0_DIV1 CFG0_CKOUT0DIV(0) /*!< CK_OUT0 is divided by 1 */ +#define RCU_CKOUT0_DIV2 CFG0_CKOUT0DIV(1) /*!< CK_OUT0 is divided by 2 */ +#define RCU_CKOUT0_DIV4 CFG0_CKOUT0DIV(2) /*!< CK_OUT0 is divided by 4 */ +#define RCU_CKOUT0_DIV8 CFG0_CKOUT0DIV(3) /*!< CK_OUT0 is divided by 8 */ +#define RCU_CKOUT0_DIV16 CFG0_CKOUT0DIV(4) /*!< CK_OUT0 is divided by 16 */ +#define RCU_CKOUT0_DIV32 CFG0_CKOUT0DIV(5) /*!< CK_OUT0 is divided by 32 */ +#define RCU_CKOUT0_DIV64 CFG0_CKOUT0DIV(6) /*!< CK_OUT0 is divided by 64 */ +#define RCU_CKOUT0_DIV128 CFG0_CKOUT0DIV(7) /*!< CK_OUT0 is divided by 128 */ + +/* CK_OUT1 clock source selection */ +#define CFG0_CKOUT1SEL(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) +#define RCU_CKOUT1SRC_NONE CFG0_CKOUT1SEL(0) /*!< no clock selected */ +#define RCU_CKOUT1SRC_CKSYS CFG0_CKOUT1SEL(1) /*!< CK_OUT1 clock source select CKSYS */ +#define RCU_CKOUT1SRC_IRC48M CFG0_CKOUT1SEL(3) /*!< CK_OUT1 clock source select IRC48M */ +#define RCU_CKOUT1SRC_HXTAL CFG0_CKOUT1SEL(4) /*!< CK_OUT1 clock source select HXTAL */ +#define RCU_CKOUT1SRC_IRC32K CFG0_CKOUT1SEL(6) /*!< CK_OUT1 clock source select IRC32K */ +#define RCU_CKOUT1SRC_LXTAL CFG0_CKOUT1SEL(7) /*!< CK_OUT1 clock source select LXTAL */ + +/* CK_OUT1 divider */ +#define CFG0_CKOUT1DIV(regval) (BITS(20,22) & ((uint32_t)(regval) << 20U)) +#define RCU_CKOUT1_DIV1 CFG0_CKOUT1DIV(0) /*!< CK_OUT1 is divided by 1 */ +#define RCU_CKOUT1_DIV2 CFG0_CKOUT1DIV(1) /*!< CK_OUT1 is divided by 2 */ +#define RCU_CKOUT1_DIV4 CFG0_CKOUT1DIV(2) /*!< CK_OUT1 is divided by 4 */ +#define RCU_CKOUT1_DIV8 CFG0_CKOUT1DIV(3) /*!< CK_OUT1 is divided by 8 */ +#define RCU_CKOUT1_DIV16 CFG0_CKOUT1DIV(4) /*!< CK_OUT1 is divided by 16 */ +#define RCU_CKOUT1_DIV32 CFG0_CKOUT1DIV(5) /*!< CK_OUT1 is divided by 32 */ +#define RCU_CKOUT1_DIV64 CFG0_CKOUT1DIV(6) /*!< CK_OUT1 is divided by 64 */ +#define RCU_CKOUT1_DIV128 CFG0_CKOUT1DIV(7) /*!< CK_OUT1 is divided by 128 */ + +/* low speed clock output source selection */ +#define RCU_LSCKOUTSRC_IRC32K (uint32_t)(0X00000000U) /*!< IRC32K clock selected */ +#define RCU_LSCKOUTSRC_LXTAL RCU_CTL1_LSCKOUTSEL /*!< LXTAL clock selected */ + +/* LXTAL drive capability */ +#define RCU_LXTAL_LOWDRI (uint32_t)(0X00000000U) /*!< lower driving capability */ +#define RCU_LXTAL_HIGHDRI RCU_CTL1_LXTALDRI /*!< higher driving capability */ + +/* RTC clock entry selection */ +#define CTL1_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define RCU_RTCSRC_NONE CTL1_RTCSRC(0) /*!< no clock selected */ +#define RCU_RTCSRC_LXTAL CTL1_RTCSRC(1) /*!< LXTAL selected as RTC source clock */ +#define RCU_RTCSRC_IRC32K CTL1_RTCSRC(2) /*!< IRC32K selected as RTC source clock */ +#define RCU_RTCSRC_HXTAL_DIV32 CTL1_RTCSRC(3) /*!< HXTAL/32 selected as RTC source clock */ + +/* USART0 clock source selection */ +#define CFG1_USART0SEL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define RCU_USART0SRC_CKAPB CFG1_USART0SEL(0) /*!< CK_USART0 select CK_APB */ +#define RCU_USART0SRC_CKSYS CFG1_USART0SEL(1) /*!< CK_USART0 select CK_SYS */ +#define RCU_USART0SRC_IRC48MDIV_PER CFG1_USART0SEL(2) /*!< CK_USART0 select CK_IRC48MDIV_PER */ +#define RCU_USART0SRC_LXTAL CFG1_USART0SEL(3) /*!< CK_USART0 select LXTAL */ + +/* I2Cx(x=0,1) clock source selection */ +#define CFG1_I2C0SEL(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) +#define RCU_I2CSRC_CKAPB CFG1_I2C0SEL(0) /*!< CK_I2C select CK_APB */ +#define RCU_I2CSRC_CKSYS CFG1_I2C0SEL(1) /*!< CK_I2C select CK_SYS */ +#define RCU_I2CSRC_IRC48MDIV_PER CFG1_I2C0SEL(2) /*!< CK_I2C select CK_IRC48MDIV_PER */ + +/* I2S clock source selection */ +#define CFG1_I2SSEL(regval) (BITS(14,15) & ((uint32_t)(regval) << 14U)) +#define RCU_I2SSRC_CKSYS CFG1_I2SSEL(0) /*!< CK_I2S select CK_SYS */ +#define RCU_I2SSRC_IRC48MDIV_PER CFG1_I2SSEL(2) /*!< CK_I2S select CK_IRC48MDIV_PER */ +#define RCU_I2SSRC_CKIN CFG1_I2SSEL(3) /*!< CK_I2S select I2S_CKIN */ + +/* ADC clock source selection */ +#define RCU_ADCSRC_CKSYS (uint32_t)0x00000000U /*!< ADC clock source select CK_SYS */ +#define RCU_ADCSRC_IRC48M_PER (uint32_t)0x00000100U /*!< ADC clock source select CK_IRC48MDIV_PER */ +#define RCU_ADCSRC_HXTAL RCU_CFG1_ADCSEL /*!< ADC clock source select CK_HXTAL */ + +/* ADC clock prescaler selection */ +#define CFG1_ADCPSC(regval) (BITS(9,12) & ((uint32_t)(regval) << 9U)) +#define RCU_ADCCK_DIV1 CFG1_ADCPSC(0) /*!< ADC clock prescaler select not divided */ +#define RCU_ADCCK_DIV2 CFG1_ADCPSC(1) /*!< ADC clock prescaler select divided by 2 */ +#define RCU_ADCCK_DIV4 CFG1_ADCPSC(2) /*!< ADC clock prescaler select divided by 4*/ +#define RCU_ADCCK_DIV6 CFG1_ADCPSC(3) /*!< ADC clock prescaler select divided by 6*/ +#define RCU_ADCCK_DIV8 CFG1_ADCPSC(4) /*!< ADC clock prescaler select divided by 8*/ +#define RCU_ADCCK_DIV10 CFG1_ADCPSC(5) /*!< ADC clock prescaler select divided by 10 */ +#define RCU_ADCCK_DIV12 CFG1_ADCPSC(6) /*!< ADC clock prescaler select divided by 12 */ +#define RCU_ADCCK_DIV16 CFG1_ADCPSC(7) /*!< ADC clock prescaler select divided by 16 */ +#define RCU_ADCCK_DIV32 CFG1_ADCPSC(8) /*!< ADC clock prescaler select divided by 32 */ +#define RCU_ADCCK_DIV64 CFG1_ADCPSC(9) /*!< ADC clock prescaler select divided by 64 */ +#define RCU_ADCCK_DIV128 CFG1_ADCPSC(10) /*!< ADC clock prescaler select divided by 128 */ +#define RCU_ADCCK_DIV256 CFG1_ADCPSC(11) /*!< ADC clock prescaler select divided by 256 */ + +#ifdef FW_DEBUG_ERR_REPORT +/* check maximum irc48m adjust value */ +#define IRC48M_ADJ_HIGH_VALUE ((uint32_t)0x0000003FU) +#define NOT_IRC48M_ADJ(irc48m_adjval) ((IRC48M_ADJ_HIGH_VALUE < (irc48m_adjval))) +#endif /* FW_DEBUG_ERR_REPORT */ + +/* function declarations */ +/* initialization, peripheral clock and reset configuration functions */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* enable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the peripherals */ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset); +/* disable reset the peripheral */ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset); +/* reset the BKP */ +void rcu_bkp_reset_enable(void); +/* disable the BKP reset */ +void rcu_bkp_reset_disable(void); + +/* system clock, AHB, APB, ADC and clock out configuration functions */ +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB prescaler selection */ +void rcu_apb_clock_config(uint32_t ck_apb); +/* configure the ADC clock source and prescaler selection */ +void rcu_adc_clock_config(uint32_t adc_clock_source, uint32_t ck_adc); +/* 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); +/* enable the low speed clock output */ +void rcu_lsckout_enable(void); +/* disable the low speed clock output */ +void rcu_lsckout_disable(void); +/* configure the LSCKOUT clock source */ +void rcu_lsckout_config(uint32_t lsckout_src); + +/* configure the USART clock source selection */ +void rcu_usart_clock_config(usart_idx_enum usart_idx, uint32_t ck_usart); +/* configure the I2Cx(x=0,1) clock source selection */ +void rcu_i2c_clock_config(i2c_idx_enum i2c_idx, uint32_t ck_i2c); +/* configure the I2S clock source selection */ +void rcu_i2s_clock_config(uint32_t ck_i2s); +/* configure the IRC48MDIV_SYS clock selection */ +void rcu_irc48mdiv_sys_clock_config(uint32_t ck_irc48mdiv_sys); +/* configure the IRC48MDIV_PER clock selection */ +void rcu_irc48mdiv_per_clock_config(uint32_t ck_irc48mdiv_per) ; +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); + +/* oscillator configuration functions */ +/* wait until oscillator stabilization flags is SET */ +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 */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* set the IRC48M adjust value */ +void rcu_irc48m_adjust_value_set(uint8_t irc48m_adjval); +/* LXTAL stabilization reset */ +void rcu_lxtal_stab_reset_enable(void); +/* disable LXTAL stabilization reset */ +void rcu_lxtal_stab_reset_disable(void); + +/* clock monitor configure functions */ +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); +/* enable the LXTAL clock monitor */ +void rcu_lxtal_clock_monitor_enable(void); +/* disable the LXTAL clock monitor */ +void rcu_lxtal_clock_monitor_disable(void); + +/* clock frequency get functions */ +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +/* flag and interrupt functions */ +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum stab_int); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum stab_int); +/* 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_clear); +#endif /* GD32C2X1_RCU_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_rtc.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_rtc.h new file mode 100644 index 0000000..1a02102 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_rtc.h @@ -0,0 +1,504 @@ +/*! + \file gd32c2x1_rtc.h + \brief definitions for the RTC + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_RTC_H +#define GD32C2X1_RTC_H + +#include "gd32c2x1.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00000000U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x00000004U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x00000008U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0000000CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x00000010U) /*!< RTC time prescaler register */ +#define RTC_ALRM0TD REG32((RTC) + 0x0000001CU) /*!< RTC alarm 0 time and date register */ +#define RTC_WPK REG32((RTC) + 0x00000024U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x00000028U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x0000002CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x00000030U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x00000034U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x00000038U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x0000003CU) /*!< RTC high resolution frequency compensation register */ +#define RTC_TYPE REG32((RTC) + 0x00000040U) /*!< RTC type register */ +#define RTC_ALRM0SS REG32((RTC) + 0x00000044U) /*!< RTC alarm 0 sub second register */ +#define RTC_BKP0 REG32((RTC) + 0x00000050U) /*!< RTC backup 0 register */ +#define RTC_BKP1 REG32((RTC) + 0x00000054U) /*!< RTC backup 1 register */ +#define RTC_BKP2 REG32((RTC) + 0x00000058U) /*!< RTC backup 2 register */ +#define RTC_BKP3 REG32((RTC) + 0x0000005CU) /*!< RTC backup 3 register */ + +/* 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_TSEG BIT(3) /*!< valid event edge of time-stamp */ +#define RTC_CTL_REFEN BIT(4) /*!< reference clock detection function enable */ +#define RTC_CTL_BPSHAD BIT(5) /*!< shadow registers bypass control */ +#define RTC_CTL_CS BIT(6) /*!< display format of clock system */ +#define RTC_CTL_ALRM0EN BIT(8) /*!< alarm0 function enable */ +#define RTC_CTL_TSEN BIT(11) /*!< time-stamp function enable */ +#define RTC_CTL_ALRM0IE BIT(12) /*!< RTC alarm0 interrupt enable */ +#define RTC_CTL_TSIE BIT(15) /*!< time-stamp interrupt enable */ +#define RTC_CTL_A1H BIT(16) /*!< add 1 hour(summer time change) */ +#define RTC_CTL_S1H BIT(17) /*!< subtract 1 hour(winter time change) */ +#define RTC_CTL_DSM BIT(18) /*!< daylight saving mark */ +#define RTC_CTL_COS BIT(19) /*!< calibration output selection */ +#define RTC_CTL_OPOL BIT(20) /*!< output polarity */ +#define RTC_CTL_OS BITS(21,22) /*!< output selection */ +#define RTC_CTL_COEN BIT(23) /*!< calibration output enable */ +#define RTC_CTL_OUT1EN BIT(31) /*!< RTC_OUT1 pin enable */ + +/* RTC_STAT */ +#define RTC_STAT_ALRM0WF BIT(0) /*!< alarm0 configuration 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_TSF BIT(11) /*!< time-stamp flag */ +#define RTC_STAT_TSOVRF BIT(12) /*!< time-stamp overflow 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_ALRMxTD */ +#define RTC_ALRMXTD_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_ALRMXTD_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_ALRMXTD_MSKS BIT(7) /*!< alarm second mask bit */ +#define RTC_ALRMXTD_MNU BITS(8,11) /*!< minutes units in BCD code */ +#define RTC_ALRMXTD_MNT BITS(12,14) /*!< minutes tens in BCD code */ +#define RTC_ALRMXTD_MSKM BIT(15) /*!< alarm minutes mask bit */ +#define RTC_ALRMXTD_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_ALRMXTD_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_ALRMXTD_PM BIT(22) /*!< AM/PM flag */ +#define RTC_ALRMXTD_MSKH BIT(23) /*!< alarm hour mask bit */ +#define RTC_ALRMXTD_DAYU BITS(24,27) /*!< date units or week day in BCD code */ +#define RTC_ALRMXTD_DAYT BITS(28,29) /*!< date tens in BCD code */ +#define RTC_ALRMXTD_DOWS BIT(30) /*!< day of week selection */ +#define RTC_ALRMXTD_MSKD BIT(31) /*!< alarm date mask bit */ + +/* RTC_WPK */ +#define RTC_WPK_WPK BITS(0,7) /*!< key for write protection */ + +/* RTC_SS */ +#define RTC_SS_SSC BITS(0,15) /*!< sub second value */ + +/* RTC_SHIFTCTL */ +#define RTC_SHIFTCTL_SFS BITS(0,14) /*!< subtract a fraction of a second */ +#define RTC_SHIFTCTL_A1S BIT(31) /*!< one second add */ + +/* RTC_TTS */ +#define RTC_TTS_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TTS_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TTS_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TTS_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TTS_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TTS_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TTS_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DTS */ +#define RTC_DTS_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DTS_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DTS_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DTS_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DTS_DOW BITS(13,15) /*!< day of week units */ + +/* RTC_SSTS */ +#define RTC_SSTS_SSC BITS(0,15) /*!< timestamp sub second units */ + +/* RTC_HRFC */ +#define RTC_HRFC_CMSK BITS(0,8) /*!< calibration mask number */ +#define RTC_HRFC_CWND16 BIT(13) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_CWND8 BIT(14) /*!< calibration window select 8 seconds */ +#define RTC_HRFC_FREQI BIT(15) /*!< increase RTC frequency by 488.5ppm */ + +/* RTC_TYPE */ +#define RTC_TYPE_DISPU BIT(15) /*!< RTC tamp x pull up disable bit */ +#define RTC_TYPE_ALRMOUTTYPE 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_BKP0 */ +#define RTC_BKP0_DATA BITS(0,15) /*!< backup domain registers */ + +/* RTC_BKP1 */ +#define RTC_BKP1_DATA BITS(0,15) /*!< backup domain registers */ + +/* RTC_BKP2 */ +#define RTC_BKP2_DATA BITS(0,15) /*!< backup domain registers */ + +/* RTC_BKP3 */ +#define RTC_BKP3_DATA BITS(0,15) /*!< backup domain registers */ + +/* constants definitions */ +/* structure for initialization of the RTC */ +typedef struct { + uint8_t year; /*!< RTC year value: 0x0 - 0x99(BCD format) */ + uint8_t month; /*!< RTC month value */ + uint8_t date; /*!< RTC date value: 0x1 - 0x31(BCD format) */ + uint8_t day_of_week; /*!< RTC weekday value */ + uint8_t hour; /*!< RTC hour value */ + uint8_t minute; /*!< RTC minute value: 0x0 - 0x59(BCD format) */ + uint8_t second; /*!< RTC second value: 0x0 - 0x59(BCD format) */ + uint16_t factor_asyn; /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */ + uint16_t factor_syn; /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */ + uint32_t am_pm; /*!< RTC AM/PM value */ + uint32_t display_format; /*!< RTC time notation */ +} rtc_parameter_struct; + +/* structure for RTC alarm configuration */ +typedef struct { + uint32_t alarm_mask; /*!< RTC alarm mask */ + uint32_t weekday_or_date; /*!< specify RTC alarm is on date or weekday */ + uint8_t alarm_day; /*!< RTC alarm date or weekday value*/ + uint8_t alarm_hour; /*!< RTC alarm hour value */ + uint8_t alarm_minute; /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */ + uint8_t alarm_second; /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */ + uint32_t am_pm; /*!< RTC alarm AM/PM value */ +} rtc_alarm_struct; + +/* structure for RTC time-stamp configuration */ +typedef struct { + uint8_t timestamp_month; /*!< RTC time-stamp month value */ + uint8_t timestamp_date; /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */ + uint8_t timestamp_day; /*!< RTC time-stamp weekday value */ + uint8_t timestamp_hour; /*!< RTC time-stamp hour value */ + uint8_t timestamp_minute; /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */ + uint8_t timestamp_second; /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */ + uint32_t am_pm; /*!< RTC time-stamp AM/PM value */ +} rtc_timestamp_struct; + +/* time register value */ +#define TIME_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_TIME_SC bit field */ +#define GET_TIME_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TIME_SC bit field */ + +#define TIME_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_TIME_MN bit field */ +#define GET_TIME_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TIME_MN bit field */ + +#define TIME_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_TIME_HR bit field */ +#define GET_TIME_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TIME_HR bit field */ + +#define RTC_AM ((uint32_t)0x00000000U) /*!< AM format */ +#define RTC_PM RTC_TIME_PM /*!< PM format */ + +/* date register value */ +#define DATE_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0)) /*!< write value to RTC_DATE_DAY bit field */ +#define GET_DATE_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DATE_DAY bit field */ + +#define DATE_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8)) /*!< write value to RTC_DATE_MON bit field */ +#define GET_DATE_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DATE_MON bit field */ +#define RTC_JAN ((uint8_t)0x01U) /*!< Janurary */ +#define RTC_FEB ((uint8_t)0x02U) /*!< February */ +#define RTC_MAR ((uint8_t)0x03U) /*!< March */ +#define RTC_APR ((uint8_t)0x04U) /*!< April */ +#define RTC_MAY ((uint8_t)0x05U) /*!< May */ +#define RTC_JUN ((uint8_t)0x06U) /*!< June */ +#define RTC_JUL ((uint8_t)0x07U) /*!< July */ +#define RTC_AUG ((uint8_t)0x08U) /*!< August */ +#define RTC_SEP ((uint8_t)0x09U) /*!< September */ +#define RTC_OCT ((uint8_t)0x10U) /*!< October */ +#define RTC_NOV ((uint8_t)0x11U) /*!< November */ +#define RTC_DEC ((uint8_t)0x12U) /*!< December */ + +#define DATE_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< write value to RTC_DATE_DOW bit field */ +#define GET_DATE_DOW(regval) GET_BITS((uint32_t)(regval),13,15) /*!< get value of RTC_DATE_DOW bit field */ +#define RTC_MONDAY ((uint8_t)0x01) /*!< monday */ +#define RTC_TUESDAY ((uint8_t)0x02) /*!< tuesday */ +#define RTC_WEDNESDAY ((uint8_t)0x03) /*!< wednesday */ +#define RTC_THURSDAY ((uint8_t)0x04) /*!< thursday */ +#define RTC_FRIDAY ((uint8_t)0x05) /*!< friday */ +#define RTC_SATURDAY ((uint8_t)0x06) /*!< saturday */ +#define RTC_SUNDAY ((uint8_t)0x07) /*!< sunday */ + +#define DATE_YR(regval) (BITS(16,23) & ((uint32_t)(regval) << 16)) /*!< write value to RTC_DATE_YR bit field */ +#define GET_DATE_YR(regval) GET_BITS((regval),16,23) /*!< get value of RTC_DATE_YR bit field */ + +#define RTC_OUT1_DISABLE ((uint32_t)0x00000000U) /*!< RTC_OUT1 disable */ +#define RTC_OUT1_ENABLE RTC_CTL_OUT1EN /*!< RTC_OUT1 enable */ + +#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_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_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 */ + +#define RTC_ALARM_OUTPUT_OD ((uint32_t)0x00000000U) /*!< RTC alarm output open-drain mode */ +#define RTC_ALARM_OUTPUT_PP RTC_TYPE_ALRMOUTTYPE /*!< RTC alarm output push-pull mode */ + +/* alrm0ss register value */ +#define ALRMXSS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0)) /*!< write value to RTC_ALRMXSS_SSC bit field */ + +#define ALRMXSS_MSKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24)) /*!< write value to RTC_ALRMXSS_MSKSSC bit field */ +#define RTC_MSKSSC_0_14 ALRMXSS_MSKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MSKSSC_1_14 ALRMXSS_MSKSSC(1) /*!< mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared */ +#define RTC_MSKSSC_2_14 ALRMXSS_MSKSSC(2) /*!< mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared */ +#define RTC_MSKSSC_3_14 ALRMXSS_MSKSSC(3) /*!< mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared */ +#define RTC_MSKSSC_4_14 ALRMXSS_MSKSSC(4) /*!< mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared */ +#define RTC_MSKSSC_5_14 ALRMXSS_MSKSSC(5) /*!< mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared */ +#define RTC_MSKSSC_6_14 ALRMXSS_MSKSSC(6) /*!< mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared */ +#define RTC_MSKSSC_7_14 ALRMXSS_MSKSSC(7) /*!< mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared */ +#define RTC_MSKSSC_8_14 ALRMXSS_MSKSSC(8) /*!< mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared */ +#define RTC_MSKSSC_9_14 ALRMXSS_MSKSSC(9) /*!< mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared */ +#define RTC_MSKSSC_10_14 ALRMXSS_MSKSSC(10) /*!< mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared */ +#define RTC_MSKSSC_11_14 ALRMXSS_MSKSSC(11) /*!< mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared */ +#define RTC_MSKSSC_12_14 ALRMXSS_MSKSSC(12) /*!< mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared */ +#define RTC_MSKSSC_13_14 ALRMXSS_MSKSSC(13) /*!< mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared */ +#define RTC_MSKSSC_14 ALRMXSS_MSKSSC(14) /*!< mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared */ +#define RTC_MSKSSC_NONE ALRMXSS_MSKSSC(15) /*!< mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared */ + +/* write protect key */ +#define RTC_UNLOCK_KEY1 ((uint8_t)0xCAU) /*!< RTC unlock key1 */ +#define RTC_UNLOCK_KEY2 ((uint8_t)0x53U) /*!< RTC unlock key2 */ +#define RTC_LOCK_KEY ((uint8_t)0xFFU) /*!< RTC lock key */ + +/* registers reset value */ +#define RTC_REGISTER_RESET ((uint32_t)0x00000000U) /*!< RTC common register reset value */ +#define RTC_DATE_RESET ((uint32_t)0x00002101U) /*!< RTC_DATE register reset value */ +#define RTC_STAT_RESET ((uint32_t)0x00000007U) /*!< RTC_STAT register reset value */ +#define RTC_PSC_RESET ((uint32_t)0x007F00FFU) /*!< RTC_PSC register reset value */ + +/* RTC alarm */ +#define RTC_ALARM0 ((uint8_t)0x01U) /*!< RTC alarm 0 */ + +/* RTC interrupt flag definitions */ +typedef enum { + RTC_INT_TIMESTAMP = ((uint32_t)RTC_CTL_TSIE), /*!< time-stamp interrupt enable */ + RTC_INT_ALARM0 = ((uint32_t)RTC_CTL_ALRM0IE), /*!< alarm interrupt enable */ +} rtc_interrupt_flag_enum; + +/* RTC flag definitions */ +typedef enum { + RTC_FLAG_ALARM0W = ((uint32_t)RTC_STAT_ALRM0WF), /*!< alarm0 configuration can be write flag */ + RTC_FLAG_SOP = ((uint32_t)RTC_STAT_SOPF ), /*!< shift function operation pending flag */ + RTC_FLAG_YCM = ((uint32_t)RTC_STAT_YCM ), /*!< year parameter configured event flag */ + RTC_FLAG_RSYN = ((uint32_t)RTC_STAT_RSYNF ), /*!< registers synchronized flag */ + RTC_FLAG_INIT = ((uint32_t)RTC_STAT_INITF ), /*!< init mode event flag */ + RTC_FLAG_SCP = ((uint32_t)RTC_STAT_SOPF ), /*!< smooth calibration pending flag */ + RTC_FLAG_ALARM0 = ((uint32_t)RTC_STAT_ALRM0F ), /*!< alarm event flag */ + RTC_FLAG_TS = ((uint32_t)RTC_STAT_TSF ), /*!< time-stamp flag */ + RTC_FLAG_TSOVR = ((uint32_t)RTC_STAT_TSOVRF ), /*!< time-stamp overflow flag */ +} rtc_flag_enum; + +/* parameter check definitions */ +#ifdef FW_DEBUG_ERR_REPORT + +/* check the RTC pointer*/ +#define NOT_RTC_VALID_POINTER(pointer) ((void *) 0 == (pointer)) /*!< check the invalid pointer */ + +#endif + +/* function declarations */ +/* enable RTC bypass shadow registers function */ +void rtc_bypass_shadow_enable(void); +/* disable RTC bypass shadow registers function */ +void rtc_bypass_shadow_disable(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); + +/* enable RTC alarm */ +void rtc_alarm_enable(void); +/* disable RTC alarm */ +ErrStatus rtc_alarm_disable(void); +/* alarm configuration functions */ +/* configure RTC alarm */ +void rtc_alarm_config(rtc_alarm_struct *rtc_alarm_time); +/* configure subsecond of RTC alarm */ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond); +/* get RTC alarm */ +void rtc_alarm_get(rtc_alarm_struct *rtc_alarm_time); +/* get RTC alarm subsecond */ +uint32_t rtc_alarm_subsecond_get(void); + +/* enter RTC init mode */ +ErrStatus rtc_init_mode_enter(void); +/* initialize RTC registers */ +ErrStatus rtc_init(rtc_parameter_struct *rtc_initpara_struct); +/* exit RTC init mode */ +void rtc_init_mode_exit(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); + +/* reset most of the RTC registers */ +ErrStatus rtc_deinit(void); + +/* 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 reference clock detection function */ +ErrStatus rtc_refclock_detection_enable(void); +/* disable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_disable(void); + +/* configure RTC smooth calibration */ +ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t smooth_minus); + +/* timestamp and tamper configuration functions */ +/* enable RTC time-stamp */ +void rtc_timestamp_enable(uint32_t edge); +/* disable RTC time-stamp */ +void rtc_timestamp_disable(void); +/* get RTC timestamp time and date */ +void rtc_timestamp_get(rtc_timestamp_struct *rtc_timestamp); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); +/* configure RTC calibration output source */ +void rtc_calibration_output_config(uint32_t source); +/* configure RTC alarm output source */ +void rtc_alarm_output_config(uint32_t alarm_output, uint32_t mode); +/* select the RTC output pin */ +void rtc_output_pin_select(uint32_t outputpin); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(rtc_interrupt_flag_enum interrupt); +/* disable specified RTC interrupt */ +void rtc_interrupt_disable(rtc_interrupt_flag_enum interrupt); +/* check specified flag */ +FlagStatus rtc_flag_get(rtc_flag_enum flag); +/* clear specified flag */ +void rtc_flag_clear(rtc_flag_enum flag_clear); + +#endif /* GD32C2X1_RTC_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_spi.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_spi.h new file mode 100644 index 0000000..b48800a --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_spi.h @@ -0,0 +1,432 @@ +/*! + \file gd32c2x1_spi.h + \brief definitions for the SPI + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_SPI_H +#define GD32C2X1_SPI_H + +#include "gd32c2x1.h" + +/* SPIx(x=0,1) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) /*!< SPI0 base address */ +#define SPI1 SPI_BASE /*!< SPI1 base address */ + +/* SPI registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00000000U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x00000004U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x00000008U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0000000CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x00000010U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x00000014U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x00000018U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x0000001CU) /*!< SPI / I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x00000020U) /*!< SPI / I2S clock prescaler register */ +#define SPI_QCTL(spix) REG32((spix) + 0x00000080U) /*!< SPI quad mode control register(only SPI1) */ + +/* 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(only for SPI0) */ +#define SPI_CTL0_CRCL BIT(11) /*!< crc length(for SPI1) */ +#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_NSSP BIT(3) /*!< SPI NSS pulse mode enable */ +#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 */ +#define SPI_CTL1_DZ BITS(8,11) /*!< data size(only for SPI1) */ +#define SPI_CTL1_BYTEN BIT(12) /*!< Byte access enable(only for SPI1) */ +#define SPI_CTL1_RXDMA_ODD BIT(13) /*!< Odd bytes in RX DMA channel(only for SPI1) */ +#define SPI_CTL1_TXDMA_ODD BIT(14) /*!< Odd bytes in TX DMA channel(only for SPI1) */ + +/* 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) /*!< 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 */ +#define SPI_STAT_RXLVL BITS(9,10) /*!< RXFIFO level(only for SPI1) */ +#define SPI_STAT_TXLVL BITS(11,12) /*!< TXFIFO level(only for SPI1) */ + +/* 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) /*!< RX 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_I2SPSC */ +#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_QCTL(only for SPI1) */ +#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 transfer type */ + 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 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 phase and polarity */ +#define SPI_CK_PL_LOW_PH_1EDGE ((uint32_t)0x00000000U) /*!< SPI clock polarity is low level and phase is first edge */ +#define SPI_CK_PL_HIGH_PH_1EDGE SPI_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)((uint32_t)(regval) << 3U)) +#define SPI_PSC_2 CTL0_PSC(0U) /*!< SPI clock prescale factor is 2 */ +#define SPI_PSC_4 CTL0_PSC(1U) /*!< SPI clock prescale factor is 4 */ +#define SPI_PSC_8 CTL0_PSC(2U) /*!< SPI clock prescale factor is 8 */ +#define SPI_PSC_16 CTL0_PSC(3U) /*!< SPI clock prescale factor is 16 */ +#define SPI_PSC_32 CTL0_PSC(4U) /*!< SPI clock prescale factor is 32 */ +#define SPI_PSC_64 CTL0_PSC(5U) /*!< SPI clock prescale factor is 64 */ +#define SPI_PSC_128 CTL0_PSC(6U) /*!< SPI clock prescale factor is 128 */ +#define SPI_PSC_256 CTL0_PSC(7U) /*!< SPI clock prescale factor is 256 */ + +/* SPIx frame size */ +#define CTL1_FRAMESIZE(regval) (BITS(8,11) & (uint32_t)((uint32_t)(regval) << 8U)) +#define SPI_FRAMESIZE_4BIT CTL1_FRAMESIZE(3U) /*!< SPI frame size is 4 bits */ +#define SPI_FRAMESIZE_5BIT CTL1_FRAMESIZE(4U) /*!< SPI frame size is 5 bits */ +#define SPI_FRAMESIZE_6BIT CTL1_FRAMESIZE(5U) /*!< SPI frame size is 6 bits */ +#define SPI_FRAMESIZE_7BIT CTL1_FRAMESIZE(6U) /*!< SPI frame size is 7 bits */ +#define SPI_FRAMESIZE_8BIT CTL1_FRAMESIZE(7U) /*!< SPI frame size is 8 bits */ +#define SPI_FRAMESIZE_9BIT CTL1_FRAMESIZE(8U) /*!< SPI frame size is 9 bits */ +#define SPI_FRAMESIZE_10BIT CTL1_FRAMESIZE(9U) /*!< SPI frame size is 10 bits */ +#define SPI_FRAMESIZE_11BIT CTL1_FRAMESIZE(10U) /*!< SPI frame size is 11 bits */ +#define SPI_FRAMESIZE_12BIT CTL1_FRAMESIZE(11U) /*!< SPI frame size is 12 bits */ +#define SPI_FRAMESIZE_13BIT CTL1_FRAMESIZE(12U) /*!< SPI frame size is 13 bits */ +#define SPI_FRAMESIZE_14BIT CTL1_FRAMESIZE(13U) /*!< SPI frame size is 14 bits */ +#define SPI_FRAMESIZE_15BIT CTL1_FRAMESIZE(14U) /*!< SPI frame size is 15 bits */ +#define SPI_FRAMESIZE_16BIT CTL1_FRAMESIZE(15U) /*!< SPI frame size is 16 bits */ + +/* SPIx CRC length(x=1) */ +#define SPI_CRC_8BIT ((uint32_t)0x00000000U) /*!< SPI CRC length is 8 bits */ +#define SPI_CRC_16BIT SPI_CTL0_CRCL /*!< SPI CRC length is 16 bits */ + +/* SPIx byte access enable(x=1) */ +#define SPI_HALFWORD_ACCESS ((uint32_t)0x00000000U) /*!< SPI half-word access to FIFO */ +#define SPI_BYTE_ACCESS SPI_CTL1_BYTEN /*!< SPI byte access to FIFO */ + +/* SPIx odd bytes in TX DMA channel(x=1) */ +#define SPI_TXDMA_EVEN ((uint32_t)0x00000000U) /*!< SPI number of byte in TX DMA channel is even */ +#define SPI_TXDMA_ODD SPI_CTL1_TXDMA_ODD /*!< SPI number of byte in TX DMA channel is odd */ + +/* SPIx odd bytes in RX DMA channel(x=1) */ +#define SPI_RXDMA_EVEN ((uint32_t)0x00000000U) /*!< SPI number of byte in RX DMA channel is even */ +#define SPI_RXDMA_ODD SPI_CTL1_RXDMA_ODD /*!< SPI number of byte in RX DMA channel is odd */ + +/* SPIx TXFIFO level(x=1) */ +#define CTL1_TXLVL(regval) (BITS(11,12) & ((uint32_t)(regval) << 11U)) +#define SPI_TXLVL_EMPTY CTL1_TXLVL(0U) /*!< SPI TXFIFO is empty */ +#define SPI_TXLVL_QUARTER_FULL CTL1_TXLVL(1U) /*!< SPI TXFIFO is a quarter of full */ +#define SPI_TXLVL_HALF_FULL CTL1_TXLVL(2U) /*!< SPI TXFIFO is a half of full */ +#define SPI_TXLVL_FULL CTL1_TXLVL(3U) /*!< SPI TXFIFO is full */ + +/* SPIx RXFIFO level(x=1) */ +#define CTL1_RXLVL(regval) (BITS(9,10) & ((uint32_t)(regval) << 9U)) +#define SPI_RXLVL_EMPTY CTL1_RXLVL(0U) /*!< SPI RXFIFO is empty */ +#define SPI_RXLVL_QUARTER_FULL CTL1_RXLVL(1U) /*!< SPI RXFIFO is a quarter of full */ +#define SPI_RXLVL_HALF_FULL CTL1_RXLVL(2U) /*!< SPI RXFIFO is a half of full */ +#define SPI_RXLVL_FULL CTL1_RXLVL(3U) /*!< SPI RXFIFO is full */ + +/* 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) << 1U)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0U) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0U) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1U) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2U) | 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) << 8U)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0U) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1U) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2U) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3U) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0U) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1U) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2U) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3U) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3U) | 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 SPI_CTL1_TBEIE /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_RBNE SPI_CTL1_RBNEIE /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_ERR SPI_CTL1_ERRIE /*!< 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 SPI_I2S_INT_FLAG_FERR ((uint8_t)0x05U) /*!< format error interrupt flag */ +#define I2S_INT_FLAG_TXURERR ((uint8_t)0x06U) /*!< underrun 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 */ +#define SPI_FLAG_TXLVL_EMPTY ((uint32_t)0x10000000U) /*!< SPI TXFIFO is empty flag */ +#define SPI_FLAG_TXLVL_QUARTER_FULL SPI_TXLVL_QUARTER_FULL /*!< SPI TXFIFO is a quarter of full flag */ +#define SPI_FLAG_TXLVL_HALF_FULL SPI_TXLVL_HALF_FULL /*!< SPI TXFIFO is a half of full flag */ +#define SPI_FLAG_TXLVL_FULL SPI_TXLVL_FULL /*!< SPI TXFIFO is full flag */ +#define SPI_FLAG_RXLVL_EMPTY ((uint32_t)0x20000000U) /*!< SPI RXFIFO is empty flag */ +#define SPI_FLAG_RXLVL_QUARTER_FULL SPI_RXLVL_QUARTER_FULL /*!< SPI RXFIFO is a quarter of full flag */ +#define SPI_FLAG_RXLVL_HALF_FULL SPI_RXLVL_HALF_FULL /*!< SPI RXFIFO is a half of full flag */ +#define SPI_FLAG_RXLVL_FULL SPI_RXLVL_FULL /*!< SPI RXFIFO is full flag */ + +/* parameter check definitions */ +#ifdef FW_DEBUG_ERR_REPORT +/* check I2S audio sample rate */ +#define NOT_VALID_I2S_AUDIOSAMPLE(i2s_audiosample) ((i2s_audiosample) == 0U) +#endif/* FW_DEBUG_ERR_REPORT */ + +/* function declarations */ +/* initialization functions */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize the parameters of SPI struct with the default values */ +void spi_struct_para_init(spi_parameter_struct *spi_struct); +/* initialize SPI parameter */ +ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl); +/* configure I2S prescaler */ +void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout); +/* enable I2S */ +void i2s_enable(uint32_t spi_periph); +/* disable I2S */ +void i2s_disable(uint32_t spi_periph); + +/* 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 dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph, uint8_t dma); +/* configure SPI total number of data transmitting by DMA is odd or not */ +void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd); +/* configure SPI total number of data receiving by DMA is odd or not */ +void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd); +/* configure SPI access size to FIFO(8-bit or 16-bit) */ +void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size); + +/* SPI/I2S transfer configure functions */ +/* configure SPI/I2S data frame format */ +ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format); +/* configure SPI bidirectional transfer direction */ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction); +/* 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); + +/* 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); +/* set CRC length */ +void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length); +/* 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 crc); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +/* SPI TI mode functions */ +/* enable SPI TI mode */ +void spi_ti_mode_enable(uint32_t spi_periph); +/* disable SPI TI mode */ +void spi_ti_mode_disable(uint32_t spi_periph); + +/* SPI NSS pulse mode functions */ +/* enable SPI NSS pulse mode */ +void spi_nssp_mode_enable(uint32_t spi_periph); +/* disable SPI NSS pulse mode */ +void spi_nssp_mode_disable(uint32_t spi_periph); + +/* quad wire SPI functions */ +/* enable quad wire SPI */ +void spi_quad_enable(uint32_t spi_periph); +/* disable quad wire SPI */ +void spi_quad_disable(uint32_t spi_periph); +/* enable quad wire SPI write */ +void spi_quad_write_enable(uint32_t spi_periph); +/* enable quad wire SPI read */ +void spi_quad_read_enable(uint32_t spi_periph); +/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_enable(uint32_t spi_periph); +/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ +void spi_quad_io23_output_disable(uint32_t spi_periph); + +/* flag and interrupt functions */ +/* clear SPI/I2S format error flag status */ +void spi_i2s_format_error_clear(uint32_t spi_periph, uint32_t flag); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag); +/* enable SPI and I2S interrupt */ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt); +/* disable SPI and I2S interrupt */ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S interrupt status */ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt); +#endif /* GD32C2X1_SPI_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_syscfg.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_syscfg.h new file mode 100644 index 0000000..e8d8672 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_syscfg.h @@ -0,0 +1,316 @@ +/*! + \file gd32c2x1_syscfg.h + \brief definitions for the SYSCFG + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_SYSCFG_H +#define GD32C2X1_SYSCFG_H + +#include "gd32c2x1.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00U) /*!< system configuration register 0 */ +#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_CFG1 REG32(SYSCFG + 0x18U) /*!< System configuration register 1 */ +#define SYSCFG_STAT REG32(SYSCFG + 0x1CU) /*!< SYSCFG STAT register */ +#define SYSCFG_CFG2 REG32(SYSCFG + 0x28U) /*!< System configuration register 2 */ +#define SYSCFG_CPU_IRQ_LAT REG32(SYSCFG + 0x100U) /*!< IRQ latency register */ +#define SYSCFG_TIMERCFG0(syscfg_timerx) REG32(SYSCFG + 0x110U + (syscfg_timerx)*8U) /*!< TIMERx configuration register0 */ +#define SYSCFG_TIMERCFG1(syscfg_timerx) REG32(SYSCFG + 0x114U + (syscfg_timerx)*8U) /*!< TIMERx configuration register1 */ +#define SYSCFG_TIMER0CFG0 REG32(SYSCFG + 0x110U) /*!< TIMER0 configuration register 0 */ +#define SYSCFG_TIMER0CFG1 REG32(SYSCFG + 0x114U) /*!< TIMER0 configuration register 1 */ +#define SYSCFG_TIMER2CFG0 REG32(SYSCFG + 0x118U) /*!< TIMER2 configuration register 0 */ +#define SYSCFG_TIMER2CFG1 REG32(SYSCFG + 0x11CU) /*!< TIMER2 configuration register 1 */ + +/* SYSCFG_CFG0 bits definitions */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,1) /*!< SYSCFG memory remap config */ +#define SYSCFG_CFG0_PA11_RMP BIT(3) /*!< PA11 remapping */ +#define SYSCFG_CFG0_PA12_RMP BIT(4) /*!< PA12 remapping */ +#define SYSCFG_CFG0_PB6_FMPEN BIT(16) /*!< I2C Fm+ mode on PB6 pin enable */ +#define SYSCFG_CFG0_PB7_FMPEN BIT(17) /*!< I2C Fm+ mode on PB7 pin enable */ +#define SYSCFG_CFG0_PB8_FMPEN BIT(18) /*!< I2C Fm+ mode on PB8 pin enable */ +#define SYSCFG_CFG0_PB9_FMPEN BIT(19) /*!< I2C Fm+ mode on PB9 pin enable */ +#define SYSCFG_CFG0_I2C0_FMPEN BIT(20) /*!< Fast Mode Plus (FM+) enable for I2C0 */ +#define SYSCFG_CFG0_PA9_FMPEN BIT(22) /*!< I2C Fm+ mode on PA9 pin enable */ +#define SYSCFG_CFG0_PA10_FMPEN BIT(23) /*!< I2C Fm+ mode on PA10 pin enable */ +#define SYSCFG_CFG0_PC14_FMPEN BIT(24) /*!< I2C Fm+ mode on PC14 pin enable */ + +/* SYSCFG_EXTISS0 bits definitions */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,1) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,5) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,9) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,13) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 bits definitions */ +#define SYSCFG_EXTISS1_EXTI4_SS BIT(0) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BIT(4) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,9) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,13) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 bits definitions */ +#define SYSCFG_EXTISS2_EXTI8_SS BIT(0) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BIT(4) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BIT(8) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BIT(12) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 bits definitions */ +#define SYSCFG_EXTISS3_EXTI12_SS BIT(0) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,5) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,9) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,13) /*!< EXTI 15 configuration */ + +/* SYSCFG_CFG1 bits definitions */ +#define SYSCFG_CFG1_LOCKUP_LOCK BIT(0) /*!< Cortex-M23 LOCKUP output lock */ +#define SYSCFG_CFG1_SRAM_ECC_LOCK BIT(1) /*!< SRAM ecc check error lock */ + +/* SYSCFG_STAT bits definitions */ +#define SYSCFG_STAT_ECCMEIF BIT(0) /*!< SRAM two bits non-correction event flag */ +#define SYSCFG_STAT_ECCSEIF BIT(1) /*!< SRAM single bit correction event flag */ + +/* SYSCFG_CFG2 bits definitions */ +#define SYSCFG_CFG2_LXTALCSS_IE BIT(1) /*!< LXTAL clock stuck interrupt enable */ +#define SYSCFG_CFG2_HXTALCSS_IE BIT(2) /*!< HXTAL clock stuck interrupt enable */ +#define SYSCFG_CFG2_ECCMEIE BIT(3) /*!< Multi-bits (two bits) non-correction error NMI interrupt enable */ +#define SYSCFG_CFG2_ECCSEIE BIT(4) /*!< Single bit correction error interrupt enable */ +#define SYSCFG_ECCSERRBITS BITS(10,15) /*!< Indicates the error bit */ +#define SYSCFG_ECCEADDR BITS(20,31) /*!< Indicates the last ECC event on SRAM occurred */ + +/* SYSCFG_CPU_IRQ_LAT bits definitions */ +#define SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY BITS(0,7) /*!< IRQ_LATENCY specifies the minimum number of cycles between an interrupt */ + +/* SYSCFG_TIMERxCFG bits definitions */ +#define SYSCFG_TSCFG0 BITS(0,2) /*!< Quadrature decoder mode 0 configuration */ +#define SYSCFG_TSCFG1 BITS(4,6) /*!< Quadrature decoder mode 1 configuration */ +#define SYSCFG_TSCFG2 BITS(8,10) /*!< Quadrature decoder mode 2 configuration */ +#define SYSCFG_TSCFG3 BITS(12,14) /*!< Restart mode configuration */ +#define SYSCFG_TSCFG4 BITS(16,18) /*!< Pause mode configuration */ +#define SYSCFG_TSCFG5 BITS(20,22) /*!< Event mode configuration */ +#define SYSCFG_TSCFG6 BITS(24,26) /*!< External clock mode 0 configuration */ +#define SYSCFG_TSCFG7 BITS(28,30) /*!< Restart event configuration */ +#define SYSCFG_TSCFG8 BITS(0,2) /*!< Internal trigger input source configuration */ + +/* constants definitions */ +/* boot mode definitions */ +#define SYSCFG_BOOTMODE_FLASH ((uint8_t)0x00U) /*!< boot from main flash */ +#define SYSCFG_BOOTMODE_SYSTEM ((uint8_t)0x01U) /*!< boot from system flash memory */ +#define SYSCFG_BOOTMODE_SRAM ((uint8_t)0x03U) /*!< boot from embedded SRAM */ + +/* EXTI source select definition */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select register 0 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select register 1 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select register 2 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select register 3 */ + +/* EXTI source select mask bits definition */ +#define EXTI_SS_MASK BITS(0,3) /*!< EXTI source select mask */ + +/* EXTI source select jumping step definition */ +#define EXTI_SS_JSTEP ((uint8_t)(0x04U)) /*!< EXTI source select jumping step */ + +/* EXTI source select moving step definition */ +#define EXTI_SS_MSTEP(pin) (EXTI_SS_JSTEP * ((pin) % EXTI_SS_JSTEP)) /*!< EXTI source select moving step */ + +/* EXTI source port definitions */ +#define EXTI_SOURCE_GPIOA ((uint8_t)0x00U) /*!< EXTI GPIOA configuration */ +#define EXTI_SOURCE_GPIOB ((uint8_t)0x01U) /*!< EXTI GPIOB configuration */ +#define EXTI_SOURCE_GPIOC ((uint8_t)0x02U) /*!< EXTI GPIOC configuration */ +#define EXTI_SOURCE_GPIOD ((uint8_t)0x03U) /*!< EXTI GPIOD configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ + +/* EXTI 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 */ + +/* SYSCFG_CPU_IRQ_LAT register IRQ_LATENCY value */ +#define IRQ_LATENCY(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to IRQ_LATENCY bits field */ + +/* SYSCFG_CFG3 register pinmux bits definitions*/ +#define SYSCFG_CFG3_PIN1_SOP8(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define SYSCFG_CFG3_PIN4_SOP8(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) +#define SYSCFG_CFG3_PIN5_SOP8(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define SYSCFG_CFG3_PIN8_SOP8(regval) (BITS(6,7) & ((uint32_t)(regval) << 6U)) +#define SYSCFG_CFG3_PIN5_TSSOP16(regval) (BITS(8,9) & ((uint32_t)(regval) << 8U)) +#define SYSCFG_CFG3_PIN9_TSSOP16(regval) (BITS(10,11) & ((uint32_t)(regval) << 10U)) +#define SYSCFG_CFG3_PIN11_TSSOP16(regval) (BITS(12,13) & ((uint32_t)(regval) << 12U)) +#define SYSCFG_CFG3_PIN12_TSSOP16(regval) (BITS(14,15) & ((uint32_t)(regval) << 13U)) + +#define SYSCFG_TIMER0 ((uint8_t)0x00U) +#define SYSCFG_TIMER2 ((uint8_t)0x01U) + +/* Quadrature decoder mode configuration bits definitions */ +#define TIMER_DECODER_MODE_DISABLE ((uint8_t)0x00U) /*!< Quadrature decoder mode disable */ +#define TIMER_COUNT_CI0FE0_EDGE (SYSCFG_TSCFG0 << 0U) /*!< The counter counts on CI0FE0 edge, while the direction depends on CI1FE1 level */ +#define TIMER_COUNT_CI1FE1_EDGE (SYSCFG_TSCFG1 << 4U) /*!< The counter counts on CI1FE1 edge, while the direction depends on CI0FE0 level */ +#define TIMER_COUNT_CI0FE0_CI1FE1_EDGE (SYSCFG_TSCFG2 << 8U) /*!< The counter counts on both CI0FE0 and CI1FE1 edge, while the direction depends on each other */ + +/* Restart mode configuration bits definitions */ +#define SYSCFG_TIMER_RESTART_MODE_CONFIG(regval) (SYSCFG_TSCFG3 & ((uint32_t)(regval) << 12U)) +#define TIMER_RESTART_MODE_DISABLE SYSCFG_TIMER_RESTART_MODE_CONFIG(0) /*!< Restart mode disable */ +#define TIMER_RESTART_MODE_TRIGGER_ITI0 SYSCFG_TIMER_RESTART_MODE_CONFIG(1) /*!< Internal trigger input 0 */ +#define TIMER_RESTART_MODE_TRIGGER_ITI2 SYSCFG_TIMER_RESTART_MODE_CONFIG(2) /*!< Internal trigger input 2 */ +#define TIMER_RESTART_MODE_TRIGGER_ITI3 SYSCFG_TIMER_RESTART_MODE_CONFIG(3) /*!< Internal trigger input 3 */ +#define TIMER_RESTART_MODE_TRIGGER_CI0F_ED SYSCFG_TIMER_RESTART_MODE_CONFIG(4) /*!< CI0 edge flag */ +#define TIMER_RESTART_MODE_TRIGGER_CI0FE0 SYSCFG_TIMER_RESTART_MODE_CONFIG(5) /*!< The filtered output of channel 0 input */ +#define TIMER_RESTART_MODE_TRIGGER_CI1FE1 SYSCFG_TIMER_RESTART_MODE_CONFIG(6) /*!< The filtered output of channel 1 input */ +#define TIMER_RESTART_MODE_TRIGGER_ETIFP SYSCFG_TIMER_RESTART_MODE_CONFIG(7) /*!< The filtered output of external trigger input */ + +/* Pause mode configuration bits definitions */ +#define SYSCFG_TIMER_PAUSE_MODE_CONFIG(regval) (SYSCFG_TSCFG4 & ((uint32_t)(regval) << 16)) +#define TIMER_PAUSE_MODE_DISABLE SYSCFG_TIMER_PAUSE_MODE_CONFIG(0) /*!< Pause mode disable */ +#define TIMER_PAUSE_MODE_TRIGGER_ITI0 SYSCFG_TIMER_PAUSE_MODE_CONFIG(1) /*!< Internal trigger input 0 */ +#define TIMER_PAUSE_MODE_TRIGGER_ITI2 SYSCFG_TIMER_PAUSE_MODE_CONFIG(2) /*!< Internal trigger input 2 */ +#define TIMER_PAUSE_MODE_TRIGGER_ITI3 SYSCFG_TIMER_PAUSE_MODE_CONFIG(3) /*!< Internal trigger input 3 */ +#define TIMER_PAUSE_MODE_TRIGGER_CI0F_ED SYSCFG_TIMER_PAUSE_MODE_CONFIG(4) /*!< CI0 edge flag */ +#define TIMER_PAUSE_MODE_TRIGGER_CI0FE0 SYSCFG_TIMER_PAUSE_MODE_CONFIG(5) /*!< The filtered output of channel 0 input */ +#define TIMER_PAUSE_MODE_TRIGGER_CI1FE1 SYSCFG_TIMER_PAUSE_MODE_CONFIG(6) /*!< The filtered output of channel 1 input */ +#define TIMER_PAUSE_MODE_TRIGGER_ETIFP SYSCFG_TIMER_PAUSE_MODE_CONFIG(7) /*!< The filtered output of external trigger input */ + +/* Event mode configuration bits definitions */ +#define SYSCFG_TIMER_EVENT_MODE_CONFIG(regval) (SYSCFG_TSCFG5 & ((uint32_t)(regval) << 20)) +#define TIMER_EVENT_MODE_DISABLE SYSCFG_TIMER_EVENT_MODE_CONFIG(0) /*!< Event mode disable */ +#define TIMER_EVENT_MODE_TRIGGER_ITI0 SYSCFG_TIMER_EVENT_MODE_CONFIG(1) /*!< Internal trigger input 0 */ +#define TIMER_EVENT_MODE_TRIGGER_ITI2 SYSCFG_TIMER_EVENT_MODE_CONFIG(2) /*!< Internal trigger input 2 */ +#define TIMER_EVENT_MODE_TRIGGER_ITI3 SYSCFG_TIMER_EVENT_MODE_CONFIG(3) /*!< Internal trigger input 3 */ +#define TIMER_EVENT_MODE_TRIGGER_CI0F_ED SYSCFG_TIMER_EVENT_MODE_CONFIG(4) /*!< CI0 edge flag */ +#define TIMER_EVENT_MODE_TRIGGER_CI0FE0 SYSCFG_TIMER_EVENT_MODE_CONFIG(5) /*!< The filtered output of channel 0 input */ +#define TIMER_EVENT_MODE_TRIGGER_CI1FE1 SYSCFG_TIMER_EVENT_MODE_CONFIG(6) /*!< The filtered output of channel 1 input */ +#define TIMER_EVENT_MODE_TRIGGER_ETIFP SYSCFG_TIMER_EVENT_MODE_CONFIG(7) /*!< The filtered output of external trigger input */ + +/* External clock mode 0 configuration bits definitions */ +#define SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(regval) (SYSCFG_TSCFG6 & ((uint32_t)(regval) << 24)) +#define TIMER_EXT_CLOCK_MODE0_DISABLE SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(0) /*!< External clock mode 0 disable */ +#define TIMER_EXT_CLOCK_MODE0_SOURCE_ITI0 SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(1) /*!< Internal trigger input 0 */ +#define TIMER_EXT_CLOCK_MODE0_SOURCE_ITI2 SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(2) /*!< Internal trigger input 2 */ +#define TIMER_EXT_CLOCK_MODE0_SOURCE_ITI3 SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(3) /*!< Internal trigger input 3 */ +#define TIMER_EXT_CLOCK_MODE0_SOURCE_CI0F_ED SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(4) /*!< CI0 edge flag */ +#define TIMER_EXT_CLOCK_MODE0_SOURCE_CI0FE0 SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(5) /*!< The filtered output of channel 0 input */ +#define TIMER_EXT_CLOCK_MODE0_SOURCE_CI1FE1 SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(6) /*!< The filtered output of channel 1 input */ +#define TIMER_EXT_CLOCK_MODE0_SOURCE_ETIFP SYSCFG_TIMER_EXT_CLOCK_MODE0_CONFIG(7) /*!< The filtered output of external trigger input */ + +/* Channel restart event configuration bits definitions */ +#define SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(regval) (SYSCFG_TSCFG7 & ((uint32_t)(regval) << 28)) +#define TIMER_CHANNEL_INPUT_SOURCE_DIS SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(0) /*!< Restart + event mode disable */ +#define TIMER_CHANNEL_INPUT_SOURCE_ITI0 SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(1) /*!< Internal trigger input 0 */ +#define TIMER_CHANNEL_INPUT_SOURCE_ITI2 SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(2) /*!< Internal trigger input 2 */ +#define TIMER_CHANNEL_INPUT_SOURCE_ITI3 SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(3) /*!< Internal trigger input 3 */ +#define TIMER_CHANNEL_INPUT_SOURCE_CI0F_ED SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(4) /*!< CI0 edge flag */ +#define TIMER_CHANNEL_INPUT_SOURCE_CI0FE0 SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(5) /*!< The filtered output of channel 0 input */ +#define TIMER_CHANNEL_INPUT_SOURCE_CI1FE1 SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(6) /*!< The filtered output of channel 1 input */ +#define TIMER_CHANNEL_INPUT_SOURCE_ETIFP SYSCFG_TIMER_CHANNEL_INPUT_SOURCE_CONFIG(7) /*!< The filtered output of external trigger input */ + +/* Internal trigger input source configuration bits definitions */ +#define SYSCFG_TIMER_TRIG_INPUT_SOURCE_CONFIG(regval) (SYSCFG_TSCFG8 & ((uint32_t)(regval) << 0)) +#define TIMER_TRIG_INPUT_SOURCE_ITI0 SYSCFG_TIMER_TRIG_INPUT_SOURCE_CONFIG(1) /*!< Internal trigger input 0 */ +#define TIMER_TRIG_INPUT_SOURCE_ITI2 SYSCFG_TIMER_TRIG_INPUT_SOURCE_CONFIG(3) /*!< Internal trigger input 2 */ +#define TIMER_TRIG_INPUT_SOURCE_ITI3 SYSCFG_TIMER_TRIG_INPUT_SOURCE_CONFIG(4) /*!< Internal trigger input 3 */ +#define TIMER_TRIG_INPUT_SOURCE_CI0F_ED SYSCFG_TIMER_TRIG_INPUT_SOURCE_CONFIG(5) /*!< CI0 edge flag */ + +/* SYSCFG pin I2C Fm+ mode */ +#define SYSCFG_PB6_FMPEN SYSCFG_CFG0_PB6_FMPEN /*!< I2C Fm+ mode on PB6 pin enable */ +#define SYSCFG_PB7_FMPEN SYSCFG_CFG0_PB7_FMPEN /*!< I2C Fm+ mode on PB7 pin enable */ +#define SYSCFG_PB8_FMPEN SYSCFG_CFG0_PB8_FMPEN /*!< I2C Fm+ mode on PB8 pin enable */ +#define SYSCFG_PB9_FMPEN SYSCFG_CFG0_PB9_FMPEN /*!< I2C Fm+ mode on PB9 pin enable */ +#define SYSCFG_I2C0_FMPEN SYSCFG_CFG0_I2C0_FMPEN /*!< Fast Mode Plus (FM+) enable for I2C0 */ +#define SYSCFG_PA9_FMPEN SYSCFG_CFG0_PA9_FMPEN /*!< I2C Fm+ mode on PA9 pin enable */ +#define SYSCFG_PA10_FMPEN SYSCFG_CFG0_PA10_FMPEN /*!< I2C Fm+ mode on PA10 pin enable */ +#define SYSCFG_PC14_FMPEN SYSCFG_CFG0_PC14_FMPEN /*!< I2C Fm+ mode on PC14 pin enable */ + +/* SYSCFG module lockup */ +#define SYSCFG_LOCKUP_LOCK SYSCFG_CFG1_LOCKUP_LOCK /*!< CPU lockup signal connected */ +#define SYSCFG_SRAM_LOCKUP SYSCFG_CFG1_SRAM_ECC_LOCK /*!< SRAM ECC check error signal connected */ + +/* SYSCFG flags */ +#define SYSCFG_FLAG_ECCME SYSCFG_STAT_ECCMEIF /*!< SRAM two bits non-correction event flag */ +#define SYSCFG_FLAG_ECCSE SYSCFG_STAT_ECCSEIF /*!< SRAM single bit correction event flag */ + +/* function declarations */ +/* initialization functions */ +/* reset the SYSCFG registers */ +void syscfg_deinit(void); + +/* enable I2C Fm+ mode */ +void syscfg_i2c_fast_mode_plus_enable(uint32_t syscfg_gpio); +/* disable I2C Fm+ mode */ +void syscfg_i2c_fast_mode_plus_disable(uint32_t syscfg_gpio); + +/* enable remap pin function for small packages */ +void syscfg_pin_remap_enable(uint32_t remap_pin); +/* disable remap pin function for small packages */ +void syscfg_pin_remap_disable(uint32_t remap_pin); + +/* get the boot mode */ +uint8_t syscfg_bootmode_get(void); + +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); + +/* enable module lockup */ +void syscfg_lockup_enable(uint32_t lockup); + +/* get SRAM ECC single correctable bit */ +uint32_t syscfg_sram_ecc_single_correctable_bit_get(void); +/* get SRAM ECC error address */ +uint32_t syscfg_sram_ecc_error_address_get(void); + +/* set the IRQ_LATENCY value */ +void syscfg_irq_latency_set(uint32_t irq_latency); + +/* enable interrupt */ +void syscfg_interrupt_enable(uint32_t interrupt); +/* disable interrupt */ +void syscfg_interrupt_disable(uint32_t interrupt); +/* interrupt flag get */ +FlagStatus syscfg_interrupt_flag_get(uint32_t flag); +/* interrupt flag clear */ +void syscfg_interrupt_flag_clear(uint32_t flag); + +#endif /* gd32c2x1_SYSCFG_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_timer.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_timer.h new file mode 100644 index 0000000..56930fc --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_timer.h @@ -0,0 +1,842 @@ +/*! + \file gd32c2x1_timer.h + \brief definitions for the TIMER + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_TIMER_H +#define GD32C2X1_TIMER_H + +#include "gd32c2x1.h" + +/* TIMERx(x=0,2,13,15,16) definitions */ +#define TIMER0 (TIMER_BASE + 0x00012C00U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER13 (TIMER_BASE + 0x00002000U) +#define TIMER15 (TIMER_BASE + 0x00014400U) +#define TIMER16 (TIMER_BASE + 0x00014800U) + +/* 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_CHCTL3(timerx) REG32((timerx) + 0x54U) /*!< TIMER channel control register 3 */ +#define TIMER_CH4CV(timerx) REG32((timerx) + 0x58U) /*!< TIMER channel 4 capture/compare value register */ +#define TIMER_AFCTL0(timerx) REG32((timerx) + 0x60U) /*!< TIMER alternate function control register 0 */ +#define TIMER_AFCTL1(timerx) REG32((timerx) + 0x64U) /*!< TIMER alternate function control register 1 */ +#define TIMER_INSEL(timerx) REG32((timerx) + 0x68U) /*!< TIMER input selection 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 */ +#define TIMER_CTL1_ISO4 BIT(16) /*!< idle state of channel 4 output */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 capture/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 capture/compare DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 capture/compare DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 capture/compare DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 capture/compare 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_BRK0IF BIT(7) /*!< break 0 interrupt flag */ +#define TIMER_INTF_BRK1IF BIT(8) /*!< break 1 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 */ +#define TIMER_INTF_SYSBIF BIT(13) /*!< System source break interrupt flag */ +#define TIMER_INTF_CH4IF BIT(16) /*!< channel 4 compare interrupt flag */ +/* TIMER_SWEVG */ +#define TIMER_SWEVG_UPG BIT(0) /*!< update event generate */ +#define TIMER_SWEVG_CH0G BIT(1) /*!< channel 0 capture or compare event generation */ +#define TIMER_SWEVG_CH1G BIT(2) /*!< channel 1 capture or compare event generation */ +#define TIMER_SWEVG_CH2G BIT(3) /*!< channel 2 capture or compare event generation */ +#define TIMER_SWEVG_CH3G BIT(4) /*!< channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CMTG BIT(5) /*!< channel commutation event generation */ +#define TIMER_SWEVG_TRGG BIT(6) /*!< trigger event generation */ +#define TIMER_SWEVG_BRK0G BIT(7) /*!< break 0 event generation */ +#define TIMER_SWEVG_BRK1G BIT(8) /*!< break 1 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) | BIT(16)) /*!< channel 0 output compare control */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS BITS(8,9) /*!< 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) | BIT(24)) /*!< channel 1 output compare control */ + +#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) | BIT(16)) /*!< channel 2 output compare control */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS BITS(8,9) /*!< 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) | BIT(24)) /*!< channel 3 output compare control */ + +#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 */ +#define TIMER_CHCTL2_CH3NP BIT(15) /*!< channel 3 complementary output polarity */ +#define TIMER_CHCTL2_CH4EN BIT(16) /*!< channel 4 capture/compare function enable */ +#define TIMER_CHCTL2_CH4P BIT(17) /*!< channel 4 capture/compare function polarity */ + +/* TIMER_CNT */ +#define TIMER_CNT_CNT BITS(0,15) /*!< timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL BITS(0,15) /*!< counter auto reload value */ + +/* TIMER_CREP */ +#define TIMER_CREP_CREP BITS(0,15) /*!< counter repetition value */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL BITS(0,15) /*!< capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL BITS(0,15) /*!< capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL BITS(0,15) /*!< capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL BITS(0,15) /*!< 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_BRK0EN BIT(12) /*!< break0 input signal enable */ +#define TIMER_CCHP_BRK0P BIT(13) /*!< break0 input signal polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ +#define TIMER_CCHP_BRK0F BITS(16,19) /*!< break0 input signal filter */ +#define TIMER_CCHP_BRK1F BITS(20,23) /*!< break1 input signal filter */ +#define TIMER_CCHP_BRK1EN BIT(24) /*!< break1 input signal enable */ +#define TIMER_CCHP_BRK1P BIT(25) /*!< break1 input signal polarity */ + +/* 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_CHCTL3 */ +#define TIMER_CHCTL3_CH4COMFEN BIT(2) /*!< channel 4 output compare fast enable */ +#define TIMER_CHCTL3_CH4COMSEN BIT(3) /*!< channel 4 output compare shadow enable */ +#define TIMER_CHCTL3_CH4COMCTL (BITS(4,6) | BIT(16)) /*!< channel 4 output compare control */ +#define TIMER_CHCTL3_CH4COMCEN BIT(7) /*!< channel 4 output compare clear enable */ + +/* TIMER_CH4CV */ +#define TIMER_CH4CV_CH4VAL BITS(0,15) /*!< capture/compare value of channel 4 */ +#define TIMER_CH4CV_CCH4CH0 BIT(29) /*!< Combine Channel 4 and Channel 0 */ +#define TIMER_CH4CV_CCH4CH1 BIT(30) /*!< Combine Channel 4 and Channel 1 */ +#define TIMER_CH4CV_CCH4CH2 BIT(31) /*!< Combine Channel 4 and Channel 2 */ + +/* TIMER_AFCTL0 */ +#define TIMER_AFCTL0_BRK0INEN BIT(0) /*!< break0 BRKIN input enable */ +#define TIMER_AFCTL0_BRK0INP BIT(9) /*!< break0 BRKIN input polarity */ +#define TIMER_AFCTL0_ETISEL BITS(14,17) /*!< ETI source selection */ + +/* TIMER_AFCTL1 */ +#define TIMER_AFCTL1_BRK1INEN BIT(0) /*!< break1 BRKIN input enable */ +#define TIMER_AFCTL1_BRK1INP BIT(9) /*!< break1 BRKIN input polarity */ + +/* TIMER_INSEL */ +#define TIMER_INSEL_CI0_SEL BITS(0,3) /*!< CH0 input selection */ +#define TIMER_INSEL_CI1_SEL BITS(8,11) /*!< CH1 input selection */ + +/* 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 */ + uint32_t period; /*!< period value */ + uint16_t clockdivision; /*!< clock division value */ + uint16_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 */ + uint32_t break0state; /*!< BREAK0 input enable */ + uint32_t break0filter; /*!< BREAK0 input filter */ + uint32_t break0polarity; /*!< BREAK0 input polarity */ + uint32_t break1state; /*!< BREAK1 input enable */ + uint32_t break1filter; /*!< BREAK1 input filter */ + uint32_t break1polarity; /*!< BREAK1 input polarity */ +}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_CH4 TIMER_INTF_CH4IF /*!< 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_BRK0 TIMER_INTF_BRK0IF /*!< break0 flag */ +#define TIMER_FLAG_BRK1 TIMER_INTF_BRK1IF /*!< break0 flag */ +#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */ +#define TIMER_FLAG_SYSB TIMER_INTF_SYSBIF /*!< system source break flag */ + +/* 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_BRK0 TIMER_INTF_BRK0IF /*!< break 0 flag */ +#define TIMER_INT_FLAG_BRK1 TIMER_INTF_BRK1IF /*!< break 1 flag */ +#define TIMER_INT_FLAG_SYSB TIMER_INTF_SYSBIF /*!< system source break interrupt flag */ + +/* 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 ((uint32_t)0x00000000U) /*!< DMA request of channel y is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint32_t)0x00000001U) /*!< 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_BRK0G ((uint16_t)0x0080U) /*!< break event generation */ +#define TIMER_EVENT_SRC_BRK1G ((uint16_t)0x0100U) /*!< BREAK1 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, he 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_BREAK0_ENABLE ((uint32_t)TIMER_CCHP_BRK0EN) /*!< break 0 input enable */ +#define TIMER_BREAK0_DISABLE ((uint32_t)0x0000U) /*!< break 0 input disable */ + +/* BREAK0 input signal polarity */ +#define TIMER_BREAK0_POLARITY_LOW ((uint32_t)0x00000000U) /*!< BREAK0 input signal polarity is low */ +#define TIMER_BREAK0_POLARITY_HIGH ((uint32_t)TIMER_CCHP_BRK0P) /*!< BREAK0 input signal polarity is high */ + +/* BREAK1 input signal enable */ +#define TIMER_BREAK1_ENABLE ((uint32_t)TIMER_CCHP_BRK1EN) /*!< BREAK1 input signal enable */ +#define TIMER_BREAK1_DISABLE ((uint32_t)0x00000000U) /*!< BREAK1 input signal disable */ + +/* BREAK1 input signal polarity */ +#define TIMER_BREAK1_POLARITY_LOW ((uint32_t)0x00000000U) /*!< BREAK1 input signal polarity is low */ +#define TIMER_BREAK1_POLARITY_HIGH ((uint32_t)TIMER_CCHP_BRK1P) /*!< BREAK1 input signal polarity is high */ + +/* TIMER BREAK0/BREAK1 */ +#define TIMER_BREAK0 ((uint16_t)0x0000U) /*!< TIMER BREAK0 */ +#define TIMER_BREAK1 ((uint16_t)0x0001U) /*!< TIMER BREAK1 */ + +/* TIMER break input enable */ +#define TIMER_BRKxINEN TIMER_AFCTL0_BRK0INEN /*!< BREAKx BRKIN0 alternate function input enable */ + +/* TIMER external break input polarity */ +#define TIMER_BRKxINP TIMER_AFCTL0_BRK0INP /*!< BREAKx BRKIN0 polarity */ + +/* TIMER break external input polarity*/ +#define TIMER_BRKIN_POLARITY_LOW ((uint16_t)0x0000U) /*!< TIMER break external input signal will not be inverted */ +#define TIMER_BRKIN_POLARITY_HIGH ((uint16_t)0x0001U) /*!< TIMER break external input signal will be inverted */ + +/* TIMER channel n(n=0,2,13,15,16) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel 0(TIMERx(x=0,2,13,15,16)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1(TIMERx(x=0,2)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2(TIMERx(x=0,2)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3(TIMERx(x=0,2)) */ +#define TIMER_CH_4 ((uint16_t)0x0004U) /*!< TIMER channel 3(TIMERx(x=0)) */ + +/* channel enable state */ +#define TIMER_CCX_ENABLE ((uint16_t)0x0001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint16_t)0x0000U) /*!< channel disable */ + +/* channel complementary output enable state */ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* channel combined 3 phase state */ +#define TIMER_COMBINE_CHANNEL_ENABLE ((uint16_t)0x0001U) /*!< channel combined enable */ +#define TIMER_COMBINE_CHANNEL_DISABLE ((uint16_t)0x0000U) /*!< channel combined 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 ((uint32_t )0x00000000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint32_t )0x00000010U) /*!!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint32_t )0x00000020U) /*!!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint32_t )0x00000030U) /*!!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint32_t )0x00000040U) /*!!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint32_t )0x00000050U) /*!!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint32_t )0x00000060U) /*!!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint32_t )0x00000070U) /*!!< PWM1 mode*/ +#define TIMER_OC_MODE_DELAYABLE_SPM0 ((uint32_t )0x00010000U) /*!!< Delayable SPM mode 0*/ +#define TIMER_OC_MODE_DELAYABLE_SPM1 ((uint32_t )0x00010010U) /*!!< Delayable SPM mode 1*/ +#define TIMER_OC_MODE_COMBINED_PWM0 ((uint32_t )0x00010040U) /*!!< Combined PWM mode 0 */ +#define TIMER_OC_MODE_COMBINED_PWM1 ((uint32_t )0x00010050U) /*!!< Combined PWM mode 1*/ +#define TIMER_OC_MODE_ASYMMETRIC_PWM0 ((uint32_t )0x00010060U) /*!!< Asymmetric PWM mode 0*/ +#define TIMER_OC_MODE_ASYMMETRIC_PWM1 ((uint32_t )0x00010070U) /*!!< Asymmetric PWM mode 1*/ + +/* 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 */ + +/* timer trigger source select definition */ +#define TIMER_SMCFG_TRGSEL_NONE ((uint8_t)0x00U) /*!< internal trigger disable */ +#define TIMER_SMCFG_TRGSEL_ITI0 ((uint8_t)0x01U) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI2 ((uint8_t)0x02U) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 ((uint8_t)0x03U) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED ((uint8_t)0x04U) /*!< TI0 edge detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 ((uint8_t)0x05U) /*!< filtered TIMER input 0 */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 ((uint8_t)0x06U) /*!< filtered TIMER input 1 */ +#define TIMER_SMCFG_TRGSEL_ETIFP ((uint8_t)0x07U) /*!< 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 channel 0 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 */ + +/* timer trigger mode select definition */ +#define TIMER_QUAD_DECODER_MODE0 ((uint8_t)0x00U) /*!< quadrature decoder mode 0 */ +#define TIMER_QUAD_DECODER_MODE1 ((uint8_t)0x01U) /*!< quadrature decoder mode 1 */ +#define TIMER_QUAD_DECODER_MODE2 ((uint8_t)0x02U) /*!< quadrature decoder mode 2 */ +#define TIMER_SLAVE_MODE_RESTART ((uint8_t)0x03U) /*!< restart mode */ +#define TIMER_SLAVE_MODE_PAUSE ((uint8_t)0x04U) /*!< pause mode */ +#define TIMER_SLAVE_MODE_EVENT ((uint8_t)0x05U) /*!< event mode */ +#define TIMER_SLAVE_MODE_EXTERNAL0 ((uint8_t)0x06U) /*!< external clock mode 0 */ +#define TIMER_SLAVE_MODE_RESTART_EVENT ((uint8_t)0x07U) /*!< slave mode disable */ +#define TIMER_SLAVE_MODE_DISABLE ((uint8_t)0x08U) /*!< slave mode disable */ + +/* 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 */ + +/* ETI source selection */ +#define AFCTL0(regval) (BITS(14, 17) & ((uint32_t)(regval) << 14U)) +#define TIMER_ETI_LEGACY_MODE SMCFG_ETPSC(0) /*!< ETI legacy mode */ +#define TIMER_ETI_ADC_WD0_OUT SMCFG_ETPSC(3) /*!< ADC_WD0_OUT */ +#define TIMER_ETI_ADC_WD1_OUT SMCFG_ETPSC(4) /*!< ADC_WD1_OUT */ +#define TIMER_ETI_ADC_WD2_OUT SMCFG_ETPSC(5) /*!< ADC_WD2_OUT */ + +/* 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 */ + +/* the output value selection */ +#define TIMER_INSEL_CMPx ((uint16_t)0x0001U) /*!< output value selection enable */ +#define TIMER_INSEL_CHx ((uint16_t)0x0000U) /*!< output value selection disable */ + +/* TIMERx(x=0,2,13,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 gd32_timer_init(uint32_t timer_periph, timer_parameter_struct *initpara); +/* enable a TIMER */ +void timer_enable(uint32_t timer_periph); +/* disable a TIMER */ +void timer_disable(uint32_t timer_periph); +/* enable the auto reload shadow function */ +void timer_auto_reload_shadow_enable(uint32_t timer_periph); +/* disable the auto reload shadow function */ +void timer_auto_reload_shadow_disable(uint32_t timer_periph); +/* enable the update event */ +void timer_update_event_enable(uint32_t timer_periph); +/* disable the update event */ +void timer_update_event_disable(uint32_t timer_periph); +/* set TIMER counter alignment mode */ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned); +/* set TIMER counter up direction */ +void timer_counter_up_direction(uint32_t timer_periph); +/* set TIMER counter down direction */ +void timer_counter_down_direction(uint32_t timer_periph); + +/* configure TIMER prescaler */ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint32_t pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition); +/* configure TIMER autoreload register value */ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload); +/* configure TIMER counter register value */ +void timer_counter_value_config(uint32_t timer_periph, uint16_t counter); +/* read TIMER counter value */ +uint16_t timer_counter_read(uint32_t timer_periph); +/* read TIMER prescaler value */ +uint16_t timer_prescaler_read(uint32_t timer_periph); +/* configure TIMER single pulse mode */ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint32_t update); + +/* TIMER DMA and event */ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_t dma_request); +/* configure the TIMER DMA transfer */ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth); +/* software generate events */ +void timer_event_software_generate(uint32_t timer_periph, uint32_t event); + +/* TIMER channel complementary protection */ +/* initialize TIMER break parameter struct */ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara); +/* configure TIMER break function */ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara); +/* enable TIMER break function */ +void timer_break_enable(uint32_t timer_periph, uint16_t break_num); +/* disable TIMER break function */ +void timer_break_disable(uint32_t timer_periph, uint16_t break_num); +/* enable TIMER output automatic function */ +void timer_automatic_output_enable(uint32_t timer_periph); +/* disable TIMER output automatic function */ +void timer_automatic_output_disable(uint32_t timer_periph); +/* 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, uint32_t ccuctl); + +/* TIMER channel output */ +/* initialize TIMER channel output parameter struct */ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara); +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct *ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint32_t ocmode); +/* configure TIMER channel output combined 3 phase pwm mode */ +void timer_channel_combined_3_phase_pwm_config(uint32_t timer_periph, uint16_t channel, uint32_t state); +/* 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 */ +uint16_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 mode */ +/* 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 outtrigger); +/* 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 input selection */ +void timer_input_selection_config(uint32_t timer_periph, uint16_t channel, uint16_t insel); +/* TIMER configure */ +/* configure TIMER write CHxVAL register selection */ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel); +/* configure TIMER output value selection */ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel); +/* configure the TIMER break source */ +void timer_break_external_source_config(uint32_t timer_periph, uint16_t break_num, ControlStatus newvalue); +/* TIMER break external inputs */ +/* configure TIMER break polarity */ +void timer_break_external_polarity_config(uint32_t timer_periph, uint16_t break_num, uint16_t bkinpolarity); +/* configure TIMER eti source */ +void timer_eti_source_selection_config(uint32_t timer_periph, uint32_t eti_source); + +/* TIMER interrupt and flag*/ +/* get TIMER flags */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flags */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get timer interrupt flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t int_flag); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t int_flag); + +#endif /* gd32c2x1_TIMER_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_usart.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_usart.h new file mode 100644 index 0000000..1e227df --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_usart.h @@ -0,0 +1,618 @@ +/*! + \file gd32c2x1_usart.h + \brief definitions for the USART + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_USART_H +#define GD32C2X1_USART_H + +#include "gd32c2x1.h" + +/* USARTx(x=0,1,2) definitions */ +#define USART0 (USART_BASE + 0x0000F400U) +#define USART1 USART_BASE +#define USART2 (USART_BASE + 0x00000400U) + +/* registers definitions */ +#define USART_CTL0(usartx) REG32((usartx) + 0x00000000U) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x00000004U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x00000008U) /*!< USART control register 2 */ +#define USART_BAUD(usartx) REG32((usartx) + 0x0000000CU) /*!< USART baud rate register */ +#define USART_GP(usartx) REG32((usartx) + 0x00000010U) /*!< USART guard time and prescaler register */ +#define USART_RT(usartx) REG32((usartx) + 0x00000014U) /*!< USART receiver timeout register */ +#define USART_CMD(usartx) REG32((usartx) + 0x00000018U) /*!< USART command register */ +#define USART_STAT(usartx) REG32((usartx) + 0x0000001CU) /*!< USART status register */ +#define USART_INTC(usartx) REG32((usartx) + 0x00000020U) /*!< USART status clear register */ +#define USART_RDATA(usartx) REG32((usartx) + 0x00000024U) /*!< USART receive data register */ +#define USART_TDATA(usartx) REG32((usartx) + 0x00000028U) /*!< USART transmit data register */ +#define USART_CHC(usartx) REG32((usartx) + 0x000000C0U) /*!< USART coherence control register */ +#define USART_RFCS(usartx) REG32((usartx) + 0x000000D0U) /*!< USART receive FIFO control and status register */ + +/* bits definitions */ +/* USARTx_CTL0 */ +#define USART_CTL0_UEN BIT(0) /*!< USART enable */ +#define USART_CTL0_UESM BIT(1) /*!< USART enable in deep-sleep 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 register 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 control enable */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_MEN BIT(13) /*!< mute mode enable */ +#define USART_CTL0_AMIE BIT(14) /*!< address match interrupt enable */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_DED BITS(16,20) /*!< driver enable deassertion time */ +#define USART_CTL0_DEA BITS(21,25) /*!< driver enable assertion time */ +#define USART_CTL0_RTIE BIT(26) /*!< receiver timeout interrupt enable */ +#define USART_CTL0_EBIE BIT(27) /*!< end of block interrupt enable */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDM BIT(4) /*!< address detection mode */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detection interrupt enable */ +#define USART_CTL1_CLEN BIT(8) /*!< last bit clock pulse */ +#define USART_CTL1_CPH BIT(9) /*!< clock phase */ +#define USART_CTL1_CPL BIT(10) /*!< clock polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< ck pin enable */ +#define USART_CTL1_STB BITS(12,13) /*!< stop bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ +#define USART_CTL1_STRP BIT(15) /*!< swap TX/RX pins */ +#define USART_CTL1_RINV BIT(16) /*!< RX pin level inversion */ +#define USART_CTL1_TINV BIT(17) /*!< TX pin level inversion */ +#define USART_CTL1_DINV BIT(18) /*!< data bit level inversion */ +#define USART_CTL1_MSBF BIT(19) /*!< most significant bit first */ +#define USART_CTL1_ABDEN BIT(20) /*!< auto baud rate enable */ +#define USART_CTL1_ABDM BITS(21,22) /*!< auto baud rate mode */ +#define USART_CTL1_RTEN BIT(23) /*!< receiver timeout enable */ +#define USART_CTL1_ADDR BITS(24,31) /*!< address of the USART terminal */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable in multibuffer communication */ +#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 enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA 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 mode */ +#define USART_CTL2_OVRD BIT(12) /*!< overrun disable */ +#define USART_CTL2_DDRE BIT(13) /*!< disable DMA on reception error */ +#define USART_CTL2_DEM BIT(14) /*!< driver enable mode */ +#define USART_CTL2_DEP BIT(15) /*!< driver enable polarity mode */ +#define USART_CTL2_SCRTNUM BITS(17,19) /*!< smartcard auto-retry number */ +#define USART_CTL2_WUM BITS(20,21) /*!< wakeup mode from deep-sleep mode */ +#define USART_CTL2_WUIE BIT(22) /*!< wakeup from deep-sleep mode interrupt enable */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer of baud-rate divider */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_CMD */ +#define USART_CMD_ABDCMD BIT(0) /*!< auto baudrate detection command */ +#define USART_CMD_SBKCMD BIT(1) /*!< send break command */ +#define USART_CMD_MMCMD BIT(2) /*!< mute mode command */ +#define USART_CMD_RXFCMD BIT(3) /*!< receive data flush command */ +#define USART_CMD_TXFCMD BIT(4) /*!< transmit data flush request */ + +/* USARTx_STAT */ +#define USART_STAT_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT_IDLEF BIT(4) /*!< idle line detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT_TC BIT(6) /*!< transmission completed */ +#define USART_STAT_TBE BIT(7) /*!< transmit data register empty */ +#define USART_STAT_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT_CTSF BIT(9) /*!< CTS change flag */ +#define USART_STAT_CTS BIT(10) /*!< CTS level */ +#define USART_STAT_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT_ABDE BIT(14) /*!< auto baudrate detection error */ +#define USART_STAT_ABDF BIT(15) /*!< auto baudrate detection flag */ +#define USART_STAT_BSY BIT(16) /*!< busy flag */ +#define USART_STAT_AMF BIT(17) /*!< address match flag */ +#define USART_STAT_SBF BIT(18) /*!< send break flag */ +#define USART_STAT_RWU BIT(19) /*!< receiver wakeup from mute mode */ +#define USART_STAT_WUF BIT(20) /*!< wakeup from deep-sleep mode flag */ +#define USART_STAT_TEA BIT(21) /*!< transmit enable acknowledge flag */ +#define USART_STAT_REA BIT(22) /*!< receive enable acknowledge flag */ + +/* USARTx_INTC */ +#define USART_INTC_PEC BIT(0) /*!< parity error clear */ +#define USART_INTC_FEC BIT(1) /*!< frame error flag clear */ +#define USART_INTC_NEC BIT(2) /*!< noise detected clear */ +#define USART_INTC_OREC BIT(3) /*!< overrun error clear */ +#define USART_INTC_IDLEC BIT(4) /*!< idle line detected clear */ +#define USART_INTC_TCC BIT(6) /*!< transmission complete clear */ +#define USART_INTC_LBDC BIT(8) /*!< LIN break detected clear */ +#define USART_INTC_CTSC BIT(9) /*!< CTS change clear */ +#define USART_INTC_RTC BIT(11) /*!< receiver timeout clear */ +#define USART_INTC_EBC BIT(12) /*!< end of timeout clear */ +#define USART_INTC_AMC BIT(17) /*!< address match clear */ +#define USART_INTC_WUC BIT(20) /*!< wakeup from deep-sleep mode clear */ + +/* USARTx_RDATA */ +#define USART_RDATA_RDATA BITS(0,8) /*!< receive data value */ + +/* USARTx_TDATA */ +#define USART_TDATA_TDATA BITS(0,8) /*!< transmit data value */ + +/* USARTx_CHC */ +#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ +#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ + +/* USARTx_RFCS */ +#define USART_RFCS_ELNACK BIT(0) /*!< early NACK */ +#define USART_RFCS_RFEN BIT(8) /*!< receive FIFO enable */ +#define USART_RFCS_RFFIE BIT(9) /*!< receive FIFO full interrupt enable */ +#define USART_RFCS_RFE BIT(10) /*!< receive FIFO empty flag */ +#define USART_RFCS_RFF BIT(11) /*!< receive FIFO full flag */ +#define USART_RFCS_RFCNT BITS(12,14) /*!< receive FIFO counter number */ +#define USART_RFCS_RFFINT BIT(15) /*!< receive FIFO full interrupt 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) & 0x0000FFFFU) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define USART_REG_VAL2(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 22))) +#define USART_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define USART_CTL0_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET ((uint32_t)0x00000004U) /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET ((uint32_t)0x00000008U) /*!< CTL2 register offset */ +#define USART_STAT_REG_OFFSET ((uint32_t)0x0000001CU) /*!< STAT register offset */ +#define USART_CHC_REG_OFFSET ((uint32_t)0x000000C0U) /*!< CHC register offset */ +#define USART_RFCS_REG_OFFSET ((uint32_t)0x000000D0U) /*!< RFCS register offset */ + +/* USART flags */ +typedef enum { + /* flags in STAT register */ + USART_FLAG_REA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 22U), /*!< receive enable acknowledge flag */ + USART_FLAG_TEA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 21U), /*!< transmit enable acknowledge flag */ + USART_FLAG_WU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 20U), /*!< wakeup from Deep-sleep mode flag */ + USART_FLAG_RWU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 19U), /*!< receiver wakeup from mute mode */ + USART_FLAG_SB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 18U), /*!< send break flag */ + USART_FLAG_AM = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 17U), /*!< ADDR match flag */ + USART_FLAG_BSY = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 16U), /*!< busy flag */ + USART_FLAG_ABDF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 15U), /*!< auto baudrate detection flag */ + USART_FLAG_ABDE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 14U), /*!< auto baudrate detection error */ + USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout flag */ + USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 10U), /*!< CTS level */ + USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit data buffer empty */ + USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty */ + USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 0U), /*!< parity error flag */ + /* flags in CHC register */ + USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U), /*!< early parity error flag */ + /* flags in RFCS register */ + USART_FLAG_RFFINT = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 15U), /*!< receive FIFO full interrupt flag */ + USART_FLAG_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 11U), /*!< receive FIFO full flag */ + USART_FLAG_RFE = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 10U) /*!< receive FIFO empty flag */ +} usart_flag_enum; + +/* USART interrupt flags */ +typedef enum { + /* interrupt flags in CTL0 register */ + USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 27U, USART_STAT_REG_OFFSET, 12U), /*!< end of block interrupt and flag */ + USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 26U, USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout interrupt and flag */ + USART_INT_FLAG_AM = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 14U, USART_STAT_REG_OFFSET, 17U), /*!< address match interrupt and flag */ + USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT_REG_OFFSET, 0U), /*!< parity error interrupt and flag */ + USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag */ + USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 6U), /*!< transmission complete interrupt and flag */ + USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and flag */ + USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag */ + USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected interrupt and flag */ + /* interrupt flags in CTL1 register */ + USART_INT_FLAG_LBD = USART_REGIDX_BIT2(USART_CTL1_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected interrupt and flag */ + /* interrupt flags in CTL2 register */ + USART_INT_FLAG_WU = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 22U, USART_STAT_REG_OFFSET, 20U), /*!< wakeup from deep-sleep mode interrupt and flag */ + USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT_REG_OFFSET, 9U), /*!< CTS interrupt and flag */ + USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 2U), /*!< error interrupt and noise error flag */ + USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 3U), /*!< error interrupt and overrun error */ + USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 1U), /*!< error interrupt and frame error flag */ + /* interrupt flags in RFCS register */ + USART_INT_FLAG_RFF = USART_REGIDX_BIT2(USART_RFCS_REG_OFFSET, 9U, USART_RFCS_REG_OFFSET, 15U) /*!< receive FIFO full interrupt and flag */ +} usart_interrupt_flag_enum; + +/* USART interrupt enable or disable */ +typedef enum { + /* interrupt in CTL0 register */ + USART_INT_EB = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 27U), /*!< end of block interrupt */ + USART_INT_RT = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 26U), /*!< receiver timeout interrupt */ + USART_INT_AM = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 14U), /*!< address match interrupt */ + USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ + USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */ + 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_WU = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 22U), /*!< wakeup from deep-sleep mode interrupt */ + USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */ + /* interrupt in RFCS register */ + USART_INT_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 9U) /*!< receive FIFO full interrupt */ +} usart_interrupt_enum; + +/* USART invert configure */ +typedef enum { + /* data bit level inversion */ + USART_DINV_ENABLE = 0, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ + /* swap TX/RX pins */ + USART_SWAP_ENABLE, /*!< swap TX/RX pins */ + USART_SWAP_DISABLE /*!< not swap TX/RX pins */ +} usart_invert_enum; + +/* 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 match */ + +/* 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 oversample mode */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< oversampling by 8 */ +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< oversampling by 16 */ + +/* USART address detection mode */ +#define CTL1_ADDM(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define USART_ADDM_4BIT CTL1_ADDM(0) /*!< 4-bit address detection */ +#define USART_ADDM_FULLBIT CTL1_ADDM(1) /*!< full-bit address detection */ + +/* USART LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits break detection */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits break detection */ + +/* USART last bit clock pulse */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< clock pulse of the last data bit (MSB) is not output to the CK pin */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< clock pulse of the last data bit (MSB) is output to the CK pin */ + +/* USART clock phase */ +#define CTL1_CPH(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CPH_1CK CTL1_CPH(0) /*!< first clock transition is the first data capture edge */ +#define USART_CPH_2CK CTL1_CPH(1) /*!< second clock transition is the first data capture edge */ + +/* USART clock polarity */ +#define CTL1_CPL(regval) (BIT(10) & ((uint32_t)(regval) << 10)) +#define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ +#define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ + +/* USART stop bits definitions */ +#define USART_STB_1BIT (uint32_t)(0x00000000U) /*!< 1 bit */ +#define USART_STB_0_5BIT (uint32_t)(0x00000001U) /*!< 0.5 bit */ +#define USART_STB_2BIT (uint32_t)(0x00000002U) /*!< 2 bits */ +#define USART_STB_1_5BIT (uint32_t)(0x00000003U) /*!< 1.5 bits */ + +/* USART data is transmitted/received with the LSB/MSB first */ +#define CTL1_MSBF(regval) (BIT(19) & ((uint32_t)(regval) << 19)) +#define USART_MSBF_LSB CTL1_MSBF(0) /*!< LSB first */ +#define USART_MSBF_MSB CTL1_MSBF(1) /*!< MSB first */ + +/* USART auto baud rate detection mode bits definitions */ +#define CTL1_ABDM(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define USART_ABDM_FTOR CTL1_ABDM(0) /*!< falling edge to rising edge measurement */ +#define USART_ABDM_FTOF CTL1_ABDM(1) /*!< falling edge to falling edge measurement */ + +/* 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 */ + +/* DMA enable for reception */ +#define CTL2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_RECEIVE_DMA_ENABLE CTL2_DENR(1) /*!< enable for reception */ +#define USART_RECEIVE_DMA_DISABLE CTL2_DENR(0) /*!< disable for reception */ + +/* DMA enable for transmission */ +#define CTL2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_TRANSMIT_DMA_ENABLE CTL2_DENT(1) /*!< enable for transmission */ +#define USART_TRANSMIT_DMA_DISABLE CTL2_DENT(0) /*!< disable for transmission */ + +/* USART RTS hardware flow control configure */ +#define CTL2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CTL2_RTSEN(1) /*!< RTS hardware flow control enabled */ +#define USART_RTS_DISABLE CTL2_RTSEN(0) /*!< RTS hardware flow control disabled */ + +/* USART CTS hardware flow control configure */ +#define CTL2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CTL2_CTSEN(1) /*!< CTS hardware flow control enabled */ +#define USART_CTS_DISABLE CTL2_CTSEN(0) /*!< CTS hardware flow control disabled */ + +/* USART one sample bit method configure */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1BIT CTL2_OSB(1) /*!< 1 sample bit */ +#define USART_OSB_3BIT CTL2_OSB(0) /*!< 3 sample bits */ + +/* USART driver enable polarity mode */ +#define CTL2_DEP(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_DEP_HIGH CTL2_DEP(0) /*!< DE signal is active high */ +#define USART_DEP_LOW CTL2_DEP(1) /*!< DE signal is active low */ + +/* USART wakeup mode from deep-sleep mode */ +#define CTL2_WUM(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define USART_WUM_ADDR CTL2_WUM(0) /*!< WUF active on address match */ +#define USART_WUM_STARTB CTL2_WUM(2) /*!< WUF active on start bit */ +#define USART_WUM_RBNE CTL2_WUM(3) /*!< WUF active on RBNE */ + +/* USART 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 */ + +/* parameter check definitions */ +#ifdef FW_DEBUG_ERR_REPORT +/* check USART baud rate */ +#define NOT_USART_BAUDRATE(baudval) ((baudval) == 0U) +/* check USART receive timeout */ +#define NOT_USART_RECEIVE_TIMEOUT(rtimeout) (0x00FFFFFFU < (rtimeout)) + +#endif /* FW_DEBUG_ERR_REPORT */ + +/* 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); +/* enable the USART overrun function */ +void usart_overrun_enable(uint32_t usart_periph); +/* disable the USART overrun function */ +void usart_overrun_disable(uint32_t usart_periph); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* configure sample bit method */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb); +/* enable receiver timeout */ +void usart_receiver_timeout_enable(uint32_t usart_periph); +/* disable receiver timeout */ +void usart_receiver_timeout_disable(uint32_t usart_periph); +/* configure receiver timeout threshold */ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout); +/* USART transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint16_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); +/* enable USART command */ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype); + +/* auto baud rate detection */ +/* enable auto baud rate detection */ +void usart_autobaud_detection_enable(uint32_t usart_periph); +/* disable auto baud rate detection */ +void usart_autobaud_detection_disable(uint32_t usart_periph); +/* configure auto baud rate detection mode */ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod); + +/* multi-processor communication */ +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* configure address detection mode */ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod); +/* enable mute mode */ +void usart_mute_mode_enable(uint32_t usart_periph); +/* disable mute mode */ +void usart_mute_mode_disable(uint32_t usart_periph); +/* configure wakeup method in mute mode */ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod); + +/* LIN mode communication */ +/* enable LIN mode */ +void usart_lin_mode_enable(uint32_t usart_periph); +/* disable LIN mode */ +void usart_lin_mode_disable(uint32_t usart_periph); +/* LIN break detection length */ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen); + +/* half-duplex communication */ +/* enable half-duplex mode */ +void usart_halfduplex_enable(uint32_t usart_periph); +/* disable half-duplex mode */ +void usart_halfduplex_disable(uint32_t usart_periph); + +/* synchronous communication */ +/* enable clock */ +void usart_clock_enable(uint32_t usart_periph); +/* disable clock */ +void usart_clock_disable(uint32_t usart_periph); +/* configure USART synchronous mode parameters */ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl); + +/* smartcard communication */ +/* configure guard time value in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph, uint8_t guat); +/* enable smartcard mode */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* disable smartcard mode */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* enable NACK in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* disable NACK in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* enable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph); +/* disable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph); +/* configure smartcard auto-retry number */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint8_t scrtnum); +/* configure block length */ +void usart_block_length_config(uint32_t usart_periph, uint8_t bl); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler */ +void usart_prescaler_config(uint32_t usart_periph, uint8_t psc); +/* configure IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); + +/* hardware flow communication */ +/* configure hardware flow control RTS */ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig); +/* configure hardware flow control CTS */ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig); + +/* coherence control */ +/* configure hardware flow control coherence mode */ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm); + +/* enable RS485 driver */ +void usart_rs485_driver_enable(uint32_t usart_periph); +/* disable RS485 driver */ +void usart_rs485_driver_disable(uint32_t usart_periph); +/* configure driver enable assertion time */ +void usart_driver_assertime_config(uint32_t usart_periph, uint8_t deatime); +/* configure driver enable de-assertion time */ +void usart_driver_deassertime_config(uint32_t usart_periph, uint8_t dedtime); +/* configure driver enable polarity mode */ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep); + +/* USART DMA */ +/* 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); +/* disable DMA on reception error */ +void usart_reception_error_dma_disable(uint32_t usart_periph); +/* enable DMA on reception error */ +void usart_reception_error_dma_enable(uint32_t usart_periph); + +/* enable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_enable(uint32_t usart_periph); +/* disable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_disable(uint32_t usart_periph); +/* configure the USART wakeup mode from deep-sleep mode */ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum); + +/* USART receive FIFO */ +/* enable receive FIFO */ +void usart_receive_fifo_enable(uint32_t usart_periph); +/* disable receive FIFO */ +void usart_receive_fifo_disable(uint32_t usart_periph); +/* read receive FIFO counter number */ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph); + +/* flag & interrupt functions */ +/* get flag in STAT/RFCS register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear USART status */ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt); +/* get USART interrupt and flag status */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); +/* clear USART interrupt flag */ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); + +#endif /* GD32C2X1_USART_H */ diff --git a/gd32c2x1/standard_peripheral/include/gd32c2x1_wwdgt.h b/gd32c2x1/standard_peripheral/include/gd32c2x1_wwdgt.h new file mode 100644 index 0000000..ba13051 --- /dev/null +++ b/gd32c2x1/standard_peripheral/include/gd32c2x1_wwdgt.h @@ -0,0 +1,107 @@ +/*! + \file gd32c2x1_wwdgt.h + \brief definitions for the WWDGT + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32C2X1_WWDGT_H +#define GD32C2X1_WWDGT_H + +#include "gd32c2x1.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00000000U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x00000004U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x00000008U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC_0_1 BITS(7,8) /*!< WWDGT prescaler divider value low bit */ +#define WWDGT_CFG_EWIE BIT(9) /*!< WWDGT early wakeup interrupt enable */ +#define WWDGT_CFG_PSC_2_3 BITS(16,17) /*!< WWDGT prescaler divider value high bit */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< WWDGT early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval1, regval2) ((BITS(7,8) & ((uint32_t)(regval1) << 7U)) | (BITS(16, 17) & ((uint32_t)(regval2) << 16))) +#define WWDGT_CFG_PSC_DIV1 ((uint32_t)CFG_PSC(0,0)) /*!< the time base of WWDGT = (PCLK1/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 ((uint32_t)CFG_PSC(1,0)) /*!< the time base of WWDGT = (PCLK1/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 ((uint32_t)CFG_PSC(2,0)) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 ((uint32_t)CFG_PSC(3,0)) /*!< the time base of WWDGT = (PCLK1/4096)/8 */ +#define WWDGT_CFG_PSC_DIV16 ((uint32_t)CFG_PSC(0,1)) /*!< the time base of WWDGT = (PCLK1/4096)/16 */ +#define WWDGT_CFG_PSC_DIV32 ((uint32_t)CFG_PSC(1,1)) /*!< the time base of WWDGT = (PCLK1/4096)/32 */ +#define WWDGT_CFG_PSC_DIV64 ((uint32_t)CFG_PSC(2,1)) /*!< the time base of WWDGT = (PCLK1/4096)/64 */ +#define WWDGT_CFG_PSC_DIV128 ((uint32_t)CFG_PSC(3,1)) /*!< the time base of WWDGT = (PCLK1/4096)/128 */ +#define WWDGT_CFG_PSC_DIV256 ((uint32_t)CFG_PSC(0,2)) /*!< the time base of WWDGT = (PCLK1/4096)/256 */ +#define WWDGT_CFG_PSC_DIV512 ((uint32_t)CFG_PSC(1,2)) /*!< the time base of WWDGT = (PCLK1/4096)/512 */ +#define WWDGT_CFG_PSC_DIV1024 ((uint32_t)CFG_PSC(2,2)) /*!< the time base of WWDGT = (PCLK1/4096)/1024 */ +#define WWDGT_CFG_PSC_DIV2048 ((uint32_t)CFG_PSC(3,2)) /*!< the time base of WWDGT = (PCLK1/4096)/2048 */ +#define WWDGT_CFG_PSC_DIV4096 ((uint32_t)CFG_PSC(0,3)) /*!< the time base of WWDGT = (PCLK1/4096)/4096 */ +#define WWDGT_CFG_PSC_DIV8192 ((uint32_t)CFG_PSC(1,3)) /*!< the time base of WWDGT = (PCLK1/4096)/8192 */ + +/* write value to WWDGT_CTL_CNT bit field */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) +/* write value to WWDGT_CFG_WIN bit field */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0)) + +/* function declarations */ +/* reset the WWDGT configuration */ +void wwdgt_deinit(void); +/* start the WWDGT counter */ +void wwdgt_enable(void); + +/* configure the WWDGT counter prescaler value */ +void wwdgt_prescaler_value_config(uint32_t prescaler); +/* configure the WWDGT counter window value */ +void wwdgt_window_value_config(uint16_t window); +/* configure the WWDGT counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); + +#endif /* gd32c2x1_WWDGT_H */ diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_adc.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_adc.c new file mode 100644 index 0000000..922ee75 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_adc.c @@ -0,0 +1,964 @@ +/*! + \file gd32c2x1_adc.c + \brief ADC driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_adc.h" + +/* discontinuous mode macro*/ +#define ADC_CHANNEL_LENGTH_SUBTRACT_ONE ((uint8_t)0x01U) + +/* ADC routine channel macro */ +#define ADC_ROUTINE_CHANNEL_RANK_SIX ((uint8_t)0x06U) +#define ADC_ROUTINE_CHANNEL_RANK_TWELVE ((uint8_t)0x0CU) +#define ADC_ROUTINE_CHANNEL_RANK_LENGTH ((uint8_t)0x05U) + +/* ADC sampling time macro */ +#define ADC_CHANNEL_SAMPLE_TEN ((uint8_t)0x0AU) +#define ADC_CHANNEL_SAMPLE_LENGTH ((uint8_t)0x03U) + +/* ADC inserted channel macro */ +#define ADC_INSERTED_CHANNEL_RANK_LENGTH ((uint8_t)0x05U) +#define ADC_INSERTED_CHANNEL_SHIFT_OFFSET ((uint8_t)0x0FU) + +/* ADC inserted channel offset macro */ +#define ADC_OFFSET_LENGTH ((uint8_t)0x03U) +#define ADC_OFFSET_SHIFT_LENGTH ((uint8_t)0x04U) + +/* ADC routine sequence length */ +#define ROUTINE_LENGTH_HIGH_VALUE ((uint32_t)0x00000010U) + +#define ADC_CHANNEL_INTERNAL_MASK (ADC_CHANNEL_INTERNAL_TEMPSENSOR | ADC_CHANNEL_INTERNAL_VREFINT) +#define ADC_FLAG_MASK ((uint32_t)0xC000001FU) +#define ADC_INT_MASK ((uint32_t)0xC00000E0U) +#define ADC_INT_FLAG_MASK ((uint32_t)0xC0000007U) + +/*! + \brief reset ADC (API_ID(0x0001U)) + \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 enable ADC interface (API_ID(0x0002U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_enable(void) +{ + if(0U == (ADC_CTL1 & ADC_CTL1_ADCON)) { + /* enable ADC */ + ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface (API_ID(0x0003U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_disable(void) +{ + /* disable ADC */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ADCON); +} + +/*! + \brief enable DMA request (API_ID(0x0004U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(void) +{ + /* enable DMA request */ + ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief disable DMA request (API_ID(0x0005U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(void) +{ + /* disable DMA request */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief configure ADC discontinuous mode (API_ID(0x0006U)) + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of routine and inserted sequence + \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 + for routine sequence, the number has no effect for inserted sequence + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint8_t adc_sequence, uint8_t length) +{ + /* disable discontinuous mode of routine & inserted sequence */ + ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* configure the number of conversions in discontinuous mode */ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM); + if((length <= 8U) && (length >= 1U)) { + ADC_CTL0 |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + /* enable routine sequence discontinuous mode */ + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + /* enable inserted sequence discontinuous mode */ + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + /* disable discontinuous mode of routine & inserted sequence */ + default: + break; + } +} + +/*! + \brief configure ADC special function (API_ID(0x0007U)) + \param[in] function: the function to configure + one or more parameters can be selected which is shown as below: + \arg ADC_SCAN_MODE: scan mode select + \arg ADC_INSERTED_CHANNEL_AUTO: inserted sequence convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_special_function_config(uint32_t function, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + /* enable ADC scan mode */ + if(0U != (function & ADC_SCAN_MODE)) { + ADC_CTL0 |= (uint32_t)ADC_SCAN_MODE; + } + /* enable ADC inserted sequence convert automatically */ + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { + ADC_CTL0 |= (uint32_t)ADC_INSERTED_CHANNEL_AUTO; + } + /* enable ADC continuous mode */ + if(0U != (function & ADC_CONTINUOUS_MODE)) { + ADC_CTL1 |= (uint32_t)ADC_CONTINUOUS_MODE; + } + } else { + /* disable ADC scan mode */ + if(0U != (function & ADC_SCAN_MODE)) { + ADC_CTL0 &= ~((uint32_t)ADC_SCAN_MODE); + } + /* disable ADC inserted sequence convert automatically */ + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) { + ADC_CTL0 &= ~((uint32_t)ADC_INSERTED_CHANNEL_AUTO); + } + /* disable ADC continuous mode */ + if(0U != (function & ADC_CONTINUOUS_MODE)) { + ADC_CTL1 &= ~((uint32_t)ADC_CONTINUOUS_MODE); + } + } +} + +/*! + \brief enable or disable ADC internal channels (API_ID(0x0008U)) + \param[in] internal_channel: the internal channels + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_INTERNAL_TEMPSENSOR: temperature sensor channel + \arg ADC_CHANNEL_INTERNAL_VREFINT: vrefint channel + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_internal_channel_config(uint32_t internal_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + ADC_CTL1 |= (uint32_t)(internal_channel & ADC_CHANNEL_INTERNAL_MASK); + } else { + ADC_CTL1 &= ~((uint32_t)internal_channel & ADC_CHANNEL_INTERNAL_MASK); + } +} + +/*! + \brief configure ADC data alignment (API_ID(0x0009U)) + \param[in] data_alignment: data alignment select + only one parameter can be selected which is shown as below: + \arg ADC_DATAALIGN_RIGHT: right alignment + \arg ADC_DATAALIGN_LEFT: left alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t data_alignment) +{ + if(ADC_DATAALIGN_RIGHT != data_alignment) { + /* left alignment */ + ADC_CTL1 |= ADC_CTL1_DAL; + } else { + /* right alignment */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief configure the channel length of routine sequence or inserted sequence (API_ID(0x000AU)) + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[in] length: the channel length of the sequence + routine sequence: 1-16 + inserted sequence 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint8_t adc_sequence, uint32_t length) +{ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* configure the length of routine sequence */ + if((length >= 1U) && (length <= ROUTINE_LENGTH_HIGH_VALUE)) { + ADC_RSQ0 &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0 |= RSQ0_RL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + break; + case ADC_INSERTED_CHANNEL: + /* configure the length of inserted sequence */ + if((length >= 1U) && (length <= 4U)) { + ADC_ISQ &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ |= ISQ_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE)); + } + break; + default: + break; + } +} + +/*! + \brief configure ADC routine channel (API_ID(0x000BU)) + \param[in] rank: the routine sequence rank, this parameter must be between 0 to 15 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x: x=0..15 + \param[in] sample_time: the sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_2POINT5: 2.5 cycles + \arg ADC_SAMPLETIME_3POINT5: 3.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_12POINT5: 12.5 cycles + \arg ADC_SAMPLETIME_19POINT5: 19.5 cycles + \arg ADC_SAMPLETIME_39POINT5: 39.5 cycles + \arg ADC_SAMPLETIME_79POINT5: 79.5 cycles + \arg ADC_SAMPLETIME_160POINT5: 160.5 cycles + \param[out] none + \retval none +*/ +void adc_routine_channel_config(uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint32_t rsq, sampt; + + /* configure ADC routine sequence */ + if(rank < ADC_ROUTINE_CHANNEL_RANK_SIX) { + /* the routine sequence rank is smaller than six */ + rsq = ADC_RSQ2; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * rank))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)(adc_channel & ADC_RSQX_RSQN) << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * rank)); + ADC_RSQ2 = rsq; + } else if(rank < ADC_ROUTINE_CHANNEL_RANK_TWELVE) { + /* the routine sequence rank is smaller than twelve */ + rsq = ADC_RSQ1; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_SIX)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)(adc_channel & ADC_RSQX_RSQN) << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_SIX))); + ADC_RSQ1 = rsq; + } else { + /* the routine sequence rank is larger than twelve */ + rsq = ADC_RSQ0; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_TWELVE)))); + /* the channel number is written to these bits to select a channel as the nth conversion in the routine sequence */ + rsq |= ((uint32_t)(adc_channel & ADC_RSQX_RSQN) << (ADC_ROUTINE_CHANNEL_RANK_LENGTH * (rank - ADC_ROUTINE_CHANNEL_RANK_TWELVE))); + ADC_RSQ0 = rsq; + } + + /* configure ADC sampling time */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) { + /* the routine sequence rank is smaller than ten */ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); + /* channel sample time set*/ + sampt |= (uint32_t)((sample_time & ADC_SAMPTX_SPTN) << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)); + ADC_SAMPT1 = sampt; + } else { + /* the routine sequence rank is smaller than fiften */ + sampt = ADC_SAMPT0; + 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_SAMPTX_SPTN) << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); + ADC_SAMPT0 = sampt; + } +} + +/*! + \brief configure ADC inserted channel (API_ID(0x000CU)) + \param[in] rank: the inserted 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..15 + \param[in] sample_time: The sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_2POINT5: 2.5 cycles + \arg ADC_SAMPLETIME_3POINT5: 3.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_12POINT5: 12.5 cycles + \arg ADC_SAMPLETIME_19POINT5: 19.5 cycles + \arg ADC_SAMPLETIME_39POINT5: 39.5 cycles + \arg ADC_SAMPLETIME_79POINT5: 79.5 cycles + \arg ADC_SAMPLETIME_160POINT5: 160.5 cycles + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq, sampt; + + /* get inserted sequence length */ + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U); + /* the channel number is written to these bits to select a channel as the nth conversion in the inserted sequence */ + if(rank < 4U) { + isq = ADC_ISQ; + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_OFFSET - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH))); + isq |= ((uint32_t)(adc_channel & ADC_ISQ_ISQN) << (ADC_INSERTED_CHANNEL_SHIFT_OFFSET - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH)); + ADC_ISQ = isq; + } + + /* configure ADC sampling time */ + if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) { + /* the inserted sequence rank is smaller than ten */ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel))); + /* channel sample time set*/ + sampt |= (uint32_t)(sample_time & ADC_SAMPTX_SPTN) << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel); + ADC_SAMPT1 = sampt; + } else { + /* the inserted sequence rank is smaller than fiften */ + sampt = ADC_SAMPT0; + 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_SAMPTX_SPTN) << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))); + ADC_SAMPT0 = sampt; + } +} + +/*! + \brief configure ADC inserted channel offset (API_ID(0x000DU)) + \param[in] inserted_channel: inserted channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3 + \param[in] offset: the offset data + \param[out] none + \retval none +*/ +void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 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; + /* configure the offset of the selected channels */ + REG32(ADC + 0x14U + num) = (uint32_t)(offset & ADC_IOFFX_IOFF); + } +} + +/*! + \brief configure ADC external trigger (API_ID(0x000EU)) + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_external_trigger_config(uint8_t adc_sequence, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + /* external trigger enable for routine sequence */ + if(0U != (adc_sequence & ADC_ROUTINE_CHANNEL)) { + ADC_CTL1 |= (uint32_t)ADC_CTL1_ETERC; + } + /* external trigger enable for inserted sequence */ + if(0U != (adc_sequence & ADC_INSERTED_CHANNEL)) { + ADC_CTL1 |= (uint32_t)ADC_CTL1_ETEIC; + } + } else { + /* external trigger disable for routine sequence */ + if(0U != (adc_sequence & ADC_ROUTINE_CHANNEL)) { + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETERC); + } + /* external trigger disable for inserted sequence */ + if(0U != (adc_sequence & ADC_INSERTED_CHANNEL)) { + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETEIC); + } + } +} + +/*! + \brief configure ADC external trigger source (API_ID(0x000FU)) + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[in] external_trigger_source: routine or inserted sequence trigger source + only one parameter can be selected which is shown as below: + for routine sequence: + \arg ADC_EXTTRIG_ROUTINE_T2_CH1: external trigger TIMER2 CH1 event select for routine channel + \arg ADC_EXTTRIG_ROUTINE_T0_CH2: external trigger TIMER0 CH2 event select for routine channel + \arg ADC_EXTTRIG_ROUTINE_T0_CH1: external trigger TIMER0 CH1 event select for routine channel + \arg ADC_EXTTRIG_ROUTINE_T2_TRGO: external trigger TIMER2 TRGO event select for routine channel + \arg ADC_EXTTRIG_ROUTINE_T0_CH0: external trigger TIMER0 CH0 event select for routine channel + \arg ADC_EXTTRIG_ROUTINE_T2_CH0: external trigger TIMER2 CH0 event select for routine channel + \arg ADC_EXTTRIG_ROUTINE_EXTI_11: external trigger interrupt line 11 select for routine channel + \arg ADC_EXTTRIG_ROUTINE_NONE: external trigger software event select for routine channel + for inserted sequence: + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: external trigger TIMER0 TRGO event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T0_CH3: external trigger TIMER0 CH3 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T13_CH0: external trigger TIMER13 CH0 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T2_CH3: external trigger TIMER2 CH3 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T2_CH2: external trigger TIMER2 CH2 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_T15_CH0: external trigger TIMER15 CH0 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_EXTI_15: external trigger interrupt line 15 event select for inserted channel + \arg ADC_EXTTRIG_INSERTED_NONE: external trigger software event select for inserted channel + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint8_t adc_sequence, uint32_t external_trigger_source) +{ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* configure ADC routine sequence external trigger source */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1 |= (uint32_t)(external_trigger_source & ADC_CTL1_ETSRC); + break; + case ADC_INSERTED_CHANNEL: + /* configure ADC inserted sequence external trigger source */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1 |= (uint32_t)(external_trigger_source & ADC_CTL1_ETSIC); + break; + default: + break; + } +} + +/*! + \brief enable ADC software trigger (API_ID(0x0010U)) + \param[in] adc_sequence: select the sequence + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint8_t adc_sequence) +{ + /* enable routine sequence software trigger */ + if(0U != (adc_sequence & ADC_ROUTINE_CHANNEL)) { + ADC_CTL1 |= (uint32_t)ADC_CTL1_SWRCST; + } + /* enable inserted sequence software trigger */ + if(0U != (adc_sequence & ADC_INSERTED_CHANNEL)) { + ADC_CTL1 |= (uint32_t)ADC_CTL1_SWICST; + } +} + +/*! + \brief read ADC routine sequence data register (API_ID(0x0011U)) + \param[in] none + \param[out] none + \retval the conversion value: 0~0x0FFF +*/ +uint16_t adc_routine_data_read(void) +{ + return ((uint16_t)(ADC_RDATA)); +} + +/*! + \brief read ADC inserted sequence data register (API_ID(0x0012U)) + \param[in] inserted_channel: inserted channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3 + \param[out] none + \retval the conversion value: 0~0xFFFF +*/ +uint16_t adc_inserted_data_read(uint8_t inserted_channel) +{ + uint32_t idata = 0U; + + /* read the data of the selected channel */ + switch(inserted_channel) { + case ADC_INSERTED_CHANNEL_0: + /* read the data of channel 0 */ + idata = ADC_IDATA0; + break; + case ADC_INSERTED_CHANNEL_1: + /* read the data of channel 1 */ + idata = ADC_IDATA1; + break; + case ADC_INSERTED_CHANNEL_2: + /* read the data of channel 2 */ + idata = ADC_IDATA2; + break; + case ADC_INSERTED_CHANNEL_3: + /* read the data of channel 3 */ + idata = ADC_IDATA3; + break; + default: + break; + } + return ((uint16_t)idata); +} + +/*! + \brief enable ADC analog watchdog 0 single channel (API_ID(0x0013U)) + \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..15 + \param[out] none + \retval none +*/ +void adc_watchdog0_single_channel_enable(uint8_t adc_channel) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC | ADC_CTL0_WD0CHSEL); + ADC_CTL0 |= (uint32_t)(adc_channel & ADC_CTL0_WD0CHSEL); + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC); +} + +/*! + \brief enable ADC analog watchdog 0 sequence channel (API_ID(0x0014U)) + \param[in] adc_sequence: the sequence use analog watchdog + only one parameter can be selected which is shown as below: + \arg ADC_ROUTINE_CHANNEL: routine sequence + \arg ADC_INSERTED_CHANNEL: inserted sequence + \arg ADC_ROUTINE_INSERTED_CHANNEL: both routine and inserted sequence + \param[out] none + \retval none +*/ +void adc_watchdog0_sequence_channel_enable(uint8_t adc_sequence) +{ + ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC)); + /* select the sequence */ + switch(adc_sequence) { + case ADC_ROUTINE_CHANNEL: + /* routine sequence analog watchdog 0 enable */ + ADC_CTL0 |= (uint32_t) ADC_CTL0_RWD0EN; + break; + case ADC_INSERTED_CHANNEL: + /* inserted sequence analog watchdog 0 enable */ + ADC_CTL0 |= (uint32_t) ADC_CTL0_IWD0EN; + break; + case ADC_ROUTINE_INSERTED_CHANNEL: + /* routine and inserted sequence analog watchdog 0 enable */ + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN); + break; + default: + break; + } +} + +/*! + \brief disable ADC analog watchdog 0 (API_ID(0x0015U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_watchdog0_disable(void) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC | ADC_CTL0_WD0CHSEL); +} + +/*! + \brief configure ADC analog watchdog 1 channel (API_ID(0x0016U)) + \param[in] selection_channel: the channel use analog watchdog 1 + one or more parameters can be selected which is shown as below: + \arg ADC_AWD1_2_SELECTION_CHANNEL_x, ADC_AWD1_2_SELECTION_CHANNEL_ALL: ADC channel analog watchdog 1/2 selection + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_watchdog1_channel_config(uint32_t selection_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + ADC_WD1SR |= (uint32_t)selection_channel; + } else { + ADC_WD1SR &= ~((uint32_t)selection_channel); + } +} + +/*! + \brief configure ADC analog watchdog 2 channel (API_ID(0x0017U)) + \param[in] selection_channel: the channel use analog watchdog 2 + one or more parameters can be selected which is shown as below: + \arg ADC_AWD1_2_SELECTION_CHANNEL_x, ADC_AWD1_2_SELECTION_CHANNEL_ALL: ADC channel analog watchdog 1/2 selection + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_watchdog2_channel_config(uint32_t selection_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + ADC_WD2SR |= (uint32_t)selection_channel; + } else { + ADC_WD2SR &= ~((uint32_t)selection_channel); + } +} + +/*! + \brief disable ADC analog watchdog 1 (API_ID(0x0018U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_watchdog1_disable(void) +{ + ADC_WD1SR &= ~((uint32_t)ADC_WD1SR_AWD1CS); +} + +/*! + \brief disable ADC analog watchdog 2 (API_ID(0x0019U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_watchdog2_disable(void) +{ + ADC_WD2SR &= ~((uint32_t)ADC_WD2SR_AWD2CS); +} + +/*! + \brief configure ADC analog watchdog 0 threshold (API_ID(0x001AU)) + \param[in] low_threshold: analog watchdog 0 low threshold, 0..4095 + \param[in] high_threshold: analog watchdog 0 high threshold, 0..4095 + \param[out] none + \retval none +*/ +void adc_watchdog0_threshold_config(uint32_t low_threshold, uint32_t high_threshold) +{ + ADC_WD0LT = (uint32_t)WD0LT_WD0LT(low_threshold); + ADC_WD0HT = (uint32_t)WD0HT_WD0HT(high_threshold); +} + +/*! + \brief configure ADC analog watchdog 1 threshold (API_ID(0x001BU)) + \param[in] low_threshold: analog watchdog 1 low threshold, 0..4095 + \param[in] high_threshold: analog watchdog 1 high threshold, 0..4095 + \param[out] none + \retval none +*/ +void adc_watchdog1_threshold_config(uint32_t low_threshold, uint32_t high_threshold) +{ + ADC_WD1LT = (uint32_t)WD1LT_WD1LT(low_threshold); + ADC_WD1HT = (uint32_t)WD1HT_WD1HT(high_threshold); +} + +/*! + \brief configure ADC analog watchdog 2 threshold (API_ID(0x001CU)) + \param[in] low_threshold: analog watchdog 2 low threshold, 0..4095 + \param[in] high_threshold: analog watchdog 2 high threshold, 0..4095 + \param[out] none + \retval none +*/ +void adc_watchdog2_threshold_config(uint32_t low_threshold, uint32_t high_threshold) +{ + ADC_WD2LT = (uint32_t)WD2LT_WD2LT(low_threshold); + ADC_WD2HT = (uint32_t)WD2HT_WD2HT(high_threshold); +} + +/*! + \brief configure ADC resolution (API_ID(0x001DU)) + \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 resolution) +{ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES); + ADC_CTL0 |= (uint32_t)(resolution & ADC_CTL0_DRES); +} + +/*! + \brief configure ADC oversample mode (API_ID(0x001EU)) + \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 mode, uint16_t shift, uint8_t ratio) +{ + /* configure ADC oversampling mode */ + if(ADC_OVERSAMPLING_ONE_CONVERT == mode) { + ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS; + } else { + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + /* configure the shift and ratio */ + ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL |= ((uint32_t)(shift & ADC_OVSAMPCTL_OVSS) | (uint32_t)(ratio & ADC_OVSAMPCTL_OVSR)); +} + +/*! + \brief enable ADC oversample mode (API_ID(0x001FU)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(void) +{ + ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief disable ADC oversample mode (API_ID(0x0020U)) + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(void) +{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} + +/*! + \brief get ADC flag (API_ID(0x0021U)) + \param[in] flag: ADC flag + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WD0E: analog watchdog 0 event flag + \arg ADC_FLAG_WD1E: analog watchdog 1 event flag + \arg ADC_FLAG_WD2E: analog watchdog 2 event flag + \arg ADC_FLAG_EOC: end of sequence conversion flag + \arg ADC_FLAG_EOIC: end of inserted sequence conversion flag + \arg ADC_FLAG_STIC: start flag of inserted sequence + \arg ADC_FLAG_STRC: start flag of routine sequence + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t flag) +{ + FlagStatus reval = RESET; + + if(0U != (ADC_STAT & flag)) { + reval = SET; + } + return reval; +} + +/*! + \brief clear ADC flag (API_ID(0x0022U)) + \param[in] flag: ADC flag + one or more parameter can be selected which is shown as below: + \arg ADC_FLAG_WD0E: analog watchdog 0 event flag + \arg ADC_FLAG_WD1E: analog watchdog 1 event flag + \arg ADC_FLAG_WD2E: analog watchdog 2 event flag + \arg ADC_FLAG_EOC: end of sequence conversion flag + \arg ADC_FLAG_EOIC: end of inserted sequence conversion flag + \arg ADC_FLAG_STIC: start flag of inserted sequence + \arg ADC_FLAG_STRC: start flag of routine sequence + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag & ADC_FLAG_MASK); +} + +/*! + \brief enable ADC interrupt (API_ID(0x0023U)) + \param[in] interrupt: ADC interrupt + one or more parameter can be selected which is shown as below: + \arg ADC_INT_WD0E: analog watchdog 0 interrupt + \arg ADC_INT_WD1E: analog watchdog 1 interrupt + \arg ADC_INT_WD2E: analog watchdog 2 interrupt + \arg ADC_INT_EOC: end of sequence conversion interrupt + \arg ADC_INT_EOIC: end of inserted sequence conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t interrupt) +{ + ADC_CTL0 |= (uint32_t) interrupt & ADC_INT_MASK; +} + +/*! + \brief disable ADC interrupt (API_ID(0x0024U)) + \param[in] interrupt: ADC interrupt + one or more parameter can be selected which is shown as below: + \arg ADC_INT_WD0E: analog watchdog 0 interrupt + \arg ADC_INT_WD1E: analog watchdog 1 interrupt + \arg ADC_INT_WD2E: analog watchdog 2 interrupt + \arg ADC_INT_EOC: end of sequence conversion interrupt + \arg ADC_INT_EOIC: end of inserted sequence conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t interrupt) +{ + ADC_CTL0 &= ~((uint32_t)interrupt & ADC_INT_MASK); +} + +/*! + \brief get ADC interrupt flag (API_ID(0x0025U)) + \param[in] int_flag: ADC interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WD0E: analog watchdog 0 interrupt flag + \arg ADC_INT_FLAG_WD1E: analog watchdog 1 interrupt flag + \arg ADC_INT_FLAG_WD2E: analog watchdog 2 interrupt flag + \arg ADC_INT_FLAG_EOC: end of sequence conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted sequence conversion interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t int_flag) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + + /* check the interrupt flags */ + switch(int_flag) { + case ADC_INT_FLAG_WD0E: + /* get the ADC analog watchdog 0 interrupt flags */ + state = ADC_STAT & ADC_STAT_WD0E; + if((0U != (ADC_CTL0 & ADC_CTL0_WD0EIE)) && (0U != state)) { + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_WD1E: + /* get the ADC analog watchdog 1 interrupt flags */ + state = ADC_STAT & ADC_STAT_WD1E; + if((0U != (ADC_CTL0 & ADC_CTL0_WD1EIE)) && (0U != state)) { + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_WD2E: + /* get the ADC analog watchdog 2 interrupt flags */ + state = ADC_STAT & ADC_STAT_WD2E; + if((0U != (ADC_CTL0 & ADC_CTL0_WD2EIE)) && (0U != state)) { + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + /* get the ADC end of sequence conversion interrupt flags */ + state = ADC_STAT & ADC_STAT_EOC; + if((0U != (ADC_CTL0 & ADC_CTL0_EOCIE)) && (0U != state)) { + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + /* get the ADC end of inserted sequence conversion interrupt flags */ + state = ADC_STAT & ADC_STAT_EOIC; + if((0U != (ADC_CTL0 & ADC_CTL0_EOICIE)) && (0U != state)) { + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear ADC interrupt flag (API_ID(0x0026U)) + \param[in] int_flag: ADC interrupt flag + one or more parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WD0E: analog watchdog 0 interrupt flag + \arg ADC_INT_FLAG_WD1E: analog watchdog 1 interrupt flag + \arg ADC_INT_FLAG_WD2E: analog watchdog 2 interrupt flag + \arg ADC_INT_FLAG_EOC: end of sequence conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted sequence conversion interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t int_flag) +{ + ADC_STAT &= ~((uint32_t)int_flag & ADC_INT_FLAG_MASK); +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_cmp.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_cmp.c new file mode 100644 index 0000000..9ae6d24 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_cmp.c @@ -0,0 +1,378 @@ +/*! + \file gd32c2x1_cmp.c + \brief CMP driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_cmp.h" + +/*! + \brief CMP deinit (API_ID(0x0001U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_deinit(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ((uint32_t)0x00000000U); + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ((uint32_t)0x00000000U); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CMP mode init (API_ID(0x0002U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] operating_mode + \arg CMP_MODE_HIGHSPEED: high speed mode + \arg CMP_MODE_MIDDLESPEED: medium speed mode + \arg CMP_MODE_LOWSPEED: low speed mode + \arg CMP_MODE_VERYLOWSPEED: very low speed mode + \param[in] inverting_input + \arg CMP_INVERTING_INPUT_1_4VREFINT: VREFINT *1/4 input + \arg CMP_INVERTING_INPUT_1_2VREFINT: VREFINT *1/2 input + \arg CMP_INVERTING_INPUT_3_4VREFINT: VREFINT *3/4 input + \arg CMP_INVERTING_INPUT_VREFINT: VREFINT input + \arg CMP_INVERTING_INPUT_PB2_PB6: PB2 input for CMP0 or PB6 input for CMP1 + \arg CMP_INVERTING_INPUT_PA0_PA2: PA0 input for CMP0 or PA2 input for CMP1 + \arg CMP_INVERTING_INPUT_PB1_PB3: PB1 input for CMP0 or PB3 input for CMP1 + \arg CMP_INVERTING_INPUT_VSSA_PB4: VSSA input for CMP0 or PB4 input for CMP1 + \param[in] output_hysteresis + \arg CMP_HYSTERESIS_NO: output no hysteresis + \arg CMP_HYSTERESIS_LOW: output low hysteresis + \arg CMP_HYSTERESIS_MIDDLE: output middle hysteresis + \arg CMP_HYSTERESIS_HIGH: output high hysteresis + \param[out] none + \retval none +*/ +void cmp_mode_init(cmp_enum cmp_periph, uint32_t operating_mode, uint32_t inverting_input, uint32_t output_hysteresis) +{ + uint32_t temp; + + if(CMP0 == cmp_periph){ + /* initialize comparator 0 mode */ + temp = CMP0_CS; + temp &= ~(uint32_t)(CMP_CS_CMPXM | CMP_CS_CMPXMSEL | CMP_CS_CMPXHST); + temp |= (uint32_t)((operating_mode & CMP_CS_CMPXM) | (inverting_input & CMP_CS_CMPXMSEL) | (output_hysteresis & CMP_CS_CMPXHST)); + CMP0_CS = temp; + }else if(CMP1 == cmp_periph){ + /* initialize comparator 1 mode */ + temp = CMP1_CS; + temp &= ~(uint32_t)(CMP_CS_CMPXM | CMP_CS_CMPXMSEL | CMP_CS_CMPXHST); + temp |= (uint32_t)((operating_mode & CMP_CS_CMPXM) | (inverting_input & CMP_CS_CMPXMSEL) | (output_hysteresis & CMP_CS_CMPXHST)); + CMP1_CS = temp; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CMP output init (API_ID(0x0003U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] output_polarity + \arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted + \arg CMP_OUTPUT_POLARITY_NONINVERTED: output is not inverted + \param[out] none + \retval none +*/ +void cmp_output_init(cmp_enum cmp_periph, uint32_t output_polarity) +{ + uint32_t temp; + + if(CMP0 == cmp_periph){ + /* initialize comparator 0 output */ + temp = CMP0_CS; + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){ + temp |= (uint32_t)CMP_CS_CMPXPL; + }else{ + temp &= ~(uint32_t)CMP_CS_CMPXPL; + } + CMP0_CS = temp; + }else if(CMP1 == cmp_periph){ + /* initialize comparator 1 output */ + temp = CMP1_CS; + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){ + temp |= (uint32_t)CMP_CS_CMPXPL; + }else{ + temp &= ~(uint32_t)CMP_CS_CMPXPL; + } + CMP1_CS = temp; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief CMP output blanking function init (API_ID(0x0004U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[in] blanking_source_selection + \arg CMP_BLANKING_NONE: CMP no blanking source + \arg CMP_BLANKING_TIMER0_OC1: CMP TIMER0_CH1 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER2_OC1: CMP TIMER2_CH1 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER13_OC0: CMP TIMER13_CH0 output compare signal selected as blanking source + \arg CMP_BLANKING_TIMER15_OC0: CMP TIMER15_CH0 output compare signal selected as blanking source + \param[out] none + \retval none +*/ +void cmp_blanking_init(cmp_enum cmp_periph, uint32_t blanking_source_selection) +{ + uint32_t temp; + + if(CMP0 == cmp_periph){ + temp = CMP0_CS; + temp &= ~(uint32_t)CMP_CS_CMPXBLK; + temp |= (uint32_t)(blanking_source_selection & CMP_CS_CMPXBLK); + CMP0_CS = temp; + }else if(CMP1 == cmp_periph){ + temp = CMP1_CS; + temp &= ~(uint32_t)CMP_CS_CMPXBLK; + temp |= (uint32_t)(blanking_source_selection & CMP_CS_CMPXBLK); + CMP1_CS = temp; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable CMP (API_ID(0x0005U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS |= (uint32_t)CMP_CS_CMPXEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS |= (uint32_t)CMP_CS_CMPXEN; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable CMP (API_ID(0x0006U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_disable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ~(uint32_t)CMP_CS_CMPXEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ~(uint32_t)CMP_CS_CMPXEN; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable CMP switch (API_ID(0x0007U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_switch_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + /* enable CMP0 switch */ + CMP0_CS |= (uint32_t)CMP_CS_CMPXSW; + }else if(CMP1 == cmp_periph){ + /* enable CMP1 switch */ + CMP1_CS |= (uint32_t)CMP_CS_CMPXSW; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable CMP switch (API_ID(0x0008U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_switch_disable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + /* disable CMP0 switch */ + CMP0_CS &= ~(uint32_t)CMP_CS_CMPXSW; + }else if(CMP1 == cmp_periph){ + /* disable CMP1 switch */ + CMP1_CS &= ~(uint32_t)CMP_CS_CMPXSW; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief lock the CMP (API_ID(0x0009U)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_lock_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + /* lock CMP0 */ + CMP0_CS |= (uint32_t)CMP_CS_CMPXLK; + }else if(CMP1 == cmp_periph){ + /* lock CMP1 */ + CMP1_CS |= (uint32_t)CMP_CS_CMPXLK; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable the voltage scaler (API_ID(0x000AU)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_voltage_scaler_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS |= (uint32_t)CMP_CS_CMPXSEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS |= (uint32_t)CMP_CS_CMPXSEN; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable the voltage scaler (API_ID(0x000BU)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_voltage_scaler_disable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ~(uint32_t)CMP_CS_CMPXSEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ~(uint32_t)CMP_CS_CMPXSEN; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable the scaler bridge (API_ID(0x000CU)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_scaler_bridge_enable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS |= (uint32_t)CMP_CS_CMPXBEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS |= (uint32_t)CMP_CS_CMPXBEN; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief disable the scaler bridge (API_ID(0x000DU)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval none +*/ +void cmp_scaler_bridge_disable(cmp_enum cmp_periph) +{ + if(CMP0 == cmp_periph){ + CMP0_CS &= ~(uint32_t)CMP_CS_CMPXBEN; + }else if(CMP1 == cmp_periph){ + CMP1_CS &= ~(uint32_t)CMP_CS_CMPXBEN; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief get output level (API_ID(0x000EU)) + \param[in] cmp_periph + \arg CMP0: comparator 0 + \arg CMP1: comparator 1 + \param[out] none + \retval the output level +*/ +uint32_t cmp_output_level_get(cmp_enum cmp_periph) +{ + uint32_t reval = CMP_OUTPUTLEVEL_LOW; + + if(CMP0 == cmp_periph){ + /* get output level of CMP0 */ + if((uint32_t)RESET != (CMP0_CS & CMP_CS_CMPXO)) { + reval = CMP_OUTPUTLEVEL_HIGH; + } + }else{ + /* get output level of CMP1 */ + if((uint32_t)RESET != (CMP1_CS & CMP_CS_CMPXO)) { + reval = CMP_OUTPUTLEVEL_HIGH; + } + } + return reval; +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_crc.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_crc.c new file mode 100644 index 0000000..7928ba9 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_crc.c @@ -0,0 +1,258 @@ +/*! + \file gd32c2x1_crc.c + \brief CRC driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_crc.h" + +#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU) +#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U) +#define CRC_IDATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU) +#define CRC_POLY_RESET_VALUE ((uint32_t)0x04C11DB7U) + +/*! + \brief deinit CRC calculation unit (API_ID: 0x0001U) + \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; + CRC_IDATA = CRC_IDATA_RESET_VALUE; + CRC_POLY = CRC_POLY_RESET_VALUE; +} + +/*! + \brief write the initialization data register (API_ID: 0x0002U) + \param[in] init_data:specify 32-bit data + \param[out] none + \retval none +*/ +void crc_init_data_register_write(uint32_t init_data) +{ + CRC_IDATA = init_data; +} + +/*! + \brief read the data register (API_ID: 0x0003U) + \param[in] none + \param[out] none + \retval 32-bit value of the data register +*/ +uint32_t crc_data_register_read(void) +{ + uint32_t data; + data = CRC_DATA; + return data; +} + +/*! + \brief read the free data register (API_ID: 0x0004U) + \param[in] none + \param[out] none + \retval 8-bit value of the free data register +*/ +uint8_t crc_free_data_register_read(void) +{ + uint8_t fdata; + fdata = (uint8_t)CRC_FDATA; + return fdata; +} + +/*! + \brief write the free data register (API_ID: 0x0005U) + \param[in] free_data: specify 8-bit data + \param[out] none + \retval none +*/ +void crc_free_data_register_write(uint8_t free_data) +{ + CRC_FDATA = (uint32_t)free_data; +} + +/*! + \brief disable the reverse operation of output data (API_ID: 0x0006U) + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_disable(void) +{ + CRC_CTL &= ~CRC_CTL_REV_O; +} + +/*! + \brief enable the reverse operation of output data (API_ID: 0x0007U) + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_enable(void) +{ + CRC_CTL &= ~CRC_CTL_REV_O; + CRC_CTL |= CRC_CTL_REV_O; +} + +/*! + \brief configure the CRC input data function (API_ID: 0x0008U) + \param[in] data_reverse: specify input data reverse function + only one parameter can be selected which is shown as below: + \arg CRC_INPUT_DATA_NOT: input data is not reversed + \arg CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits + \arg CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits + \arg CRC_INPUT_DATA_WORD: input data is reversed on 32 bits + \param[out] none + \retval none +*/ +void crc_input_data_reverse_config(uint32_t data_reverse) +{ + CRC_CTL &= ~CRC_CTL_REV_I; + CRC_CTL |= (uint32_t)(data_reverse & CRC_CTL_REV_I); +} + +/*! + \brief reset data register to the value of initialization data register (API_ID: 0x0009U) + \param[in] none + \param[out] none + \retval none +*/ +void crc_data_register_reset(void) +{ + CRC_CTL |= CRC_CTL_RST; +} + +/*! + \brief configure the CRC size of polynomial function (API_ID: 0x000AU) + \param[in] poly_size: size of polynomial + only one parameter can be selected which is shown as below: + \arg CRC_CTL_PS_32: 32-bit polynomial for CRC calculation + \arg CRC_CTL_PS_16: 16-bit polynomial for CRC calculation + \arg CRC_CTL_PS_8: 8-bit polynomial for CRC calculation + \arg CRC_CTL_PS_7: 7-bit polynomial for CRC calculation + \param[out] none + \retval none +*/ +void crc_polynomial_size_set(uint32_t poly_size) +{ + CRC_CTL &= ~CRC_CTL_PS; + CRC_CTL |= (uint32_t)(poly_size & CRC_CTL_PS); +} + +/*! + \brief configure the CRC polynomial value function (API_ID: 0x000BU) + \param[in] poly: configurable polynomial value + \param[out] none + \retval none +*/ +void crc_polynomial_set(uint32_t poly) +{ + CRC_POLY &= ~CRC_POLY_POLY; + CRC_POLY = poly; +} + +/*! + \brief CRC calculate single data (API_ID: 0x000CU) + \param[in] sdata: specify input data + \param[in] data_format: input data format + only one parameter can be selected which is shown as below: + \arg INPUT_FORMAT_WORD: input data in word format + \arg INPUT_FORMAT_HALFWORD: input data in half-word format + \arg INPUT_FORMAT_BYTE: input data in byte format + \param[out] none + \retval CRC calculate value +*/ +uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format) +{ + uint32_t crc_val = 0xFFFFFFFFU; + + if(INPUT_FORMAT_WORD == data_format) { + REG32(CRC) = sdata; + } else if(INPUT_FORMAT_HALFWORD == data_format) { + REG16(CRC) = (uint16_t)sdata; + } else { + REG8(CRC) = (uint8_t)sdata; + } + crc_val = CRC_DATA; + + return crc_val; +} + +/*! + \brief CRC calculate a data array (API_ID: 0x000DU) + \param[in] array: pointer to the input data array + \param[in] size: size of the array + \param[in] data_format: input data format + only one parameter can be selected which is shown as below: + \arg INPUT_FORMAT_WORD: input data in word format + \arg INPUT_FORMAT_HALFWORD: input data in half-word format + \arg INPUT_FORMAT_BYTE: input data in byte format + \param[out] none + \retval CRC calculate value +*/ +uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format) +{ + uint32_t data; + uint32_t index; + uint32_t crc_val = 0xFFFFFFFFU; + +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_VALID_POINTER(array)) { + fw_debug_report_err(CRC_MODULE_ID, API_ID(0x000DU), ERR_PARAM_POINTER); + } else +#endif + { + data = (uint32_t)array; + + if(INPUT_FORMAT_WORD == data_format) { + for(index = 0U; index < size; index++) { + REG32(CRC) = *(uint32_t *)data; + data += 4U; + } + } else if(INPUT_FORMAT_HALFWORD == data_format) { + for(index = 0U; index < size; index++) { + REG16(CRC) = *(uint16_t *)data; + data += 2U; + } + } else { + for(index = 0U; index < size; index++) { + REG8(CRC) = *(uint8_t *)data; + data += 1U; + } + } + crc_val = CRC_DATA; + } + return crc_val; +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_dbg.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_dbg.c new file mode 100644 index 0000000..554c15a --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_dbg.c @@ -0,0 +1,135 @@ +/*! + \file gd32c2x1_dbg.c + \brief DBG driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_dbg.h" + +#define DBG_RESET_VAL ((uint32_t)0x00000000U) /*!< DBG reset value */ +#define DBG_LOWPOWER_MASK ((uint32_t)0x00000007U) /*!< DBG low power mask */ + +/*! + \brief deinitialize the DBG (API_ID: (0x0001U)) + \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 (API_ID: (0x0002U)) + \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 (API_ID: (0x0003U)) + \param[in] dbg_low_power: + one or more parameters can be selected which are shown as below: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_enable(uint32_t dbg_low_power) +{ + DBG_CTL0 |= (dbg_low_power & DBG_LOWPOWER_MASK); +} + +/*! + \brief disable low power behavior when the MCU is in debug mode (API_ID: (0x0004U)) + \param[in] dbg_low_power: + one or more parameters can be selected which are shown as below: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL0 &= ~(dbg_low_power & DBG_LOWPOWER_MASK); +} + +/*! + \brief enable peripheral behavior when the MCU is in debug mode (API_ID: (0x0005U)) + \param[in] dbg_periph: DBG peripheral + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD: hold FWDGT counter when core is halted + \arg DBG_WWDGT_HOLD: hold WWDGT counter when core is halted + \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted + \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted + \arg DBG_TIMER16_HOLD: hold TIMER16 counter 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_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the MCU is in debug mode (API_ID: (0x0006U)) + \param[in] dbg_periph: DBG peripheral + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD: hold FWDGT counter when core is halted + \arg DBG_WWDGT_HOLD: hold WWDGT counter when core is halted + \arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted + \arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted + \arg DBG_TIMER16_HOLD: hold TIMER16 counter 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_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph)); +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_dma.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_dma.c new file mode 100644 index 0000000..a733e94 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_dma.c @@ -0,0 +1,1149 @@ +/*! + \file gd32c2x1_dma.c + \brief DMA driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_dma.h" + +#define RM_CHXCFG_NBR_OFFSET ((uint32_t)0x00000013U) /*!< bit offset of NBR in DMAMUX_RM_CHXCFG */ +#define RM_CHXCFG_SYNCID_OFFSET ((uint32_t)0x00000018U) /*!< bit offset of SYNCID in RM_CHXCFG_SYNCID */ + +/* DMA bits mask */ +#define DMA_CHXCTL_INT_MASK ((uint32_t)0x0000001EU) /*!< DMA_CHXCTL interrupt mask */ +/* DMAMUX bits mask */ +#define RM_CHXCFG_SYNCID_MASK ((uint32_t)0x0000001FU) /*!< RM_CHXCFG_SYNCID mask */ + +/*! + \brief deinitialize DMA a channel registers (API ID: 0x0001U) + \param[in] channelx: specify which DMA channel is deinitialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_deinit(dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHMADDR(channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); +} + +/*! + \brief initialize the parameters of DMA struct with the default values (API ID: 0x0002U) + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMA channel + \retval none +*/ +void dma_struct_para_init(dma_parameter_struct *init_struct) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(init_struct)) { + fw_debug_report_err(DMA_DMAMUX_MODULE_ID, API_ID(0x0002U), ERR_PARAM_POINTER); + } else +#endif + { + /* set the DMA struct with the default values */ + init_struct->periph_addr = 0U; + init_struct->periph_width = 0U; + init_struct->periph_inc = (uint8_t)DMA_PERIPH_INCREASE_DISABLE; + init_struct->memory_addr = 0U; + init_struct->memory_width = 0U; + init_struct->memory_inc = (uint8_t)DMA_MEMORY_INCREASE_DISABLE; + init_struct->number = 0U; + init_struct->direction = (uint8_t)DMA_PERIPHERAL_TO_MEMORY; + init_struct->priority = (uint32_t)DMA_PRIORITY_LOW; + init_struct->request = DMA_REQUEST_M2M; + } +} + +/*! + \brief initialize DMA channel (API ID: 0x0003U) + \param[in] channelx: specify which DMA channel is initialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] init_struct: the data needed to initialize DMA channel + periph_addr: peripheral base address + periph_width: DMA_PERIPHERAL_WIDTH_8BIT, DMA_PERIPHERAL_WIDTH_16BIT, DMA_PERIPHERAL_WIDTH_32BIT + periph_inc: DMA_PERIPH_INCREASE_ENABLE, DMA_PERIPH_INCREASE_DISABLE + memory_addr: memory 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 + direction: DMA_PERIPHERAL_TO_MEMORY, DMA_MEMORY_TO_PERIPHERAL + 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 + request: DMA_REQUEST_M2M + DMA_REQUEST_GENERATOR0 + DMA_REQUEST_GENERATOR1 + DMA_REQUEST_GENERATOR2 + DMA_REQUEST_GENERATOR3 + DMA_REQUEST_ADC + DMA_REQUEST_I2C0_RX + DMA_REQUEST_I2C0_TX + DMA_REQUEST_I2C1_RX + DMA_REQUEST_I2C1_TX + DMA_REQUEST_SPI0_RX + DMA_REQUEST_SPI0_TX + DMA_REQUEST_SPI1_RX + DMA_REQUEST_SPI1_TX + DMA_REQUEST_TIMER0_CH0 + DMA_REQUEST_TIMER0_CH1 + DMA_REQUEST_TIMER0_CH2 + DMA_REQUEST_TIMER0_CH3 + DMA_REQUEST_TIMER0_TRIG + DMA_REQUEST_TIMER0_UP + DMA_REQUEST_TIMER0_COM + DMA_REQUEST_TIMER2_CH0 + DMA_REQUEST_TIMER2_CH1 + DMA_REQUEST_TIMER2_CH2 + DMA_REQUEST_TIMER2_CH3 + DMA_REQUEST_TIMER2_TRIG + DMA_REQUEST_TIMER2_UP + DMA_REQUEST_TIMER15_CH0 + DMA_REQUEST_TIMER15_UP + DMA_REQUEST_TIMER16_CH0 + DMA_REQUEST_TIMER16_UP + DMA_REQUEST_USART0_RX + DMA_REQUEST_USART0_TX + DMA_REQUEST_USART1_RX + DMA_REQUEST_USART1_TX + \param[out] none + \retval none +*/ +void dma_init(dma_channel_enum channelx, dma_parameter_struct *init_struct) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(init_struct)) { + fw_debug_report_err(DMA_DMAMUX_MODULE_ID, API_ID(0x0003U), ERR_PARAM_POINTER); + } else +#endif + { + uint32_t ctl; + dma_channel_disable(channelx); + + /* configure peripheral base address */ + DMA_CHPADDR(channelx) = init_struct->periph_addr; + + /* configure memory base address */ + DMA_CHMADDR(channelx) = init_struct->memory_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK); + + /* configure peripheral transfer width, memory transfer width, channel priority */ + ctl = DMA_CHCTL(channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO); + ctl |= ((init_struct->memory_width & DMA_CHXCTL_MWIDTH) | (init_struct->periph_width & DMA_CHXCTL_PWIDTH ) | (init_struct->priority & DMA_CHXCTL_PRIO)); + DMA_CHCTL(channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) { + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) { + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure the direction of data transfer */ + if(DMA_PERIPHERAL_TO_MEMORY == init_struct->direction) { + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } + + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG(channelx) |= (init_struct->request & DMAMUX_RM_CHXCFG_MUXID); + } +} + +/*! + \brief enable DMA circulation mode (API ID: 0x0004U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_circulation_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode (API ID: 0x0005U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_circulation_disable(dma_channel_enum channelx) +{ + + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable memory to memory mode (API ID: 0x0006U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_M2M; +} + +/*! + \brief disable memory to memory mode (API ID: 0x0007U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_M2M; +} + +/*! + \brief enable DMA channel (API ID: 0x0008U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_channel_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel (API ID: 0x0009U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_channel_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief set DMA peripheral base address (API ID: 0x000AU) + \param[in] channelx: specify which DMA channel to set peripheral base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHPADDR(channelx) = address; +} + +/*! + \brief set DMA memory base address (API ID: 0x000BU) + \param[in] channelx: specify which DMA channel to set memory base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] address: memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHMADDR(channelx) = address; +} + +/*! + \brief set the number of remaining data to be transferred by the DMA (API ID: 0x000CU) + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] number: the number of remaining data to be transferred by the DMA + \arg 0x0 - 0xFFFF + \param[out] none + \retval none +*/ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number) +{ + DMA_CHCNT(channelx) = (number & DMA_CHANNEL_CNT_MASK); +} + +/*! + \brief get the number of remaining data to be transferred by the DMA (API ID: 0x000DU) + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval the number of remaining data to be transferred by the DMA, 0x0 - 0xFFFF +*/ +uint32_t dma_transfer_number_get(dma_channel_enum channelx) +{ + uint32_t reval ; + reval = (uint32_t)DMA_CHCNT(channelx); + return reval; +} + +/*! + \brief configure priority level of DMA channel (API ID: 0x000EU) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \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(dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= (priority & DMA_CHXCTL_PRIO); + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data width of memory (API ID: 0x000FU) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] mwidth: transfer data width of memory + only one parameter can be selected which is shown as below: + \arg DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data width of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config(dma_channel_enum channelx, uint32_t mwidth) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= (mwidth & DMA_CHXCTL_MWIDTH); + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data width of peripheral (API ID: 0x0010U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] pwidth: transfer data width of peripheral + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit + \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data width of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config(dma_channel_enum channelx, uint32_t pwidth) +{ + uint32_t ctl; + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= (pwidth & DMA_CHXCTL_PWIDTH); + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief enable next address increasement algorithm of memory (API ID: 0x0011U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_memory_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; +} + +/*! + \brief disable next address increasement algorithm of memory (API ID: 0x0012U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_memory_increase_disable(dma_channel_enum channelx) +{ + + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; +} + +/*! + \brief enable next address increasement algorithm of peripheral (API ID: 0x0013U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_periph_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; +} + +/*! + \brief disable next address increasement algorithm of peripheral (API ID: 0x0014U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[out] none + \retval none +*/ +void dma_periph_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; +} + +/*! + \brief configure the direction of data transfer on the channel (API ID: 0x0015U) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] direction: specify the direction of data transfer + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction) +{ + if(DMA_PERIPHERAL_TO_MEMORY == direction) { + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } + +} + +/*! + \brief check DMA flag is set or not (API ID: 0x0016U) + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + FlagStatus reval = RESET; + if((uint32_t)RESET != (DMA_INTF & DMA_FLAG_ADD(flag, channelx))) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} + +/*! + \brief clear a DMA channel flag (API ID: 0x0017U) + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief check DMA flag and interrupt enable bit is set or not (API ID: 0x0018U) + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_FTF: transfer finish flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish flag of channel + \arg DMA_INT_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t int_flag) +{ + FlagStatus reval = RESET; + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + switch(int_flag) { + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_ERRIE; + break; + default: + break; + } + + if((0U != interrupt_flag) && (0U != interrupt_enable)) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} + +/*! + \brief clear a DMA channel interrupt flag (API ID: 0x0019U) + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_G: global interrupt flag of channel + \arg DMA_INT_FLAG_FTF: transfer finish flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish flag of channel + \arg DMA_INT_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t int_flag) +{ + DMA_INTC |= DMA_FLAG_ADD(int_flag, channelx); +} + +/*! + \brief enable DMA interrupt (API ID: 0x001AU) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] source: specify which interrupt to enable + only one parameter can be selected which is shown as below: + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_FTF: channel full transfer finish interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) |= source & DMA_CHXCTL_INT_MASK; +} + +/*! + \brief disable DMA interrupt (API ID: 0x001BU) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..2) + \param[in] source: specify which interrupt to disable + only one parameter can be selected which is shown as below: + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_FTF: channel full transfer finish interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) &= ~source & DMA_CHXCTL_INT_MASK; +} + +/*! + \brief initialize the parameters of DMAMUX synchronization mode structure with the default values (API ID: 0x001CU) + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMAMUX request multiplexer channel synchronization mode + \retval none +*/ +void dmamux_sync_struct_para_init(dmamux_sync_parameter_struct *init_struct) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(init_struct)) { + fw_debug_report_err(DMA_DMAMUX_MODULE_ID, API_ID(0x001CU), ERR_PARAM_POINTER); + } else +#endif + { + /* set the DMAMUX synchronization struct with the default values */ + init_struct->sync_id = DMAMUX_SYNC_EVT0_OUT; + init_struct->sync_polarity = DMAMUX_SYNC_RISING; + init_struct->request_number = 1U; + } +} + +/*! + \brief initialize DMAMUX request multiplexer channel synchronization mode (API ID: 0x001DU) + \param[in] channelx: specify which DMAMUX request multiplexer channel is initialized + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[in] init_struct: the data needed to initialize DMAMUX request multiplexer channel + sync_id: DMAMUX_SYNC_EXTI0, DMAMUX_SYNC_EXTI1, DMAMUX_SYNC_EXTI2, DMAMUX_SYNC_EXTI3, + DMAMUX_SYNC_EXTI4, DMAMUX_SYNC_EXTI5, DMAMUX_SYNC_EXTI6, DMAMUX_SYNC_EXTI7, + DMAMUX_SYNC_EXTI8, DMAMUX_SYNC_EXTI9, DMAMUX_SYNC_EXTI10, DMAMUX_SYNC_EXTI11, + DMAMUX_SYNC_EXTI12, DMAMUX_SYNC_EXTI13, DMAMUX_SYNC_EXTI14, DMAMUX_SYNC_EXTI15, + DMAMUX_SYNC_EVT0_OUT, DMAMUX_SYNC_EVT1_OUT, DMAMUX_SYNC_EVT2_OUT, DMAMUX_SYNC_TIMER13_O + sync_polarity: DMAMUX_SYNC_NO_EVENT, DMAMUX_SYNC_RISING, DMAMUX_SYNC_FALLING, DMAMUX_SYNC_RISING_FALLING + request_number: the number of DMA request that will be authorized after a sync event, from 1 to 32 + \param[out] none + \retval none +*/ +void dmamux_synchronization_init(dmamux_multiplexer_channel_enum channelx, + dmamux_sync_parameter_struct *init_struct) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(init_struct)) { + fw_debug_report_err(DMA_DMAMUX_MODULE_ID, API_ID(0x001DU), ERR_PARAM_POINTER); + } else +#endif + { + uint32_t cfg; + /* disable synchronization mode and event generation for DMA request forward number configuration */ + DMAMUX_RM_CHXCFG(channelx) &= ~(DMAMUX_RM_CHXCFG_SYNCEN | DMAMUX_RM_CHXCFG_EVGEN); + + /* configure synchronization input identification, synchronization input polarity, number of DMA requests to forward */ + cfg = DMAMUX_RM_CHXCFG(channelx); + cfg &= ~(DMAMUX_RM_CHXCFG_SYNCID | DMAMUX_RM_CHXCFG_NBR | DMAMUX_RM_CHXCFG_SYNCP); + cfg |= ((init_struct->sync_polarity & DMAMUX_RM_CHXCFG_SYNCP) | (init_struct->sync_id & DMAMUX_RM_CHXCFG_SYNCID) | RM_CHXCFG_NBR( init_struct->request_number - 1U)); + DMAMUX_RM_CHXCFG(channelx) = cfg; + } +} + +/*! + \brief enable synchronization mode (API ID: 0x001EU) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[out] none + \retval none +*/ +void dmamux_synchronization_enable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) |= DMAMUX_RM_CHXCFG_SYNCEN; +} + +/*! + \brief disable synchronization mode (API ID: 0x001FU) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[out] none + \retval none +*/ +void dmamux_synchronization_disable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) &= (~DMAMUX_RM_CHXCFG_SYNCEN); +} +/*! + \brief enable event generation (API ID: 0x0020U) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[out] none + \retval none +*/ +void dmamux_event_generation_enable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) |= DMAMUX_RM_CHXCFG_EVGEN; +} + +/*! + \brief disable event generation (API ID: 0x0021U) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[out] none + \retval none +*/ +void dmamux_event_generation_disable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) &= (~DMAMUX_RM_CHXCFG_EVGEN); +} + +/*! + \brief initialize the parameters of DMAMUX request generator structure with the default values (API ID: 0x0022U) + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMAMUX request generator channel + \retval none +*/ +void dmamux_gen_struct_para_init(dmamux_gen_parameter_struct *init_struct) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(init_struct)) { + fw_debug_report_err(DMA_DMAMUX_MODULE_ID, API_ID(0x0022U), ERR_PARAM_POINTER); + } else +#endif + { + /* set the DMAMUX request generator structure with the default values */ + init_struct->trigger_id = DMAMUX_TRIGGER_EXTI0; + init_struct->trigger_polarity = DMAMUX_GEN_RISING; + init_struct->request_number = 1U; + } +} + +/*! + \brief initialize DMAMUX request generator channel (API ID: 0x0023U) + \param[in] channelx: specify which DMAMUX request generator channel is initialized + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..3) + \param[in] init_struct: the data needed to initialize DMAMUX request generator channel + trigger_id: DMAMUX_TRIGGER_EXTI0, DMAMUX_TRIGGER_EXTI1, DMAMUX_TRIGGER_EXTI2, DMAMUX_TRIGGER_EXTI3, + DMAMUX_TRIGGER_EXTI4, DMAMUX_TRIGGER_EXTI5, DMAMUX_TRIGGER_EXTI6, DMAMUX_TRIGGER_EXTI7, + DMAMUX_TRIGGER_EXTI8, DMAMUX_TRIGGER_EXTI9, DMAMUX_TRIGGER_EXTI10, DMAMUX_TRIGGER_EXTI11, + DMAMUX_TRIGGER_EXTI12, DMAMUX_TRIGGER_EXTI13, DMAMUX_TRIGGER_EXTI14, DMAMUX_TRIGGER_EXTI15, + DMAMUX_TRIGGER_EVT0_OUT, DMAMUX_TRIGGER_EVT1_OUT, DMAMUX_TRIGGER_EVT2_OUT, DMAMUX_TRIGGER_TIMER13_O + trigger_polarity: DMAMUX_GEN_NO_EVENT, DMAMUX_GEN_RISING, DMAMUX_GEN_FALLING, DMAMUX_GEN_RISING_FALLING + request_number: the number of DMA request that will be generated after a signal event, from 1 to 32 + \param[out] none + \retval none +*/ +void dmamux_request_generator_init(dmamux_generator_channel_enum channelx, + dmamux_gen_parameter_struct *init_struct) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(init_struct)) { + fw_debug_report_err(DMA_DMAMUX_MODULE_ID, API_ID(0x0023U), ERR_PARAM_POINTER); + } else +#endif + { + uint32_t cfg; + /* disable DMAMUX request generator channel for DMA request generation number configuration */ + DMAMUX_RG_CHXCFG(channelx) &= ~(DMAMUX_RG_CHXCFG_RGEN); + + /* configure trigger input identification, trigger polarity, number of DMA requests to be generated */ + cfg = DMAMUX_RG_CHXCFG(channelx); + cfg &= ~(DMAMUX_RG_CHXCFG_TID | DMAMUX_RG_CHXCFG_NBRG | DMAMUX_RG_CHXCFG_RGTP); + cfg |= (RG_CHXCFG_NBRG(init_struct->request_number - 1U) | (init_struct->trigger_id & DMAMUX_RG_CHXCFG_TID) | + (init_struct->trigger_polarity & DMAMUX_RG_CHXCFG_RGTP)); + DMAMUX_RG_CHXCFG(channelx) = cfg; + } +} + +/*! + \brief enable DMAMUX request generator channel (API ID: 0x0024U) + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..3) + \param[out] none + \retval none +*/ +void dmamux_request_generator_channel_enable(dmamux_generator_channel_enum channelx) +{ + DMAMUX_RG_CHXCFG(channelx) |= DMAMUX_RG_CHXCFG_RGEN; +} + +/*! + \brief disable DMAMUX request generator channel (API ID: 0x0025U) + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..3) + \param[out] none + \retval none +*/ +void dmamux_request_generator_channel_disable(dmamux_generator_channel_enum channelx) +{ + DMAMUX_RG_CHXCFG(channelx) &= (~DMAMUX_RG_CHXCFG_RGEN); +} + +/*! + \brief configure synchronization input polarity (API ID: 0x0026U) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[in] polarity: synchronization input polarity + only one parameter can be selected which is shown as below: + \arg DMAMUX_SYNC_NO_EVENT: no event detection + \arg DMAMUX_SYNC_RISING: rising edge + \arg DMAMUX_SYNC_FALLING: falling edge + \arg DMAMUX_SYNC_RISING_FALLING: rising and falling edges + \param[out] none + \retval none +*/ +void dmamux_synchronization_polarity_config(dmamux_multiplexer_channel_enum channelx, + uint32_t polarity) +{ + + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_SYNCP; + DMAMUX_RM_CHXCFG(channelx) |= (polarity & DMAMUX_RM_CHXCFG_SYNCP); +} + +/*! + \brief configure number of DMA requests to forward (API ID: 0x0027U) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[in] number: DMA requests number to forward + only one parameter can be selected which is shown as below: + \arg 1 - 32 + \param[out] none + \retval none +*/ +void dmamux_request_forward_number_config(dmamux_multiplexer_channel_enum channelx, uint32_t number) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_NBR; + DMAMUX_RM_CHXCFG(channelx) |= RM_CHXCFG_NBR(number - 1U) & DMAMUX_RM_CHXCFG_NBR; +} + +/*! + \brief configure synchronization input identification (API ID: 0x0028U) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[in] id: synchronization input identification + only one parameter can be selected which is shown as below: + \arg DMAMUX_SYNC_EXTI0: synchronization input is EXTI0 + \arg DMAMUX_SYNC_EXTI1: synchronization input is EXTI1 + \arg DMAMUX_SYNC_EXTI2: synchronization input is EXTI2 + \arg DMAMUX_SYNC_EXTI3: synchronization input is EXTI3 + \arg DMAMUX_SYNC_EXTI4: synchronization input is EXTI4 + \arg DMAMUX_SYNC_EXTI5: synchronization input is EXTI5 + \arg DMAMUX_SYNC_EXTI6: synchronization input is EXTI6 + \arg DMAMUX_SYNC_EXTI7: synchronization input is EXTI7 + \arg DMAMUX_SYNC_EXTI8: synchronization input is EXTI8 + \arg DMAMUX_SYNC_EXTI9: synchronization input is EXTI9 + \arg DMAMUX_SYNC_EXTI10: synchronization input is EXTI10 + \arg DMAMUX_SYNC_EXTI11: synchronization input is EXTI11 + \arg DMAMUX_SYNC_EXTI12: synchronization input is EXTI12 + \arg DMAMUX_SYNC_EXTI13: synchronization input is EXTI13 + \arg DMAMUX_SYNC_EXTI14: synchronization input is EXTI14 + \arg DMAMUX_SYNC_EXTI15: synchronization input is EXTI15 + \arg DMAMUX_SYNC_EVT0_OUT: synchronization input is Evt0_out + \arg DMAMUX_SYNC_EVT1_OUT: synchronization input is Evt1_out + \arg DMAMUX_SYNC_EVT2_OUT: synchronization input is Evt2_out + \arg DMAMUX_TRIGGER_TIMER13_O: synchronization input is TIMER13 O + + \param[out] none + \retval none +*/ +void dmamux_sync_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_SYNCID; + DMAMUX_RM_CHXCFG(channelx) |= (uint32_t)(id & RM_CHXCFG_SYNCID_MASK); +} + +/*! + \brief configure multiplexer input identification (API ID: 0x0029U) + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..2) + \param[in] id: input DMA request identification + only one parameter can be selected which is shown as below: + \arg DMA_REQUEST_M2M : memory to memory transfer + \arg DMA_REQUEST_GENERATOR0 : DMAMUX request generator 0 + \arg DMA_REQUEST_GENERATOR1 : DMAMUX request generator 1 + \arg DMA_REQUEST_GENERATOR2 : DMAMUX request generator 2 + \arg DMA_REQUEST_GENERATOR3 : DMAMUX request generator 3 + \arg DMA_REQUEST_ADC : DMAMUX ADC request + \arg DMA_REQUEST_I2C0_RX : DMAMUX I2C0 RX request + \arg DMA_REQUEST_I2C0_TX : DMAMUX I2C0 TX request + \arg DMA_REQUEST_I2C1_RX : DMAMUX I2C1 RX request + \arg DMA_REQUEST_I2C1_TX : DMAMUX I2C1 TX request + \arg DMA_REQUEST_SPI0_RX : DMAMUX SPI0 RX request + \arg DMA_REQUEST_SPI0_TX : DMAMUX SPI0 TX request + \arg DMA_REQUEST_SPI1_RX : DMAMUX SPI1 RX request + \arg DMA_REQUEST_SPI1_TX : DMAMUX SPI1 TX request + \arg DMA_REQUEST_TIMER0_CH0 : DMAMUX TIMER0 CH0 request + \arg DMA_REQUEST_TIMER0_CH1 : DMAMUX TIMER0 CH1 request + \arg DMA_REQUEST_TIMER0_CH2 : DMAMUX TIMER0 CH2 request + \arg DMA_REQUEST_TIMER0_CH3 : DMAMUX TIMER0 CH3 request + \arg DMA_REQUEST_TIMER0_TRIG: DMAMUX TIMER0 TRIG request + \arg DMA_REQUEST_TIMER0_UP : DMAMUX TIMER0 UP request + \arg DMA_REQUEST_TIMER0_COM : DMAMUX TIMER0 COM request + \arg DMA_REQUEST_TIMER2_CH0 : DMAMUX TIMER2 CH0 request + \arg DMA_REQUEST_TIMER2_CH1 : DMAMUX TIMER2 CH1 request + \arg DMA_REQUEST_TIMER2_CH2 : DMAMUX TIMER2 CH2 request + \arg DMA_REQUEST_TIMER2_CH3 : DMAMUX TIMER2 CH3 request + \arg DMA_REQUEST_TIMER2_TRIG: DMAMUX TIMER2 TRIG request + \arg DMA_REQUEST_TIMER2_UP : DMAMUX TIMER2 UP request + \arg DMA_REQUEST_TIMER15_CH0: DMAMUX TIMER15 CH0 request + \arg DMA_REQUEST_TIMER15_UP : DMAMUX TIMER15 UP request + \arg DMA_REQUEST_TIMER16_CH0: DMAMUX TIMER16 CH0 request + \arg DMA_REQUEST_TIMER16_UP : DMAMUX TIMER16 UP request + \arg DMA_REQUEST_USART0_RX : DMAMUX USART0 RX request + \arg DMA_REQUEST_USART0_TX : DMAMUX USART0 TX request + \arg DMA_REQUEST_USART1_RX : DMAMUX USART1 RX request + \arg DMA_REQUEST_USART1_TX : DMAMUX USART1 TX request + \param[out] none + \retval none +*/ +void dmamux_request_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG(channelx) |= (id & DMAMUX_RM_CHXCFG_MUXID); +} + +/*! + \brief configure trigger input polarity (API ID: 0x002AU) + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..3) + \param[in] polarity: trigger input polarity + only one parameter can be selected which is shown as below: + \arg DMAMUX_GEN_NO_EVENT: no event detection + \arg DMAMUX_GEN_RISING: rising edge + \arg DMAMUX_GEN_FALLING: falling edge + \arg DMAMUX_GEN_RISING_FALLING: rising and falling edges + \param[out] none + \retval none +*/ +void dmamux_trigger_polarity_config(dmamux_generator_channel_enum channelx, uint32_t polarity) +{ + DMAMUX_RG_CHXCFG(channelx) &= ~DMAMUX_RG_CHXCFG_RGTP; + DMAMUX_RG_CHXCFG(channelx) |= (polarity & DMAMUX_RG_CHXCFG_RGTP); +} + +/*! + \brief configure number of DMA requests to be generated (API ID: 0x002BU) + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..3) + \param[in] number: DMA requests number to be generated + only one parameter can be selected which is shown as below: + \arg 1 - 32 + \param[out] none + \retval none +*/ +void dmamux_request_generate_number_config(dmamux_generator_channel_enum channelx, uint32_t number) +{ + DMAMUX_RG_CHXCFG(channelx) &= ~DMAMUX_RG_CHXCFG_NBRG; + DMAMUX_RG_CHXCFG(channelx) |= RG_CHXCFG_NBRG((number - 1U) & DMAMUX_RG_CHXCFG_NBRG); +} + +/*! + \brief configure trigger input identification (API ID: 0x002CU) + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..3) + \param[in] id: trigger input identification + only one parameter can be selected which is shown as below: + \arg DMAMUX_TRIGGER_EXTI0: trigger input is EXTI0 + \arg DMAMUX_TRIGGER_EXTI1: trigger input is EXTI1 + \arg DMAMUX_TRIGGER_EXTI2: trigger input is EXTI2 + \arg DMAMUX_TRIGGER_EXTI3: trigger input is EXTI3 + \arg DMAMUX_TRIGGER_EXTI4: trigger input is EXTI4 + \arg DMAMUX_TRIGGER_EXTI5: trigger input is EXTI5 + \arg DMAMUX_TRIGGER_EXTI6: trigger input is EXTI6 + \arg DMAMUX_TRIGGER_EXTI7: trigger input is EXTI7 + \arg DMAMUX_TRIGGER_EXTI8: trigger input is EXTI8 + \arg DMAMUX_TRIGGER_EXTI9: trigger input is EXTI9 + \arg DMAMUX_TRIGGER_EXTI10: trigger input is EXTI10 + \arg DMAMUX_TRIGGER_EXTI11: trigger input is EXTI11 + \arg DMAMUX_TRIGGER_EXTI12: trigger input is EXTI12 + \arg DMAMUX_TRIGGER_EXTI13: trigger input is EXTI13 + \arg DMAMUX_TRIGGER_EXTI14: trigger input is EXTI14 + \arg DMAMUX_TRIGGER_EXTI15: trigger input is EXTI15 + \arg DMAMUX_TRIGGER_EVT0_OUT: trigger input is Evt0_out + \arg DMAMUX_TRIGGER_EVT1_OUT: trigger input is Evt1_out + \arg DMAMUX_TRIGGER_EVT2_OUT: trigger input is Evt2_out + \arg DMAMUX_TRIGGER_TIMER13_O: trigger input is TIMER13 O + \param[out] none + \retval none +*/ +void dmamux_trigger_id_config(dmamux_generator_channel_enum channelx, uint32_t id) +{ + DMAMUX_RG_CHXCFG(channelx) &= ~DMAMUX_RG_CHXCFG_TID; + DMAMUX_RG_CHXCFG(channelx) |= (id & DMAMUX_RG_CHXCFG_TID); +} + +/*! + \brief get DMAMUX flag (API ID: 0x002CU) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun flag + \arg DMAMUX_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun flag + \arg DMAMUX_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun flag + \arg DMAMUX_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun flag + \arg DMAMUX_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dmamux_flag_get(dmamux_flag_enum flag) +{ + FlagStatus reval = RESET; + if((uint32_t)RESET != (DMAMUX_REG_VAL(flag) & BIT(DMAMUX_BIT_POS(flag)))) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} + +/*! + \brief clear DMAMUX flag (API ID: 0x002DU) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun flag + \arg DMAMUX_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun flag + \arg DMAMUX_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun flag + \arg DMAMUX_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun flag + \arg DMAMUX_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun flag + \param[out] none + \retval none +*/ +void dmamux_flag_clear(dmamux_flag_enum flag) +{ + DMAMUX_REG_VAL3(flag) = BIT(DMAMUX_BIT_POS(flag)); +} + +/*! + \brief get DMAMUX interrupt flag (API ID: 0x002EU) + \param[in] int_flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dmamux_interrupt_flag_get(dmamux_interrupt_flag_enum int_flag) +{ + FlagStatus reval = RESET; + uint32_t intenable, flagstatus ; + /* get the interrupt enable bit status */ + intenable = (DMAMUX_REG_VAL2(int_flag) & BIT(DMAMUX_BIT_POS2(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (DMAMUX_REG_VAL(int_flag) & BIT(DMAMUX_BIT_POS(int_flag))); + + if((0U != flagstatus) && (0U != intenable)) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} + +/*! + \brief clear DMAMUX interrupt flag (API ID: 0x002FU) + \param[in] int_flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt flag + \arg DMAMUX_INT_FLAG_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt flag + \param[out] none + \retval none +*/ +void dmamux_interrupt_flag_clear(dmamux_interrupt_flag_enum int_flag) +{ + DMAMUX_REG_VAL3(int_flag) = BIT(DMAMUX_BIT_POS(int_flag)); +} + +/*! + \brief enable DMAMUX interrupt (API ID: 0x0030U) + \param[in] interrupt: specify which interrupt to enable + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt + \arg DMAMUX_INT_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt + \arg DMAMUX_INT_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt + \arg DMAMUX_INT_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt + \arg DMAMUX_INT_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt + \param[out] none + \retval none +*/ +void dmamux_interrupt_enable(dmamux_interrupt_enum interrupt) +{ + DMAMUX_REG_VAL(interrupt) |= BIT(DMAMUX_BIT_POS(interrupt)); +} + +/*! + \brief disable DMAMUX interrupt (API ID: 0x0031U) + \param[in] interrupt: specify which interrupt to disable + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt + \arg DMAMUX_INT_GENCH0_TO: DMAMUX request generator channel 0 trigger overrun interrupt + \arg DMAMUX_INT_GENCH1_TO: DMAMUX request generator channel 1 trigger overrun interrupt + \arg DMAMUX_INT_GENCH2_TO: DMAMUX request generator channel 2 trigger overrun interrupt + \arg DMAMUX_INT_GENCH3_TO: DMAMUX request generator channel 3 trigger overrun interrupt + \param[out] none + \retval none +*/ +void dmamux_interrupt_disable(dmamux_interrupt_enum interrupt) +{ + DMAMUX_REG_VAL(interrupt) &= ~BIT(DMAMUX_BIT_POS(interrupt)); +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_exti.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_exti.c new file mode 100644 index 0000000..4919b04 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_exti.c @@ -0,0 +1,260 @@ +/*! + \file gd32c2x1_exti.c + \brief EXTI driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_exti.h" + +#define EXTI_REG_RESET_VALUE ((uint32_t)0x00000000U) + +/*! + \brief deinitialize the EXTI (API ID: 0x0001U) + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of all the EXTI registers */ + EXTI_INTEN = EXTI_REG_RESET_VALUE; + EXTI_EVEN = EXTI_REG_RESET_VALUE; + EXTI_RTEN = EXTI_REG_RESET_VALUE; + EXTI_FTEN = EXTI_REG_RESET_VALUE; + EXTI_SWIEV = EXTI_REG_RESET_VALUE; +} + +/*! + \brief initialize the EXTI, enable the configuration of EXTI initialize (API_ID: 0x0002U) + \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..23): 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: + break; + default: + break; + } +} + +/*! + \brief enable the interrupts from EXTI line x (API_ID: 0x0003U) + \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..23): 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 (API_ID: 0x0004U) + \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..23): 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 (API_ID: 0x0005U) + \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..23): 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 (API_ID: 0x0006U) + \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..23): 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 (API_ID: 0x0007U) + \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..23): 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 (API_ID: 0x0008U) + \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..23): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t)linex; +} + +/*! + \brief get EXTI line x interrupt pending flag (API_ID: 0x0009U) + \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..23): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + FlagStatus reval = RESET; + + if(0U != (EXTI_PD & (uint32_t)linex)) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief clear EXTI line x interrupt pending flag (API_ID: 0x000AU) + \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..23): EXTI line x + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief get EXTI line x interrupt pending flag (API_ID: 0x000BU) + \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..23): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + FlagStatus reval = RESET; + + if(0U != (EXTI_PD & (uint32_t)linex)) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief clear EXTI line x interrupt pending flag (API_ID: 0x000CU) + \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..23): 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/gd32c2x1/standard_peripheral/source/gd32c2x1_fmc.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_fmc.c new file mode 100644 index 0000000..370a85f --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_fmc.c @@ -0,0 +1,1249 @@ +/*! + \file gd32c2x1_fmc.c + \brief FMC driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_fmc.h" + +#define FMC_FLAG_MASK ((uint32_t)0x0000C2FBU) /*!< FMC flag mask */ +#define FMC_INTERRUPT_CFG_MASK ((uint32_t)0x07000000U) /*!< FMC interrupt config mask */ +#define FMC_INTERRUPT_FLAG_MASK ((uint32_t)0x00004003U) /*!< FMC interrupt flag mask */ +#define FMC_DFLASH_WP_CFG_MASK ((uint32_t)0x0000000FU) /*!< FMC data flash config mask */ + +/*! + \brief unlock the main FMC operation (API_ID(0x0001U)) + it is better to used in pairs with fmc_lock + \param[in] none + \param[out] none + \retval none +*/ +void fmc_unlock(void) +{ + if(0U != (FMC_CTL & FMC_CTL_LK)) { + /* write the FMC unlock key */ + FMC_KEY = FMC_UNLOCK_KEY0; + FMC_KEY = FMC_UNLOCK_KEY1; + } +} + +/*! + \brief lock the main FMC operation (API_ID(0x0002U)) + it is better to used in pairs with fmc_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit */ + FMC_CTL |= FMC_CTL_LK; +} + +/*! + \brief get the main flash empty check status (API_ID(0x0003U)) + \param[in] none + \param[out] none + \retval empty check status +*/ +FlagStatus fmc_main_flash_empty_stat_get(void) +{ + FlagStatus status; + + if(0U!=(FMC_WS & FMC_WS_MFPE)) { + status = SET; + } else { + status = RESET; + } + + return status; +} + +/** + * \brief modify the main flash empty check status (API_ID(0x0004U)) + \param[in] empty_check_status: status of check + only one parameter can be selected which is shown as below: + \arg FMC_WS_MFPE_PROGRAMMED: the first location of main flash is programmed + \arg FMC_WS_MFPE_EMPTY: the first location of main flash is empty + \param[out] none + \retval none +*/ +void fmc_main_flash_empty_stat_modify(uint32_t empty_check_status) +{ + FMC_WS &= ~FMC_WS_MFPE; + FMC_WS |= empty_check_status & FMC_WS_MFPE; +} + +/*! + \brief set the wait state (API_ID(0x0005U)) + \param[in] wscnt: wait state + only one parameter can be selected which is shown as below: + \arg FMC_WAIT_STATE_0: 0 wait state added + \arg FMC_WAIT_STATE_1: 1 wait state added + \param[out] none + \retval none +*/ +void fmc_wscnt_set(uint32_t wscnt) +{ + uint32_t reg = 0U; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_FMC_WAIT_STATE(wscnt)) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x0005U), ERR_PARAM_OUT_OF_RANGE); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* set the wait state counter value */ + reg = FMC_WS; + reg &= ~FMC_WS_WSCNT; + reg |= wscnt & FMC_WS_WSCNT; + FMC_WS = reg; + } +} + +/*! + \brief enable pre-fetch (API_ID(0x0006U)) + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_enable(void) +{ + FMC_WS |= FMC_WS_PFEN; +} + +/*! + \brief disable pre-fetch (API_ID(0x0007U)) + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_disable(void) +{ + FMC_WS &= ~FMC_WS_PFEN; +} + +/*! + \brief enable IBUS cache (API_ID(0x0008U)) + \param[in] none + \param[out] none + \retval none +*/ +void fmc_icache_enable(void) +{ + FMC_WS |= FMC_WS_ICEN; +} + +/*! + \brief disable IBUS cache (API_ID(0x0009U)) + \param[in] none + \param[out] none + \retval none +*/ +void fmc_icache_disable(void) +{ + FMC_WS &= ~FMC_WS_ICEN; +} + +/*! + \brief reset IBUS cache (API_ID(0x000AU)) + \param[in] none + \param[out] none + \retval none +*/ +void fmc_icache_reset(void) +{ + FMC_WS |= FMC_WS_ICRST; +} + +/*! + \brief erase page (API_ID(0x000BU)) + \param[in] page_number: page offset + only one parameter can be selected which is shown as below: + \arg 0 ~ (max count of pages)-1 + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum fmc_page_erase(uint32_t page_number) +{ + fmc_state_enum fmc_state; +#ifdef FW_DEBUG_ERR_REPORT + if(page_number >= MAIN_FLASH_PAGE_TOTAL_NUM) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x000BU), ERR_PARAM_OUT_OF_RANGE); + fmc_state = FMC_UNDEFINEDERR; + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* select the bank page in */ + FMC_CTL &= ~FMC_CTL_PN; + FMC_CTL |= page_number << CTL_PN_OFFSET; + FMC_CTL |= FMC_CTL_PER; + + /* start page erase */ + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + FMC_CTL &= ~FMC_CTL_PER; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief erase whole chip (API_ID(0x000CU)) + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error +*/ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start chip erase */ + FMC_CTL |= FMC_CTL_MER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bit */ + FMC_CTL &= ~FMC_CTL_MER; + } + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a double word at the given address in main flash (API_ID(0x000DU)) + \param[in] address: address to program + \param[in] data: double word to program + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data) +{ + uint32_t data0, data1; + fmc_state_enum fmc_state; +#ifdef FW_DEBUG_ERR_REPORT + if((address % 8U) != 0U) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x000DU), ERR_PARAM_OUT_OF_RANGE); + fmc_state = FMC_UNDEFINEDERR; + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + data0 = (uint32_t)(data & 0xFFFFFFFFU); + data1 = (uint32_t)((data >> 32U) & 0xFFFFFFFFU); + + if(FMC_READY == fmc_state) { + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + REG32(address) = data0; + REG32(address + 4U) = data1; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief fast program a row at the corresponding address (API_ID(0x000EU)) + \param[in] address: address to program + \param[in] data_buf: data buffer to program + \param[out] none + \retval state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum fmc_fast_program(uint32_t address, uint32_t data_buf) +{ + uint8_t index; + fmc_state_enum fmc_state; +#ifdef FW_DEBUG_ERR_REPORT + if((address % 16U) != 0U) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x000EU), ERR_PARAM_OUT_OF_RANGE); + fmc_state = FMC_UNDEFINEDERR; + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* set the FSTPG bit to start program */ + FMC_CTL |= FMC_CTL_FSTPG; + + /* program the row data */ + for(index = 0U; index < DOUBLEWORD_CNT_IN_ROW; index++) { + REG32(address) = REG32(data_buf); + REG32(address + 4U) = REG32(data_buf + 4U); + address += 8U; + data_buf += 8U; + } + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the FSTPG bit */ + FMC_CTL &= ~FMC_CTL_FSTPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable debugger (API_ID(0x000FU)) + \param[in] none + \param[out] none + \retval none +*/ +void fmc_debugger_enable(void) +{ + FMC_WS |= FMC_WS_DBGEN; +} + +/*! + * \brief disable debugger (API_ID(0x0010U)) + \param[in] none + \param[out] none + \retval none + */ +void fmc_debugger_disable(void) +{ + FMC_WS &= ~FMC_WS_DBGEN; +} + +/*! + \brief enable secure area protection (API_ID(0x0011U)) + \param[in] none + \param[out] none + \retval none +*/ +void fmc_scr_area_enable(void) +{ + FMC_CTL |= FMC_CTL_SCR; +} + +/*! + \brief unlock the option bytes operation (API_ID(0x0012U)) + it is better to used in pairs with ob_lock + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(0U != (FMC_CTL & FMC_CTL_OBLK)) { + /* write the FMC ob unlock key */ + FMC_OBKEY = OB_UNLOCK_KEY0; + FMC_OBKEY = OB_UNLOCK_KEY1; + } +} + +/*! + \brief lock the option bytes operation (API_ID(0x0013U)) + it is better to used in pairs with ob_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_lock(void) +{ + /* reset the OBWEN bit */ + FMC_CTL &= ~FMC_CTL_OBLK; +} + +/*! + \brief reload the option bytes operation (API_ID(0x0014U)) + \param[in] none + \param[out] none + \retval none +*/ +void ob_reload(void) +{ + /* set the OBRLD bit */ + FMC_CTL |= FMC_CTL_OBRLD; +} + +/*! + \brief program the option bytes USER (API_ID(0x0015U)) + programmer must ensure FMC & option bytes are both unlocked before calling this function + this function can only clear the corresponding bits to be 0 rather than 1. + \param[in] ob_user: user option bytes. When write one parameter, the corresponding mask should be set. + one or more (bitwise OR) parameters can be selected which are shown as below: + \arg OB_NRST_PIN_INPUT_MODE/OB_NRST_PIN_NORMAL_GPIO/OB_NRST_PIN_INPUT_OUTPUT_MODE: reset pin mode + \arg OB_NBOOT0_VALUE_0/OB_NBOOT0_VALUE_1: boot0 value 0 or value 1 + \arg OB_NBOOT1_VALUE_0/OB_NBOOT1_VALUE_1: boot1 value 0 or value 1 + \arg OB_SWBOOT0_FROM_OB_BOOT0/OB_SWBOOT0_FROM_PIN: boot by option byte value or by PB8/BOOT0 pin + \arg OB_SRAM_PARITY_CHECK_ENABLE/OB_SRAM_PARITY_CHECK_DISABLE: SRAM parity check enable configuration + \arg OB_SRAM_ECC_ENABLE/OB_SRAM_ECC_DISABLE: SRAM ECC enable configuration + \arg OB_HXTAL_REMAP_ENABLE/OB_HXTAL_REMAP_DISABLE: HXTAL remapping + \arg OB_WWDGT_HW/OB_WWDGT_SW: hardware or software window watchdog timer + \arg OB_FWDGT_HW/OB_FWDGT_SW: hardware or software free watchdog timer + \arg OB_STDBY_RST/OB_STDBY_NRST: reset or not entering standby mode + \arg OB_DEEPSLEEP_RST/OB_DEEPSLEEP_NRST: reset or not entering deep sleep mode + \arg OB_BORR_TH_VALUE0/OB_BORR_TH_VALUE1/OB_BORR_TH_VALUE2/OB_BORR_TH_VALUE3: BOR rising threshold value + \arg OB_BORF_TH_VALUE0/OB_BORF_TH_VALUE1/OB_BORF_TH_VALUE2/OB_BORF_TH_VALUE3: BOR falling threshold value + \arg OB_BORST_DISABLE/OB_BORST_ENABLE: BOR reset configuration + \param[in] ob_user_mask: user bits mask. They correspond to the above parameter value one by one. + one or more (bitwise OR) parameters can be selected which are shown as below: + \arg FMC_OBCTL_NRST_MDSEL: reset pin mode bit mask + \arg FMC_OBCTL_NBOOT0: NBOOT0 option bit mask + \arg FMC_OBCTL_NBOOT1: NBOOT1 option bit mask + \arg FMC_OBCTL_SWBT0: software BOOT0 bit mask + \arg FMC_OBCTL_SRAM_ECC_EN: SRAM ECC disable bit mask + \arg FMC_OBCTL_HXTAL_REMAP: HXTAL remapping bit mask + \arg FMC_OBCTL_NWWDG_HW: window watchdog configuration bit mask + \arg FMC_OBCTL_NFWDG_HW: free watchdog configuration bit mask + \arg FMC_OBCTL_NRST_STDBY: option byte standby reset bit mask + \arg FMC_OBCTL_NRST_DPSLP: option byte deepsleep reset bit mask + \arg FMC_OBCTL_BORR_TH: BORR threshold bits mask + \arg FMC_OBCTL_BORF_TH: BORF threshold bits mask + \arg FMC_OBCTL_BORST_EN: brown out reset bit mask + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: high security protection + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum ob_user_write(uint32_t ob_user, uint32_t ob_user_mask) +{ + uint32_t obctl_reg; + fmc_state_enum fmc_state = FMC_UNDEFINEDERR; +#ifdef FW_DEBUG_ERR_REPORT + /* ob_user_mask is not supported */ + if(NOT_FMC_OB_USER_MASK(ob_user_mask)){ + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x0015U), ERR_PARAM_INVALID); + /* ob_user doesn't match ob_user_mask */ + } else if( 0u != (ob_user & (~ob_user_mask))){ + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x0015U), ERR_PARAM_INVALID); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* check the option bytes security protection value */ + if(FMC_HSPC == (FMC_OBCTL & FMC_OBCTL_SPC)) { + fmc_state = FMC_OB_HSPC; + } else { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obctl_reg = FMC_OBCTL; + FMC_OBCTL = (obctl_reg & (~ob_user_mask)) | ob_user; + FMC_CTL |= FMC_CTL_OBSTART; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + } + } + return fmc_state; +} + +/*! + \brief configure security protection level (API_ID(0x0016U)) + programmer must ensure FMC & option bytes are both unlocked before calling this function + \param[in] ob_spc: specify security protection + 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 state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: high security protection +*/ +fmc_state_enum ob_security_protection_level_config(uint8_t ob_spc) +{ + uint32_t obctl_reg; + fmc_state_enum fmc_state; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + obctl_reg = FMC_OBCTL; + + /* reset the SPC, set according to ob_spc */ + obctl_reg &= ~FMC_OBCTL_SPC; + obctl_reg |= (uint32_t)ob_spc; + FMC_OBCTL = obctl_reg; + FMC_CTL |= FMC_CTL_OBSTART; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure the option bytes DCRP area (API_ID(0x0017U)) + \param[in] dcrp_area: DCRP area + only one parameter can be selected which is shown as below: + \arg DCRP_AREA_0: the DCRP area 0 + \arg DCRP_AREA_1: the DCRP area 1 + \param[in] dcrp_eren: DCRP area erase enable bit + \arg OB_DCRP_AREA_ERASE_DISABLE: DCRP area is not erased when low security protection to no security protection + \arg OB_DCRP_AREA_ERASE_ENABLE: DCRP area is erased when low security protection to no security protection + \param[in] dcrp_start: the first page offset of the DCRP area + \param[in] dcrp_end: the last page offset of the DCRP area + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: high security protection + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum ob_dcrp_area_config(uint32_t dcrp_area, uint32_t dcrp_eren, uint32_t dcrp_start, + uint32_t dcrp_end) +{ + uint32_t reg_value; + fmc_state_enum fmc_state; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_FMC_DCRP_AREA_VALID_CFG(dcrp_area,dcrp_eren,dcrp_start,dcrp_end)) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x0017U), ERR_PARAM_OUT_OF_RANGE); + fmc_state = FMC_UNDEFINEDERR; + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* check the option bytes security protection value */ + if(FMC_HSPC == (FMC_OBCTL & FMC_OBCTL_SPC)) { + fmc_state = FMC_OB_HSPC; + } else { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* configure DCRP area */ + if(DCRP_AREA_0 == dcrp_area) { + FMC_DCRP_SADDR0 = dcrp_start << DCRP_SADDR_OFFSET; + reg_value = FMC_DCRP_EADDR0; + reg_value &= ~FMC_DCRP_EADDR0_DCRP_EREN; + reg_value &= ~FMC_DCRP_EADDR0_DCRP0_EADDR; + reg_value |= (dcrp_end << DCRP_EADDR_OFFSET); + FMC_DCRP_EADDR0 = reg_value; + } else{ + FMC_DCRP_SADDR1 = dcrp_start << DCRP_SADDR_OFFSET; + FMC_DCRP_EADDR1 = dcrp_end << DCRP_EADDR_OFFSET; + } + + /* configure EREN */ + reg_value = FMC_DCRP_EADDR0; + reg_value &= ~FMC_DCRP_EADDR0_DCRP_EREN; + reg_value |= dcrp_eren; + FMC_DCRP_EADDR0 = reg_value; + + /* set the OBSTART bit in FMC_CTL register */ + FMC_CTL |= FMC_CTL_OBSTART; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure the option bytes write protection area (API_ID(0x0018U)) + \param[in] wp_area: write protection area + only one parameter can be selected which is shown as below: + \arg WP_AREA_0: the first area + \arg WP_AREA_1: the second area + \param[in] wp_start: first page of write protection area + \param[in] wp_end: last page of write protection area + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: high security protection + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum ob_write_protection_area_config(uint32_t wp_area, uint32_t wp_start, uint32_t wp_end) +{ + uint32_t value; + fmc_state_enum fmc_state; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_FMC_WP_AREA_VALID_CFG(wp_area,wp_start,wp_end)){ + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x0018U), ERR_PARAM_OUT_OF_RANGE); + fmc_state = FMC_UNDEFINEDERR; + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* check the option bytes security protection value */ + if(FMC_HSPC == (FMC_OBCTL & FMC_OBCTL_SPC)) { + fmc_state = FMC_OB_HSPC; + } else + { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + if(FMC_READY == fmc_state) { + value = (wp_start << WP_SADDR_OFFSET) | (wp_end << WP_EADDR_OFFSET); + /* configure the write protected area */ + if(WP_AREA_0 == wp_area) { + FMC_WP0 = value; + } else { + FMC_WP1 = value; + } + /* set the OBSTART bit in FMC_CTL register */ + FMC_CTL |= FMC_CTL_OBSTART; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure the option bytes secure area (API_ID(0x0019U)) + \param[in] secure_size: size of secure area in page unit + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: high security protection + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum ob_scr_area_config(uint32_t secure_size) +{ + uint32_t reg_value; + fmc_state_enum fmc_state; +#ifdef FW_DEBUG_ERR_REPORT + if(secure_size > MAIN_FLASH_PAGE_TOTAL_NUM) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x0019U), ERR_PARAM_OUT_OF_RANGE); + fmc_state = FMC_UNDEFINEDERR; + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* check the option bytes security protection value */ + if(FMC_HSPC == (FMC_OBCTL & FMC_OBCTL_SPC)) { + fmc_state = FMC_OB_HSPC; + } else { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* configure secure area */ + reg_value = FMC_SCR; + reg_value &= ~FMC_SCR_SCR_PAGE_CNT; + reg_value |= secure_size << SCR_PAGE_CNT_OFFSET; + FMC_SCR = reg_value; + } + + /* set the OBSTART bit in FMC_CTL register */ + FMC_CTL |= FMC_CTL_OBSTART; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure the option bytes boot lock (API_ID(0x001AU)) + \param[in] boot_config: boot configuration + only one parameter can be selected which is shown as below: + \arg OB_BOOT_LOCK_FROM_MAIN_FLASH: boot from main flash + \arg OB_BOOT_UNLOCK: unlock boot + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: high security protection + \arg FMC_UNDEFINEDERR: undefined error for function input parameter checking +*/ +fmc_state_enum ob_boot_lock_config(uint32_t boot_config) +{ + uint32_t reg_value; + fmc_state_enum fmc_state; + + /* check the option bytes security protection value */ + if(FMC_HSPC == (FMC_OBCTL & FMC_OBCTL_SPC)) { + fmc_state = FMC_OB_HSPC; + } else { + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + reg_value = FMC_SCR; + reg_value &= ~FMC_SCR_BOOTLK; + reg_value |= boot_config & FMC_SCR_BOOTLK; + FMC_SCR = reg_value; + + /* set the OBSTART bit in FMC_CTL register */ + FMC_CTL |= FMC_CTL_OBSTART; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get the value of option bytes USER (API_ID(0x001BU)) + \param[in] user_data_extract_info:user data extract information which include mask and start bit position + \arg OBCTL_USER_DATA_BORST_EN: brown out reset enable mask and it's start bit position + \arg OBCTL_USER_DATA_BOR_TH: BOR threshold mask and it's start bit position + \arg OBCTL_USER_DATA_BORR_TH: BOR threshold at rising VDD supply mask and it's start bit position + \arg OBCTL_USER_DATA_BORF_TH: BOR threshold at falling VDD supply mask and it's start bit position + \arg OBCTL_USER_DATA_NRST_DPSLP: option byte deepsleep reset value bit mask and it's start bit position + \arg OBCTL_USER_DATA_NRST_STDBY: option byte standby reset value bit mask and it's start bit position + \arg OBCTL_USER_DATA_NFWDG_HW: free watchdog configuration bit mask and it's start bit position + \arg OBCTL_USER_DATA_NWWDG_HW: window watchdog configuration bit mask and it's start bit position + \arg OBCTL_USER_DATA_HXTAL_REMAP: HXTAL remapping bit mask and it's start bit position + \arg OBCTL_USER_DATA_SRAM_ECC_EN: SRAM ECC enable bit mask and it's start bit position + \arg OBCTL_USER_DATA_SRAM_PARITY_CHECK: SRAM parity check configuration bit mask and it's start bit position + \arg OBCTL_USER_DATA_MLT_BND_SEC_EN: Multiple-bonding security enable bit mask and it's start bit position + \arg OBCTL_USER_DATA_SWBT0: software BOOT0 bit mask and it's start bit position + \arg OBCTL_USER_DATA_NBOOT1: NBOOT1 option bit mask and it's start bit position + \arg OBCTL_USER_DATA_NBOOT0: NBOOT0 option bit mask and it's start bit position + \arg OBCTL_USER_DATA_NRST_MDSEL: NRST pin mode bit mask and it's start bit position + \param[out] ob_user_data: the user data + \retval state of return user value + \arg INVLD_RETURN_VALUE: the area address is invalid + \arg VLD_RETURN_VALUE: the area address is valid +*/ +uint32_t ob_user_get(ob_user_data_extract_info_enum user_data_extract_info, uint8_t * ob_user_data) +{ + uint32_t ret = INVLD_RETURN_VALUE; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(ob_user_data)){ + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x001BU), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* return the FMC user option bytes value */ + uint32_t user_data_mask = (uint32_t)user_data_extract_info & 0xFFF0U; + uint8_t user_data_start_position = (uint8_t)((uint32_t)user_data_extract_info & 0x000FU); + *ob_user_data = (uint8_t)((FMC_OBCTL & user_data_mask) >> user_data_start_position); + ret = VLD_RETURN_VALUE; + } + return ret; +} + +/*! + \brief get the value of option bytes security protection level in FMC_OBCTL register (API_ID(0x001CU)) + \param[in] none + \param[out] none + \retval protection level + \arg FMC_NSPC: no protection + \arg FMC_LSPC: protection level low + \arg FMC_HSPC: protection level high +*/ +uint8_t ob_security_protection_level_get(void) +{ + return (uint8_t)((FMC_OBCTL & FMC_OBCTL_SPC) >> OBCTL_SPC_OFFSET); +} + +/*! + \brief get configuration of DCRP area (API_ID(0x001DU)) + \param[in] dcrp_area: DCRP area + only one parameter can be selected which is shown as below: + \arg DCRP_AREA_0: the DCRP area 0 + \arg DCRP_AREA_1: the DCRP area 1 + \param[out] dcrp_erase_option: erase option of DCRP area + \param[out] dcrp_start: start address of DCRP area + \param[out] dcrp_end: end address of DCRP area + \retval state of address + \arg INVLD_RETURN_VALUE: the area address is invalid + \arg VLD_RETURN_VALUE: the area address is valid +*/ +uint32_t ob_dcrp_area_get(uint32_t dcrp_area, uint32_t *dcrp_erase_option, + uint32_t *dcrp_start, uint32_t *dcrp_end) +{ + uint32_t dcrp_area_start, dcrp_area_end; + uint32_t ret = INVLD_RETURN_VALUE; +#ifdef FW_DEBUG_ERR_REPORT + if((dcrp_area != DCRP_AREA_0) && (dcrp_area != DCRP_AREA_1)) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x001DU), ERR_PARAM_OUT_OF_RANGE); + } else if((NOT_VALID_POINTER(dcrp_erase_option)) || + (NOT_VALID_POINTER(dcrp_start)) || + (NOT_VALID_POINTER(dcrp_end))) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x001DU), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + if(DCRP_AREA_0 == dcrp_area) { + dcrp_area_start = (FMC_DCRP_SADDR0 & FMC_DCRP_SADDR0_DCRP0_SADDR) >> DCRP_SADDR_OFFSET; + dcrp_area_end = (FMC_DCRP_EADDR0 & FMC_DCRP_EADDR0_DCRP0_EADDR) >> DCRP_EADDR_OFFSET; + + } else { + dcrp_area_start = (FMC_DCRP_SADDR1 & FMC_DCRP_SADDR1_DCRP1_SADDR) >> DCRP_SADDR_OFFSET; + dcrp_area_end = (FMC_DCRP_EADDR1 & FMC_DCRP_EADDR1_DCRP1_EADDR) >> DCRP_EADDR_OFFSET; + } + /* get erase option of DCRP area */ + *dcrp_erase_option = (FMC_DCRP_EADDR0 & FMC_DCRP_EADDR0_DCRP_EREN) >> DCRP_EREN_OFFSET; + /* get start address and end address of DCRP area */ + *dcrp_start = MAIN_FLASH_BASE_ADDRESS + dcrp_area_start * DCRP_AREA_SUBPAGE_SIZE; + *dcrp_end = MAIN_FLASH_BASE_ADDRESS + (dcrp_area_end + 1U) * DCRP_AREA_SUBPAGE_SIZE - 1U; + + if(dcrp_area_start <= dcrp_area_end) { + /* the DCRP area is valid */ + ret = VLD_RETURN_VALUE; + } else { + /* the DCRP area is invalid */ + ret = INVLD_RETURN_VALUE; + } + } + return ret; +} + +/*! + \brief get address of write protection area (API_ID(0x001EU)) + \param[in] wp_area: write protection area + only one parameter can be selected which is shown as below: + \arg WP_AREA_0: write protection area 0 + \arg WP_AREA_1: write protection area 1 + \param[out] wp_start: start address of write protection area + \param[out] wp_end: end address of write protection area + \retval state of address + \arg INVLD_RETURN_VALUE: the area address is invalid + \arg VLD_RETURN_VALUE: the area address is valid +*/ +uint32_t ob_write_protection_area_get(uint32_t wp_area, uint32_t *wp_start, + uint32_t *wp_end) +{ + uint32_t wp_area_start , wp_area_end ; + uint32_t ret = INVLD_RETURN_VALUE; +#ifdef FW_DEBUG_ERR_REPORT + if((wp_area != WP_AREA_0) && (wp_area != WP_AREA_1)) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x001EU), ERR_PARAM_OUT_OF_RANGE); + } else if((NOT_VALID_POINTER(wp_start)) || + (NOT_VALID_POINTER(wp_end))) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x001EU), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + if(WP_AREA_0 == wp_area) { + wp_area_start = (FMC_WP0 & FMC_WP0_WP0_SADDR) >> WP_SADDR_OFFSET; + wp_area_end = (FMC_WP0 & FMC_WP0_WP0_EADDR) >> WP_EADDR_OFFSET; + } else { + wp_area_start = (FMC_WP1 & FMC_WP1_WP1_SADDR) >> WP_SADDR_OFFSET; + wp_area_end = (FMC_WP1 & FMC_WP1_WP1_EADDR) >> WP_EADDR_OFFSET; + } + + *wp_start = MAIN_FLASH_BASE_ADDRESS + wp_area_start * WP_AREA_SUBPAGE_SIZE; + *wp_end = MAIN_FLASH_BASE_ADDRESS + (wp_area_end + 1U) * WP_AREA_SUBPAGE_SIZE - 1U; + + if(wp_area_start <= wp_area_end) { + /* the write protected area is valid */ + ret = VLD_RETURN_VALUE; + } else { + /* the write protected area is invalid */ + ret = INVLD_RETURN_VALUE; + } + } + return ret; +} +/*! + \brief get size of secure area (API_ID(0x001FU)) + \param[out] scr_area_byte_cnt: secure area size in byte unit + \retval none +*/ +uint32_t ob_scr_area_get(uint32_t *scr_area_byte_cnt) +{ + uint32_t scr_area_byte_size; + uint32_t ret = INVLD_RETURN_VALUE; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(scr_area_byte_cnt)) { + fw_debug_report_err(FMC_MODULE_ID, API_ID(0x001FU), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + scr_area_byte_size = (FMC_SCR & FMC_SCR_SCR_PAGE_CNT) >> SCR_PAGE_CNT_OFFSET; + *scr_area_byte_cnt = scr_area_byte_size * MAIN_FLASH_PAGE_SIZE; + ret = VLD_RETURN_VALUE; + } + return ret; +} + +/*! + \brief get boot lock configuration (API_ID(0x0020U)) + \param[in] none + \param[out] none + \retval boot configuration + \arg OB_BOOT_LOCK_FROM_MAIN_FLASH: boot from main flash + \arg OB_BOOT_UNLOCK: unlock boot +*/ +uint32_t ob_boot_lock_get(void) +{ + return (uint32_t)(FMC_SCR & FMC_SCR_BOOTLK); +} + +/*! + \brief get FMC flag status (API_ID(0x0021U)) + \param[in] flag: FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_BUSY: FMC operation is in progress + \arg FMC_FLAG_OBERR: option byte read error + \arg FMC_FLAG_WPERR: erase/program protection error + \arg FMC_FLAG_PGSERR: program sequence error + \arg FMC_FLAG_PGMERR: program size error + \arg FMC_FLAG_PGAERR: program alignment error + \arg FMC_FLAG_FSTPERR: fast programming error + \arg FMC_FLAG_RPERR: read protection error + \arg FMC_FLAG_PGERR: program error + \arg FMC_FLAG_OPRERR: operation error + \arg FMC_FLAG_ENDF: FMC end of operation flag error + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + + flag &= FMC_FLAG_MASK | FMC_STAT_BUSY; + if(0U!=(FMC_STAT & flag)) { + status = SET; + } + + /* return the state of corresponding FMC flag */ + return status; +} + +/*! + \brief clear the FMC flag (API_ID(0x0022U)) + \param[in] flag: FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_OBERR: option byte read error + \arg FMC_FLAG_WPERR: erase/program protection error + \arg FMC_FLAG_PGSERR: program sequence error + \arg FMC_FLAG_PGMERR: program size error + \arg FMC_FLAG_PGAERR: program alignment error + \arg FMC_FLAG_FSTPERR: fast programming error + \arg FMC_FLAG_RPERR: read protection error + \arg FMC_FLAG_PGERR: program error + \arg FMC_FLAG_OPRERR: operation error + \arg FMC_FLAG_ENDF: FMC end of operation flag error + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t flag) +{ + /* clear the flags */ + FMC_STAT = flag & FMC_FLAG_MASK; +} + +/*! + \brief enable FMC interrupt (API_ID(0x0023U)) + \param[in] interrupt: the FMC interrupt + only one parameter can be selected which is shown as below: + \arg FMC_INT_END: FMC end of operation interrupt + \arg FMC_INT_ERR: FMC error interrupt + \arg FMC_INT_RPERR: read protection error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(uint32_t interrupt) +{ + FMC_CTL |= interrupt & FMC_INTERRUPT_CFG_MASK; +} + +/*! + \brief disable FMC interrupt (API_ID(0x0024U)) + \param[in] interrupt: the FMC interrupt + only one parameter can be selected which is shown as below: + \arg FMC_INT_END: FMC end of operation interrupt + \arg FMC_INT_ERR: FMC error interrupt + \arg FMC_INT_RPERR: read protection error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(uint32_t interrupt) +{ + FMC_CTL &= ~(interrupt & FMC_INTERRUPT_CFG_MASK); +} + +/*! + \brief get FMC interrupt flag (API_ID(0x0025U)) + \param[in] flag: FMC interrupt flag + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag + \arg FMC_INT_FLAG_OPRERR: FMC error interrupt flag + \arg FMC_INT_FLAG_RPERR: read protection error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_interrupt_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + + flag &= FMC_INTERRUPT_FLAG_MASK; + + if(0U!=(FMC_STAT & flag)) { + status = SET; + } + /* return the state of corresponding FMC flag */ + return status; +} + +/*! + \brief clear FMC interrupt flag (API_ID(0x0026U)) + \param[in] flag: FMC interrupt flag + one or more parameters can be selected which is shown as below: + \arg FMC_INT_FLAG_END: FMC end of operation interrupt flag + \arg FMC_INT_FLAG_OPRERR: FMC error interrupt flag + \arg FMC_INT_FLAG_RPERR: read protection error interrupt flag + \param[out] none + \retval none +*/ +void fmc_interrupt_flag_clear(uint32_t flag) +{ + /* clear the flag */ + FMC_STAT = flag & FMC_INTERRUPT_FLAG_MASK; +} + +/*! + \brief get the FMC state (API_ID(0x0027U)) + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)) { + fmc_state = FMC_BUSY; + } else { + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)) { + fmc_state = FMC_WPERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGERR)) { + fmc_state = FMC_PGERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGSERR)) { + fmc_state = FMC_PGSERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGAERR)) { + fmc_state = FMC_PGAERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_RPERR)) { + fmc_state = FMC_RPERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGMERR)) { + fmc_state = FMC_PGMERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_FSTPERR)) { + fmc_state = FMC_FSTPERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_OPRERR)) { + fmc_state = FMC_OPRERR; + } else if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_OBERR)) { + fmc_state = FMC_OBERR; + } else { + /* illegal parameters */ + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not (API_ID(0x0028U)) + \param[in] timeout: timeout count + \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_OBERR: option byte read error + \arg FMC_RPERR: read protection error + \arg FMC_FSTPERR: fast programming error + \arg FMC_PGSERR: program sequence error + \arg FMC_PGMERR: program size error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_PGERR: program error + \arg FMC_OPRERR: operation error + \arg FMC_TOERR: timeout error + \note This function includes timeout exit scenarios. + Modify according to the user's actual usage scenarios. +*/ +fmc_state_enum fmc_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state; + + /* wait for FMC ready */ + do { + /* get FMC state */ + fmc_state = fmc_state_get(); + timeout--; + } while((FMC_BUSY == fmc_state) && (0x00U != timeout)); + + if(FMC_BUSY == fmc_state) { + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_fwdgt.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_fwdgt.c new file mode 100644 index 0000000..f7faf73 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_fwdgt.c @@ -0,0 +1,242 @@ +/*! + \file gd32c2x1_fwdgt.c + \brief FWDGT driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_fwdgt.h" + +/*! + \brief enable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND (API_ID(0x0001U)) + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_enable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; +} + +/*! + \brief disable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND (API_ID(0x0002U)) + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_disable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE; +} + +/*! + \brief start the FWDGT counter (API_ID(0x0003U)) + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the FWDGT counter prescaler value (API_ID(0x0004U)) + \param[in] prescaler_value: specify prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS + \note This function includes timeout exit scenarios. + Modify according to the user's actual usage scenarios. +*/ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value) +{ + ErrStatus prescaler_flag = SUCCESS; + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status; + + /* enable write access to FWDGT_PSC */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + /* wait until the PUD flag to be reset */ + do { + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + } while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + if((uint32_t)RESET != flag_status) { + prescaler_flag = ERROR; + } + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_value; + + return prescaler_flag; +} + +/*! + \brief configure the FWDGT counter reload value (API_ID(0x0005U)) + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS + \note This function includes timeout exit scenarios. + Modify according to the user's actual usage scenarios. +*/ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value) +{ + ErrStatus reload_flag = SUCCESS; + uint32_t timeout = FWDGT_RLD_TIMEOUT; + uint32_t flag_status; + + /* enable write access to FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + /* wait until the RUD flag to be reset */ + do { + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + } while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + if((uint32_t)RESET != flag_status) { + reload_flag = ERROR; + } + FWDGT_RLD = RLD_RLD(reload_value); + + return reload_flag; +} + +/*! + \brief configure the FWDGT counter window value (API_ID(0x0006U)) + \param[in] window_value: specify window value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS + \note This function includes timeout exit scenarios. + Modify according to the user's actual usage scenarios. +*/ +ErrStatus fwdgt_window_value_config(uint16_t window_value) +{ + ErrStatus window_flag = SUCCESS; + uint32_t timeout = FWDGT_WND_TIMEOUT; + uint32_t flag_status; + + /* enable write access to FWDGT_WND */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + /* wait until the WUD flag to be reset */ + do { + flag_status = FWDGT_STAT & FWDGT_STAT_WUD; + } while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + if((uint32_t)RESET != flag_status) { + window_flag = ERROR; + } + FWDGT_WND = WND_WND(window_value); + + return window_flag; +} + +/*! + \brief reload the counter of FWDGT (API_ID(0x0007U)) + \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 (API_ID(0x0008U)) + \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 + \note This function includes timeout exit scenarios. + Modify according to the user's actual usage scenarios. +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + ErrStatus fwdgt_flag = SUCCESS; + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status; + + /* 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) { + fwdgt_flag = 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) { + fwdgt_flag = ERROR; + } + FWDGT_RLD = RLD_RLD(reload_value); + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return fwdgt_flag; +} + +/*! + \brief get flag state of FWDGT (API_ID(0x0009U)) + \param[in] flag: flag to get + only one parameter can be selected which is shown as below: + \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going + \arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fwdgt_flag_get(uint16_t flag) +{ + FlagStatus fwdgt_flag = RESET; + + if((uint32_t)RESET != (FWDGT_STAT & flag)) { + fwdgt_flag = SET; + } + + return fwdgt_flag; +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_gpio.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_gpio.c new file mode 100644 index 0000000..df4470d --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_gpio.c @@ -0,0 +1,421 @@ +/*! + \file gd32c2x1_gpio.c + \brief GPIO driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_gpio.h" + +/*! + \brief reset GPIO port (API_ID: (0x0001U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \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 GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO mode (API_ID: (0x0002U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] mode: gpio pin mode + only one parameter can be selected which is shown as below: + \arg GPIO_MODE_INPUT: input mode + \arg GPIO_MODE_OUTPUT: output mode + \arg GPIO_MODE_AF: alternate function mode + \arg GPIO_MODE_ANALOG: analog mode + \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor + only one parameter can be selected which is shown as below: + \arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors + \arg GPIO_PUPD_PULLUP: with pull-up resistor + \arg GPIO_PUPD_PULLDOWN:with pull-down resistor + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin) +{ + uint16_t i; + uint32_t ctl, pupd; + + ctl = GPIO_CTL(gpio_periph); + pupd = GPIO_PUD(gpio_periph); + + for(i = 0U; i < 16U; i++) { + if(((((uint32_t)1U << i)) & (pin & BITS(0,15))) != (uint32_t)0U) { + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode & BITS(0,1)); + + /* 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 & BITS(0,1)); + } + } + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +/*! + \brief set GPIO output type and speed (API_ID: (0x0003U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] otype: gpio pin output mode + only one parameter can be selected which is shown as below: + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed: gpio pin output max speed + only one parameter can be selected which is shown as below: + \arg GPIO_OSPEED_LEVEL_0: output speed level 0 + \arg GPIO_OSPEED_LEVEL_1: output speed level 1 + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin) +{ + uint16_t i; + uint32_t ospeed; + + if(GPIO_OTYPE_OD == (otype & (uint8_t)BIT(0))) { + GPIO_OMODE(gpio_periph) |= (uint32_t)(pin & BITS(0,15)); + } else { + GPIO_OMODE(gpio_periph) &= (uint32_t)(~(pin & BITS(0,15))); + } + + /* get the specified pin output speed bits value */ + ospeed = GPIO_OSPD(gpio_periph); + + for(i = 0U; i < 16U; i++) { + if((((uint32_t)1U << i) & (pin & BITS(0,15))) != (uint32_t)0U) { + /* clear the specified pin output speed bits */ + ospeed &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeed |= GPIO_OSPEED_SET(i, speed & BIT(0)); + } + } + GPIO_OSPD(gpio_periph) = ospeed; +} + +/*! + \brief set GPIO pin bit (API_ID: (0x0004U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_set(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BOP(gpio_periph) = (uint32_t)(pin & BITS(0,15)); +} + +/*! + \brief reset GPIO pin bit (API_ID: (0x0005U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BC(gpio_periph) = (uint32_t)(pin & BITS(0,15)); +} + +/*! + \brief write data to the specified GPIO pin (API_ID: (0x0006U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[in] bit_value: SET or RESET + only one parameter can be selected which is shown as below: + \arg RESET: clear the port pin + \arg SET: set the port pin + \param[out] none + \retval none +*/ +void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value) +{ + if(RESET != bit_value) { + GPIO_BOP(gpio_periph) = (uint32_t)(pin & BITS(0,15)); + } else { + GPIO_BC(gpio_periph) = (uint32_t)(pin & BITS(0,15)); + } +} + +/*! + \brief write data to the specified GPIO port (API_ID: (0x0007U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \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 (API_ID: (0x0008U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + FlagStatus reval; + + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph) & ((pin & BITS(0,15))))) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief get GPIO port input status (API_ID: (0x0009U)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_input_port_get(uint32_t gpio_periph) +{ + return ((uint16_t)GPIO_ISTAT(gpio_periph)); +} + +/*! + \brief get GPIO pin output status (API_ID: (0x000AU)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + FlagStatus reval; + + if((uint32_t)RESET != (GPIO_OCTL(gpio_periph) & ((pin & BITS(0,15))))) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} + +/*! + \brief get GPIO port output status (API_ID: (0x000BU)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_output_port_get(uint32_t gpio_periph) +{ + return ((uint16_t)GPIO_OCTL(gpio_periph)); +} + +/*! + \brief set GPIO alternate function (API_ID: (0x000CU)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] alt_func_num: GPIO pin af function, please refer to specific device datasheet + only one parameter can be selected which is shown as below: + \arg GPIO_AF_0: RTC_OUT, CK_OUT0, SWDIO, SWCLK, SPI0, SPI1, USART0, EVENTOUT + \arg GPIO_AF_1: USART0, USART1, USART2, TIMER0, TIMER2, SPI1 + \arg GPIO_AF_2: TIMER0, TIMER13, TIMER15, TIMER16 + \arg GPIO_AF_3: SPI1, TIMER2, CK_OUT1, USART2 + \arg GPIO_AF_4: USART0, USART1, SPI1, TIMER13 + \arg GPIO_AF_5: TIMER0, TIMER16, I2S, USART0, SPI1 + \arg GPIO_AF_6: I2C0, I2C1, USART1, USART2, + \arg GPIO_AF_7: CMP0, CMP1, EVENTOUT, I2C0 + \arg GPIO_AF_8: SPI0 + \arg GPIO_AF_9: TIMER0, USART1 + \arg GPIO_AF_10: SPI0, TIMER0, TIMER15, TIMER16 + \arg GPIO_AF_11: CK_OUT1, TIMER0, TIMER2 + \arg GPIO_AF_12: USART0, TIMER0, TIMER2 + \arg GPIO_AF_13: TIMER2, TIMER13 + \arg GPIO_AF_14: USART0, TIMER15, I2C0 + \arg GPIO_AF_15: CK_OUT1, TIMER16, 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((((uint32_t)1U << i) & (pin & BITS(0,15))) != (uint32_t)0U) { + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i, alt_func_num & BITS(0,3)); + } + } + + for(i = 8U; i < 16U; i++) { + if((((uint32_t)1U << i) & (pin & BITS(0,15))) != (uint32_t)0U) { + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U, alt_func_num & BITS(0,3)); + } + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} + +/*! + \brief lock GPIO pin bit (API_ID: (0x000DU)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_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 & BITS(0,15)); + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + GPIO_LOCK(gpio_periph); + GPIO_LOCK(gpio_periph); +} + +/*! + \brief toggle GPIO pin status (API_ID: (0x000EU)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_TG(gpio_periph) = (uint32_t)(pin & BITS(0,15)); +} + +/*! + \brief toggle GPIO port status (API_ID: (0x000FU)) + \param[in] gpio_periph: GPIOx(x = A,B,C,D,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,F) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_i2c.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_i2c.c new file mode 100644 index 0000000..e85925c --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_i2c.c @@ -0,0 +1,976 @@ +/*! + \file gd32c2x1_i2c.c + \brief I2C driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_i2c.h" + +/* I2C register bit mask */ +#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */ +#define I2C_STATC_MASK ((uint32_t)0x00003F38U) /*!< i2c status clear mask */ +#define I2C_INT_EN_MASK ((uint32_t)0x000000FEU) /*!< I2C interrupt enable mask */ + +/* I2C register bit offset */ +#define CTL0_DNF_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of DNF in I2C_CTL0 */ +#define CTL1_BYTENUM_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BYTENUM in I2C_CTL1 */ +#define STAT_READDR_OFFSET ((uint32_t)0x00000011U) /*!< bit offset of READDR in I2C_STAT */ +#define TIMING_SCLL_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of SCLL in I2C_TIMING */ +#define TIMING_SCLH_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of SCLH in I2C_TIMING */ +#define TIMING_SDADELY_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SDADELY in I2C_TIMING */ +#define TIMING_SCLDELY_OFFSET ((uint32_t)0x00000014U) /*!< bit offset of SCLDELY in I2C_TIMING */ +#define TIMING_PSC_OFFSET ((uint32_t)0x0000001CU) /*!< bit offset of PSC in I2C_TIMING */ +#define SADDR1_ADDMSK_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of ADDMSK in I2C_SADDR1 */ +#define TIMEOUT_BUSTOB_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BUSTOB in I2C_TIMEOUT */ +#define CTL2_ADDMSK_OFFSET ((uint32_t)0x00000009U) /*!< bit offset of ADDM in I2C_CTL2 */ + +/*! + \brief reset I2C (API_ID(0x0001U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph) { + case I2C0: + /* disable I2C0 */ + i2c_disable(I2C0); + /* reset I2C0 */ + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + /* disable I2C1 */ + i2c_disable(I2C1); + /* reset I2C1 */ + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; + default: + break; + } +} + +/*! + \brief configure the timing parameters (API_ID(0x0002U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] psc: 0-0x0000000F, timing prescaler + \param[in] scl_dely: 0-0x0000000F, data setup time + \param[in] sda_dely: 0-0x0000000F, data hold time + \param[out] none + \retval none +*/ +void i2c_timing_config(uint32_t i2c_periph, uint32_t psc, uint32_t scl_dely, uint32_t sda_dely) +{ + /* clear PSC, SCLDELY, SDADELY bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_PSC; + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLDELY; + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SDADELY; + /* mask PSC, SCLDELY, SDADELY bits in I2C_TIMING register */ + psc = (uint32_t)(psc << TIMING_PSC_OFFSET) & I2C_TIMING_PSC; + scl_dely = (uint32_t)(scl_dely << TIMING_SCLDELY_OFFSET) & I2C_TIMING_SCLDELY; + sda_dely = (uint32_t)(sda_dely << TIMING_SDADELY_OFFSET) & I2C_TIMING_SDADELY; + /* write PSC, SCLDELY, SDADELY bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) |= (psc | scl_dely | sda_dely); +} + +/*! + \brief configure digital noise filter (API_ID(0x0003U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] filter_length: the length of filter spikes + only one parameter can be selected which is shown as below: + \arg FILTER_DISABLE: digital filter is disabled + \arg FILTER_LENGTH_1: digital filter is enabled and filter spikes with a length of up to 1 tI2CCLK + \arg FILTER_LENGTH_2: digital filter is enabled and filter spikes with a length of up to 2 tI2CCLK + \arg FILTER_LENGTH_3: digital filter is enabled and filter spikes with a length of up to 3 tI2CCLK + \arg FILTER_LENGTH_4: digital filter is enabled and filter spikes with a length of up to 4 tI2CCLK + \arg FILTER_LENGTH_5: digital filter is enabled and filter spikes with a length of up to 5 tI2CCLK + \arg FILTER_LENGTH_6: digital filter is enabled and filter spikes with a length of up to 6 tI2CCLK + \arg FILTER_LENGTH_7: digital filter is enabled and filter spikes with a length of up to 7 tI2CCLK + \arg FILTER_LENGTH_8: digital filter is enabled and filter spikes with a length of up to 8 tI2CCLK + \arg FILTER_LENGTH_9: digital filter is enabled and filter spikes with a length of up to 9 tI2CCLK + \arg FILTER_LENGTH_10: digital filter is enabled and filter spikes with a length of up to 10 tI2CCLK + \arg FILTER_LENGTH_11: digital filter is enabled and filter spikes with a length of up to 11 tI2CCLK + \arg FILTER_LENGTH_12: digital filter is enabled and filter spikes with a length of up to 12 tI2CCLK + \arg FILTER_LENGTH_13: digital filter is enabled and filter spikes with a length of up to 13 tI2CCLK + \arg FILTER_LENGTH_14: digital filter is enabled and filter spikes with a length of up to 14 tI2CCLK + \arg FILTER_LENGTH_15: digital filter is enabled and filter spikes with a length of up to 15 tI2CCLK + \param[out] none + \retval none +*/ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, uint32_t filter_length) +{ + /* clear DNF bits in I2C_CTL0 register */ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DNF; + /* mask DNF bits in I2C_CTL0 register */ + filter_length = (uint32_t)(filter_length << CTL0_DNF_OFFSET) & I2C_CTL0_DNF; + /* write DNF bits in I2C_CTL0 register */ + I2C_CTL0(i2c_periph) |= filter_length; +} + +/*! + \brief enable analog noise filter (API_ID(0x0004U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_ANOFF; +} + +/*! + \brief disable analog noise filter (API_ID(0x0005U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ANOFF; +} + +/*! + \brief configure the SCL high and low period of clock in master mode (API_ID(0x0006U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] sclh: 0-0x000000FF, SCL high period + \param[in] scll: 0-0x000000FF, SCL low period + \param[out] none + \retval none +*/ +void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll) +{ + /* clear SCLH, SCLL bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLH; + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLL; + /* mask SCLH, SCLL bits in I2C_TIMING register */ + sclh = (uint32_t)(sclh << TIMING_SCLH_OFFSET) & I2C_TIMING_SCLH; + scll = (uint32_t)(scll << TIMING_SCLL_OFFSET) & I2C_TIMING_SCLL; + /* write SCLH, SCLL bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) |= (sclh | scll); +} + +/*! + \brief configure I2C slave address and transfer direction in master mode (API_ID(0x0007U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] address: 0-0x3FF except reserved address, I2C slave address to be sent + \param[in] trans_direction: I2C transfer direction in master mode + only one parameter can be selected which is shown as below: + \arg I2C_MASTER_TRANSMIT: master transmit + \arg I2C_MASTER_RECEIVE: master receive + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction) +{ + /* configure slave address */ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_SADDRESS; + I2C_CTL1(i2c_periph) |= (uint32_t)(address & I2C_CTL1_SADDRESS); + /* configure transfer direction */ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_TRDIR; + I2C_CTL1(i2c_periph) |= (uint32_t)(trans_direction & I2C_CTL1_TRDIR); +} + +/*! + \brief 10-bit address header executes read direction only in master receive mode (API_ID(0x0008U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_header_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_HEAD10R; +} + +/*! + \brief 10-bit address header executes complete sequence in master receive mode (API_ID(0x0009U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_header_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_HEAD10R; +} + +/*! + \brief enable 10-bit addressing mode in master mode (API_ID(0x000AU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_ADD10EN; +} + +/*! + \brief disable 10-bit addressing mode in master mode (API_ID(0x000BU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_ADD10EN; +} + +/*! + \brief enable I2C automatic end mode in master mode (API_ID(0x000CU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_automatic_end_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_AUTOEND; +} + +/*! + \brief disable I2C automatic end mode in master mode (API_ID(0x000DU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_automatic_end_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_AUTOEND; +} + +/*! + \brief enable the response to a general call (API_ID(0x000EU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_GCEN; +} + +/*! + \brief disable the response to a general call (API_ID(0x000FU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_GCEN; +} + +/*! + \brief enable to stretch SCL low when data is not ready in slave mode (API_ID(0x0010U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SS; +} + +/*! + \brief disable to stretch SCL low when data is not ready in slave mode (API_ID(0x0011U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SS; +} + +/*! + \brief configure I2C slave address (API_ID(0x0012U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] address: I2C address + \param[in] addr_format: 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[out] none + \retval none +*/ +void i2c_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_format) +{ + /* configure ADDRESS[7:1] and address format */ + address = address & I2C_ADDRESS_MASK; + addr_format = addr_format & I2C_SADDR0_ADDFORMAT; + I2C_SADDR0(i2c_periph) = (addr_format | address); + /* enable I2C address in slave mode */ + I2C_SADDR0(i2c_periph) |= I2C_SADDR0_ADDRESSEN; +} + +/*! + \brief define which bits of ADDRESS[7:1] need to compare with the incoming address byte (API_ID(0x0013U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] compare_bits: the bits need to compare + one or more parameters can be selected which are shown as below: + ADDRESS_BIT1_COMPARE: address bit1 needs compare + ADDRESS_BIT2_COMPARE: address bit2 needs compare + ADDRESS_BIT3_COMPARE: address bit3 needs compare + ADDRESS_BIT4_COMPARE: address bit4 needs compare + ADDRESS_BIT5_COMPARE: address bit5 needs compare + ADDRESS_BIT6_COMPARE: address bit6 needs compare + ADDRESS_BIT7_COMPARE: address bit7 needs compare + \param[out] none + \retval none +*/ +void i2c_address_bit_compare_config(uint32_t i2c_periph, uint32_t compare_bits) +{ + /* clear ADDM bits in I2C_CTL2 register */ + I2C_CTL2(i2c_periph) &= ~I2C_CTL2_ADDM; + /* mask ADDM bits in I2C_CTL2 register */ + compare_bits = (compare_bits << CTL2_ADDMSK_OFFSET) & I2C_CTL2_ADDM; + /* write ADDM bits in I2C_CTL2 register */ + I2C_CTL2(i2c_periph) |= compare_bits; +} + +/*! + \brief disable I2C address in slave mode (API_ID(0x0014U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address_disable(uint32_t i2c_periph) +{ + I2C_SADDR0(i2c_periph) &= ~I2C_SADDR0_ADDRESSEN; +} + +/*! + \brief configure I2C second slave address (API_ID(0x0015U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] address: I2C address + \param[in] addr_mask: the bits not need to compare + only one parameters can be selected which are shown as below: + \arg ADDRESS2_NO_MASK: no mask, all the bits must be compared + \arg ADDRESS2_MASK_BIT1: ADDRESS2[1] is masked, only ADDRESS2[7:2] are compared + \arg ADDRESS2_MASK_BIT1_2: ADDRESS2[2:1] is masked, only ADDRESS2[7:3] are compared + \arg ADDRESS2_MASK_BIT1_3: ADDRESS2[3:1] is masked, only ADDRESS2[7:4] are compared + \arg ADDRESS2_MASK_BIT1_4: ADDRESS2[4:1] is masked, only ADDRESS2[7:5] are compared + \arg ADDRESS2_MASK_BIT1_5: ADDRESS2[5:1] is masked, only ADDRESS2[7:6] are compared + \arg ADDRESS2_MASK_BIT1_6: ADDRESS2[6:1] is masked, only ADDRESS2[7] are compared + \arg ADDRESS2_MASK_ALL: all the ADDRESS2[7:1] bits are masked + \param[out] none + \retval none +*/ +void i2c_second_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_mask) +{ + /* configure ADDRESS2[7:1] */ + I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDRESS2; + I2C_SADDR1(i2c_periph) |= (uint32_t)(address & I2C_SADDR1_ADDRESS2); + /* configure ADDRESS2[7:1] mask */ + I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDMSK2; + I2C_SADDR1(i2c_periph) |= (uint32_t)(addr_mask << SADDR1_ADDMSK_OFFSET) & I2C_SADDR1_ADDMSK2; + /* enable i2c second address in slave mode */ + I2C_SADDR1(i2c_periph) |= I2C_SADDR1_ADDRESS2EN; +} + +/*! + \brief disable I2C second address in slave mode (API_ID(0x0016U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_second_address_disable(uint32_t i2c_periph) +{ + I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDRESS2EN; +} + +/*! + \brief get received match address in slave mode (API_ID(0x0017U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval received match address +*/ +uint32_t i2c_received_address_get(uint32_t i2c_periph) +{ + return (uint32_t)((I2C_STAT(i2c_periph) & I2C_STAT_READDR) >> STAT_READDR_OFFSET); +} + +/*! + \brief enable slave byte control (API_ID(0x0018U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_slave_byte_control_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SBCTL; +} + +/*! + \brief disable slave byte control (API_ID(0x0019U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_slave_byte_control_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SBCTL; +} + +/*! + \brief generate a NACK in slave mode (API_ID(0x001AU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_nack_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_NACKEN; +} + +/*! + \brief enable wakeup from deep-sleep mode (API_ID(0x001BU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_wakeup_from_deepsleep_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_WUEN; +} + +/*! + \brief disable wakeup from deep-sleep mode (API_ID(0x001CU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_wakeup_from_deepsleep_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_WUEN; +} + +/*! + \brief enable I2C (API_ID(0x001DU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN; +} + +/*! + \brief disable I2C (API_ID(0x001EU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \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 (API_ID(0x001FU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_START; +} + +/*! + \brief generate a STOP condition on I2C bus (API_ID(0x0020U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_STOP; +} + +/*! + \brief I2C transmit data (API_ID(0x0021U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] data: data to be transmitted + \param[out] none + \retval none +*/ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) +{ + I2C_TDATA(i2c_periph) = (I2C_TDATA_TDATA & (uint32_t)data); +} + +/*! + \brief I2C receive data (API_ID(0x0022U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval received data +*/ +uint8_t i2c_data_receive(uint32_t i2c_periph) +{ + return (uint8_t)(I2C_RDATA(i2c_periph) & I2C_RDATA_RDATA); +} + +/*! + \brief enable I2C reload mode (API_ID(0x0023U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_reload_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_RELOAD; +} + +/*! + \brief disable I2C reload mode (API_ID(0x0024U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_reload_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_RELOAD; +} + +/*! + \brief configure number of bytes to be transferred (API_ID(0x0025U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] byte_number: 0x0-0xFF, number of bytes to be transferred + \param[out] none + \retval none +*/ +void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint8_t byte_number) +{ + I2C_CTL1(i2c_periph) &= (uint32_t)(~I2C_CTL1_BYTENUM); + I2C_CTL1(i2c_periph) |= (uint32_t)((uint32_t)byte_number << CTL1_BYTENUM_OFFSET); +} + +/*! + \brief enable I2C DMA for transmission or reception (API_ID(0x0026U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dma: I2C DMA + only one parameter can be selected which is shown as below: + \arg I2C_DMA_TRANSMIT: transmit data using DMA + \arg I2C_DMA_RECEIVE: receive data using DMA + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma) +{ + if(I2C_DMA_TRANSMIT == dma) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_DENT; + } else if(I2C_DMA_RECEIVE == dma) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_DENR; + } else { + /* do nothing */ + } +} + +/*! + \brief disable I2C DMA for transmission or reception (API_ID(0x0027U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dma: I2C DMA + only one parameter can be selected which is shown as below: + \arg I2C_DMA_TRANSMIT: transmit data using DMA + \arg I2C_DMA_RECEIVE: receive data using DMA + \param[out] none + \retval none +*/ +void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma) +{ + if(I2C_DMA_TRANSMIT == dma) { + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENT; + } else if(I2C_DMA_RECEIVE == dma) { + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENR; + } else { + /* do nothing */ + } +} + +/*! + \brief I2C transfers PEC value (API_ID(0x0028U)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_pec_transfer(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_PECTRANS; +} + +/*! + \brief enable I2C PEC calculation (API_ID(0x0029U)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_pec_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_PECEN; +} + +/*! + \brief disable I2C PEC calculation (API_ID(0x002AU)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_pec_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_PECEN; +} + +/*! + \brief get packet error checking value (API_ID(0x002BU)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval PEC value +*/ +uint32_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (I2C_PEC(i2c_periph) & I2C_PEC_PECV); +} + +/*! + \brief enable SMBus alert (API_ID(0x002CU)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_smbus_alert_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBALTEN; +} + +/*! + \brief disable SMBus alert (API_ID(0x002DU)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_smbus_alert_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBALTEN; +} + +/*! + \brief enable SMBus device default address (API_ID(0x002EU)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_smbus_default_addr_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBDAEN; +} + +/*! + \brief disable SMBus device default address (API_ID(0x002FU)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_smbus_default_addr_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBDAEN; +} + +/*! + \brief enable SMBus host address (API_ID(0x0030U)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_smbus_host_addr_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBHAEN; +} + +/*! + \brief disable SMBus host address (API_ID(0x0031U)) + \param[in] i2c_periph: I2Cx(x=0) + \param[out] none + \retval none +*/ +void i2c_smbus_host_addr_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBHAEN; +} + +/*! + \brief enable extended clock timeout detection (API_ID(0x0032U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_extended_clock_timeout_enable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_EXTOEN; +} + +/*! + \brief disable extended clock timeout detection (API_ID(0x0033U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_extended_clock_timeout_disable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_EXTOEN; +} + +/*! + \brief enable clock timeout detection (API_ID(0x0034U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_clock_timeout_enable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_TOEN; +} + +/*! + \brief disable clock timeout detection (API_ID(0x0035U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_clock_timeout_disable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOEN; +} + +/*! + \brief configure bus timeout B (API_ID(0x0036U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] timeout: bus timeout B(0-0xfff) + \param[out] none + \retval none +*/ +void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOB; + I2C_TIMEOUT(i2c_periph) |= (uint32_t)(timeout << TIMEOUT_BUSTOB_OFFSET) & I2C_TIMEOUT_BUSTOB; +} + +/*! + \brief configure bus timeout A (API_ID(0x0037U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] timeout: bus timeout A(0-0xfff) + \param[out] none + \retval none +*/ +void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOA; + I2C_TIMEOUT(i2c_periph) |= (uint32_t)(timeout & I2C_TIMEOUT_BUSTOA); +} + +/*! + \brief configure idle clock timeout detection (API_ID(0x0038U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] timeout: Idle clock timeout detection content + only one parameter can be selected which is shown as below: + \arg BUSTOA_DETECT_SCL_LOW: BUSTOA is used to detect SCL low timeout + \arg BUSTOA_DETECT_IDLE: BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle + \param[out] none + \retval none +*/ +void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOIDLE; + I2C_TIMEOUT(i2c_periph) |= timeout & I2C_TIMEOUT_TOIDLE; +} + +/*! + \brief get I2C flag status (API_ID(0x0039U)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] flag: I2C flags + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_TBE: I2C_TDATA is empty during transmitting + \arg I2C_FLAG_TI: transmit interrupt + \arg I2C_FLAG_RBNE: I2C_RDATA is not empty during receiving + \arg I2C_FLAG_ADDSEND: address received matches in slave mode + \arg I2C_FLAG_NACK: not acknowledge flag + \arg I2C_FLAG_STPDET: STOP condition detected in slave mode + \arg I2C_FLAG_TC: transfer complete in master mode + \arg I2C_FLAG_TCR: transfer complete reload + \arg I2C_FLAG_BERR: bus error + \arg I2C_FLAG_LOSTARB: arbitration Lost + \arg I2C_FLAG_OUERR: overrun/underrun error in slave mode + \arg I2C_FLAG_PECERR: PEC error + \arg I2C_FLAG_TIMEOUT: timeout flag + \arg I2C_FLAG_SMBALT: SMBus alert + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver in slave mode + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag) +{ + FlagStatus reval = RESET; + + if(0U != (I2C_STAT(i2c_periph) & flag)) { + reval = SET; + } else { + /* do nothing */ + } + + return reval; +} + +/*! + \brief clear I2C flag status (API_ID(0x003AU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] flag: I2C flags + one or more parameters can be selected which are shown as below: + \arg I2C_FLAG_ADDSEND: address received matches in slave mode + \arg I2C_FLAG_NACK: not acknowledge flag + \arg I2C_FLAG_STPDET: STOP condition detected in slave mode + \arg I2C_FLAG_BERR: bus error + \arg I2C_FLAG_LOSTARB: arbitration Lost + \arg I2C_FLAG_OUERR: overrun/underrun error in slave mode + \arg I2C_FLAG_PECERR: PEC error + \arg I2C_FLAG_TIMEOUT: timeout flag + \arg I2C_FLAG_SMBALT: SMBus alert + \param[out] none + \retval none +*/ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag) +{ + I2C_STATC(i2c_periph) |= (flag & I2C_STATC_MASK); +} + +/*! + \brief enable I2C interrupt (API_ID(0x003BU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] interrupt: I2C interrupts + one or more parameters can be selected which are shown as below: + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_TC: transfer complete interrupt + \arg I2C_INT_STPDET: stop detection interrupt + \arg I2C_INT_NACK: not acknowledge received interrupt + \arg I2C_INT_ADDM: address match interrupt + \arg I2C_INT_RBNE: receive interrupt + \arg I2C_INT_TI: transmit interrupt + \param[out] none + \retval none +*/ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t interrupt) +{ + I2C_CTL0(i2c_periph) |= (interrupt & I2C_INT_EN_MASK); +} + +/*! + \brief disable I2C interrupt (API_ID(0x003CU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] interrupt: I2C interrupts + one or more parameters can be selected which are shown as below: + \arg I2C_INT_ERR: error interrupt + \arg I2C_INT_TC: transfer complete interrupt + \arg I2C_INT_STPDET: stop detection interrupt + \arg I2C_INT_NACK: not acknowledge received interrupt + \arg I2C_INT_ADDM: address match interrupt + \arg I2C_INT_RBNE: receive interrupt + \arg I2C_INT_TI: transmit interrupt + \param[out] none + \retval none +*/ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t interrupt) +{ + I2C_CTL0(i2c_periph) &= ~(interrupt & I2C_INT_EN_MASK); +} + +/*! + \brief get I2C interrupt flag status (API_ID(0x003DU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \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_TI: transmit interrupt flag + \arg I2C_INT_FLAG_RBNE: I2C_RDATA is not empty during receiving interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address received matches in slave mode interrupt flag + \arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag + \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_TC: transfer complete in master mode interrupt flag + \arg I2C_INT_FLAG_TCR: transfer complete reload interrupt flag + \arg I2C_INT_FLAG_BERR: bus error interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag + \arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error interrupt flag + \arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + FlagStatus reval = RESET; + uint32_t ret1; + uint32_t ret2; + + /* get the status of interrupt enable bit */ + ret1 = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag))); + /* get the status of interrupt flag */ + ret2 = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag))); + + if((0U != ret1) && (0U != ret2)) { + reval = SET; + } else { + /* do nothing */ + } + + return reval; +} + +/*! + \brief clear I2C interrupt flag status (API_ID(0x003EU)) + \param[in] i2c_periph: I2Cx(x=0,1) + \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 received matches in slave mode interrupt flag + \arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag + \arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_BERR: bus error interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag + \arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error interrupt flag + \arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag + \param[out] none + \retval none +*/ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + I2C_STATC(i2c_periph) |= BIT(I2C_BIT_POS2(int_flag)); +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_misc.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_misc.c new file mode 100644 index 0000000..33d7f1c --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_misc.c @@ -0,0 +1,142 @@ +/*! + \file gd32c2x1_misc.c + \brief MISC driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_misc.h" + +#define NVIC_IRQ_PRI_MASK ((uint32_t)0x00000003U) +#define SCB_LPM_MASK ((uint32_t)0x00000016U) + +/*! + \brief enable NVIC request (API ID: 0x0001U) + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[in] nvic_irq_priority: the priority needed to set (0-3) + \param[out] none + \retval none +*/ +void nvic_irq_enable(IRQn_Type nvic_irq, uint8_t nvic_irq_priority) +{ + /* set the priority and enable the selected IRQ */ + NVIC_SetPriority(nvic_irq, ((uint32_t)nvic_irq_priority & NVIC_IRQ_PRI_MASK)); + NVIC_EnableIRQ(nvic_irq); +} + +/*! + \brief disable NVIC request (API ID: 0x0002U) + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(IRQn_Type nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC_DisableIRQ(nvic_irq); +} + +/*! + \brief set the NVIC vector table base address (API ID: 0x0003U) + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \arg NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: Vector Table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); + __DSB(); +} + +/*! + \brief initiates a system reset request to reset the MCU (API ID: 0x0004U) + \param[in] none + \param[out] none + \retval none +*/ +void nvic_system_reset(void) +{ + NVIC_SystemReset(); +} + +/*! + \brief set the state of the low power mode (API ID: 0x0005U) + \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 & SCB_LPM_MASK); +} + +/*! + \brief reset the state of the low power mode (API ID: 0x0006U) + \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 & SCB_LPM_MASK); +} + +/*! + \brief set the systick clock source (API ID: 0x0007U) + \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/gd32c2x1/standard_peripheral/source/gd32c2x1_pmu.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_pmu.c new file mode 100644 index 0000000..38f85a5 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_pmu.c @@ -0,0 +1,345 @@ +/*! + \file gd32c2x1_pmu.c + \brief PMU driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_pmu.h" + +/* PMU register bit offset */ +#define PAR_TWK_EFLASH_OFFSET ((uint32_t)21U) /*!< bit offset of TWK_EFLASH in PMU_PAR */ +#define PAR_TSW_IRC48MCNT_OFFSET ((uint32_t)16U) /*!< bit offset of TSW_IRC48MCNT in PMU_PAR */ + +/* bit mask */ +#define PMU_LPMOD_MASK ((uint32_t)0x3U) +#define PMU_DSMODVS_MASK ((uint32_t)0x3000U) +#define PMU_WAKEUP_MASK ((uint32_t)0x2F00U) + +/*! + \brief reset PMU registers (API_ID(0x0001U)) + \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 deepsleep mode voltage (API_ID(0x0002U)) + \param[in] dsv_n: + only one parameter can be selected which is shown as below: + \arg PMU_DSV_0: 0.9V (only valid when NPLDO is off) + \arg PMU_DSV_1: 1.0V + \arg PMU_DSV_2: 1.1V + \arg PMU_DSV_3: 1.2V + \param[out] none + \retval none +*/ +void pmu_deepsleep_voltage_select(uint32_t dsv_n) +{ + PMU_CTL0 &= ~PMU_CTL0_DSMODVS; + PMU_CTL0 |= (dsv_n & PMU_DSMODVS_MASK); +} + +/*! + \brief enable low power LDO (API_ID(0x0003U)) + \param[in] none + \param[out] none + \retval none +*/ +void pmu_low_power_ldo_enable(void) +{ + PMU_CTL0 |= PMU_CTL0_LPLDOEN; +} + +/*! + \brief disable low power LDO (API_ID(0x0004U)) + \param[in] none + \param[out] none + \retval none +*/ +void pmu_low_power_ldo_disable(void) +{ + PMU_CTL0 &= ~PMU_CTL0_LPLDOEN; +} + +/*! + \brief PMU work in Sleep mode (API_ID(0x0005U)) + \param[in] sleepmodecmd: sleep mode command + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepDeep bit of Cortex-M23 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 { + __SEV(); + __WFE(); + __WFE(); + } +} + +/*! + \brief PMU work in Deep-sleep mode (API_ID(0x0006U)) + \param[in] deepsleepmodecmd: deepsleep mode command + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[in] deepsleepmode: deepsleep mode + only one parameter can be selected which is shown as below: + \arg PMU_DEEPSLEEP: Deep-sleep mode + \arg PMU_DEEPSLEEP1: Deep-sleep mode 1 + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint8_t deepsleepmodecmd, uint8_t deepsleepmode) +{ + /* configure lowpower mode */ + PMU_CTL0 &= ~((uint32_t)(PMU_CTL0_LPMOD)); + PMU_CTL0 |= (deepsleepmode & PMU_LPMOD_MASK); + + /* set sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* select WFI or WFE command to enter Deep-sleep mode */ + if(WFI_CMD == deepsleepmodecmd) { + __WFI(); + } else { + __SEV(); + __WFE(); + __WFE(); + } + /* reset sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + /* clear lowpower mode */ + PMU_CTL0 &= ~((uint32_t)(PMU_CTL0_LPMOD)); +} + +/*! + \brief pmu work in standby mode (API_ID(0x0007U)) + \param[in] none + \param[out] none + \retval none +*/ +void pmu_to_standbymode(void) +{ + /* select the low-power mode to enter */ + PMU_CTL0 |= PMU_STANDBY; + + /* reset wakeup flag and standby flag */ + PMU_CTL0 |= (PMU_CTL0_WURST | PMU_CTL0_STBRST); + + /* set sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + REG32(0xE000E010U) &= 0x00010004U; + REG32(0xE000E180U) = 0xFFFFFFF3U; + REG32(0xE000E184U) = 0xFFFFFDFFU; + REG32(0xE000E188U) = 0xFFFFFFFFU; + + /* select WFI command to enter standby mode */ + __WFI(); +} + +/*! + \brief enable PMU wakeup pin (API_ID(0x0008U)) + \param[in] wakeup_pin: wakeup pin + one or more parameters can be selected which are shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13/PA4) + \arg PMU_WAKEUP_PIN2: WKUP Pin 2 (PB6) + \arg PMU_WAKEUP_PIN3: WKUP Pin 3 (PA2) + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin) +{ + PMU_CS |= (wakeup_pin & PMU_WAKEUP_MASK); +} + +/*! + \brief disable PMU wakeup pin (API_ID(0x0009U)) + \param[in] wakeup_pin: wakeup pin + one or more parameters can be selected which are shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13/PA4) + \arg PMU_WAKEUP_PIN2: WKUP Pin 2 (PB6) + \arg PMU_WAKEUP_PIN3: WKUP Pin 3 (PA2) + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin) +{ + PMU_CS &= ~(wakeup_pin & PMU_WAKEUP_MASK); +} + +/*! + \brief enable write access to the backup registers in RTC (API_ID(0x000AU)) + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL0 |= PMU_CTL0_BKPWEN; +} + +/*! + \brief disable write access to the backup registers in RTC (API_ID(0x000BU)) + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL0 &= ~PMU_CTL0_BKPWEN; +} + +/*! + \brief configure power state of eflash domain when enter run/run1 (API_ID(0x000CU)) + \param[in] state: power state of eflash domain + only one parameter can be selected which is shown as below: + \arg ENABLE: eflash domain power on + \arg DISABLE: eflash domain power off + \param[out] none + \retval none +*/ +void pmu_eflash_run_power_config(ControlStatus state) +{ + if(ENABLE == state) { + PMU_CTL1 &= ~PMU_CTL1_EFPSLEEP; + } else { + PMU_CTL1 |= PMU_CTL1_EFPSLEEP; + } +} + +/*! + \brief configure power state of eflash domain when enter deepsleep/deepsleep1 (API_ID(0x000DU)) + \param[in] state: power state of eflash domain when enter deepsleep/deepsleep1 + only one parameter can be selected which is shown as below: + \arg ENABLE: eflash domain power on + \arg DISABLE: eflash domain power off + \param[out] none + \retval none +*/ +void pmu_eflash_deepsleep_power_config(ControlStatus state) +{ + if(ENABLE == state) { + PMU_CTL1 &= ~PMU_CTL1_EFDSPSLEEP; + } else { + PMU_CTL1 |= PMU_CTL1_EFDSPSLEEP; + } +} + +/*! + \brief configure eflash wakeup time, using IRC48M counter (API_ID(0x000EU)) + \param[in] wakeup_time: 0~0xFF + \param[out] none + \retval none +*/ +void pmu_eflash_wakeup_time_config(uint32_t wakeup_time) +{ + PMU_PAR &= ~PMU_PAR_TWK_EFLASH; + PMU_PAR |= ((wakeup_time & 0x000000FFU) << PAR_TWK_EFLASH_OFFSET); +} + +/*! + \brief configure IRC48M counter before enter Deepsleep/Deepsleep1 mode (API_ID(0x000FU)) + \param[in] wait_time: 0~0x1F + \param[out] none + \retval none +*/ +void pmu_deepsleep_wait_time_config(uint32_t wait_time) +{ + PMU_PAR &= ~PMU_PAR_TSW_IRC48MCNT; + PMU_PAR |= ((wait_time & 0x0000001FU) << PAR_TSW_IRC48MCNT_OFFSET); +} + +/*! + \brief get flag state (API_ID(0x0010U)) + \param[in] flag: PMU flags + only one parameter can be selected which is shown as below: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LDOVSRF: LDO voltage select ready flag + \arg PMU_FLAG_NPRDY: normal-power LDO ready flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag) +{ + FlagStatus ret; + if(0U != (PMU_CS & flag)) { + ret = SET; + }else{ + ret = RESET; + } + return ret; +} + +/*! + \brief clear flag bit (API_ID(0x0011U)) + \param[in] flag: PMU flags + only one parameter can be selected which is shown as below: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag) +{ + switch(flag) { + case PMU_FLAG_WAKEUP: + /* clear wakeup flag */ + PMU_CTL0 |= PMU_CTL0_WURST; + break; + case PMU_FLAG_STANDBY: + /* clear standby flag */ + PMU_CTL0 |= PMU_CTL0_STBRST; + break; + default : + break; + } +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_rcu.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_rcu.c new file mode 100644 index 0000000..491a2d8 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_rcu.c @@ -0,0 +1,1116 @@ +/*! + \file gd32c2x1_rcu.c + \brief RCU driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_rcu.h" + +/* define clock source */ +#define SEL_IRC48MDIV 0x00U +#define SEL_HXTAL 0x01U +#define SEL_IRC32K 0x02U +#define SEL_LXTAL 0x03U + +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0x000FFFFFU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x03FFFFFFU) + +/*! + \brief deinitialize the RCU (API_ID(0x0001U)) + \param[in] none + \param[out] none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC48M */ + RCU_CTL0 |= RCU_CTL0_IRC48MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC48MSTB)) { + } + RCU_CFG0 &= ~RCU_CFG0_SCS; + /* reset CTL register */ + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_HXTALBPS ); + /* reset CTL register */ + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_HXTALBPS ); + /* reset RCU_CFG0 register */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APBPSC | \ + RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV |RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV ); + /* reset RCU_CFG1 register */ + RCU_CFG1 &= ~(RCU_CFG1_USART0SEL | RCU_CFG1_I2C0SEL | RCU_CFG1_I2C1SEL | RCU_CFG1_ADCSEL | \ + RCU_CFG1_ADCPSC | RCU_CFG1_I2SSEL); + RCU_INT = 0x00000000U; +} + +/*! + \brief enable the peripherals clock (API_ID(0x0002U)) + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC: FMC clock + \arg RCU_CRC: CRC clock + \arg RCU_DMA: DMA clock + \arg RCU_DMAMUX: DMAMUX clock + \arg RCU_GPIOx (x=A,B,C,D,F): GPIO ports clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_CMP: CMP clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,2,13,15,16): TIMER clock + \arg RCU_SPIx (x=0,1): SPI clock + \arg RCU_USARTx (x=0,1,2): USART clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_DBGMCU: DBGMCU clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC 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 (API_ID(0x0003U)) + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_CRC: CRC clock + \arg RCU_DMA: DMA clock + \arg RCU_DMAMUX: DMAMUX clock + \arg RCU_GPIOx (x=A,B,C,D,F): GPIO ports clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_CMP: CMP clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,1,2,5,13,15,16): TIMER clock + \arg RCU_SPIx (x=0,1): SPI clock + \arg RCU_USARTx (x=0,1,2): USART clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_DBGMCU: DBGMCU clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC 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 (API_ID(0x0004U)) + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_SRAM_SLP: SRAM clock + \arg RCU_FMC_SLP: FMC clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_DMA_SLP: DMA clock + \arg RCU_DMAMUX_SLP: DMAMUX clock + \arg RCU_GPIOx_SLP (x = A,B,C,D,F): GPIO ports clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_CMP_SLP: CMP clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_ADC_SLP: ADC clock + \arg RCU_TIMERx_SLP (x=0,2,13,15,16): TIMER clock + \arg RCU_SPIx_SLP (x = 0,1): SPI clock + \arg RCU_USARTx_SLP (x = 0,1,2): USART clock + \arg RCU_I2Cx_SLP (x = 0,1): I2C clock + \arg RCU_PMU_SLP: PMU 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 (API_ID(0x0005U)) + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_SRAM_SLP: SRAM clock + \arg RCU_FMC_SLP: FMC clock + \arg RCU_CRC_SLP: CRC clock + \arg RCU_DMA_SLP: DMA clock + \arg RCU_DMAMUX_SLP: DMAMUX clock + \arg RCU_GPIOx_SLP (x = A,B,C,D,F): GPIO ports clock + \arg RCU_SYSCFG_SLP: SYSCFG clock + \arg RCU_CMP_SLP: CMP clock + \arg RCU_WWDGT_SLP: WWDGT clock + \arg RCU_ADC_SLP: ADC clock + \arg RCU_TIMERx_SLP (x=0,2,13,15,16): TIMER clock + \arg RCU_SPIx_SLP (x = 0,1): SPI clock + \arg RCU_USARTx_SLP (x = 0,1,2): USART clock + \arg RCU_I2Cx_SLP (x = 0,1): I2C clock + \arg RCU_PMU_SLP: PMU 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 (API_ID(0x0006U)) + \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_CRCRST: reset CRC + \arg RCU_DMARST: reset DMA + \arg RCU_DMAMUXRST: reset DMAMUX + \arg RCU_GPIOxRST (x = A,B,C,D,F): reset GPIO ports + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_CMPRST: reset CMP + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,2,13,15,16): reset TIMER + \arg RCU_SPIxRST (x = 0,1): reset SPI + \arg RCU_USARTxRST (x = 0,1,2): reset USART + \arg RCU_I2CxRST (x = 0,1): reset I2C + \arg RCU_PMURST: reset PMU + \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 (API_ID(0x0007U)) + \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_CRCRST: reset CRC + \arg RCU_DMARST: reset DMA + \arg RCU_DMAMUXRST: reset DMAMUX + \arg RCU_GPIOxRST (x = A,B,C,D,F): reset GPIO ports + \arg RCU_SYSCFGRST: reset SYSCFG + \arg RCU_CMPRST: reset CMP + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,2,13,15,16): reset TIMER + \arg RCU_SPIxRST (x = 0,1): reset SPI + \arg RCU_USARTxRST (x = 0,1,2): reset USART + \arg RCU_I2CxRST (x = 0,1): reset I2C + \arg RCU_PMURST: reset PMU + \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 (API_ID(0x0008U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_CTL1 |= RCU_CTL1_BKPRST; +} + +/*! + \brief disable the BKP reset (API_ID(0x0009U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_disable(void) +{ + RCU_CTL1 &= ~RCU_CTL1_BKPRST; +} + +/*! + \brief configure the system clock source (API_ID(0x000CU)) + \param[in] ck_sys: system clock source select + only one parameter can be selected which is shown as below: + \arg RCU_CKSYSSRC_IRC48MDIV_SYS: select IRC48MDIV_SYS as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_IRC32K: select IRC32K as the CK_SYS source + \arg RCU_CKSYSSRC_LXTAL: select LXTLA as the CK_SYS source + \param[out] none + \retval none +*/ +void rcu_system_clock_source_config(uint32_t ck_sys) +{ + uint32_t cksys_source; + cksys_source = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + cksys_source &= ~RCU_CFG0_SCS; + RCU_CFG0 = ((ck_sys & RCU_CFG0_SCS) | cksys_source); +} + +/*! + \brief get the system clock source (API_ID(0x000DU)) + \param[in] none + \param[out] none + \retval which clock is selected as CK_SYS source + \arg RCU_CKSYSSRC_IRC48MDIV_SYS: select IRC48MDIV_SYS as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_IRC32K: select IRC32K as the CK_SYS source + \arg RCU_CKSYSSRC_LXTAL: select LXTLA 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 (API_ID(0x000EU)) + \param[in] ck_ahb: AHB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512: select CK_SYS/x as CK_AHB + \param[out] none + \retval none +*/ +void rcu_ahb_clock_config(uint32_t ck_ahb) +{ + uint32_t ahbpsc; + ahbpsc = RCU_CFG0; + /* reset the AHBPSC bits and set according to ck_ahb */ + ahbpsc &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = ((ck_ahb & RCU_CFG0_AHBPSC) | ahbpsc); +} + + +/*! + \brief configure the APB clock prescaler selection (API_ID(0x000FU)) + \param[in] ck_apb: APB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB_CKAHB_DIV1: select CK_AHB as CK_APB + \arg RCU_APB_CKAHB_DIV2: select CK_AHB/2 as CK_APB + \arg RCU_APB_CKAHB_DIV4: select CK_AHB/4 as CK_APB + \arg RCU_APB_CKAHB_DIV8: select CK_AHB/8 as CK_APB + \arg RCU_APB_CKAHB_DIV16: select CK_AHB/16 as CK_APB + \param[out] none + \retval none +*/ +void rcu_apb_clock_config(uint32_t ck_apb) +{ + uint32_t apbpsc; + apbpsc = RCU_CFG0; + /* reset the APBPSC and set according to ck_apb */ + apbpsc &= ~RCU_CFG0_APBPSC; + RCU_CFG0 = ((ck_apb & RCU_CFG0_APBPSC) | apbpsc); +} + +/*! + \brief configure the ADC clock source and prescaler selection (API_ID(0x0010U)) + \param[in] adc_clock_source: ADC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_ADCSRC_CKSYS: ADC clock source select CK_SYS + \arg RCU_ADCSRC_IRC48M_PER: ADC clock source select CK_IRC48MDIV_PER + \param[in] ck_adc: ADC clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_ADCCK_DIV1: ADC clock prescaler select not divided + \arg RCU_ADCCK_DIV2: ADC clock prescaler select divided by 2 + \arg RCU_ADCCK_DIV4: ADC clock prescaler select divided by 4 + \arg RCU_ADCCK_DIV6: ADC clock prescaler select divided by 6 + \arg RCU_ADCCK_DIV8: ADC clock prescaler select divided by 8 + \arg RCU_ADCCK_DIV10: ADC clock prescaler select divided by 10 + \arg RCU_ADCCK_DIV12: ADC clock prescaler select divided by 12 + \arg RCU_ADCCK_DIV16: ADC clock prescaler select divided by 16 + \arg RCU_ADCCK_DIV32: ADC clock prescaler select divided by 32 + \arg RCU_ADCCK_DIV64: ADC clock prescaler select divided by 64 + \arg RCU_ADCCK_DIV128: ADC clock prescaler select divided by 128 + \arg RCU_ADCCK_DIV256: ADC clock prescaler select divided by 256 + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(uint32_t adc_clock_source, uint32_t ck_adc) +{ + uint32_t cfg1_val; + + /* Read the current value of RCU_CFG1 */ + cfg1_val = RCU_CFG1; + + /* Reset the ADCPSC and ADCSEL bits */ + cfg1_val &= ~RCU_CFG1_ADCPSC; + cfg1_val &= ~RCU_CFG1_ADCSEL; + + /* Set the ADC clock source according to adc_clock_source */ + cfg1_val |= (adc_clock_source & RCU_CFG1_ADCSEL); + + /* Set the ADC clock prescaler according to ck_adc */ + cfg1_val |= (ck_adc & RCU_CFG1_ADCPSC); + + /* Write back the modified value to RCU_CFG1 */ + RCU_CFG1 = cfg1_val; +} + +/*! + \brief configure the CK_OUT0 clock source and divider (API_ID(0x0012U)) + \param[in] ckout_src: CK_OUT0 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUT0SRC_NONE: no clock selected + \arg RCU_CKOUT0SRC_CKSYS: CK_OUT0 clock source select CKSYS + \arg RCU_CKOUT0SRC_IRC48M: CK_OUT0 clock source select IRC48M + \arg RCU_CKOUT0SRC_HXTAL: CK_OUT0 clock source select HXTAL + \arg RCU_CKOUT0SRC_IRC32K: CK_OUT0 clock source select IRC32K + \arg RCU_CKOUT0SRC_LXTAL: CK_OUT0 clock source select LXTAL + \param[in] ckout_div: CK_OUT0 divider + \arg RCU_CKOUT0_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout0_config(uint32_t ckout0_src, uint32_t ckout0_div) +{ + uint32_t ckout; + ckout = RCU_CFG0; + /* reset the CKOUT0SEL and CKOUT0DIV bits and set according to ckout_src and ckout_div */ + ckout &= ~(RCU_CFG0_CKOUT0SEL | RCU_CFG0_CKOUT0DIV ); + RCU_CFG0 = (ckout | (ckout0_src & RCU_CFG0_CKOUT0SEL) | (ckout0_div & RCU_CFG0_CKOUT0DIV)); +} + +/*! + \brief configure the CK_OUT1 clock source and divider (API_ID(0x0013U)) + \param[in] ckout_src: CK_OUT1 clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUT1SRC_NONE: no clock selected + \arg RCU_CKOUT1SRC_CKSYS: CK_OUT1 clock source select CKSYS + \arg RCU_CKOUT1SRC_IRC48M: CK_OUT1 clock source select IRC48M + \arg RCU_CKOUT1SRC_HXTAL: CK_OUT1 clock source select HXTAL + \arg RCU_CKOUT1SRC_IRC32K: CK_OUT1 clock source select IRC32K + \arg RCU_CKOUT1SRC_LXTAL: CK_OUT1 clock source select LXTAL + \param[in] ckout_div: CK_OUT divider + \arg RCU_CKOUT1_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout1_config(uint32_t ckout1_src, uint32_t ckout1_div) +{ + uint32_t ckout; + ckout = RCU_CFG0; + /* reset the CKOUT1SEL and CKOUT1DIV bits and set according to ckout_src and ckout_div */ + ckout &= ~(RCU_CFG0_CKOUT1SEL | RCU_CFG0_CKOUT1DIV ); + RCU_CFG0 = (ckout | (ckout1_src & RCU_CFG0_CKOUT1SEL) | (ckout1_div | RCU_CFG0_CKOUT1DIV)); +} + +/*! + \brief enable the low speed clock output (API_ID(0x0014U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lsckout_enable(void) +{ + RCU_CTL1 |= RCU_CTL1_LSCKOUTEN; +} + +/*! + \brief disable the low speed clock output (API_ID(0x0015U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lsckout_disable(void) +{ + RCU_CTL1 &= ~RCU_CTL1_LSCKOUTEN; +} + +/*! + \brief configure the LSCKOUT clock source (API_ID(0x0016U)) + \param[in] lsc_ckout_src: LSCKOUT clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_LSCKOUTSRC_IRC32K: IRC32K clock selected + \arg RCU_LSCKOUTSRC_LXTAL: LXTAL selected + \param[out] none + \retval none +*/ +void rcu_lsckout_config(uint32_t lsckout_src) +{ + uint32_t reg; + + reg = RCU_CTL1; + /* reset the LSCKOUTSEL */ + reg &= ~(RCU_CTL1_LSCKOUTSEL); + RCU_CTL1 = (reg | (lsckout_src & (RCU_CTL1_LSCKOUTSEL))); +} + +/*! + \brief configure the USART clock source selection (API_ID(0x0017U)) + \param[in] usart_idx: IDX_USART0 + \param[in] ck_usart: USART clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_USART0SRC_CKAPB: CK_USART select CK_APB + \arg RCU_USART0SRC_CKSYS: CK_USART select CK_SYS + \arg RCU_USART0SRC_IRC48MDIV_PER: CK_USART select CK_IRC48MDIV_PER + \arg RCU_USART0SRC_LXTAL: CK_USART select LXTAL + \param[out] none + \retval none +*/ +void rcu_usart_clock_config(usart_idx_enum usart_idx, uint32_t ck_usart) +{ + switch(usart_idx) { + case IDX_USART0: + { + uint32_t reg_val = RCU_CFG1; + /* reset the USART0SEL bits and set according to ck_usart */ + reg_val &= ~RCU_CFG1_USART0SEL; + reg_val |= (ck_usart & RCU_CFG1_USART0SEL); + RCU_CFG1 = reg_val; + } + break; + default: + break; + } +} + +/*! + \brief configure the I2Cx(x=0,1) clock source selection (API_ID(0x0018U)) + \param[in] i2c_idx: IDX_I2Cx(x=0,1) + \param[in] ck_i2c: I2C clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_I2CSRC_CKAPB: CK_I2C select CK_APB + \arg RCU_I2CSRC_CKSYS: CK_I2C select CK_SYS + \arg RCU_I2CSRC_IRC48MDIV_PER: CK_I2C select CK_IRC48MDIV_PER + \param[out] none + \retval none +*/ +void rcu_i2c_clock_config(i2c_idx_enum i2c_idx, uint32_t ck_i2c) +{ + switch(i2c_idx) { + case IDX_I2C0: + { + uint32_t reg_val = RCU_CFG1; + /* reset the I2C0SEL bits and set according to ck_i2c */ + reg_val &= ~RCU_CFG1_I2C0SEL; + reg_val |= (ck_i2c & RCU_CFG1_I2C0SEL); + RCU_CFG1 = reg_val; + } + break; + case IDX_I2C1: + { + uint32_t reg_val = RCU_CFG1; + /* reset the I2C1SEL bits and set according to ck_i2c */ + reg_val &= ~RCU_CFG1_I2C1SEL; + reg_val |= ((uint32_t)ck_i2c & RCU_CFG1_I2C0SEL) << 2U; + RCU_CFG1 = reg_val; + } + break; + default: + break; + } +} + +/*! + \brief configure the I2S clock source selection (API_ID(0x0019U)) + \param[in] ck_i2s: I2S clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_I2SSRC_CKSYS: CK_I2S select CK_SYS + \arg RCU_I2SSRC_IRC48MDIV_PER: CK_I2S select IRC48MDIV_PER + \arg RCU_I2SSRC_CKIN: CK_I2S select I2S_CKIN + \param[out] none + \retval none +*/ +void rcu_i2s_clock_config(uint32_t ck_i2s) +{ + uint32_t reg_val = RCU_CFG1; + /* reset the I2SSEL bits and set according to ck_i2s */ + reg_val &= ~RCU_CFG1_I2SSEL; + reg_val |= (ck_i2s & RCU_CFG1_I2SSEL); + RCU_CFG1 = reg_val; +} + +/*! + \brief configure the IRC48MDIV_SYS clock selection (API_ID(0x001AU)) + \param[in] ck_irc48mdiv_sys: IRC48MDIV clock selection + only one parameter can be selected which is shown as below: + \arg RCU_IRC48MDIV_SYS_1: CK_IRC48MDIV_SYS select CK_IRC48M + \arg RCU_IRC48MDIV_SYS_2: CK_IRC48MDIV_SYS select CK_IRC48M divided by 2 + \arg RCU_IRC48MDIV_SYS_4: CK_IRC48MDIV_SYS select CK_IRC48M divided by 4 + \arg RCU_IRC48MDIV_SYS_8: CK_IRC48MDIV_SYS select CK_IRC48M divided by 8 + \arg RCU_IRC48MDIV_SYS_16: CK_IRC48MDIV_SYS select CK_IRC48M divided by 16 + \arg RCU_IRC48MDIV_SYS_32: CK_IRC48MDIV_SYS select CK_IRC48M divided by 32 + \arg RCU_IRC48MDIV_SYS_64: CK_IRC48MDIV_SYS select CK_IRC48M divided by 64 + \arg RCU_IRC48MDIV_SYS_128: CK_IRC48MDIV_SYS select CK_IRC48M divided by 128 + + \param[out] none + \retval none +*/ +void rcu_irc48mdiv_sys_clock_config(uint32_t ck_irc48mdiv_sys) +{ + uint32_t reg_val = RCU_CTL0; + /* reset the IRC48MDIV_SYS bits and set according to ck_irc48mdiv_sys */ + reg_val &= ~RCU_CTL0_IRC48MDIV_SYS; + reg_val |= (ck_irc48mdiv_sys & RCU_CTL0_IRC48MDIV_SYS); + RCU_CTL0 = reg_val; +} + + +/*! + \brief configure the IRC48MDIV clock selection (API_ID(0x001BU)) + \param[in] ck_irc48mdiv_per: IRC48MDIV clock selection + only one parameter can be selected which is shown as below: + \arg RCU_IRC48MDIV_PER_1: CK_IRC48MDIV_PER select CK_IRC48M + \arg RCU_IRC48MDIV_PER_2: CK_IRC48MDIV_PER select CK_IRC48M divided by 2 + \arg RCU_IRC48MDIV_PER_3: CK_IRC48MDIV_PER select CK_IRC48M divided by 3 + \arg RCU_IRC48MDIV_PER_4: CK_IRC48MDIV_PER select CK_IRC48M divided by 4 + \arg RCU_IRC48MDIV_PER_5: CK_IRC48MDIV_PER select CK_IRC48M divided by 5 + \arg RCU_IRC48MDIV_PER_6: CK_IRC48MDIV_PER select CK_IRC48M divided by 6 + \arg RCU_IRC48MDIV_PER_7: CK_IRC48MDIV_PER select CK_IRC48M divided by 7 + \arg RCU_IRC48MDIV_PER_8: CK_IRC48MDIV_PER select CK_IRC48M divided by 8 + + \param[out] none + \retval none +*/ +void rcu_irc48mdiv_per_clock_config(uint32_t ck_irc48mdiv_per) +{ + uint32_t reg_val = RCU_CTL0; + /* reset the IRC48MDIV_PER bits and set according to ck_irc48mdiv_per */ + reg_val &= ~RCU_CTL0_IRC48MDIV_PER; + reg_val |= (ck_irc48mdiv_per & RCU_CTL0_IRC48MDIV_PER); + RCU_CTL0 = reg_val; +} + +/*! + \brief configure the RTC clock source selection (API_ID(0x001CU)) + \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_DIV32: CK_HXTAL/32 selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + /* reset the RTCSRC bits and set according to rtc_clock_source */ + uint32_t reg_val = RCU_CTL1; + reg_val &= ~RCU_CTL1_RTCSRC; + reg_val |= (rtc_clock_source & RCU_CTL1_RTCSRC); + RCU_CTL1 = reg_val; +} + +/*! + \brief configure the LXTAL drive capability (API_ID(0x001DU)) + \param[in] lxtal_dricap: drive capability of LXTAL + only one parameter can be selected which is shown as below: + \arg RCU_LXTAL_LOWDRI: lower driving capability + \arg RCU_LXTAL_HIGHDRI: higher driving capability + \param[out] none + \retval none +*/ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap) +{ + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + uint32_t reg_val = RCU_CTL1; + reg_val &= ~RCU_CTL1_LXTALDRI; + reg_val |= (lxtal_dricap & RCU_CTL1_LXTALDRI); + RCU_CTL1 = reg_val; +} + +/*! + \brief wait until oscillator stabilization flags is SET (API_ID(0x001EU)) + \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_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \param[out] none + \retval ErrStatus: SUCCESS or ERROR + \note This function includes timeout exit scenarios. + Modify according to the user's actual usage scenarios. +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + switch(osci) { + case RCU_HXTAL: + /* wait until HXTAL is stabilization and osci_stat is not more than timeout */ + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + 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 or not */ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)) { + 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 or not */ + 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 or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC32KSTB)) { + reval = SUCCESS; + } + break; + + default: + break; + } + /* return value */ + return reval; +} + +/*! + \brief turn on the oscillator (API_ID(0x001FU)) + \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_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \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 (API_ID(0x0022U)) + \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_IRC48M: IRC48M + \arg RCU_IRC32K: IRC32K + \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 (API_ID(0x0023U)) + \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 + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci) { + case RCU_HXTAL: + /* HXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg | RCU_CTL0_HXTALBPS); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_CTL1; + RCU_CTL1 &= ~RCU_CTL1_LXTALEN; + RCU_CTL1 = (reg | RCU_CTL1_LXTALBPS); + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it (API_ID(0x0024U)) + \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 + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci) { + case RCU_HXTAL: + /* HXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg & (~RCU_CTL0_HXTALBPS)); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_CTL1; + RCU_CTL1 &= ~RCU_CTL1_LXTALEN; + RCU_CTL1 = (reg & (~RCU_CTL1_LXTALBPS)); + break; + default: + break; + } +} + +/*! + \brief set the IRC48M adjust value (API_ID(0x0025U)) + \param[in] irc48m_adjval: IRC48M adjust value, must be between 0 and 0x3F + \param[out] none + \retval none +*/ +void rcu_irc48m_adjust_value_set(uint8_t irc48m_adjval) +{ + uint32_t adjust; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_IRC48M_ADJ(irc48m_adjval)) { + fw_debug_report_err(RCU_MODULE_ID, API_ID(0x0025U), ERR_PARAM_INVALID); + }else +#endif /* FW_DEBUG_ERR_REPORT */ + { + adjust = RCU_CTL0; + /* reset the IRC48MADJ bits and set according to irc48m_adjval */ + adjust &= ~RCU_CTL0_IRC48MADJ; + RCU_CTL0 = (adjust | (((uint32_t)irc48m_adjval) << 2U)); + } +} + +/*! + \brief enable LXTAL stabilization reset (API_ID(0x0026U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_stab_reset_enable(void) +{ + RCU_CTL1 |= RCU_CTL1_LXTALSTBRST; +} + +/*! + \brief disable LXTAL stabilization reset (API_ID(0x0027U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_stab_reset_disable(void) +{ + RCU_CTL1 &= ~RCU_CTL1_LXTALSTBRST; +} + +/*! + \brief enable the HXTAL clock monitor (API_ID(0x0028U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL0 |= RCU_CTL0_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor (API_ID(0x0029U)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL0 &= ~RCU_CTL0_CKMEN; +} + +/*! + \brief enable the LXTAL clock monitor (API_ID(0x002AU)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_clock_monitor_enable(void) +{ + RCU_CTL1 |= RCU_CTL1_LCKMEN; +} + +/*! + \brief disable the LXTAL clock monitor (API_ID(0x002BU)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_clock_monitor_disable(void) +{ + RCU_CTL1 &= ~RCU_CTL1_LCKMEN; +} + + +/*! + \brief get the system clock, bus and peripheral clock frequency (API_ID(0x002CU)) + \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_APB: APB clock frequency + \arg CK_ADC: ADC clock frequency + \arg CK_USART0: USART0 clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB, ADC or USRAT0 +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws, ck_freq = 0U; + uint32_t cksys_freq, ahb_freq, apb_freq, irc48m_per_freq; + uint32_t adc_freq, usart_freq; + uint32_t idx, clk_exp; + /* exponent of AHB, APB, ADC 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 apb_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t IRC48M_exp[8] = {0, 1, 2, 3, 4, 5, 6, 7}; + const uint8_t irc48m_per_exp[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + const uint16_t adc_exp[12] = {1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws) { + /* IRC48M is selected as CK_SYS */ + case SEL_IRC48MDIV: + idx = GET_BITS(RCU_CTL0, 29, 31); + clk_exp = IRC48M_exp[idx]; + cksys_freq = IRC48M_VALUE >> clk_exp ; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* IRC32k is selected as CK_SYS */ + case SEL_IRC32K: + cksys_freq = IRC32K_VALUE; + break; + /* LXTAL is selected as CK_SYS */ + default: + cksys_freq = LXTAL_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 APB clock frequency */ + idx = GET_BITS(RCU_CFG0, 11, 13); + clk_exp = apb_exp[idx]; + apb_freq = ahb_freq >> clk_exp; + + idx = GET_BITS(RCU_CTL0, 25, 27); + clk_exp = irc48m_per_exp[idx]; + irc48m_per_freq = IRC48M_VALUE / 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_APB: + ck_freq = apb_freq; + break; + case CK_ADC: + /* calculate ADC clock frequency */ + if(RCU_ADCSRC_CKSYS == (RCU_CFG1 & RCU_CFG1_ADCSEL)) { + adc_freq = cksys_freq; + } else if(RCU_ADCSRC_IRC48M_PER == (RCU_CFG1 & RCU_CFG1_ADCSEL)){ + adc_freq = irc48m_per_freq; + } else { + adc_freq = HXTAL_VALUE; + } + idx = GET_BITS(RCU_CFG1, 9, 12); + if(idx < sizeof(adc_exp) / sizeof(adc_exp[0])){ + clk_exp = adc_exp[idx]; + ck_freq = adc_freq / clk_exp; + } else { + ck_freq = 0U; + } + break; + case CK_USART0: + /* calculate USART0 clock frequency */ + if(RCU_USART0SRC_CKAPB == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = apb_freq; + } else if(RCU_USART0SRC_CKSYS == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = cksys_freq; + } else if(RCU_USART0SRC_LXTAL == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = LXTAL_VALUE; + } else if(RCU_USART0SRC_IRC48MDIV_PER == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + /* calculate IRC48MDIV clock frequency */ + idx = GET_BITS(RCU_CTL0, 25, 27); + usart_freq = IRC48M_VALUE /(idx + 1U); + } else if(RCU_USART0SRC_CKSYS == (RCU_CFG1 & RCU_CFG1_USART0SEL)) { + usart_freq = cksys_freq; + }else { + usart_freq = 0U; + } + ck_freq = usart_freq; + break; + default: + break; + } + return ck_freq; +} + +/*! + \brief get the clock stabilization and periphral reset flags (API_ID(0x002DU)) + \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_IRC32KSTB: IRC32K stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC48MSTB: IRC48M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_OBLRST: option byte loader reset flag + \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: FWDGT reset flag + \arg RCU_FLAG_WWDGTRST: WWDGT reset flag + \arg RCU_FLAG_LPRST: low-power reset flag + \arg RCU_FLAG_LCKCMD: LXTAL clock failure detection flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + FlagStatus reval; + if(0U != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} + +/*! + \brief clear the reset flag (API_ID(0x002EU)) + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief enable the stabilization interrupt (API_ID(0x002FU)) + \param[in] stab_int: 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_IRC48MSTB: IRC48M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) |= BIT(RCU_BIT_POS(stab_int)); +} + +/*! + \brief disable the stabilization interrupt (API_ID(0x0030U)) + \param[in] stab_int: 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_IRC48MSTB: IRC48M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) &= ~BIT(RCU_BIT_POS(stab_int)); +} + +/*! + \brief get the clock stabilization interrupt and ckm flags (API_ID(0x0031U)) + \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_IRC48MSTB: IRC48M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_LXTALCKM: LXTAL clock stuck interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) +{ + FlagStatus reval; + if(0U != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} + +/*! + \brief clear the interrupt flags (API_ID(0x0032U)) + \param[in] int_flag_clear: 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_IRC48MSTB_CLR: IRC48M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALCKM_CLR: LXTAL clock stuck interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear) +{ + RCU_REG_VAL(int_flag_clear) |= BIT(RCU_BIT_POS(int_flag_clear)); +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_rtc.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_rtc.c new file mode 100644 index 0000000..42fdd86 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_rtc.c @@ -0,0 +1,977 @@ +/*! + \file gd32c2x1_rtc.c + \brief RTC driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_rtc.h" + +/* RTC timeout value */ +#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)0x00008000U) /*!< recalibration pending flag timeout */ +#define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ +#define RTC_ALRMXWF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be written flag timeout */ + +/*! + \brief enable RTC bypass shadow registers function (API_ID(0x0001U)) + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC bypass shadow registers function (API_ID(0x0002U)) + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow (API_ID(0x0003U)) + registers are updated + \param[in] none + \param[out] none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status; + 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)0U == 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 enable RTC alarm (API_ID(0x0004U)) + \param[in] none + \param[out] none + \retval none +*/ +void rtc_alarm_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_ALRM0EN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC alarm (API_ID(0x0005U)) + \param[out] none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(void) +{ + volatile uint32_t time_index = RTC_ALRMXWF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status ; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of 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)); + + if((uint32_t)RESET != flag_status) { + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief configure RTC alarm (API_ID(0x0006U)) + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc display_format + alarm_minute: 0x0 - 0x59(BCD format) + alarm_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \param[out] none + \retval none +*/ +void rtc_alarm_config(rtc_alarm_struct *rtc_alarm_time) +{ +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_RTC_VALID_POINTER(rtc_alarm_time)) { + fw_debug_report_err(RTC_MODULE_ID, API_ID(0x0006U), ERR_PARAM_POINTER); + }else +#endif /* FW_DEBUG_ERR_REPORT */ + { + uint32_t reg_alrmtd; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + reg_alrmtd = (rtc_alarm_time->alarm_mask | \ + rtc_alarm_time->weekday_or_date | \ + rtc_alarm_time->am_pm | \ + ALRMTD_DAY(rtc_alarm_time->alarm_day) | \ + ALRMTD_HR(rtc_alarm_time->alarm_hour) | \ + ALRMTD_MN(rtc_alarm_time->alarm_minute) | \ + ALRMTD_SC(rtc_alarm_time->alarm_second)); + + RTC_ALRM0TD = reg_alrmtd; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + } +} + +/*! + \brief configure subsecond of RTC alarm (API_ID(0x0007U)) + \param[in] mask_subsecond: alarm subsecond mask + only one parameter can be selected which is shown as below: + \arg RTC_MSKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MSKSSC_1_14: mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared + \arg RTC_MSKSSC_2_14: mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared + \arg RTC_MSKSSC_3_14: mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared + \arg RTC_MSKSSC_4_14: mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared + \arg RTC_MSKSSC_5_14: mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared + \arg RTC_MSKSSC_6_14: mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared + \arg RTC_MSKSSC_7_14: mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared + \arg RTC_MSKSSC_8_14: mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared + \arg RTC_MSKSSC_9_14: mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared + \arg RTC_MSKSSC_10_14: mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared + \arg RTC_MSKSSC_11_14: mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared + \arg RTC_MSKSSC_12_14: mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared + \arg RTC_MSKSSC_13_14: mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared + \arg RTC_MSKSSC_14: mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared + \arg RTC_MSKSSC_NONE: mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared + \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF) + \param[out] none + \retval none +*/ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0SS = mask_subsecond | subsecond; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC alarm (API_ID(0x0008U)) + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc display_format + alarm_minute: 0x0 - 0x59(BCD format) + alarm_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_alarm_get(rtc_alarm_struct *rtc_alarm_time) +{ +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_RTC_VALID_POINTER(rtc_alarm_time)){ + fw_debug_report_err(RTC_MODULE_ID, API_ID(0x0008U), ERR_PARAM_POINTER); + }else +#endif /* FW_DEBUG_ERR_REPORT */ + { + uint32_t reg_alrmtd; + + /* get the value of RTC_ALRM0TD register */ + reg_alrmtd = RTC_ALRM0TD; + + /* 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 (API_ID(0x0009U)) + \param[in] none + \param[out] none + \retval RTC alarm subsecond value +*/ +uint32_t rtc_alarm_subsecond_get(void) +{ + return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); +} + +/*! + \brief enter RTC init mode (API_ID(0x000AU)) + \param[in] none + \param[out] none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + volatile uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status ; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)) { + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do { + flag_status = RTC_STAT & RTC_STAT_INITF; + } while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status) { + error_status = SUCCESS; + } + } else { + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief initialize RTC registers (API_ID(0x000BU)) + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + year: 0x0 - 0x99(BCD format) + month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + date: 0x1 - 0x31(BCD format) + day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc display_format chose + minute: 0x0 - 0x59(BCD format) + second: 0x0 - 0x59(BCD format) + factor_asyn: 0x0 - 0x7F + factor_syn: 0x0 - 0x7FFF + am_pm: RTC_AM, RTC_PM + display_format: RTC_24HOUR, RTC_12HOUR + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct *rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_RTC_VALID_POINTER(rtc_initpara_struct)) { + fw_debug_report_err(RTC_MODULE_ID, API_ID(0x000BU), ERR_PARAM_POINTER); + }else +#endif /* FW_DEBUG_ERR_REPORT */ + { + uint32_t reg_time , reg_date ; + + 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 exit RTC init mode (API_ID(0x000CU)) + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief get current time and date (API_ID(0x000DU)) + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + year: 0x0 - 0x99(BCD format) + month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + date: 0x1 - 0x31(BCD format) + day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc display_format chose + minute: 0x0 - 0x59(BCD format) + second: 0x0 - 0x59(BCD format) + factor_asyn: 0x0 - 0x7F + factor_syn: 0x0 - 0x7FFF + am_pm: RTC_AM, RTC_PM + display_format: RTC_24HOUR, RTC_12HOUR + \retval none +*/ +void rtc_current_time_get(rtc_parameter_struct *rtc_initpara_struct) +{ +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_RTC_VALID_POINTER(rtc_initpara_struct)) { + fw_debug_report_err(RTC_MODULE_ID, API_ID(0x000DU), ERR_PARAM_POINTER); + }else +#endif /* FW_DEBUG_ERR_REPORT */ + { + uint32_t temp_tr, temp_dr, temp_pscr, temp_ctlr; + + temp_tr = (uint32_t)RTC_TIME; + temp_dr = (uint32_t)RTC_DATE; + temp_pscr = (uint32_t)RTC_PSC; + temp_ctlr = (uint32_t)RTC_CTL; + + /* get current time and construct rtc_parameter_struct structure */ + rtc_initpara_struct->year = (uint8_t)GET_DATE_YR(temp_dr); + rtc_initpara_struct->month = (uint8_t)GET_DATE_MON(temp_dr); + rtc_initpara_struct->date = (uint8_t)GET_DATE_DAY(temp_dr); + rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->hour = (uint8_t)GET_TIME_HR(temp_tr); + rtc_initpara_struct->minute = (uint8_t)GET_TIME_MN(temp_tr); + rtc_initpara_struct->second = (uint8_t)GET_TIME_SC(temp_tr); + rtc_initpara_struct->factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); + rtc_initpara_struct->factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); + rtc_initpara_struct->am_pm = (uint32_t)(temp_tr & RTC_TIME_PM); + rtc_initpara_struct->display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); + } +} + +/*! + \brief get current subsecond value (API_ID(0x000EU)) + \param[in] none + \param[out] none + \retval current subsecond value +*/ +uint32_t rtc_subsecond_get(void) +{ + uint32_t reg; + /* 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 reset most of the RTC registers (API_ID(0x000FU)) + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + /* After Backup domain reset, some of the RTC registers are write-protected: RTC_TIME, RTC_DATE, RTC_PSC, + RTC_HRFC, RTC_SHIFTCTL, the bit INITM in RTC_STAT and the bits CS, S1H, A1H, REFEN in RTC_CTL. */ + ErrStatus error_status = ERROR;; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* rtc alarmx related registers are not under the protection of RTC_WPK, different from former GD32MCU */ + RTC_CTL &= ((uint32_t)~(RTC_CTL_ALRM0EN)); + /* to write RTC_ALRMxTD and RTC_ALRMxSS register, 1 ALRMxEN bit in RTC_CTL register should be reset as the condition + 2 or in INIT mode */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + + /* reset RTC_CTL register, this can be done without the init mode */ + RTC_CTL &= RTC_REGISTER_RESET; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status) { + /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. + in order to read calendar from shadow register, not the real registers being reset */ + RTC_TIME = RTC_REGISTER_RESET; + RTC_DATE = RTC_DATE_RESET; + + RTC_PSC = RTC_PSC_RESET; + + /* reset RTC_STAT register, also exit init mode. + at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ + RTC_STAT = RTC_STAT_RESET; + + /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + + /* reset RTC_SHIFTCTL and RTC_HRFC register, and the bits S1H, A1H, REFEN in RTC_CTL, these can be done without the init mode */ + RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_HRFC = RTC_REGISTER_RESET; + + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief adjust the daylight saving time by adding or substracting one hour from the current time (API_ID(0x0010U)) + \param[in] operation: hour adjustment operation + only one parameter can be selected which is shown as below: + \arg RTC_CTL_A1H: add one hour + \arg RTC_CTL_S1H: substract one hour + \param[out] none + \retval none +*/ +void rtc_hour_adjust(uint32_t operation) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint32_t)((operation)&(RTC_CTL_A1H |RTC_CTL_S1H)); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + + +/*! + \brief adjust RTC second or subsecond value of current time (API_ID(0x0011U)) + \param[in] add: add 1s to current time or not + only one parameter can be selected which is shown as below: + \arg RTC_SHIFT_ADD1S_RESET: no effect + \arg RTC_SHIFT_ADD1S_SET: add 1s to current time + \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF) + \param[out] none + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) +{ + ErrStatus error_status = ERROR; + + uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + + uint32_t flag_status; + uint32_t temp ; + + /* 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((0U == flag_status) && (0U == 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 reference clock detection function (API_ID(0x0012U)) + \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 (API_ID(0x0013U)) + \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 configure RTC smooth calibration (API_ID(0x0014U)) + \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 + \note This function may contain scenarios leading to an infinite loop. + Modify it according to the actual usage requirements. + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t smooth_minus) +{ + ErrStatus error_status = ERROR; + + volatile uint32_t time_index = RTC_HRFC_TIMEOUT; + uint32_t flag_status; + + /* 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(smooth_minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC time-stamp (API_ID(0x0015U)) + \param[in] edge: specify which edge to detect of time-stamp + only one parameter can be selected which is shown as below: + \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event + \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event + \param[out] none + \retval none +*/ +void rtc_timestamp_enable(uint32_t edge) +{ + uint32_t reg_ctl; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the bits to be configured in RTC_CTL */ + reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN))); + + /* new configuration */ + reg_ctl |= (uint32_t)((edge&(RTC_CTL_TSEG)) | RTC_CTL_TSEN); + + RTC_CTL = (uint32_t)reg_ctl; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC time-stamp (API_ID(0x0016U)) + \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 (API_ID(0x0017U)) + \param[in] none + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + parameters for RTC time-stamp configuration + members of the structure and the member values are shown as below: + timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + timestamp_date: 0x1 - 0x31(BCD format) + timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDNESDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY + timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc display_format + timestamp_minute: 0x0 - 0x59(BCD format) + timestamp_second: 0x0 - 0x59(BCD format) + am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_timestamp_get(rtc_timestamp_struct *rtc_timestamp) +{ +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_RTC_VALID_POINTER(rtc_timestamp)) { + fw_debug_report_err(RTC_MODULE_ID, API_ID(0x0017U), ERR_PARAM_POINTER); + }else +#endif /* FW_DEBUG_ERR_REPORT */ + { + uint32_t temp_tts, temp_dts; + + /* 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 (API_ID(0x0018U)) + \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 configure rtc calibration output source (API_ID(0x0019U)) + \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&((RTC_CTL_COEN | RTC_CTL_COS))); + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure rtc alarm output source (API_ID(0x001AU)) + \param[in] source: specify signal to output + only one parameter can be selected which is shown as below: + \arg RTC_ALARM0_HIGH: when the alarm0 flag is set, the output pin is high + \arg RTC_ALARM0_LOW: when the alarm0 flag is set, the output pin is low + \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 alarm_output, 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_TYPE &= ~RTC_TYPE_ALRMOUTTYPE; + + RTC_CTL |= (uint32_t)(alarm_output &((RTC_CTL_OS | RTC_CTL_OPOL)) ); + /* alarm output */ + RTC_TYPE |= (uint32_t)(mode & RTC_TYPE_ALRMOUTTYPE); + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief select the RTC output pin (API_ID(0x001BU)) + \param[in] outputpin: specify the rtc output pin is PC13 or not + \arg RTC_OUT1_DISABLE: the rtc output pin is RTC_OUT0 + \arg RTC_OUT1_ENABLE: the rtc output pin is RTC_OUT1 + \param[out] none + \retval none +*/ +void rtc_output_pin_select(uint32_t outputpin) +{ + uint32_t ctl_tmp = RTC_CTL; + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + ctl_tmp &= (uint32_t)~(RTC_CTL_OUT1EN); + ctl_tmp |= (uint32_t)(outputpin & RTC_CTL_OUT1EN); + RTC_CTL = ctl_tmp; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable specified RTC interrupt (API_ID(0x001CU)) + \param[in] interrupt: specify which interrupt source to be enabled + only one parameter can be selected which is shown as below: + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM0: alarm0 interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(rtc_interrupt_flag_enum 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); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disble specified RTC interrupt (API_ID(0x001DU)) + \param[in] interrupt: specify which interrupt source to be disabled + only one parameter can be selected which is shown as below: + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM0: alarm0 interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(rtc_interrupt_flag_enum 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); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief check specified flag (API_ID(0x001EU)) + \param[in] flag: specify which flag to check + only one parameter can be selected which is shown as below: + \arg RTC_FLAG_SCP: smooth calibration pending 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_INIT: initialization state flag + \arg RTC_FLAG_RSYN: register synchronization flag + \arg RTC_FLAG_YCM: year configuration mark status flag + \arg RTC_FLAG_SOP: shift function operation pending flag + \arg RTC_FLAG_ALARM0W: alarm0 configuration can be written flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtc_flag_get(rtc_flag_enum flag) +{ + FlagStatus flag_state = RESET; + + if((uint32_t)RESET != (RTC_STAT & (uint32_t)flag)) { + flag_state = SET; + } + return flag_state; +} + +/*! + \brief clear specified flag (API_ID(0x001FU)) + \param[in] flag_clear: specify which flag to clear + only one parameter can be selected which is shown as below: + \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_RSYN: register synchronization flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(rtc_flag_enum flag_clear) +{ + RTC_STAT &= ~(uint32_t)(flag_clear); +} \ No newline at end of file diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_spi.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_spi.c new file mode 100644 index 0000000..d174ba3 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_spi.c @@ -0,0 +1,1046 @@ +/*! + \file gd32c2x1_spi.c + \brief SPI driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_spi.h" + +/* SPI/I2S parameter initialization mask */ +#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI init mask */ +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S init mask */ +#define SPI_FIFO_INIT_MASK1 ((uint32_t)0x00003840U) /*!< SPI parameter initialization mask1 */ +#define SPI_FIFO_INIT_MASK2 ((uint32_t)0x0000F0FFU) /*!< SPI parameter initialization mask2*/ +#define SPI_BYTEN_MASK ((uint32_t)0x00001000U) /*!< SPI access to FIFO mask */ +#define SPI_TXLVL_MASK ((uint32_t)0x00001800U) /*!< SPI TXFIFO mask */ +#define SPI_RXLVL_MASK ((uint32_t)0x00000600U) /*!< SPI RXFIFO mask */ +/* default value */ +#define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /*!< default value of SPI_I2SPSC register */ +/* I2S clock source selection, multiplication and division mask */ +#define I2S0_CLOCK_SEL ((uint32_t)0x0000C000U) /*!< I2S clock source selection */ +#define I2S_CLOCK_MUL_MASK ((uint32_t)0x0000F000U) /*!< I2S clock multiplication mask */ +#define I2S_CLOCK_DIV_MASK ((uint32_t)0x000000F0U) /*!< I2S clock division mask */ +#define I2S_STANDARD_MASK ((uint32_t)0x000000B0U) /*!< I2S standard mask */ + +#define SPI_TRANS_MODE_MASK ((uint32_t)0x0000C400U) /*!< SPI transfer mode mask */ +#define SPI_I2S_INT_MASK ((uint32_t)0x000000E0U) /*!< SPI and I2S interrupt enable mask */ + +/*! + \brief reset SPI and I2S (API_ID(0x0001U)) + \param[in] spi_periph: SPIx(x=0,1) + \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 and I2S1 */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + default : + break; + } +} + +/*! + \brief initialize the parameters of SPI struct with default values (API_ID(0x0002U)) + \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) +{ +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_VALID_POINTER(spi_struct)) { + fw_debug_report_err(SPI_MODULE_ID, API_ID(0x0002U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* 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 (API_ID(0x0003U)) + \param[in] spi_periph: SPIx(x=0,1) + \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_4BIT, SPI_FRAMESIZE_5BIT + SPI_FRAMESIZE_6BIT, SPI_FRAMESIZE_7BIT + SPI_FRAMESIZE_8BIT, SPI_FRAMESIZE_9BIT + SPI_FRAMESIZE_10BIT, SPI_FRAMESIZE_11BIT + SPI_FRAMESIZE_12BIT, SPI_FRAMESIZE_13BIT + SPI_FRAMESIZE_14BIT, SPI_FRAMESIZE_15BIT + SPI_FRAMESIZE_16BIT + 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 ErrStatus: ERROR or SUCCESS +*/ +ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct) +{ + ErrStatus reval = SUCCESS; + uint32_t reg1; + uint32_t reg2, reg3; + +#ifdef FW_DEBUG_ERR_REPORT + /* check parameter */ + if(NOT_VALID_POINTER(spi_struct)) { + fw_debug_report_err(SPI_MODULE_ID, API_ID(0x0003U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + reg1 = SPI_CTL0(spi_periph); + reg1 &= SPI_INIT_MASK; + + reg2 = SPI_CTL0(spi_periph); + reg2 &= SPI_FIFO_INIT_MASK1; + + reg3 = SPI_CTL1(spi_periph); + reg3 &= SPI_FIFO_INIT_MASK2; + + if(SPI0 == spi_periph) { + /* select SPI as master or slave */ + reg1 |= (spi_struct->device_mode & SPI_MASTER); + /* select SPI transfer mode */ + reg1 |= (spi_struct->trans_mode & SPI_TRANS_MODE_MASK); + /* select SPI NSS use hardware or software */ + reg1 |= (spi_struct->nss & SPI_NSS_SOFT); + /* select SPI LSB or MSB */ + reg1 |= (spi_struct->endian & SPI_ENDIAN_LSB); + /* select SPI polarity and phase */ + reg1 |= (spi_struct->clock_polarity_phase & SPI_CK_PL_HIGH_PH_2EDGE); + /* select SPI prescale to adjust transmit speed */ + reg1 |= (spi_struct->prescale & SPI_PSC_256); + /* select SPI frame size */ + /* check SPI0 frame size is 8bits/16bits or not*/ + if((SPI_FRAMESIZE_8BIT != spi_struct->frame_size) && (SPI_FRAMESIZE_16BIT != spi_struct->frame_size)) { + reval = ERROR; + } else { + reg1 |= (uint32_t)(spi_struct->frame_size & SPI_CTL0_FF16); + } + + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg1; + + } else { + /* select SPI as master or slave */ + reg2 |= (spi_struct->device_mode & SPI_MASTER); + /* select SPI transfer mode */ + reg2 |= (spi_struct->trans_mode & SPI_TRANS_MODE_MASK); + /* select SPI NSS use hardware or software */ + reg2 |= (spi_struct->nss & SPI_NSS_SOFT); + /* select SPI LSB or MSB */ + reg2 |= (spi_struct->endian & SPI_ENDIAN_LSB); + /* select SPI polarity and phase */ + reg2 |= (spi_struct->clock_polarity_phase & SPI_CK_PL_HIGH_PH_2EDGE); + /* select SPI prescale to adjust transmit speed */ + reg2 |= (spi_struct->prescale & SPI_PSC_256); + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg2; + + /* select SPI data size */ + reg3 |= (uint32_t)(spi_struct->frame_size & SPI_CTL1_DZ); + /* write to SPI_CTL1 register */ + SPI_CTL1(spi_periph) = (uint32_t)reg3; + } + } + /* select SPI mode */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); + return reval; +} + +/*! + \brief enable SPI (API_ID(0x0004U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief disable SPI (API_ID(0x0005U)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x0006U)) + \param[in] spi_periph: SPIx(x=0) + \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; + + 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 & I2S_MODE_MASTERRX); + /* select I2S standard */ + reg |= (uint32_t)(i2s_standard & I2S_STANDARD_MASK); + /* select I2S polarity */ + reg |= (uint32_t)(i2s_ckpl & I2S_CKPL_HIGH); + + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief configure I2S prescaler (API_ID(0x0007U)) + \param[in] spi_periph: SPIx(x=0) + \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, i2sof; + uint32_t clks; + uint32_t i2sclock; + +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_I2S_AUDIOSAMPLE(i2s_audiosample)) { + fw_debug_report_err(SPI_MODULE_ID, API_ID(0x0007U), ERR_PARAM_INVALID); + } else +#endif + { + /* deinit SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = SPI_I2SPSC_DEFAULT_VALUE; + + /* I2S1 clock source selection */ + clks = I2S0_CLOCK_SEL; + + if(0U != (RCU_CFG1 & clks)) { + /* get RCU PLL2 clock multiplication factor */ + clks = (uint32_t)((RCU_CFG1 & I2S_CLOCK_MUL_MASK) >> 12U); + + if((clks > 5U) && (clks < 15U)) { + /* multiplier is between 8 and 14 */ + clks += 2U; + } else { + if(15U == clks) { + /* multiplier is 20 */ + clks = 20U; + } + } + + /* get the PREDV1 value */ + i2sclock = (uint32_t)(((RCU_CFG1 & I2S_CLOCK_DIV_MASK) >> 4U) + 1U); + /* calculate i2sclock based on PLL2 and PREDV1 */ + i2sclock = (uint32_t)((HXTAL_VALUE / i2sclock) * clks * 2U); + } else { + /* get system clock */ + i2sclock = rcu_clock_freq_get(CK_SYS); + } + + /* configure 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 & SPI_I2SPSC_DIV) | (i2sof & SPI_I2SPSC_OF) | (i2s_mckout & I2S_MCKOUT_ENABLE)); + + /* 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 & I2S_FRAMEFORMAT_DT32B_CH32B); + } +} + +/*! + \brief enable I2S (API_ID(0x0008U)) + \param[in] spi_periph: SPIx(x=0) + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief disable I2S (API_ID(0x0009U)) + \param[in] spi_periph: SPIx(x=0) + \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 (API_ID(0x000AU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x000BU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x000CU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x000DU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x000EU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] 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 dma) +{ + if(SPI_DMA_TRANSMIT == dma) { + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + } else { + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief disable SPI DMA send or receive (API_ID(0x000FU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] 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 dma) +{ + if(SPI_DMA_TRANSMIT == dma) { + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + } else { + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI1 total number of data to transmit by DMA is odd or not (API_ID(0x0010U)) + \param[in] spi_periph: SPIx(x=1) + \param[in] odd: odd bytes in TX DMA channel + only one parameter can be selected which is shown as below: + \arg SPI_TXDMA_EVEN: number of byte in TX DMA channel is even + \arg SPI_TXDMA_ODD: number of byte in TX DMA channel is odd + \param[out] none + \retval none +*/ +void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd) +{ + /* clear SPI_CTL1_TXDMA_ODD bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TXDMA_ODD); + /* configure SPI_CTL1_TXDMA_ODD bit */ + SPI_CTL1(spi_periph) |= (uint32_t)(odd & SPI_TXDMA_ODD); +} + +/*! + \brief configure SPI1 total number of data to receive by DMA is odd or not (API_ID(0x0011U)) + \param[in] spi_periph: SPIx(x=1) + \param[in] odd: odd bytes in RX DMA channel + only one parameter can be selected which is shown as below: + \arg SPI_RXDMA_EVEN: number of bytes in RX DMA channel is even + \arg SPI_RXDMA_ODD: number of bytes in RX DMA channel is odd + \param[out] none + \retval none +*/ +void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd) +{ + /* clear SPI_CTL1_RXDMA_ODD bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RXDMA_ODD); + /* configure SPI_CTL1_RXDMA_ODD bit */ + SPI_CTL1(spi_periph) |= (uint32_t)(odd & SPI_TXDMA_ODD); +} + +/*! + \brief configure SPI0 access size to FIFO(8bit or 16bit) (API_ID(0x0012U)) + \param[in] spi_periph: SPIx(x=1) + \param[in] fifo_access_size: byte access enable + only one parameter can be selected which is shown as below: + \arg SPI_HALFWORD_ACCESS: half-word access to FIFO + \arg SPI_BYTE_ACCESS: byte access to FIFO + \param[out] none + \retval none +*/ +void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size) +{ + /* clear SPI_CTL1_BYTEN bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_BYTEN); + /* configure SPI_CTL1_BYTEN bit */ + SPI_CTL1(spi_periph) |= (uint32_t)(fifo_access_size & SPI_BYTE_ACCESS); +} + +/*! + \brief configure SPI data frame format (API_ID(0x0013U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] frame_format: SPI frame size + only one parameter can be selected which is shown as below: + \arg SPI_FRAMESIZE_xBIT(x=4,5..16, for SPI1, x=8,16, for SPI0):SPI frame size is x bits + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + ErrStatus reval = SUCCESS; + uint32_t reg; + + if(SPI0 == spi_periph) { + /* check SPI0 frame size is 8bits/16bits or not*/ + if((SPI_FRAMESIZE_8BIT != frame_format) && (SPI_FRAMESIZE_16BIT != frame_format)) { + reval = ERROR; + } else { + /* 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 & SPI_CTL0_FF16); + } + } else { + reg = SPI_CTL1(spi_periph); + /* clear SPI_CTL1_DZ bits */ + reg &= (uint32_t)(~SPI_CTL1_DZ); + reg |= (uint32_t)(frame_format & SPI_CTL1_DZ); + /* configure SPI_CTL1_DZ bits */ + SPI_CTL1(spi_periph) = reg; + } + return reval; +} + + +/*! + \brief configure SPI bidirectional transfer direction (API_ID(0x0014U)) + \param[in] spi_periph: SPIx(x=0,1) + \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 SPI transmit data (API_ID(0x0015U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data) +{ + uint32_t reg, byten; + + if(SPI0 == spi_periph) { + SPI_DATA(spi_periph) = (uint16_t)data; + } else { + /* get the access size to FIFO */ + byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK; + if(0U != byten) { + reg = spi_periph + 0x0CU; + *(uint8_t *)(reg) = (uint8_t)data; + } else { + SPI_DATA(spi_periph) = (uint16_t)data; + } + } +} + +/*! + \brief SPI receive data (API_ID(0x0016U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval 16-bit data +*/ +uint16_t spi_i2s_data_receive(uint32_t spi_periph) +{ + uint16_t reval = 0U; + + uint32_t reg, byten; + + if(SPI0 == spi_periph) { + reval = ((uint16_t)SPI_DATA(spi_periph)); + } else { + /* get the access size to FIFO */ + byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK; + if(0U != byten) { + reg = spi_periph + 0x0CU; + reval = (uint16_t)(*(uint8_t *)(reg)); + } else { + reval = ((uint16_t)SPI_DATA(spi_periph)); + } + } + + return reval; +} + +/*! + \brief set SPI CRC polynomial (API_ID(0x0017U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] crc_poly: CRC polynomial value + \param[out] none + \retval none +*/ +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly) +{ + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint16_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial (API_ID(0x0018U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval 16-bit CRC polynomial +*/ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + uint16_t reval = 0U; + + reval = ((uint16_t)SPI_CRCPOLY(spi_periph)); + return reval; +} + +/*! + \brief set CRC length (API_ID(0x0019U)) + \param[in] spi_periph: SPIx(x=1) + \param[in] crc_length: CRC length + only one parameter can be selected which is shown as below: + \arg SPI_CRC_8BIT: CRC length is 8 bits + \arg SPI_CRC_16BIT: CRC length is 16 bits + \param[out] none + \retval none +*/ +void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length) +{ + /* clear SPI_CTL0_CRCL bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCL); + /* configure SPI_CTL0_CRCL bit */ + SPI_CTL0(spi_periph) |= (uint32_t)(crc_length & SPI_CRC_16BIT); +} + +/*! + \brief turn on CRC function (API_ID(0x001AU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x001BU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x001CU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x001DU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] crc: SPI crc value + only one parameter can be selected which is shown as below: + \arg SPI_CRC_TX: get transmit crc value + \arg SPI_CRC_RX: get receive crc value + \param[out] none + \retval 16-bit CRC value +*/ +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc) +{ + uint16_t reval = 0U; + + if(SPI_CRC_TX == crc) { + reval = ((uint16_t)(SPI_TCRC(spi_periph))); + } else { + reval = ((uint16_t)(SPI_RCRC(spi_periph))); + } + return reval; +} + +/*! + \brief clear SPI CRC error flag status (API_ID(0x001EU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); +} + +/*! + \brief enable SPI TI mode (API_ID(0x001FU)) + \param[in] spi_periph: SPIx(x=0,1) + \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 (API_ID(0x0020U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_ti_mode_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD); +} + +/*! + \brief enable SPI NSS pulse mode (API_ID(0x0021U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nssp_mode_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSP; +} + +/*! + \brief disable SPI NSS pulse mode (API_ID(0x0022U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nssp_mode_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSP); +} + +/*! + \brief enable quad wire SPI (API_ID(0x0023U)) + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void spi_quad_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief disable quad wire SPI (API_ID(0x0024U)) + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void spi_quad_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD); +} + +/*! + \brief enable quad wire SPI write (API_ID(0x0025U)) + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void spi_quad_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief enable quad wire SPI read (API_ID(0x0026U)) + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void spi_quad_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief enable SPI_IO2 and SPI_IO3 pin output (API_ID(0x0027U)) + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void spi_quad_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + +/*! + \brief disable SPI_IO2 and SPI_IO3 pin output (API_ID(0x0028U)) + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void spi_quad_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} + +/*! + \brief clear SPI/I2S format error flag status (API_ID(0x0029U)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] flag: SPI/I2S frame format error flag + one or more parameters can be selected which is shown as below: + \arg SPI_FLAG_FERR: SPI format error flag + \arg I2S_FLAG_FERR: I2S format error flag + \param[out] none + \retval none +*/ +void spi_i2s_format_error_clear(uint32_t spi_periph, uint32_t flag) +{ + SPI_STAT(spi_periph) = (uint32_t)(~flag); +} + +/*! + \brief get SPI and I2S flag status (API_ID(0x002AU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] flag: SPI/I2S flag status + only one parameter can be selected which are shown as below: + \arg SPI_FLAG_TBE: transmit buffer empty flag + \arg SPI_FLAG_RBNE: receive buffer not empty flag + \arg SPI_FLAG_TRANS: transmit on-going flag + \arg SPI_FLAG_RXORERR: receive overrun error flag + \arg SPI_FLAG_CONFERR: mode config error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: SPI format error interrupt flag + \arg I2S_FLAG_TBE: transmit buffer empty flag + \arg I2S_FLAG_RBNE: receive buffer not empty flag + \arg I2S_FLAG_CH: channel side flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_TRANS: transmit on-going flag + \arg I2S_FLAG_RXORERR: overrun error flag + \arg I2S_FLAG_FERR: I2S format error interrupt flag + only for SPI1: + \arg SPI_FLAG_TXLVL_EMPTY: SPI TXFIFO is empty + \arg SPI_FLAG_TXLVL_QUARTER_FULL: SPI TXFIFO is a quarter of full + \arg SPI_FLAG_TXLVL_HALF_FULL: SPI TXFIFO is a half of full + \arg SPI_FLAG_TXLVL_FULL: SPI TXFIFO is full + \arg SPI_FLAG_RXLVL_EMPTY: SPI RXFIFO is empty + \arg SPI_FLAG_RXLVL_QUARTER_FULL: SPI RXFIFO is a quarter of full + \arg SPI_FLAG_RXLVL_HALF_FULL: SPI RXFIFO is a half of full + \arg SPI_FLAG_RXLVL_FULL: SPI RXFIFO is full + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag) +{ + FlagStatus reval = RESET; + uint32_t reg = SPI_STAT(spi_periph); + + switch(flag) { +#if defined(GD32C231) || defined(GD32C221) + case SPI_FLAG_TXLVL_EMPTY: + if(0U == (reg & SPI_TXLVL_MASK)) { + reval = SET; + } + break; + case SPI_FLAG_TXLVL_QUARTER_FULL: + case SPI_FLAG_TXLVL_HALF_FULL: + case SPI_FLAG_TXLVL_FULL: + if(flag == (reg & SPI_TXLVL_MASK)) { + reval = SET; + } + break; + case SPI_FLAG_RXLVL_EMPTY: + if(0U == (reg & SPI_RXLVL_MASK)) { + reval = SET; + } + break; + case SPI_FLAG_RXLVL_QUARTER_FULL: + case SPI_FLAG_RXLVL_HALF_FULL: + case SPI_FLAG_RXLVL_FULL: + if(flag == (reg & SPI_RXLVL_MASK)) { + reval = SET; + } + break; +#endif + default: + if(0U != (reg & flag)) { + reval = SET; + } + break; + } + + return reval; +} + +/*! + \brief enable SPI and I2S interrupt (API_ID(0x002BU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error, configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt) +{ + SPI_CTL1(spi_periph) |= (uint32_t)(interrupt & SPI_I2S_INT_MASK); +} + +/*! + \brief disable SPI and I2S interrupt (API_ID(0x002CU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt) +{ + SPI_CTL1(spi_periph) &= ~(uint32_t)(interrupt & SPI_I2S_INT_MASK); +} + +/*! + \brief get SPI and I2S interrupt flag status (API_ID(0x002DU)) + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt flag status + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag + \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag + \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag + \arg SPI_INT_FLAG_CONFERR: config error interrupt flag + \arg SPI_INT_FLAG_CRCERR: CRC error interrupt flag + \arg I2S_INT_FLAG_TXURERR: underrun error interrupt flag + \arg SPI_I2S_INT_FLAG_FERR: format error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt) +{ + FlagStatus reval = RESET; + uint32_t reg1 = SPI_STAT(spi_periph); + uint32_t reg2 = SPI_CTL1(spi_periph); + + switch(interrupt) { + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_FLAG_TBE: + reg1 = reg1 & SPI_STAT_TBE; + reg2 = reg2 & SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_FLAG_RBNE: + reg1 = reg1 & SPI_STAT_RBNE; + reg2 = reg2 & SPI_CTL1_RBNEIE; + break; + /* SPI/I2S overrun interrupt */ + case SPI_I2S_INT_FLAG_RXORERR: + reg1 = reg1 & SPI_STAT_RXORERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI config error interrupt */ + case SPI_INT_FLAG_CONFERR: + reg1 = reg1 & SPI_STAT_CONFERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI CRC error interrupt */ + case SPI_INT_FLAG_CRCERR: + reg1 = reg1 & SPI_STAT_CRCERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* underrun error interrupt flag */ + 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((0U != reg1) && (0U != reg2)) { + reval = SET; + } else { + reval = RESET; + } + return reval; +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_syscfg.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_syscfg.c new file mode 100644 index 0000000..050bd7e --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_syscfg.c @@ -0,0 +1,309 @@ +/*! + \file gd32c2x1_syscfg.c + \brief SYSCFG driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_syscfg.h" + +#define SYSCFG_CFG0_FMPEN_MASK (0x01DF0000U) +#define SYSCFG_CFG0_RMP_MASK (0x00000018U) +#define SYSCFG_CFG1_LOCK_MASK (0x00000003U) +#define SYSCFG_CFG2_IE_MASK (0x0000001FU) +#define SYSCFG_STAT_FLAG_MASK (0x00000003U) + +/*! + \brief reset the SYSCFG registers (API_ID(0x0001U)) + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_SYSCFGRST); + rcu_periph_reset_disable(RCU_SYSCFGRST); +} + +/*! + \brief enable I2C Fm+ mode (API_ID(0x0002U)) + \param[in] syscfg_gpio + one or more parameters can be selected which are shown as below: + \arg SYSCFG_PB6_FMPEN: PB6 pin I2C Fm+ mode + \arg SYSCFG_PB7_FMPEN: PB7 pin I2C Fm+ mode + \arg SYSCFG_PB8_FMPEN: PB8 pin I2C Fm+ mode + \arg SYSCFG_PB9_FMPEN: PB9 pin I2C Fm+ mode + \arg SYSCFG_I2C0_FMPEN: I2C0 Fm+ mode + \arg SYSCFG_PA9_FMPEN: PA9 pin I2C Fm+ mode + \arg SYSCFG_PA10_FMPEN: PA10 pin I2C Fm+ mode + \arg SYSCFG_PC14_FMPEN: PC14 pin I2C Fm+ mode + \param[out] none + \retval none +*/ +void syscfg_i2c_fast_mode_plus_enable(uint32_t syscfg_gpio) +{ + SYSCFG_CFG0 |= (syscfg_gpio & SYSCFG_CFG0_FMPEN_MASK); +} + +/*! + \brief disable I2C Fm+ mode (API_ID(0x0003U)) + \param[in] syscfg_gpio + only one parameters can be selected which are shown as below: + \arg SYSCFG_PB6_FMPEN: PB6 pin I2C Fm+ mode + \arg SYSCFG_PB7_FMPEN: PB7 pin I2C Fm+ mode + \arg SYSCFG_PB8_FMPEN: PB8 pin I2C Fm+ mode + \arg SYSCFG_PB9_FMPEN: PB9 pin I2C Fm+ mode + \arg SYSCFG_I2C0_FMPEN: I2C0 Fm+ mode + \arg SYSCFG_PA9_FMPEN: PA9 pin I2C Fm+ mode + \arg SYSCFG_PA10_FMPEN: PA10 pin I2C Fm+ mode + \arg SYSCFG_PC14_FMPEN: PC14 pin I2C Fm+ mode + \param[out] none + \retval none +*/ +void syscfg_i2c_fast_mode_plus_disable(uint32_t syscfg_gpio) +{ + + SYSCFG_CFG0 &= (uint32_t)(~(syscfg_gpio & SYSCFG_CFG0_FMPEN_MASK)); + +} + +/*! + \brief enable remap pin function for small packages (API_ID(0x0004U)) + \param[in] remap_pin + one or more parameters can be selected which are shown as below: + \arg SYSCFG_CFG0_PA11_RMP : PA11 remap to PA9 + \arg SYSCFG_CFG0_PA12_RMP : PA12 remap to PA10 + \param[out] none + \retval none +*/ +void syscfg_pin_remap_enable(uint32_t remap_pin) +{ + SYSCFG_CFG0 |= (remap_pin & SYSCFG_CFG0_RMP_MASK); +} + +/*! + \brief disable remap pin function for small packages (API_ID(0x0005U)) + \param[in] remap_pin + one or more parameters can be selected which are shown as below: + \arg SYSCFG_CFG0_PA11_RMP : PA11 remap to PA9 + \arg SYSCFG_CFG0_PA12_RMP : PA12 remap to PA10 + \param[out] none + \retval none +*/ +void syscfg_pin_remap_disable(uint32_t remap_pin) +{ + SYSCFG_CFG0 &= ~(remap_pin & SYSCFG_CFG0_RMP_MASK); +} + +/*! + \brief get the current boot mode (API_ID(0x0006U)) + \param[in] none + \param[out] none + \retval the boot mode + \arg SYSCFG_BOOTMODE_FLASH: boot from the main flash + \arg SYSCFG_BOOTMODE_SYSTEM: boot from the system flash memory + \arg SYSCFG_BOOTMODE_SRAM: boot from the embedded SRAM +*/ +uint8_t syscfg_bootmode_get(void) +{ + /* get the bootmode */ + uint8_t temp = (uint8_t)(SYSCFG_CFG0 & 0x00000003U); + + return temp; +} + +/*! + \brief configure the GPIO pin as EXTI Line (API_ID(0x0007U)) + \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,F): 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(GPIOAx = 0..15, GPIOBx = 0..15, GPIOCx = 0..15, GPIODx = 0..6,8,9, GPIOFx = 0,1): EXTI GPIO pin + \param[out] none + \retval none +*/ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) +{ + uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); + uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); + + switch(exti_pin / EXTI_SS_JSTEP) { + case EXTISS0: + /* clear EXTI source line(0..3) */ + SYSCFG_EXTISS0 &= clear_exti_mask; + /* configure EXTI soure line(0..3) */ + SYSCFG_EXTISS0 |= config_exti_mask; + break; + case EXTISS1: + /* clear EXTI soure line(4..7) */ + SYSCFG_EXTISS1 &= clear_exti_mask; + /* configure EXTI soure line(4..7) */ + SYSCFG_EXTISS1 |= config_exti_mask; + break; + case EXTISS2: + /* clear EXTI soure line(8..11) */ + SYSCFG_EXTISS2 &= clear_exti_mask; + /* configure EXTI soure line(8..11) */ + SYSCFG_EXTISS2 |= config_exti_mask; + break; + case EXTISS3: + /* clear EXTI soure line(12..15) */ + SYSCFG_EXTISS3 &= clear_exti_mask; + /* configure EXTI soure line(12..15) */ + SYSCFG_EXTISS3 |= config_exti_mask; + break; + default: + break; + } +} + +/*! + \brief enable module lockup function (function can be disabled by system reset) (API_ID(0x0008U)) + \param[in] lockup: + one or more parameters can be selected which is shown as below: + \arg SYSCFG_LOCKUP_LOCK: CPU lockup signal + \arg SYSCFG_SRAM_LOCKUP: SRAM ECC check error lock signal + \param[out] none + \retval none +*/ +void syscfg_lockup_enable(uint32_t lockup) +{ + SYSCFG_CFG1 |= (lockup & SYSCFG_CFG1_LOCK_MASK); +} + +/*! + \brief SRAM ECC single correctable bit get (API_ID(0x0009U)) + \param[in] none + \param[out] none + \retval single correctable bit +*/ +uint32_t syscfg_sram_ecc_single_correctable_bit_get(void) +{ + uint32_t error_bits; + error_bits = (uint32_t)((SYSCFG_CFG2 & SYSCFG_ECCSERRBITS) >> 10U); + return error_bits; +} + +/*! + \brief SRAM ECC error address get (API_ID(0x000AU)) + \param[in] none + \param[out] none + \retval SRAM ECC error address +*/ +uint32_t syscfg_sram_ecc_error_address_get(void) +{ + uint32_t addr; + addr = (uint32_t)((SYSCFG_CFG2 & SYSCFG_ECCEADDR)>> 20U); + return addr; +} + +/*! + \brief set the IRQ_LATENCY value (API_ID(0x000BU)) + \param[in] irq_latency: IRQ_LATENCY value (0x00 - 0xFF) + \param[out] none + \retval none +*/ +void syscfg_irq_latency_set(uint32_t irq_latency) +{ + uint32_t reg; + reg = SYSCFG_CPU_IRQ_LAT & (~(uint32_t)SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY); + reg |= (uint32_t)(IRQ_LATENCY(irq_latency & 0xFFU)); + SYSCFG_CPU_IRQ_LAT = (uint32_t)reg; +} + +/*! + \brief interrupt enable (API_ID(0x000DU)) + \param[in] interrupt: + one or more parameter can be selected which is shown as below: + \arg SYSCFG_CFG2_LXTALCSS_IE: LXTAL clock stuck interrupt enable + \arg SYSCFG_CFG2_HXTALCSS_IE: HXTAL clock stuck interrupt enable + \arg SYSCFG_CFG2_ECCMEIE: Multi-bits (two bits) non-correction error NMI interrupt enable + \arg SYSCFG_CFG2_ECCSEIE: Single bit correction error interrupt enable + \param[out] none + \retval none +*/ +void syscfg_interrupt_enable(uint32_t interrupt) +{ + SYSCFG_CFG2 |= (interrupt & SYSCFG_CFG2_IE_MASK); +} + +/*! + \brief interrupt disable (API_ID(0x000EU)) + \param[in] interrupt: + one or more parameter can be selected which is shown as below: + \arg SYSCFG_CFG2_LXTALCSS_IE: LXTAL clock stuck interrupt enable + \arg SYSCFG_CFG2_HXTALCSS_IE: HXTAL clock stuck interrupt enable + \arg SYSCFG_CFG2_ECCMEIE: Multi-bits (two bits) non-correction error NMI interrupt disable + \arg SYSCFG_CFG2_ECCSEIE: Single bit correction error interrupt disable + \param[out] none + \retval none +*/ +void syscfg_interrupt_disable(uint32_t interrupt) +{ + SYSCFG_CFG2 &= ~(interrupt & SYSCFG_CFG2_IE_MASK); +} + +/*! + \brief get SYSCFG flag state (API_ID(0x000F)) + \param[in] flag: SYSCFG flags + one or more parameter can be selected which is shown as below: + \arg SYSCFG_FLAG_ECCME: SRAM two bits non-correction event flag + \arg SYSCFG_FLAG_ECCSE: SRAM single bit correction event flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus syscfg_interrupt_flag_get(uint32_t flag) +{ + FlagStatus interrupt_flag; + + /* get flag and interrupt enable state */ + if( 0U != (SYSCFG_STAT & (flag & SYSCFG_STAT_FLAG_MASK))) { + interrupt_flag = SET; + } else { + interrupt_flag = RESET; + } + + return interrupt_flag; +} + +/*! + \brief clear SYSCFG flag state (API_ID(0x0010)) + \param[in] flag: SYSCFG flags + one or more parameter can be selected which is shown as below: + \arg SYSCFG_FLAG_ECCME: SRAM two bits non-correction event flag + \arg SYSCFG_FLAG_ECCSE: SRAM single bit correction event flag + \param[out] none + \retval none +*/ +void syscfg_interrupt_flag_clear(uint32_t flag) +{ + SYSCFG_STAT = (flag & SYSCFG_STAT_FLAG_MASK); +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_timer.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_timer.c new file mode 100644 index 0000000..2224eeb --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_timer.c @@ -0,0 +1,2526 @@ +/*! + \file gd32c2x1_timer.c + \brief TIMER driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_timer.h" + +/* TIMER init parameter mask */ +#define ALIGNEDMODE_MASK ((uint32_t)0x00000060U) /*!< TIMER init parameter aligne dmode mask */ +#define COUNTERDIRECTION_MASK ((uint32_t)0x00000010U) /*!< TIMER init parameter counter direction mask */ +#define CLOCKDIVISION_MASK ((uint32_t)0x00000300U) /*!< TIMER init parameter clock division value mask */ +#define DEADTIME_MASK ((uint32_t)0x000000FFU) /*!< TIMER init parameter deadtime value mask */ +#define BREAK0FILTER_MASK ((uint32_t)0x000F0000U) /*!< TIMER berak0 filter mask */ +#define BREAK1FILTER_MASK ((uint32_t)0x00F00000U) /*!< TIMER berak1 filter mask */ +/*! + \brief deinit a TIMER (API_ID(0x0001U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER13: + /* reset TIMER13 */ + rcu_periph_reset_enable(RCU_TIMER13RST); + rcu_periph_reset_disable(RCU_TIMER13RST); + break; + case TIMER15: + /* reset TIMER15 */ + rcu_periph_reset_enable(RCU_TIMER15RST); + rcu_periph_reset_disable(RCU_TIMER15RST); + break; + case TIMER16: + /* reset TIMER16 */ + rcu_periph_reset_enable(RCU_TIMER16RST); + rcu_periph_reset_disable(RCU_TIMER16RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER init parameter struct with a default value (API_ID(0x0002U)) + \param[in] initpara: init parameter struct + \param[out] none + \retval none +*/ +void timer_struct_para_init(timer_parameter_struct *initpara) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(initpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x0002U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* 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 (API_ID(0x0003U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \param[in] initpara: init parameter struct + prescaler: prescaler value of the counter clock, 0~65535 + alignedmode: TIMER_COUNTER_EDGE, TIMER_COUNTER_CENTER_DOWN, TIMER_COUNTER_CENTER_UP, TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP, TIMER_COUNTER_DOWN + period: counter auto reload value, 0~65535 + clockdivision: TIMER_CKDIV_DIV1, TIMER_CKDIV_DIV2, TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value, 0~65535 + \param[out] none + \retval none +*/ +void gd32_timer_init(uint32_t timer_periph, timer_parameter_struct *initpara) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(initpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x0003U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER2 == timer_periph)) { + TIMER_CTL0(timer_periph) &= (~(uint32_t)(TIMER_CTL0_DIR | TIMER_CTL0_CAM)); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->alignedmode & ALIGNEDMODE_MASK); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->counterdirection & COUNTERDIRECTION_MASK); + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_CKDIV); + TIMER_CTL0(timer_periph) |= (uint32_t)((initpara->clockdivision) &CLOCKDIVISION_MASK); + + if((TIMER0 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == 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 (API_ID(0x0004U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0005U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0006U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0007U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0008U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0009U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x000AU)) + \param[in] timer_periph: TIMERx(x=0,2) + \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 & ALIGNEDMODE_MASK); +} + +/*! + \brief set TIMER counter up direction (API_ID(0x000BU)) + \param[in] timer_periph: TIMERx(x=0,2) + \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 (API_ID(0x000CU)) + \param[in] timer_periph: TIMERx(x=0,2) + \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 (API_ID(0x000DU)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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, uint32_t pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)prescaler; + + if(TIMER_PSC_RELOAD_NOW == pscreload) { + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value (API_ID(0x000EU)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \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 (API_ID(0x000FU)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \param[in] autoreload: the counter auto-reload value,0~65535 + \param[out] none + \retval none +*/ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload) +{ + TIMER_CAR(timer_periph) = (uint32_t)autoreload; +} + +/*! + \brief configure TIMER counter register value (API_ID(0x0010U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \param[in] counter: the counter value,0~65535 + \param[out] none + \retval none +*/ +void timer_counter_value_config(uint32_t timer_periph, uint16_t counter) +{ + TIMER_CNT(timer_periph) = (uint32_t)counter; +} + +/*! + \brief read TIMER counter value (API_ID(0x0011U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \param[out] none + \retval counter value +*/ +uint16_t timer_counter_read(uint32_t timer_periph) +{ + uint16_t count_value = 0U; + count_value = (uint16_t)(TIMER_CNT(timer_periph)); + return (count_value); +} + +/*! + \brief read TIMER prescaler value (API_ID(0x0012U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0013U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0014U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \param[in] update: + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATE_SRC_GLOBAL: update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger + \arg TIMER_UPDATE_SRC_REGULAR: update generate only by counter overflow/underflow + \param[out] none + \retval none +*/ +void timer_update_source_config(uint32_t timer_periph, uint32_t update) +{ + if(TIMER_UPDATE_SRC_REGULAR == update) { + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + } else if(TIMER_UPDATE_SRC_GLOBAL == update) { + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; + } else { + /* illegal parameters */ + } +} + +/*! + \brief enable the TIMER DMA (API_ID(0x0015U)) + \param[in] timer_periph: please refer to the following parameters + \param[in] dma: specify which DMA to enable + only one parameter can be selected which is shown as below: + \arg TIMER_DMA_UPD: update DMA ,TIMERx(x=0,2,15,16) + \arg TIMER_DMA_CH0D: channel 0 DMA request,TIMERx(x=0,2,15,16) + \arg TIMER_DMA_CH1D: channel 1 DMA request,TIMERx(x=0,2) + \arg TIMER_DMA_CH2D: channel 2 DMA request,TIMERx(x=0,2) + \arg TIMER_DMA_CH3D: channel 3 DMA request,TIMERx(x=0,2) + \arg TIMER_DMA_CMTD: commutation DMA request,TIMERx(x=0) + \arg TIMER_DMA_TRGD: trigger DMA request,TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= ((uint32_t) dma & 0X5F00U); +} + +/*! + \brief disable the TIMER DMA (API_ID(0x0016U)) + \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 are shown as below: + \arg TIMER_DMA_UPD: update DMA ,TIMERx(x=0,2,15,16) + \arg TIMER_DMA_CH0D: channel 0 DMA request,TIMERx(x=0,2,15,16) + \arg TIMER_DMA_CH1D: channel 1 DMA request,TIMERx(x=0,2) + \arg TIMER_DMA_CH2D: channel 2 DMA request,TIMERx(x=0,2) + \arg TIMER_DMA_CH3D: channel 3 DMA request,TIMERx(x=0,2) + \arg TIMER_DMA_CMTD: commutation DMA request,TIMERx(x=0) + \arg TIMER_DMA_TRGD: trigger DMA request,TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~((uint32_t)dma & 0X5F00U)); +} + +/*! + \brief channel DMA request source selection (API_ID(0x0017U)) + \param[in] timer_periph: TIMERx(x=0,2,15,16) + \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, uint32_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + } else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request) { + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure the TIMER DMA transfer (API_ID(0x0018U)) + \param[in] timer_periph: TIMERx(x=0,2,15,16) + \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 + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1 + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0 + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1 + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2 + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG + \arg TIMER_DMACFG_DMATA_DMATB: DMA transfer address is TIMER_DMATB + \param[in] dma_lenth: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..17): 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) +{ + uint32_t ctl; + ctl = TIMER_DMACFG(timer_periph); + ctl &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + ctl |= (uint32_t)((uint32_t)(dma_baseaddr & TIMER_DMACFG_DMATA) | (dma_lenth & TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) = ctl; +} + +/*! + \brief software generate events (API_ID(0x0019U)) + \param[in] timer_periph: please refer to the following parameters + \param[in] event: + one or more parameters can be selected which are shown as below: + \arg TIMER_EVENT_SRC_UPG: update event,TIMERx(x=0,2,13,15,16) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation,TIMERx(x=0,2,13,15,16) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation,TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation,TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation,TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation,TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation, TIMERx(x=0,15,16) + \arg TIMER_EVENT_SRC_BRK0G: BREAK0 event generation, TIMERx(x=0,15,16) + \arg TIMER_EVENT_SRC_BRK1G: BREAK1 event generation, TIMERx(x=0,15,16) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint32_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief initialize TIMER break parameter struct with a default value (API_ID(0x001AU)) + \param[in] breakpara: TIMER break parameter struct + \param[out] none + \retval none +*/ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(breakpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x001AU), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* initialize the break parameter struct member with the default value */ + breakpara->runoffstate = TIMER_ROS_STATE_DISABLE; + breakpara->ideloffstate = TIMER_IOS_STATE_DISABLE; + breakpara->deadtime = 0U; + breakpara->outputautostate = TIMER_OUTAUTO_DISABLE; + breakpara->protectmode = TIMER_CCHP_PROT_OFF; + breakpara->break0state = TIMER_BREAK0_DISABLE; + breakpara->break0filter = 0U; + breakpara->break0polarity = TIMER_BREAK0_POLARITY_LOW; + breakpara->break1state = TIMER_BREAK1_DISABLE; + breakpara->break1filter = 0U; + breakpara->break1polarity = TIMER_BREAK1_POLARITY_LOW; + } +} + +/*! + \brief configure TIMER break function (API_ID(0x001BU)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE,TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + outputautostate: TIMER_OUTAUTO_ENABLE,TIMER_OUTAUTO_DISABLE + protectmode: TIMER_CCHP_PROT_OFF,TIMER_CCHP_PROT_0,TIMER_CCHP_PROT_1,TIMER_CCHP_PROT_2 + break0state: TIMER_BREAK0_ENABLE, TIMER_BREAK0_DISABLE + break0filter: 0~15 + break0polarity: TIMER_BREAK0_POLARITY_LOW, TIMER_BREAK0_POLARITY_HIGH + break1state: TIMER_BREAK1_ENABLE, TIMER_BREAK1_DISABLE + break1filter: 0~15 + break1polarity: TIMER_BREAK1_POLARITY_LOW, TIMER_BREAK1_POLARITY_HIGH + \param[out] none + \retval none +*/ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(breakpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x001BU), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + if((TIMER0 == timer_periph) ) { + TIMER_CCHP(timer_periph) = ((((uint32_t)(breakpara->runoffstate) &TIMER_ROS_STATE_ENABLE))| + (((uint32_t)(breakpara->ideloffstate) &TIMER_IOS_STATE_ENABLE))| + (((uint32_t)(breakpara->deadtime)&DEADTIME_MASK))| + (((uint32_t)(breakpara->outputautostate) &TIMER_OUTAUTO_ENABLE))| + (((uint32_t)(breakpara->break0state) &TIMER_BREAK0_ENABLE)) | + (((uint32_t)(breakpara->break0filter << 16U)&BREAK0FILTER_MASK)) | + (((uint32_t)(breakpara->break0polarity) &TIMER_BREAK0_POLARITY_HIGH))| + (((uint32_t)(breakpara->break1state) &TIMER_BREAK1_ENABLE)) | + (((uint32_t)(breakpara->break1filter << 20U)&BREAK1FILTER_MASK)) | + (((uint32_t)(breakpara->break1polarity) & TIMER_BREAK1_POLARITY_HIGH))| + (((uint32_t)(breakpara->protectmode)&TIMER_CCHP_PROT_2))) ; + } else if((TIMER15 == timer_periph) || (TIMER16 == timer_periph)) { + TIMER_CCHP(timer_periph) = ((((uint32_t)(breakpara->runoffstate) &TIMER_ROS_STATE_ENABLE))| + (((uint32_t)(breakpara->ideloffstate) &TIMER_IOS_STATE_ENABLE))| + (((uint32_t)(breakpara->deadtime)&DEADTIME_MASK))| + (((uint32_t)(breakpara->outputautostate) &TIMER_OUTAUTO_ENABLE))| + (((uint32_t)(breakpara->break0state) &TIMER_BREAK0_ENABLE)) | + (((uint32_t)(breakpara->break0filter << 16U)&BREAK0FILTER_MASK)) | + (((uint32_t)(breakpara->break0polarity) &TIMER_BREAK0_POLARITY_HIGH))| + (((uint32_t)(breakpara->protectmode)&TIMER_CCHP_PROT_2))) ; + } else { + /* illegal parameters */ + } + } +} + +/*! + \brief enable TIMER break function (API_ID(0x001CU)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signals, TIMERx(x=0,15,16) + \arg TIMER_BREAK1: BREAK1 input signals, TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph, uint16_t break_num) +{ + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK0EN; + } else if(TIMER0 == timer_periph) { + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRK1EN; + } else { + /* illegal parameters */ + } +} + +/*! + \brief disable TIMER break function (API_ID(0x001DU)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signals, TIMERx(x=0,15,16) + \arg TIMER_BREAK1: BREAK1 input signals, TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph, uint16_t break_num) +{ + if(TIMER_BREAK0 == break_num) { + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRK0EN; + } else if(TIMER0 == timer_periph) { + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_BRK1EN); + } else { + /* illegal parameters */ + } +} + +/*! + \brief enable TIMER output automatic function (API_ID(0x001EU)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \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 (API_ID(0x001FU)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \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 (API_ID(0x0020U)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \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 (API_ID(0x0021U)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \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 (API_ID(0x0022U)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \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, uint32_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 (API_ID(0x0023U)) + \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) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(ocpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x0023U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* initialize the channel output parameter struct member with the default value */ + ocpara->outputstate = TIMER_CCX_DISABLE; + ocpara->outputnstate = TIMER_CCXN_DISABLE; + ocpara->ocpolarity = TIMER_OC_POLARITY_HIGH; + ocpara->ocnpolarity = TIMER_OCN_POLARITY_HIGH; + ocpara->ocidlestate = TIMER_OC_IDLE_STATE_LOW; + ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; + } +} + +/*! + \brief configure TIMER channel output function (API_ID(0x0024U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,2)) + \arg TIMER_CH_4: TIMER channel 4(TIMERx(x=0)) + \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) +{ + uint32_t ctl; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(ocpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x0024U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + 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 & TIMER_CCX_ENABLE); + /* set the CH0P bit */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH0P); + ctl |= ((uint32_t)ocpara->ocpolarity & TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) = ctl; + if((TIMER0 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == 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 & TIMER_CHCTL2_CH0NEN); + /* 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 & TIMER_CHCTL2_CH0NP); + /* 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 & TIMER_CTL1_ISO0); + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)(ocpara->ocnidlestate & TIMER_CTL1_ISO0N); + } + 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)ocpara->outputstate & TIMER_CCX_ENABLE) << 4U); + /* set the CH1P bit */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH1P); + ctl |= (uint32_t)(((uint32_t)ocpara->ocpolarity & TIMER_CHCTL2_CH0P) << 4U); + TIMER_CHCTL2(timer_periph) = ctl; + if(TIMER0 == 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 & TIMER_CHCTL2_CH0NEN) << 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 & TIMER_CHCTL2_CH0NP) << 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 & TIMER_CTL1_ISO0) << 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 & TIMER_CTL1_ISO0N) << 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)ocpara->outputstate & TIMER_CCX_ENABLE) << 8U); + /* set the CH2P bit */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH2P); + ctl |= (((uint32_t)ocpara->ocpolarity & TIMER_CHCTL2_CH0P) << 8U); + TIMER_CHCTL2(timer_periph) = ctl; + if(TIMER0 == 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 & TIMER_CHCTL2_CH0NEN) << 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 & TIMER_CHCTL2_CH0NP) << 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 & TIMER_CTL1_ISO0) << 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 & TIMER_CTL1_ISO0N) << 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)ocpara->outputstate & TIMER_CCX_ENABLE) << 12U); + /* set the CH3P bit */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH3P); + ctl |= (((uint32_t)ocpara->ocpolarity & TIMER_CHCTL2_CH0P) << 12U); + TIMER_CHCTL2(timer_periph) = ctl; + if(TIMER0 == 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 & TIMER_CTL1_ISO0) << 6U); + } + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + if(TIMER0 == timer_periph){ + /* reset the CH4EN bit */ + TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH4EN); + /* set the CH4EN bit */ + TIMER_CHCTL2(timer_periph) |= (((uint32_t)ocpara->outputstate & TIMER_CCX_ENABLE) << 16U); + /* set the CH4P bit */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH4P); + ctl |= (((uint32_t)ocpara->ocpolarity & TIMER_CHCTL2_CH0P) << 16U); + TIMER_CHCTL2(timer_periph) = ctl; + /* reset the ISO4 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO4); + /* set the ISO4 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate & TIMER_CTL1_ISO0) << 8U); + } + break; + default: + break; + } + } +} + +/*! + \brief configure TIMER channel output compare mode (API_ID(0x0025U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \arg TIMER_CH_4: TIMER channel4(TIMERx(x=0)) + \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(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_ACTIVE: active mode(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_INACTIVE: inactive mode(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_TOGGLE: toggle mode(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_LOW: force low mode(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_HIGH: force high mode(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_PWM0: PWM0 mode(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_PWM1: PWM1 mode(TIMERx(x=0,2,13,15,16)) + \arg TIMER_OC_MODE_DELAYABLE_SPM0 : Delayable SPM mode 0(TIMERx(x=0,2)) + \arg TIMER_OC_MODE_DELAYABLE_SPM1 : Delayable SPM mode 1(TIMERx(x=0,2)) + \arg TIMER_OC_MODE_COMBINED_PWM0 : Combined PWM mode 0(TIMERx(x=0,2)) + \arg TIMER_OC_MODE_COMBINED_PWM1 : Combined PWM mode 1(TIMERx(x=0,2)) + \arg TIMER_OC_MODE_ASYMMETRIC_PWM0 : Asymmetric PWM mode 0(TIMERx(x=0,2)) + \arg TIMER_OC_MODE_ASYMMETRIC_PWM1 : Asymmetric PWM mode 1(TIMERx(x=0,2)) + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint32_t ocmode) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); + ctl |= (uint32_t)(ocmode&TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL); + ctl |= (uint32_t)((uint32_t)(ocmode&TIMER_CHCTL0_CH0COMCTL) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + ctl |= (uint32_t)(ocmode&TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); + ctl |= (uint32_t)((uint32_t)(ocmode&TIMER_CHCTL1_CH2COMCTL) << 8U); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + ctl = TIMER_CHCTL3(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL3_CH4COMCTL); + ctl |= (uint32_t)(ocmode&TIMER_CHCTL3_CH4COMCTL); + TIMER_CHCTL3(timer_periph) = ctl; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output combine mode (API_ID(0x0026U)) + \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)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0)) + \param[in] state: channel combined_3_phase_pwm + only one parameter can be selected which is shown as below: + \arg TIMER_COMBINE_CHANNEL_DISABLE: channel combined 3 phase disable + \arg TIMER_COMBINE_CHANNEL_ENABLE: channel combined 3 phase enable + \param[out] none + \retval none +*/ +void timer_channel_combined_3_phase_pwm_config(uint32_t timer_periph, uint16_t channel, uint32_t state) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CH4CV(timer_periph); + ctl &= (~(uint32_t)TIMER_CH4CV_CCH4CH0); + ctl |= (uint32_t)((state & TIMER_COMBINE_CHANNEL_ENABLE) << 29U); + TIMER_CH4CV(timer_periph) = ctl; + break; + case TIMER_CH_1: + ctl = TIMER_CH4CV(timer_periph); + ctl &= (~(uint32_t)TIMER_CH4CV_CCH4CH1); + ctl |= (uint32_t)((state & TIMER_COMBINE_CHANNEL_ENABLE) << 30U); + TIMER_CH4CV(timer_periph) = ctl; + break; + case TIMER_CH_2: + ctl = TIMER_CH4CV(timer_periph); + ctl &= (~(uint32_t)TIMER_CH4CV_CCH4CH2); + ctl |= (uint32_t)((state & TIMER_COMBINE_CHANNEL_ENABLE) << 31U); + TIMER_CH4CV(timer_periph) = ctl; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value (API_ID(0x0027U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \arg TIMER_CH_4: TIMER channel4(TIMERx(x=0)) + \param[in] pulse: channel output pulse value + \param[out] none + \retval none +*/ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + TIMER_CH4CV(timer_periph) = (uint32_t)(pulse & 0xFFFFU); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function (API_ID(0x0028U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \arg TIMER_CH_4: TIMER channel3(TIMERx(x=0)) + \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) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); + ctl |= ((uint32_t)ocshadow & TIMER_OC_SHADOW_ENABLE); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN); + ctl |= (((uint32_t)ocshadow & TIMER_OC_SHADOW_ENABLE) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN); + ctl |= ((uint32_t)ocshadow & TIMER_OC_SHADOW_ENABLE); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN); + ctl |= (((uint32_t)ocshadow & TIMER_OC_SHADOW_ENABLE) << 8U); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + ctl = TIMER_CHCTL3(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL3_CH4COMSEN); + ctl |= ((uint32_t)ocshadow & TIMER_OC_SHADOW_ENABLE); + TIMER_CHCTL3(timer_periph) = ctl; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function (API_ID(0x0029U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \arg TIMER_CH_4: TIMER channel4(TIMERx(x=0)) + \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) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN); + ctl |= ((uint32_t)ocfast & TIMER_OC_FAST_ENABLE); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1COMFEN); + ctl |= (((uint32_t)ocfast & TIMER_OC_FAST_ENABLE) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN); + ctl |= ((uint32_t)ocfast & TIMER_OC_FAST_ENABLE); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH3COMFEN); + ctl |= (((uint32_t)ocfast & TIMER_OC_FAST_ENABLE) << 8U); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + ctl = TIMER_CHCTL3(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL3_CH4COMFEN); + ctl |= ((uint32_t)ocfast & TIMER_OC_FAST_ENABLE); + TIMER_CHCTL3(timer_periph) = ctl; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function (API_ID(0x002AU)) + \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,2) + \arg TIMER_CH_1: TIMER channel1 TIMERx(x=0,2) + \arg TIMER_CH_2: TIMER channel2 TIMERx(x=0,2) + \arg TIMER_CH_3: TIMER channel3 TIMERx(x=0,2) + \arg TIMER_CH_4: TIMER channel4 TIMERx(x=0) + \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) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); + ctl |= ((uint32_t)occlear & TIMER_OC_CLEAR_ENABLE); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN); + ctl |= (((uint32_t)occlear & TIMER_OC_CLEAR_ENABLE) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN); + ctl |= ((uint32_t)occlear & TIMER_OC_CLEAR_ENABLE); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN); + ctl |= (((uint32_t)occlear & TIMER_OC_CLEAR_ENABLE) << 8U); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + ctl = TIMER_CHCTL3(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL3_CH4COMCEN); + ctl |= ((uint32_t)occlear & TIMER_OC_CLEAR_ENABLE); + TIMER_CHCTL3(timer_periph) = ctl; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity (API_ID(0x002BU)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \arg TIMER_CH_4: TIMER channel4(TIMERx(x=0)) + \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) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH0P); + ctl |= ((uint32_t)ocpolarity & TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH1P); + ctl |= (((uint32_t)ocpolarity & TIMER_CHCTL2_CH0P) << 4U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH2P); + ctl |= (((uint32_t)ocpolarity & TIMER_CHCTL2_CH0P) << 8U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH3P); + ctl |= (((uint32_t)ocpolarity & TIMER_CHCTL2_CH0P) << 12U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH4P); + ctl |= (((uint32_t)ocpolarity & TIMER_CHCTL2_CH0P) << 16U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity (API_ID(0x002CU)) + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: channel to be configured + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0)) + \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 & TIMER_CHCTL2_CH0NP); + 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 & TIMER_CHCTL2_CH0NP) << 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 & TIMER_CHCTL2_CH0NP) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state (API_ID(0x002DU)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \arg TIMER_CH_4: TIMER channel4(TIMERx(x=0)) + \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) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + ctl |= (uint32_t)(state & TIMER_CHCTL2_CH0EN); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + ctl |= (uint32_t)((uint32_t)(state & TIMER_CHCTL2_CH0EN) << 4U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + ctl |= (uint32_t)((uint32_t)(state & TIMER_CHCTL2_CH0EN) << 8U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + ctl |= (uint32_t)((uint32_t)(state & TIMER_CHCTL2_CH0EN) << 12U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + /* configure TIMER_CH_4 */ + case TIMER_CH_4: + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL2_CH4EN); + ctl |= (uint32_t)((uint32_t)(state & TIMER_CHCTL2_CH0EN) << 16U); + TIMER_CHCTL2(timer_periph) = ctl; + break; + default: + break; + } +} + + +/*! + \brief configure TIMER channel complementary output enable state (API_ID(0x002EU)) + \param[in] timer_periph: TIMERx(x=0) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,15,16)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0)) + \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 & TIMER_CCXN_ENABLE); + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + TIMER_CHCTL2(timer_periph) |= (((uint32_t)ocnstate & TIMER_CCXN_ENABLE) << 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 & TIMER_CCXN_ENABLE) << 8U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER channel input parameter struct with a default value (API_ID(0x002FU)) + \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) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(icpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x002FU), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + /* 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 (API_ID(0x0030U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \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) +{ + uint32_t ctl; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(icpara)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x0030U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + 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 */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + ctl |= (((uint32_t)icpara->icpolarity) & TIMER_IC_POLARITY_BOTH_EDGE); + TIMER_CHCTL2(timer_periph) = ctl; + /* reset the CH0MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + ctl |= (uint32_t)((icpara->icselection) & TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) = ctl; + /* reset the CH0CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + ctl |= ((((uint32_t)icpara->icfilter) & 0XFU) << 4U); + TIMER_CHCTL0(timer_periph) = ctl; + /* 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 */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + ctl |= (((uint32_t)(icpara->icpolarity) & TIMER_IC_POLARITY_BOTH_EDGE) << 4U); + TIMER_CHCTL2(timer_periph) = ctl; + /* reset the CH1MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + ctl |= (uint32_t)((uint32_t)((icpara->icselection) & TIMER_CHCTL0_CH0MS) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + /* reset the CH1CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + ctl |= ((((uint32_t)icpara->icfilter) & 0XFU) << 12U); + TIMER_CHCTL0(timer_periph) = ctl; + /* 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 */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH2P | TIMER_CHCTL2_CH2NP)); + ctl |= ((((uint32_t)icpara->icpolarity) & TIMER_IC_POLARITY_BOTH_EDGE) << 8U); + TIMER_CHCTL2(timer_periph) = ctl; + /* reset the CH2MS bit */ + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + ctl |= (uint32_t)((uint32_t)((icpara->icselection) & TIMER_CHCTL0_CH0MS)); + TIMER_CHCTL1(timer_periph) = ctl; + /* reset the CH2CAPFLT bit */ + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + ctl |= ((((uint32_t)icpara->icfilter) & 0XFU) << 4U); + TIMER_CHCTL1(timer_periph) = ctl; + /* 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 and CH3NP bits */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH3P | TIMER_CHCTL2_CH3NP)); + ctl |= ((((uint32_t)icpara->icpolarity) & TIMER_IC_POLARITY_BOTH_EDGE) << 12U); + TIMER_CHCTL2(timer_periph) = ctl; + /* reset the CH3MS bit */ + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + ctl |= (uint32_t)((uint32_t)((icpara->icselection) & TIMER_CHCTL0_CH0MS) << 8U); + TIMER_CHCTL1(timer_periph) = ctl; + /* reset the CH3CAPFLT bit */ + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + ctl |= ((((uint32_t)icpara->icfilter) & 0XFU) << 12U); + TIMER_CHCTL1(timer_periph) = ctl; + /* 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 (API_ID(0x0031U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \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) +{ + uint32_t ctl; + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); + ctl |= ((uint32_t)prescaler & TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC); + ctl |= (((uint32_t)prescaler & TIMER_CHCTL0_CH0CAPPSC) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC); + ctl |= ((uint32_t)prescaler & TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL1(timer_periph) = ctl; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + ctl = TIMER_CHCTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC); + ctl |= (((uint32_t)prescaler & TIMER_CHCTL0_CH0CAPPSC) << 8U); + TIMER_CHCTL1(timer_periph) = ctl; + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value (API_ID(0x0032U)) + \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,2,13,15,16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[out] none + \retval channel capture compare register value +*/ +uint16_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint16_t count_value = 0U; + switch(channel) { + /* read TIMER channel 0 capture compare register value */ + case TIMER_CH_0: + count_value = (uint16_t)TIMER_CH0CV(timer_periph); + break; + /* read TIMER channel 1 capture compare register value */ + case TIMER_CH_1: + count_value = (uint16_t)TIMER_CH1CV(timer_periph); + break; + /* read TIMER channel 2 capture compare register value */ + case TIMER_CH_2: + count_value = (uint16_t)TIMER_CH2CV(timer_periph); + break; + /* read TIMER channel 3 capture compare register value */ + case TIMER_CH_3: + count_value = (uint16_t)TIMER_CH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function (API_ID(0x0033U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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) +{ + uint32_t ctl; +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_VALID_POINTER(icpwm)) { + fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x0033U), ERR_PARAM_POINTER); + } else +#endif /* FW_DEBUG_ERR_REPORT */ + { + uint16_t icpolarity; + uint16_t icselection; + + /* 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); + /* set the CH0P and CH0NP bits */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + ctl |= (((uint32_t)icpwm->icpolarity) & TIMER_IC_POLARITY_BOTH_EDGE); + TIMER_CHCTL2(timer_periph) = ctl; + /* set the CH0MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + ctl |= (uint32_t)((icpwm->icselection) & TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) = ctl; + /* set the CH0CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + ctl |= ((((uint32_t)icpwm->icfilter) & 0xFU) << 4U); + TIMER_CHCTL0(timer_periph) = ctl; + /* 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) & TIMER_IC_PSC_DIV8)); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* set the CH1P and CH1NP bits */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + ctl |= (((uint32_t)icpolarity & TIMER_IC_POLARITY_BOTH_EDGE) << 4U); + TIMER_CHCTL2(timer_periph) = ctl; + + /* set the CH1MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + ctl |= (((uint32_t)icselection & TIMER_CHCTL0_CH0MS) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + + /* set the CH1CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + ctl |= ((((uint32_t)icpwm->icfilter) & 0xFU) << 12U); + TIMER_CHCTL0(timer_periph) = ctl; + + /* 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) & TIMER_IC_PSC_DIV8)); + } else { + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* set the CH1P and CH1NP bits */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + ctl |= ((((uint32_t)icpwm->icpolarity) & TIMER_IC_POLARITY_BOTH_EDGE) << 4U); + TIMER_CHCTL2(timer_periph) = ctl; + /* set the CH1MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + ctl |= ((((uint32_t)icpwm->icselection) &TIMER_CHCTL0_CH0MS) << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + /* set the CH1CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + ctl |= ((((uint32_t)icpwm->icfilter) & 0xFU) << 12U); + TIMER_CHCTL0(timer_periph) = ctl; + /* 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)& TIMER_IC_PSC_DIV8)); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* set the CH0P and CH0NP bits */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + ctl |= ((uint32_t)icpolarity & TIMER_IC_POLARITY_BOTH_EDGE); + TIMER_CHCTL2(timer_periph) = ctl; + /* set the CH0MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + ctl |= ((uint32_t)icselection & TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) = ctl; + /* set the CH0CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + ctl |= ((((uint32_t)icpwm->icfilter) & 0xFU) << 4U); + TIMER_CHCTL0(timer_periph) = ctl; + /* 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) & TIMER_IC_PSC_DIV8)); + } + } +} + +/*! + \brief configure TIMER hall sensor mode (API_ID(0x0034U)) + \param[in] timer_periph: TIMERx(x=0,2) + \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 { + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S; + } +} + +/*! + \brief select TIMER input trigger source (API_ID(0x0035U)) + \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_NONE: internal trigger disable + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0 + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2 + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3 + \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 + \arg TIMER_SMCFG_TRGSEL_ETIFP: external trigger + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger) +{ + uint32_t TIMERxCFG_temp0 = 0U,TIMERxCFG_temp1 = 0U; + volatile uint32_t *TIMERxCFG_addr0, *TIMERxCFG_addr1; + uint8_t i = 0U; + switch(timer_periph){ + case TIMER0: + TIMERxCFG_addr0 = &SYSCFG_TIMER0CFG0; + TIMERxCFG_addr1 = &SYSCFG_TIMER0CFG1; + break; + case TIMER2: + TIMERxCFG_addr0 = &SYSCFG_TIMER2CFG0; + TIMERxCFG_addr1 = &SYSCFG_TIMER2CFG1; + break; + default: + break; + } + TIMERxCFG_temp0 = REG32(TIMERxCFG_addr0); + TIMERxCFG_temp1 = REG32(TIMERxCFG_addr1); + if((TIMERxCFG_temp0 & 0xFFFFFFFFU) == 0U){ + TIMERxCFG_temp1 = (BITS(0,2) & intrigger); + REG32(TIMERxCFG_addr1) = TIMERxCFG_temp1; + }else{ + for(i = 0U; i < 8U; i++){ + if((TIMERxCFG_temp0 & (BITS(0,3) << (i * 4U))) != 0U){ + break; + } + } + TIMERxCFG_temp0 = ((BITS(0,3) << (i * 4U)) & ((uint32_t)(intrigger) << (i * 4U))); + REG32(TIMERxCFG_addr0) = TIMERxCFG_temp0; + } +} + +/*! + \brief select TIMER master mode output trigger source (API_ID(0x0036U)) + \param[in] timer_periph: please refer to the following parameters + \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,2)) + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output (TIMERx(x=0,2)) + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output (TIMERx(x=0,2)) + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channal0 as trigger output TRGO (TIMERx(x=0,2)) + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output (TIMERx(x=0,2)) + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output (TIMERx(x=0,2)) + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output (TIMERx(x=0,2)) + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output (TIMERx(x=0,2)) + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outtrigger) +{ + uint32_t ctl; + ctl = TIMER_CTL1(timer_periph); + ctl &= (~(uint32_t)TIMER_CTL1_MMC); + ctl |= (uint32_t)(outtrigger & TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) = ctl; +} + +/*! + \brief select TIMER slave mode (API_ID(0x0037U)) + \param[in] timer_periph: please refer to the following parameters + \param[in] slavemode: + only one parameter can be selected which is shown as below: + \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable + \arg TIMER_QUAD_DECODER_MODE0: quadrature decoder mode 0 (TIMERx(x=0,2)) + \arg TIMER_QUAD_DECODER_MODE1: quadrature decoder mode 1 (TIMERx(x=0,2)) + \arg TIMER_QUAD_DECODER_MODE2: quadrature decoder mode 2 (TIMERx(x=0,2)) + \arg TIMER_SLAVE_MODE_RESTART: restart mode (TIMERx(x=0,2,13,15,16)) + \arg TIMER_SLAVE_MODE_PAUSE: pause mode (TIMERx(x=0,2,13,15,16)) + \arg TIMER_SLAVE_MODE_EVENT: event mode (TIMERx(x=0,2,13,15,16)) + \arg TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0 (TIMERx(x=0,2,13,15,16)) + \arg TIMER_SLAVE_MODE_RESTART_EVENT: restart + event mode (TIMERx(x=0,2,13,15,16)) + \param[out] none + \retval none +*/ + +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) +{ + uint32_t TIMERxCFG_temp0 = 0U,TIMERxCFG_temp1 = 0U; + volatile uint32_t *TIMERxCFG_addr0, *TIMERxCFG_addr1; + uint32_t trigger_temp = 0U; + uint8_t i = 0U; + switch(timer_periph){ + case TIMER0: + TIMERxCFG_addr0 = &SYSCFG_TIMER0CFG0; + TIMERxCFG_addr1 = &SYSCFG_TIMER0CFG1; + break; + case TIMER2: + TIMERxCFG_addr0 = &SYSCFG_TIMER2CFG0; + TIMERxCFG_addr1 = &SYSCFG_TIMER2CFG1; + break; + default: + break; + } + TIMERxCFG_temp0 = REG32(TIMERxCFG_addr0); + TIMERxCFG_temp1 = REG32(TIMERxCFG_addr1); + if((((TIMERxCFG_temp0 & 0xFFFFFFFFU) == 0U)&&(((TIMERxCFG_temp1 & 0xFFFFFFFFU)) == 0U))){ + if(slavemode == TIMER_SLAVE_MODE_DISABLE){ + REG32(TIMERxCFG_addr1) = BITS(0,2); + }else{ + REG32(TIMERxCFG_addr0) = 0x7U << (slavemode * 4U); + } + }else if((TIMERxCFG_temp0 & 0xFFFFFFFFU) == 0U){ + if(slavemode != TIMER_SLAVE_MODE_DISABLE){ + trigger_temp = (TIMERxCFG_temp1 & BITS(0,2)); + TIMERxCFG_temp0 = trigger_temp << (slavemode * 4U); + REG32(TIMERxCFG_addr0) = TIMERxCFG_temp0; + REG32(TIMERxCFG_addr1) = 0U; + } + }else{ + for(i = 0U; i < 8U; i++){ + if((TIMERxCFG_temp0 & (BITS(0,2) << (i * 4U))) != 0U){ + trigger_temp = (TIMERxCFG_temp0 & (BITS(0,2) << (i * 4U))) >> (i * 4U); + break; + } + } + if(slavemode != TIMER_SLAVE_MODE_DISABLE){ + TIMERxCFG_temp0 = trigger_temp << (slavemode * 4U); + REG32(TIMERxCFG_addr0) = TIMERxCFG_temp0; + REG32(TIMERxCFG_addr1) = 0U; + }else{ + TIMERxCFG_temp1 = trigger_temp; + REG32(TIMERxCFG_addr0) = 0U; + REG32(TIMERxCFG_addr1) = TIMERxCFG_temp1; + } + } +} + +/*! + \brief configure TIMER master slave mode (API_ID(0x0038U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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 (API_ID(0x0039U)) + \param[in] timer_periph: TIMERx(x=0,2) + \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) +{ + uint32_t ctl; + ctl = TIMER_SMCFG(timer_periph); + ctl &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC)); + ctl |= (uint32_t)((extprescaler & TIMER_EXT_TRI_PSC_DIV8) | (extpolarity & TIMER_ETP_FALLING)); + ctl |= (((uint32_t)extfilter & 0xFU) << 8U); + TIMER_SMCFG(timer_periph) = ctl; +} + +/*! + \brief configure TIMER quadrature decoder mode (API_ID(0x003AU)) + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] decomode: + only one parameter can be selected which is shown as below: + \arg TIMER_QUAD_DECODER_MODE0: quadrature decoder mode 0 + \arg TIMER_QUAD_DECODER_MODE1: quadrature decoder mode 1 + \arg TIMER_QUAD_DECODER_MODE2: quadrature decoder mode 2 + \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 + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both 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 + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity) +{ + uint32_t ctl; + /* configure the quadrature decoder mode */ + timer_slave_mode_select(timer_periph, decomode); + /* configure input capture selection */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS)) & ((~(uint32_t)TIMER_CHCTL0_CH1MS))); + ctl |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI | ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + TIMER_CHCTL0(timer_periph) = ctl; + /* configure channel input capture polarity */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + ctl |= (((uint32_t)ic0polarity & TIMER_IC_POLARITY_BOTH_EDGE) | (((uint32_t)ic1polarity &TIMER_IC_POLARITY_BOTH_EDGE) << 4U)); + TIMER_CHCTL2(timer_periph) = ctl; +} + +/*! + \brief configure TIMER internal clock mode (API_ID(0x003BU)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_DISABLE); +} + +/*! + \brief configure TIMER the internal trigger as external clock input(API_ID(0x003CU)) + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] intrigger: trigger selection + 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) +{ + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, intrigger); + /* select TIMER slave mode */ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_EXTERNAL0); +} + +/*! + \brief configure TIMER the external trigger as external clock input(API_ID(0x003DU)) + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] extrigger: external trigger selection + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \param[in] extpolarity: external trigger polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: active high or rising edge active + \arg TIMER_IC_POLARITY_FALLING: active low or falling edge active + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter) +{ + uint32_t ctl; + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger) { + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* set the CH1NP bit */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + ctl |= (((uint32_t)extpolarity & TIMER_IC_POLARITY_BOTH_EDGE) << 4U); + TIMER_CHCTL2(timer_periph) = ctl; + /* set the CH1MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + ctl |= ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + TIMER_CHCTL0(timer_periph) = ctl; + /* set the CH1CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + ctl |= (((uint32_t)extfilter &0xFU) << 12U); + TIMER_CHCTL0(timer_periph) = ctl; + /* 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); + /* set the CH0P and CH0NP bits */ + ctl = TIMER_CHCTL2(timer_periph); + ctl &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + ctl |= ((uint32_t)extpolarity & TIMER_IC_POLARITY_BOTH_EDGE); + TIMER_CHCTL2(timer_periph) = ctl; + /* set the CH0MS bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + ctl |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI; + TIMER_CHCTL0(timer_periph) = ctl; + /* reset the CH0CAPFLT bit */ + ctl = TIMER_CHCTL0(timer_periph); + ctl &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + ctl |= (((uint32_t)extfilter &0xFU) << 4U); + TIMER_CHCTL0(timer_periph) = ctl; + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + } + /* select TIMER slave mode */ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_EXTERNAL0); + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, extrigger); +} + +/*! + \brief configure TIMER the external clock mode0 (API_ID(0x003EU)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \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, ((uint32_t)extprescaler & TIMER_EXT_TRI_PSC_DIV8), ((uint32_t)extpolarity & TIMER_ETP_FALLING), ((uint32_t)extfilter & 0xFU)); + /* select TIMER slave mode */ + timer_slave_mode_select(timer_periph, TIMER_SLAVE_MODE_EXTERNAL0); + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 (API_ID(0x003FU)) + \param[in] timer_periph: TIMERx(x=0,2) + \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, ((uint32_t)extprescaler & TIMER_EXT_TRI_PSC_DIV8), ((uint32_t)extpolarity & TIMER_ETP_FALLING), (extfilter & 0xFU)); + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 (API_ID(0x0040U)) + \param[in] timer_periph: TIMERx(x=0,2) + \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 input selection (API_ID(0x0041U)) + \param[in] timer_periph: TIMERx(x=0,13,15,16) + \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] insel: + only one parameter can be selected which is shown as below: + \arg TIMER_INSEL_CHx: connect to CH0 + \arg TIMER_INSEL_CMPx: connect to CMP1 + \param[out] none + \retval none +*/ +void timer_input_selection_config(uint32_t timer_periph, uint16_t channel, uint16_t insel) +{ + if(TIMER_CH_0 == channel) { + TIMER_INSEL(timer_periph) &= ~(uint32_t)TIMER_INSEL_CI0_SEL; + TIMER_INSEL(timer_periph) |= (uint32_t) (insel & TIMER_INSEL_CI0_SEL); + }else{ + TIMER_INSEL(timer_periph) &= ~(uint32_t)TIMER_INSEL_CI1_SEL; + TIMER_INSEL(timer_periph) |= (uint32_t) ((uint32_t)(insel & TIMER_INSEL_CI1_SEL) << 8U); + } +} +/*! + \brief configure TIMER write CHxVAL register selection (API_ID(0x0042U)) + \param[in] timer_periph: TIMERx(x=0,2,13,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 (API_ID(0x0043U)) + \param[in] timer_periph: TIMERx(x=0,2,13,15,16) + \param[in] outsel: + only one parameter can be selected which is shown as below: + \arg TIMER_OUTSEL_DISABLE: no effect + \arg TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel) +{ + if(TIMER_OUTSEL_ENABLE == outsel) { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL; + } else if(TIMER_OUTSEL_DISABLE == outsel) { + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure the TIMER break source (API_ID(0x0044U)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signal, TIMERx(x=0,15,16) + \arg TIMER_BREAK1: BREAK1 input signal, TIMERx(x=0) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_break_external_source_config(uint32_t timer_periph, uint16_t break_num, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + if(TIMER_BREAK0 == break_num) { + TIMER_AFCTL0(timer_periph) |= TIMER_AFCTL0_BRK0INEN; + } else if(TIMER_BREAK1 == break_num) { + TIMER_AFCTL1(timer_periph) |= TIMER_AFCTL1_BRK1INEN; + } else { + /* illegal parameters */ + } + } else { + if(TIMER_BREAK0 == break_num) { + TIMER_AFCTL0(timer_periph) &= (~TIMER_AFCTL0_BRK0INEN); + } else if(TIMER_BREAK1 == break_num) { + TIMER_AFCTL1(timer_periph) &= (~TIMER_AFCTL1_BRK1INEN); + } else { + /* illegal parameters */ + } + } +} + +/*! + \brief configure TIMER break polarity (API_ID(0x0045U)) + \param[in] timer_periph: TIMERx(x=0,15,16) + \param[in] break_num: TIMER BREAKx + only one parameter can be selected which is shown as below: + \arg TIMER_BREAK0: BREAK0 input signal, TIMERx(x=0,15,16) + \arg TIMER_BREAK1: BREAK1 input signal, TIMERx(x=0) + \param[in] bkinpolarity: break polarity + only one parameter can be selected which is shown as below: + TIMER_BRKIN_POLARITY_LOW: input signal will not be inverted + TIMER_BRKIN_POLARITY_HIGH: input signal will be inverted + \param[out] none + \retval none +*/ +void timer_break_external_polarity_config(uint32_t timer_periph, uint16_t break_num, uint16_t bkinpolarity) +{ + if(TIMER_BREAK0 == break_num) { + TIMER_AFCTL0(timer_periph) &= (~(uint32_t)TIMER_AFCTL0_BRK0INP); + TIMER_AFCTL0(timer_periph) |= (((uint32_t)bkinpolarity &TIMER_BRKIN_POLARITY_HIGH) << 9U); + }else{ + TIMER_AFCTL1(timer_periph) &= (~(uint32_t)TIMER_AFCTL1_BRK1INP); + TIMER_AFCTL1(timer_periph) |= (((uint32_t)bkinpolarity &TIMER_BRKIN_POLARITY_HIGH) << 9U); + } +} + + +/*! + \brief configure TIMER eti source (API_ID(0x0046U)) + \param[in] timer_periph: TIMERx(x=0) + \param[in] eti_source: eti source select + only one parameter can be selected which is shown as below: + \arg TIMER_ETI_LEGACY_MODE : input signal, TIMERx(x=0) + \arg TIMER_ETI_ADC_WD0_OUT input signal, TIMERx(x=0) + \arg TIMER_ETI_ADC_WD1_OUT input signal, TIMERx(x=0) + \arg TIMER_ETI_ADC_WD2_OUT input signal, TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_eti_source_selection_config(uint32_t timer_periph, uint32_t eti_source) +{ + TIMER_AFCTL0(timer_periph) &= (~(uint32_t)TIMER_AFCTL0_ETISEL); + TIMER_AFCTL0(timer_periph) |= ((uint32_t)eti_source &TIMER_AFCTL0_ETISEL); +} + +/*! + \brief get TIMER flags (API_ID(0x0047U)) + \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,2,13,15,16) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0,2) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0,2) + \arg TIMER_FLAG_CH4: channel 3 flag,TIMERx(x=0) + \arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,2) + \arg TIMER_FLAG_BRK0: BREAK0 flag, TIMERx(x=0,15,16) + \arg TIMER_FLAG_BRK1: BREAK1 flag, TIMERx(x=0) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag,TIMERx(x=0,2) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag,TIMERx(x=0,2) + \arg TIMER_FLAG_SYSB: channel 3 system source break,TIMERx(x=0) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + FlagStatus timer_flag = RESET; + if((uint32_t)RESET != (TIMER_INTF(timer_periph) & flag)) { + timer_flag = SET; + } else { + timer_flag = RESET; + } + return timer_flag; +} + +/*! + \brief clear TIMER flags (API_ID(0x0048U)) + \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,2,13,15,16) + \arg TIMER_FLAG_CH0: channel 0 flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH1: channel 1 flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH2: channel 2 flag,TIMERx(x=0,2) + \arg TIMER_FLAG_CH3: channel 3 flag,TIMERx(x=0,2) + \arg TIMER_FLAG_TRG: trigger flag,TIMERx(x=0,2) + \arg TIMER_FLAG_BRK0: BREAK0 flag, TIMERx(x=0,15,16) + \arg TIMER_FLAG_BRK1: BREAK1 flag, TIMERx(x=0) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag,TIMERx(x=0,2) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag,TIMERx(x=0,2) + \arg TIMER_FLAG_SYSB: channel 3 system source break,TIMERx(x=0) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)flag); +} + +/*! + \brief enable the TIMER interrupt (API_ID(0x0049U)) + \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,2,3,6,8,11) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CH3: channel 3 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,15,16) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,15,16) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) (interrupt & 0xFFU); +} + +/*! + \brief disable the TIMER interrupt (API_ID(0x0050U)) + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: timer interrupt source disable + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0,2,3,6,8,11) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CH3: channel 3 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,15,16) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,15,16) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(interrupt & 0xFFU)); +} + +/*! + \brief get timer interrupt flag (API_ID(0x0051U)) + \param[in] timer_periph: please refer to the following parameters + \param[in] int_flag: the timer interrupt flag + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CMT: trigger interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_BRK0: trigger interrupt flag,TIMERx(x=0,15,16) + \arg TIMER_INT_FLAG_BRK1: trigger interrupt flag,TIMERx(x=0) + \arg TIMER_INT_FLAG_SYSB: trigger interrupt flag,TIMERx(x=0,15,16) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t int_flag) +{ + FlagStatus timer_interrupt_flag = RESET; + uint32_t val; + if( int_flag != TIMER_INT_FLAG_BRK1 ) { + val = (TIMER_DMAINTEN(timer_periph) & int_flag); + } + else { + val = (TIMER_DMAINTEN(timer_periph) & TIMER_DMAINTEN_BRKIE ); + } + if(((uint32_t)RESET != (TIMER_INTF(timer_periph) & int_flag)) && ((uint32_t)RESET != val)) { + timer_interrupt_flag = SET; + } else { + timer_interrupt_flag = RESET; + } + return timer_interrupt_flag; +} + +/*! + \brief get timer interrupt flag (API_ID(0x0052U)) + \param[in] timer_periph: please refer to the following parameters + \param[in] int_flag: the timer interrupt flag + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0,2,13,15,16) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CMT: trigger interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_BRK0: trigger interrupt flag,TIMERx(x=0,15,16) + \arg TIMER_INT_FLAG_BRK1: trigger interrupt flag,TIMERx(x=0) + \arg TIMER_INT_FLAG_SYSB: trigger interrupt flag,TIMERx(x=0,15,16) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t int_flag) +{ + TIMER_INTF(timer_periph) = (~(uint32_t)int_flag); +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_usart.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_usart.c new file mode 100644 index 0000000..e23ac4a --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_usart.c @@ -0,0 +1,1354 @@ +/*! + \file gd32c2x1_usart.c + \brief USART driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_usart.h" + +#define USART_CMD_MASK ((uint32_t)0x0000001FU) /* bit mask of USART command */ + +#define USART_STB_OFFSET ((uint8_t)0x0CU) /* bit offset of USART stop bits */ +#define USART_GP_GUAT_OFFSET ((uint8_t)0x08U) /* bit offset of USART guard time bits */ +#define USART_CTL1_ADDR_OFFSET ((uint8_t)0x18U) /* bit offset of USART terminal address bits */ +#define USART_CTL2_SCRTNUM_OFFSET ((uint8_t)0x11U) /* bit offset of USART smartcard auto-retry number bits */ +#define USART_RT_BL_OFFSET ((uint8_t)0x18U) /* bit offset of USART block length bits */ +#define USART_CTL0_DEA_OFFSET ((uint8_t)0x15U) /* bit offset of USART driver enable assertion time bits */ +#define USART_CTL0_DED_OFFSET ((uint8_t)0x10U) /* bit offset of USART driver enable deassertion time bits */ + +/*! + \brief reset USART (API ID: 0x0001U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph) { + case USART0: + /* reset USART0 */ + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + /* reset USART1 */ + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + case USART2: + /* reset USART2 */ + rcu_periph_reset_enable(RCU_USART2RST); + rcu_periph_reset_disable(RCU_USART2RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value (API_ID: 0x0002U) + \param[in] usart_periph: USARTx(x=0,1,2) + \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; + uint32_t intdiv, fradiv, udiv; + +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_USART_BAUDRATE(baudval)) { + fw_debug_report_err(USART_MODULE_ID, API_ID(0x0002U), ERR_PARAM_OUT_OF_RANGE); + } else +#endif + { + switch(usart_periph) { + /* get clock frequency */ + case USART0: + /* get USART0 clock */ + uclk = rcu_clock_freq_get(CK_USART0); + break; + case USART1: + /* get USART1 clock */ + uclk = rcu_clock_freq_get(CK_APB); + break; + case USART2: + /* get USART2 clock */ + uclk = rcu_clock_freq_get(CK_APB); + break; + default: + break; + } + if(USART_CTL0_OVSMOD == (USART_CTL0(usart_periph) & USART_CTL0_OVSMOD)) { + /* oversampling by 8, configure the value of USART_BAUD */ + udiv = ((2U * uclk) + baudval / 2U) / baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = (udiv >> 1U) & 0x00000007U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } else { + /* oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk + baudval / 2U) / baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = udiv & 0x0000000fU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } + } +} + +/*! + \brief configure USART parity (API_ID: 0x0003U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] paritycfg: USART parity configure + only one parameter can be selected which is shown as below: + \arg USART_PM_NONE: no parity + \arg USART_PM_ODD: odd parity + \arg USART_PM_EVEN: even parity + \param[out] none + \retval none +*/ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 PM,PCEN bits */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); + /* configure USART parity mode */ + USART_CTL0(usart_periph) |= paritycfg & (USART_CTL0_PM | USART_CTL0_PCEN); +} + +/*! + \brief configure USART word length (API_ID: 0x0004U) + \param[in] usart_periph: USARTx(x=0,1,2) + \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) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 WL bit */ + USART_CTL0(usart_periph) &= ~USART_CTL0_WL; + /* configure USART word length */ + USART_CTL0(usart_periph) |= wlen & USART_CTL0_WL; +} + +/*! + \brief configure USART stop bit length (API_ID: 0x0005U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] stblen: USART stop bit configure + only one parameter can be selected which is shown as below: + \arg USART_STB_1BIT: 1 bit + \arg USART_STB_0_5BIT: 0.5bit + \arg USART_STB_2BIT: 2 bits + \arg USART_STB_1_5BIT: 1.5bit + \param[out] none + \retval none +*/ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL1 STB bits */ + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + USART_CTL1(usart_periph) |= (stblen << USART_STB_OFFSET) & USART_CTL1_STB; +} + +/*! + \brief enable USART (API_ID: 0x0006U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UEN; +} + +/*! + \brief disable USART (API_ID: 0x0007U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); +} + +/*! + \brief configure USART transmitter (API_ID: 0x0008U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] txconfig: enable or disable USART transmitter + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_ENABLE: enable USART transmission + \arg USART_TRANSMIT_DISABLE: enable USART transmission + \param[out] none + \retval none +*/ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_TEN; + /* configure transfer mode */ + USART_CTL0(usart_periph) |= txconfig & USART_CTL0_TEN; +} + +/*! + \brief configure USART receiver (API_ID: 0x0009U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] rxconfig: enable or disable USART receiver + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_ENABLE: enable USART reception + \arg USART_RECEIVE_DISABLE: disable USART reception + \param[out] none + \retval none +*/ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_REN; + /* configure receiver mode */ + USART_CTL0(usart_periph) |= rxconfig & USART_CTL0_REN; +} + +/*! + \brief data is transmitted/received with the LSB/MSB first (API_ID: 0x000AU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] msbf: LSB/MSB + only one parameter can be selected which is shown as below: + \arg USART_MSBF_LSB: LSB first + \arg USART_MSBF_MSB: MSB first + \param[out] none + \retval none +*/ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* configure LSB or MSB first */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_MSBF); + USART_CTL1(usart_periph) |= (USART_CTL1_MSBF & msbf); +} + +/*! + \brief configure USART inverted (API_ID: 0x000BU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] invertpara: refer to usart_invert_enum + only one parameter can be selected which is shown as below: + \arg USART_DINV_ENABLE: data bit level inversion + \arg USART_DINV_DISABLE: data bit level not inversion + \arg USART_TXPIN_ENABLE: TX pin level inversion + \arg USART_TXPIN_DISABLE: TX pin level not inversion + \arg USART_RXPIN_ENABLE: RX pin level inversion + \arg USART_RXPIN_DISABLE: RX pin level not inversion + \arg USART_SWAP_ENABLE: swap TX/RX pins + \arg USART_SWAP_DISABLE: not swap TX/RX pins + \param[out] none + \retval none +*/ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* inverted or not the specified signal */ + switch(invertpara) { + case USART_DINV_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_DINV; + break; + case USART_DINV_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_DINV); + break; + case USART_TXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_TINV; + break; + case USART_TXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_TINV); + break; + case USART_RXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_RINV; + break; + case USART_RXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_RINV); + break; + case USART_SWAP_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_STRP; + break; + case USART_SWAP_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_STRP); + break; + default: + break; + } +} + +/*! + \brief enable the USART overrun function (API_ID: 0x000CU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_overrun_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* enable overrun function */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_OVRD); +} + +/*! + \brief disable the USART overrun function (API_ID: 0x000DU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_overrun_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* disable overrun function */ + USART_CTL2(usart_periph) |= USART_CTL2_OVRD; +} + +/*! + \brief configure the USART oversample mode (API_ID: 0x000EU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] oversamp: oversample value + only one parameter can be selected which is shown as below: + \arg USART_OVSMOD_8: oversampling by 8 + \arg USART_OVSMOD_16: oversampling by 16 + \param[out] none + \retval none +*/ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear OVSMOD bit */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD); + USART_CTL0(usart_periph) |= oversamp & USART_CTL0_OVSMOD; +} + +/*! + \brief configure the sample bit method (API_ID: 0x000FU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] osb: sample bit + only one parameter can be selected which is shown as below: + \arg USART_OSB_1BIT: 1 bit + \arg USART_OSB_3BIT: 3 bits + \param[out] none + \retval none +*/ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); + USART_CTL2(usart_periph) |= osb & USART_CTL2_OSB; +} + +/*! + \brief enable receiver timeout (API_ID: 0x0010U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_RTEN; +} + +/*! + \brief disable receiver timeout (API_ID: 0x0011U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN); + +} + +/*! + \brief configure receiver timeout threshold (API_ID: 0x0012U) + \param[in] usart_periph: USARTx(x=0) + \param[in] rtimeout: 0x00000000-0x00FFFFFF, receiver timeout value in terms of number of baud clocks + \param[out] none + \retval none +*/ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout) +{ +#ifdef FW_DEBUG_ERR_REPORT + if(NOT_USART_RECEIVE_TIMEOUT(rtimeout)) { + fw_debug_report_err(USART_MODULE_ID, API_ID(0x0012U), ERR_PARAM_OUT_OF_RANGE); + } else +#endif + { + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= rtimeout & USART_RT_RT; + } +} + +/*! + \brief USART transmit data function (API_ID: 0x0013U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint16_t data) +{ + USART_TDATA(usart_periph) = (USART_TDATA_TDATA & (uint32_t)data); +} + +/*! + \brief USART receive data function (API_ID: 0x0014U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval data of received +*/ +uint16_t usart_data_receive(uint32_t usart_periph) +{ + uint16_t data = 0U; + + data = (uint16_t)(GET_BITS(USART_RDATA(usart_periph), 0U, 8U)); + return data; +} + +/*! + \brief enable USART command (API_ID: 0x0015U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] cmdtype: command type + one or more parameter can be selected which is shown as below: + \arg USART_CMD_ABDCMD: auto baudrate detection command, only for USART0 + \arg USART_CMD_SBKCMD: send break command, only for USART0 + \arg USART_CMD_MMCMD: mute mode command + \arg USART_CMD_RXFCMD: receive data flush command + \arg USART_CMD_TXFCMD: transmit data flush request(only support usart0) + \param[out] none + \retval none +*/ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype) +{ + USART_CMD(usart_periph) |= (cmdtype & USART_CMD_MASK); +} + +/*! + \brief enable auto baud rate detection (API_ID: 0x0016U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_ABDEN; +} + +/*! + \brief disable auto baud rate detection (API_ID: 0x0017U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDEN); +} + +/*! + \brief configure auto baud rate detection mode (API_ID: 0x0018U) + \param[in] usart_periph: USARTx(x=0) + \param[in] abdmod: auto baud rate detection mode + only one parameter can be selected which is shown as below: + \arg USART_ABDM_FTOR: falling edge to rising edge measurement + \arg USART_ABDM_FTOF: falling edge to falling edge measurement + \param[out] none + \retval none +*/ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod) +{ + /* reset ABDM bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDM); + USART_CTL1(usart_periph) |= abdmod & USART_CTL1_ABDM; +} + +/*! + \brief configure address of the USART (API_ID: 0x0019U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] addr: 0x00-0xFF, address of USART terminal + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (((uint32_t)addr) << USART_CTL1_ADDR_OFFSET)); + +} + +/*! + \brief configure address detection mode (API_ID: 0x001AU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] addmod: address detection mode + only one parameter can be selected which is shown as below: + \arg USART_ADDM_4BIT: 4 bits + \arg USART_ADDM_FULLBIT: full bits + \param[out] none + \retval none +*/ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDM); + USART_CTL1(usart_periph) |= USART_CTL1_ADDM & (addmod); +} + +/*! + \brief enable mute mode (API_ID: 0x001BU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_MEN; +} + +/*! + \brief disable mute mode (API_ID: 0x001CU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_MEN); +} + +/*! + \brief configure wakeup method in mute mode (API_ID: 0x001DU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] wmethod: two methods be used to enter or exit the mute mode + only one parameter can be selected which is shown as below: + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mark + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmethod & USART_CTL0_WM; +} + +/*! + \brief enable LIN mode (API_ID: 0x001EU) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode (API_ID: 0x001FU) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief LIN break detection length (API_ID: 0x0020U) + \param[in] usart_periph: USARTx(x=0) + \param[in] lblen: LIN break detection length + only one parameter can be selected which is shown as below: + \arg USART_LBLEN_10B: 10 bits break detection + \arg USART_LBLEN_11B: 11 bits break detection + \param[out] none + \retval none +*/ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= USART_CTL1_LBLEN & (lblen); +} + +/*! + \brief enable half-duplex mode (API_ID: 0x0021U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_halfduplex_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) |= USART_CTL2_HDEN; +} + +/*! + \brief disable half-duplex mode (API_ID: 0x0022U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_halfduplex_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable clock (API_ID: 0x0023U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_clock_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable clock (API_ID: 0x0024U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_clock_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN); +} + +/*! + \brief configure USART synchronous mode parameters (API_ID: 0x0025U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] clen: last bit clock pulse + only one parameter can be selected which is shown as below: + \arg USART_CLEN_NONE: clock pulse of the last data bit (MSB) is not output to the CK pin + \arg USART_CLEN_EN: clock pulse of the last data bit (MSB) is output to the CK pin + \param[in] cph: clock phase + only one parameter can be selected which is shown as below: + \arg USART_CPH_1CK: first clock transition is the first data capture edge + \arg USART_CPH_2CK: second clock transition is the first data capture edge + \param[in] cpl: clock polarity + only one parameter can be selected which is shown as below: + \arg USART_CPL_LOW: steady low value on CK pin + \arg USART_CPL_HIGH: steady high value on CK pin + \param[out] none + \retval none +*/ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset USART_CTL1 CLEN,CPH,CPL bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + + USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen); + USART_CTL1(usart_periph) |= (USART_CTL1_CPH & cph); + USART_CTL1(usart_periph) |= (USART_CTL1_CPL & cpl); +} + +/*! + \brief configure guard time value in smartcard mode (API_ID: 0x0026U) + \param[in] usart_periph: USARTx(x=0) + \param[in] guat: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, uint8_t guat) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((uint32_t)(guat) << USART_GP_GUAT_OFFSET)); +} + +/*! + \brief enable smartcard mode (API_ID: 0x0027U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief disable smartcard mode (API_ID: 0x0028U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief enable NACK in smartcard mode (API_ID: 0x0029U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief disable NACK in smartcard mode (API_ID: 0x002AU) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief enable early NACK in smartcard mode (API_ID: 0x002BU) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) |= USART_RFCS_ELNACK; +} + +/*! + \brief disable early NACK in smartcard mode (API_ID: 0x002CU) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) &= ~USART_RFCS_ELNACK; +} + +/*! + \brief configure smartcard auto-retry number (API_ID: 0x002DU) + \param[in] usart_periph: USARTx(x=0) + \param[in] scrtnum: 0x00-0x07, smartcard auto-retry number + \param[out] none + \retval none +*/ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint8_t scrtnum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCRTNUM); + USART_CTL2(usart_periph) |= (USART_CTL2_SCRTNUM & (((uint32_t)scrtnum) << USART_CTL2_SCRTNUM_OFFSET)); +} + +/*! + \brief configure block length (API_ID: 0x002EU) + \param[in] usart_periph: USARTx(x=0) + \param[in] bl: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint8_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & (((uint32_t)bl) << USART_RT_BL_OFFSET)); +} + +/*! + \brief enable IrDA mode (API_ID: 0x002FU) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode (API_ID: 0x0030U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power or SmartCard mode (API_ID: 0x0031U) + \param[in] usart_periph: USARTx(x=0) + \param[in] psc: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint8_t psc) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= psc; +} + +/*! + \brief configure IrDA low-power (API_ID: 0x0032U) + \param[in] usart_periph: USARTx(x=0) + \param[in] irlp: IrDA low-power or normal + only one parameter can be selected which is shown as below: + \arg USART_IRLP_LOW: low-power + \arg USART_IRLP_NORMAL: normal + \param[out] none + \retval none +*/ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP); + USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp); +} + +/*! + \brief configure hardware flow control RTS (API_ID: 0x0033U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] rtsconfig: enable or disable RTS + only one parameter can be selected which is shown as below: + \arg USART_RTS_ENABLE: enable RTS + \arg USART_RTS_DISABLE: disable RTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN); + USART_CTL2(usart_periph) |= rtsconfig & USART_CTL2_RTSEN; +} + +/*! + \brief configure hardware flow control CTS (API_ID: 0x0034U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] ctsconfig: enable or disable CTS + only one parameter can be selected which is shown as below: + \arg USART_CTS_ENABLE: enable CTS + \arg USART_CTS_DISABLE: disable CTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~USART_CTL2_CTSEN; + USART_CTL2(usart_periph) |= ctsconfig & USART_CTL2_CTSEN; +} + +/*! + \brief configure hardware flow control coherence mode (API_ID: 0x0035U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] hcm: + only one parameter can be selected which is shown as below: + \arg USART_HCM_NONE: nRTS signal equals to the rxne status register + \arg USART_HCM_EN: nRTS signal is set when the last data bit has been sampled + \param[out] none + \retval none +*/ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_HCM); + USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm); +} + +/*! + \brief enable RS485 driver (API_ID: 0x0036U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_rs485_driver_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_DEM; +} + +/*! + \brief disable RS485 driver (API_ID: 0x0037U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_rs485_driver_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEM); +} + +/*! + \brief configure driver enable assertion time (API_ID: 0x0038U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] deatime: 0x00-0x1F + \param[out] none + \retval none +*/ +void usart_driver_assertime_config(uint32_t usart_periph, uint8_t deatime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DEA); + USART_CTL0(usart_periph) |= (USART_CTL0_DEA & (((uint32_t)deatime) << USART_CTL0_DEA_OFFSET)); +} + +/*! + \brief configure driver enable de-assertion time (API_ID: 0x0039U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] dedtime: 0x00-0x1F + \param[out] none + \retval none +*/ +void usart_driver_deassertime_config(uint32_t usart_periph, uint8_t dedtime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DED); + USART_CTL0(usart_periph) |= (USART_CTL0_DED & (((uint32_t)dedtime) << USART_CTL0_DED_OFFSET)); +} + +/*! + \brief configure driver enable polarity mode (API_ID: 0x003AU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] dep: DE signal + only one parameter can be selected which is shown as below: + \arg USART_DEP_HIGH: DE signal is active high + \arg USART_DEP_LOW: DE signal is active low + \param[out] none + \retval none +*/ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset DEP bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEP); + USART_CTL2(usart_periph) |= (USART_CTL2_DEP & dep); +} + +/*! + \brief configure USART DMA reception (API_ID: 0x003BU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] dmacmd: enable or disable DMA for reception + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_DMA_ENABLE: DMA enable for reception + \arg USART_RECEIVE_DMA_DISABLE: DMA disable for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENR; + /* configure DMA reception */ + USART_CTL2(usart_periph) |= dmacmd & USART_CTL2_DENR; +} + +/*! + \brief configure USART DMA transmission (API_ID: 0x003CU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] dmacmd: enable or disable DMA for transmission + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_DMA_ENABLE: DMA enable for transmission + \arg USART_TRANSMIT_DMA_DISABLE: DMA disable for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENT; + /* configure DMA transmission */ + USART_CTL2(usart_periph) |= dmacmd & USART_CTL2_DENT; +} + +/*! + \brief disable DMA on reception error (API_ID: 0x003DU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) |= USART_CTL2_DDRE; +} + +/*! + \brief enable DMA on reception error (API_ID: 0x003EU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_DDRE); +} + +/*! + \brief enable USART to wakeup the mcu from deep-sleep mode (API_ID: 0x003FU) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UESM; +} + +/*! + \brief disable USART to wakeup the mcu from deep-sleep mode (API_ID: 0x0040U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM); +} + +/*! + \brief configure the USART wakeup mode from deep-sleep mode (API_ID: 0x0041U) + \param[in] usart_periph: USARTx(x=0) + \param[in] wum: wakeup mode + only one parameter can be selected which is shown as below: + \arg USART_WUM_ADDR: WUF active on address match + \arg USART_WUM_STARTB: WUF active on start bit + \arg USART_WUM_RBNE: WUF active on RBNE + \param[out] none + \retval none +*/ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset WUM bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_WUM); + USART_CTL2(usart_periph) |= USART_CTL2_WUM & (wum); +} + +/*! + \brief enable receive FIFO (API_ID: 0x0042U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receive_fifo_enable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) |= USART_RFCS_RFEN; +} + +/*! + \brief disable receive FIFO (API_ID: 0x0043U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receive_fifo_disable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) &= ~(USART_RFCS_RFEN); +} + +/*! + \brief read receive FIFO counter number (API_ID: 0x0044U) + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval receive FIFO counter number +*/ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph) +{ + uint8_t number = 0U; + + number = (uint8_t)(GET_BITS(USART_RFCS(usart_periph), 12U, 14U)); + return number; +} + +/*! + \brief get flag in STAT/CHC/RFCS register (API_ID: 0x0045U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_TC: transmission completed + \arg USART_FLAG_TBE: transmit data register empty + \arg USART_FLAG_LBD: LIN break detected flag (only support USART0) + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_CTS: CTS level + \arg USART_FLAG_RT: receiver timeout flag (only support USART0) + \arg USART_FLAG_EB: end of block flag (only support USART0) + \arg USART_FLAG_ABDE: auto baudrate detection error flag, only for USART0 + \arg USART_FLAG_ABDF: auto baudrate detection flag, only for USART0 + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_SB: send break flag + \arg USART_FLAG_RWU: receiver wakeup from mute mode. + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag (only support USART0) + \arg USART_FLAG_TEA: transmit enable acknowledge flag + \arg USART_FLAG_REA: receive enable acknowledge flag + \arg USART_FLAG_EPERR: early parity error flag + \arg USART_FLAG_RFE: receive FIFO empty flag (only support USART0) + \arg USART_FLAG_RFF: receive FIFO full flag (only support USART0) + \arg USART_FLAG_RFFINT: receive FIFO full interrupt flag (only support USART0) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) +{ + FlagStatus status = RESET; + + if(0U != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))) { + status = SET; + } else { + status = RESET; + } + return status; +} + +/*! + \brief clear USART status (API_ID: 0x0046U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise detected flag + \arg USART_FLAG_ORERR: overrun error flag + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_TC: transmission complete flag + \arg USART_FLAG_LBD: LIN break detected flag (only support USART0) + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_RT: receiver timeout flag (only support USART0) + \arg USART_FLAG_EB: end of block flag (only support USART0) + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag (only support USART0) + \arg USART_FLAG_EPERR: early parity error flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); +} + +/*! + \brief enable USART interrupt (API_ID: 0x0047U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] interrupt: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt enable interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt (only support USART0) + \arg USART_INT_EB: end of block interrupt (only support USART0) + \arg USART_INT_LBD: LIN break detection interrupt (only support USART0) + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt (only support USART0) + \arg USART_INT_RFF: receive FIFO full interrupt enable (only support USART0) + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt) +{ + USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt)); +} + +/*! + \brief disable USART interrupt (API_ID: 0x0048U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] interrupt: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt(only support USART0) + \arg USART_INT_EB: end of block interrupt(only support USART0) + \arg USART_INT_LBD: LIN break detection interrupt(only support USART0) + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt (only support USART0) + \arg USART_INT_RFF: receive FIFO full interrupt enable (only support USART0) + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt) +{ + USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt)); +} + +/*! + \brief get USART interrupt and flag status (API_ID: 0x0049U) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_EB: end of block interrupt and flag (only support USART0) + \arg USART_INT_FLAG_RT: receiver timeout interrupt and flag (only support USART0) + \arg USART_INT_FLAG_AM: address match interrupt and flag + \arg USART_INT_FLAG_PERR: parity error interrupt and flag + \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag + \arg USART_INT_FLAG_TC: transmission complete interrupt and flag + \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag + \arg USART_INT_FLAG_LBD: LIN break detected interrupt and flag (only support USART0) + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt and flag (only support USART0) + \arg USART_INT_FLAG_CTS: CTS interrupt and flag + \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag (only support USART0) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + uint32_t intenable, flagstatus; + FlagStatus status = RESET; + + /* get the interrupt enable bit status */ + intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag))); + + if((0U != flagstatus) && (0U != intenable)) { + status = SET; + } else { + status = RESET; + } + return status; +} + +/*! + \brief clear USART interrupt flag (API_ID: 0x004AU) + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] int_flag: USART interrupt flag + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_PERR: parity error flag + \arg USART_INT_FLAG_ERR_FERR: frame error flag + \arg USART_INT_FLAG_ERR_NERR: noise detected flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_IDLE: idle line detected flag + \arg USART_INT_FLAG_TC: transmission complete flag + \arg USART_INT_FLAG_LBD: LIN break detected flag (only support USART0) + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_RT: receiver timeout flag (only support USART0) + \arg USART_INT_FLAG_EB: end of block flag (only support USART0) + \arg USART_INT_FLAG_AM: address match flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode flag (only support USART0) + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag (only support USART0) + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + if(USART_INT_FLAG_RFF == int_flag) { + USART_RFCS(usart_periph) &= (uint32_t)(~USART_RFCS_RFFINT); + } else { + USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(int_flag)); + } +} diff --git a/gd32c2x1/standard_peripheral/source/gd32c2x1_wwdgt.c b/gd32c2x1/standard_peripheral/source/gd32c2x1_wwdgt.c new file mode 100644 index 0000000..175bf01 --- /dev/null +++ b/gd32c2x1/standard_peripheral/source/gd32c2x1_wwdgt.c @@ -0,0 +1,186 @@ +/*! + \file gd32c2x1_wwdgt.c + \brief WWDGT driver + + \version 2025-08-08, V1.1.0, firmware for gd32c2x1 +*/ + +/* + Copyright (c) 2025, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32c2x1_wwdgt.h" + +#define WWDGT_PSC_MASK ((uint32_t)0x00030180U) + +/*! + \brief reset the WWDGT configuration (API_ID(0x0001U)) + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_deinit(void) +{ + rcu_periph_reset_enable(RCU_WWDGTRST); + rcu_periph_reset_disable(RCU_WWDGTRST); +} + +/*! + \brief start the WWDGT counter (API_ID(0x0002U)) + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure the WWDGT counter prescaler value (API_ID(0x0003U)) + \param[in] prescaler: WWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1 + \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2 + \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4 + \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8 + \arg WWDGT_CFG_PSC_DIV16: the time base of window watchdog counter = (PCLK1/4096)/16 + \arg WWDGT_CFG_PSC_DIV32: the time base of window watchdog counter = (PCLK1/4096)/32 + \arg WWDGT_CFG_PSC_DIV64: the time base of window watchdog counter = (PCLK1/4096)/64 + \arg WWDGT_CFG_PSC_DIV128: the time base of window watchdog counter = (PCLK1/4096)/128 + \arg WWDGT_CFG_PSC_DIV256: the time base of window watchdog counter = (PCLK1/4096)/256 + \arg WWDGT_CFG_PSC_DIV512: the time base of window watchdog counter = (PCLK1/4096)/512 + \arg WWDGT_CFG_PSC_DIV1024: the time base of window watchdog counter = (PCLK1/4096)/1024 + \arg WWDGT_CFG_PSC_DIV2048: the time base of window watchdog counter = (PCLK1/4096)/2048 + \arg WWDGT_CFG_PSC_DIV4096: the time base of window watchdog counter = (PCLK1/4096)/4096 + \arg WWDGT_CFG_PSC_DIV8192: the time base of window watchdog counter = (PCLK1/4096)/8192 + \param[out] none + \retval none +*/ +void wwdgt_prescaler_value_config(uint32_t prescaler) +{ + uint32_t reg_cfg; + + /* clear WIN and PSC bits */ + reg_cfg = WWDGT_CFG & (~(WWDGT_CFG_PSC_0_1 | WWDGT_CFG_PSC_2_3)); + /* configure PSC bits */ + reg_cfg |= (uint32_t)(prescaler & WWDGT_PSC_MASK); + WWDGT_CFG = (uint32_t)reg_cfg; +} + +/*! + \brief configure the WWDGT counter window value (API_ID(0x0004U)) + \param[in] window: specify window value(0x0000 - 0x007F) + \param[out] none + \retval none +*/ +void wwdgt_window_value_config(uint16_t window) +{ + uint32_t reg_cfg; + + /* clear WIN and PSC bits */ + reg_cfg = WWDGT_CFG & (~WWDGT_CFG_WIN); + /* configure WIN bits */ + reg_cfg |= (uint32_t)(window & WWDGT_CFG_WIN); + WWDGT_CFG = (uint32_t)reg_cfg; +} + +/*! + \brief configure the WWDGT counter value (API_ID(0x0005U)) + \param[in] counter_value: 0x00 - 0x7F + \param[out] none + \retval none +*/ +void wwdgt_counter_update(uint16_t counter_value) +{ + WWDGT_CTL = (uint32_t)(CTL_CNT(counter_value)); +} + +/*! + \brief configure counter value, window value, and prescaler divider value (API_ID(0x0006U)) + \param[in] counter: 0x0000 - 0x007F + \param[in] window: 0x0000 - 0x007F + \param[in] prescaler: WWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1 + \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2 + \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4 + \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8 + \arg WWDGT_CFG_PSC_DIV16: the time base of window watchdog counter = (PCLK1/4096)/16 + \arg WWDGT_CFG_PSC_DIV32: the time base of window watchdog counter = (PCLK1/4096)/32 + \arg WWDGT_CFG_PSC_DIV64: the time base of window watchdog counter = (PCLK1/4096)/64 + \arg WWDGT_CFG_PSC_DIV128: the time base of window watchdog counter = (PCLK1/4096)/128 + \arg WWDGT_CFG_PSC_DIV256: the time base of window watchdog counter = (PCLK1/4096)/256 + \arg WWDGT_CFG_PSC_DIV512: the time base of window watchdog counter = (PCLK1/4096)/512 + \arg WWDGT_CFG_PSC_DIV1024: the time base of window watchdog counter = (PCLK1/4096)/1024 + \arg WWDGT_CFG_PSC_DIV2048: the time base of window watchdog counter = (PCLK1/4096)/2048 + \arg WWDGT_CFG_PSC_DIV4096: the time base of window watchdog counter = (PCLK1/4096)/4096 + \arg WWDGT_CFG_PSC_DIV8192: the time base of window watchdog counter = (PCLK1/4096)/8192 + \param[out] none + \retval none +*/ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler) +{ + WWDGT_CTL = (uint32_t)(CTL_CNT(counter)); + WWDGT_CFG = (uint32_t)(CFG_WIN(window) | (prescaler & WWDGT_PSC_MASK)); +} + +/*! + \brief check early wakeup interrupt state of WWDGT (API_ID(0x0007U)) + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus wwdgt_flag_get(void) +{ + FlagStatus wwdgt_flag = RESET; + if((uint32_t)RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)) { + wwdgt_flag = SET; + } + return wwdgt_flag; +} + +/*! + \brief clear early wakeup interrupt state of WWDGT (API_ID(0x0008U)) + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_flag_clear(void) +{ + WWDGT_STAT &= ~(uint32_t)(WWDGT_STAT_EWIF); +} + +/*! + \brief enable early wakeup interrupt of WWDGT (API_ID(0x0009U)) + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_interrupt_enable(void) +{ + WWDGT_CFG |= WWDGT_CFG_EWIE; +} diff --git a/include/dt-bindings/pinctrl/gd32c231c(6-8)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32c231c(6-8)xx-pinctrl.h new file mode 100644 index 0000000..b113b3e --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32c231c(6-8)xx-pinctrl.h @@ -0,0 +1,819 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC_IN0 */ +#define ADC_IN0_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) + +/* ADC_IN1 */ +#define ADC_IN1_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) + +/* ADC_IN10 */ +#define ADC_IN10_PB2 \ + GD32_PINMUX_AF('B', 2, ANALOG) + +/* ADC_IN11 */ +#define ADC_IN11_PB10 \ + GD32_PINMUX_AF('B', 10, ANALOG) + +/* ADC_IN12 */ +#define ADC_IN12_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) + +/* ADC_IN2 */ +#define ADC_IN2_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) + +/* ADC_IN3 */ +#define ADC_IN3_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC_IN4 */ +#define ADC_IN4_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC_IN5 */ +#define ADC_IN5_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) + +/* ADC_IN6 */ +#define ADC_IN6_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) + +/* ADC_IN7 */ +#define ADC_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* ADC_IN8 */ +#define ADC_IN8_PB0 \ + GD32_PINMUX_AF('B', 0, ANALOG) + +/* ADC_IN9 */ +#define ADC_IN9_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) + +/* ANALOG */ +#define ANALOG_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) +#define ANALOG_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) +#define ANALOG_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) +#define ANALOG_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) +#define ANALOG_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) +#define ANALOG_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) +#define ANALOG_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) +#define ANALOG_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) +#define ANALOG_PA8 \ + GD32_PINMUX_AF('A', 8, ANALOG) +#define ANALOG_PA9 \ + GD32_PINMUX_AF('A', 9, ANALOG) +#define ANALOG_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) +#define ANALOG_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) +#define ANALOG_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) +#define ANALOG_PA13 \ + GD32_PINMUX_AF('A', 13, ANALOG) +#define ANALOG_PA14 \ + GD32_PINMUX_AF('A', 14, ANALOG) +#define ANALOG_PA15 \ + GD32_PINMUX_AF('A', 15, ANALOG) +#define ANALOG_PB0 \ + GD32_PINMUX_AF('B', 0, ANALOG) +#define ANALOG_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) +#define ANALOG_PB2 \ + GD32_PINMUX_AF('B', 2, ANALOG) +#define ANALOG_PB3 \ + GD32_PINMUX_AF('B', 3, ANALOG) +#define ANALOG_PB4 \ + GD32_PINMUX_AF('B', 4, ANALOG) +#define ANALOG_PB5 \ + GD32_PINMUX_AF('B', 5, ANALOG) +#define ANALOG_PB6 \ + GD32_PINMUX_AF('B', 6, ANALOG) +#define ANALOG_PB7 \ + GD32_PINMUX_AF('B', 7, ANALOG) +#define ANALOG_PB8 \ + GD32_PINMUX_AF('B', 8, ANALOG) +#define ANALOG_PB9 \ + GD32_PINMUX_AF('B', 9, ANALOG) +#define ANALOG_PB10 \ + GD32_PINMUX_AF('B', 10, ANALOG) +#define ANALOG_PB11 \ + GD32_PINMUX_AF('B', 11, ANALOG) +#define ANALOG_PB12 \ + GD32_PINMUX_AF('B', 12, ANALOG) +#define ANALOG_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) +#define ANALOG_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) +#define ANALOG_PB15 \ + GD32_PINMUX_AF('B', 15, ANALOG) +#define ANALOG_PC6 \ + GD32_PINMUX_AF('C', 6, ANALOG) +#define ANALOG_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) +#define ANALOG_PC13 \ + GD32_PINMUX_AF('C', 13, ANALOG) +#define ANALOG_PC14 \ + GD32_PINMUX_AF('C', 14, ANALOG) +#define ANALOG_PC15 \ + GD32_PINMUX_AF('C', 15, ANALOG) +#define ANALOG_PD0 \ + GD32_PINMUX_AF('D', 0, ANALOG) +#define ANALOG_PD1 \ + GD32_PINMUX_AF('D', 1, ANALOG) +#define ANALOG_PD2 \ + GD32_PINMUX_AF('D', 2, ANALOG) +#define ANALOG_PD3 \ + GD32_PINMUX_AF('D', 3, ANALOG) +#define ANALOG_PF0 \ + GD32_PINMUX_AF('F', 0, ANALOG) +#define ANALOG_PF1 \ + GD32_PINMUX_AF('F', 1, ANALOG) +#define ANALOG_PF2 \ + GD32_PINMUX_AF('F', 2, ANALOG) +#define ANALOG_PF3 \ + GD32_PINMUX_AF('F', 3, ANALOG) + +/* CK_OUT0 */ +#define CK_OUT0_PA8 \ + GD32_PINMUX_AF('A', 8, AF0) +#define CK_OUT0_PA9 \ + GD32_PINMUX_AF('A', 9, AF0) +#define CK_OUT0_PF2 \ + GD32_PINMUX_AF('F', 2, AF0) + +/* CK_OUT1 */ +#define CK_OUT1_PA8 \ + GD32_PINMUX_AF('A', 8, AF14) +#define CK_OUT1_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define CK_OUT1_PA14 \ + GD32_PINMUX_AF('A', 14, AF11) +#define CK_OUT1_PA15 \ + GD32_PINMUX_AF('A', 15, AF3) +#define CK_OUT1_PB2 \ + GD32_PINMUX_AF('B', 2, AF3) + +/* CMP0_OUT */ +#define CMP0_OUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF7) +#define CMP0_OUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF7) +#define CMP0_OUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) +#define CMP0_OUT_PB0 \ + GD32_PINMUX_AF('B', 0, AF7) +#define CMP0_OUT_PB10 \ + GD32_PINMUX_AF('B', 10, AF6) + +/* CMP1_OUT */ +#define CMP1_OUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) +#define CMP1_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) +#define CMP1_OUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF7) +#define CMP1_OUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF7) +#define CMP1_OUT_PB11 \ + GD32_PINMUX_AF('B', 11, AF6) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF15) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF15) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF15) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF15) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF15) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF15) +#define EVENTOUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF15) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF15) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF15) +#define EVENTOUT_PA9 \ + GD32_PINMUX_AF('A', 9, AF15) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF15) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF15) +#define EVENTOUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF15) +#define EVENTOUT_PA13 \ + GD32_PINMUX_AF('A', 13, AF15) +#define EVENTOUT_PA14 \ + GD32_PINMUX_AF('A', 14, AF15) +#define EVENTOUT_PA15 \ + GD32_PINMUX_AF('A', 15, AF15) +#define EVENTOUT_PB0 \ + GD32_PINMUX_AF('B', 0, AF15) +#define EVENTOUT_PB1 \ + GD32_PINMUX_AF('B', 1, AF15) +#define EVENTOUT_PB2 \ + GD32_PINMUX_AF('B', 2, AF15) +#define EVENTOUT_PB3 \ + GD32_PINMUX_AF('B', 3, AF15) +#define EVENTOUT_PB4 \ + GD32_PINMUX_AF('B', 4, AF15) +#define EVENTOUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF15) +#define EVENTOUT_PB6 \ + GD32_PINMUX_AF('B', 6, AF15) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF15) +#define EVENTOUT_PB8 \ + GD32_PINMUX_AF('B', 8, AF15) +#define EVENTOUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF15) +#define EVENTOUT_PB10 \ + GD32_PINMUX_AF('B', 10, AF15) +#define EVENTOUT_PB11 \ + GD32_PINMUX_AF('B', 11, AF15) +#define EVENTOUT_PB12 \ + GD32_PINMUX_AF('B', 12, AF15) +#define EVENTOUT_PB13 \ + GD32_PINMUX_AF('B', 13, AF15) +#define EVENTOUT_PB14 \ + GD32_PINMUX_AF('B', 14, AF15) +#define EVENTOUT_PB15 \ + GD32_PINMUX_AF('B', 15, AF15) +#define EVENTOUT_PC6 \ + GD32_PINMUX_AF('C', 6, AF15) +#define EVENTOUT_PC7 \ + GD32_PINMUX_AF('C', 7, AF15) +#define EVENTOUT_PC13 \ + GD32_PINMUX_AF('C', 13, AF15) +#define EVENTOUT_PC14 \ + GD32_PINMUX_AF('C', 14, AF15) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF15) +#define EVENTOUT_PD0 \ + GD32_PINMUX_AF('D', 0, AF15) +#define EVENTOUT_PD1 \ + GD32_PINMUX_AF('D', 1, AF15) +#define EVENTOUT_PD2 \ + GD32_PINMUX_AF('D', 2, AF15) +#define EVENTOUT_PD3 \ + GD32_PINMUX_AF('D', 3, AF15) +#define EVENTOUT_PF0 \ + GD32_PINMUX_AF('F', 0, AF15) +#define EVENTOUT_PF1 \ + GD32_PINMUX_AF('F', 1, AF15) +#define EVENTOUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF15) +#define EVENTOUT_PF3 \ + GD32_PINMUX_AF('F', 3, AF15) + +/* I2C0_SCL */ +#define I2C0_SCL_PA9 \ + GD32_PINMUX_AF('A', 9, AF6) +#define I2C0_SCL_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) +#define I2C0_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) +#define I2C0_SCL_PB8 \ + GD32_PINMUX_AF('B', 8, AF4) + +/* I2C0_SDA */ +#define I2C0_SDA_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) +#define I2C0_SDA_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) +#define I2C0_SDA_PB9 \ + GD32_PINMUX_AF('B', 9, AF4) + +/* I2C0_SMBA */ +#define I2C0_SMBA_PA1 \ + GD32_PINMUX_AF('A', 1, AF6) +#define I2C0_SMBA_PB5 \ + GD32_PINMUX_AF('B', 5, AF6) +#define I2C0_SMBA_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) + +/* I2C1_SCL */ +#define I2C1_SCL_PA11 \ + GD32_PINMUX_AF('A', 11, AF6) +#define I2C1_SCL_PB10 \ + GD32_PINMUX_AF('B', 10, AF4) + +/* I2C1_SDA */ +#define I2C1_SDA_PA12 \ + GD32_PINMUX_AF('A', 12, AF6) +#define I2C1_SDA_PB11 \ + GD32_PINMUX_AF('B', 11, AF4) + +/* I2S0_CK */ +#define I2S0_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define I2S0_CK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define I2S0_CK_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) +#define I2S0_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_SD */ +#define I2S0_SD_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define I2S0_SD_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define I2S0_SD_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define I2S0_SD_PB5 \ + GD32_PINMUX_AF('B', 5, AF0) +#define I2S0_SD_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_WS */ +#define I2S0_WS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define I2S0_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define I2S0_WS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) +#define I2S0_WS_PA15 \ + GD32_PINMUX_AF('A', 15, AF0) +#define I2S0_WS_PB0 \ + GD32_PINMUX_AF('B', 0, AF0) + +/* I2S_CKIN */ +#define I2S_CKIN_PA12 \ + GD32_PINMUX_AF('A', 12, AF5) + +/* OSC32EN */ +#define OSC32EN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* OSCEN */ +#define OSCEN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) +#define OSCEN_PF1 \ + GD32_PINMUX_AF('F', 1, AF0) + +/* SPI0_MISO */ +#define SPI0_MISO_PA6 \ + GD32_PINMUX_AF('A', 6, AF0) +#define SPI0_MISO_PA11 \ + GD32_PINMUX_AF('A', 11, AF0) +#define SPI0_MISO_PB4 \ + GD32_PINMUX_AF('B', 4, AF0) +#define SPI0_MISO_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define SPI0_MOSI_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define SPI0_MOSI_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define SPI0_MOSI_PB5 \ + GD32_PINMUX_AF('B', 5, AF0) +#define SPI0_MOSI_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_NSS */ +#define SPI0_NSS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define SPI0_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define SPI0_NSS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) +#define SPI0_NSS_PA15 \ + GD32_PINMUX_AF('A', 15, AF0) +#define SPI0_NSS_PB0 \ + GD32_PINMUX_AF('B', 0, AF0) + +/* SPI0_SCK */ +#define SPI0_SCK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define SPI0_SCK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define SPI0_SCK_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) +#define SPI0_SCK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI1_IO2 */ +#define SPI1_IO2_PA1 \ + GD32_PINMUX_AF('A', 1, AF3) +#define SPI1_IO2_PA5 \ + GD32_PINMUX_AF('A', 5, AF3) +#define SPI1_IO2_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) + +/* SPI1_IO3 */ +#define SPI1_IO3_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI1_IO3_PA6 \ + GD32_PINMUX_AF('A', 6, AF3) +#define SPI1_IO3_PA12 \ + GD32_PINMUX_AF('A', 12, AF3) + +/* SPI1_MISO */ +#define SPI1_MISO_PA3 \ + GD32_PINMUX_AF('A', 3, AF0) +#define SPI1_MISO_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) +#define SPI1_MISO_PB2 \ + GD32_PINMUX_AF('B', 2, AF1) +#define SPI1_MISO_PB5 \ + GD32_PINMUX_AF('B', 5, AF4) +#define SPI1_MISO_PB14 \ + GD32_PINMUX_AF('B', 14, AF5) +#define SPI1_MISO_PD3 \ + GD32_PINMUX_AF('D', 3, AF5) + +/* SPI1_MOSI */ +#define SPI1_MOSI_PA4 \ + GD32_PINMUX_AF('A', 4, AF3) +#define SPI1_MOSI_PA10 \ + GD32_PINMUX_AF('A', 10, AF0) +#define SPI1_MOSI_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) +#define SPI1_MOSI_PB11 \ + GD32_PINMUX_AF('B', 11, AF5) +#define SPI1_MOSI_PB15 \ + GD32_PINMUX_AF('B', 15, AF5) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF3) +#define SPI1_NSS_PB9 \ + GD32_PINMUX_AF('B', 9, AF5) +#define SPI1_NSS_PB12 \ + GD32_PINMUX_AF('B', 12, AF5) +#define SPI1_NSS_PD0 \ + GD32_PINMUX_AF('D', 0, AF5) + +/* SPI1_SCK */ +#define SPI1_SCK_PA0 \ + GD32_PINMUX_AF('A', 0, AF0) +#define SPI1_SCK_PB8 \ + GD32_PINMUX_AF('B', 8, AF5) +#define SPI1_SCK_PB10 \ + GD32_PINMUX_AF('B', 10, AF5) +#define SPI1_SCK_PB13 \ + GD32_PINMUX_AF('B', 13, AF5) +#define SPI1_SCK_PD1 \ + GD32_PINMUX_AF('D', 1, AF5) + +/* SWCLK */ +#define SWCLK_PA14 \ + GD32_PINMUX_AF('A', 14, AF0) + +/* SWDIO */ +#define SWDIO_PA13 \ + GD32_PINMUX_AF('A', 13, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) +#define TIMER0_BRKIN0_PB12 \ + GD32_PINMUX_AF('B', 12, AF1) +#define TIMER0_BRKIN0_PC13 \ + GD32_PINMUX_AF('C', 13, AF1) + +/* TIMER0_BRKIN1 */ +#define TIMER0_BRKIN1_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define TIMER0_BRKIN1_PB12 \ + GD32_PINMUX_AF('B', 12, AF1) +#define TIMER0_BRKIN1_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF5) +#define TIMER0_CH0_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) +#define TIMER0_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) +#define TIMER0_CH0_PA14 \ + GD32_PINMUX_AF('A', 14, AF10) +#define TIMER0_CH0_PA15 \ + GD32_PINMUX_AF('A', 15, AF2) + +/* TIMER0_CH0_ON */ +#define TIMER0_CH0_ON_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) +#define TIMER0_CH0_ON_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) +#define TIMER0_CH0_ON_PB13 \ + GD32_PINMUX_AF('B', 13, AF1) +#define TIMER0_CH0_ON_PD2 \ + GD32_PINMUX_AF('D', 2, AF1) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA1 \ + GD32_PINMUX_AF('A', 1, AF5) +#define TIMER0_CH1_PA9 \ + GD32_PINMUX_AF('A', 9, AF2) +#define TIMER0_CH1_PB3 \ + GD32_PINMUX_AF('B', 3, AF1) +#define TIMER0_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH1_ON */ +#define TIMER0_CH1_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF2) +#define TIMER0_CH1_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF8) +#define TIMER0_CH1_ON_PB0 \ + GD32_PINMUX_AF('B', 0, AF2) +#define TIMER0_CH1_ON_PB1 \ + GD32_PINMUX_AF('B', 1, AF5) +#define TIMER0_CH1_ON_PB14 \ + GD32_PINMUX_AF('B', 14, AF1) +#define TIMER0_CH1_ON_PD3 \ + GD32_PINMUX_AF('D', 3, AF1) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF5) +#define TIMER0_CH2_PA10 \ + GD32_PINMUX_AF('A', 10, AF2) +#define TIMER0_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH2_ON */ +#define TIMER0_CH2_ON_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) +#define TIMER0_CH2_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) +#define TIMER0_CH2_ON_PB1 \ + GD32_PINMUX_AF('B', 1, AF2) +#define TIMER0_CH2_ON_PB15 \ + GD32_PINMUX_AF('B', 15, AF1) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define TIMER0_CH3_PA11 \ + GD32_PINMUX_AF('A', 11, AF2) +#define TIMER0_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER0_CH3_PF2 \ + GD32_PINMUX_AF('F', 2, AF1) + +/* TIMER0_ETI */ +#define TIMER0_ETI_PA12 \ + GD32_PINMUX_AF('A', 12, AF2) +#define TIMER0_ETI_PC13 \ + GD32_PINMUX_AF('C', 13, AF1) +#define TIMER0_ETI_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) +#define TIMER0_ETI_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER13_CH0 */ +#define TIMER13_CH0_PA4 \ + GD32_PINMUX_AF('A', 4, AF4) +#define TIMER13_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF4) +#define TIMER13_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF12) +#define TIMER13_CH0_PB1 \ + GD32_PINMUX_AF('B', 1, AF0) +#define TIMER13_CH0_PF0 \ + GD32_PINMUX_AF('F', 0, AF2) + +/* TIMER15_BRKIN0 */ +#define TIMER15_BRKIN0_PB5 \ + GD32_PINMUX_AF('B', 5, AF2) +#define TIMER15_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER15_CH0 */ +#define TIMER15_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF2) +#define TIMER15_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) +#define TIMER15_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER15_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER15_CH0_PD0 \ + GD32_PINMUX_AF('D', 0, AF2) + +/* TIMER15_CH0_ON */ +#define TIMER15_CH0_ON_PA2 \ + GD32_PINMUX_AF('A', 2, AF2) +#define TIMER15_CH0_ON_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_BRKIN0 */ +#define TIMER16_BRKIN0_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define TIMER16_BRKIN0_PB4 \ + GD32_PINMUX_AF('B', 4, AF5) +#define TIMER16_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_CH0 */ +#define TIMER16_CH0_PA1 \ + GD32_PINMUX_AF('A', 1, AF2) +#define TIMER16_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) +#define TIMER16_CH0_PB9 \ + GD32_PINMUX_AF('B', 9, AF2) +#define TIMER16_CH0_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) +#define TIMER16_CH0_PD1 \ + GD32_PINMUX_AF('D', 1, AF2) + +/* TIMER16_CH0_ON */ +#define TIMER16_CH0_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define TIMER16_CH0_ON_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_CH0 */ +#define TIMER2_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF1) +#define TIMER2_CH0_PB4 \ + GD32_PINMUX_AF('B', 4, AF1) +#define TIMER2_CH0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER2_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER2_CH0_PC6 \ + GD32_PINMUX_AF('C', 6, AF2) + +/* TIMER2_CH1 */ +#define TIMER2_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER2_CH1_PB3 \ + GD32_PINMUX_AF('B', 3, AF3) +#define TIMER2_CH1_PB5 \ + GD32_PINMUX_AF('B', 5, AF1) +#define TIMER2_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH1_PB9 \ + GD32_PINMUX_AF('B', 9, AF2) +#define TIMER2_CH1_PC7 \ + GD32_PINMUX_AF('C', 7, AF2) +#define TIMER2_CH1_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER2_CH2 */ +#define TIMER2_CH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF10) +#define TIMER2_CH2_PB0 \ + GD32_PINMUX_AF('B', 0, AF1) +#define TIMER2_CH2_PB5 \ + GD32_PINMUX_AF('B', 5, AF3) +#define TIMER2_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH2_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) + +/* TIMER2_CH3 */ +#define TIMER2_CH3_PA8 \ + GD32_PINMUX_AF('A', 8, AF11) +#define TIMER2_CH3_PB1 \ + GD32_PINMUX_AF('B', 1, AF1) +#define TIMER2_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_ETI */ +#define TIMER2_ETI_PA2 \ + GD32_PINMUX_AF('A', 2, AF3) +#define TIMER2_ETI_PA9 \ + GD32_PINMUX_AF('A', 9, AF3) +#define TIMER2_ETI_PA13 \ + GD32_PINMUX_AF('A', 13, AF3) +#define TIMER2_ETI_PD2 \ + GD32_PINMUX_AF('D', 2, AF2) + +/* USART0_CTS */ +#define USART0_CTS_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) +#define USART0_CTS_PB4 \ + GD32_PINMUX_AF('B', 4, AF4) +#define USART0_CTS_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RTS_DE_CK */ +#define USART0_RTS_DE_CK_PA12 \ + GD32_PINMUX_AF('A', 12, AF1) +#define USART0_RTS_DE_CK_PA14 \ + GD32_PINMUX_AF('A', 14, AF12) +#define USART0_RTS_DE_CK_PA15 \ + GD32_PINMUX_AF('A', 15, AF4) +#define USART0_RTS_DE_CK_PB3 \ + GD32_PINMUX_AF('B', 3, AF4) +#define USART0_RTS_DE_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RX */ +#define USART0_RX_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define USART0_RX_PA8 \ + GD32_PINMUX_AF('A', 8, AF13) +#define USART0_RX_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) +#define USART0_RX_PB2 \ + GD32_PINMUX_AF('B', 2, AF0) +#define USART0_RX_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) + +/* USART0_TX */ +#define USART0_TX_PA0 \ + GD32_PINMUX_AF('A', 0, AF4) +#define USART0_TX_PA9 \ + GD32_PINMUX_AF('A', 9, AF1) +#define USART0_TX_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) +#define USART0_TX_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_CTS */ +#define USART1_CTS_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) +#define USART1_CTS_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) +#define USART1_CTS_PB8 \ + GD32_PINMUX_AF('B', 8, AF7) +#define USART1_CTS_PD3 \ + GD32_PINMUX_AF('D', 3, AF7) + +/* USART1_RTS_DE_CK */ +#define USART1_RTS_DE_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) +#define USART1_RTS_DE_CK_PB9 \ + GD32_PINMUX_AF('B', 9, AF7) +#define USART1_RTS_DE_CK_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_RX */ +#define USART1_RX_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) +#define USART1_RX_PA5 \ + GD32_PINMUX_AF('A', 5, AF1) +#define USART1_RX_PA13 \ + GD32_PINMUX_AF('A', 13, AF4) +#define USART1_RX_PA14 \ + GD32_PINMUX_AF('A', 14, AF9) +#define USART1_RX_PA15 \ + GD32_PINMUX_AF('A', 15, AF1) + +/* USART1_TX */ +#define USART1_TX_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) +#define USART1_TX_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) +#define USART1_TX_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) +#define USART1_TX_PA14 \ + GD32_PINMUX_AF('A', 14, AF1) + +/* USART2_CTS */ +#define USART2_CTS_PA6 \ + GD32_PINMUX_AF('A', 6, AF6) +#define USART2_CTS_PB13 \ + GD32_PINMUX_AF('B', 13, AF8) + +/* USART2_RTS_DE_CK */ +#define USART2_RTS_DE_CK_PA7 \ + GD32_PINMUX_AF('A', 7, AF6) +#define USART2_RTS_DE_CK_PB1 \ + GD32_PINMUX_AF('B', 1, AF6) +#define USART2_RTS_DE_CK_PB12 \ + GD32_PINMUX_AF('B', 12, AF8) + +/* USART2_RX */ +#define USART2_RX_PA3 \ + GD32_PINMUX_AF('A', 3, AF6) +#define USART2_RX_PB10 \ + GD32_PINMUX_AF('B', 10, AF8) + +/* USART2_TX */ +#define USART2_TX_PA2 \ + GD32_PINMUX_AF('A', 2, AF6) +#define USART2_TX_PB11 \ + GD32_PINMUX_AF('B', 11, AF8) diff --git a/include/dt-bindings/pinctrl/gd32c231f(6-8)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32c231f(6-8)xx-pinctrl.h new file mode 100644 index 0000000..aa88757 --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32c231f(6-8)xx-pinctrl.h @@ -0,0 +1,519 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC_IN0 */ +#define ADC_IN0_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) + +/* ADC_IN1 */ +#define ADC_IN1_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) + +/* ADC_IN12 */ +#define ADC_IN12_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) + +/* ADC_IN2 */ +#define ADC_IN2_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) + +/* ADC_IN3 */ +#define ADC_IN3_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC_IN4 */ +#define ADC_IN4_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC_IN5 */ +#define ADC_IN5_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) + +/* ADC_IN6 */ +#define ADC_IN6_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) + +/* ADC_IN7 */ +#define ADC_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* ANALOG */ +#define ANALOG_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) +#define ANALOG_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) +#define ANALOG_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) +#define ANALOG_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) +#define ANALOG_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) +#define ANALOG_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) +#define ANALOG_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) +#define ANALOG_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) +#define ANALOG_PA8 \ + GD32_PINMUX_AF('A', 8, ANALOG) +#define ANALOG_PA9 \ + GD32_PINMUX_AF('A', 9, ANALOG) +#define ANALOG_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) +#define ANALOG_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) +#define ANALOG_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) +#define ANALOG_PA13 \ + GD32_PINMUX_AF('A', 13, ANALOG) +#define ANALOG_PA14 \ + GD32_PINMUX_AF('A', 14, ANALOG) +#define ANALOG_PB6 \ + GD32_PINMUX_AF('B', 6, ANALOG) +#define ANALOG_PB7 \ + GD32_PINMUX_AF('B', 7, ANALOG) +#define ANALOG_PC14 \ + GD32_PINMUX_AF('C', 14, ANALOG) +#define ANALOG_PC15 \ + GD32_PINMUX_AF('C', 15, ANALOG) +#define ANALOG_PF2 \ + GD32_PINMUX_AF('F', 2, ANALOG) + +/* CK_OUT0 */ +#define CK_OUT0_PA8 \ + GD32_PINMUX_AF('A', 8, AF0) +#define CK_OUT0_PA9 \ + GD32_PINMUX_AF('A', 9, AF0) +#define CK_OUT0_PF2 \ + GD32_PINMUX_AF('F', 2, AF0) + +/* CK_OUT1 */ +#define CK_OUT1_PA8 \ + GD32_PINMUX_AF('A', 8, AF14) +#define CK_OUT1_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define CK_OUT1_PA14 \ + GD32_PINMUX_AF('A', 14, AF11) + +/* CMP0_OUT */ +#define CMP0_OUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF7) +#define CMP0_OUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF7) +#define CMP0_OUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) + +/* CMP1_OUT */ +#define CMP1_OUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) +#define CMP1_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) +#define CMP1_OUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF7) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF15) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF15) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF15) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF15) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF15) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF15) +#define EVENTOUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF15) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF15) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF15) +#define EVENTOUT_PA9 \ + GD32_PINMUX_AF('A', 9, AF15) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF15) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF15) +#define EVENTOUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF15) +#define EVENTOUT_PA13 \ + GD32_PINMUX_AF('A', 13, AF15) +#define EVENTOUT_PA14 \ + GD32_PINMUX_AF('A', 14, AF15) +#define EVENTOUT_PB6 \ + GD32_PINMUX_AF('B', 6, AF15) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF15) +#define EVENTOUT_PC14 \ + GD32_PINMUX_AF('C', 14, AF15) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF15) +#define EVENTOUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF15) + +/* I2C0_SCL */ +#define I2C0_SCL_PA9 \ + GD32_PINMUX_AF('A', 9, AF6) +#define I2C0_SCL_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) +#define I2C0_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) + +/* I2C0_SDA */ +#define I2C0_SDA_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) +#define I2C0_SDA_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) + +/* I2C0_SMBA */ +#define I2C0_SMBA_PA1 \ + GD32_PINMUX_AF('A', 1, AF6) +#define I2C0_SMBA_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) + +/* I2S0_CK */ +#define I2S0_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define I2S0_CK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define I2S0_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_SD */ +#define I2S0_SD_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define I2S0_SD_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define I2S0_SD_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define I2S0_SD_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_WS */ +#define I2S0_WS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define I2S0_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define I2S0_WS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) + +/* I2S_CKIN */ +#define I2S_CKIN_PA12 \ + GD32_PINMUX_AF('A', 12, AF5) + +/* OSC32EN */ +#define OSC32EN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* OSCEN */ +#define OSCEN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* SPI0_MISO */ +#define SPI0_MISO_PA6 \ + GD32_PINMUX_AF('A', 6, AF0) +#define SPI0_MISO_PA11 \ + GD32_PINMUX_AF('A', 11, AF0) +#define SPI0_MISO_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define SPI0_MOSI_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define SPI0_MOSI_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define SPI0_MOSI_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_NSS */ +#define SPI0_NSS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define SPI0_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define SPI0_NSS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) + +/* SPI0_SCK */ +#define SPI0_SCK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define SPI0_SCK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define SPI0_SCK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI1_IO2 */ +#define SPI1_IO2_PA1 \ + GD32_PINMUX_AF('A', 1, AF3) +#define SPI1_IO2_PA5 \ + GD32_PINMUX_AF('A', 5, AF3) +#define SPI1_IO2_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) + +/* SPI1_IO3 */ +#define SPI1_IO3_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI1_IO3_PA6 \ + GD32_PINMUX_AF('A', 6, AF3) +#define SPI1_IO3_PA12 \ + GD32_PINMUX_AF('A', 12, AF3) + +/* SPI1_MISO */ +#define SPI1_MISO_PA3 \ + GD32_PINMUX_AF('A', 3, AF0) +#define SPI1_MISO_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) + +/* SPI1_MOSI */ +#define SPI1_MOSI_PA4 \ + GD32_PINMUX_AF('A', 4, AF3) +#define SPI1_MOSI_PA10 \ + GD32_PINMUX_AF('A', 10, AF0) +#define SPI1_MOSI_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF3) + +/* SPI1_SCK */ +#define SPI1_SCK_PA0 \ + GD32_PINMUX_AF('A', 0, AF0) + +/* SWCLK */ +#define SWCLK_PA14 \ + GD32_PINMUX_AF('A', 14, AF0) + +/* SWDIO */ +#define SWDIO_PA13 \ + GD32_PINMUX_AF('A', 13, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) + +/* TIMER0_BRKIN1 */ +#define TIMER0_BRKIN1_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define TIMER0_BRKIN1_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF5) +#define TIMER0_CH0_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) +#define TIMER0_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) +#define TIMER0_CH0_PA14 \ + GD32_PINMUX_AF('A', 14, AF10) + +/* TIMER0_CH0_ON */ +#define TIMER0_CH0_ON_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) +#define TIMER0_CH0_ON_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA1 \ + GD32_PINMUX_AF('A', 1, AF5) +#define TIMER0_CH1_PA9 \ + GD32_PINMUX_AF('A', 9, AF2) +#define TIMER0_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH1_ON */ +#define TIMER0_CH1_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF2) +#define TIMER0_CH1_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF8) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF5) +#define TIMER0_CH2_PA10 \ + GD32_PINMUX_AF('A', 10, AF2) +#define TIMER0_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH2_ON */ +#define TIMER0_CH2_ON_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) +#define TIMER0_CH2_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define TIMER0_CH3_PA11 \ + GD32_PINMUX_AF('A', 11, AF2) +#define TIMER0_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER0_CH3_PF2 \ + GD32_PINMUX_AF('F', 2, AF1) + +/* TIMER0_ETI */ +#define TIMER0_ETI_PA12 \ + GD32_PINMUX_AF('A', 12, AF2) +#define TIMER0_ETI_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) +#define TIMER0_ETI_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER13_CH0 */ +#define TIMER13_CH0_PA4 \ + GD32_PINMUX_AF('A', 4, AF4) +#define TIMER13_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF4) +#define TIMER13_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF12) + +/* TIMER15_BRKIN0 */ +#define TIMER15_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER15_CH0 */ +#define TIMER15_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF2) +#define TIMER15_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) +#define TIMER15_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER15_CH0_ON */ +#define TIMER15_CH0_ON_PA2 \ + GD32_PINMUX_AF('A', 2, AF2) +#define TIMER15_CH0_ON_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_BRKIN0 */ +#define TIMER16_BRKIN0_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define TIMER16_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_CH0 */ +#define TIMER16_CH0_PA1 \ + GD32_PINMUX_AF('A', 1, AF2) +#define TIMER16_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) +#define TIMER16_CH0_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER16_CH0_ON */ +#define TIMER16_CH0_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define TIMER16_CH0_ON_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_CH0 */ +#define TIMER2_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF1) +#define TIMER2_CH0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_CH1 */ +#define TIMER2_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER2_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH1_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER2_CH2 */ +#define TIMER2_CH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF10) +#define TIMER2_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH2_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) + +/* TIMER2_CH3 */ +#define TIMER2_CH3_PA8 \ + GD32_PINMUX_AF('A', 8, AF11) +#define TIMER2_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_ETI */ +#define TIMER2_ETI_PA2 \ + GD32_PINMUX_AF('A', 2, AF3) +#define TIMER2_ETI_PA9 \ + GD32_PINMUX_AF('A', 9, AF3) +#define TIMER2_ETI_PA13 \ + GD32_PINMUX_AF('A', 13, AF3) + +/* USART0_CTS */ +#define USART0_CTS_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) +#define USART0_CTS_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RTS_DE_CK */ +#define USART0_RTS_DE_CK_PA12 \ + GD32_PINMUX_AF('A', 12, AF1) +#define USART0_RTS_DE_CK_PA14 \ + GD32_PINMUX_AF('A', 14, AF12) +#define USART0_RTS_DE_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RX */ +#define USART0_RX_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define USART0_RX_PA8 \ + GD32_PINMUX_AF('A', 8, AF13) +#define USART0_RX_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) +#define USART0_RX_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) + +/* USART0_TX */ +#define USART0_TX_PA0 \ + GD32_PINMUX_AF('A', 0, AF4) +#define USART0_TX_PA9 \ + GD32_PINMUX_AF('A', 9, AF1) +#define USART0_TX_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) +#define USART0_TX_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_CTS */ +#define USART1_CTS_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) +#define USART1_CTS_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) + +/* USART1_RTS_DE_CK */ +#define USART1_RTS_DE_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) +#define USART1_RTS_DE_CK_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_RX */ +#define USART1_RX_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) +#define USART1_RX_PA5 \ + GD32_PINMUX_AF('A', 5, AF1) +#define USART1_RX_PA13 \ + GD32_PINMUX_AF('A', 13, AF4) +#define USART1_RX_PA14 \ + GD32_PINMUX_AF('A', 14, AF9) + +/* USART1_TX */ +#define USART1_TX_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) +#define USART1_TX_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) +#define USART1_TX_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) +#define USART1_TX_PA14 \ + GD32_PINMUX_AF('A', 14, AF1) diff --git a/include/dt-bindings/pinctrl/gd32c231g(6-8)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32c231g(6-8)xx-pinctrl.h new file mode 100644 index 0000000..58bf6a1 --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32c231g(6-8)xx-pinctrl.h @@ -0,0 +1,635 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC_IN0 */ +#define ADC_IN0_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) + +/* ADC_IN1 */ +#define ADC_IN1_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) + +/* ADC_IN12 */ +#define ADC_IN12_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) + +/* ADC_IN2 */ +#define ADC_IN2_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) + +/* ADC_IN3 */ +#define ADC_IN3_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC_IN4 */ +#define ADC_IN4_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC_IN5 */ +#define ADC_IN5_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) + +/* ADC_IN6 */ +#define ADC_IN6_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) + +/* ADC_IN7 */ +#define ADC_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* ADC_IN8 */ +#define ADC_IN8_PB0 \ + GD32_PINMUX_AF('B', 0, ANALOG) + +/* ADC_IN9 */ +#define ADC_IN9_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) + +/* ANALOG */ +#define ANALOG_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) +#define ANALOG_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) +#define ANALOG_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) +#define ANALOG_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) +#define ANALOG_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) +#define ANALOG_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) +#define ANALOG_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) +#define ANALOG_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) +#define ANALOG_PA8 \ + GD32_PINMUX_AF('A', 8, ANALOG) +#define ANALOG_PA9 \ + GD32_PINMUX_AF('A', 9, ANALOG) +#define ANALOG_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) +#define ANALOG_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) +#define ANALOG_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) +#define ANALOG_PA13 \ + GD32_PINMUX_AF('A', 13, ANALOG) +#define ANALOG_PA14 \ + GD32_PINMUX_AF('A', 14, ANALOG) +#define ANALOG_PA15 \ + GD32_PINMUX_AF('A', 15, ANALOG) +#define ANALOG_PB0 \ + GD32_PINMUX_AF('B', 0, ANALOG) +#define ANALOG_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) +#define ANALOG_PB3 \ + GD32_PINMUX_AF('B', 3, ANALOG) +#define ANALOG_PB4 \ + GD32_PINMUX_AF('B', 4, ANALOG) +#define ANALOG_PB5 \ + GD32_PINMUX_AF('B', 5, ANALOG) +#define ANALOG_PB6 \ + GD32_PINMUX_AF('B', 6, ANALOG) +#define ANALOG_PB7 \ + GD32_PINMUX_AF('B', 7, ANALOG) +#define ANALOG_PB8 \ + GD32_PINMUX_AF('B', 8, ANALOG) +#define ANALOG_PC6 \ + GD32_PINMUX_AF('C', 6, ANALOG) +#define ANALOG_PC14 \ + GD32_PINMUX_AF('C', 14, ANALOG) +#define ANALOG_PC15 \ + GD32_PINMUX_AF('C', 15, ANALOG) +#define ANALOG_PF2 \ + GD32_PINMUX_AF('F', 2, ANALOG) + +/* CK_OUT0 */ +#define CK_OUT0_PA8 \ + GD32_PINMUX_AF('A', 8, AF0) +#define CK_OUT0_PA9 \ + GD32_PINMUX_AF('A', 9, AF0) +#define CK_OUT0_PF2 \ + GD32_PINMUX_AF('F', 2, AF0) + +/* CK_OUT1 */ +#define CK_OUT1_PA8 \ + GD32_PINMUX_AF('A', 8, AF14) +#define CK_OUT1_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define CK_OUT1_PA14 \ + GD32_PINMUX_AF('A', 14, AF11) +#define CK_OUT1_PA15 \ + GD32_PINMUX_AF('A', 15, AF3) + +/* CMP0_OUT */ +#define CMP0_OUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF7) +#define CMP0_OUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF7) +#define CMP0_OUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) +#define CMP0_OUT_PB0 \ + GD32_PINMUX_AF('B', 0, AF7) + +/* CMP1_OUT */ +#define CMP1_OUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) +#define CMP1_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) +#define CMP1_OUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF7) +#define CMP1_OUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF7) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF15) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF15) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF15) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF15) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF15) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF15) +#define EVENTOUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF15) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF15) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF15) +#define EVENTOUT_PA9 \ + GD32_PINMUX_AF('A', 9, AF15) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF15) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF15) +#define EVENTOUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF15) +#define EVENTOUT_PA13 \ + GD32_PINMUX_AF('A', 13, AF15) +#define EVENTOUT_PA14 \ + GD32_PINMUX_AF('A', 14, AF15) +#define EVENTOUT_PA15 \ + GD32_PINMUX_AF('A', 15, AF15) +#define EVENTOUT_PB0 \ + GD32_PINMUX_AF('B', 0, AF15) +#define EVENTOUT_PB1 \ + GD32_PINMUX_AF('B', 1, AF15) +#define EVENTOUT_PB3 \ + GD32_PINMUX_AF('B', 3, AF15) +#define EVENTOUT_PB4 \ + GD32_PINMUX_AF('B', 4, AF15) +#define EVENTOUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF15) +#define EVENTOUT_PB6 \ + GD32_PINMUX_AF('B', 6, AF15) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF15) +#define EVENTOUT_PB8 \ + GD32_PINMUX_AF('B', 8, AF15) +#define EVENTOUT_PC6 \ + GD32_PINMUX_AF('C', 6, AF15) +#define EVENTOUT_PC14 \ + GD32_PINMUX_AF('C', 14, AF15) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF15) +#define EVENTOUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF15) + +/* I2C0_SCL */ +#define I2C0_SCL_PA9 \ + GD32_PINMUX_AF('A', 9, AF6) +#define I2C0_SCL_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) +#define I2C0_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) +#define I2C0_SCL_PB8 \ + GD32_PINMUX_AF('B', 8, AF4) + +/* I2C0_SDA */ +#define I2C0_SDA_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) +#define I2C0_SDA_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) + +/* I2C0_SMBA */ +#define I2C0_SMBA_PA1 \ + GD32_PINMUX_AF('A', 1, AF6) +#define I2C0_SMBA_PB5 \ + GD32_PINMUX_AF('B', 5, AF6) +#define I2C0_SMBA_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) + +/* I2S0_CK */ +#define I2S0_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define I2S0_CK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define I2S0_CK_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) +#define I2S0_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_SD */ +#define I2S0_SD_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define I2S0_SD_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define I2S0_SD_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define I2S0_SD_PB5 \ + GD32_PINMUX_AF('B', 5, AF0) +#define I2S0_SD_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_WS */ +#define I2S0_WS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define I2S0_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define I2S0_WS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) +#define I2S0_WS_PA15 \ + GD32_PINMUX_AF('A', 15, AF0) +#define I2S0_WS_PB0 \ + GD32_PINMUX_AF('B', 0, AF0) + +/* I2S_CKIN */ +#define I2S_CKIN_PA12 \ + GD32_PINMUX_AF('A', 12, AF5) + +/* OSC32EN */ +#define OSC32EN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* OSCEN */ +#define OSCEN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* SPI0_MISO */ +#define SPI0_MISO_PA6 \ + GD32_PINMUX_AF('A', 6, AF0) +#define SPI0_MISO_PA11 \ + GD32_PINMUX_AF('A', 11, AF0) +#define SPI0_MISO_PB4 \ + GD32_PINMUX_AF('B', 4, AF0) +#define SPI0_MISO_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define SPI0_MOSI_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define SPI0_MOSI_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define SPI0_MOSI_PB5 \ + GD32_PINMUX_AF('B', 5, AF0) +#define SPI0_MOSI_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_NSS */ +#define SPI0_NSS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define SPI0_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define SPI0_NSS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) +#define SPI0_NSS_PA15 \ + GD32_PINMUX_AF('A', 15, AF0) +#define SPI0_NSS_PB0 \ + GD32_PINMUX_AF('B', 0, AF0) + +/* SPI0_SCK */ +#define SPI0_SCK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define SPI0_SCK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define SPI0_SCK_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) +#define SPI0_SCK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI1_IO2 */ +#define SPI1_IO2_PA1 \ + GD32_PINMUX_AF('A', 1, AF3) +#define SPI1_IO2_PA5 \ + GD32_PINMUX_AF('A', 5, AF3) +#define SPI1_IO2_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) + +/* SPI1_IO3 */ +#define SPI1_IO3_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI1_IO3_PA6 \ + GD32_PINMUX_AF('A', 6, AF3) +#define SPI1_IO3_PA12 \ + GD32_PINMUX_AF('A', 12, AF3) + +/* SPI1_MISO */ +#define SPI1_MISO_PA3 \ + GD32_PINMUX_AF('A', 3, AF0) +#define SPI1_MISO_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) +#define SPI1_MISO_PB5 \ + GD32_PINMUX_AF('B', 5, AF4) + +/* SPI1_MOSI */ +#define SPI1_MOSI_PA4 \ + GD32_PINMUX_AF('A', 4, AF3) +#define SPI1_MOSI_PA10 \ + GD32_PINMUX_AF('A', 10, AF0) +#define SPI1_MOSI_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF3) + +/* SPI1_SCK */ +#define SPI1_SCK_PA0 \ + GD32_PINMUX_AF('A', 0, AF0) +#define SPI1_SCK_PB8 \ + GD32_PINMUX_AF('B', 8, AF5) + +/* SWCLK */ +#define SWCLK_PA14 \ + GD32_PINMUX_AF('A', 14, AF0) + +/* SWDIO */ +#define SWDIO_PA13 \ + GD32_PINMUX_AF('A', 13, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) + +/* TIMER0_BRKIN1 */ +#define TIMER0_BRKIN1_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define TIMER0_BRKIN1_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF5) +#define TIMER0_CH0_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) +#define TIMER0_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) +#define TIMER0_CH0_PA14 \ + GD32_PINMUX_AF('A', 14, AF10) +#define TIMER0_CH0_PA15 \ + GD32_PINMUX_AF('A', 15, AF2) + +/* TIMER0_CH0_ON */ +#define TIMER0_CH0_ON_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) +#define TIMER0_CH0_ON_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA1 \ + GD32_PINMUX_AF('A', 1, AF5) +#define TIMER0_CH1_PA9 \ + GD32_PINMUX_AF('A', 9, AF2) +#define TIMER0_CH1_PB3 \ + GD32_PINMUX_AF('B', 3, AF1) +#define TIMER0_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH1_ON */ +#define TIMER0_CH1_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF2) +#define TIMER0_CH1_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF8) +#define TIMER0_CH1_ON_PB0 \ + GD32_PINMUX_AF('B', 0, AF2) +#define TIMER0_CH1_ON_PB1 \ + GD32_PINMUX_AF('B', 1, AF5) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF5) +#define TIMER0_CH2_PA10 \ + GD32_PINMUX_AF('A', 10, AF2) +#define TIMER0_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH2_ON */ +#define TIMER0_CH2_ON_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) +#define TIMER0_CH2_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) +#define TIMER0_CH2_ON_PB1 \ + GD32_PINMUX_AF('B', 1, AF2) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define TIMER0_CH3_PA11 \ + GD32_PINMUX_AF('A', 11, AF2) +#define TIMER0_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER0_CH3_PF2 \ + GD32_PINMUX_AF('F', 2, AF1) + +/* TIMER0_ETI */ +#define TIMER0_ETI_PA12 \ + GD32_PINMUX_AF('A', 12, AF2) +#define TIMER0_ETI_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) +#define TIMER0_ETI_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER13_CH0 */ +#define TIMER13_CH0_PA4 \ + GD32_PINMUX_AF('A', 4, AF4) +#define TIMER13_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF4) +#define TIMER13_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF12) +#define TIMER13_CH0_PB1 \ + GD32_PINMUX_AF('B', 1, AF0) + +/* TIMER15_BRKIN0 */ +#define TIMER15_BRKIN0_PB5 \ + GD32_PINMUX_AF('B', 5, AF2) +#define TIMER15_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER15_CH0 */ +#define TIMER15_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF2) +#define TIMER15_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) +#define TIMER15_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER15_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) + +/* TIMER15_CH0_ON */ +#define TIMER15_CH0_ON_PA2 \ + GD32_PINMUX_AF('A', 2, AF2) +#define TIMER15_CH0_ON_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_BRKIN0 */ +#define TIMER16_BRKIN0_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define TIMER16_BRKIN0_PB4 \ + GD32_PINMUX_AF('B', 4, AF5) +#define TIMER16_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_CH0 */ +#define TIMER16_CH0_PA1 \ + GD32_PINMUX_AF('A', 1, AF2) +#define TIMER16_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) +#define TIMER16_CH0_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER16_CH0_ON */ +#define TIMER16_CH0_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define TIMER16_CH0_ON_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_CH0 */ +#define TIMER2_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF1) +#define TIMER2_CH0_PB4 \ + GD32_PINMUX_AF('B', 4, AF1) +#define TIMER2_CH0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER2_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER2_CH0_PC6 \ + GD32_PINMUX_AF('C', 6, AF2) + +/* TIMER2_CH1 */ +#define TIMER2_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER2_CH1_PB3 \ + GD32_PINMUX_AF('B', 3, AF3) +#define TIMER2_CH1_PB5 \ + GD32_PINMUX_AF('B', 5, AF1) +#define TIMER2_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH1_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER2_CH2 */ +#define TIMER2_CH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF10) +#define TIMER2_CH2_PB0 \ + GD32_PINMUX_AF('B', 0, AF1) +#define TIMER2_CH2_PB5 \ + GD32_PINMUX_AF('B', 5, AF3) +#define TIMER2_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH2_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) + +/* TIMER2_CH3 */ +#define TIMER2_CH3_PA8 \ + GD32_PINMUX_AF('A', 8, AF11) +#define TIMER2_CH3_PB1 \ + GD32_PINMUX_AF('B', 1, AF1) +#define TIMER2_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_ETI */ +#define TIMER2_ETI_PA2 \ + GD32_PINMUX_AF('A', 2, AF3) +#define TIMER2_ETI_PA9 \ + GD32_PINMUX_AF('A', 9, AF3) +#define TIMER2_ETI_PA13 \ + GD32_PINMUX_AF('A', 13, AF3) + +/* USART0_CTS */ +#define USART0_CTS_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) +#define USART0_CTS_PB4 \ + GD32_PINMUX_AF('B', 4, AF4) +#define USART0_CTS_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RTS_DE_CK */ +#define USART0_RTS_DE_CK_PA12 \ + GD32_PINMUX_AF('A', 12, AF1) +#define USART0_RTS_DE_CK_PA14 \ + GD32_PINMUX_AF('A', 14, AF12) +#define USART0_RTS_DE_CK_PA15 \ + GD32_PINMUX_AF('A', 15, AF4) +#define USART0_RTS_DE_CK_PB3 \ + GD32_PINMUX_AF('B', 3, AF4) +#define USART0_RTS_DE_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RX */ +#define USART0_RX_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define USART0_RX_PA8 \ + GD32_PINMUX_AF('A', 8, AF13) +#define USART0_RX_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) +#define USART0_RX_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) + +/* USART0_TX */ +#define USART0_TX_PA0 \ + GD32_PINMUX_AF('A', 0, AF4) +#define USART0_TX_PA9 \ + GD32_PINMUX_AF('A', 9, AF1) +#define USART0_TX_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) +#define USART0_TX_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_CTS */ +#define USART1_CTS_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) +#define USART1_CTS_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) +#define USART1_CTS_PB8 \ + GD32_PINMUX_AF('B', 8, AF7) + +/* USART1_RTS_DE_CK */ +#define USART1_RTS_DE_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) +#define USART1_RTS_DE_CK_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_RX */ +#define USART1_RX_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) +#define USART1_RX_PA5 \ + GD32_PINMUX_AF('A', 5, AF1) +#define USART1_RX_PA13 \ + GD32_PINMUX_AF('A', 13, AF4) +#define USART1_RX_PA14 \ + GD32_PINMUX_AF('A', 14, AF9) +#define USART1_RX_PA15 \ + GD32_PINMUX_AF('A', 15, AF1) + +/* USART1_TX */ +#define USART1_TX_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) +#define USART1_TX_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) +#define USART1_TX_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) +#define USART1_TX_PA14 \ + GD32_PINMUX_AF('A', 14, AF1) diff --git a/include/dt-bindings/pinctrl/gd32c231k(6-8)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32c231k(6-8)xx-pinctrl.h new file mode 100644 index 0000000..49e32fe --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32c231k(6-8)xx-pinctrl.h @@ -0,0 +1,689 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC_IN0 */ +#define ADC_IN0_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) + +/* ADC_IN1 */ +#define ADC_IN1_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) + +/* ADC_IN10 */ +#define ADC_IN10_PB2 \ + GD32_PINMUX_AF('B', 2, ANALOG) + +/* ADC_IN12 */ +#define ADC_IN12_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) + +/* ADC_IN2 */ +#define ADC_IN2_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) + +/* ADC_IN3 */ +#define ADC_IN3_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC_IN4 */ +#define ADC_IN4_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC_IN5 */ +#define ADC_IN5_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) + +/* ADC_IN6 */ +#define ADC_IN6_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) + +/* ADC_IN7 */ +#define ADC_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* ADC_IN8 */ +#define ADC_IN8_PB0 \ + GD32_PINMUX_AF('B', 0, ANALOG) + +/* ADC_IN9 */ +#define ADC_IN9_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) + +/* ANALOG */ +#define ANALOG_PA0 \ + GD32_PINMUX_AF('A', 0, ANALOG) +#define ANALOG_PA1 \ + GD32_PINMUX_AF('A', 1, ANALOG) +#define ANALOG_PA2 \ + GD32_PINMUX_AF('A', 2, ANALOG) +#define ANALOG_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) +#define ANALOG_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) +#define ANALOG_PA5 \ + GD32_PINMUX_AF('A', 5, ANALOG) +#define ANALOG_PA6 \ + GD32_PINMUX_AF('A', 6, ANALOG) +#define ANALOG_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) +#define ANALOG_PA8 \ + GD32_PINMUX_AF('A', 8, ANALOG) +#define ANALOG_PA9 \ + GD32_PINMUX_AF('A', 9, ANALOG) +#define ANALOG_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) +#define ANALOG_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) +#define ANALOG_PA12 \ + GD32_PINMUX_AF('A', 12, ANALOG) +#define ANALOG_PA13 \ + GD32_PINMUX_AF('A', 13, ANALOG) +#define ANALOG_PA14 \ + GD32_PINMUX_AF('A', 14, ANALOG) +#define ANALOG_PA15 \ + GD32_PINMUX_AF('A', 15, ANALOG) +#define ANALOG_PB0 \ + GD32_PINMUX_AF('B', 0, ANALOG) +#define ANALOG_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) +#define ANALOG_PB2 \ + GD32_PINMUX_AF('B', 2, ANALOG) +#define ANALOG_PB3 \ + GD32_PINMUX_AF('B', 3, ANALOG) +#define ANALOG_PB4 \ + GD32_PINMUX_AF('B', 4, ANALOG) +#define ANALOG_PB5 \ + GD32_PINMUX_AF('B', 5, ANALOG) +#define ANALOG_PB6 \ + GD32_PINMUX_AF('B', 6, ANALOG) +#define ANALOG_PB7 \ + GD32_PINMUX_AF('B', 7, ANALOG) +#define ANALOG_PB8 \ + GD32_PINMUX_AF('B', 8, ANALOG) +#define ANALOG_PB9 \ + GD32_PINMUX_AF('B', 9, ANALOG) +#define ANALOG_PC6 \ + GD32_PINMUX_AF('C', 6, ANALOG) +#define ANALOG_PC14 \ + GD32_PINMUX_AF('C', 14, ANALOG) +#define ANALOG_PC15 \ + GD32_PINMUX_AF('C', 15, ANALOG) +#define ANALOG_PF2 \ + GD32_PINMUX_AF('F', 2, ANALOG) + +/* CK_OUT0 */ +#define CK_OUT0_PA8 \ + GD32_PINMUX_AF('A', 8, AF0) +#define CK_OUT0_PA9 \ + GD32_PINMUX_AF('A', 9, AF0) +#define CK_OUT0_PF2 \ + GD32_PINMUX_AF('F', 2, AF0) + +/* CK_OUT1 */ +#define CK_OUT1_PA8 \ + GD32_PINMUX_AF('A', 8, AF14) +#define CK_OUT1_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define CK_OUT1_PA14 \ + GD32_PINMUX_AF('A', 14, AF11) +#define CK_OUT1_PA15 \ + GD32_PINMUX_AF('A', 15, AF3) +#define CK_OUT1_PB2 \ + GD32_PINMUX_AF('B', 2, AF3) + +/* CMP0_OUT */ +#define CMP0_OUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF7) +#define CMP0_OUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF7) +#define CMP0_OUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) +#define CMP0_OUT_PB0 \ + GD32_PINMUX_AF('B', 0, AF7) + +/* CMP1_OUT */ +#define CMP1_OUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) +#define CMP1_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) +#define CMP1_OUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF7) +#define CMP1_OUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF7) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF15) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF15) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF15) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF15) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF15) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF15) +#define EVENTOUT_PA6 \ + GD32_PINMUX_AF('A', 6, AF15) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF15) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF15) +#define EVENTOUT_PA9 \ + GD32_PINMUX_AF('A', 9, AF15) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF15) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF15) +#define EVENTOUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF15) +#define EVENTOUT_PA13 \ + GD32_PINMUX_AF('A', 13, AF15) +#define EVENTOUT_PA14 \ + GD32_PINMUX_AF('A', 14, AF15) +#define EVENTOUT_PA15 \ + GD32_PINMUX_AF('A', 15, AF15) +#define EVENTOUT_PB0 \ + GD32_PINMUX_AF('B', 0, AF15) +#define EVENTOUT_PB1 \ + GD32_PINMUX_AF('B', 1, AF15) +#define EVENTOUT_PB2 \ + GD32_PINMUX_AF('B', 2, AF15) +#define EVENTOUT_PB3 \ + GD32_PINMUX_AF('B', 3, AF15) +#define EVENTOUT_PB4 \ + GD32_PINMUX_AF('B', 4, AF15) +#define EVENTOUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF15) +#define EVENTOUT_PB6 \ + GD32_PINMUX_AF('B', 6, AF15) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF15) +#define EVENTOUT_PB8 \ + GD32_PINMUX_AF('B', 8, AF15) +#define EVENTOUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF15) +#define EVENTOUT_PC6 \ + GD32_PINMUX_AF('C', 6, AF15) +#define EVENTOUT_PC14 \ + GD32_PINMUX_AF('C', 14, AF15) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF15) +#define EVENTOUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF15) + +/* I2C0_SCL */ +#define I2C0_SCL_PA9 \ + GD32_PINMUX_AF('A', 9, AF6) +#define I2C0_SCL_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) +#define I2C0_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) +#define I2C0_SCL_PB8 \ + GD32_PINMUX_AF('B', 8, AF4) + +/* I2C0_SDA */ +#define I2C0_SDA_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) +#define I2C0_SDA_PB7 \ + GD32_PINMUX_AF('B', 7, AF4) +#define I2C0_SDA_PB9 \ + GD32_PINMUX_AF('B', 9, AF4) + +/* I2C0_SMBA */ +#define I2C0_SMBA_PA1 \ + GD32_PINMUX_AF('A', 1, AF6) +#define I2C0_SMBA_PB5 \ + GD32_PINMUX_AF('B', 5, AF6) +#define I2C0_SMBA_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) + +/* I2C1_SCL */ +#define I2C1_SCL_PA11 \ + GD32_PINMUX_AF('A', 11, AF6) + +/* I2C1_SDA */ +#define I2C1_SDA_PA12 \ + GD32_PINMUX_AF('A', 12, AF6) + +/* I2S0_CK */ +#define I2S0_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define I2S0_CK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define I2S0_CK_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) +#define I2S0_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_SD */ +#define I2S0_SD_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define I2S0_SD_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define I2S0_SD_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define I2S0_SD_PB5 \ + GD32_PINMUX_AF('B', 5, AF0) +#define I2S0_SD_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S0_WS */ +#define I2S0_WS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define I2S0_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define I2S0_WS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) +#define I2S0_WS_PA15 \ + GD32_PINMUX_AF('A', 15, AF0) +#define I2S0_WS_PB0 \ + GD32_PINMUX_AF('B', 0, AF0) + +/* I2S_CKIN */ +#define I2S_CKIN_PA12 \ + GD32_PINMUX_AF('A', 12, AF5) + +/* OSC32EN */ +#define OSC32EN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* OSCEN */ +#define OSCEN_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* SPI0_MISO */ +#define SPI0_MISO_PA6 \ + GD32_PINMUX_AF('A', 6, AF0) +#define SPI0_MISO_PA11 \ + GD32_PINMUX_AF('A', 11, AF0) +#define SPI0_MISO_PB4 \ + GD32_PINMUX_AF('B', 4, AF0) +#define SPI0_MISO_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF0) +#define SPI0_MOSI_PA7 \ + GD32_PINMUX_AF('A', 7, AF0) +#define SPI0_MOSI_PA12 \ + GD32_PINMUX_AF('A', 12, AF0) +#define SPI0_MOSI_PB5 \ + GD32_PINMUX_AF('B', 5, AF0) +#define SPI0_MOSI_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI0_NSS */ +#define SPI0_NSS_PA4 \ + GD32_PINMUX_AF('A', 4, AF0) +#define SPI0_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) +#define SPI0_NSS_PA14 \ + GD32_PINMUX_AF('A', 14, AF7) +#define SPI0_NSS_PA15 \ + GD32_PINMUX_AF('A', 15, AF0) +#define SPI0_NSS_PB0 \ + GD32_PINMUX_AF('B', 0, AF0) + +/* SPI0_SCK */ +#define SPI0_SCK_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) +#define SPI0_SCK_PA5 \ + GD32_PINMUX_AF('A', 5, AF0) +#define SPI0_SCK_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) +#define SPI0_SCK_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI1_IO2 */ +#define SPI1_IO2_PA1 \ + GD32_PINMUX_AF('A', 1, AF3) +#define SPI1_IO2_PA5 \ + GD32_PINMUX_AF('A', 5, AF3) +#define SPI1_IO2_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) + +/* SPI1_IO3 */ +#define SPI1_IO3_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI1_IO3_PA6 \ + GD32_PINMUX_AF('A', 6, AF3) +#define SPI1_IO3_PA12 \ + GD32_PINMUX_AF('A', 12, AF3) + +/* SPI1_MISO */ +#define SPI1_MISO_PA3 \ + GD32_PINMUX_AF('A', 3, AF0) +#define SPI1_MISO_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) +#define SPI1_MISO_PB2 \ + GD32_PINMUX_AF('B', 2, AF1) +#define SPI1_MISO_PB5 \ + GD32_PINMUX_AF('B', 5, AF4) + +/* SPI1_MOSI */ +#define SPI1_MOSI_PA4 \ + GD32_PINMUX_AF('A', 4, AF3) +#define SPI1_MOSI_PA10 \ + GD32_PINMUX_AF('A', 10, AF0) +#define SPI1_MOSI_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF3) +#define SPI1_NSS_PB9 \ + GD32_PINMUX_AF('B', 9, AF5) + +/* SPI1_SCK */ +#define SPI1_SCK_PA0 \ + GD32_PINMUX_AF('A', 0, AF0) +#define SPI1_SCK_PB8 \ + GD32_PINMUX_AF('B', 8, AF5) + +/* SWCLK */ +#define SWCLK_PA14 \ + GD32_PINMUX_AF('A', 14, AF0) + +/* SWDIO */ +#define SWDIO_PA13 \ + GD32_PINMUX_AF('A', 13, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) + +/* TIMER0_BRKIN1 */ +#define TIMER0_BRKIN1_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define TIMER0_BRKIN1_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF5) +#define TIMER0_CH0_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) +#define TIMER0_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) +#define TIMER0_CH0_PA14 \ + GD32_PINMUX_AF('A', 14, AF10) +#define TIMER0_CH0_PA15 \ + GD32_PINMUX_AF('A', 15, AF2) + +/* TIMER0_CH0_ON */ +#define TIMER0_CH0_ON_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) +#define TIMER0_CH0_ON_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA1 \ + GD32_PINMUX_AF('A', 1, AF5) +#define TIMER0_CH1_PA9 \ + GD32_PINMUX_AF('A', 9, AF2) +#define TIMER0_CH1_PB3 \ + GD32_PINMUX_AF('B', 3, AF1) +#define TIMER0_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH1_ON */ +#define TIMER0_CH1_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF2) +#define TIMER0_CH1_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF8) +#define TIMER0_CH1_ON_PB0 \ + GD32_PINMUX_AF('B', 0, AF2) +#define TIMER0_CH1_ON_PB1 \ + GD32_PINMUX_AF('B', 1, AF5) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF5) +#define TIMER0_CH2_PA10 \ + GD32_PINMUX_AF('A', 10, AF2) +#define TIMER0_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF1) + +/* TIMER0_CH2_ON */ +#define TIMER0_CH2_ON_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) +#define TIMER0_CH2_ON_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) +#define TIMER0_CH2_ON_PB1 \ + GD32_PINMUX_AF('B', 1, AF2) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define TIMER0_CH3_PA11 \ + GD32_PINMUX_AF('A', 11, AF2) +#define TIMER0_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER0_CH3_PF2 \ + GD32_PINMUX_AF('F', 2, AF1) + +/* TIMER0_ETI */ +#define TIMER0_ETI_PA12 \ + GD32_PINMUX_AF('A', 12, AF2) +#define TIMER0_ETI_PC14 \ + GD32_PINMUX_AF('C', 14, AF1) +#define TIMER0_ETI_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER13_CH0 */ +#define TIMER13_CH0_PA4 \ + GD32_PINMUX_AF('A', 4, AF4) +#define TIMER13_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF4) +#define TIMER13_CH0_PA8 \ + GD32_PINMUX_AF('A', 8, AF12) +#define TIMER13_CH0_PB1 \ + GD32_PINMUX_AF('B', 1, AF0) + +/* TIMER15_BRKIN0 */ +#define TIMER15_BRKIN0_PB5 \ + GD32_PINMUX_AF('B', 5, AF2) +#define TIMER15_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER15_CH0 */ +#define TIMER15_CH0_PA0 \ + GD32_PINMUX_AF('A', 0, AF2) +#define TIMER15_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) +#define TIMER15_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER15_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) + +/* TIMER15_CH0_ON */ +#define TIMER15_CH0_ON_PA2 \ + GD32_PINMUX_AF('A', 2, AF2) +#define TIMER15_CH0_ON_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_BRKIN0 */ +#define TIMER16_BRKIN0_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define TIMER16_BRKIN0_PB4 \ + GD32_PINMUX_AF('B', 4, AF5) +#define TIMER16_BRKIN0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) + +/* TIMER16_CH0 */ +#define TIMER16_CH0_PA1 \ + GD32_PINMUX_AF('A', 1, AF2) +#define TIMER16_CH0_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) +#define TIMER16_CH0_PB9 \ + GD32_PINMUX_AF('B', 9, AF2) +#define TIMER16_CH0_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER16_CH0_ON */ +#define TIMER16_CH0_ON_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define TIMER16_CH0_ON_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_CH0 */ +#define TIMER2_CH0_PA6 \ + GD32_PINMUX_AF('A', 6, AF1) +#define TIMER2_CH0_PB4 \ + GD32_PINMUX_AF('B', 4, AF1) +#define TIMER2_CH0_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER2_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER2_CH0_PC6 \ + GD32_PINMUX_AF('C', 6, AF2) + +/* TIMER2_CH1 */ +#define TIMER2_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER2_CH1_PB3 \ + GD32_PINMUX_AF('B', 3, AF3) +#define TIMER2_CH1_PB5 \ + GD32_PINMUX_AF('B', 5, AF1) +#define TIMER2_CH1_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH1_PB9 \ + GD32_PINMUX_AF('B', 9, AF2) +#define TIMER2_CH1_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER2_CH2 */ +#define TIMER2_CH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF10) +#define TIMER2_CH2_PB0 \ + GD32_PINMUX_AF('B', 0, AF1) +#define TIMER2_CH2_PB5 \ + GD32_PINMUX_AF('B', 5, AF3) +#define TIMER2_CH2_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER2_CH2_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) + +/* TIMER2_CH3 */ +#define TIMER2_CH3_PA8 \ + GD32_PINMUX_AF('A', 8, AF11) +#define TIMER2_CH3_PB1 \ + GD32_PINMUX_AF('B', 1, AF1) +#define TIMER2_CH3_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) + +/* TIMER2_ETI */ +#define TIMER2_ETI_PA2 \ + GD32_PINMUX_AF('A', 2, AF3) +#define TIMER2_ETI_PA9 \ + GD32_PINMUX_AF('A', 9, AF3) +#define TIMER2_ETI_PA13 \ + GD32_PINMUX_AF('A', 13, AF3) + +/* USART0_CTS */ +#define USART0_CTS_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) +#define USART0_CTS_PB4 \ + GD32_PINMUX_AF('B', 4, AF4) +#define USART0_CTS_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RTS_DE_CK */ +#define USART0_RTS_DE_CK_PA12 \ + GD32_PINMUX_AF('A', 12, AF1) +#define USART0_RTS_DE_CK_PA14 \ + GD32_PINMUX_AF('A', 14, AF12) +#define USART0_RTS_DE_CK_PA15 \ + GD32_PINMUX_AF('A', 15, AF4) +#define USART0_RTS_DE_CK_PB3 \ + GD32_PINMUX_AF('B', 3, AF4) +#define USART0_RTS_DE_CK_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) + +/* USART0_RX */ +#define USART0_RX_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define USART0_RX_PA8 \ + GD32_PINMUX_AF('A', 8, AF13) +#define USART0_RX_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) +#define USART0_RX_PB2 \ + GD32_PINMUX_AF('B', 2, AF0) +#define USART0_RX_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) + +/* USART0_TX */ +#define USART0_TX_PA0 \ + GD32_PINMUX_AF('A', 0, AF4) +#define USART0_TX_PA9 \ + GD32_PINMUX_AF('A', 9, AF1) +#define USART0_TX_PB6 \ + GD32_PINMUX_AF('B', 6, AF7) +#define USART0_TX_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_CTS */ +#define USART1_CTS_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) +#define USART1_CTS_PB7 \ + GD32_PINMUX_AF('B', 7, AF7) +#define USART1_CTS_PB8 \ + GD32_PINMUX_AF('B', 8, AF7) + +/* USART1_RTS_DE_CK */ +#define USART1_RTS_DE_CK_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) +#define USART1_RTS_DE_CK_PB9 \ + GD32_PINMUX_AF('B', 9, AF7) +#define USART1_RTS_DE_CK_PC14 \ + GD32_PINMUX_AF('C', 14, AF7) + +/* USART1_RX */ +#define USART1_RX_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) +#define USART1_RX_PA5 \ + GD32_PINMUX_AF('A', 5, AF1) +#define USART1_RX_PA13 \ + GD32_PINMUX_AF('A', 13, AF4) +#define USART1_RX_PA14 \ + GD32_PINMUX_AF('A', 14, AF9) +#define USART1_RX_PA15 \ + GD32_PINMUX_AF('A', 15, AF1) + +/* USART1_TX */ +#define USART1_TX_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) +#define USART1_TX_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) +#define USART1_TX_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) +#define USART1_TX_PA14 \ + GD32_PINMUX_AF('A', 14, AF1) + +/* USART2_CTS */ +#define USART2_CTS_PA6 \ + GD32_PINMUX_AF('A', 6, AF6) + +/* USART2_RTS_DE_CK */ +#define USART2_RTS_DE_CK_PA7 \ + GD32_PINMUX_AF('A', 7, AF6) +#define USART2_RTS_DE_CK_PB1 \ + GD32_PINMUX_AF('B', 1, AF6) + +/* USART2_RX */ +#define USART2_RX_PA3 \ + GD32_PINMUX_AF('A', 3, AF6) + +/* USART2_TX */ +#define USART2_TX_PA2 \ + GD32_PINMUX_AF('A', 2, AF6) diff --git a/pinconfigs/gd32c231xx.yml b/pinconfigs/gd32c231xx.yml new file mode 100644 index 0000000..44b18e8 --- /dev/null +++ b/pinconfigs/gd32c231xx.yml @@ -0,0 +1,507 @@ +# GD32C231XX pin definitions +# +# Sources: +# - GD32C231XX Datasheet +# - C231F_LGA20.xml +# - C231G_QFN28.xml +# - C231K_LQFP32.xml +# - C231C_LQFP48.xml +# +# Pin codes: +# +# - 20 pins: F (GD32C231Fx-LGA20) +# - 28 pins: G (GD32C231Gx-QFN28) +# - 32 pins: K (GD32C231Kx-LQFP32) +# - 48 pins: C (GD32C231Cx-LQFP48) +# +# Memory codes: +# +# - 12Kb Flash: 6 +# - 12Kb Flash: 8 +# +# Copyright (c) 2025 +# SPDX-License-Identifier: Apache 2.0 + +model: af + +series: gd32c231 + +variants: + - pincode: F + memories: [6, 8] + - pincode: G + memories: [6, 8] + - pincode: K + memories: [6, 8] + - pincode: C + memories: [6, 8] + +signal-configs: + USART2_TX: + exclude-pincodes: [F, G] + USART2_RX: + exclude-pincodes: [F, G] + USART2_CTS: + exclude-pincodes: [F, G] + USART2_RTS_DE_CK: + exclude-pincodes: [F, G] + I2C1_SCL: + exclude-pincodes: [F, G] + I2C1_SDA: + exclude-pincodes: [F, G] + PC6: + exclude-pincodes: [F] + PC7: + exclude-pincodes: [F, G, K] + PC13: + exclude-pincodes: [F, G, K] + PB2: + exclude-pincodes: [F, G] + PB10: + exclude-pincodes: [F, G, K] + PB11: + exclude-pincodes: [F, G, K] + PB12: + exclude-pincodes: [F, G, K] + PB13: + exclude-pincodes: [F, G, K] + PB14: + exclude-pincodes: [F, G, K] + PB15: + exclude-pincodes: [F, G, K] + PD0: + exclude-pincodes: [F, G, K] + PD1: + exclude-pincodes: [F, G, K] + PD2: + exclude-pincodes: [F, G, K] + PD3: + exclude-pincodes: [F, G, K] + PF0: + exclude-pincodes: [F, G, K] + PF1: + exclude-pincodes: [F, G, K] + PF3: + exclude-pincodes: [F, G, K] + +pins: + PA0: + afs: + ADC_IN0: ANALOG + SPI1_SCK: 0 + USART1_CTS: 1 + TIMER15_CH0: 2 + USART0_TX: 4 + TIMER0_CH0: 5 + CMP0_OUT: 7 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA1: + afs: + ADC_IN1: ANALOG + SPI0_SCK: 0 + I2S0_CK: 0 + USART1_RTS_DE_CK: 1 + TIMER16_CH0: 2 + SPI1_IO2: 3 + USART0_RX: 4 + TIMER0_CH1: 5 + I2C0_SMBA: 6 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA2: + afs: + ADC_IN2: ANALOG + SPI0_MOSI: 0 + I2S0_SD: 0 + USART1_TX: 1 + TIMER15_CH0_ON: 2 + TIMER2_ETI: 3 + SPI1_IO3: 4 + TIMER0_CH2: 5 + USART2_TX: 6 + CMP1_OUT: 7 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA3: + afs: + ADC_IN3: ANALOG + SPI1_MISO: 0 + USART1_RX: 1 + TIMER0_CH0_ON: 2 + TIMER0_CH3: 5 + USART2_RX: 6 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA4: + afs: + ADC_IN4: ANALOG + SPI0_NSS: 0 + I2S0_WS: 0 + USART1_TX: 1 + TIMER0_CH1_ON: 2 + SPI1_MOSI: 3 + TIMER13_CH0: 4 + TIMER16_CH0_ON: 5 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA5: + afs: + ADC_IN5: ANALOG + SPI0_SCK: 0 + I2S0_CK: 0 + USART1_RX: 1 + TIMER0_CH2_ON: 2 + SPI1_IO2: 3 + TIMER0_CH0: 5 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA6: + afs: + ADC_IN6: ANALOG + SPI0_MISO: 0 + TIMER2_CH0: 1 + TIMER0_BRKIN0: 2 + SPI1_IO3: 3 + TIMER15_CH0: 5 + USART2_CTS: 6 + CMP0_OUT: 7 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA7: + afs: + ADC_IN7: ANALOG + SPI0_MOSI: 0 + I2S0_SD: 0 + TIMER2_CH1: 1 + TIMER0_CH0_ON: 2 + TIMER13_CH0: 4 + TIMER16_CH0: 5 + USART2_RTS_DE_CK: 6 + CMP1_OUT: 7 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA8: + afs: + CK_OUT0: 0 + USART1_TX: 1 + TIMER0_CH0: 2 + SPI1_NSS: 3 + SPI0_NSS: 7 + I2S0_WS: 7 + TIMER0_CH1_ON: 8 + TIMER0_CH2_ON: 9 + TIMER2_CH2: 10 + TIMER2_CH3: 11 + TIMER13_CH0: 12 + USART0_RX: 13 + CK_OUT1: 14 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA9: + afs: + CK_OUT0: 0 + USART0_TX: 1 + TIMER0_CH1: 2 + TIMER2_ETI: 3 + SPI1_MISO: 4 + I2C0_SCL: 6 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA10: + afs: + SPI1_MOSI: 0 + USART0_RX: 1 + TIMER0_CH2: 2 + CK_OUT1: 3 + TIMER16_BRKIN0: 5 + I2C0_SDA: 6 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA11: + afs: + SPI0_MISO: 0 + USART0_CTS: 1 + TIMER0_CH3: 2 + SPI1_IO2: 3 + TIMER0_BRKIN1: 5 + I2C1_SCL: 6 + CMP0_OUT: 7 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA12: + afs: + ADC_IN12: ANALOG + SPI0_MOSI: 0 + I2S0_SD: 0 + USART0_RTS_DE_CK: 1 + TIMER0_ETI: 2 + SPI1_IO3: 3 + I2S_CKIN: 5 + I2C1_SDA: 6 + CMP1_OUT: 7 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA13: + afs: + SWDIO: 0 + TIMER2_ETI: 3 + USART1_RX: 4 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA14: + afs: + SWCLK: 0 + USART1_TX: 1 + SPI0_NSS: 7 + I2S0_WS: 7 + USART1_RX: 9 + TIMER0_CH0: 10 + CK_OUT1: 11 + USART0_RTS_DE_CK: 12 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PA15: + afs: + SPI0_NSS: 0 + I2S0_WS: 0 + USART1_RX: 1 + TIMER0_CH0: 2 + CK_OUT1: 3 + USART0_RTS_DE_CK: 4 + EVENTOUT: 15 + pincodes: [G, K, C] + PB0: + afs: + ADC_IN8: ANALOG + SPI0_NSS: 0 + I2S0_WS: 0 + TIMER2_CH2: 1 + TIMER0_CH1_ON: 2 + CMP0_OUT: 7 + EVENTOUT: 15 + pincodes: [G, K, C] + PB1: + afs: + ADC_IN9: ANALOG + TIMER13_CH0: 0 + TIMER2_CH3: 1 + TIMER0_CH2_ON: 2 + TIMER0_CH1_ON: 5 + USART2_RTS_DE_CK: 6 + EVENTOUT: 15 + pincodes: [G, K, C] + PB2: + afs: + ADC_IN10: ANALOG + USART0_RX: 0 + SPI1_MISO: 1 + CK_OUT1: 3 + EVENTOUT: 15 + pincodes: [K, C] + PB3: + afs: + SPI0_SCK: 0 + I2S0_CK: 0 + TIMER0_CH1: 1 + TIMER2_CH1: 3 + USART0_RTS_DE_CK: 4 + EVENTOUT: 15 + pincodes: [G, K, C] + PB4: + afs: + SPI0_MISO: 0 + TIMER2_CH0: 1 + USART0_CTS: 4 + TIMER16_BRKIN0: 5 + EVENTOUT: 15 + pincodes: [G, K, C] + PB5: + afs: + SPI0_MOSI: 0 + I2S0_SD: 0 + TIMER2_CH1: 1 + TIMER15_BRKIN0: 2 + TIMER2_CH2: 3 + SPI1_MISO: 4 + I2C0_SMBA: 6 + CMP1_OUT: 7 + EVENTOUT: 15 + pincodes: [G, K, C] + PB6: + afs: + USART0_TX: 7 + TIMER0_CH2: 1 + TIMER15_CH0_ON: 2 + TIMER2_CH2: 2 + USART0_RTS_DE_CK: 7 + USART0_CTS: 7 + I2C0_SCL: 4 + I2C0_SMBA: 4 + SPI0_MOSI: 5 + I2S0_SD: 5 + SPI0_MISO: 5 + SPI0_SCK: 5 + I2S0_CK: 5 + TIMER0_CH1: 1 + TIMER2_CH0: 2 + TIMER2_CH1: 2 + TIMER15_BRKIN0: 2 + TIMER16_BRKIN0: 2 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PB7: + afs: + USART0_RX: 7 + TIMER0_CH3: 1 + TIMER16_CH0_ON: 2 + TIMER2_CH3: 2 + SPI1_MOSI: 5 + I2C0_SDA: 4 + USART1_CTS: 7 + TIMER15_CH0: 2 + TIMER2_CH0: 2 + I2C0_SCL: 4 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PB8: + afs: + SPI1_SCK: 5 + USART1_CTS: 7 + TIMER15_CH0: 2 + TIMER2_CH0: 2 + I2C0_SCL: 4 + EVENTOUT: 15 + pincodes: [G, K, C] + PB9: + afs: + USART1_RTS_DE_CK: 7 + TIMER16_CH0: 2 + TIMER2_CH1: 2 + SPI1_NSS: 5 + I2C0_SDA: 4 + EVENTOUT: 15 + pincodes: [K, C] + PB10: + afs: + ADC_IN11: ANALOG + USART2_RX: 8 + SPI1_SCK: 5 + I2C1_SCL: 4 + CMP0_OUT: 6 + EVENTOUT: 15 + pincodes: [C] + PB11: + afs: + SPI1_MOSI: 5 + USART2_TX: 8 + I2C1_SDA: 4 + CMP1_OUT: 6 + EVENTOUT: 15 + pincodes: [C] + PB12: + afs: + SPI1_NSS: 5 + TIMER0_BRKIN1: 1 + TIMER0_BRKIN0: 1 + USART2_RTS_DE_CK: 8 + EVENTOUT: 15 + pincodes: [C] + PB13: + afs: + SPI1_SCK: 5 + USART2_CTS: 8 + TIMER0_CH0_ON: 1 + EVENTOUT: 15 + pincodes: [C] + PB14: + afs: + SPI1_MISO: 5 + TIMER0_CH1_ON: 1 + EVENTOUT: 15 + pincodes: [C] + PB15: + afs: + SPI1_MOSI: 5 + TIMER0_CH2_ON: 1 + EVENTOUT: 15 + pincodes: [C] + PC6: + afs: + TIMER2_CH0: 2 + EVENTOUT: 15 + pincodes: [G, K, C] + PC7: + afs: + TIMER2_CH1: 2 + EVENTOUT: 15 + pincodes: [C] + PC13: + afs: + TIMER0_ETI: 1 + TIMER0_BRKIN0: 1 + EVENTOUT: 15 + pincodes: [C] + PC14: + afs: + USART0_TX: 7 + TIMER0_ETI: 1 + TIMER0_BRKIN1: 1 + USART1_RTS_DE_CK: 7 + TIMER16_CH0: 2 + TIMER2_CH1: 2 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PC15: + afs: + OSC32EN: 0 + OSCEN: 0 + TIMER0_ETI: 1 + TIMER2_CH2: 2 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PD0: + afs: + SPI1_NSS: 5 + TIMER15_CH0: 2 + EVENTOUT: 15 + pincodes: [C] + PD1: + afs: + SPI1_SCK: 5 + TIMER16_CH0: 2 + EVENTOUT: 15 + pincodes: [C] + PD2: + afs: + TIMER2_ETI: 2 + TIMER0_CH0_ON: 1 + EVENTOUT: 15 + pincodes: [C] + PD3: + afs: + USART1_CTS: 7 + SPI1_MISO: 5 + TIMER0_CH1_ON: 1 + EVENTOUT: 15 + pincodes: [C] + PF0: + afs: + TIMER13_CH0: 2 + EVENTOUT: 15 + pincodes: [C] + PF1: + afs: + OSCEN: 0 + EVENTOUT: 15 + pincodes: [C] + PF2: + afs: + CK_OUT0: 0 + TIMER0_CH3: 1 + EVENTOUT: 15 + pincodes: [F, G, K, C] + PF3: + afs: + EVENTOUT: 15 + pincodes: [C] \ No newline at end of file