From 32180403d43055d416a98964300664cd42ea1154 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 4 Dec 2022 13:00:23 +0800 Subject: [PATCH 1/8] hal: gd32a503: add gd32a503 firmware library 1.0.1 add firmware library support for gd32a503. Origin: https://www.gd32mcu.com/data/documents/toolSoftware/GD32A50x_Firmware_Library_V1.0.1.rar Signed-off-by: YuLong Yao --- gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h | 255 ++ .../gd/gd32a50x/include/system_gd32a50x.h | 58 + .../gd/gd32a50x/source/system_gd32a50x.c | 833 +++++ .../include/gd32a50x_adc.h | 430 +++ .../include/gd32a50x_bkp.h | 184 + .../include/gd32a50x_can.h | 1274 +++++++ .../include/gd32a50x_cmp.h | 240 ++ .../include/gd32a50x_crc.h | 122 + .../include/gd32a50x_dac.h | 210 ++ .../include/gd32a50x_dbg.h | 120 + .../include/gd32a50x_dma.h | 709 ++++ .../include/gd32a50x_exti.h | 286 ++ .../include/gd32a50x_fmc.h | 537 +++ .../include/gd32a50x_fwdgt.h | 123 + .../include/gd32a50x_gpio.h | 390 +++ .../include/gd32a50x_i2c.h | 401 +++ .../include/gd32a50x_libopt.h | 61 + .../include/gd32a50x_mfcom.h | 452 +++ .../include/gd32a50x_misc.h | 93 + .../include/gd32a50x_pmu.h | 165 + .../include/gd32a50x_rcu.h | 761 +++++ .../include/gd32a50x_rtc.h | 142 + .../include/gd32a50x_spi.h | 375 ++ .../include/gd32a50x_syscfg.h | 301 ++ .../include/gd32a50x_timer.h | 1135 ++++++ .../include/gd32a50x_trigsel.h | 210 ++ .../include/gd32a50x_usart.h | 593 ++++ .../include/gd32a50x_wwdgt.h | 91 + .../standard_peripheral/source/gd32a50x_adc.c | 987 ++++++ .../standard_peripheral/source/gd32a50x_bkp.c | 346 ++ .../standard_peripheral/source/gd32a50x_can.c | 1844 ++++++++++ .../standard_peripheral/source/gd32a50x_cmp.c | 238 ++ .../standard_peripheral/source/gd32a50x_crc.c | 241 ++ .../standard_peripheral/source/gd32a50x_dac.c | 426 +++ .../standard_peripheral/source/gd32a50x_dbg.c | 126 + .../standard_peripheral/source/gd32a50x_dma.c | 1245 +++++++ .../source/gd32a50x_exti.c | 252 ++ .../standard_peripheral/source/gd32a50x_fmc.c | 2175 ++++++++++++ .../source/gd32a50x_fwdgt.c | 243 ++ .../source/gd32a50x_gpio.c | 414 +++ .../standard_peripheral/source/gd32a50x_i2c.c | 949 ++++++ .../source/gd32a50x_mfcom.c | 772 +++++ .../source/gd32a50x_misc.c | 183 + .../standard_peripheral/source/gd32a50x_pmu.c | 375 ++ .../standard_peripheral/source/gd32a50x_rcu.c | 1151 +++++++ .../standard_peripheral/source/gd32a50x_rtc.c | 260 ++ .../standard_peripheral/source/gd32a50x_spi.c | 803 +++++ .../source/gd32a50x_syscfg.c | 453 +++ .../source/gd32a50x_timer.c | 3035 +++++++++++++++++ .../source/gd32a50x_trigsel.c | 382 +++ .../source/gd32a50x_usart.c | 1291 +++++++ .../source/gd32a50x_wwdgt.c | 125 + 52 files changed, 28867 insertions(+) create mode 100644 gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h create mode 100644 gd32a50x/cmsis/gd/gd32a50x/include/system_gd32a50x.h create mode 100644 gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_adc.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_bkp.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_can.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_cmp.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_crc.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_dac.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_dbg.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_dma.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_exti.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_fmc.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_fwdgt.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_gpio.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_i2c.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_libopt.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_mfcom.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_misc.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_pmu.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_rcu.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_rtc.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_spi.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_syscfg.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_timer.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_trigsel.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_usart.h create mode 100644 gd32a50x/standard_peripheral/include/gd32a50x_wwdgt.h create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_adc.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_bkp.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_can.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_cmp.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_crc.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_dac.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_dbg.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_dma.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_exti.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_fmc.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_fwdgt.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_gpio.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_i2c.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_mfcom.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_misc.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_pmu.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_rcu.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_rtc.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_spi.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_syscfg.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_timer.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_trigsel.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_usart.c create mode 100644 gd32a50x/standard_peripheral/source/gd32a50x_wwdgt.c diff --git a/gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h b/gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h new file mode 100644 index 0000000..b0f58a8 --- /dev/null +++ b/gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h @@ -0,0 +1,255 @@ +/*! + \file gd32a50x.h + \brief general definitions for GD32A50x + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_H +#define GD32A50X_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if !defined (GD32A50X) +#error "Please select the target GD32A50X device used in your application (in gd32a50x.h file)" +#endif /* undefine GD32A50X tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined HXTAL_VALUE +#define HXTAL_VALUE ((uint32_t)8000000) /*!< value of the external oscillator in Hz */ +#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 8MHz RC oscillator (IRC8M) in Hz */ +#if !defined (IRC8M_VALUE) +#define IRC8M_VALUE ((uint32_t)8000000) +#endif /* internal 8MHz RC oscillator value */ + +/* define startup timeout value of internal 8MHz RC oscillator (IRC8M) */ +#if !defined (IRC8M_STARTUP_TIMEOUT) +#define IRC8M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 8MHz RC oscillator startup timeout */ + +/* define value of internal 40KHz RC oscillator(IRC40K) in Hz */ +#if !defined (IRC40K_VALUE) +#define IRC40K_VALUE ((uint32_t)40000) +#endif /* internal 40KHz 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 */ + +/* GD32E50x firmware library version number V1.0 */ +#define __GD32A50X_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __GD32A50X_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32A50X_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32A50X_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32A50X_STDPERIPH_VERSION ((__GD32A50X_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32A50X_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32A50X_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32A50X_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M33 processor and core peripherals */ +#define __CM33_REV 0x0003U /*!< Core revision r0p3 */ +#define __SAUREGION_PRESENT 0U /*!< SAU regions are not present */ +#define __MPU_PRESENT 1U /*!< MPU is present */ +#define __VTOR_PRESENT 1U /*!< VTOR is present */ +#define __NVIC_PRIO_BITS 4U /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /*!< FPU present */ +#define __DSP_PRESENT 1U /*!< DSP present */ + +/* define interrupt number */ +typedef enum IRQn +{ + /* Cortex-M33 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< non mask-able interrupt */ + HardFault_IRQn = -13, /*!< hard-fault interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M33 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M33 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M33 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M33 sv call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M33 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M33 pend sv interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M33 system tick interrupt */ + /* interrupt numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ + RTC_IRQn = 3, /*!< RTC Wakeup interrupt */ + FMC_IRQn = 4, /*!< FMC interrupt */ + RCU_IRQn = 5, /*!< RCU and CTC interrupt */ + EXTI0_IRQn = 6, /*!< EXTI line 0 interrupts */ + EXTI1_IRQn = 7, /*!< EXTI line 1 interrupts */ + EXTI2_IRQn = 8, /*!< EXTI line 2 interrupts */ + EXTI3_IRQn = 9, /*!< EXTI line 3 interrupts */ + EXTI4_IRQn = 10, /*!< EXTI line 4 interrupts */ + DMA0_Channel0_IRQn = 11, /*!< DMA0 channel 0 interrupt */ + DMA0_Channel1_IRQn = 12, /*!< DMA0 channel 1 interrupt */ + DMA0_Channel2_IRQn = 13, /*!< DMA0 channel 2 interrupt */ + DMA0_Channel3_IRQn = 14, /*!< DMA0 channel 3 interrupt */ + DMA0_Channel4_IRQn = 15, /*!< DMA0 channel 4 interrupt */ + DMA0_Channel5_IRQn = 16, /*!< DMA0 channel 5 interrupt */ + DMA0_Channel6_IRQn = 17, /*!< DMA0 channel 6 interrupt */ + ADC0_1_IRQn = 18, /*!< ADC0_1 interrupts */ + CAN0_Message_IRQn = 19, /*!< CAN0 message buffer interrupt */ + CAN0_Busoff_IRQn = 20, /*!< CAN0 bus off interrupt */ + CAN0_Error_IRQn = 21, /*!< CAN0 error interrupt */ + CAN0_FastError_IRQn = 22, /*!< CAN0 fast transmission error interrupt */ + CAN0_TEC_IRQn = 23, /*!< CAN0 transmit warning interrupt */ + CAN0_REC_IRQn = 24, /*!< CAN0 receive warning interrupt */ + CAN0_WKUP_IRQn = 25, /*!< CAN0 wakeup through EXTI Line detection interrupt */ + TIMER0_BRK_UP_TRG_CMT_IRQn = 26, /*!< TIMER0 break, update, trigger and commutation interrupt */ + TIMER0_Channel_IRQn = 27, /*!< TIMER0 capture compare interrupt */ + TIMER1_IRQn = 28, /*!< TIMER1 interrupt */ + TIMER19_BRK_UP_TRG_CMT_IRQn = 29, /*!< TIMER19 break, update, trigger and commutation interrupt */ + TIMER19_Channel_IRQn = 30, /*!< TIMER19 capture compare interrupt */ + I2C0_EV_IRQn = 31, /*!< I2C0 event interrupt */ + I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ + I2C1_EV_IRQn = 33, /*!< I2C1 event interrupt */ + I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ + SPI0_IRQn = 35, /*!< SPI0 interrupt */ + SPI1_IRQn = 36, /*!< SPI1 interrupt */ + USART0_IRQn = 37, /*!< USART0 interrupt */ + USART1_IRQn = 38, /*!< USART1 interrupt */ + USART2_IRQn = 39, /*!< USART2 interrupt */ + EXTI10_15_IRQn = 40, /*!< EXTI line 10 to 15 interrupts */ + EXTI5_9_IRQn = 41, /*!< EXTI line 5 to 9 interrupts */ + TAMPER_IRQn = 42, /*!< BKP Tamper interrupt */ + TIMER20_BRK_UP_TRG_CMT_IRQn = 43, /*!< TIMER20 break, update, trigger and commutation interrupt */ + TIMER20_Channel_IRQn = 44, /*!< TIMER20 capture compare interrupt */ + TIMER7_BRK_UP_TRG_CMT_IRQn = 45, /*!< TIMER7 break, update, trigger and commutation interrupt */ + TIMER7_Channel_IRQn = 46, /*!< TIMER7 capture compare interrupt */ + DMAMUX_IRQn = 47, /*!< DMAMUX interrupt */ + SRAMC_ECCSE_IRQn = 48, /*!< SYSCFG SRAM ECC single err interrupt */ + CMP_IRQn = 49, /*!< Comparator interrupt */ + OVD_IRQn = 51, /*!< Over voltage detector interrupt */ + TIMER5_DAC_IRQn = 54, /*!< TIMER5 and DAC interrupt */ + TIMER6_IRQn = 55, /*!< TIMER6 interrupt */ + DMA1_Channel0_IRQn = 56, /*!< DMA1 channel 0 interrupt */ + DMA1_Channel1_IRQn = 57, /*!< DMA1 channel 1 interrupt */ + DMA1_Channel2_IRQn = 58, /*!< DMA1 channel 2 interrupt */ + DMA1_Channel3_IRQn = 59, /*!< DMA1 channel 3 interrupt */ + DMA1_Channel4_IRQn = 60, /*!< DMA1 channel 4 interrupt */ + CAN1_WKUP_IRQn = 62, /*!< CAN1 wakeup through EXTI Line detection interrupt */ + CAN1_Message_IRQn = 63, /*!< CAN1 message buffer interrupt */ + CAN1_Busoff_IRQn = 64, /*!< CAN1 bus off interrupt */ + CAN1_Error_IRQn = 65, /*!< CAN1 error interrupt */ + CAN1_FastError_IRQn = 66, /*!< CAN1 fast transmission error interrupt */ + CAN1_TEC_IRQn = 67, /*!< CAN1 transmit warning interrupt */ + CAN1_REC_IRQn = 68, /*!< CAN1 receive warning interrupt */ + FPU_IRQn = 69, /*!< FPU interrupt */ + MFCOM_IRQn = 70 /*!< MFCOM interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm33.h" +#include "system_gd32a50x.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG64(addr) (*(volatile uint64_t *)(uint32_t)(addr)) +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM base address */ + +/* peripheral memory map */ +#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ +#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb3 base address */ + +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define RTC_BASE (APB1_BUS_BASE + 0x00002800U) /*!< RTC base address */ +#define WWDGT_BASE (APB1_BUS_BASE + 0x00002C00U) /*!< WWDGT base address */ +#define FWDGT_BASE (APB1_BUS_BASE + 0x00003000U) /*!< FWDGT base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define BKP_BASE (APB1_BUS_BASE + 0x00006C00U) /*!< BKP base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +#define DAC_BASE (APB1_BUS_BASE + 0x00007400U) /*!< DAC base address */ + +/* advanced peripheral bus 2 memory map */ +#define SYSCFG_BASE (APB2_BUS_BASE + 0x00000000U) /*!< SYSCFG base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */ +#define CMP_BASE (APB2_BUS_BASE + 0x00007C00U) /*!< CMP base address */ +#define TRIGSEL_BASE (APB2_BUS_BASE + 0x00008400U) /*!< TRIGSEL base address */ +#define CAN_BASE (APB2_BUS_BASE + 0x0000A000U) /*!< CAN base address */ + +/* advanced high performance bus 1 memory map */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ +#define DMAMUX_BASE (AHB1_BUS_BASE + 0x00000800U) /*!< DMAMUX base address */ +#define 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 */ +#define MFCOM_BASE (AHB1_BUS_BASE + 0x00018400U) /*!< MFCOM 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)0xE0044000U) /*!< DBG base address */ + +/* define marco USE_STDPERIPH_DRIVER */ +#if !defined USE_STDPERIPH_DRIVER +#define USE_STDPERIPH_DRIVER +#endif +#ifdef USE_STDPERIPH_DRIVER +#include "gd32a50x_libopt.h" +#endif /* USE_STDPERIPH_DRIVER */ + +#ifdef __cplusplus +} +#endif + +#endif /* GD32A50X_H */ diff --git a/gd32a50x/cmsis/gd/gd32a50x/include/system_gd32a50x.h b/gd32a50x/cmsis/gd/gd32a50x/include/system_gd32a50x.h new file mode 100644 index 0000000..4ce71da --- /dev/null +++ b/gd32a50x/cmsis/gd/gd32a50x/include/system_gd32a50x.h @@ -0,0 +1,58 @@ +/*! + \file system_gd32a50x.h + \brief CMSIS Cortex-M33 Device Peripheral Access Layer Header File for + GD32A50X 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_GD32A50X_H +#define SYSTEM_GD32A50X_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* system clock frequency (core clock) */ +extern uint32_t SystemCoreClock; + +/* function declarations */ +/* initialize the system and update the SystemCoreClock variable */ +extern void SystemInit(void); +/* update the SystemCoreClock with current core clock retrieved from CPU registers */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_GD32A50X_H */ diff --git a/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c b/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c new file mode 100644 index 0000000..e42cc91 --- /dev/null +++ b/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c @@ -0,0 +1,833 @@ +/*! + \file system_gd32a50x.c + \brief CMSIS Cortex-M33 Device Peripheral Access Layer Source File for + GD32A50X 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 "gd32a50x.h" + +#define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ + +#define VECT_TAB_OFFSET (uint32_t)0x00 /* vector table base offset */ + +/* select a system clock by uncommenting the following line */ +/* use IRC8M */ +//#define __SYSTEM_CLOCK_IRC8M (uint32_t)(__IRC8M) +//#define __SYSTEM_CLOCK_24M_PLL_IRC8M (uint32_t)(24000000) +//#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000) +//#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000) +//#define __SYSTEM_CLOCK_100M_PLL_IRC8M (uint32_t)(100000000) + +/* use HXTAL(CK_HXTAL = 8M)*/ +//#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL) +//#define __SYSTEM_CLOCK_24M_PLL_HXTAL (uint32_t)(24000000) +//#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000) +//#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) +#define __SYSTEM_CLOCK_100M_PLL_HXTAL (uint32_t)(100000000) + + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_IRC8M +uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC8M; +static void system_clock_8m_irc8m(void); +#elif defined (__SYSTEM_CLOCK_24M_PLL_IRC8M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_24M_PLL_IRC8M; +static void system_clock_24m_pll_irc8m(void); +#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_IRC8M; +static void system_clock_48m_pll_irc8m(void); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M; +static void system_clock_72m_pll_irc8m(void); +#elif defined (__SYSTEM_CLOCK_100M_PLL_IRC8M) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_100M_PLL_IRC8M; +static void system_clock_100m_pll_irc8m(void); + +#elif defined (__SYSTEM_CLOCK_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL; +static void system_clock_hxtal(void); +#elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_24M_PLL_HXTAL; +static void system_clock_24m_pll_hxtal(void); +#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_48M_PLL_HXTAL; +static void system_clock_48m_pll_hxtal(void); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL; +static void system_clock_72m_pll_hxtal(void); +#elif defined (__SYSTEM_CLOCK_100M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_100M_PLL_HXTAL; +static void system_clock_100m_pll_hxtal(void); +#endif /* __SYSTEM_CLOCK_IRC8M */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief setup the micro-controller system, initialize the system + \param[in] none + \param[out] none + \retval none +*/ +void SystemInit(void) +{ + /* FPU settings */ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10 and CP11 Full Access */ +#endif + /* reset the RCU clock configuration to the default reset state */ + /* set IRC8MEN bit */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + RCU_CFG0 &= ~RCU_CFG0_SCS; + /* reset HXTALSCAL, LCKMEN, PLLMEN, PLLEN, CKMEN and HXTALEN bits */ + RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN | RCU_CTL_HXTALSCAL | RCU_CTL_LCKMEN | RCU_CTL_PLLMEN); + /* disable all interrupts */ + RCU_INT = 0x00FF0000U; + + /* Reset CFG0 and CFG1 registers */ + RCU_CFG0 = 0x00020000U; + RCU_CFG1 = 0x00000000U; + + /* reset HXTALBPS bit */ + RCU_CTL &= ~(RCU_CTL_HXTALBPS); + + /* configure the system clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */ + system_clock_config(); + + /* LXTALBPS configuration */ + if(0U == (RCU_APB1EN & RCU_APB1EN_PMUEN)) { + /* check whether PMU clock is enabled */ + RCU_APB1EN |= RCU_APB1EN_PMUEN; + if(0U == (PMU_CTL & PMU_CTL_BKPWEN)) { + /* BKPWEN bit is not been set */ + PMU_CTL |= PMU_CTL_BKPWEN; + /* LXTALBPS bit must be configured to 1 */ + RCU_BDCTL |= RCU_BDCTL_LXTALBPS; + /* clear the BKPWEN bit */ + PMU_CTL &= ~PMU_CTL_BKPWEN; + } else { + /* LXTALBPS bit must be configured to 1 */ + RCU_BDCTL |= RCU_BDCTL_LXTALBPS; + } + + /* disable the PMU clock */ + RCU_APB1EN &= ~RCU_APB1EN_PMUEN; + } else { + /* the PMU clock is already enabled */ + if(0U == (PMU_CTL & PMU_CTL_BKPWEN)) { + /* BKPWEN bit is not been set */ + PMU_CTL |= PMU_CTL_BKPWEN; + /* LXTALBPS bit must be configured to 1 */ + RCU_BDCTL |= RCU_BDCTL_LXTALBPS; + /* clear the BKPWEN bit */ + PMU_CTL &= ~PMU_CTL_BKPWEN; + } else { + /* LXTALBPS bit must be configured to 1 */ + RCU_BDCTL |= RCU_BDCTL_LXTALBPS; + } + } + +#ifdef VECT_TAB_SRAM + nvic_vector_table_set(NVIC_VECTTAB_RAM, VECT_TAB_OFFSET); +#else + nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET); +#endif +} + +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_IRC8M + system_clock_8m_irc8m(); +#elif defined (__SYSTEM_CLOCK_24M_PLL_IRC8M) + system_clock_24m_pll_irc8m(); +#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M) + system_clock_48m_pll_irc8m(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M) + system_clock_72m_pll_irc8m(); +#elif defined (__SYSTEM_CLOCK_100M_PLL_IRC8M) + system_clock_100m_pll_irc8m(); + +#elif defined (__SYSTEM_CLOCK_HXTAL) + system_clock_hxtal(); +#elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL) + system_clock_24m_pll_hxtal(); +#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL) + system_clock_48m_pll_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) + system_clock_72m_pll_hxtal(); +#elif defined (__SYSTEM_CLOCK_100M_PLL_HXTAL) + system_clock_100m_pll_hxtal(); +#endif /* __SYSTEM_CLOCK_IRC8M */ +} + +#ifdef __SYSTEM_CLOCK_IRC8M +/*! + \brief configure the system clock to 8M by IRC8M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(0); + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/1 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select IRC8M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC8M; + + /* wait until IRC8M is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_IRC8M) { + } +} +/*! + \brief configure the system clock to 24M by PLL which selects IRC8M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +#elif defined (__SYSTEM_CLOCK_24M_PLL_IRC8M) +static void system_clock_24m_pll_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(0); + + /* LDO output voltage high mode */ + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* IRC8M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_IRC8M/2) * 6 = 24 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= RCU_PLL_MUL6; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} + + +#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M) +/*! + \brief configure the system clock to 48M by PLL which selects IRC8M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_48m_pll_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(1); + + /* LDO output voltage high mode */ + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* IRC8M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_IRC8M/2) * 12 = 48 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= RCU_PLL_MUL12; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M) +/*! + \brief configure the system clock to 72M by PLL which selects IRC8M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_pll_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(2); + + /* LDO output voltage high mode */ + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* IRC8M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_IRC8M/2) * 18 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= RCU_PLL_MUL18; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} + +#elif defined (__SYSTEM_CLOCK_100M_PLL_IRC8M) +/*! + \brief configure the system clock to 100M by PLL which selects IRC8M as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_100m_pll_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB); + } while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(3); + + /* LDO output voltage high mode */ + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* IRC8M is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (CK_IRC8M/2) * 25 = 100 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= RCU_PLL_MUL25; + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} + +#elif defined (__SYSTEM_CLOCK_HXTAL) +/*! + \brief configure the system clock to HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(0); + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/1 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_HXTAL) { + } +} + +#elif defined (__SYSTEM_CLOCK_24M_PLL_HXTAL) +/*! + \brief configure the system clock to 24M by PLL which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_24m_pll_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(0); + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (HXTAL / 2) * 6 = 24 MHz */ + RCU_CFG1 |= RCU_PREDV_DIV2; + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL6); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} + +#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL) +/*! + \brief configure the system clock to 48M by PLL which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_48m_pll_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(1); + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (HXTAL / 2) * 12 = 48 MHz */ + RCU_CFG1 |= RCU_PREDV_DIV2; + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL12); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +/*! + \brief configure the system clock to 72M by PLL which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_pll_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(2); + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (HXTAL / 2) * 18 = 72 MHz */ + RCU_CFG1 |= RCU_PREDV_DIV2; + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL18); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} + +#elif defined (__SYSTEM_CLOCK_100M_PLL_HXTAL) +/*! + \brief configure the system clock to 100M by PLL which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_100m_pll_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL |= RCU_CTL_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do { + timeout++; + stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); + } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) { + while(1) { + } + } + + FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(3); + + RCU_APB1EN |= RCU_APB1EN_PMUEN; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB/1 */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB/2 */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + + /* CK_PLL = (HXTAL / 2) * 25 = 100 MHz */ + RCU_CFG1 |= RCU_PREDV_DIV2; + RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL25); + + /* enable PLL */ + RCU_CTL |= RCU_CTL_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL & RCU_CTL_PLLSTB)) { + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLL) { + } +} +#endif /* __SYSTEM_CLOCK_IRC8M */ + +/*! + \brief update the SystemCoreClock with current core clock retrieved from CPU registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate(void) +{ + uint32_t sws; + uint32_t pllsel, pllmf, ck_src, idx, clk_exp; + uint32_t predv0; + + /* exponent of AHB, APB1 and APB2 clock divider */ + uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + sws = RCU_CFG0 & RCU_CFG0_SCSS; + switch(sws) { + /* IRC8M is selected as CK_SYS */ + case RCU_SCSS_IRC8M: + SystemCoreClock = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case RCU_SCSS_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case RCU_SCSS_PLL: + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL); + + if(RCU_PLLSRC_HXTAL == pllsel) { + /* PLL clock source is HXTAL */ + ck_src = HXTAL_VALUE; + predv0 = (RCU_CFG1 & RCU_CFG1_PREDV) + 1U; + ck_src /= predv0; + } else { + /* PLL clock source is IRC8M/2 */ + ck_src = IRC8M_VALUE / 2U; + } + + /* PLL multiplication factor */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf += ((RCU_CFG0 & RCU_CFG0_PLLMF_4) ? 15U : 0U); + pllmf += ((0xFU == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); + + SystemCoreClock = ck_src * pllmf; + + break; + /* IRC8M is selected as CK_SYS */ + default: + SystemCoreClock = IRC8M_VALUE; + break; + } + + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + SystemCoreClock >>= clk_exp; +} diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_adc.h b/gd32a50x/standard_peripheral/include/gd32a50x_adc.h new file mode 100644 index 0000000..ada21f8 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_adc.h @@ -0,0 +1,430 @@ +/*! + \file gd32a50x_adc.h + \brief definitions for the ADC + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_ADC_H +#define GD32A50X_ADC_H + +#include "gd32a50x.h" + +/* ADC definitions */ +#define ADC0 ADC_BASE +#define ADC1 (ADC_BASE + 0x00000400U) + +/* registers definitions */ +#define ADC_STAT(adcx) REG32((adcx) + 0x00000000U) /*!< ADC status register */ +#define ADC_CTL0(adcx) REG32((adcx) + 0x00000004U) /*!< ADC control register 0 */ +#define ADC_CTL1(adcx) REG32((adcx) + 0x00000008U) /*!< ADC control register 1 */ +#define ADC_SAMPT0(adcx) REG32((adcx) + 0x0000000CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1(adcx) REG32((adcx) + 0x00000010U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0(adcx) REG32((adcx) + 0x00000014U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1(adcx) REG32((adcx) + 0x00000018U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2(adcx) REG32((adcx) + 0x0000001CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3(adcx) REG32((adcx) + 0x00000020U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT0(adcx) REG32((adcx) + 0x00000024U) /*!< ADC watchdog high threshold register 0 */ +#define ADC_WDLT0(adcx) REG32((adcx) + 0x00000028U) /*!< ADC watchdog low threshold register 0 */ +#define ADC_RSQ0(adcx) REG32((adcx) + 0x0000002CU) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1(adcx) REG32((adcx) + 0x00000030U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2(adcx) REG32((adcx) + 0x00000034U) /*!< ADC regular sequence register 2 */ +#define ADC_ISQ(adcx) REG32((adcx) + 0x00000038U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0(adcx) REG32((adcx) + 0x0000003CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1(adcx) REG32((adcx) + 0x00000040U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2(adcx) REG32((adcx) + 0x00000044U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3(adcx) REG32((adcx) + 0x00000048U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA(adcx) REG32((adcx) + 0x0000004CU) /*!< ADC regular data register */ +#define ADC_OVSAMPCTL(adcx) REG32((adcx) + 0x00000080U) /*!< ADC oversampling control register */ +#define ADC_WD1SR(adcx) REG32((adcx) + 0x000000A0U) /*!< ADC watchdog 1 channel selection register */ +#define ADC_WDT1(adcx) REG32((adcx) + 0x000000A8U) /*!< ADC watchdog threshold register 1 */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE0 BIT(0) /*!< analog watchdog 0 event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of group conversion flag */ +#define ADC_STAT_EOIC BIT(2) /*!< end of inserted group conversion flag */ +#define ADC_STAT_STIC BIT(3) /*!< start flag of inserted channel group */ +#define ADC_STAT_STRC BIT(4) /*!< start flag of regular channel group */ +#define ADC_STAT_WDE1 BIT(30) /*!< analog watchdog 1 event flag */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WD0CHSEL BITS(0, 4) /*!< analog watchdog 0 channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDE0IE BIT(6) /*!< analog watchdog 0 interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ +#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 group conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13, 15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_SYNCM BITS(16, 19) /*!< sync mode selection */ +#define ADC_CTL0_IWD0EN BIT(22) /*!< analog watchdog 0 enable on inserted channels */ +#define ADC_CTL0_RWD0EN BIT(23) /*!< analog watchdog 0 enable on regular channels */ +#define ADC_CTL0_WDE1IE BIT(30) /*!< analog watchdog 1 interrupt enable */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< DMA request enable */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BIT(12) /*!< external trigger select for inserted channel */ +#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger enable for inserted channel */ +#define ADC_CTL1_ETSRC BIT(17) /*!< external trigger select for regular channel */ +#define ADC_CTL1_ETERC BIT(20) /*!< external trigger enable for regular channel */ +#define ADC_CTL1_SWICST BIT(21) /*!< start on inserted channel */ +#define ADC_CTL1_SWRCST BIT(22) /*!< start on regular channel */ +#define ADC_CTL1_TSVEN BIT(23) /*!< channel 16 enable of ADC0 */ +#define ADC_CTL1_INREFEN BIT(24) /*!< channel 17 enable of ADC0 */ + +/* ADC_SAMPTx x=0..1 */ +#define ADC_SAMPTX_SPTN BITS(0, 2) /*!< channel n(n=0..17) sample time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0, 11) /*!< data offset for inserted channel x */ + +/* ADC_WDHT */ +#define ADC_WDHT0_WDHT0 BITS(0, 11) /*!< analog watchdog 0 high threshold */ + +/* ADC_WDLT */ +#define ADC_WDLT0_WDLT0 BITS(0, 11) /*!< analog watchdog 0 low threshold */ + +/* ADC_RSQx x=0..2 */ +#define ADC_RSQX_RSQN BITS(0, 4) /*!< n conversion in regular sequence */ +#define ADC_RSQ0_RL BITS(20, 23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0, 4) /*!< n conversion in regular sequence */ +#define ADC_ISQ_IL BITS(20, 21) /*!< inserted sequence length */ + +/* ADC_IDATAx x=0..3 */ +#define ADC_IDATAX_IDATAN BITS(0, 15) /*!< inserted channel x conversion data */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0, 15) /*!< regular data */ +#define ADC_RDATA_ADC1RDTR BITS(16, 31) /*!< ADC1 regular channel data */ + +/* ADC_OVSAMPCTL */ +#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSAMPCTL_OVSR BITS(2, 4) /*!< oversampling ratio */ +#define ADC_OVSAMPCTL_OVSS BITS(5, 8) /*!< oversampling shift */ +#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ +#define ADC_OVSAMPCTL_DRES BITS(12, 13) /*!< ADC resolution */ + +/* ADC_WD1SR */ +#define ADC_WD1SR_AWD1CS BITS(0, 17) /*!< analog watchdog 1 channel selection */ + +/* ADC_WDT1 */ +#define ADC_WDT1_WDLT1 BITS(0, 7) /*!< analog watchdog 1 low threshold */ +#define ADC_WDT1_WDHT1 BITS(16, 23) /*!< analog watchdog 1 high threshold */ + +/* constants definitions */ +/* ADC flag definitions */ +#define ADC_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of conversion */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< inserted channel end of conversion */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< inserted channel start flag */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< regular channel start flag */ +#define ADC_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event flag */ + +/* configure number of conversions in discontinuous mode */ +#define CTL0_DISNUM(regval) (BITS(13, 15) & ((uint32_t)(regval) << 13)) /*!< write value to ADC_CTL0_DISNUM bit field */ + +/* ADC special function definitions */ +#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ +#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ + +/* ADC synchronization mode */ +#define CTL0_SYNCM(regval) (BITS(16, 19) & ((uint32_t)(regval) << 16)) /*!< write value to ADC_CTL0_SYNCM bit field */ +#define ADC_MODE_FREE CTL0_SYNCM(0) /*!< all the ADCs work independently */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL CTL0_SYNCM(1) /*!< ADC0 and ADC1 work in combined regular parallel + inserted parallel mode */ +#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION CTL0_SYNCM(2) /*!< ADC0 and ADC1 work in combined regular parallel + trigger rotation mode */ +#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(3) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode */ +#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(4) /*!< ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode */ +#define ADC_DAUL_INSERTED_PARALLEL CTL0_SYNCM(5) /*!< ADC0 and ADC1 work in inserted parallel mode only */ +#define ADC_DAUL_REGULAL_PARALLEL CTL0_SYNCM(6) /*!< ADC0 and ADC1 work in regular parallel mode only */ +#define ADC_DAUL_REGULAL_FOLLOWUP_FAST CTL0_SYNCM(7) /*!< ADC0 and ADC1 work in follow-up fast mode only */ +#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW CTL0_SYNCM(8) /*!< ADC0 and ADC1 work in follow-up slow mode only */ +#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION CTL0_SYNCM(9) /*!< ADC0 and ADC1 work in trigger rotation mode only */ + +/* 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 regular channel */ +#define ADC0_1_EXTTRIG_REGULAR_TRIGSEL ((uint32_t)0x00000000U) /*!< TRIGSEL trigger */ +#define ADC0_1_EXTTRIG_REGULAR_NONE ADC_CTL1_ETSRC /*!< software trigger */ + +/* ADC external trigger select for inserted channel */ +#define ADC0_1_EXTTRIG_INSERTED_TRIGSEL ((uint32_t)0x00000000U) /*!< TRIGSEL trigger */ +#define ADC0_1_EXTTRIG_INSERTED_NONE ADC_CTL1_ETSIC /*!< software trigger */ + +/* ADC_SAMPTX register value */ +#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_14POINT5 SAMPTX_SPT(1) /*!< 14.5 sampling cycles */ +#define ADC_SAMPLETIME_27POINT5 SAMPTX_SPT(2) /*!< 27.5 sampling cycles */ +#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(3) /*!< 55.5 sampling cycles */ +#define ADC_SAMPLETIME_83POINT5 SAMPTX_SPT(4) /*!< 83.5 sampling cycles */ +#define ADC_SAMPLETIME_111POINT5 SAMPTX_SPT(5) /*!< 111.5 sampling cycles */ +#define ADC_SAMPLETIME_143POINT5 SAMPTX_SPT(6) /*!< 143.5 sampling cycles */ +#define ADC_SAMPLETIME_479POINT5 SAMPTX_SPT(7) /*!< 479.5 sampling cycles */ + +/* ADC data offset for inserted channel x */ +#define IOFFX_IOFF(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) + +/* ADC analog watchdog 0 high threshold */ +#define WDHT0_WDHT0(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) + +/* ADC analog watchdog 0 low threshold */ +#define WDLT0_WDLT0(regval) (BITS(0, 11) & ((uint32_t)(regval) << 0)) + +/* ADC analog watchdog 1 high threshold */ +#define WDT1_WDHT1(regval) (BITS(16, 23) & ((uint32_t)(regval) << 16)) + +/* ADC analog watchdog 1 low threshold */ +#define WDT1_WDLT1(regval) (BITS(0, 7) & ((uint32_t)(regval) << 0)) + +/* ADC regular channel group length */ +#define RSQ0_RL(regval) (BITS(20, 23) & ((uint32_t)(regval) << 20)) + +/* ADC inserted channel group length */ +#define ISQ_IL(regval) (BITS(20, 21) & ((uint32_t)(regval) << 20)) + +/* adc_ovsampctl register value */ +/* ADC resolution */ +#define OVSAMPCTL_DRES(regval) (BITS(12, 13) & ((uint32_t)(regval) << 12)) /*!< write value to ADC_OVSAMPCTL_DRES bit field */ +#define ADC_RESOLUTION_12B OVSAMPCTL_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B OVSAMPCTL_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B OVSAMPCTL_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B OVSAMPCTL_DRES(3) /*!< 6-bit ADC resolution */ + +/* oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5, 8) & ((uint32_t)(regval) << 5)) /*!< write value to ADC_OVSAMPCTL_OVSS bit field */ +#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */ + +/* oversampling ratio */ +#define OVSAMPCTL_OVSR(regval) (BITS(2, 4) & ((uint32_t)(regval) << 2)) /*!< write value to ADC_OVSAMPCTL_OVSR bit field */ +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ + +/* triggered oversampling */ +#define ADC_OVERSAMPLING_ALL_CONVERT ((uint32_t)0x00000000U) /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT ADC_OVSAMPCTL_TOVS /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC channel group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< ADC regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< ADC inserted channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC inserted channel 3 */ + +/* ADC channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ +#define ADC_CHANNEL_10 ((uint8_t)0x0AU) /*!< ADC channel 10 */ +#define ADC_CHANNEL_11 ((uint8_t)0x0BU) /*!< ADC channel 11 */ +#define ADC_CHANNEL_12 ((uint8_t)0x0CU) /*!< ADC channel 12 */ +#define ADC_CHANNEL_13 ((uint8_t)0x0DU) /*!< ADC channel 13 */ +#define ADC_CHANNEL_14 ((uint8_t)0x0EU) /*!< ADC channel 14 */ +#define ADC_CHANNEL_15 ((uint8_t)0x0FU) /*!< ADC channel 15 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ + +/* analog watchdog 1 channel selection for channel n(n=0..17) */ +#define ADC_AWD1_SELECTION_CHANNEL_0 ((uint32_t)0x00000001U) /*!< ADC channel 0 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_1 ((uint32_t)0x00000002U) /*!< ADC channel 1 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_2 ((uint32_t)0x00000004U) /*!< ADC channel 2 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_3 ((uint32_t)0x00000008U) /*!< ADC channel 3 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_4 ((uint32_t)0x00000010U) /*!< ADC channel 4 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_5 ((uint32_t)0x00000020U) /*!< ADC channel 5 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_6 ((uint32_t)0x00000040U) /*!< ADC channel 6 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_7 ((uint32_t)0x00000080U) /*!< ADC channel 7 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_8 ((uint32_t)0x00000100U) /*!< ADC channel 8 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_9 ((uint32_t)0x00000200U) /*!< ADC channel 9 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_10 ((uint32_t)0x00000400U) /*!< ADC channel 10 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_11 ((uint32_t)0x00000800U) /*!< ADC channel 11 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_12 ((uint32_t)0x00001000U) /*!< ADC channel 12 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_13 ((uint32_t)0x00002000U) /*!< ADC channel 13 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_14 ((uint32_t)0x00004000U) /*!< ADC channel 14 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_15 ((uint32_t)0x00008000U) /*!< ADC channel 15 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_16 ((uint32_t)0x00010000U) /*!< ADC channel 16 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_17 ((uint32_t)0x00020000U) /*!< ADC channel 17 analog watchdog 1 selection */ +#define ADC_AWD1_SELECTION_CHANNEL_ALL ((uint32_t)0x0003FFFFU) /*!< all ADC channels analog watchdog 1 selection */ + +/* ADC interrupt */ +#define ADC_INT_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event interrupt */ +#define ADC_INT_EOC ADC_STAT_EOC /*!< end of group conversion interrupt */ +#define ADC_INT_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */ +#define ADC_INT_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event interrupt */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WDE0 ADC_STAT_WDE0 /*!< analog watchdog 0 event interrupt flag */ +#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt flag */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt flag */ +#define ADC_INT_FLAG_WDE1 ADC_STAT_WDE1 /*!< analog watchdog 1 event interrupt flag */ + +/* function declarations */ + +/* ADC deinitialization and initialization functions */ +/* reset ADC */ +void adc_deinit(uint32_t adc_periph); +/* enable ADC interface */ +void adc_enable(uint32_t adc_periph); +/* disable ADC interface */ +void adc_disable(uint32_t adc_periph); + +/* ADC calibration and DMA functions */ +/* ADC calibration and reset calibration */ +void adc_calibration_enable(uint32_t adc_periph); +/* enable DMA request */ +void adc_dma_mode_enable(uint32_t adc_periph); +/* disable DMA request */ +void adc_dma_mode_disable(uint32_t adc_periph); + +/* configure ADC temperature sensor and vrefint channel */ +/* enable the temperature sensor channel */ +void adc_tempsensor_enable(void); +/* disable the temperature sensor channel */ +void adc_tempsensor_disable(void); +/* enable vrefint channel */ +void adc_vrefint_enable(void); +/* disable vrefint channel */ +void adc_vrefint_disable(void); + +/* ADC special function functions */ +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint32_t adc_periph , uint8_t adc_channel_group , uint8_t length); +/* configure the ADC0 mode */ +void adc_mode_config(uint32_t mode); +/* configure ADC special function */ +void adc_special_function_config(uint32_t adc_periph , uint32_t function , ControlStatus newvalue); + +/* ADC channel configuration functions */ +/* configure ADC data alignment */ +void adc_data_alignment_config(uint32_t adc_periph , uint32_t data_alignment); +/* configure the length of regular channel group or inserted channel group */ +void adc_channel_length_config(uint32_t adc_periph , uint8_t adc_channel_group , uint32_t length); +/* configure ADC regular channel */ +void adc_regular_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); +/* configure ADC inserted channel */ +void adc_inserted_channel_config(uint32_t adc_periph , uint8_t rank , uint8_t adc_channel , uint32_t sample_time); +/* configure ADC inserted channel offset */ +void adc_inserted_channel_offset_config(uint32_t adc_periph , uint8_t inserted_channel , uint16_t offset); + + +/* ADC external trigger functions */ +/* configure ADC external trigger */ +void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue); +/* configure ADC external trigger source */ +void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint32_t adc_periph , uint8_t adc_channel_group); + +/* ADC data read functions */ +/* read ADC regular group data register */ +uint16_t adc_regular_data_read(uint32_t adc_periph); +/* read ADC inserted group data register */ +uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel); +/* read the last ADC0 and ADC1 conversion result data in sync mode */ +uint32_t adc_sync_mode_convert_value_read(void); + +/* ADC analog watchdog functions */ +/* configure ADC analog watchdog 0 single channel */ +void adc_watchdog0_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel); +/* configure ADC analog watchdog 0 group channel */ +void adc_watchdog0_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group); +/* disable ADC analog watchdog 0 */ +void adc_watchdog0_disable(uint32_t adc_periph); +/* configure ADC analog watchdog 1 channel */ +void adc_watchdog1_channel_config(uint32_t adc_periph, uint32_t adc_channel, ControlStatus newvalue); +/* disable ADC analog watchdog 1 */ +void adc_watchdog1_disable(uint32_t adc_periph); +/* configure ADC analog watchdog 0 threshold */ +void adc_watchdog0_threshold_config(uint32_t adc_periph , uint16_t low_threshold , uint16_t high_threshold); +/* configure ADC analog watchdog 1 threshold */ +void adc_watchdog1_threshold_config(uint32_t adc_periph , uint8_t low_threshold , uint8_t high_threshold); + +/* ADC resolution and oversample functions */ +/* configure ADC resolution */ +void adc_resolution_config(uint32_t adc_periph , uint32_t resolution); +/* configure ADC oversample mode */ +void adc_oversample_mode_config(uint32_t adc_periph , uint32_t mode , uint16_t shift , uint8_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(uint32_t adc_periph); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(uint32_t adc_periph); + +/* flag and interrupt functions */ +/* get the ADC flag */ +FlagStatus adc_flag_get(uint32_t adc_periph , uint32_t flag); +/* clear the ADC flag */ +void adc_flag_clear(uint32_t adc_periph , uint32_t flag); +/* enable ADC interrupt */ +void adc_interrupt_enable(uint32_t adc_periph , uint32_t interrupt); +/* disable ADC interrupt */ +void adc_interrupt_disable(uint32_t adc_periph , uint32_t interrupt); +/* get the ADC interrupt */ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t int_flag); +/* clear the ADC flag */ +void adc_interrupt_flag_clear(uint32_t adc_periph , uint32_t int_flag); + +#endif /* GD32A50X_ADC_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_bkp.h b/gd32a50x/standard_peripheral/include/gd32a50x_bkp.h new file mode 100644 index 0000000..61993ed --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_bkp.h @@ -0,0 +1,184 @@ +/*! + \file gd32a50x_bkp.h + \brief definitions for the BKP + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_BKP_H +#define GD32A50X_BKP_H + +#include "gd32a50x.h" + +/* BKP definitions */ +#define BKP BKP_BASE /*!< BKP base address */ + +/* registers definitions */ +#define BKP_DATA0 REG16((BKP) + 0x0004U) /*!< BKP data register 0 */ +#define BKP_DATA1 REG16((BKP) + 0x0008U) /*!< BKP data register 1 */ +#define BKP_DATA2 REG16((BKP) + 0x000CU) /*!< BKP data register 2 */ +#define BKP_DATA3 REG16((BKP) + 0x0010U) /*!< BKP data register 3 */ +#define BKP_DATA4 REG16((BKP) + 0x0014U) /*!< BKP data register 4 */ +#define BKP_DATA5 REG16((BKP) + 0x0018U) /*!< BKP data register 5 */ +#define BKP_DATA6 REG16((BKP) + 0x001CU) /*!< BKP data register 6 */ +#define BKP_DATA7 REG16((BKP) + 0x0020U) /*!< BKP data register 7 */ +#define BKP_DATA8 REG16((BKP) + 0x0024U) /*!< BKP data register 8 */ +#define BKP_DATA9 REG16((BKP) + 0x0028U) /*!< BKP data register 9 */ +#define BKP_OCTL REG16((BKP) + 0x002CU) /*!< RTC signal output control register */ +#define BKP_TPCTL REG16((BKP) + 0x0030U) /*!< tamper pin control register */ +#define BKP_TPCS REG16((BKP) + 0x0034U) /*!< tamper control and status register */ + +/* bits definitions */ +/* BKP_DATA */ +#define BKP_DATA BITS(0,15) /*!< backup data */ + +/* BKP_OCTL */ +#define BKP_OCTL_RCCV BITS(0,6) /*!< RTC clock calibration value */ +#define BKP_OCTL_COEN BIT(7) /*!< RTC clock calibration output enable */ +#define BKP_OCTL_ASOEN BIT(8) /*!< RTC alarm or second signal output enable */ +#define BKP_OCTL_ROSEL BIT(9) /*!< RTC output selection */ +#define BKP_OCTL_CCOSEL BIT(14) /*!< RTC clock output selection */ +#define BKP_OCTL_CALDIR BIT(15) /*!< RTC clock calibration direction */ + +/* BKP_TPCTL */ +#define BKP_TPCTL_TPEN BIT(0) /*!< tamper detection enable */ +#define BKP_TPCTL_TPAL BIT(1) /*!< tamper pin active level */ +#define BKP_TPCTL_PCSEL BIT(15) /*!< OSC32IN pin select */ + +/* BKP_TPCS */ +#define BKP_TPCS_TER BIT(0) /*!< tamper event reset */ +#define BKP_TPCS_TIR BIT(1) /*!< tamper interrupt reset */ +#define BKP_TPCS_TPIE BIT(2) /*!< tamper interrupt enable */ +#define BKP_TPCS_TEF BIT(8) /*!< tamper event flag */ +#define BKP_TPCS_TIF BIT(9) /*!< tamper interrupt flag */ + +/* constants definitions */ +/* BKP register */ +#define BKP_DATA0_9(number) REG16((BKP) + 0x04U + (number) * 0x04U) + +/* get data of BKP data register */ +#define BKP_DATA_GET(regval) GET_BITS((uint32_t)(regval), 0, 15) + +/* RTC clock calibration value */ +#define OCTL_RCCV(regval) (BITS(0,6) & (uint32_t)(regval)) + +/* RTC output selection */ +#define RTC_OUTPUT_ALARM_PULSE ((uint16_t)0x0000U) /*!< RTC alarm pulse is selected as the RTC output */ +#define RTC_OUTPUT_SECOND_PULSE ((uint16_t)0x0200U) /*!< RTC second pulse is selected as the RTC output */ + +/* RTC clock output selection */ +#define RTC_CLOCK_DIV_64 ((uint16_t)0x0000U) /*!< RTC clock div 64 */ +#define RTC_CLOCK_DIV_1 ((uint16_t)0x4000U) /*!< RTC clock div 1 */ + +/* RTC clock calibration direction */ +#define RTC_CLOCK_SLOWED_DOWN ((uint16_t)0x0000U) /*!< RTC clock slow down */ +#define RTC_CLOCK_SPEED_UP ((uint16_t)0x8000U) /*!< RTC clock speed up */ + +/* OSC32IN pin select */ +#define OSC32IN_PC13 ((uint16_t)0x0000U) /*!< OSC32IN pin is PC13 */ +#define OSC32IN_PC14 ((uint16_t)0x8000U) /*!< OSC32IN pin is PC14 */ + +/* tamper pin active level */ +#define TAMPER_PIN_ACTIVE_HIGH ((uint16_t)0x0000U) /*!< the tamper pin is active high */ +#define TAMPER_PIN_ACTIVE_LOW ((uint16_t)0x0002U) /*!< the tamper pin is active low */ + +/* tamper flag */ +#define BKP_FLAG_TAMPER BKP_TPCS_TEF /*!< tamper event flag */ + +/* tamper interrupt flag */ +#define BKP_INT_FLAG_TAMPER BKP_TPCS_TIF /*!< tamper interrupt flag */ + +/* BKP data register number */ +typedef enum +{ + BKP_DATA_0 = 1, /*!< BKP data register 0 */ + BKP_DATA_1, /*!< BKP data register 1 */ + BKP_DATA_2, /*!< BKP data register 2 */ + BKP_DATA_3, /*!< BKP data register 3 */ + BKP_DATA_4, /*!< BKP data register 4 */ + BKP_DATA_5, /*!< BKP data register 5 */ + BKP_DATA_6, /*!< BKP data register 6 */ + BKP_DATA_7, /*!< BKP data register 7 */ + BKP_DATA_8, /*!< BKP data register 8 */ + BKP_DATA_9, /*!< BKP data register 9 */ +}bkp_data_register_enum; + +/* function declarations */ +/* reset BKP registers */ +void bkp_deinit(void); +/* write BKP data register */ +void bkp_data_write(bkp_data_register_enum register_number, uint16_t data); +/* read BKP data register */ +uint16_t bkp_data_read(bkp_data_register_enum register_number); + +/* RTC related functions */ +/* enable RTC clock calibration output */ +void bkp_rtc_calibration_output_enable(void); +/* disable RTC clock calibration output */ +void bkp_rtc_calibration_output_disable(void); +/* enable RTC alarm or second signal output */ +void bkp_rtc_signal_output_enable(void); +/* disable RTC alarm or second signal output */ +void bkp_rtc_signal_output_disable(void); +/* select RTC output */ +void bkp_rtc_output_select(uint16_t outputsel); +/* select RTC clock output */ +void bkp_rtc_clock_output_select(uint16_t clocksel); +/* RTC clock calibration direction */ +void bkp_rtc_clock_calibration_direction(uint16_t direction); +/* set RTC clock calibration value */ +void bkp_rtc_calibration_value_set(uint8_t value); + +/* select OSC32IN pin */ +void bkp_osc32in_pin_select(uint16_t inputpin); + +/* tamper pin related functions */ +/* enable tamper pin detection */ +void bkp_tamper_detection_enable(void); +/* disable tamper pin detection */ +void bkp_tamper_detection_disable(void); +/* set tamper pin active level */ +void bkp_tamper_active_level_set(uint16_t level); +/* enable tamper pin interrupt */ +void bkp_tamper_interrupt_enable(void); +/* disable tamper pin interrupt */ +void bkp_tamper_interrupt_disable(void); + +/* flag functions */ +/* get BKP flag state */ +FlagStatus bkp_flag_get(uint16_t flag); +/* clear BKP flag state */ +void bkp_flag_clear(uint16_t flag); +/* get BKP interrupt flag state */ +FlagStatus bkp_interrupt_flag_get(uint16_t flag); +/* clear BKP interrupt flag state */ +void bkp_interrupt_flag_clear(uint16_t flag); + +#endif /* GD32A50X_BKP_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_can.h b/gd32a50x/standard_peripheral/include/gd32a50x_can.h new file mode 100644 index 0000000..5d679b6 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_can.h @@ -0,0 +1,1274 @@ +/*! + \file gd32a50x_can.h + \brief definitions for the CAN + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_CAN_H +#define GD32A50X_CAN_H + +#include "gd32a50x.h" + +/* CAN definitions */ +#define CAN0 CAN_BASE /*!< CAN0 base address */ +#define CAN1 (CAN_BASE + 0x00001000U) /*!< CAN1 base address */ +#define CAN_RAM(canx) ((uint32_t)((canx) + 0x00000080U)) /*!< can ram base address */ +#define CAN_PN_RAM(canx) ((uint32_t)(canx) + 0x00000B40U) /*!< Pretended Networking ram base address */ + +/* registers definitions */ +#define CAN_CTL0(canx) REG32((canx) + 0x00000000U) /*!< CAN control register 0 */ +#define CAN_CTL1(canx) REG32((canx) + 0x00000004U) /*!< CAN control register 1 */ +#define CAN_TIMER(canx) REG32((canx) + 0x00000008U) /*!< CAN timer register */ +#define CAN_RMPUBF(canx) REG32((canx) + 0x00000010U) /*!< CAN receive mailbox public filter register */ +#define CAN_ERR0(canx) REG32((canx) + 0x0000001CU) /*!< CAN error register 0 */ +#define CAN_ERR1(canx) REG32((canx) + 0x00000020U) /*!< CAN error register 1 */ +#define CAN_INTEN(canx) REG32((canx) + 0x00000028U) /*!< CAN interrupt enable register */ +#define CAN_STAT(canx) REG32((canx) + 0x00000030U) /*!< CAN status register */ +#define CAN_CTL2(canx) REG32((canx) + 0x00000034U) /*!< CAN control register 2 */ +#define CAN_CRCC(canx) REG32((canx) + 0x00000044U) /*!< CAN crc for classical frame register */ +#define CAN_RFIFOPUBF(canx) REG32((canx) + 0x00000048U) /*!< CAN receive fifo public filter register */ +#define CAN_RFIFOIFMN(canx) REG32((canx) + 0x0000004CU) /*!< CAN receive fifo identifier filter matching number register */ +#define CAN_BT(canx) REG32((canx) + 0x00000050U) /*!< CAN bit timing register */ +#define CAN_RFIFOMPF0(canx) REG32((canx) + 0x00000880U) /*!< CAN receive fifo / mailbox private filter 0 register */ +#define CAN_RFIFOMPF1(canx) REG32((canx) + 0x00000884U) /*!< CAN receive fifo / mailbox private filter 1 register */ +#define CAN_RFIFOMPF2(canx) REG32((canx) + 0x00000888U) /*!< CAN receive fifo / mailbox private filter 2 register */ +#define CAN_RFIFOMPF3(canx) REG32((canx) + 0x0000088CU) /*!< CAN receive fifo / mailbox private filter 3 register */ +#define CAN_RFIFOMPF4(canx) REG32((canx) + 0x00000890U) /*!< CAN receive fifo / mailbox private filter 4 register */ +#define CAN_RFIFOMPF5(canx) REG32((canx) + 0x00000894U) /*!< CAN receive fifo / mailbox private filter 5 register */ +#define CAN_RFIFOMPF6(canx) REG32((canx) + 0x00000898U) /*!< CAN receive fifo / mailbox private filter 6 register */ +#define CAN_RFIFOMPF7(canx) REG32((canx) + 0x0000089CU) /*!< CAN receive fifo / mailbox private filter 7 register */ +#define CAN_RFIFOMPF8(canx) REG32((canx) + 0x000008A0U) /*!< CAN receive fifo / mailbox private filter 8 register */ +#define CAN_RFIFOMPF9(canx) REG32((canx) + 0x000008A4U) /*!< CAN receive fifo / mailbox private filter 9 register */ +#define CAN_RFIFOMPF10(canx) REG32((canx) + 0x000008A8U) /*!< CAN receive fifo / mailbox private filter 10 register */ +#define CAN_RFIFOMPF11(canx) REG32((canx) + 0x000008ACU) /*!< CAN receive fifo / mailbox private filter 11 register */ +#define CAN_RFIFOMPF12(canx) REG32((canx) + 0x000008B0U) /*!< CAN receive fifo / mailbox private filter 12 register */ +#define CAN_RFIFOMPF13(canx) REG32((canx) + 0x000008B4U) /*!< CAN receive fifo / mailbox private filter 13 register */ +#define CAN_RFIFOMPF14(canx) REG32((canx) + 0x000008B8U) /*!< CAN receive fifo / mailbox private filter 14 register */ +#define CAN_RFIFOMPF15(canx) REG32((canx) + 0x000008BCU) /*!< CAN receive fifo / mailbox private filter 15 register */ +#define CAN_RFIFOMPF16(canx) REG32((canx) + 0x000008C0U) /*!< CAN receive fifo / mailbox private filter 16 register */ +#define CAN_RFIFOMPF17(canx) REG32((canx) + 0x000008C4U) /*!< CAN receive fifo / mailbox private filter 17 register */ +#define CAN_RFIFOMPF18(canx) REG32((canx) + 0x000008C8U) /*!< CAN receive fifo / mailbox private filter 18 register */ +#define CAN_RFIFOMPF19(canx) REG32((canx) + 0x000008CCU) /*!< CAN receive fifo / mailbox private filter 19 register */ +#define CAN_RFIFOMPF20(canx) REG32((canx) + 0x000008D0U) /*!< CAN receive fifo / mailbox private filter 20 register */ +#define CAN_RFIFOMPF21(canx) REG32((canx) + 0x000008D4U) /*!< CAN receive fifo / mailbox private filter 21 register */ +#define CAN_RFIFOMPF22(canx) REG32((canx) + 0x000008D8U) /*!< CAN receive fifo / mailbox private filter 22 register */ +#define CAN_RFIFOMPF23(canx) REG32((canx) + 0x000008DCU) /*!< CAN receive fifo / mailbox private filter 23 register */ +#define CAN_RFIFOMPF24(canx) REG32((canx) + 0x000008E0U) /*!< CAN receive fifo / mailbox private filter 24 register */ +#define CAN_RFIFOMPF25(canx) REG32((canx) + 0x000008E4U) /*!< CAN receive fifo / mailbox private filter 25 register */ +#define CAN_RFIFOMPF26(canx) REG32((canx) + 0x000008E8U) /*!< CAN receive fifo / mailbox private filter 26 register */ +#define CAN_RFIFOMPF27(canx) REG32((canx) + 0x000008ECU) /*!< CAN receive fifo / mailbox private filter 27 register */ +#define CAN_RFIFOMPF28(canx) REG32((canx) + 0x000008F0U) /*!< CAN receive fifo / mailbox private filter 28 register */ +#define CAN_RFIFOMPF29(canx) REG32((canx) + 0x000008F4U) /*!< CAN receive fifo / mailbox private filter 29 register */ +#define CAN_RFIFOMPF30(canx) REG32((canx) + 0x000008F8U) /*!< CAN receive fifo / mailbox private filter 30 register */ +#define CAN_RFIFOMPF31(canx) REG32((canx) + 0x000008FCU) /*!< CAN receive fifo / mailbox private filter 31 register */ +#define CAN_PN_CTL0(canx) REG32((canx) + 0x00000B00U) /*!< Pretended Networking mode control register 0 */ +#define CAN_PN_TO(canx) REG32((canx) + 0x00000B04U) /*!< Pretended Networking mode timeout register */ +#define CAN_PN_STAT(canx) REG32((canx) + 0x00000B08U) /*!< Pretended Networking mode status register */ +#define CAN_PN_EID0(canx) REG32((canx) + 0x00000B0CU) /*!< Pretended Networking mode expected identifier 0 register */ +#define CAN_PN_EDLC(canx) REG32((canx) + 0x00000B10U) /*!< Pretended Networking mode expected dlc register */ +#define CAN_PN_EDL0(canx) REG32((canx) + 0x00000B14U) /*!< Pretended Networking mode expected data low 0 register */ +#define CAN_PN_EDL1(canx) REG32((canx) + 0x00000B18U) /*!< Pretended Networking mode expected data low 1 register */ +#define CAN_PN_IFEID1(canx) REG32((canx) + 0x00000B1CU) /*!< Pretended Networking mode identifier filter / expected identifier 1 register */ +#define CAN_PN_DF0EDH0(canx) REG32((canx) + 0x00000B20U) /*!< Pretended Networking mode data 0 filter / expected data high 0 register */ +#define CAN_PN_DF1EDH1(canx) REG32((canx) + 0x00000B24U) /*!< Pretended Networking mode data 1 filter / expected data high 1 register */ +#define CAN_PN_RWM0CS(canx) REG32((canx) + 0x00000B40U) /*!< Pretended Networking mode received wakeup mailbox 0 control status information register */ +#define CAN_PN_RWM0I(canx) REG32((canx) + 0x00000B44U) /*!< Pretended Networking mode received wakeup mailbox 0 identifier register */ +#define CAN_PN_RWM0D0(canx) REG32((canx) + 0x00000B48U) /*!< Pretended Networking mode received wakeup mailbox 0 data 0 register */ +#define CAN_PN_RWM0D1(canx) REG32((canx) + 0x00000B4CU) /*!< Pretended Networking mode received wakeup mailbox 0 data 1 register */ +#define CAN_PN_RWM1CS(canx) REG32((canx) + 0x00000B50U) /*!< Pretended Networking mode received wakeup mailbox 1 control status information register */ +#define CAN_PN_RWM1I(canx) REG32((canx) + 0x00000B54U) /*!< Pretended Networking mode received wakeup mailbox 1 identifier register */ +#define CAN_PN_RWM1D0(canx) REG32((canx) + 0x00000B58U) /*!< Pretended Networking mode received wakeup mailbox 1 data 0 register */ +#define CAN_PN_RWM1D1(canx) REG32((canx) + 0x00000B5CU) /*!< Pretended Networking mode received wakeup mailbox 1 data 1 register */ +#define CAN_PN_RWM2CS(canx) REG32((canx) + 0x00000B60U) /*!< Pretended Networking mode received wakeup mailbox 2 control status information register */ +#define CAN_PN_RWM2I(canx) REG32((canx) + 0x00000B64U) /*!< Pretended Networking mode received wakeup mailbox 2 identifier register */ +#define CAN_PN_RWM2D0(canx) REG32((canx) + 0x00000B68U) /*!< Pretended Networking mode received wakeup mailbox 2 data 0 register */ +#define CAN_PN_RWM2D1(canx) REG32((canx) + 0x00000B6CU) /*!< Pretended Networking mode received wakeup mailbox 2 data 1 register */ +#define CAN_PN_RWM3CS(canx) REG32((canx) + 0x00000B70U) /*!< Pretended Networking mode received wakeup mailbox 3 control status information register */ +#define CAN_PN_RWM3I(canx) REG32((canx) + 0x00000B74U) /*!< Pretended Networking mode received wakeup mailbox 3 identifier register */ +#define CAN_PN_RWM3D0(canx) REG32((canx) + 0x00000B78U) /*!< Pretended Networking mode received wakeup mailbox 3 data 0 register */ +#define CAN_PN_RWM3D1(canx) REG32((canx) + 0x00000B7CU) /*!< Pretended Networking mode received wakeup mailbox 3 data 1 register */ +#define CAN_FDCTL(canx) REG32((canx) + 0x00000C00U) /*!< CAN FD control register */ +#define CAN_FDBT(canx) REG32((canx) + 0x00000C04U) /*!< CAN bit timing register */ +#define CAN_CRCCFD(canx) REG32((canx) + 0x00000C08U) /*!< CAN CRC for classical and FD frame register */ + +/* bits definitions */ +/* CAN_CTL0 */ +#define CAN_CTL0_MSZ BITS(0, 4) /*!< memory size */ +#define CAN_CTL0_FS BITS(8, 9) /*!< format selection */ +#define CAN_CTL0_FDEN BIT(11) /*!< CAN FD operation enable */ +#define CAN_CTL0_MST BIT(12) /*!< mailbox stop transmission */ +#define CAN_CTL0_LAPRIOEN BIT(13) /*!< enable local arbitration priority */ +#define CAN_CTL0_PNMOD BIT(14) /*!< Pretended Networking mode selection */ +#define CAN_CTL0_DMAEN BIT(15) /*!< enable DMA */ +#define CAN_CTL0_RPFQEN BIT(16) /*!< enable rx private filters enable & rx mailbox queue */ +#define CAN_CTL0_SRDIS BIT(17) /*!< enable self reception */ +#define CAN_CTL0_PNS BIT(18) /*!< Pretended Networking state */ +#define CAN_CTL0_PNEN BIT(19) /*!< enable Pretended Networking mode */ +#define CAN_CTL0_LPS BIT(20) /*!< low power state */ +#define CAN_CTL0_WERREN BIT(21) /*!< enable error warning */ +#define CAN_CTL0_INAS BIT(24) /*!< inactive mode state */ +#define CAN_CTL0_SWRST BIT(25) /*!< software reset */ +#define CAN_CTL0_NRDY BIT(27) /*!< not ready */ +#define CAN_CTL0_HALT BIT(28) /*!< halt CAN */ +#define CAN_CTL0_RFEN BIT(29) /*!< rx fifo enable */ +#define CAN_CTL0_INAMOD BIT(30) /*!< enable inactive mode */ +#define CAN_CTL0_CANDIS BIT(31) /*!< disable CAN */ + +/* CAN_CTL1 */ +#define CAN_CTL1_MMOD BIT(3) /*!< monitor mode */ +#define CAN_CTL1_MTO BIT(4) /*!< mailbox transmission order */ +#define CAN_CTL1_TSYNC BIT(5) /*!< enable time synchronization */ +#define CAN_CTL1_ABORDIS BIT(6) /*!< not enable automatic bus off recovery */ +#define CAN_CTL1_BSPMOD BIT(7) /*!< bit sampling mode */ +#define CAN_CTL1_RWERRIE BIT(10) /*!< enable rx error warning interrupt */ +#define CAN_CTL1_TWERRIE BIT(11) /*!< enable tx error warning interrupt */ +#define CAN_CTL1_LSCMOD BIT(12) /*!< loopback and silent communication mode */ +#define CAN_CTL1_ERRSIE BIT(14) /*!< enable error summary interrupt */ +#define CAN_CTL1_BOIE BIT(15) /*!< enable bus off interrupt */ + +/* CAN_TIMER */ +#define CAN_TIMER_CNT BITS(0,15) /*!< counter value */ + +/* CAN_RMPUBF */ +#define CAN_RMPUBF_MFD0 BIT(0) /*!< mailbox filter data bit 0 */ +#define CAN_RMPUBF_MFD1 BIT(1) /*!< mailbox filter data bit 1 */ +#define CAN_RMPUBF_MFD2 BIT(2) /*!< mailbox filter data bit 2 */ +#define CAN_RMPUBF_MFD3 BIT(3) /*!< mailbox filter data bit 3 */ +#define CAN_RMPUBF_MFD4 BIT(4) /*!< mailbox filter data bit 4 */ +#define CAN_RMPUBF_MFD5 BIT(5) /*!< mailbox filter data bit 5 */ +#define CAN_RMPUBF_MFD6 BIT(6) /*!< mailbox filter data bit 6 */ +#define CAN_RMPUBF_MFD7 BIT(7) /*!< mailbox filter data bit 7 */ +#define CAN_RMPUBF_MFD8 BIT(8) /*!< mailbox filter data bit 8 */ +#define CAN_RMPUBF_MFD9 BIT(9) /*!< mailbox filter data bit 9 */ +#define CAN_RMPUBF_MFD10 BIT(10) /*!< mailbox filter data bit 10 */ +#define CAN_RMPUBF_MFD11 BIT(11) /*!< mailbox filter data bit 11 */ +#define CAN_RMPUBF_MFD12 BIT(12) /*!< mailbox filter data bit 12 */ +#define CAN_RMPUBF_MFD13 BIT(13) /*!< mailbox filter data bit 13 */ +#define CAN_RMPUBF_MFD14 BIT(14) /*!< mailbox filter data bit 14 */ +#define CAN_RMPUBF_MFD15 BIT(15) /*!< mailbox filter data bit 15 */ +#define CAN_RMPUBF_MFD16 BIT(16) /*!< mailbox filter data bit 16 */ +#define CAN_RMPUBF_MFD17 BIT(17) /*!< mailbox filter data bit 17 */ +#define CAN_RMPUBF_MFD18 BIT(18) /*!< mailbox filter data bit 18 */ +#define CAN_RMPUBF_MFD19 BIT(19) /*!< mailbox filter data bit 19 */ +#define CAN_RMPUBF_MFD20 BIT(20) /*!< mailbox filter data bit 20 */ +#define CAN_RMPUBF_MFD21 BIT(21) /*!< mailbox filter data bit 21 */ +#define CAN_RMPUBF_MFD22 BIT(22) /*!< mailbox filter data bit 22 */ +#define CAN_RMPUBF_MFD23 BIT(23) /*!< mailbox filter data bit 23 */ +#define CAN_RMPUBF_MFD24 BIT(24) /*!< mailbox filter data bit 24 */ +#define CAN_RMPUBF_MFD25 BIT(25) /*!< mailbox filter data bit 25 */ +#define CAN_RMPUBF_MFD26 BIT(26) /*!< mailbox filter data bit 26 */ +#define CAN_RMPUBF_MFD27 BIT(27) /*!< mailbox filter data bit 27 */ +#define CAN_RMPUBF_MFD28 BIT(28) /*!< mailbox filter data bit 28 */ +#define CAN_RMPUBF_MFD29 BIT(29) /*!< mailbox filter data bit 29 */ +#define CAN_RMPUBF_MFD30 BIT(30) /*!< mailbox filter data bit 30 */ +#define CAN_RMPUBF_MFD31 BIT(31) /*!< mailbox filter data bit 31 */ + +/* CAN_ERR0 */ +#define CAN_ERR0_TECNT BITS(0, 7) /*!< transmit error count defined by the CAN standard */ +#define CAN_ERR0_RECNT BITS(8, 15) /*!< receive error count defined by the CAN standard */ +#define CAN_ERR0_TEFCNT BITS(16, 23) /*!< transmit error count for the data phase of FD frames with BRS bit set */ +#define CAN_ERR0_REFCNT BITS(24, 31) /*!< receive error count for the data phase of FD frames with BRS bit set */ + +/* CAN_ERR1 */ +#define CAN_ERR1_ERRSF BIT(1) /*!< error summary flag */ +#define CAN_ERR1_BOF BIT(2) /*!< bus off flag */ +#define CAN_ERR1_RS BIT(3) /*!< receiving state */ +#define CAN_ERR1_ERRSI BITS(4, 5) /*!< error state indicator */ +#define CAN_ERR1_TS BIT(6) /*!< transmitting state */ +#define CAN_ERR1_IDLEF BIT(7) /*!< idle flag */ +#define CAN_ERR1_RWERRF BIT(8) /*!< rx error warning flag */ +#define CAN_ERR1_TWERRF BIT(9) /*!< tx error warning flag */ +#define CAN_ERR1_STFERR BIT(10) /*!< stuff error */ +#define CAN_ERR1_FMERR BIT(11) /*!< form error */ +#define CAN_ERR1_CRCERR BIT(12) /*!< CRC error */ +#define CAN_ERR1_ACKERR BIT(13) /*!< ACK error */ +#define CAN_ERR1_BDERR BIT(14) /*!< bit dominant error for all format frames */ +#define CAN_ERR1_BRERR BIT(15) /*!< bit recessive error for all format frames */ +#define CAN_ERR1_RWERRIF BIT(16) /*!< rx error warning interrupt flag */ +#define CAN_ERR1_TWERRIF BIT(17) /*!< tx error warning interrupt flag */ +#define CAN_ERR1_SYN BIT(18) /*!< synchronization flag */ +#define CAN_ERR1_BORF BIT(19) /*!< bus off recovery flag */ +#define CAN_ERR1_ERRFSF BIT(20) /*!< error summary flag for data phase of FD frames with BRS bit set */ +#define CAN_ERR1_ERROVR BIT(21) /*!< error overrun */ +#define CAN_ERR1_STFFERR BIT(26) /*!< stuff error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_FMFERR BIT(27) /*!< form error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_CRCFERR BIT(28) /*!< CRC error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_BDFERR BIT(30) /*!< bit dominant error in data phase of FD frames with BRS bit set */ +#define CAN_ERR1_BRFERR BIT(31) /*!< bit recessive error in data phase of FD frames with BRS bit set */ + +/* CAN_INTEN */ +#define CAN_INTEN_MIE0 BIT(0) /*!< enable message 0 transmission and reception interrupt */ +#define CAN_INTEN_MIE1 BIT(1) /*!< enable message 1 transmission and reception interrupt */ +#define CAN_INTEN_MIE2 BIT(2) /*!< enable message 2 transmission and reception interrupt */ +#define CAN_INTEN_MIE3 BIT(3) /*!< enable message 3 transmission and reception interrupt */ +#define CAN_INTEN_MIE4 BIT(4) /*!< enable message 4 transmission and reception interrupt */ +#define CAN_INTEN_MIE5 BIT(5) /*!< enable message 5 transmission and reception interrupt */ +#define CAN_INTEN_MIE6 BIT(6) /*!< enable message 6 transmission and reception interrupt */ +#define CAN_INTEN_MIE7 BIT(7) /*!< enable message 7 transmission and reception interrupt */ +#define CAN_INTEN_MIE8 BIT(8) /*!< enable message 8 transmission and reception interrupt */ +#define CAN_INTEN_MIE9 BIT(9) /*!< enable message 9 transmission and reception interrupt */ +#define CAN_INTEN_MIE10 BIT(10) /*!< enable message 10 transmission and reception interrupt */ +#define CAN_INTEN_MIE11 BIT(11) /*!< enable message 11 transmission and reception interrupt */ +#define CAN_INTEN_MIE12 BIT(12) /*!< enable message 12 transmission and reception interrupt */ +#define CAN_INTEN_MIE13 BIT(13) /*!< enable message 13 transmission and reception interrupt */ +#define CAN_INTEN_MIE14 BIT(14) /*!< enable message 14 transmission and reception interrupt */ +#define CAN_INTEN_MIE15 BIT(15) /*!< enable message 15 transmission and reception interrupt */ +#define CAN_INTEN_MIE16 BIT(16) /*!< enable message 16 transmission and reception interrupt */ +#define CAN_INTEN_MIE17 BIT(17) /*!< enable message 17 transmission and reception interrupt */ +#define CAN_INTEN_MIE18 BIT(18) /*!< enable message 18 transmission and reception interrupt */ +#define CAN_INTEN_MIE19 BIT(19) /*!< enable message 19 transmission and reception interrupt */ +#define CAN_INTEN_MIE20 BIT(20) /*!< enable message 20 transmission and reception interrupt */ +#define CAN_INTEN_MIE21 BIT(21) /*!< enable message 21 transmission and reception interrupt */ +#define CAN_INTEN_MIE22 BIT(22) /*!< enable message 22 transmission and reception interrupt */ +#define CAN_INTEN_MIE23 BIT(23) /*!< enable message 23 transmission and reception interrupt */ +#define CAN_INTEN_MIE24 BIT(24) /*!< enable message 24 transmission and reception interrupt */ +#define CAN_INTEN_MIE25 BIT(25) /*!< enable message 25 transmission and reception interrupt */ +#define CAN_INTEN_MIE26 BIT(26) /*!< enable message 26 transmission and reception interrupt */ +#define CAN_INTEN_MIE27 BIT(27) /*!< enable message 27 transmission and reception interrupt */ +#define CAN_INTEN_MIE28 BIT(28) /*!< enable message 28 transmission and reception interrupt */ +#define CAN_INTEN_MIE29 BIT(29) /*!< enable message 29 transmission and reception interrupt */ +#define CAN_INTEN_MIE30 BIT(30) /*!< enable message 30 transmission and reception interrupt */ +#define CAN_INTEN_MIE31 BIT(31) /*!< enable message 31 transmission and reception interrupt */ + +/* CAN_STAT */ +#define CAN_STAT_MS0_RFC BIT(0) /*!< mailbox 0 state / clear rx fifo bit */ +#define CAN_STAT_MS1_RES BIT(1) /*!< mailbox 1 state */ +#define CAN_STAT_MS2_RES BIT(2) /*!< mailbox 2 state */ +#define CAN_STAT_MS3_RES BIT(3) /*!< mailbox 3 state */ +#define CAN_STAT_MS4_RES BIT(4) /*!< mailbox 4 state */ +#define CAN_STAT_MS5_RFNE BIT(5) /*!< mailbox 5 state / rx fifo not empty */ +#define CAN_STAT_MS6_RFW BIT(6) /*!< mailbox 6 state / rx fifo warning */ +#define CAN_STAT_MS7_RFO BIT(7) /*!< mailbox 7 state / rx fifo overflow */ +#define CAN_STAT_MS8 BIT(8) /*!< mailbox 8 state */ +#define CAN_STAT_MS9 BIT(9) /*!< mailbox 9 state */ +#define CAN_STAT_MS10 BIT(10) /*!< mailbox 10 state */ +#define CAN_STAT_MS11 BIT(11) /*!< mailbox 11 state */ +#define CAN_STAT_MS12 BIT(12) /*!< mailbox 12 state */ +#define CAN_STAT_MS13 BIT(13) /*!< mailbox 13 state */ +#define CAN_STAT_MS14 BIT(14) /*!< mailbox 14 state */ +#define CAN_STAT_MS15 BIT(15) /*!< mailbox 15 state */ +#define CAN_STAT_MS16 BIT(16) /*!< mailbox 16 state */ +#define CAN_STAT_MS17 BIT(17) /*!< mailbox 17 state */ +#define CAN_STAT_MS18 BIT(18) /*!< mailbox 18 state */ +#define CAN_STAT_MS19 BIT(19) /*!< mailbox 19 state */ +#define CAN_STAT_MS20 BIT(20) /*!< mailbox 20 state */ +#define CAN_STAT_MS21 BIT(21) /*!< mailbox 21 state */ +#define CAN_STAT_MS22 BIT(22) /*!< mailbox 22 state */ +#define CAN_STAT_MS23 BIT(23) /*!< mailbox 23 state */ +#define CAN_STAT_MS24 BIT(24) /*!< mailbox 24 state */ +#define CAN_STAT_MS25 BIT(25) /*!< mailbox 25 state */ +#define CAN_STAT_MS26 BIT(26) /*!< mailbox 26 state */ +#define CAN_STAT_MS27 BIT(27) /*!< mailbox 27 state */ +#define CAN_STAT_MS28 BIT(28) /*!< mailbox 28 state */ +#define CAN_STAT_MS29 BIT(29) /*!< mailbox 29 state */ +#define CAN_STAT_MS30 BIT(30) /*!< mailbox 30 state */ +#define CAN_STAT_MS31 BIT(31) /*!< mailbox 31 state */ + +/* CAN_CTL2 */ +#define CAN_CTL2_EFDIS BIT(11) /*!< disable edge filtering */ +#define CAN_CTL2_ISO BIT(12) /*!< ISO CAN FD */ +#define CAN_CTL2_PREEN BIT(14) /*!< protocol exception detection enable by CAN standard */ +#define CAN_CTL2_ITSRC BIT(15) /*!< internal counter source */ +#define CAN_CTL2_IDERTR_RMF BIT(16) /*!< IDE and RTR field filter type for rx mailbox reception */ +#define CAN_CTL2_RRFRMS BIT(17) /*!< remote request frame is stored */ +#define CAN_CTL2_RFO BIT(18) /*!< receive filter order */ +#define CAN_CTL2_ASD BITS(19, 23) /*!< arbitration start delay */ +#define CAN_CTL2_RFFN BITS(24, 27) /*!< rx fifo filter number */ +#define CAN_CTL2_BORIE BIT(30) /*!< enable bus off recovery interrupt */ +#define CAN_CTL2_ERRFSIE BIT(31) /*!< error summary interrupt enable bit for data phase of FD frames with BRS bit set */ + +/* CAN_CRCC */ +#define CAN_CRCC_CRCTC BITS(0, 14) /*!< transmitted CRC value for classical frames */ +#define CAN_CRCC_ANTM BITS(16, 20) /*!< associated number of mailbox for transmitting the CRCTC[14:0] value */ + +/* CAN_RFIFOPUBF */ +#define CAN_RFIFOPUBF_FFD0 BIT(0) /*!< rx fifo filter data bit 0 */ +#define CAN_RFIFOPUBF_FFD1 BIT(1) /*!< rx fifo filter data bit 1 */ +#define CAN_RFIFOPUBF_FFD2 BIT(2) /*!< rx fifo filter data bit 2 */ +#define CAN_RFIFOPUBF_FFD3 BIT(3) /*!< rx fifo filter data bit 3 */ +#define CAN_RFIFOPUBF_FFD4 BIT(4) /*!< rx fifo filter data bit 4 */ +#define CAN_RFIFOPUBF_FFD5 BIT(5) /*!< rx fifo filter data bit 5 */ +#define CAN_RFIFOPUBF_FFD6 BIT(6) /*!< rx fifo filter data bit 6 */ +#define CAN_RFIFOPUBF_FFD7 BIT(7) /*!< rx fifo filter data bit 7 */ +#define CAN_RFIFOPUBF_FFD8 BIT(8) /*!< rx fifo filter data bit 8 */ +#define CAN_RFIFOPUBF_FFD9 BIT(9) /*!< rx fifo filter data bit 9 */ +#define CAN_RFIFOPUBF_FFD10 BIT(10) /*!< rx fifo filter data bit 10 */ +#define CAN_RFIFOPUBF_FFD11 BIT(11) /*!< rx fifo filter data bit 11 */ +#define CAN_RFIFOPUBF_FFD12 BIT(12) /*!< rx fifo filter data bit 12 */ +#define CAN_RFIFOPUBF_FFD13 BIT(13) /*!< rx fifo filter data bit 13 */ +#define CAN_RFIFOPUBF_FFD14 BIT(14) /*!< rx fifo filter data bit 14 */ +#define CAN_RFIFOPUBF_FFD15 BIT(15) /*!< rx fifo filter data bit 15 */ +#define CAN_RFIFOPUBF_FFD16 BIT(16) /*!< rx fifo filter data bit 16 */ +#define CAN_RFIFOPUBF_FFD17 BIT(17) /*!< rx fifo filter data bit 17 */ +#define CAN_RFIFOPUBF_FFD18 BIT(18) /*!< rx fifo filter data bit 18 */ +#define CAN_RFIFOPUBF_FFD19 BIT(19) /*!< rx fifo filter data bit 19 */ +#define CAN_RFIFOPUBF_FFD20 BIT(20) /*!< rx fifo filter data bit 20 */ +#define CAN_RFIFOPUBF_FFD21 BIT(21) /*!< rx fifo filter data bit 21 */ +#define CAN_RFIFOPUBF_FFD22 BIT(22) /*!< rx fifo filter data bit 22 */ +#define CAN_RFIFOPUBF_FFD23 BIT(23) /*!< rx fifo filter data bit 23 */ +#define CAN_RFIFOPUBF_FFD24 BIT(24) /*!< rx fifo filter data bit 24 */ +#define CAN_RFIFOPUBF_FFD25 BIT(25) /*!< rx fifo filter data bit 25 */ +#define CAN_RFIFOPUBF_FFD26 BIT(26) /*!< rx fifo filter data bit 26 */ +#define CAN_RFIFOPUBF_FFD27 BIT(27) /*!< rx fifo filter data bit 27 */ +#define CAN_RFIFOPUBF_FFD28 BIT(28) /*!< rx fifo filter data bit 28 */ +#define CAN_RFIFOPUBF_FFD29 BIT(29) /*!< rx fifo filter data bit 29 */ +#define CAN_RFIFOPUBF_FFD30 BIT(30) /*!< rx fifo filter data bit 30 */ +#define CAN_RFIFOPUBF_FFD31 BIT(31) /*!< rx fifo filter data bit 31 */ + +/* CAN_RFIFOIFMN */ +#define CAN_RFIFOIFMN_IDFMN BITS(0, 8) /*!< identifier filter matching number */ + +/* CAN_BT */ +#define CAN_BT_PBS2 BITS(0, 4) /*!< phase buffer segment 2 */ +#define CAN_BT_PBS1 BITS(5, 9) /*!< phase buffer segment 1 */ +#define CAN_BT_PTS BITS(10, 15) /*!< propagation time segment */ +#define CAN_BT_SJW BITS(16, 20) /*!< resynchronization jump width */ +#define CAN_BT_BAUDPSC BITS(21, 30) /*!< baud rate prescaler */ + +/* CAN_RFIFOMPFx, x = 0..31 */ +#define CAN_RFIFOMPF_FMFD0 BIT(0) /*!< fifo / mailbox filter data bit 0 */ +#define CAN_RFIFOMPF_FMFD1 BIT(1) /*!< fifo / mailbox filter data bit 1 */ +#define CAN_RFIFOMPF_FMFD2 BIT(2) /*!< fifo / mailbox filter data bit 2 */ +#define CAN_RFIFOMPF_FMFD3 BIT(3) /*!< fifo / mailbox filter data bit 3 */ +#define CAN_RFIFOMPF_FMFD4 BIT(4) /*!< fifo / mailbox filter data bit 4 */ +#define CAN_RFIFOMPF_FMFD5 BIT(5) /*!< fifo / mailbox filter data bit 5 */ +#define CAN_RFIFOMPF_FMFD6 BIT(6) /*!< fifo / mailbox filter data bit 6 */ +#define CAN_RFIFOMPF_FMFD7 BIT(7) /*!< fifo / mailbox filter data bit 7 */ +#define CAN_RFIFOMPF_FMFD8 BIT(8) /*!< fifo / mailbox filter data bit 8 */ +#define CAN_RFIFOMPF_FMFD9 BIT(9) /*!< fifo / mailbox filter data bit 9 */ +#define CAN_RFIFOMPF_FMFD10 BIT(10) /*!< fifo / mailbox filter data bit 10 */ +#define CAN_RFIFOMPF_FMFD11 BIT(11) /*!< fifo / mailbox filter data bit 11 */ +#define CAN_RFIFOMPF_FMFD12 BIT(12) /*!< fifo / mailbox filter data bit 12 */ +#define CAN_RFIFOMPF_FMFD13 BIT(13) /*!< fifo / mailbox filter data bit 13 */ +#define CAN_RFIFOMPF_FMFD14 BIT(14) /*!< fifo / mailbox filter data bit 14 */ +#define CAN_RFIFOMPF_FMFD15 BIT(15) /*!< fifo / mailbox filter data bit 15 */ +#define CAN_RFIFOMPF_FMFD16 BIT(16) /*!< fifo / mailbox filter data bit 16 */ +#define CAN_RFIFOMPF_FMFD17 BIT(17) /*!< fifo / mailbox filter data bit 17 */ +#define CAN_RFIFOMPF_FMFD18 BIT(18) /*!< fifo / mailbox filter data bit 18 */ +#define CAN_RFIFOMPF_FMFD19 BIT(19) /*!< fifo / mailbox filter data bit 19 */ +#define CAN_RFIFOMPF_FMFD20 BIT(20) /*!< fifo / mailbox filter data bit 20 */ +#define CAN_RFIFOMPF_FMFD21 BIT(21) /*!< fifo / mailbox filter data bit 21 */ +#define CAN_RFIFOMPF_FMFD22 BIT(22) /*!< fifo / mailbox filter data bit 22 */ +#define CAN_RFIFOMPF_FMFD23 BIT(23) /*!< fifo / mailbox filter data bit 23 */ +#define CAN_RFIFOMPF_FMFD24 BIT(24) /*!< fifo / mailbox filter data bit 24 */ +#define CAN_RFIFOMPF_FMFD25 BIT(25) /*!< fifo / mailbox filter data bit 25 */ +#define CAN_RFIFOMPF_FMFD26 BIT(26) /*!< fifo / mailbox filter data bit 26 */ +#define CAN_RFIFOMPF_FMFD27 BIT(27) /*!< fifo / mailbox filter data bit 27 */ +#define CAN_RFIFOMPF_FMFD28 BIT(28) /*!< fifo / mailbox filter data bit 28 */ +#define CAN_RFIFOMPF_FMFD29 BIT(29) /*!< fifo / mailbox filter data bit 29 */ +#define CAN_RFIFOMPF_FMFD30 BIT(30) /*!< fifo / mailbox filter data bit 30 */ +#define CAN_RFIFOMPF_FMFD31 BIT(31) /*!< fifo / mailbox filter data bit 31 */ + +/* CAN_PN_CTL0 */ +#define CAN_PN_CTL0_FFT BITS(0, 1) /*!< frame filtering type in Pretended Networking mode */ +#define CAN_PN_CTL0_IDFT BITS(2, 3) /*!< ID field filtering type in Pretended Networking mode */ +#define CAN_PN_CTL0_DATAFT BITS(4, 5) /*!< data field filtering type in Pretended Networking mode */ +#define CAN_PN_CTL0_NMM BITS(8, 15) /*!< number of messages matching times */ +#define CAN_PN_CTL0_WMIE BIT(16) /*!< enable wakeup match interrupt */ +#define CAN_PN_CTL0_WTOIE BIT(17) /*!< enable wakeup timeout interrupt */ + +/* CAN_PN_TO */ +#define CAN_PN_TO_WTO BITS(0, 15) /*!< wakeup timeout */ + +/* CAN_PN_STAT */ +#define CAN_PN_STAT_MMCNTS BIT(7) /*!< matching message counter state */ +#define CAN_PN_STAT_MMCNT BITS(8, 15) /*!< matching message counter in Pretended Networking mode */ +#define CAN_PN_STAT_WMS BIT(16) /*!< wakeup match flag status */ +#define CAN_PN_STAT_WTOS BIT(17) /*!< wakeup timeout flag status */ + +/* CAN_PN_EID0 */ +#define CAN_PN_EID0_EID_ELT BITS(0, 28) /*!< expected ID field / expected ID low threshold in Pretended Networking mode */ +#define CAN_PN_EID0_ERTR BIT(29) /*!< expected RTR in Pretended Networking mode */ +#define CAN_PN_EID0_EIDE BIT(30) /*!< expected IDE in Pretended Networking mode */ + +/* CAN_PN_EDLC */ +#define CAN_PN_EDLC_DLCEHT BITS(0, 3) /*!< DLC expected high threshold in Pretended Networking mode */ +#define CAN_PN_EDLC_DLCELT BITS(16, 19) /*!< DLC expected low threshold in Pretended Networking mode */ + +/* CAN_PN_EDL0 */ +#define CAN_PN_EDL0_DB3ELT BITS(0, 7) /*!< data byte 3 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL0_DB2ELT BITS(8, 15) /*!< data byte 2 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL0_DB1ELT BITS(16, 23) /*!< data byte 1 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL0_DB0ELT BITS(24, 31) /*!< data byte 0 expected low threshold in Pretended Networking mode */ + +/* CAN_PN_EDL1 */ +#define CAN_PN_EDL1_DB7ELT BITS(0, 7) /*!< data byte 7 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL1_DB6ELT BITS(8, 15) /*!< data byte 6 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL1_DB5ELT BITS(16, 23) /*!< data byte 5 expected low threshold in Pretended Networking mode */ +#define CAN_PN_EDL1_DB4ELT BITS(24, 31) /*!< data byte 4 expected low threshold in Pretended Networking mode */ + +/* CAN_PN_IFEID1 */ +#define CAN_PN_IFEID1_IDFD_EHT BITS(0, 28) /*!< IDE filter data in Pretended Networking mode */ +#define CAN_PN_IFEID1_RTRFD BIT(29) /*!< RTR filter data in Pretended Networking mode */ +#define CAN_PN_IFEID1_IDEFD BIT(30) /*!< ID filter data / ID expected high threshold in Pretended Networking mode */ + +/* CAN_PN_DF0EDH0 */ +#define CAN_PN_DF0EDH0_DB3FD_EHT BITS(0, 7) /*!< data byte 3 filter data / data byte 3 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF0EDH0_DB2FD_EHT BITS(8, 15) /*!< data byte 2 filter data / data byte 2 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF0EDH0_DB1FD_EHT BITS(16, 23) /*!< data byte 1 filter data / data byte 1 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF0EDH0_DB0FD_EHT BITS(24, 31) /*!< data byte 0 filter data / data byte 0 expected high threshold in Pretended Networking mode */ + +/* CAN_PN_DF1EDH1 */ +#define CAN_PN_DF1EDH1_DB7FD_EHT BITS(0, 7) /*!< data byte 7 filter data / data byte 7 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF1EDH1_DB6FD_EHT BITS(8, 15) /*!< data byte 6 filter data / data byte 6 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF1EDH1_DB5FD_EHT BITS(16, 23) /*!< data byte 5 filter data / data byte 5 expected high threshold in Pretended Networking mode */ +#define CAN_PN_DF1EDH1_DB4FD_EHT BITS(24, 31) /*!< data byte 4 filter data / data byte 4 expected high threshold in Pretended Networking mode */ + +/* CAN_PN_RWMxCS, x = 0..3 */ +#define CAN_PN_RWMXCS_RDLC BITS(16, 19) /*!< received DLC bits */ +#define CAN_PN_RWMXCS_RRTR BIT(20) /*!< received RTR bit */ +#define CAN_PN_RWMXCS_RIDE BIT(21) /*!< received IDE bit */ +#define CAN_PN_RWMXCS_RSRR BIT(22) /*!< received SRR bit */ + +/* CAN_PN_RWMxI, x = 0..3 */ +#define CAN_PN_RWMXI_RID BITS(0, 28) /*!< received ID bits */ + +/* CAN_PN_RWMxD0, x = 0..3 */ +#define CAN_PN_RWMXD0_RDB3 BITS(0, 7) /*!< received data byte 3 */ +#define CAN_PN_RWMXD0_RDB2 BITS(8, 15) /*!< received data byte 2 */ +#define CAN_PN_RWMXD0_RDB1 BITS(16, 23) /*!< received data byte 1 */ +#define CAN_PN_RWMXD0_RDB0 BITS(24, 31) /*!< received data byte 0 */ + +/* CAN_PN_RWMxD1, x = 0..3 */ +#define CAN_PN_RWMXD1_RDB7 BITS(0, 7) /*!< received data byte 7 */ +#define CAN_PN_RWMXD1_RDB6 BITS(8, 15) /*!< received data byte 6 */ +#define CAN_PN_RWMXD1_RDB5 BITS(16, 23) /*!< received data byte 5 */ +#define CAN_PN_RWMXD1_RDB4 BITS(24, 31) /*!< received data byte 4 */ + +/* CAN_FDCTL */ +#define CAN_FDCTL_TDCV BITS(0, 5) /*!< transmitter delay compensation value */ +#define CAN_FDCTL_TDCO BITS(8, 12) /*!< transmitter delay compensation offset */ +#define CAN_FDCTL_TDCS BIT(14) /*!< transmitter delay compensation status */ +#define CAN_FDCTL_TDCEN BIT(15) /*!< transmitter delay compensation enable */ +#define CAN_FDCTL_MDSZ BITS(16, 17) /*!< mailbox data size */ +#define CAN_FDCTL_BRSEN BIT(31) /*!< bit rate of data switch enable */ + +/* CAN_FDBT */ +#define CAN_FDBT_DPBS2 BITS(0, 2) /*!< phase buffer segment 2 for data bit time */ +#define CAN_FDBT_DPBS1 BITS(5, 7) /*!< phase buffer segment 1 for data bit time */ +#define CAN_FDBT_DPTS BITS(10, 14) /*!< propagation time segment for data bit time */ +#define CAN_FDBT_DSJW BITS(16, 18) /*!< resynchronization jump width for data bit time */ +#define CAN_FDBT_DBAUDPSC BITS(20, 29) /*!< baud rate prescaler for data bit time */ + +/* CAN_CRCCFD */ +#define CAN_CRCCFD_CRCTCI BITS(0, 20) /*!< transmitted CRC value for classical and ISO / non-ISO frames */ +#define CAN_CRCCFD_ANTM BITS(24, 28) /*!< associated number of mailbox for transmitting the CRCTCI[20:0] value */ + +/* CAN_MDES0 */ +#define CAN_MDES0_TIMESTAMP BITS(0, 15) /*!< free-running counter timestamp */ +#define CAN_MDES0_DLC BITS(16, 19) /*!< data length code in bytes */ +#define CAN_MDES0_RTR BIT(20) /*!< remote transmission request */ +#define CAN_MDES0_IDE BIT(21) /*!< ID extended bit */ +#define CAN_MDES0_SRR BIT(22) /*!< substitute remote request */ +#define CAN_MDES0_CODE BITS(24, 27) /*!< mailbox code */ +#define CAN_MDES0_ESI BIT(29) /*!< error state indicator */ +#define CAN_MDES0_BRS BIT(30) /*!< bit rate switch */ +#define CAN_MDES0_FDF BIT(31) /*!< FD format indicator */ + +/* CAN_MDES1 */ +#define CAN_MDES1_ID_EXD BITS(0, 17) /*!< identifier for extended frame */ +#define CAN_MDES1_ID_STD BITS(18, 28) /*!< identifier for standard frame */ +#define CAN_MDES1_PRIO BITS(29, 31) /*!< local priority */ + +/* CAN_FDES0 */ +#define CAN_FDES0_TIMESTAMP BITS(0, 15) /*!< free-running counter timestamp */ +#define CAN_FDES0_DLC BITS(16, 19) /*!< data length code in bytes */ +#define CAN_FDES0_RTR BIT(20) /*!< remote transmission request */ +#define CAN_FDES0_IDE BIT(21) /*!< ID extended bit */ +#define CAN_FDES0_SRR BIT(22) /*!< substitute remote request */ +#define CAN_FDES0_IDFMN BITS(23, 31) /*!< identifier filter matching number */ + +/* CAN_FDES1 */ +#define CAN_FDES1_ID_EXT BITS(0, 17) /*!< identifier for extended frame */ +#define CAN_FDES1_ID_STD BITS(18, 28) /*!< identifier for standard frame */ + +/* CAN_FDESX_A */ +#define CAN_FDESX_ID_EXD_A BITS(0, 28) /*!< extended ID in format A */ +#define CAN_FDESX_ID_STD_A BITS(18, 28) /*!< standard ID in format A */ +#define CAN_FDESX_IDE_A BIT(30) /*!< ID extended frame for format A */ +#define CAN_FDESX_RTR_A BIT(31) /*!< remote frame for format A */ + +/* CAN_FDESX_B */ +#define CAN_FDESX_ID_EXD_B_1 BITS(0, 13) /*!< extended ID 1 in format B */ +#define CAN_FDESX_ID_STD_B_1 BITS(3, 13) /*!< standard ID 1 in format B */ +#define CAN_FDESX_IDE_B1 BIT(14) /*!< ID extended frame 1 for format B */ +#define CAN_FDESX_RTR_B1 BIT(15) /*!< remote frame 1 for format B */ +#define CAN_FDESX_ID_EXD_B_0 BITS(16, 29) /*!< extended ID 0 in format B */ +#define CAN_FDESX_ID_STD_B_0 BITS(19, 29) /*!< standard ID 0 in format B */ +#define CAN_FDESX_IDE_B0 BIT(30) /*!< ID extended frame 0 for format B */ +#define CAN_FDESX_RTR_B0 BIT(31) /*!< remote frame 0 for format B */ + +/* CAN_FDESX_C */ +#define CAN_FDESX_ID_C_3 BITS(0, 7) /*!< ID for frame 3 for format C */ +#define CAN_FDESX_ID_C_2 BITS(8, 15) /*!< ID for frame 2 for format C */ +#define CAN_FDESX_ID_C_1 BITS(16, 23) /*!< ID for frame 1 for format C */ +#define CAN_FDESX_ID_C_0 BITS(24, 31) /*!< ID for frame 0 for format C */ + +/* consts definitions */ +/* define the CAN bit position and its register index offset */ +#define CAN_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6U) | (uint32_t)(bitpos)) +#define CAN_REG_VAL(canx, offset) (REG32((uint32_t)(canx) + ((uint32_t)(offset) >> 6U))) +#define CAN_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define CAN_RFIFOMPF(canx, num) REG32((canx) + 0x00000880U + (num) * 0x00000004U) /*!< CAN receive fifo / mailbox private filter x register */ + +/* register offset */ +#define CTL0_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define CTL1_REG_OFFSET ((uint32_t)0x00000004U) /*!< CTL1 register offset */ +#define ERR1_REG_OFFSET ((uint32_t)0x00000020U) /*!< ERR1 register offset */ +#define INTEN_REG_OFFSET ((uint32_t)0x00000028U) /*!< INTEN register offset */ +#define STAT_REG_OFFSET ((uint32_t)0x00000030U) /*!< STAT register offset */ +#define CTL2_REG_OFFSET ((uint32_t)0x00000034U) /*!< CTL2 register offset */ +#define PN_CTL0_REG_OFFSET ((uint32_t)0x00000B00U) /*!< PN_CTL0 register offset */ +#define PN_STAT_REG_OFFSET ((uint32_t)0x00000B08U) /*!< PN_STAT register offset */ +#define FDCTL_REG_OFFSET ((uint32_t)0x00000C00U) /*!< FDCTL register offset */ + +/* CAN interrupt enable or disable */ +typedef enum { + /* interrupt in CLT1 register */ + CAN_INT_RX_WARNING = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 10U), /*!< receive warning interrupt */ + CAN_INT_TX_WARNING = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 11U), /*!< transmit warning interrupt */ + CAN_INT_ERR_SUMMARY = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 14U), /*!< error interrupt */ + CAN_INT_BUSOFF = CAN_REGIDX_BIT(CTL1_REG_OFFSET, 15U), /*!< bus off interrupt */ + /* interrupt in CLT2 register */ + CAN_INT_BUSOFF_RECOVERY = CAN_REGIDX_BIT(CTL2_REG_OFFSET, 30U), /*!< bus off recovery interrupt */ + CAN_INT_ERR_SUMMARY_FD = CAN_REGIDX_BIT(CTL2_REG_OFFSET, 31U), /*!< fd error interrupt */ + /* interrupt in INTEN register */ + CAN_INT_MB0 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 0U), /*!< mailbox 0 interrupt */ + CAN_INT_MB1 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 1U), /*!< mailbox 1 interrupt */ + CAN_INT_MB2 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 2U), /*!< mailbox 2 interrupt */ + CAN_INT_MB3 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 3U), /*!< mailbox 3 interrupt */ + CAN_INT_MB4 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 4U), /*!< mailbox 4 interrupt */ + CAN_INT_MB5 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 5U), /*!< mailbox 5 interrupt */ + CAN_INT_MB6 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 6U), /*!< mailbox 6 interrupt */ + CAN_INT_MB7 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 7U), /*!< mailbox 7 interrupt */ + CAN_INT_MB8 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 8U), /*!< mailbox 8 interrupt */ + CAN_INT_MB9 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 9U), /*!< mailbox 9 interrupt */ + CAN_INT_MB10 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 10U), /*!< mailbox 10 interrupt */ + CAN_INT_MB11 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 11U), /*!< mailbox 11 interrupt */ + CAN_INT_MB12 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 12U), /*!< mailbox 12 interrupt */ + CAN_INT_MB13 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 13U), /*!< mailbox 13 interrupt */ + CAN_INT_MB14 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 14U), /*!< mailbox 14 interrupt */ + CAN_INT_MB15 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 15U), /*!< mailbox 15 interrupt */ + CAN_INT_MB16 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 16U), /*!< mailbox 16 interrupt */ + CAN_INT_MB17 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 17U), /*!< mailbox 17 interrupt */ + CAN_INT_MB18 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 18U), /*!< mailbox 18 interrupt */ + CAN_INT_MB19 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 19U), /*!< mailbox 19 interrupt */ + CAN_INT_MB20 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 20U), /*!< mailbox 20 interrupt */ + CAN_INT_MB21 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 21U), /*!< mailbox 21 interrupt */ + CAN_INT_MB22 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 22U), /*!< mailbox 22 interrupt */ + CAN_INT_MB23 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 23U), /*!< mailbox 23 interrupt */ + CAN_INT_MB24 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 24U), /*!< mailbox 24 interrupt */ + CAN_INT_MB25 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 25U), /*!< mailbox 25 interrupt */ + CAN_INT_MB26 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 26U), /*!< mailbox 26 interrupt */ + CAN_INT_MB27 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 27U), /*!< mailbox 27 interrupt */ + CAN_INT_MB28 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 28U), /*!< mailbox 28 interrupt */ + CAN_INT_MB29 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 29U), /*!< mailbox 29 interrupt */ + CAN_INT_MB30 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 30U), /*!< mailbox 30 interrupt */ + CAN_INT_MB31 = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 31U), /*!< mailbox 31 interrupt */ + CAN_INT_FIFO_AVAILABLE = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 5U), /*!< fifo availabe interrupt */ + CAN_INT_FIFO_WARNING = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 6U), /*!< fifo warning interrupt */ + CAN_INT_FIFO_OVERFLOW = CAN_REGIDX_BIT(INTEN_REG_OFFSET, 7U), /*!< fifo overflow interrupt */ + /* interrupt in PN_CTL0 registeister */ + CAN_INT_WAKEUP_MATCH = CAN_REGIDX_BIT(PN_CTL0_REG_OFFSET, 16U), /*!< Pretended Networking match interrupt */ + CAN_INT_WAKEUP_TIMEOUT = CAN_REGIDX_BIT(PN_CTL0_REG_OFFSET, 17U) /*!< Pretended Networking timeout wakeup interrupt */ +} can_interrupt_enum; + +/* CAN flags */ +typedef enum { + /* flags in CTL0 register */ + CAN_FLAG_CAN_PN = CAN_REGIDX_BIT(CTL0_REG_OFFSET, 18U), /*!< Pretended Networking state flag */ + CAN_FLAG_SOFT_RST = CAN_REGIDX_BIT(CTL0_REG_OFFSET, 25U), /*!< software reset flag */ + /* flags in ERR1 register */ + CAN_FLAG_ERR_SUMMARY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 1U), /*!< error summary flag */ + CAN_FLAG_BUSOFF = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 2U), /*!< bus off flag */ + CAN_FLAG_RECEIVING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 3U), /*!< receiving state flag */ + CAN_FLAG_TRANSMITTING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 6U), /*!< transmitting state flag */ + CAN_FLAG_IDLE = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 7U), /*!< IDLE state flag */ + CAN_FLAG_RX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 8U), /*!< receive warning flag */ + CAN_FLAG_TX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 9U), /*!< transmit warning flag */ + CAN_FLAG_STUFF_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 10U), /*!< stuff error flag */ + CAN_FLAG_FORM_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 11U), /*!< form error flag */ + CAN_FLAG_CRC_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 12U), /*!< CRC error flag */ + CAN_FLAG_ACK_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 13U), /*!< ACK error flag */ + CAN_FLAG_BIT_DOMINANT_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 14U), /*!< bit dominant error flag */ + CAN_FLAG_BIT_RECESSIVE_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 15U), /*!< bit recessive error flag */ + CAN_FLAG_SYNC_ERR = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 18U), /*!< synchronization flag */ + CAN_FLAG_BUSOFF_RECOVERY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 19U), /*!< bus off recovery flag */ + CAN_FLAG_ERR_SUMMARY_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 20U), /*!< FD error summary flag */ + CAN_FLAG_ERR_OVERRUN = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 21U), /*!< error overrun flag */ + CAN_FLAG_STUFF_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 26U), /*!< stuff error in FD data phase flag */ + CAN_FLAG_FORM_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 27U), /*!< form error in FD data phase flag */ + CAN_FLAG_CRC_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 28U), /*!< CRC error in FD data phase flag */ + CAN_FLAG_BIT_DOMINANT_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 30U), /*!< bit dominant error in FD data phase flag */ + CAN_FLAG_BIT_RECESSIVE_ERR_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 31U), /*!< bit recessive error in FD data phase flag */ + /* flags in STAT register */ + CAN_FLAG_MB0 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 0U), /*!< mailbox 0 flag */ + CAN_FLAG_MB1 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 1U), /*!< mailbox 1 flag */ + CAN_FLAG_MB2 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< mailbox 2 flag */ + CAN_FLAG_MB3 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< mailbox 3 flag */ + CAN_FLAG_MB4 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< mailbox 4 flag */ + CAN_FLAG_MB5 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< mailbox 5 flag */ + CAN_FLAG_MB6 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< mailbox 6 flag */ + CAN_FLAG_MB7 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< mailbox 7 flag */ + CAN_FLAG_MB8 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 8U), /*!< mailbox 8 flag */ + CAN_FLAG_MB9 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 9U), /*!< mailbox 9 flag */ + CAN_FLAG_MB10 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 10U), /*!< mailbox 10 flag */ + CAN_FLAG_MB11 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 11U), /*!< mailbox 11 flag */ + CAN_FLAG_MB12 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 12U), /*!< mailbox 12 flag */ + CAN_FLAG_MB13 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 13U), /*!< mailbox 13 flag */ + CAN_FLAG_MB14 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 14U), /*!< mailbox 14 flag */ + CAN_FLAG_MB15 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 15U), /*!< mailbox 15 flag */ + CAN_FLAG_MB16 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 16U), /*!< mailbox 16 flag */ + CAN_FLAG_MB17 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 17U), /*!< mailbox 17 flag */ + CAN_FLAG_MB18 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 18U), /*!< mailbox 18 flag */ + CAN_FLAG_MB19 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 19U), /*!< mailbox 19 flag */ + CAN_FLAG_MB20 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 20U), /*!< mailbox 20 flag */ + CAN_FLAG_MB21 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 21U), /*!< mailbox 21 flag */ + CAN_FLAG_MB22 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 22U), /*!< mailbox 22 flag */ + CAN_FLAG_MB23 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 23U), /*!< mailbox 23 flag */ + CAN_FLAG_MB24 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 24U), /*!< mailbox 24 flag */ + CAN_FLAG_MB25 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 25U), /*!< mailbox 25 flag */ + CAN_FLAG_MB26 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 26U), /*!< mailbox 26 flag */ + CAN_FLAG_MB27 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 27U), /*!< mailbox 27 flag */ + CAN_FLAG_MB28 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 28U), /*!< mailbox 28 flag */ + CAN_FLAG_MB29 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 29U), /*!< mailbox 29 flag */ + CAN_FLAG_MB30 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 30U), /*!< mailbox 30 flag */ + CAN_FLAG_MB31 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 31U), /*!< mailbox 31 flag */ + CAN_FLAG_FIFO_AVAILABLE = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< fifo availabe flag */ + CAN_FLAG_FIFO_WARNING = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< fifo warning flag */ + CAN_FLAG_FIFO_OVERFLOW = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< fifo overflow flag */ + /* flags in PN_STAT register */ + CAN_FLAG_WAKEUP_MATCH = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 16U), /*!< Pretended Networking match flag */ + CAN_FLAG_WAKEUP_TIMEOUT = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 17U), /*!< Pretended Networking timeout wakeup flag */ + /* flags in FDCTL register */ + CAN_FLAG_TDC_OUT_OF_RANGE = CAN_REGIDX_BIT(FDCTL_REG_OFFSET, 14U), /*!< transmitter delay is out of compensation range flag */ +} can_flag_enum; + +/* CAN interrupt flags */ +typedef enum { + /* interrupt flags in ERR1 register */ + CAN_INT_FLAG_ERR_SUMMARY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 1U), /*!< error summary interrupt flag */ + CAN_INT_FLAG_BUSOFF = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 2U), /*!< bus off interrupt flag */ + CAN_INT_FLAG_RX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 16U), /*!< receive warning interrupt flag */ + CAN_INT_FLAG_TX_WARNING = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 17U), /*!< transmit warning interrupt flag */ + CAN_INT_FLAG_BUSOFF_RECOVERY = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 19U), /*!< bus off recovery interrupt flag */ + CAN_INT_FLAG_ERR_SUMMARY_FD = CAN_REGIDX_BIT(ERR1_REG_OFFSET, 20U), /*!< fd error summary interrupt flag */ + /* interrupt flags in STAT register */ + CAN_INT_FLAG_MB0 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 0U), /*!< mailbox 0 interrupt flag */ + CAN_INT_FLAG_MB1 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 1U), /*!< mailbox 1 interrupt flag */ + CAN_INT_FLAG_MB2 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 2U), /*!< mailbox 2 interrupt flag */ + CAN_INT_FLAG_MB3 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 3U), /*!< mailbox 3 interrupt flag */ + CAN_INT_FLAG_MB4 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 4U), /*!< mailbox 4 interrupt flag */ + CAN_INT_FLAG_MB5 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< mailbox 5 interrupt flag */ + CAN_INT_FLAG_MB6 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< mailbox 6 interrupt flag */ + CAN_INT_FLAG_MB7 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< mailbox 7 interrupt flag */ + CAN_INT_FLAG_MB8 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 8U), /*!< mailbox 8 interrupt flag */ + CAN_INT_FLAG_MB9 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 9U), /*!< mailbox 9 interrupt flag */ + CAN_INT_FLAG_MB10 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 10U), /*!< mailbox 10 interrupt flag */ + CAN_INT_FLAG_MB11 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 11U), /*!< mailbox 11 interrupt flag */ + CAN_INT_FLAG_MB12 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 12U), /*!< mailbox 12 interrupt flag */ + CAN_INT_FLAG_MB13 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 13U), /*!< mailbox 13 interrupt flag */ + CAN_INT_FLAG_MB14 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 14U), /*!< mailbox 14 interrupt flag */ + CAN_INT_FLAG_MB15 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 15U), /*!< mailbox 15 interrupt flag */ + CAN_INT_FLAG_MB16 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 16U), /*!< mailbox 16 interrupt flag */ + CAN_INT_FLAG_MB17 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 17U), /*!< mailbox 17 interrupt flag */ + CAN_INT_FLAG_MB18 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 18U), /*!< mailbox 18 interrupt flag */ + CAN_INT_FLAG_MB19 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 19U), /*!< mailbox 19 interrupt flag */ + CAN_INT_FLAG_MB20 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 20U), /*!< mailbox 20 interrupt flag */ + CAN_INT_FLAG_MB21 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 21U), /*!< mailbox 21 interrupt flag */ + CAN_INT_FLAG_MB22 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 22U), /*!< mailbox 22 interrupt flag */ + CAN_INT_FLAG_MB23 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 23U), /*!< mailbox 23 interrupt flag */ + CAN_INT_FLAG_MB24 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 24U), /*!< mailbox 24 interrupt flag */ + CAN_INT_FLAG_MB25 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 25U), /*!< mailbox 25 interrupt flag */ + CAN_INT_FLAG_MB26 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 26U), /*!< mailbox 26 interrupt flag */ + CAN_INT_FLAG_MB27 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 27U), /*!< mailbox 27 interrupt flag */ + CAN_INT_FLAG_MB28 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 28U), /*!< mailbox 28 interrupt flag */ + CAN_INT_FLAG_MB29 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 29U), /*!< mailbox 29 interrupt flag */ + CAN_INT_FLAG_MB30 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 30U), /*!< mailbox 30 interrupt flag */ + CAN_INT_FLAG_MB31 = CAN_REGIDX_BIT(STAT_REG_OFFSET, 31U), /*!< mailbox 31 interrupt flag */ + CAN_INT_FLAG_FIFO_AVAILABLE = CAN_REGIDX_BIT(STAT_REG_OFFSET, 5U), /*!< fifo availabe interrupt flag */ + CAN_INT_FLAG_FIFO_WARNING = CAN_REGIDX_BIT(STAT_REG_OFFSET, 6U), /*!< fifo warning interrupt flag */ + CAN_INT_FLAG_FIFO_OVERFLOW = CAN_REGIDX_BIT(STAT_REG_OFFSET, 7U), /*!< fifo overflow interrupt flag */ + /* interrupt flags in PN_STAT register */ + CAN_INT_FLAG_WAKEUP_MATCH = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 16U), /*!< Pretended Networking match interrupt flag */ + CAN_INT_FLAG_WAKEUP_TIMEOUT = CAN_REGIDX_BIT(PN_STAT_REG_OFFSET, 17U) /*!< Pretended Networking timeout wakeup interrupt flag */ +} can_interrupt_flag_enum; + +/* operation modes */ +typedef enum { + CAN_NORMAL_MODE = 0U, /*!< normal mode */ + CAN_MONITOR_MODE = 1U, /*!< monitor mode */ + CAN_LOOPBACK_SILENT_MODE = 2U, /*!< loopback mode */ + CAN_INACTIVE_MODE = 3U, /*!< inactive mode */ + CAN_DISABLE_MODE = 4U, /*!< disable mode */ + CAN_PN_MODE = 5U /*!< Pretended Networking mode */ +} can_operation_modes_enum; + +/* initiliaze parameter type */ +typedef enum { + CAN_INIT_STRUCT = 0U, /*!< CAN initiliaze parameters struct */ + CAN_FD_INIT_STRUCT = 1U, /*!< CAN FD parameters struct */ + CAN_FIFO_INIT_STRUCT = 2U, /*!< CAN fifo parameters struct */ + CAN_PN_MODE_INIT_STRUCT = 3U, /*!< Pretended Networking mode parameter strcut */ + CAN_PN_MODE_FILTER_STRUCT = 4U, /*!< Pretended Networking mode filter parameter strcut */ + CAN_MDSC_STRUCT = 5U, /*!< mailbox descriptor strcut */ + CAN_FDES_STRUCT = 6U, /*!< Rx fifo descriptor strcut */ + CAN_FIFO_ID_FILTER_STRUCT = 7U, /*!< Rx fifo id filter strcut */ + CAN_CRC_STRUCT = 8U, /*!< CRC strcut */ + CAN_ERRCNT_STRUCT = 9U, /*!< error counter strcut */ +} can_struct_type_enum; + +/* error state indicator */ +typedef enum { + CAN_ERROR_STATE_ACTIVE = 0U, /*!< CAN in error active */ + CAN_ERROR_STATE_PASSIVE = 1U, /*!< CAN in error passive */ + CAN_ERROR_STATE_BUS_OFF = 2U /*!< CAN in bus off */ +} can_error_state_enum; + +/* error counter structure */ +typedef struct { + uint8_t fd_data_phase_rx_errcnt; /*!< receive error counter for data phase of FD frames with BRS bit set */ + uint8_t fd_data_phase_tx_errcnt; /*!< transmit error count for the data phase of FD frames with BRS bit set */ + uint8_t rx_errcnt; /*!< receive error count defined by the CAN standard */ + uint8_t tx_errcnt; /*!< transmit error count defined by the CAN standard */ +} can_error_counter_struct; + +/* CAN initiliaze parameters structure */ +typedef struct { + uint32_t internal_counter_source; /*!< internal counter source */ + uint32_t mb_tx_order; /*!< mailbox transmit order */ + uint32_t mb_rx_ide_rtr_type; /*!< IDE and RTR field fitler type */ + uint32_t mb_remote_frame; /*!< remote request frame is stored */ + uint8_t self_reception; /*!< enable or disable self reception */ + uint8_t mb_tx_abort_enable; /*!< enable or disable transmit abort */ + uint8_t local_priority_enable; /*!< enable or disable local priority */ + uint8_t rx_private_filter_queue_enable; /*!< private filter and queue enable */ + uint32_t edge_filter_enable; /*!< edge filter enable*/ + uint32_t protocol_exception_enable; /*!< protocol exception enable */ + uint32_t rx_filter_order; /*!< receive filter order */ + uint32_t memory_size; /*!< memory size */ + uint32_t mb_public_filter; /*!< mailbox public filter */ + uint32_t prescaler; /*!< baudrate prescaler */ + uint8_t resync_jump_width; /*!< resynchronization jump width */ + uint8_t prop_time_segment; /*!< propagation time segment */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ +} can_parameter_struct; + +/* mailbox descriptor struct */ +typedef struct { + uint32_t timestamp : 16; /*!< free-running counter timestamp */ + uint32_t dlc : 4; /*!< data length code in bytes */ + uint32_t rtr : 1; /*!< remote transmission request */ + uint32_t ide : 1; /*!< ID extended bit */ + uint32_t srr : 1; /*!< substitute remote request */ + uint32_t reserve1 : 1; /*!< reserve bit 1 */ + uint32_t code : 4; /*!< mailbox code */ + uint32_t reserve2 : 1; /*!< reserve bit 2 */ + uint32_t esi : 1; /*!< error state indicator */ + uint32_t brs : 1; /*!< bit rate switch */ + uint32_t fdf : 1; /*!< FD format indicator */ + uint32_t id : 29; /*!< identifier for frame */ + uint32_t prio : 3; /*!< local priority */ + uint32_t *data; /*!< data */ + uint32_t data_bytes; /*!< data bytes */ + uint8_t padding; /*!< FD mode padding data */ +} can_mailbox_descriptor_struct; + +/* fifo descriptor struct */ +typedef struct { + uint32_t timestamp : 16; /*!< free-running counter timestamp */ + uint32_t dlc : 4; /*!< data length code in bytes */ + uint32_t rtr : 1; /*!< remote transmission request */ + uint32_t ide : 1; /*!< ID extended bit */ + uint32_t srr : 1; /*!< substitute remote request */ + uint32_t idhit : 9; /*!< identifier filter matching number */ + uint32_t id; /*!< identifier for frame */ + uint32_t data[2]; /*!< fifo data */ +} can_rx_fifo_struct; + +/* FD initiliaze parameter struct */ +typedef struct { + uint32_t iso_can_fd_enable; /*!< ISO CAN FD protocol enable */ + uint32_t bitrate_switch_enable; /*!< data bit rate switch */ + uint32_t mailbox_data_size; /*!< mailbox data size */ + uint32_t tdc_enable; /*!< trnasmitter delay compensation enable */ + uint32_t tdc_offset; /*!< trnasmitter delay compensation offset */ + uint32_t prescaler; /*!< baudrate prescaler */ + uint8_t resync_jump_width; /*!< resynchronization jump width */ + uint8_t prop_time_segment; /*!< propagation time segment */ + uint8_t time_segment_1; /*!< time segment 1 */ + uint8_t time_segment_2; /*!< time segment 2 */ +} can_fd_parameter_struct; + +/* FIFO ID filter table struct */ +typedef struct { + uint32_t remote_frame; /*!< expected remote frame*/ + uint32_t extended_frame; /*!< expected extended frame */ + uint32_t id; /*!< expected id */ +} can_rx_fifo_id_filter_struct; + +/* FIFO initiliaze parameter struct */ +typedef struct { + uint8_t dma_enable; /*!< DMA enable */ + uint32_t filter_format_and_number; /*!< FIFO ID filter format and number */ + uint32_t fifo_public_filter; /*!< FIFO ID public filter */ +} can_fifo_parameter_struct; + +/* Pretended Networking mode filter parameter struct */ +typedef struct { + uint32_t remote_frame; /*!< remote frame */ + uint32_t extended_frame; /*!< extended frame */ + uint32_t id; /*!< id */ + uint32_t dlc_high_threshold; /*!< DLC expected high threshold */ + uint32_t dlc_low_threshold; /*!< DLC expected low threshold */ + uint32_t payload[2]; /*!< data */ +} can_pn_mode_filter_struct; + +/* Pretended Networking mode initiliaze parameter struct */ +typedef struct { + uint32_t timeout_int; /*!< enable or disable timeout interrupt */ + uint32_t match_int; /*!< enable or disable match interrupt */ + uint32_t num_matches; /*!< set number of message matching times */ + uint32_t match_timeout; /*!< set wakeup timeout value */ + uint32_t frame_filter; /*!< set frame filtering type */ + uint32_t id_filter; /*!< set id filtering type */ + uint32_t data_filter; /*!< set data filtering type */ +} can_pn_mode_config_struct; + +/* CRC parameter struct */ +typedef struct { + uint32_t classical_frm_mb_number; /*!< associated number of mailbox for transmitting the CRCTC[14:0] value */ + uint32_t classical_frm_transmitted_crc; /*!< transmitted CRC value for classical frames */ + uint32_t classical_fd_frm_mb_number; /*!< associated number of mailbox for transmitting the CRCTCI[20:0] value */ + uint32_t classical_fd_frm_transmitted_crc; /*!< transmitted CRC value for classical and ISO / non-ISO FD frames */ +} can_crc_struct; + +/* CAN_CTL0 register */ +#define CTL0_MSZ(regval) (CAN_CTL0_MSZ & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_CTL0_MSZ bit field */ +#define CAN_MEMSIZE_1_UNIT CTL0_MSZ(0U) /*!< 1 unit for message transmission and reception */ +#define CAN_MEMSIZE_2_UNIT CTL0_MSZ(1U) /*!< 2 units for message transmission and reception */ +#define CAN_MEMSIZE_3_UNIT CTL0_MSZ(2U) /*!< 3 units for message transmission and reception */ +#define CAN_MEMSIZE_4_UNIT CTL0_MSZ(3U) /*!< 4 units for message transmission and reception */ +#define CAN_MEMSIZE_5_UNIT CTL0_MSZ(4U) /*!< 5 units for message transmission and reception */ +#define CAN_MEMSIZE_6_UNIT CTL0_MSZ(5U) /*!< 6 units for message transmission and reception */ +#define CAN_MEMSIZE_7_UNIT CTL0_MSZ(6U) /*!< 7 units for message transmission and reception */ +#define CAN_MEMSIZE_8_UNIT CTL0_MSZ(7U) /*!< 8 units for message transmission and reception */ +#define CAN_MEMSIZE_9_UNIT CTL0_MSZ(8U) /*!< 9 units for message transmission and reception */ +#define CAN_MEMSIZE_10_UNIT CTL0_MSZ(9U) /*!< 10 units for message transmission and reception */ +#define CAN_MEMSIZE_11_UNIT CTL0_MSZ(10U) /*!< 11 units for message transmission and reception */ +#define CAN_MEMSIZE_12_UNIT CTL0_MSZ(11U) /*!< 12 units for message transmission and reception */ +#define CAN_MEMSIZE_13_UNIT CTL0_MSZ(12U) /*!< 13 units for message transmission and reception */ +#define CAN_MEMSIZE_14_UNIT CTL0_MSZ(13U) /*!< 14 units for message transmission and reception */ +#define CAN_MEMSIZE_15_UNIT CTL0_MSZ(14U) /*!< 15 units for message transmission and reception */ +#define CAN_MEMSIZE_16_UNIT CTL0_MSZ(15U) /*!< 16 units for message transmission and reception */ +#define CAN_MEMSIZE_17_UNIT CTL0_MSZ(16U) /*!< 17 units for message transmission and reception */ +#define CAN_MEMSIZE_18_UNIT CTL0_MSZ(17U) /*!< 18 units for message transmission and reception */ +#define CAN_MEMSIZE_19_UNIT CTL0_MSZ(18U) /*!< 19 units for message transmission and reception */ +#define CAN_MEMSIZE_20_UNIT CTL0_MSZ(19U) /*!< 20 units for message transmission and reception */ +#define CAN_MEMSIZE_21_UNIT CTL0_MSZ(20U) /*!< 21 units for message transmission and reception */ +#define CAN_MEMSIZE_22_UNIT CTL0_MSZ(21U) /*!< 22 units for message transmission and reception */ +#define CAN_MEMSIZE_23_UNIT CTL0_MSZ(22U) /*!< 23 units for message transmission and reception */ +#define CAN_MEMSIZE_24_UNIT CTL0_MSZ(23U) /*!< 24 units for message transmission and reception */ +#define CAN_MEMSIZE_25_UNIT CTL0_MSZ(24U) /*!< 25 units for message transmission and reception */ +#define CAN_MEMSIZE_26_UNIT CTL0_MSZ(25U) /*!< 26 units for message transmission and reception */ +#define CAN_MEMSIZE_27_UNIT CTL0_MSZ(26U) /*!< 27 units for message transmission and reception */ +#define CAN_MEMSIZE_28_UNIT CTL0_MSZ(27U) /*!< 28 units for message transmission and reception */ +#define CAN_MEMSIZE_29_UNIT CTL0_MSZ(28U) /*!< 29 units for message transmission and reception */ +#define CAN_MEMSIZE_30_UNIT CTL0_MSZ(29U) /*!< 30 units for message transmission and reception */ +#define CAN_MEMSIZE_31_UNIT CTL0_MSZ(30U) /*!< 31 units for message transmission and reception */ +#define CAN_MEMSIZE_32_UNIT CTL0_MSZ(31U) /*!< 32 units for message transmission and reception */ + +#define CTL0_FS(regval) (CAN_CTL0_FS & ((uint32_t)(regval) << 8U)) /*!< write value to CAN_CTL0_FS bit field */ +#define CAN_FIFO_FILTER_FORMAT_A CTL0_FS(0U) /*!< FIFO filter format A */ +#define CAN_FIFO_FILTER_FORMAT_B CTL0_FS(1U) /*!< FIFO filter format B */ +#define CAN_FIFO_FILTER_FORMAT_C CTL0_FS(2U) /*!< FIFO filter format C */ +#define CAN_FIFO_FILTER_FORMAT_D CTL0_FS(3U) /*!< FIFO filter format D */ + +#define GET_CTL0_FS(regval) GET_BITS((regval),8,9) /*!< get CAN_CTL0_FS bit field */ + +/* CAN_CTL1 register */ +#define CAN_TX_HIGH_PRIORITY_MB_FIRST ((uint32_t)0x00000000U) /*!< highest priority mailbox first */ +#define CAN_TX_LOW_NUM_MB_FIRST CAN_CTL1_MTO /*!< low number mailbox first */ + +#define CAN_BSP_MODE_ONE_SAMPLE ((uint32_t)0x00000000U) /*!< one sample for the received bit */ +#define CAN_BSP_MODE_THREE_SAMPLES CAN_CTL1_BSPMOD /*!< three sample for received bit */ + +/* CAN_ERR0 register */ +#define GET_ERR0_REFCNT(regval) GET_BITS((regval),24,31) /*!< get receive error counter for data phase of FD frames with BRS bit set */ +#define GET_ERR0_TEFCNT(regval) GET_BITS((regval),16,23) /*!< get transmit error counter for data phase of FD frames with BRS bit set */ +#define GET_ERR0_RECNT(regval) GET_BITS((regval),8,15) /*!< get receive error counter defined by the CAN standard */ +#define GET_ERR0_TECNT(regval) GET_BITS((regval),0,7) /*!< get transmit error counter defined by the CAN standard */ +#define ERR0_REFCNT(regval) (BITS(24,31) & ((uint32_t)(regval) << 24U)) /*!< set receive error counter for data phase of FD frames with BRS bit set */ +#define ERR0_TEFCNT(regval) (BITS(16,23) & ((uint32_t)(regval) << 16U)) /*!< set transmit error counter for data phase of FD frames with BRS bit set */ +#define ERR0_RECNT(regval) (BITS(8,15) & ((uint32_t)(regval) << 8U)) /*!< set receive error counter defined by the CAN standard */ +#define ERR0_TECNT(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< set transmit error counter defined by the CAN standard */ + +/* CAN_ERR1 register */ +#define GET_ERR1_ERRSI(regval) GET_BITS((regval),4,5) /*!< read CAN_ERR1_ERRSI bit field */ + +/* CAN_STAT register */ +#define STAT_MS(regval) BIT(regval) /*!< write value to CAN_STAT_MS bit field */ + +/* CAN_CTL2 register */ +#define CAN_TIMER_SOURCE_BIT_CLOCK ((uint32_t)0x00000000U) /*!< internal counter source is CAN bit clock */ +#define CAN_TIMER_SOURCE_EXTERNAL_TIME_TICK CAN_CTL2_ITSRC /*!< internal counter source is external time tick */ + +#define CAN_IDE_RTR_COMPARED ((uint32_t)0x00000000U) /*!< always compare IDE bit, never compare RTR bit */ +#define CAN_IDE_RTR_FILTERED CAN_CTL2_IDERTR_RMF /*!< filtering IDE and RTR fields */ + +#define CAN_GEN_REMOTE_RESPONSE_FRAME ((uint32_t)0x00000000U) /* remote response frame is generated when a mailbox with CODE RANSWER is found with the same ID */ +#define CAN_STORE_REMOTE_REQUEST_FRAME CAN_CTL2_RRFRMS /* remote request frame is stored as a data frame without automatic remote response frame transmitted */ + +#define CAN_RX_FILTER_ORDER_FIFO_FIRST ((uint32_t)0x00000000U) /*!< receive search FIFO first */ +#define CAN_RX_FILTER_ORDER_MAILBOX_FIRST CAN_CTL2_RFO /*!< receive search mailbox first */ + +#define CTL2_ASD(regval) (BITS(19,23) & ((uint32_t)(regval) << 19U)) /*!< write value to CAN_CTL2_ASD bit field */ + +#define CTL2_RFFN(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U)) /*!< write value to CAN_CTL2_RFFN bit field */ +#define GET_CTL2_RFFN(regval) GET_BITS((regval),24,27) /*!< get CAN_CTL2_RFFN bit field */ +#define CAN_RXFIFO_FILTER_A_NUM_8 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(0U)) /*!< FIFO ID filter format A and 8 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_16 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(1U)) /*!< FIFO ID filter format A and 16 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_24 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(2U)) /*!< FIFO ID filter format A and 24 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_32 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(3U)) /*!< FIFO ID filter format A and 32 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_40 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(4U)) /*!< FIFO ID filter format A and 40 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_48 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(5U)) /*!< FIFO ID filter format A and 48 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_56 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(6U)) /*!< FIFO ID filter format A and 56 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_64 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(7U)) /*!< FIFO ID filter format A and 64 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_72 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(8U)) /*!< FIFO ID filter format A and 72 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_80 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(9U)) /*!< FIFO ID filter format A and 80 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_88 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(10U)) /*!< FIFO ID filter format A and 88 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_96 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(11U)) /*!< FIFO ID filter format A and 96 filters */ +#define CAN_RXFIFO_FILTER_A_NUM_104 (CAN_FIFO_FILTER_FORMAT_A | CTL2_RFFN(12U)) /*!< FIFO ID filter format A and 104 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_16 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(0U)) /*!< FIFO ID filter format B and 16 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_32 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(1U)) /*!< FIFO ID filter format B and 32 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_48 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(2U)) /*!< FIFO ID filter format B and 48 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_64 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(3U)) /*!< FIFO ID filter format B and 64 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_80 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(4U)) /*!< FIFO ID filter format B and 80 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_96 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(5U)) /*!< FIFO ID filter format B and 96 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_112 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(6U)) /*!< FIFO ID filter format B and 112 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_128 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(7U)) /*!< FIFO ID filter format B and 128 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_144 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(8U)) /*!< FIFO ID filter format B and 144 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_160 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(9U)) /*!< FIFO ID filter format B and 160 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_176 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(10U)) /*!< FIFO ID filter format B and 176 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_192 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(11U)) /*!< FIFO ID filter format B and 192 filters */ +#define CAN_RXFIFO_FILTER_B_NUM_208 (CAN_FIFO_FILTER_FORMAT_B | CTL2_RFFN(12U)) /*!< FIFO ID filter format B and 208 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_32 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(0U)) /*!< FIFO ID filter format C and 32 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_64 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(1U)) /*!< FIFO ID filter format C and 64 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_96 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(2U)) /*!< FIFO ID filter format C and 96 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_128 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(3U)) /*!< FIFO ID filter format C and 128 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_160 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(4U)) /*!< FIFO ID filter format C and 160 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_192 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(5U)) /*!< FIFO ID filter format C and 192 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_224 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(6U)) /*!< FIFO ID filter format C and 224 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_256 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(7U)) /*!< FIFO ID filter format C and 256 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_288 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(8U)) /*!< FIFO ID filter format C and 288 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_320 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(9U)) /*!< FIFO ID filter format C and 320 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_352 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(10U)) /*!< FIFO ID filter format C and 352 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_384 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(11U)) /*!< FIFO ID filter format C and 384 filters */ +#define CAN_RXFIFO_FILTER_C_NUM_416 (CAN_FIFO_FILTER_FORMAT_C | CTL2_RFFN(12U)) /*!< FIFO ID filter format C and 416 filters */ +#define CAN_RXFIFO_FILTER_D CAN_FIFO_FILTER_FORMAT_D /*!< FIFO ID filter format D */ + +/* CAN_CRCC register */ +#define GET_CRCC_ANTM(regval) GET_BITS((regval),16,20) /*!< get associated number of mailbox for transmitting the CRCTC[14:0] value */ +#define GET_CRCC_CRCTC(regval) GET_BITS((regval),0,14) /*!< get transmitted CRC value for classical frames */ + +/* CAN_RFIFOIFMN register */ +#define GET_RFIFOIFMN_IDFMN(regval) GET_BITS((regval),0,8) /*!< get identifier filter matching number */ + +/* CAN_BT register */ +#define BT_PBS2(regval) (BITS(0,4) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_BT_PBS2 bit field */ +#define BT_PBS1(regval) (BITS(5,9) & ((uint32_t)(regval) << 5U)) /*!< write value to CAN_BT_PBS1 bit field */ +#define BT_PTS(regval) (BITS(10,15) & ((uint32_t)(regval) << 10U)) /*!< write value to CAN_BT_PTS bit field */ +#define BT_SJW(regval) (BITS(16,20) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_BT_SJW bit field */ +#define BT_BAUDPSC(regval) (BITS(21,30) & ((uint32_t)(regval) << 21U)) /*!< write value to CAN_BT_BAUDPSC bit field */ + +/* CAN_FDCTL register */ +#define GET_FDCTL_MDSZ(regval) GET_BITS((regval),16,17) /*!< get mailbox data size */ + +/* CAN_PN_CTL0 register */ +#define PN_CTL0_FFT(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_CTL0_FFT bit field */ +#define CAN_PN_FRAME_FILTERING_ID PN_CTL0_FFT(0U) /*!< all fields except DATA field, DLC field are filtered */ +#define CAN_PN_FRAME_FILTERING_ID_DATA PN_CTL0_FFT(1U) /*!< all fields are filtered */ +#define CAN_PN_FRAME_FILTERING_ID_NMM PN_CTL0_FFT(2U) /*!< all fields except DATA field, DLC field are filtered with NMM[7:0] matching times */ +#define CAN_PN_FRAME_FILTERING_ID_DATA_NMM PN_CTL0_FFT(3U) /*!< all fields are filtered with NMM[7:0] matching times */ + +#define PN_CTL0_IDFT(regval) (BITS(2,3) & ((uint32_t)(regval) << 2U)) /*!< write value to CAN_PN_CTL0_IDFT bit field */ +#define CAN_PN_ID_FILTERING_EXACT PN_CTL0_IDFT(0U) /*!< DATA field equal to the expected data field */ +#define CAN_PN_ID_FILTERING_GREATER PN_CTL0_IDFT(1U) /*!< DATA field greater than or equal to the expected data */ +#define CAN_PN_ID_FILTERING_SMALLER PN_CTL0_IDFT(2U) /*!< DATA field greater than or equal to the expected data */ +#define CAN_PN_ID_FILTERING_RANGE PN_CTL0_IDFT(3U) /*!< DATA field is between expected data high threshold and low threshold */ + +#define PN_CTL0_DATAFT(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) /*!< write value to CAN_PN_CTL0_DATAFT bit field */ +#define CAN_PN_DATA_FILTERING_EXACT PN_CTL0_DATAFT(0U) /*!< ID field equal to the expected identifie */ +#define CAN_PN_DATA_FILTERING_GREATER PN_CTL0_DATAFT(1U) /*!< ID field greater than or equal to the expected identifier */ +#define CAN_PN_DATA_FILTERING_SMALLER PN_CTL0_DATAFT(2U) /*!< ID field smaller than or equal to the expected identifier */ +#define CAN_PN_DATA_FILTERING_RANGE PN_CTL0_DATAFT(3U) /*!< ID field is between expected idetifier high threshold and low threshold */ + +#define PN_CTL0_NMM(regval) (BITS(8,15) & ((uint32_t)(regval) << 8U)) /*!< write value to CAN_PN_CTL0_NMM bit field */ + +#define PN_CTL0_WMIE(regval) (BIT(16) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_PN_CTL0_WMIE bit */ + +#define PN_CTL0_WTOIE(regval) (BIT(17) & ((uint32_t)(regval) << 17U)) /*!< write value to CAN_PN_CTL0_WTOIE bit */ + +/* CAN_PN_TO register */ +#define PN_TO_WTO(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_TO_WTO bit field */ + +/* CAN_PN_STAT register */ +#define GET_PN_STAT_MMCNT(regval) GET_BITS((regval),8,15) /*!< get matching message counter in Pretended Networking mode */ + +/* CAN_PN_EID0 register */ +#define PN_EID0_EIDF_ELT_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to CAN_PN_EID0_EIDF_ELT bit field for standard frames */ +#define PN_EID0_EIDF_ELT_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_EID0_EIDF_ELT bit field for extended frames */ + +/* CAN_PN_EDLC register */ +#define PN_EDLC_DLCEHT(regval) (BITS(0,3) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_EDLC_DLCEHT bit field */ +#define PN_EDLC_DLCELT(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_PN_EDLC_DLCELT bit field */ + +/* CAN_PN_IFEID1 register */ +#define PN_IFEID1_IDEFD_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to CAN_PN_IFEID1_IDEFD bit field for standard frames */ +#define PN_IFEID1_IDEFD_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_PN_IFEID1_IDEFD bit field for extended frames */ + +/* CAN_FDCTL register */ +#define GET_FDCTL_TDCV(regval) GET_BITS((regval),0,5) /*!< get transmitter delay compensation value */ + +#define FDCTL_TDCO(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to CAN_FDCTL_TDCO bit field */ + +#define FDCTL_MDSZ(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_FDCTL_MDSZ bit field */ +#define CAN_MAILBOX_DATA_SIZE_8_BYTES FDCTL_MDSZ(0U) /*!< mailbox data size is 8 bytes */ +#define CAN_MAILBOX_DATA_SIZE_16_BYTES FDCTL_MDSZ(1U) /*!< mailbox data size is 16 bytes */ +#define CAN_MAILBOX_DATA_SIZE_32_BYTES FDCTL_MDSZ(2U) /*!< mailbox data size is 32 bytes */ +#define CAN_MAILBOX_DATA_SIZE_64_BYTES FDCTL_MDSZ(3U) /*!< mailbox data size is 64 bytes */ + +/* CAN_FDBT register */ +#define FDBT_DPBS2(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) /*!< write value to CAN_FDBT_DPBS2 bit field */ +#define FDBT_DPBS1(regval) (BITS(5,7) & ((uint32_t)(regval) << 5U)) /*!< write value to CAN_FDBT_DPBS1 bit field */ +#define FDBT_DPTS(regval) (BITS(10,14) & ((uint32_t)(regval) << 10U)) /*!< write value to CAN_FDBT_DPTS bit field */ +#define FDBT_DSJW(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) /*!< write value to CAN_FDBT_DSJW bit field */ +#define FDBT_DBAUDPSC(regval) (BITS(20,29) & ((uint32_t)(regval) << 20U)) /*!< write value to CAN_FDBT_DBAUDPSC bit field */ + +/* CAN_CRCCFD register */ +#define GET_CRCCFD_CRCTCI(regval) GET_BITS((regval),0,20) /*!< get transmitted CRC value for classical and ISO / non-ISO FD frames */ +#define GET_CRCCFD_ANTM(regval) GET_BITS((regval),24,28) /*!< get associated number of mailbox for transmitting the CRCTCI[20:0] value */ + +/* MDES0 descriptor */ +#define MDES0_DLC(regval) (BITS(16,19) & ((uint32_t)(regval) << 16U)) /*!< write value to MDES0 descriptor DLC bit field */ + +#define MDES0_CODE(regval) (((uint32_t)(regval) << 24U) & CAN_MDES0_CODE) +#define CAN_MB_RX_STATUS_INACTIVE (0U) /*!< mailbox receive status inactive */ +#define CAN_MB_RX_STATUS_FULL (2U) /*!< mailbox receive status full */ +#define CAN_MB_RX_STATUS_EMPTY (4U) /*!< mailbox receive status empty */ +#define CAN_MB_RX_STATUS_OVERRUN (6U) /*!< mailbox receive status overrun */ +#define CAN_MB_RX_STATUS_RANSWER (10U) /*!< mailbox receive status answer */ +#define CAN_MB_RX_STATUS_BUSY (1U) /*!< mailbox receive status busy */ +#define CAN_MB_TX_STATUS_INACTIVE (8U) /*!< mailbox transmit status inactive */ +#define CAN_MB_TX_STATUS_ABORT (9U) /*!< mailbox transmit status abort */ +#define CAN_MB_TX_STATUS_DATA (12U) /*!< mailbox transmit status data */ + +#define GET_MDES0_CODE(regval) GET_BITS((regval),24,27) /*!< get MDES0 descriptor CODE bit field */ + +/* MDES1 descriptor */ +#define GET_MDES1_ID_EXD(regval) GET_BITS((regval),0,28) /*!< get MDES1 descriptor ID_STD and ID_EXD bit field */ +#define MDES1_ID_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to MDES1 descriptor ID_STD and ID_EXD bit field */ + +#define GET_MDES1_ID_STD(regval) GET_BITS((regval),18,28) /*!< get MDES1 descriptor ID_STD bit field */ +#define MDES1_ID_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to MDES1 descriptor ID_STD bit field */ + +#define MDES1_PRIO(regval) (BITS(29,31) & ((uint32_t)(regval) << 29U)) /*!< write value to MDES1 descriptor PRIO bit field */ + +/* FDES1 descriptor */ +#define GET_FDES1_ID_EXD(regval) GET_BITS((regval),0,28) /*!< get FDES1 descriptor ID_STD and ID_EXD bit field */ +#define FDES1_ID_EXD(regval) (BITS(0,28) & ((uint32_t)(regval) << 0U)) /*!< write value to FDES1 descriptor ID_STD and ID_EXD bit field */ + +#define GET_FDES1_ID_STD(regval) GET_BITS((regval),18,28) /*!< get FDES1 descriptor ID_STD bit field */ +#define FDES1_ID_STD(regval) (BITS(18,28) & ((uint32_t)(regval) << 18U)) /*!< write value to FDES1 descriptor ID_STD bit field */ + +/* FDESx descriptor */ +#define CAN_DATA_FRAME_ACCEPTED ((uint32_t)0x00000000U) /*!< remote frames are rejected and data frames can be stored */ +#define CAN_REMOTE_FRAME_ACCEPTED ((uint32_t)0x00000001U) /*!< remote frames can be stored and data frames are rejected */ + +#define CAN_STANDARD_FRAME_ACCEPTED ((uint32_t)0x00000000U) /*!< extended frames are rejected and standard frames can be stored */ +#define CAN_EXTENDED_FRAME_ACCEPTED ((uint32_t)0x00000001U) /*!< extended frames can be stored and standard frames are rejected */ + +#define FIFO_FILTER_ID_EXD_A(val) (((uint32_t)(val) << 0U) & CAN_FDESX_ID_EXD_A) /*!< valid extended ID filter field in format A */ +#define FIFO_FILTER_ID_STD_A(val) (((uint32_t)(val) << 18U) & CAN_FDESX_ID_STD_A)/*!< valid standard ID filter field in format A */ +#define FIFO_FILTER_ID_EXD_B0(val) (GET_BITS((val),15,28) << 16U) /*!< valid extended ID filter field in format B */ +#define FIFO_FILTER_ID_EXD_B1(val) (GET_BITS((val),15,28) << 0U) /*!< valid extended ID filter field in format B */ +#define FIFO_FILTER_ID_STD_B0(val) (GET_BITS((val),0,10) << 19U) /*!< valid standard ID filter field in format B */ +#define FIFO_FILTER_ID_STD_B1(val) (GET_BITS((val),0,10) << 3U) /*!< valid standard ID filter field in format B */ +#define FIFO_FILTER_ID_EXD_C0(val) (GET_BITS((val),21,28) << 24U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_EXD_C1(val) (GET_BITS((val),21,28) << 16U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_EXD_C2(val) (GET_BITS((val),21,28) << 8U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_EXD_C3(val) (GET_BITS((val),21,28) << 0U) /*!< valid extended ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C0(val) (GET_BITS((val),3,10) << 24U) /*!< valid standard ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C1(val) (GET_BITS((val),3,10) << 16U) /*!< valid standard ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C2(val) (GET_BITS((val),3,10) << 8U) /*!< valid standard ID filter field in format C */ +#define FIFO_FILTER_ID_STD_C3(val) (GET_BITS((val),3,10) << 0U) /*!< valid standard ID filter field in format C */ + +/* timeout definitions */ +#define CAN_DELAY ((uint32_t)0x01FFFFFFU) /*!< state timeout */ +#define CAN_MAX_MAILBOX_NUM 32U /*!< the supported maximum mailbox number */ +#define CAN_MAX_RAM_SIZE (CAN_MAX_MAILBOX_NUM * 4U) /*!< the maximum RAM size used for CAN mailbox */ + + +/* function declarations */ +/* CAN module initialize */ +/* deinitialize CAN */ +void can_deinit(uint32_t can_periph); +/* reset CAN interanl state machines and CAN registers */ +ErrStatus can_software_reset(uint32_t can_periph); +/* CAN module initialization */ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init); +/* initialize CAN parameter structure with a default value */ +void can_struct_para_init(can_struct_type_enum type, void *p_struct); +/* configure receive fifo/mailbox private filter */ +void can_private_filter_config(uint32_t can_periph, uint32_t index, uint32_t filter_data); + +/* CAN operation modes */ +/* enter the corresponding mode */ +ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum mode); +/* get operation mode */ +can_operation_modes_enum can_operation_mode_get(uint32_t can_periph); +/* exit inactive mode */ +ErrStatus can_inactive_mode_exit(uint32_t can_periph); +/* exit Pretended Networking mode */ +ErrStatus can_pn_mode_exit(uint32_t can_periph); + +/* CAN FD mode configuration */ +/* can FD initialize */ +void can_fd_config(uint32_t can_periph, can_fd_parameter_struct *can_fd_para_init); +/* enable bit rate switching */ +void can_bitrate_switch_enable(uint32_t can_periph); +/* disable bit rate switching */ +void can_bitrate_switch_disable(uint32_t can_periph); +/* get transmitter delay compensation value */ +uint32_t can_tdc_get(uint32_t can_periph); +/* enable transmitter delay compensation */ +void can_tdc_enable(uint32_t can_periph); +/* disable transmitter delay compensation */ +void can_tdc_disable(uint32_t can_periph); + +/* CAN FIFO configuration */ +/* configure rx FIFO */ +void can_rx_fifo_config(uint32_t can_periph, can_fifo_parameter_struct *can_fifo_para_init); +/* configure rx FIFO filter table */ +void can_rx_fifo_filter_table_config(uint32_t can_periph, can_rx_fifo_id_filter_struct id_filter_table[]); +/* read rx FIFO data */ +void can_rx_fifo_read(uint32_t can_periph, can_rx_fifo_struct *rx_fifo); +/* get rx FIFO filter matching number */ +uint32_t can_rx_fifo_filter_matching_number_get(uint32_t can_periph); +/* clear rx FIFO */ +void can_rx_fifo_clear(uint32_t can_periph); + +/* CAN mailbox operation */ +/* get mailbox RAM address */ +uint32_t *can_ram_address_get(uint32_t can_periph, uint32_t index); +/* config mailbox */ +void can_mailbox_config(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara); +/* abort mailbox transmit */ +void can_mailbox_transmit_abort(uint32_t can_periph, uint32_t index); +/* inactive transmit mailbox */ +void can_mailbox_transmit_inactive(uint32_t can_periph, uint32_t index); +/* read receive mailbox data */ +ErrStatus can_mailbox_receive_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara); +/* lock the receive mailbox */ +void can_mailbox_receive_lock(uint32_t can_periph, uint32_t index); +/* unlock the receive mailbox */ +void can_mailbox_receive_unlock(uint32_t can_periph); +/* inactive the receive mailbox */ +void can_mailbox_receive_inactive(uint32_t can_periph, uint32_t index); +/* get mailbox code value */ +uint32_t can_mailbox_code_get(uint32_t can_periph, uint32_t index); + +/* errors & CRC */ +/* configure error counter */ +void can_error_counter_config(uint32_t can_periph, can_error_counter_struct *errcnt_struct); +/* get error count */ +void can_error_counter_get(uint32_t can_periph, can_error_counter_struct *errcnt_struct); +/* get error state indicator */ +can_error_state_enum can_error_state_get(uint32_t can_periph); +/* get mailbox CRC value */ +void can_crc_get(uint32_t can_periph, can_crc_struct *crc_struct); + +/* Pretended Networking mode configuration */ +/* configure Pretended Networking mode parameter */ +void can_pn_mode_config(uint32_t can_periph, can_pn_mode_config_struct *pnmod_config); +/* configure pn mode filter */ +void can_pn_mode_filter_config(uint32_t can_periph, can_pn_mode_filter_struct *expect, can_pn_mode_filter_struct *filter); +/* get matching message counter of Pretended Networking mode */ +int32_t can_pn_mode_num_of_match_get(uint32_t can_periph); +/* get matching message */ +void can_pn_mode_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara); + +/* others */ +/* enable self reception */ +void can_self_reception_enable(uint32_t can_periph); +/* disable self reception */ +void can_self_reception_disable(uint32_t can_periph); +/* enable transmit abort */ +void can_transmit_abort_enable(uint32_t can_periph); +/* disable transmit abort */ +void can_transmit_abort_disable(uint32_t can_periph); +/* enable auto bus off recovery mode */ +void can_auto_busoff_recovery_enable(uint32_t can_periph); +/* disable auto bus off recovery mode */ +void can_auto_busoff_recovery_disable(uint32_t can_periph); +/* enable time sync mode */ +void can_time_sync_enable(uint32_t can_periph); +/* disable time sync mode */ +void can_time_sync_disable(uint32_t can_periph); +/* enable edge filter mode */ +void can_edge_filter_mode_enable(uint32_t can_periph); +/* disable edge filter mode */ +void can_edge_filter_mode_disable(uint32_t can_periph); +/* enable protocol exception detection mode */ +void can_ped_mode_enable(uint32_t can_periph); +/* disable protocol exception detection mode */ +void can_ped_mode_disable(uint32_t can_periph); +/* configure arbitation delay bits */ +void can_arbitation_delay_bits_config(uint32_t can_periph, uint32_t delay_bits); +/* configure bit sampling mode */ +void can_bsp_mode_config(uint32_t can_periph, uint32_t sampling_mode); + +/* CAN interrupt and flag */ +/* get CAN flag */ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag); +/* clear CAN flag */ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag); +/* enable CAN interrupt */ +void can_interrupt_enable(uint32_t can_periph, can_interrupt_enum interrupt); +/* disable CAN interrupt */ +void can_interrupt_disable(uint32_t can_periph, can_interrupt_enum interrupt); +/* get CAN interrupt flag */ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum int_flag); +/* clear CAN interrupt flag */ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum int_flag); + +#endif /* GD32A50X_CAN_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_cmp.h b/gd32a50x/standard_peripheral/include/gd32a50x_cmp.h new file mode 100644 index 0000000..df6304e --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_cmp.h @@ -0,0 +1,240 @@ +/*! + \file gd32a50x_cmp.h + \brief definitions for the CMP + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_CMP_H +#define GD32A50X_CMP_H + +#include "gd32a50x.h" + +/* CMP definitions */ +#define CMP CMP_BASE + 0x00000000U /*!< CMP base address */ + +/* registers definitions */ +#define CMP_CS REG32(CMP + 0x00000000U) /*!< CMP control and status register */ + +/* bits definitions */ +/* CMP_CS */ +#define CMP_CS_EN BIT(0) /*!< CMP enable */ +#define CMP_CS_PM BITS(2,3) /*!< CMP mode */ +#define CMP_CS_MESEL BITS(4,6) /*!< CMP_IM external input selection */ +#define CMP_CS_MISEL BITS(7,9) /*!< CMP_IM internal input selection */ +#define CMP_CS_PSEL BITS(10,12) /*!< CMP_IP input selection */ +#define CMP_CS_OSEL BITS(13,14) /*!< CMP output selection */ +#define CMP_CS_PL BIT(15) /*!< polarity of CMP output */ +#define CMP_CS_HST BITS(16,17) /*!< CMP hysteresis */ +#define CMP_CS_BLK BITS(18,20) /*!< CMP output blanking source */ +#define CMP_CS_BEN BIT(22) /*!< scaler bridge enable bit */ +#define CMP_CS_SEN BIT(23) /*!< voltage input scaler */ +#define CMP_CS_OT BIT(30) /*!< CMP output */ +#define CMP_CS_LK BIT(31) /*!< CMP lock */ + +/* constants definitions */ +/* operating mode */ +typedef enum { + CMP_HIGHSPEED = 0, /*!< high speed mode */ + CMP_MIDDLESPEED = 1, /*!< middle speed mode */ + CMP_LOWSPEED = 3 /*!< low speed mode */ +} operating_mode_enum; + +/* inverting input */ +typedef enum { + CMP_1_4VREFINT = 0, /*!< VREFINT /4 input */ + CMP_1_2VREFINT = 8, /*!< VREFINT /2 input */ + CMP_3_4VREFINT = 16, /*!< VREFINT *3/4 input */ + CMP_VREFINT = 24, /*!< VREFINT input */ + CMP_DAC_OUT = 32, /*!< DAC_OUT input */ + CMP_IM_PC11 = 40, /*!< PC11*/ + CMP_IM_PC10 = 41, /*!< PC10 */ + CMP_IM_PB8 = 42, /*!< PB8 */ + CMP_IM_PA0 = 43, /*!< PA0 */ + CMP_IM_PA3 = 44, /*!< PA3 */ + CMP_IM_PA4 = 45, /*!< PA4 */ + CMP_IM_PA5 = 46, /*!< PA5 */ + CMP_IM_PA6 = 47, /*!< PA6 */ +} cmp_inverting_input_enum; + +/* plus input */ +typedef enum { + CMP_IP_PC11 = 0, /*!< PC11*/ + CMP_IP_PC10, /*!< PC10 */ + CMP_IP_PB8, /*!< PB8 */ + CMP_IP_PA0, /*!< PA0 */ + CMP_IP_PA3, /*!< PA3 */ + CMP_IP_PA4, /*!< PA4 */ + CMP_IP_PA5, /*!< PA5 */ + CMP_IP_PA6 /*!< PA6 */ +} cmp_plus_input_enum; + +/* hysteresis */ +typedef enum { + CMP_HYSTERESIS_NO = 0, /*!< output no hysteresis */ + CMP_HYSTERESIS_LOW, /*!< output low hysteresis */ + CMP_HYSTERESIS_MIDDLE, /*!< output middle hysteresis */ + CMP_HYSTERESIS_HIGH /*!< output high hysteresis */ +} cmp_hysteresis_enum; + +/* output */ +typedef enum { + CMP_OUTPUT_NONE = 0, /*!< output no selection */ + CMP_OUTPUT_TIMER0IC0, /*!< TIMER 0 channel0 input capture */ + CMP_OUTPUT_TIMER7IC0 /*!< TIMER 7 channel0 input capture */ +} cmp_output_enum; + +/* output inv */ +typedef enum { + CMP_OUTPUT_POLARITY_NOINVERTED = 0, /*!< output is not inverted */ + CMP_OUTPUT_POLARITY_INVERTED /*!< output is inverted */ +} cmp_output_inv_enum; + +/* blanking_source*/ +typedef enum { + CMP_BLANKING_NONE = 0, /*!< no blanking */ + CMP_BLANKING_TIMER0_OC1, /*!< select TIMER0_CH1 as blanking source */ + CMP_BLANKING_TIMER7_OC1, /*!< select TIMER7_CH1 as blanking source */ + CMP_BLANKING_TIMER1_OC1 /*!< select TIMER1_CH1 as blanking source */ +} blanking_source_enum; + +/* output state */ +typedef enum { + CMP_OUTPUTLEVEL_LOW = 0, /*!< the output is low */ + CMP_OUTPUTLEVEL_HIGH /*!< the output is high */ +} cmp_output_state_enum; + +/* CMP mode */ +#define CS_CMPPM(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define CS_CMPPM_HIGHSPEED CS_CMPPM(0) /*!< CMP mode high speed */ +#define CS_CMPPM_MIDDLESPEED CS_CMPPM(1) /*!< CMP mode middle speed */ +#define CS_CMPPM_LOWSPEED CS_CMPPM(3) /*!< CMP mode low speed */ + +/* CMP input */ +/* IM input */ +#define CS_CMPMSEL(regval) (BITS(4,9) & ((uint32_t)(regval) << 4)) +#define CS_CMPMSEL_1_4VREFINT CS_CMPMSEL(0) /*!< CMP inverting internal input VREFINT *1/4 */ +#define CS_CMPMSEL_1_2VREFINT CS_CMPMSEL(8) /*!< CMP inverting internal input VREFINT *1/2 */ +#define CS_CMPMSEL_3_4VREFINT CS_CMPMSEL(16) /*!< CMP inverting internal input VREFINT *3/4 */ +#define CS_CMPMSEL_VREFINT CS_CMPMSEL(24) /*!< CMP inverting internal input VREFINT */ +#define CS_CMPMSEL_DAC_OUT CS_CMPMSEL(32) /*!< CMP inverting internal input DAC_OUT */ +#define CS_CMPMSEL_PC11 CS_CMPMSEL(40) /*!< CMP inverting external input PC11 */ +#define CS_CMPMSEL_PC10 CS_CMPMSEL(41) /*!< CMP inverting external input PC10 */ +#define CS_CMPMSEL_PB8 CS_CMPMSEL(42) /*!< CMP inverting external input PB8 */ +#define CS_CMPMSEL_PA0 CS_CMPMSEL(43) /*!< CMP inverting external input PA0 */ +#define CS_CMPMSEL_PA3 CS_CMPMSEL(44) /*!< CMP inverting external input PA3 */ +#define CS_CMPMSEL_PA4 CS_CMPMSEL(45) /*!< CMP inverting external input PA4 */ +#define CS_CMPMSEL_PA5 CS_CMPMSEL(46) /*!< CMP inverting external input PA5 */ +#define CS_CMPMSEL_PA6 CS_CMPMSEL(47) /*!< CMP inverting external input PA6 */ + +/* IP input */ +#define CS_CMPPSEL(regval) (BITS(10,12) & ((uint32_t)(regval) << 10)) +#define CS_CMPPSEL_PC11 CS_CMPPSEL(0) /*!< CMP plus input PC11 */ +#define CS_CMPPSEL_PC10 CS_CMPPSEL(1) /*!< CMP plus input PC10 */ +#define CS_CMPPSEL_PB8 CS_CMPPSEL(2) /*!< CMP plus input PB8 */ +#define CS_CMPPSEL_PA0 CS_CMPPSEL(3) /*!< CMP plus input PA0 */ +#define CS_CMPPSEL_PA3 CS_CMPPSEL(4) /*!< CMP plus input PA3 */ +#define CS_CMPPSEL_PA4 CS_CMPPSEL(5) /*!< CMP plus input PA4 */ +#define CS_CMPPSEL_PA5 CS_CMPPSEL(6) /*!< CMP plus input PA5 */ +#define CS_CMPPSEL_PA6 CS_CMPPSEL(7) /*!< CMP plus input PA6 */ + +/* CMP output selection */ +#define CS_CMPOSEL(regval) (BITS(13,14) & ((uint32_t)(regval) << 13)) +#define CS_CMPOSEL_NOSELECTION CS_CMPOSEL(0) /*!< CMP no output selection */ +#define CS_CMPOSEL_TIMER0IC0 CS_CMPOSEL(1) /*!< CMP as TIMER0 channel0 input capture source */ +#define CS_CMPOSEL_TIMER7IC0 CS_CMPOSEL(2) /*!< CMP as TIMER7 channel0 input capture source */ + +/* CMP output polarity*/ +#define CS_CMPPL(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define CS_CMPPL_NOT CS_CMPPL(0) /*!< CMP output not inverted */ +#define CS_CMPPL_INV CS_CMPPL(1) /*!< CMP output inverted */ + +/* CMP hysteresis */ +#define CS_CMPHST(regval) (BITS(16,17) & ((uint32_t)(regval) << 16)) +#define CS_CMPHST_HYSTERESIS_NO CS_CMPHST(0) /*!< CMP output no hysteresis */ +#define CS_CMPHST_HYSTERESIS_LOW CS_CMPHST(1) /*!< CMP output low hysteresis */ +#define CS_CMPHST_HYSTERESIS_MIDDLE CS_CMPHST(2) /*!< CMP output middle hysteresis */ +#define CS_CMPHST_HYSTERESIS_HIGH CS_CMPHST(3) /*!< CMP output high hysteresis */ + +/* CMP blanking suorce */ +#define CS_CMPBLK(regval) (BITS(18,20) & ((uint32_t)(regval) << 18)) +#define CS_CMPBLK_NOBLK CS_CMPBLK(0) /*!< CMP no blanking */ +#define CS_CMPBLK_TIMER0_OC1 CS_CMPBLK(1) /*!< CMP TIMER0 OC1 selected as blanking source */ +#define CS_CMPBLK_TIMER7_OC1 CS_CMPBLK(2) /*!< CMP TIMER7 OC1 selected as blanking source */ +#define CS_CMPBLK_TIMER1_OC1 CS_CMPBLK(4) /*!< CMP TIMER1 OC1 selected as blanking source */ + +/* CMP bridge enable*/ +#define CS_CMPBEN(regval) (BIT(22) & ((uint32_t)(regval) << 22)) +#define CS_CMPBEN_DISABLE CS_CMPBEN(0) /*!< CMP bridge enable */ +#define CS_CMPBEN_ENABLE CS_CMPBEN(1) /*!< CMP bridge disable */ + +/* CMP voltage scaler*/ +#define CS_CMPSEN(regval) (BIT(23) & ((uint32_t)(regval) << 23)) +#define CS_CMPSEN_DISABLE CS_CMPSEN(0) /*!< CMP voltage scaler enable */ +#define CS_CMPSEN_ENABLE CS_CMPSEN(1) /*!< CMP voltage scaler disable */ + +/* CMP lock bit*/ +#define CS_CMPLK(regval) (BIT(31) & ((uint32_t)(regval) << 31)) +#define CS_CMPLK_DISABLE CS_CMPLK(0) /*!< CMP_CS bits are read-write */ +#define CS_CMPLK_ENABLE CS_CMPLK(1) /*!< CMP_CS bits are read-only */ + +/* function declarations */ +/* initialization functions */ +/* deinitialize comparator */ +void cmp_deinit(void); +/* initialize comparator mode */ +void cmp_mode_init(operating_mode_enum operating_mode, cmp_inverting_input_enum inverting_input, cmp_plus_input_enum plus_input, + cmp_hysteresis_enum output_hysteresis); +/* initialize comparator output */ +void cmp_output_init(cmp_output_enum output_selection, cmp_output_inv_enum output_polarity); +/* initialize comparator blanking function */ +void cmp_outputblank_init(blanking_source_enum blanking_source_selection); + +/* enable functions */ +/* enable comparator */ +void cmp_enable(void); +/* disable comparator */ +void cmp_disable(void); +/* enable the voltage scaler */ +void cmp_voltage_scaler_enable(void); +/* disable the voltage scaler */ +void cmp_voltage_scaler_disable(void); +/* enable the scaler bridge */ +void cmp_scaler_bridge_enable(void); +/* disable the scaler bridge */ +void cmp_scaler_bridge_disable(void); +/* lock the comparator */ +void cmp_lock_enable(void); + +/* output functions */ +/* get output level */ +cmp_output_state_enum cmp_output_level_get(void); + +#endif /* GD32A50X_CMP_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_crc.h b/gd32a50x/standard_peripheral/include/gd32a50x_crc.h new file mode 100644 index 0000000..7100fcb --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_crc.h @@ -0,0 +1,122 @@ +/*! + \file gd32a50x_crc.h + \brief definitions for the CRC + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_CRC_H +#define GD32A50X_CRC_H + +#include "gd32a50x.h" + +/* CRC definitions */ +#define CRC CRC_BASE /*!< CRC bsae address */ + +/* registers definitions */ +#define CRC_DATA REG32((CRC) + 0x00000000U) /*!< CRC data register */ +#define CRC_FDATA REG32((CRC) + 0x00000004U) /*!< CRC free data register */ +#define CRC_CTL REG32((CRC) + 0x00000008U) /*!< CRC control register */ +#define CRC_IDATA REG32((CRC) + 0x00000010U) /*!< CRC initialization data register */ +#define CRC_POLY REG32((CRC) + 0x00000014U) /*!< CRC polynomial register */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0, 31) /*!< CRC data bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0, 7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset bit */ +#define CRC_CTL_PS BITS(3, 4) /*!< size of polynomial function bits */ +#define CRC_CTL_REV_I BITS(5, 6) /*!< input data reverse function bits */ +#define CRC_CTL_REV_O BIT(7) /*!< output data reverse function bit */ + +/* CRC_INIT */ +#define CRC_IDATA_IDATA BITS(0, 31) /*!< CRC initialization data bits */ + +/* CRC_POLY */ +#define CRC_POLY_POLY BITS(0, 31) /*!< CRC polynomial value bits */ + +/* constants definitions */ +/* size of polynomial function */ +#define CTL_PS(regval) (BITS(3, 4) & ((regval) << 3)) +#define CRC_CTL_PS_32 CTL_PS(0) /*!< 32-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_16 CTL_PS(1) /*!< 16-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_8 CTL_PS(2) /*!< 8-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_7 CTL_PS(3) /*!< 7-bit polynomial for CRC calculation */ + +/* input data reverse function */ +#define CTL_REV_I(regval) (BITS(5, 6) & ((regval) << 5)) +#define CRC_INPUT_DATA_NOT CTL_REV_I(0) /*!< input data not reverse */ +#define CRC_INPUT_DATA_BYTE CTL_REV_I(1) /*!< input data reversed by byte type */ +#define CRC_INPUT_DATA_HALFWORD CTL_REV_I(2) /*!< input data reversed by half-word type */ +#define CRC_INPUT_DATA_WORD CTL_REV_I(3) /*!< input data reversed by word type */ + +/* input data format */ +#define INPUT_FORMAT_WORD 0U /*!< input data in word format */ +#define INPUT_FORMAT_HALFWORD 1U /*!< input data in half-word format */ +#define INPUT_FORMAT_BYTE 2U /*!< input data in byte format */ + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); +/* enable the reverse operation of output data */ +void crc_reverse_output_data_enable(void); +/* disable the reverse operation of output data */ +void crc_reverse_output_data_disable(void); + +/* reset data register to the value of initialization data register */ +void crc_data_register_reset(void); +/* read the data register */ +uint32_t crc_data_register_read(void); + +/* read the free data register */ +uint8_t crc_free_data_register_read(void); +/* write the free data register */ +void crc_free_data_register_write(uint8_t free_data); + +/* write the initial value register */ +void crc_init_data_register_write(uint32_t init_data); +/* configure the CRC input data function */ +void crc_input_data_reverse_config(uint32_t data_reverse); + +/* configure the CRC size of polynomial function */ +void crc_polynomial_size_set(uint32_t poly_size); +/* configure the CRC polynomial value function */ +void crc_polynomial_set(uint32_t poly); + +/* CRC calculate single data */ +uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format); +/* CRC calculate a data array */ +uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format); + +#endif /* GD32A50X_CRC_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_dac.h b/gd32a50x/standard_peripheral/include/gd32a50x_dac.h new file mode 100644 index 0000000..17d000f --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_dac.h @@ -0,0 +1,210 @@ +/*! + \file gd32fxxx_dac.h + \brief definitions for the DAC + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_DAC_H +#define GD32A50X_DAC_H + +#include "gd32a50x.h" + +/* DAC definitions */ +#define DAC DAC_BASE /*!< DAC base address */ + +/* registers definitions */ +#define DAC_CTL REG32(DAC + 0x00000000U) /*!< DAC control register */ +#define DAC_SWT REG32(DAC + 0x00000004U) /*!< DAC software trigger register */ +#define OUT_R12DH REG32(DAC + 0x00000008U) /*!< DAC_OUT 12-bit right-aligned data holding register */ +#define OUT_L12DH REG32(DAC + 0x0000000CU) /*!< DAC_OUT 12-bit left-aligned data holding register */ +#define OUT_R8DH REG32(DAC + 0x00000010U) /*!< DAC_OUT 8-bit right-aligned data holding register */ +#define OUT_DO REG32(DAC + 0x00000014U) /*!< DAC_OUT data output register */ +#define DAC_STAT REG32(DAC + 0x00000018U) /*!< DAC status register */ + +/* bits definitions */ +/* DAC_CTL */ +#define DAC_CTL_DEN BIT(0) /*!< DAC_OUT enable/disable bit */ +#define DAC_CTL_DBOFF BIT(1) /*!< DAC_OUT output buffer turn on/turn off bit */ +#define DAC_CTL_DTEN BIT(2) /*!< DAC_OUT trigger enable/disable bit */ +#define DAC_CTL_DTSEL BITS(3,4) /*!< DAC_OUT trigger source selection enable/disable bits */ +#define DAC_CTL_DWM BITS(6,7) /*!< DAC_OUT noise wave mode */ +#define DAC_CTL_DWBW BITS(8,11) /*!< DAC_OUT noise wave bit width */ +#define DAC_CTL_DDMAEN BIT(12) /*!< DAC_OUT DMA enable/disable bit */ +#define DAC_CTL_DDUDRIE BIT(13) /*!< DAC_OUT DMA underrun interrupt enable/disable bit */ +#define DAC_CTL_DDISC BIT(14) + +/* DAC_SWT */ +#define DAC_SWT_SWTR BIT(0) /*!< DAC_OUT software trigger bit, cleared by hardware */ + +/* OUT_R12DH */ +#define OUT_R12DH_OUT_DH BITS(0,11) /*!< DAC_OUT 12-bit right-aligned data bits */ + +/* OUT_L12DH */ +#define OUT_L12DH_OUT_DH BITS(4,15) /*!< DAC_OUT 12-bit left-aligned data bits */ + +/* OUT_R8DH */ +#define OUT_R8DH_OUT_DH BITS(0,7) /*!< DAC_OUT 8-bit right-aligned data bits */ + +/* OUT_DO */ +#define OUT_DO_OUT_DO BITS(0,11) /*!< DAC_OUT 12-bit output data bits */ + +/* DAC_STAT0 */ +#define DAC_STAT_DDUDR BIT(13) /*!< DAC_OUT DMA underrun flag */ + +/* constants definitions */ +/* DAC trigger source */ +#define CTL_DTSEL(regval) (BITS(3,4) & ((uint32_t)(regval) << 3)) +#define DAC_TRIGGER_EXTRIG CTL_DTSEL(0) /*!< external trigger source */ +#define DAC_TRIGGER_SOFTWARE CTL_DTSEL(1) /*!< software trigger */ + +/* DAC noise wave mode */ +#define CTL_DWM(regval) (BITS(6,7) & ((uint32_t)(regval) << 6)) +#define DAC_WAVE_DISABLE CTL_DWM(0) /*!< wave disable */ +#define DAC_WAVE_MODE_LFSR CTL_DWM(1) /*!< LFSR noise mode */ +#define DAC_WAVE_MODE_TRIANGLE CTL_DWM(2) /*!< triangle noise mode */ + +/* DAC noise wave bit width */ +#define DWBW(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) +#define DAC_WAVE_BIT_WIDTH_1 DWBW(0) /*!< bit width of the wave signal is 1 */ +#define DAC_WAVE_BIT_WIDTH_2 DWBW(1) /*!< bit width of the wave signal is 2 */ +#define DAC_WAVE_BIT_WIDTH_3 DWBW(2) /*!< bit width of the wave signal is 3 */ +#define DAC_WAVE_BIT_WIDTH_4 DWBW(3) /*!< bit width of the wave signal is 4 */ +#define DAC_WAVE_BIT_WIDTH_5 DWBW(4) /*!< bit width of the wave signal is 5 */ +#define DAC_WAVE_BIT_WIDTH_6 DWBW(5) /*!< bit width of the wave signal is 6 */ +#define DAC_WAVE_BIT_WIDTH_7 DWBW(6) /*!< bit width of the wave signal is 7 */ +#define DAC_WAVE_BIT_WIDTH_8 DWBW(7) /*!< bit width of the wave signal is 8 */ +#define DAC_WAVE_BIT_WIDTH_9 DWBW(8) /*!< bit width of the wave signal is 9 */ +#define DAC_WAVE_BIT_WIDTH_10 DWBW(9) /*!< bit width of the wave signal is 10 */ +#define DAC_WAVE_BIT_WIDTH_11 DWBW(10) /*!< bit width of the wave signal is 11 */ +#define DAC_WAVE_BIT_WIDTH_12 DWBW(11) /*!< bit width of the wave signal is 12 */ + +/* unmask LFSR bits in DAC LFSR noise mode */ +#define DAC_LFSR_BIT0 DAC_WAVE_BIT_WIDTH_1 /*!< unmask the LFSR bit0 */ +#define DAC_LFSR_BITS1_0 DAC_WAVE_BIT_WIDTH_2 /*!< unmask the LFSR bits[1:0] */ +#define DAC_LFSR_BITS2_0 DAC_WAVE_BIT_WIDTH_3 /*!< unmask the LFSR bits[2:0] */ +#define DAC_LFSR_BITS3_0 DAC_WAVE_BIT_WIDTH_4 /*!< unmask the LFSR bits[3:0] */ +#define DAC_LFSR_BITS4_0 DAC_WAVE_BIT_WIDTH_5 /*!< unmask the LFSR bits[4:0] */ +#define DAC_LFSR_BITS5_0 DAC_WAVE_BIT_WIDTH_6 /*!< unmask the LFSR bits[5:0] */ +#define DAC_LFSR_BITS6_0 DAC_WAVE_BIT_WIDTH_7 /*!< unmask the LFSR bits[6:0] */ +#define DAC_LFSR_BITS7_0 DAC_WAVE_BIT_WIDTH_8 /*!< unmask the LFSR bits[7:0] */ +#define DAC_LFSR_BITS8_0 DAC_WAVE_BIT_WIDTH_9 /*!< unmask the LFSR bits[8:0] */ +#define DAC_LFSR_BITS9_0 DAC_WAVE_BIT_WIDTH_10 /*!< unmask the LFSR bits[9:0] */ +#define DAC_LFSR_BITS10_0 DAC_WAVE_BIT_WIDTH_11 /*!< unmask the LFSR bits[10:0] */ +#define DAC_LFSR_BITS11_0 DAC_WAVE_BIT_WIDTH_12 /*!< unmask the LFSR bits[11:0] */ + +/* DAC data alignment */ +#define DATA_ALIGN(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define DAC_ALIGN_12B_R DATA_ALIGN(0) /*!< 12-bit right-aligned data */ +#define DAC_ALIGN_12B_L DATA_ALIGN(1) /*!< 12-bit left-aligned data */ +#define DAC_ALIGN_8B_R DATA_ALIGN(2) /*!< 8-bit right-aligned data */ + +/* triangle amplitude in DAC triangle noise mode */ +#define DAC_TRIANGLE_AMPLITUDE_1 DAC_WAVE_BIT_WIDTH_1 /*!< triangle amplitude is 1 */ +#define DAC_TRIANGLE_AMPLITUDE_3 DAC_WAVE_BIT_WIDTH_2 /*!< triangle amplitude is 3 */ +#define DAC_TRIANGLE_AMPLITUDE_7 DAC_WAVE_BIT_WIDTH_3 /*!< triangle amplitude is 7 */ +#define DAC_TRIANGLE_AMPLITUDE_15 DAC_WAVE_BIT_WIDTH_4 /*!< triangle amplitude is 15 */ +#define DAC_TRIANGLE_AMPLITUDE_31 DAC_WAVE_BIT_WIDTH_5 /*!< triangle amplitude is 31 */ +#define DAC_TRIANGLE_AMPLITUDE_63 DAC_WAVE_BIT_WIDTH_6 /*!< triangle amplitude is 63 */ +#define DAC_TRIANGLE_AMPLITUDE_127 DAC_WAVE_BIT_WIDTH_7 /*!< triangle amplitude is 127 */ +#define DAC_TRIANGLE_AMPLITUDE_255 DAC_WAVE_BIT_WIDTH_8 /*!< triangle amplitude is 255 */ +#define DAC_TRIANGLE_AMPLITUDE_511 DAC_WAVE_BIT_WIDTH_9 /*!< triangle amplitude is 511 */ +#define DAC_TRIANGLE_AMPLITUDE_1023 DAC_WAVE_BIT_WIDTH_10 /*!< triangle amplitude is 1023 */ +#define DAC_TRIANGLE_AMPLITUDE_2047 DAC_WAVE_BIT_WIDTH_11 /*!< triangle amplitude is 2047 */ +#define DAC_TRIANGLE_AMPLITUDE_4095 DAC_WAVE_BIT_WIDTH_12 /*!< triangle amplitude is 4095 */ + + +/* DAC interrupt */ +#define DAC_INT_DDUDRIE DAC_CTL_DDUDRIE /*!< DAC_OUT DMA underrun interrupt enable */ + +/* DAC interrupt flag */ +#define DAC_INT_FLAG_DDUDR DAC_STAT_DDUDR /*!< DAC_OUT DMA underrun interrupt flag */ + +/* DAC flag */ +#define DAC_FLAG_DDUDR DAC_STAT_DDUDR /*!< DAC_OUT DMA underrun flag */ + +/* function declarations */ +/* initialization functions */ +/* deinitialize DAC */ +void dac_deinit(void); +/* enable DAC */ +void dac_enable(void); +/* disable DAC */ +void dac_disable(void); +/* enable DAC DMA */ +void dac_dma_enable(void); +/* disable DAC DMA */ +void dac_dma_disable(void); +/* enable DAC output buffer */ +void dac_output_buffer_enable(void); +/* disable DAC output buffer */ +void dac_output_buffer_disable(void); +/* get DAC output value */ +uint16_t dac_output_value_get(void); +/* set DAC data holding register value */ +void dac_data_set(uint32_t dac_align, uint16_t data); + +/* DAC trigger configuration */ +/* enable DAC trigger */ +void dac_trigger_enable(void); +/* disable DAC trigger */ +void dac_trigger_disable(void); +/* configure DAC trigger source */ +void dac_trigger_source_config(uint32_t triggersource); +/* enable DAC software trigger */ +void dac_software_trigger_enable(void); +/* disable DAC software trigger */ +void dac_software_trigger_disable(void); + +/* DAC wave mode configuration */ +/* configure DAC wave mode */ +void dac_wave_mode_config(uint32_t wave_mode); +/* configure DAC wave bit width */ +void dac_wave_bit_width_config(uint32_t bit_width); +/* configure DAC LFSR noise mode */ +void dac_lfsr_noise_config(uint32_t unmask_bits); +/* configure DAC triangle noise mode */ +void dac_triangle_noise_config(uint32_t amplitude); + +/* interrupt and flag functions */ +/* get DAC flag */ +FlagStatus dac_flag_get(uint32_t flag); +/* clear DAC flag */ +void dac_flag_clear(uint32_t flag); +/* enable DAC interrupt */ +void dac_interrupt_enable(uint32_t interrupt); +/* disable DAC interrupt */ +void dac_interrupt_disable(uint32_t interrupt); +/* get DAC interrupt flag */ +FlagStatus dac_interrupt_flag_get(uint32_t int_flag); +/* clear DAC interrupt flag */ +void dac_interrupt_flag_clear(uint32_t int_flag); + +#endif /* GD32A50X_DAC_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_dbg.h b/gd32a50x/standard_peripheral/include/gd32a50x_dbg.h new file mode 100644 index 0000000..31e10c6 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_dbg.h @@ -0,0 +1,120 @@ +/*! + \file gd32a50x_dbg.h + \brief definitions for the DBG + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_DBG_H +#define GD32A50X_DBG_H + +#include "gd32a50x.h" + +/* DBG definitions */ +#define DBG DBG_BASE /*!< DBG base address */ + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00000000U) /*!< DBG_ID code register */ +#define DBG_CTL REG32(DBG + 0x00000004U) /*!< DBG control register */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code */ + +/* DBG_CTL */ +#define DBG_CTL_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL_FWDGT_HOLD BIT(8) /*!< hold FWDGT counter when core is halted */ +#define DBG_CTL_WWDGT_HOLD BIT(9) /*!< hold WWDGT counter when core is halted */ +#define DBG_CTL_TIMER0_HOLD BIT(10) /*!< hold TIMER0 counter when core is halted */ +#define DBG_CTL_TIMER1_HOLD BIT(11) /*!< hold TIMER1 counter when core is halted */ +#define DBG_CTL_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus timeout when core is halted */ +#define DBG_CTL_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus timeout when core is halted */ +#define DBG_CTL_TIMER7_HOLD BIT(17) /*!< hold TIMER7 counter when core is halted */ +#define DBG_CTL_TIMER5_HOLD BIT(19) /*!< hold TIMER5 counter when core is halted */ +#define DBG_CTL_TIMER6_HOLD BIT(20) /*!< hold TIMER6 counter when core is halted */ +#define DBG_CTL_MFCOM_HOLD BIT(21) /*!< hold MFCOM counter when core is halted */ +#define DBG_CTL_CAN0_HOLD BIT(22) /*!< hold CAN0 counter when core is halted */ +#define DBG_CTL_CAN1_HOLD BIT(23) /*!< hold CAN1 counter when core is halted */ +#define DBG_CTL_TIMER20_HOLD BIT(30) /*!< hold TIMER20 counter when core is halted */ +#define DBG_CTL_TIMER19_HOLD BIT(31) /*!< hold TIMER19 counter when core is halted */ + + +/* constants definitions */ +#define DBG_LOW_POWER_SLEEP DBG_CTL_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL_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 */ +#define DBG_IDX_CTL ((uint32_t)0x00000004U) + +typedef enum +{ + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 8U), /*!< hold FWDGT counter when core is halted */ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 9U), /*!< hold WWDGT counter when core is halted */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 10U), /*!< hold TIMER0 counter when core is halted */ + DBG_TIMER1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 11U), /*!< hold TIMER1 counter when core is halted */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 15U), /*!< hold I2C0 smbus timeout when core is halted */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 16U), /*!< hold I2C1 smbus timeout when core is halted */ + DBG_TIMER7_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 17U), /*!< hold TIMER7 counter when core is halted */ + DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 19U), /*!< hold TIMER5 counter when core is halted */ + DBG_TIMER6_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 20U), /*!< hold TIMER6 counter when core is halted */ + DBG_MFCOM_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 21U), /*!< hold MFCOM counter when core is halted */ + DBG_CAN0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 22U), /*!< hold CAN0 counter when core is halted */ + DBG_CAN1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 23U), /*!< hold CAN1 counter when core is halted */ + DBG_TIMER20_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 30U), /*!< hold TIMER20 counter when core is halted */ + DBG_TIMER19_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL, 31U), /*!< hold TIMER19 counter when core is halted */ +}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 /* GD32A50X_DBG_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_dma.h b/gd32a50x/standard_peripheral/include/gd32a50x_dma.h new file mode 100644 index 0000000..1f141d5 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_dma.h @@ -0,0 +1,709 @@ +/*! + \file gd32a50x_dma.h + \brief definitions for the DMA + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_DMA_H +#define GD32A50X_DMA_H + +#include "gd32a50x.h" + +/* DMAx(x=0,1) definitions */ +#define DMA0 DMA_BASE /*!< DMA0 base address */ +#define DMA1 (DMA_BASE + 0x00000400U) /*!< DMA1 base address */ +/* DMAMUX definitions */ +#define DMAMUX DMAMUX_BASE /*!< DMA base address */ + +/* DMAx(x=0,1) registers definitions */ +#define DMA_INTF(dmax) REG32((dmax) + 0x00000000U) /*!< DMA interrupt flag register */ +#define DMA_INTC(dmax) REG32((dmax) + 0x00000004U) /*!< DMA interrupt flag clear register */ +#define DMA_CH0CTL(dmax) REG32((dmax) + 0x00000008U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT(dmax) REG32((dmax) + 0x0000000CU) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR(dmax) REG32((dmax) + 0x00000010U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0MADDR(dmax) REG32((dmax) + 0x00000014U) /*!< DMA channel 0 memory base address register */ +#define DMA_CH1CTL(dmax) REG32((dmax) + 0x0000001CU) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT(dmax) REG32((dmax) + 0x00000020U) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR(dmax) REG32((dmax) + 0x00000024U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1MADDR(dmax) REG32((dmax) + 0x00000028U) /*!< DMA channel 1 memory base address register */ +#define DMA_CH2CTL(dmax) REG32((dmax) + 0x00000030U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT(dmax) REG32((dmax) + 0x00000034U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR(dmax) REG32((dmax) + 0x00000038U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2MADDR(dmax) REG32((dmax) + 0x0000003CU) /*!< DMA channel 2 memory base address register */ +#define DMA_CH3CTL(dmax) REG32((dmax) + 0x00000044U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT(dmax) REG32((dmax) + 0x00000048U) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR(dmax) REG32((dmax) + 0x0000004CU) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3MADDR(dmax) REG32((dmax) + 0x00000050U) /*!< DMA channel 3 memory base address register */ +#define DMA_CH4CTL(dmax) REG32((dmax) + 0x00000058U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT(dmax) REG32((dmax) + 0x0000005CU) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR(dmax) REG32((dmax) + 0x00000060U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4MADDR(dmax) REG32((dmax) + 0x00000064U) /*!< DMA channel 4 memory base address register */ + +/* DMAx(x=0) registers definitions */ +#define DMA_CH5CTL(dmax) REG32((dmax) + 0x0000006CU) /*!< DMA channel 5 control register */ +#define DMA_CH5CNT(dmax) REG32((dmax) + 0x00000070U) /*!< DMA channel 5 counter register */ +#define DMA_CH5PADDR(dmax) REG32((dmax) + 0x00000074U) /*!< DMA channel 5 peripheral base address register */ +#define DMA_CH5MADDR(dmax) REG32((dmax) + 0x00000078U) /*!< DMA channel 5 memory base address register */ +#define DMA_CH6CTL(dmax) REG32((dmax) + 0x00000080U) /*!< DMA channel 6 control register */ +#define DMA_CH6CNT(dmax) REG32((dmax) + 0x00000084U) /*!< DMA channel 6 counter register */ +#define DMA_CH6PADDR(dmax) REG32((dmax) + 0x00000088U) /*!< DMA channel 6 peripheral base address register */ +#define DMA_CH6MADDR(dmax) REG32((dmax) + 0x0000008CU) /*!< DMA channel 6 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_CH3CFG REG32(DMAMUX + 0x0000000CU) /*!< DMAMUX request multiplexer channel 3 configuration register */ +#define DMAMUX_RM_CH4CFG REG32(DMAMUX + 0x00000010U) /*!< DMAMUX request multiplexer channel 4 configuration register */ +#define DMAMUX_RM_CH5CFG REG32(DMAMUX + 0x00000014U) /*!< DMAMUX request multiplexer channel 5 configuration register */ +#define DMAMUX_RM_CH6CFG REG32(DMAMUX + 0x00000018U) /*!< DMAMUX request multiplexer channel 6 configuration register */ +#define DMAMUX_RM_CH7CFG REG32(DMAMUX + 0x0000001CU) /*!< DMAMUX request multiplexer channel 7 configuration register */ +#define DMAMUX_RM_CH8CFG REG32(DMAMUX + 0x00000020U) /*!< DMAMUX request multiplexer channel 8 configuration register */ +#define DMAMUX_RM_CH9CFG REG32(DMAMUX + 0x00000024U) /*!< DMAMUX request multiplexer channel 9 configuration register */ +#define DMAMUX_RM_CH10CFG REG32(DMAMUX + 0x00000028U) /*!< DMAMUX request multiplexer channel 10 configuration register */ +#define DMAMUX_RM_CH11CFG REG32(DMAMUX + 0x0000002CU) /*!< DMAMUX request multiplexer channel 11 configuration register */ + +#define DMAMUX_RM_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..6 */ +#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..6 */ +#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */ + +/* DMA_CHxPADDR,x=0..6 */ +#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */ + +/* DMA_CHxMADDR,x=0..6 */ +#define DMA_CHXMADDR_MADDR BITS(0,31) /*!< memory base address */ + +/* DMAMUX_RM_CHxCFG,x=0..6 */ +#define DMAMUX_RM_CHXCFG_MUXID BITS(0,6) /*!< multiplexer input identification */ +#define DMAMUX_RM_CHXCFG_SOIE BIT(8) /*!< synchronization overrun interrupt enable */ +#define DMAMUX_RM_CHXCFG_EVGEN BIT(9) /*!< event generation enable */ +#define DMAMUX_RM_CHXCFG_SYNCEN BIT(16) /*!< synchronization enable */ +#define DMAMUX_RM_CHXCFG_SYNCP BITS(17,18) /*!< synchronization input polarity */ +#define DMAMUX_RM_CHXCFG_NBR BITS(19,23) /*!< number of DMA requests to forward */ +#define DMAMUX_RM_CHXCFG_SYNCID BITS(24,28) /*!< synchronization input identification */ + +/* DMAMUX_RM_INTF */ +#define DMAMUX_RM_INTF_SOIF0 BIT(0) /*!< synchronization overrun event flag of request multiplexer channel 0 */ +#define DMAMUX_RM_INTF_SOIF1 BIT(1) /*!< synchronization overrun event flag of request multiplexer channel 1 */ +#define DMAMUX_RM_INTF_SOIF2 BIT(2) /*!< synchronization overrun event flag of request multiplexer channel 2 */ +#define DMAMUX_RM_INTF_SOIF3 BIT(3) /*!< synchronization overrun event flag of request multiplexer channel 3 */ +#define DMAMUX_RM_INTF_SOIF4 BIT(4) /*!< synchronization overrun event flag of request multiplexer channel 4 */ +#define DMAMUX_RM_INTF_SOIF5 BIT(5) /*!< synchronization overrun event flag of request multiplexer channel 5 */ +#define DMAMUX_RM_INTF_SOIF6 BIT(6) /*!< synchronization overrun event flag of request multiplexer channel 6 */ +#define DMAMUX_RM_INTF_SOIF7 BIT(7) /*!< synchronization overrun event flag of request multiplexer channel 7 */ +#define DMAMUX_RM_INTF_SOIF8 BIT(8) /*!< synchronization overrun event flag of request multiplexer channel 8 */ +#define DMAMUX_RM_INTF_SOIF9 BIT(9) /*!< synchronization overrun event flag of request multiplexer channel 9 */ +#define DMAMUX_RM_INTF_SOIF10 BIT(10) /*!< synchronization overrun event flag of request multiplexer channel 10 */ +#define DMAMUX_RM_INTF_SOIF11 BIT(11) /*!< synchronization overrun event flag of request multiplexer channel 11 */ + +/* 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 */ +#define DMAMUX_RM_INTF_SOIFC3 BIT(3) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 3 */ +#define DMAMUX_RM_INTF_SOIFC4 BIT(4) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 4 */ +#define DMAMUX_RM_INTF_SOIFC5 BIT(5) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 5 */ +#define DMAMUX_RM_INTF_SOIFC6 BIT(6) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 6 */ +#define DMAMUX_RM_INTF_SOIFC7 BIT(7) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 7 */ +#define DMAMUX_RM_INTF_SOIFC8 BIT(8) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 8 */ +#define DMAMUX_RM_INTF_SOIFC9 BIT(9) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 9 */ +#define DMAMUX_RM_INTF_SOIFC10 BIT(10) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 10 */ +#define DMAMUX_RM_INTF_SOIFC11 BIT(11) /*!< clear bit for synchronization overrun event flag of request multiplexer channel 11 */ + +/* 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) << 6U) | (uint32_t)(bitpos)) +#define DMAMUX_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22U) | (uint32_t)((bitpos2) << 16U) \ + | (((uint32_t)(regidx) << 6U) | (uint32_t)(bitpos))) + +#define DMAMUX_REG_VAL(offset) (REG32(DMAMUX + (((uint32_t)(offset) & 0x0000FFFFU) >> 6U))) +#define DMAMUX_REG_VAL2(offset) (REG32(DMAMUX + ((uint32_t)(offset) >> 22U))) +#define DMAMUX_REG_VAL3(offset) (REG32(DMAMUX + (((uint32_t)(offset) & 0x0000FFFFU) >> 6U) + 0x4U)) + +#define DMAMUX_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define DMAMUX_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16U) + +/* 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_RM_CH3CFG_REG_OFFSET 0x0000000CU /*!< DMAMUX_RM_CH3CFG register offset */ +#define DMAMUX_RM_CH4CFG_REG_OFFSET 0x00000010U /*!< DMAMUX_RM_CH4CFG register offset */ +#define DMAMUX_RM_CH5CFG_REG_OFFSET 0x00000014U /*!< DMAMUX_RM_CH5CFG register offset */ +#define DMAMUX_RM_CH6CFG_REG_OFFSET 0x00000018U /*!< DMAMUX_RM_CH6CFG register offset */ +#define DMAMUX_RM_CH7CFG_REG_OFFSET 0x0000001CU /*!< DMAMUX_RM_CH7CFG register offset */ +#define DMAMUX_RM_CH8CFG_REG_OFFSET 0x00000020U /*!< DMAMUX_RM_CH8CFG register offset */ +#define DMAMUX_RM_CH9CFG_REG_OFFSET 0x00000024U /*!< DMAMUX_RM_CH9CFG register offset */ +#define DMAMUX_RM_CH10CFG_REG_OFFSET 0x00000028U /*!< DMAMUX_RM_CH10CFG register offset */ +#define DMAMUX_RM_CH11CFG_REG_OFFSET 0x0000002CU /*!< DMAMUX_RM_CH11CFG 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_RM_INTC_REG_OFFSET 0x00000084U /*!< DMAMUX_RM_INTC register offset */ +#define DMAMUX_RG_INTF_REG_OFFSET 0x00000140U /*!< DMAMUX_RG_INTF register offset */ +#define DMAMUX_RG_INTC_REG_OFFSET 0x00000144U /*!< DMAMUX_RG_INTC register offset */ + +/* DMA channel select */ +typedef enum +{ + DMA_CH0 = 0U, /*!< DMA Channel 0 */ + DMA_CH1, /*!< DMA Channel 1 */ + DMA_CH2, /*!< DMA Channel 2 */ + DMA_CH3, /*!< DMA Channel 3 */ + DMA_CH4, /*!< DMA Channel 4 */ + DMA_CH5, /*!< DMA Channel 5 */ + DMA_CH6, /*!< DMA Channel 6 */ +} dma_channel_enum; + +/* DMAMUX request line multiplexer channel */ +typedef enum +{ + DMAMUX_MULTIPLEXER_CH0 = 0, /*!< DMAMUX request multiplexer Channel0 */ + DMAMUX_MULTIPLEXER_CH1, /*!< DMAMUX request multiplexer Channel1 */ + DMAMUX_MULTIPLEXER_CH2, /*!< DMAMUX request multiplexer Channel2 */ + DMAMUX_MULTIPLEXER_CH3, /*!< DMAMUX request multiplexer Channel3 */ + DMAMUX_MULTIPLEXER_CH4, /*!< DMAMUX request multiplexer Channel4 */ + DMAMUX_MULTIPLEXER_CH5, /*!< DMAMUX request multiplexer Channel5 */ + DMAMUX_MULTIPLEXER_CH6, /*!< DMAMUX request multiplexer Channel6 */ + DMAMUX_MULTIPLEXER_CH7, /*!< DMAMUX request multiplexer Channel7 */ + DMAMUX_MULTIPLEXER_CH8, /*!< DMAMUX request multiplexer Channel8 */ + DMAMUX_MULTIPLEXER_CH9, /*!< DMAMUX request multiplexer Channel9 */ + DMAMUX_MULTIPLEXER_CH10, /*!< DMAMUX request multiplexer Channel10 */ + DMAMUX_MULTIPLEXER_CH11, /*!< DMAMUX request multiplexer Channel11 */ +} 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; + +/* 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_MUXCH3_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 3 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH4_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH4CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 4 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH5_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH5CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH6_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH6CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH7_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH7CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH8_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH8CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH9_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH9CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH10_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH10CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_MUXCH11_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_CH11CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt */ + DMAMUX_INT_GENCH0_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH0CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 0 trigger overrun interrupt */ + DMAMUX_INT_GENCH1_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH1CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 1 trigger overrun interrupt */ + DMAMUX_INT_GENCH2_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH2CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 2 trigger overrun interrupt */ + DMAMUX_INT_GENCH3_TO = DMAMUX_REGIDX_BIT(DMAMUX_RG_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request generator channel 3 trigger overrun interrupt */ +} dmamux_interrupt_enum; + + +/* DMAMUX flags */ +typedef enum { + /* flags in INTF register */ + DMAMUX_FLAG_MUXCH0_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 0U), /*!< DMAMUX request multiplexer channel 0 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH1_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 1U), /*!< DMAMUX request multiplexer channel 1 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH2_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 2U), /*!< DMAMUX request multiplexer channel 2 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH3_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 3U), /*!< DMAMUX request multiplexer channel 3 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH4_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 4U), /*!< DMAMUX request multiplexer channel 4 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH5_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 5U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH6_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 6U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH7_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 7U), /*!< DMAMUX request multiplexer channel 7 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH8_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 8 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH9_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 9U), /*!< DMAMUX request multiplexer channel 9 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH10_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 10U), /*!< DMAMUX request multiplexer channel 10 synchronization overrun flag */ + DMAMUX_FLAG_MUXCH11_SO = DMAMUX_REGIDX_BIT(DMAMUX_RM_INTF_REG_OFFSET, 11U), /*!< DMAMUX request multiplexer channel 11 synchronization overrun flag */ + DMAMUX_FLAG_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_MUXCH3_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 3U, DMAMUX_RM_CH3CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 3 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH4_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 4U, DMAMUX_RM_CH4CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 4 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH5_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 5U, DMAMUX_RM_CH5CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 5 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH6_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 6U, DMAMUX_RM_CH6CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 6 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH7_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 7U, DMAMUX_RM_CH7CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 7 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH8_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 8U, DMAMUX_RM_CH8CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 8 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH9_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 9U, DMAMUX_RM_CH9CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 9 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH10_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 10U, DMAMUX_RM_CH10CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 10 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_MUXCH11_SO = DMAMUX_REGIDX_BIT2(DMAMUX_RM_INTF_REG_OFFSET, 11U, DMAMUX_RM_CH11CFG_REG_OFFSET, 8U), /*!< DMAMUX request multiplexer channel 11 synchronization overrun interrupt flag */ + DMAMUX_INT_FLAG_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 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; /*!< DMA 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) /*!< the reset value of DMA channel DMA_INTF register */ + +#define DMA_FLAG_ADD(flag, shift) ((uint32_t)flag << ((uint32_t)(shift) * 4U)) /*!< DMA channel flag shift */ + +/* DMA channel shift bit */ +#define DMA_CHCTL(dma, channel) REG32(((dma) + 0x00000008U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(dma, channel) REG32(((dma) + 0x0000000CU) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(dma, channel) REG32(((dma) + 0x00000010U) + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHMADDR(dma, channel) REG32(((dma) + 0x00000014U) + 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 channel CHxCFG register */ + +/* DMAMUX request multiplexer channel shift bit */ +#define DMAMUX_RM_CHXCFG(channel) REG32(DMAMUX_RM_CHXCFG_BASE + 0x4U * (uint32_t)(channel)) /*!< the address of DMAMUX 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 + 0x4U * (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 channel */ +#define DMA_INT_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish interrupt flag of channel */ +#define DMA_INT_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish interrupt flag of channel */ +#define DMA_INT_FLAG_ERR DMA_INTF_ERRIF /*!< error interrupt flag of channel */ + +/* DMA flag bits */ +#define DMA_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of channel */ +#define DMA_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish flag of channel */ +#define DMA_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish flag of channel */ +#define DMA_FLAG_ERR DMA_INTF_ERRIF /*!< error flag of channel */ + +/* DMA interrupt enable bits */ +#define DMA_INT_FTF DMA_CHXCTL_FTFIE /*!< enable bit for channel full transfer finish interrupt */ +#define DMA_INT_HTF DMA_CHXCTL_HTFIE /*!< enable bit for channel half transfer finish interrupt */ +#define DMA_INT_ERR DMA_CHXCTL_ERRIE /*!< enable bit for 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 ((uint32_t)0x00U) /*!< next address of peripheral is fixed address mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint32_t)0x01U) /*!< next address of peripheral is increasing address mode */ + +/* DMA memory increasing mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint32_t)0x00U) /*!< next address of memory is fixed address mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint32_t)0x01U) /*!< next address of memory is increasing address mode */ + +/* DMA transfer data size of peripheral */ +#define CHCTL_PWIDTH(regval) (BITS(8,9) & ((regval) << 8U)) /*!< 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) << 10U)) /*!< 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) << 12U)) /*!< 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) << 0U)) /*!< multiplexer input identification */ +#define DMA_REQUEST_M2M RM_CHXCFG_MUXID(0U) /*!< memory to memory transfer */ +#define DMA_REQUEST_GENERATOR0 RM_CHXCFG_MUXID(1U) /*!< DMAMUX request generator 0 */ +#define DMA_REQUEST_GENERATOR1 RM_CHXCFG_MUXID(2U) /*!< DMAMUX request generator 1 */ +#define DMA_REQUEST_GENERATOR2 RM_CHXCFG_MUXID(3U) /*!< DMAMUX request generator 2 */ +#define DMA_REQUEST_GENERATOR3 RM_CHXCFG_MUXID(4U) /*!< DMAMUX request generator 3 */ +#define DMA_REQUEST_ADC RM_CHXCFG_MUXID(5U) /*!< DMAMUX ADC request */ +#define DMA_REQUEST_DAC_CH0 RM_CHXCFG_MUXID(6U) /*!< DMAMUX DAC CH0 request */ +#define DMA_REQUEST_I2C1_RX RM_CHXCFG_MUXID(8U) /*!< DMAMUX I2C1 RX request */ +#define DMA_REQUEST_I2C1_TX RM_CHXCFG_MUXID(9U) /*!< DMAMUX I2C1 TX 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_REQUESR_SSTAT0 RM_CHXCFG_MUXID(12U) /*!< DMAMUX SSTAT0 request */ +#define DMA_REQUESR_SSTAT1 RM_CHXCFG_MUXID(13U) /*!< DMAMUX SSTAT1 request */ +#define DMA_REQUESR_SSTAT2 RM_CHXCFG_MUXID(14U) /*!< DMAMUX SSTAT2 request */ +#define DMA_REQUESR_SSTAT3 RM_CHXCFG_MUXID(15U) /*!< DMAMUX SSTAT3 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_TI RM_CHXCFG_MUXID(24U) /*!< DMAMUX TIMER0 TI request */ +#define DMA_REQUEST_TIMER0_UP RM_CHXCFG_MUXID(25U) /*!< DMAMUX TIMER0 UP request */ +#define DMA_REQUEST_TIMER0_CO RM_CHXCFG_MUXID(26U) /*!< DMAMUX TIMER0 CO request */ +#define DMA_REQUEST_TIMER0_MCH0 RM_CHXCFG_MUXID(27U) /*!< DMAMUX TIMER0 MCH0 request */ +#define DMA_REQUEST_TIMER0_MCH1 RM_CHXCFG_MUXID(28U) /*!< DMAMUX TIMER0 MCH1 request */ +#define DMA_REQUEST_TIMER0_MCH2 RM_CHXCFG_MUXID(29U) /*!< DMAMUX TIMER0 MCH2 request */ +#define DMA_REQUEST_TIMER0_MCH3 RM_CHXCFG_MUXID(30U) /*!< DMAMUX TIMER0 MCH3 request */ +#define DMA_REQUEST_TIMER1_CH0 RM_CHXCFG_MUXID(31U) /*!< DMAMUX TIMER1 CH0 request */ +#define DMA_REQUEST_TIMER1_CH1 RM_CHXCFG_MUXID(32U) /*!< DMAMUX TIMER1 CH1 request */ +#define DMA_REQUEST_TIMER1_CH2 RM_CHXCFG_MUXID(33U) /*!< DMAMUX TIMER1 CH2 request */ +#define DMA_REQUEST_TIMER1_CH3 RM_CHXCFG_MUXID(34U) /*!< DMAMUX TIMER1 CH3 request */ +#define DMA_REQUEST_TIMER1_TI RM_CHXCFG_MUXID(35U) /*!< DMAMUX TIMER1 TI request */ +#define DMA_REQUEST_TIMER1_UP RM_CHXCFG_MUXID(36U) /*!< DMAMUX TIMER1 UP request */ +#define DMA_REQUEST_TIMER7_CH0 RM_CHXCFG_MUXID(37U) /*!< DMAMUX TIMER7 CH0 request */ +#define DMA_REQUEST_TIMER7_CH1 RM_CHXCFG_MUXID(38U) /*!< DMAMUX TIMER7 CH1 request */ +#define DMA_REQUEST_TIMER7_CH2 RM_CHXCFG_MUXID(39U) /*!< DMAMUX TIMER7 CH2 request */ +#define DMA_REQUEST_TIMER7_CH3 RM_CHXCFG_MUXID(40U) /*!< DMAMUX TIMER7 CH3 request */ +#define DMA_REQUEST_TIMER7_TI RM_CHXCFG_MUXID(41U) /*!< DMAMUX TIMER7 TI request */ +#define DMA_REQUEST_TIMER7_UP RM_CHXCFG_MUXID(42U) /*!< DMAMUX TIMER7 UP request */ +#define DMA_REQUEST_TIMER7_CO RM_CHXCFG_MUXID(43U) /*!< DMAMUX TIMER7 CO request */ +#define DMA_REQUEST_TIMER7_MCH0 RM_CHXCFG_MUXID(44U) /*!< DMAMUX TIMER7 MCH0 request */ +#define DMA_REQUEST_TIMER7_MCH1 RM_CHXCFG_MUXID(45U) /*!< DMAMUX TIMER7 MCH1 request */ +#define DMA_REQUEST_TIMER7_MCH2 RM_CHXCFG_MUXID(46U) /*!< DMAMUX TIMER7 MCH2 request */ +#define DMA_REQUEST_TIMER7_MCH3 RM_CHXCFG_MUXID(47U) /*!< DMAMUX TIMER7 MCH3 request */ +#define DMA_REQUEST_CAN1 RM_CHXCFG_MUXID(48U) /*!< DMAMUX CAN1 request */ +#define DMA_REQUEST_CAN0 RM_CHXCFG_MUXID(49U) /*!< DMAMUX CAN0 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 USART2 RX request */ +#define DMA_REQUEST_USART2_TX RM_CHXCFG_MUXID(55U) /*!< DMAMUX USART2 TX request */ +#define DMA_REQUEST_TIMER5_UP RM_CHXCFG_MUXID(56U) /*!< DMAMUX TIMER5 UP request */ +#define DMA_REQUEST_TIMER6_UP RM_CHXCFG_MUXID(57U) /*!< DMAMUX TIMER6 UP request */ +#define DMA_REQUEST_TIMER19_CH0 RM_CHXCFG_MUXID(58U) /*!< DMAMUX TIMER19 CH0 request */ +#define DMA_REQUEST_TIMER19_CH1 RM_CHXCFG_MUXID(59U) /*!< DMAMUX TIMER19 CH1 request */ +#define DMA_REQUEST_TIMER19_CH2 RM_CHXCFG_MUXID(60U) /*!< DMAMUX TIMER19 CH2 request */ +#define DMA_REQUEST_TIMER19_CH3 RM_CHXCFG_MUXID(61U) /*!< DMAMUX TIMER19 CH3 request */ +#define DMA_REQUEST_TIMER19_TI RM_CHXCFG_MUXID(62U) /*!< DMAMUX TIMER19 TI request */ +#define DMA_REQUEST_TIMER19_UP RM_CHXCFG_MUXID(63U) /*!< DMAMUX TIMER19 UP request */ +#define DMA_REQUEST_TIMER19_CO RM_CHXCFG_MUXID(64U) /*!< DMAMUX TIMER19 CO request */ +#define DMA_REQUEST_TIMER19_MCH0 RM_CHXCFG_MUXID(65U) /*!< DMAMUX TIMER19 MCH0 request */ +#define DMA_REQUEST_TIMER19_MCH1 RM_CHXCFG_MUXID(66U) /*!< DMAMUX TIMER19 MCH1 request */ +#define DMA_REQUEST_TIMER19_MCH2 RM_CHXCFG_MUXID(67U) /*!< DMAMUX TIMER19 MCH2 request */ +#define DMA_REQUEST_TIMER19_MCH3 RM_CHXCFG_MUXID(68U) /*!< DMAMUX TIMER19 MCH3 request */ +#define DMA_REQUEST_TIMER20_CH0 RM_CHXCFG_MUXID(69U) /*!< DMAMUX TIMER20 CH0 request */ +#define DMA_REQUEST_TIMER20_CH1 RM_CHXCFG_MUXID(70U) /*!< DMAMUX TIMER20 CH1 request */ +#define DMA_REQUEST_TIMER20_CH2 RM_CHXCFG_MUXID(71U) /*!< DMAMUX TIMER20 CH2 request */ +#define DMA_REQUEST_TIMER20_CH3 RM_CHXCFG_MUXID(72U) /*!< DMAMUX TIMER20 CH3 request */ +#define DMA_REQUEST_TIMER20_TI RM_CHXCFG_MUXID(73U) /*!< DMAMUX TIMER20 TI request */ +#define DMA_REQUEST_TIMER20_UP RM_CHXCFG_MUXID(74U) /*!< DMAMUX TIMER20 UP request */ +#define DMA_REQUEST_TIMER20_CO RM_CHXCFG_MUXID(75U) /*!< DMAMUX TIMER20 CO request */ +#define DMA_REQUEST_TIMER20_MCH0 RM_CHXCFG_MUXID(76U) /*!< DMAMUX TIMER20 MCH0 request */ +#define DMA_REQUEST_TIMER20_MCH1 RM_CHXCFG_MUXID(77U) /*!< DMAMUX TIMER20 MCH1 request */ +#define DMA_REQUEST_TIMER20_MCH2 RM_CHXCFG_MUXID(78U) /*!< DMAMUX TIMER20 MCH2 request */ +#define DMA_REQUEST_TIMER20_MCH3 RM_CHXCFG_MUXID(79U) /*!< DMAMUX TIMER20 MCH3 request */ + +/* DMAMUX request generator trigger input identification */ +#define RG_CHXCFG_TID(regval) (BITS(0,4) & ((regval) << 0U)) /*!< 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_EVTX_OUT0 RG_CHXCFG_TID(16U) /*!< trigger input is Evtx_out0 */ +#define DMAMUX_TRIGGER_EVTX_OUT1 RG_CHXCFG_TID(17U) /*!< trigger input is Evtx_out1 */ +#define DMAMUX_TRIGGER_EVTX_OUT2 RG_CHXCFG_TID(18U) /*!< trigger input is Evtx_out2 */ +#define DMAMUX_TRIGGER_EVTX_OUT3 RG_CHXCFG_TID(19U) /*!< trigger input is Evtx_out3 */ +#define DMAMUX_TRIGGER_TIMER20_CH0_O RG_CHXCFG_TID(22U) /*!< trigger input is TIMER20_CH0_O */ + +/* DMAMUX request generator trigger polarity */ +#define RM_CHXCFG_RGTP(regval) (BITS(17,18) & ((regval) << 17U)) /*!< DMA request generator trigger polarity */ +#define DMAMUX_GEN_NO_EVENT RM_CHXCFG_RGTP(0U) /*!< no event detection */ +#define DMAMUX_GEN_RISING RM_CHXCFG_RGTP(1U) /*!< rising edge */ +#define DMAMUX_GEN_FALLING RM_CHXCFG_RGTP(2U) /*!< falling edge */ +#define DMAMUX_GEN_RISING_FALLING RM_CHXCFG_RGTP(3U) /*!< rising and falling edges */ + +/* number of DMA requests to be generated */ +#define RG_CHXCFG_NBRG(regval) (BITS(19,23) & ((regval) << 19U)) /*!< number of DMA requests to be generated */ + +/* DMAMUX request multiplexer channel synchronization input identification */ +#define RM_CHXCFG_SYNCID(regval) (BITS(24,28) & ((regval) << 24U)) /*!< 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_EVTX_OUT0 RM_CHXCFG_SYNCID(16U) /*!< synchronization input is Evtx_out0 */ +#define DMAMUX_SYNC_EVTX_OUT1 RM_CHXCFG_SYNCID(17U) /*!< synchronization input is Evtx_out1 */ +#define DMAMUX_SYNC_EVTX_OUT2 RM_CHXCFG_SYNCID(18U) /*!< synchronization input is Evtx_out2 */ +#define DMAMUX_SYNC_EVTX_OUT3 RM_CHXCFG_SYNCID(19U) /*!< synchronization input is Evtx_out3 */ +#define DMAMUX_SYNC_TIMER20_CH0_O RM_CHXCFG_SYNCID(22U) /*!< synchronization input is TIMER20_CH0_O */ + +/* DMAMUX request multiplexer synchronization input polarity */ +#define RM_CHXCFG_SYNCP(regval) (BITS(17,18) & ((regval) << 17U)) /*!< synchronization input polarity */ +#define DMAMUX_SYNC_NO_EVENT RM_CHXCFG_SYNCP(0U) /*!< no event detection */ +#define DMAMUX_SYNC_RISING RM_CHXCFG_SYNCP(1U) /*!< rising edge */ +#define DMAMUX_SYNC_FALLING RM_CHXCFG_SYNCP(2U) /*!< falling edge */ +#define DMAMUX_SYNC_RISING_FALLING RM_CHXCFG_SYNCP(3U) /*!< rising and falling edges */ + +/* number of DMA requests to forward */ +#define RM_CHXCFG_NBR(regval) (BITS(19,23) & ((regval) << 19)) /*!< number of DMA requests to forward */ + +/* function declarations */ +/* DMA functions */ +/* DMA initialization functions */ +/* deinitialize DMA channel registers */ +void dma_deinit(uint32_t dma_periph, 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(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct* init_struct); +/* enable DMA circulation mode */ +void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* enable memory to memory mode */ +void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable memory to memory mode */ +void dma_memory_to_memory_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx); + +/* DMA configuration functions */ +/* set DMA peripheral base address */ +void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address); +/* configure DMA memory base address */ +void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address); +/* configure the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number); +/* get the number of remaining data to be transferred by the DMA */ +uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority); +/* configure transfer data size of memory */ +void dma_memory_width_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t mwidth); +/* configure transfer data size of peripheral */ +void dma_periph_width_config (uint32_t dma_periph, dma_channel_enum channelx, uint32_t pwidth); +/* enable next address increasement algorithm of memory */ +void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable next address increasement algorithm of memory */ +void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* enable next address increasement algorithm of peripheral */ +void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx); +/* disable next address increasement algorithm of peripheral */ +void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction); + +/* DMA interrupt and flag functions */ +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* clear a DMA channel flag */ +void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source); +/* check DMA flag and interrupt enable bit is set or not */ +FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag); +/* clear a DMA channel interrupt flag */ +void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag); + +/* DMAMUX functions */ +/* DMAMUX request multiplexer functions */ +/* initialize the parameters of DMAMUX synchronization mode structure with the default values */ +void dmamux_sync_struct_para_init(dmamux_sync_parameter_struct *init_struct); +/* initialize DMAMUX request multiplexer channel synchronization mode */ +void dmamux_synchronization_init(dmamux_multiplexer_channel_enum channelx, dmamux_sync_parameter_struct *init_struct); +/* enable synchronization mode */ +void dmamux_synchronization_enable(dmamux_multiplexer_channel_enum channelx); +/* disable synchronization mode */ +void dmamux_synchronization_disable(dmamux_multiplexer_channel_enum channelx); +/* enable event generation */ +void dmamux_event_generation_enable(dmamux_multiplexer_channel_enum channelx); +/* disable event generation */ +void dmamux_event_generation_disable(dmamux_multiplexer_channel_enum channelx); + +/* DMAMUX request generator functions */ +/* initialize the parameters of DMAMUX request generator structure with the default values */ +void dmamux_gen_struct_para_init(dmamux_gen_parameter_struct *init_struct); +/* initialize DMAMUX request generator channel */ +void dmamux_request_generator_init(dmamux_generator_channel_enum channelx, dmamux_gen_parameter_struct *init_struct); +/* enable DMAMUX request generator channel */ +void dmamux_request_generator_channel_enable(dmamux_generator_channel_enum channelx); +/* disable DMAMUX request generator channel */ +void dmamux_request_generator_channel_disable(dmamux_generator_channel_enum channelx); + +/* DMAMUX configuration functions */ +/* configure synchronization input polarity */ +void dmamux_synchronization_polarity_config(dmamux_multiplexer_channel_enum channelx, uint32_t polarity); +/* configure number of DMA requests to forward */ +void dmamux_request_forward_number_config(dmamux_multiplexer_channel_enum channelx, uint32_t number); +/* configure synchronization input identification */ +void dmamux_sync_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id); +/* configure multiplexer input identification */ +void dmamux_request_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id); +/* configure trigger input polarity */ +void dmamux_trigger_polarity_config(dmamux_generator_channel_enum channelx, uint32_t polarity); +/* configure number of DMA requests to be generated */ +void dmamux_request_generate_number_config(dmamux_generator_channel_enum channelx, uint32_t number); +/* configure trigger input identification */ +void dmamux_trigger_id_config(dmamux_generator_channel_enum channelx, uint32_t id); + +/* 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 /* GD32A50X_DMA_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_exti.h b/gd32a50x/standard_peripheral/include/gd32a50x_exti.h new file mode 100644 index 0000000..3c9dfaa --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_exti.h @@ -0,0 +1,286 @@ +/*! + \file gd32a50x_exti.h + \brief definitions for the EXTI + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_EXTI_H +#define GD32A50X_EXTI_H + +#include "gd32a50x.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00000000U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x00000004U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x00000008U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0000000CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x00000010U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x00000014U) /*!< 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 */ +#define EXTI_INTEN_INTEN24 BIT(24) /*!< interrupt from line 24 */ +/* 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 */ +#define EXTI_EVEN_EVEN24 BIT(24) /*!< event from line 24 */ + +/* 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 */ +#define EXTI_RTEN_RTEN24 BIT(24) /*!< rising edge from line 24 */ + +/* 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 */ +#define EXTI_FTEN_FTEN24 BIT(24) /*!< falling edge from line 24 */ +/* 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 */ +#define EXTI_SWIEV_SWIEV24 BIT(24) /*!< software interrupt/event request from line 24 */ + +/* EXTI_PD */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt/event pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt/event pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt/event pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt/event pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt/event pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt/event pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt/event pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt/event pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt/event pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt/event pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt/event pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt/event pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt/event pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt/event pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt/event pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt/event pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt/event pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt/event pending status from line 17 */ +#define EXTI_PD_PD18 BIT(18) /*!< interrupt/event pending status from line 18 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt/event pending status from line 19 */ +#define EXTI_PD_PD20 BIT(20) /*!< interrupt/event pending status from line 20 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt/event pending status from line 21 */ +#define EXTI_PD_PD22 BIT(22) /*!< interrupt/event pending status from line 22 */ +#define EXTI_PD_PD23 BIT(23) /*!< interrupt/event pending status from line 23 */ +#define EXTI_PD_PD24 BIT(24) /*!< interrupt/event pending status from line 24 */ + +/* 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_24 = BIT(24), /*!< EXTI line 24 */ +}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 */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* initialize the EXTI */ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); +/* enable the interrupts from EXTI line x */ +void exti_interrupt_enable(exti_line_enum linex); +/* disable the interrupts from EXTI line x */ +void exti_interrupt_disable(exti_line_enum linex); +/* enable the events from EXTI line x */ +void exti_event_enable(exti_line_enum linex); +/* disable the events from EXTI line x */ +void exti_event_disable(exti_line_enum linex); + +/* enable the EXTI software interrupt event */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* disable the EXTI software interrupt event */ +void exti_software_interrupt_disable(exti_line_enum linex); +/* get EXTI line x pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI line x pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI line x flag when the interrupt flag is set */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI line x pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); + +#endif /* GD32A50X_EXTI_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_fmc.h b/gd32a50x/standard_peripheral/include/gd32a50x_fmc.h new file mode 100644 index 0000000..24d9f25 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_fmc.h @@ -0,0 +1,537 @@ +/*! + \file gd32a50x_fmc.h + \brief definitions for the FMC + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_FMC_H +#define GD32A50X_FMC_H + +#include "gd32a50x.h" + +/* FMC and option bytes definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option bytes 0 base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00000000U) /*!< FMC wait state register */ +#define FMC_ECCCS REG32((FMC) + 0x00000004U) /*!< FMC ECC control and status register */ +#define FMC_KEY0 REG32((FMC) + 0x00000008U) /*!< FMC unlock key register 0 */ +#define FMC_STAT0 REG32((FMC) + 0x0000000CU) /*!< FMC status register 0 */ +#define FMC_CTL0 REG32((FMC) + 0x00000010U) /*!< FMC control register 0 */ +#define FMC_ADDR0 REG32((FMC) + 0x00000014U) /*!< FMC address register 0 */ +#define FMC_OBKEY REG32((FMC) + 0x00000044U) /*!< FMC option byte unlock key register */ +#define FMC_KEY1 REG32((FMC) + 0x00000048U) /*!< FMC unlock key register 1 */ +#define FMC_STAT1 REG32((FMC) + 0x0000004CU) /*!< FMC status register 1 */ +#define FMC_CTL1 REG32((FMC) + 0x00000050U) /*!< FMC control register 1 */ +#define FMC_ADDR1 REG32((FMC) + 0x00000054U) /*!< FMC address register 1 */ +#define FMC_EPCNT REG32((FMC) + 0x00000058U) /*!< FMC EEPROM counter register */ +#define FMC_OBSTAT REG32((FMC) + 0x0000005CU) /*!< FMC option byte status register */ +#define FMC_WP0 REG32((FMC) + 0x00000060U) /*!< FMC erase/program protection register 0 */ +#define FMC_WP1 REG32((FMC) + 0x00000064U) /*!< FMC erase/program protection register 1 */ +#define FMC_OB1CS REG32((FMC) + 0x00000068U) /*!< FMC option byte 1 control and status register */ +#define FMC_PID REG32((FMC) + 0x00000100U) /*!< FMC product ID register */ + +#define OP_BYTE(x) REG32(OB + ((uint32_t)((uint32_t)0x04U * (x)))) /*!< option bytes 0 value */ +#define OB_SPC REG16((OB) + 0x00000000U) /*!< option bytes 0 security protection value*/ +#define OB_USER REG16((OB) + 0x00000002U) /*!< option bytes 0 user value*/ +#define OB_SPC_USER REG32((OB) + 0x00000000U) /*!< option bytes 0 security protection value and user value */ +#define OB_DATA REG32((OB) + 0x00000004U) /*!< option bytes 0 data value */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */ +#define FMC_WS_PFEN BIT(4) /*!< pre-fetch enable */ +#define FMC_WS_IDCEN BIT(9) /*!< cache enable */ +#define FMC_WS_IDRST BIT(11) /*!< cache reset */ +#define FMC_WS_SLEEP_SLP BIT(14) /*!< flash goto sleep mode or power-down mode when MCU enters deepsleep mode */ +#define FMC_WS_ERAMRDY BIT(16) /*!< EEPROM SRAM ready flag */ +#define FMC_WS_BRAMRDY BIT(17) /*!< basic SRAM ready flag */ +#define FMC_WS_PRAMRDY BIT(18) /*!< fast PG SRAM ready flag */ + +/* FMC_ECCCS */ +#define FMC_ECCCS_ECCADDR BITS(0,14) /*!< the offset address of double word where an ECC error is detected */ +#define FMC_ECCCS_OB0_ECC BIT(19) /*!< option bytes 0 one bit error flag */ +#define FMC_ECCCS_BK1_ECC BIT(20) /*!< bank1 one bit error flag */ +#define FMC_ECCCS_SYS_ECC BIT(21) /*!< system memory one bit error flag */ +#define FMC_ECCCS_DF_ECC BIT(22) /*!< data flash one bit error flag */ +#define FMC_ECCCS_OTP_ECC BIT(23) /*!< OTP one bit error flag */ +#define FMC_ECCCS_ECCCORIE BIT(24) /*!< one bit error correct interrupt enable */ +#define FMC_ECCCS_ECCDETIE BIT(25) /*!< two bits error detect interrupt enable */ +#define FMC_ECCCS_OB1ECCDET BIT(26) /*!< option bytes 1 two bits error detect flag */ +#define FMC_ECCCS_OB0ECCDET BIT(27) /*!< option bytes 0 two bits error detect flag */ +#define FMC_ECCCS_EPECCDET BIT(29) /*!< EEPROM two bits error detect flag */ +#define FMC_ECCCS_ECCCOR BIT(30) /*!< one bit error detected and correct flag */ +#define FMC_ECCCS_ECCDET BIT(31) /*!< two bits error detect flag */ + +/* FMC_KEY0 */ +#define FMC_KEY0_KEY BITS(0,31) /*!< flash bank0 unlock key bits */ + +/* FMC_STAT0 */ +#define FMC_STAT0_BUSY BIT(0) /*!< flash bank0 busy flag */ +#define FMC_STAT0_PGSERR BIT(1) /*!< flash bank0 program sequence error flag */ +#define FMC_STAT0_PGERR BIT(2) /*!< flash bank0 program error flag */ +#define FMC_STAT0_PGAERR BIT(3) /*!< flash bank0 program alignment error flag */ +#define FMC_STAT0_WPERR BIT(4) /*!< flash bank0 erase/program protection error flag */ +#define FMC_STAT0_ENDF BIT(5) /*!< flash bank0 end of operation flag */ +#define FMC_STAT0_CBCMDERR BIT(6) /*!< flash bank0 checked area by the check blank command is all 0xFF or not */ +#define FMC_STAT0_RSTERR BIT(15) /*!< flash bank0 BOR/POR or system reset during erase/program flag */ + +/* FMC_CTL0 */ +#define FMC_CTL0_PG BIT(0) /*!< flash bank0 program command bit */ +#define FMC_CTL0_PER BIT(1) /*!< flash bank0 page erase bit */ +#define FMC_CTL0_MER BIT(2) /*!< flash bank0 mass erase bit */ +#define FMC_CTL0_START BIT(6) /*!< send erase command to flash bank0 bit */ +#define FMC_CTL0_LK BIT(7) /*!< flash bank0 lock bit */ +#define FMC_CTL0_FSTPG BIT(8) /*!< flash bank0 fast program command bit */ +#define FMC_CTL0_ERRIE BIT(10) /*!< flash bank0 error interrupt enable bit */ +#define FMC_CTL0_ENDIE BIT(12) /*!< flash bank0 end of operation interrupt enable bit */ +#define FMC_CTL0_CBCMD BIT(16) /*!< send check blank command to flash bank0 bit */ +#define FMC_CTL0_CBCMDLEN BITS(29,31) /*!< check blank command read length to flash bank0 */ + +/* FMC_ADDR0 */ +#define FMC_ADDR0_ADDR BITS(0,31) /*!< flash bank0 command address bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key bits */ + +/* FMC_KEY1 */ +#define FMC_KEY1_KEY BITS(0,31) /*!< flash bank1 unlock key bits */ + +/* FMC_STAT1 */ +#define FMC_STAT1_BUSY BIT(0) /*!< flash bank1 busy flag */ +#define FMC_STAT1_PGSERR BIT(1) /*!< flash bank1 program sequence error flag */ +#define FMC_STAT1_PGERR BIT(2) /*!< flash bank1 program error flag */ +#define FMC_STAT1_PGAERR BIT(3) /*!< flash bank1 program alignment error flag */ +#define FMC_STAT1_WPERR BIT(4) /*!< flash bank1 erase/program protection error flag */ +#define FMC_STAT1_ENDF BIT(5) /*!< flash bank1 end of operation flag */ +#define FMC_STAT1_CBCMDERR BIT(6) /*!< flash bank1 checked area by the check blank command is all 0xFF or not */ +#define FMC_STAT1_RSTERR BIT(15) /*!< flash bank1 BOR/POR or system reset during erase/program flag */ + +/* FMC_CTL1 */ +#define FMC_CTL1_PG BIT(0) /*!< flash bank1 program command bit */ +#define FMC_CTL1_PER BIT(1) /*!< flash bank1 page erase bit */ +#define FMC_CTL1_MER BIT(2) /*!< flash bank1 mass erase bit */ +#define FMC_CTL1_MERDF BIT(3) /*!< data flash mass erase bit */ +#define FMC_CTL1_OB0PG BIT(4) /*!< option bytes 0 program command bit */ +#define FMC_CTL1_OB0ER BIT(5) /*!< option bytes 0 erase command bit */ +#define FMC_CTL1_START BIT(6) /*!< send erase command to FMC bit */ +#define FMC_CTL1_LK BIT(7) /*!< flash bank1 lock bit */ +#define FMC_CTL1_FSTPG BIT(8) /*!< fast program command bit */ +#define FMC_CTL1_OBWEN BIT(9) /*!< option bytes erase/program enable bit */ +#define FMC_CTL1_ERRIE BIT(10) /*!< flash bank1 error interrupt enable bit */ +#define FMC_CTL1_ENDIE BIT(12) /*!< flash bank1 end of operation interrupt enable bit */ +#define FMC_CTL1_OBRLD BIT(13) /*!< option bytes reload bit */ +#define FMC_CTL1_CBCMD BIT(16) /*!< send check blank command to flash bank1 bit */ +#define FMC_CTL1_SRAMCMD BITS(24,25) /*!< send shared SRAM command */ +#define FMC_CTL1_CBCMDLEN BITS(29,31) /*!< check blank command read length to flash bank1 */ + +/* FMC_ADDR1 */ +#define FMC_ADDR1_ADDR BITS(0,31) /*!< flash bank1 command address bits */ + +/* FMC_EPCNT */ +#define FMC_EPCNT_EPCNT BITS(0,31) /*!< EEPROM erase counter */ + +/* FMC_OBSTAT */ +#define FMC_OBSTAT_OBERR BIT(0) /*!< option bytes read error bit */ +#define FMC_OBSTAT_PLEVEL BITS(1,2) /*!< protection level bits */ +#define FMC_OBSTAT_USER BITS(8,15) /*!< option bytes user bits */ +#define FMC_OBSTAT_DATA BITS(16,31) /*!< option bytes data bits */ + +/* FMC_WP0 */ +#define FMC_WP0_BK0WP BITS(0,31) /*!< store OB_BK0WP[31:0] of option bytes 0 block after system reset */ + +/* FMC_WP1 */ +#define FMC_WP1_BK1WP BITS(0,7) /*!< store OB_BK1WP[7:0] of option bytes 0 block after system reset */ +#define FMC_WP1_DFWP BITS(8,15) /*!< store OB_DFWP[7:0] of option bytes 0 block after system reset */ +#define FMC_WP1_EPWP BITS(16,23) /*!< store OB_EPWP[7:0] of option bytes 0 block after system reset */ + +/* FMC_OB1CS */ +#define FMC_OB1CS_OB1ERR BIT(0) /*!< option bytes 1 read error bit */ +#define FMC_OB1CS_OB1START BIT(1) /*!< send option bytes 1 change command to FMC */ +#define FMC_OB1CS_OB1LK BIT(2) /*!< option bytes 1 lock bit */ +#define FMC_OB1CS_EFALC BITS(4,7) /*!< load EFALC of option bytes 1 after reset */ +#define FMC_OB1CS_EPSIZE BITS(8,11) /*!< load EPSIZE of option bytes 1 after reset */ +#define FMC_OB1CS_EPLOAD BIT(15) /*!< load EPLOAD of option bytes 1 after reset */ +#define FMC_OB1CS_LKVAL BITS(16,31) /*!< load LKVAL of option bytes 1 after reset */ + +/* FMC_PID */ +#define FMC_PID_PID BITS(0,31) /*!< product ID bits */ + +/* constants definitions */ +/* fmc state */ +typedef enum { + FMC_READY, /*!< the operation has been completed */ + FMC_BUSY, /*!< the operation is in progress */ + FMC_PGSERR, /*!< program sequence error */ + FMC_PGERR, /*!< program error */ + FMC_PGAERR, /*!< program alignment error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_TOERR, /*!< timeout error */ + FMC_CBCMDERR, /*!< the checked area not blank error */ + FMC_RSTERR, /*!< BOR/POR or system reset during flash erase/program error */ + FMC_OB_HSPC, /*!< FMC is under high security protection */ + FMC_OB1_LK /*!< option bytes 1 is locked */ +} fmc_state_enum; + +/* shared SRAM mode */ +typedef enum { + NO_SRAM_MODE = 0, /*!< SRAM mode is not configured */ + FASTPG_SRAM_MODE = 1, /*!< fast program SRAM mode */ + BASIC_SRAM_MODE = 2, /*!< basic SRAM mode */ + EEPROM_SRAM_MODE = 3 /*!< EEPROM SRAM mode */ +} fmc_sram_mode_enum; + +/* FMC area */ +typedef enum { + BANK0_AREA = 0, /*!< main flash bank0 area */ + BANK1_AREA = 1, /*!< main flash bank1 area */ + DATA_FLASH_AREA = 2, /*!< data flash area */ + EEPROM_AREA = 3 /*!< EEPROM area */ +} fmc_area_enum; + +/* define the FMC bit position and its register index offset */ +#define FMC_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define FMC_REG_VAL(offset) (REG32(FMC + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define FMC_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define FMC_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define FMC_REG_VAL2(offset) (REG32(FMC + ((uint32_t)(offset) >> 22))) +#define FMC_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define FMC_STAT0_REG_OFFSET ((uint32_t)0x0000000CU) /*!< STAT0 register offset */ +#define FMC_STAT1_REG_OFFSET ((uint32_t)0x0000004CU) /*!< STAT1 register offset */ +#define FMC_ECCCS_REG_OFFSET ((uint32_t)0x00000004U) /*!< ECCCS register offset */ +#define FMC_OB1CS_REG_OFFSET ((uint32_t)0x00000068U) /*!< OB1CS register offset */ +#define FMC_CTL0_REG_OFFSET ((uint32_t)0x00000010U) /*!< CTL0 register offset */ +#define FMC_CTL1_REG_OFFSET ((uint32_t)0x00000050U) /*!< CTL1 register offset */ +#define FMC_OBSTAT_REG_OFFSET ((uint32_t)0x0000005CU) /*!< OBSTAT register offset */ + +/* FMC flags */ +typedef enum { + /* flags in STAT0 register */ + FMC_BANK0_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 0U), /*!< flash bank0 busy flag */ + FMC_BANK0_FLAG_PGSERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 1U), /*!< flash bank0 program sequence error flag */ + FMC_BANK0_FLAG_PGERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 2U), /*!< flash bank0 program error flag */ + FMC_BANK0_FLAG_PGAERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 3U), /*!< flash bank0 program alignment error flag */ + FMC_BANK0_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 4U), /*!< flash bank0 erase/program protection error flag */ + FMC_BANK0_FLAG_END = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 5U), /*!< flash bank0 end of operation flag */ + FMC_BANK0_FLAG_CBCMDERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 6U), /*!< flash bank0 checked area by the check blank command is all 0xFF or not flag */ + FMC_BANK0_FLAG_RSTERR = FMC_REGIDX_BIT(FMC_STAT0_REG_OFFSET, 15U), /*!< flash bank0 BOR/POR or system reset during erase/program flag */ + /* flags in STAT1 register */ + FMC_BANK1_FLAG_BUSY = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 0U), /*!< flash bank1 busy flag */ + FMC_BANK1_FLAG_PGSERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 1U), /*!< flash bank1 program sequence error flag */ + FMC_BANK1_FLAG_PGERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 2U), /*!< flash bank1 program error flag */ + FMC_BANK1_FLAG_PGAERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 3U), /*!< flash bank1 program alignment error flag */ + FMC_BANK1_FLAG_WPERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 4U), /*!< flash bank1 erase/program protection error flag */ + FMC_BANK1_FLAG_END = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 5U), /*!< flash bank1 end of operation flag */ + FMC_BANK1_FLAG_CBCMDERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 6U), /*!< flash bank1 checked area by the check blank command is all 0xFF or not flag */ + FMC_BANK1_FLAG_RSTERR = FMC_REGIDX_BIT(FMC_STAT1_REG_OFFSET, 15U), /*!< flash bank1 BOR/POR or system reset during erase/program flag */ + /* flags in ECCCS register */ + FMC_FLAG_BK0ECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 28U), /*!< an ECC bit error is detected in bank 0 flag */ + FMC_FLAG_OB0ECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 19U), /*!< an ECC bit error is detected in option byte 0 flag */ + FMC_FLAG_BK1ECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 20U), /*!< an ECC bit error is detected in bank 1 flag */ + FMC_FLAG_SYSECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 21U), /*!< an ECC bit error is detected in system memory flag */ + FMC_FLAG_DFECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 22U), /*!< an ECC bit error is detected in data flash flag */ + FMC_FLAG_OTPECC = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 23U), /*!< an ECC bit error is detected in OTP flag */ + FMC_FLAG_OB1ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 26U), /*!< option bytes 1 two bit error detect flag */ + FMC_FLAG_OB0ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 27U), /*!< option bytes 0 two bit error detect flag */ + FMC_FLAG_EPECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 29U), /*!< EEPROM two bits error detect flag */ + FMC_FLAG_ECCCOR = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 30U), /*!< one bit error detected and correct flag */ + FMC_FLAG_ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 31U), /*!< OTP/data flash/system memory/bank1 two bit error detect flag */ + /* flags in OBSTAT register */ + FMC_FLAG_OBERR = FMC_REGIDX_BIT(FMC_OBSTAT_REG_OFFSET, 0U), /*!< option bytes 0 error flag */ + /* flags in OB1CS register */ + FMC_FLAG_OB1ERR = FMC_REGIDX_BIT(FMC_OB1CS_REG_OFFSET, 0U) /*!< option bytes 1 read error flag */ +} fmc_flag_enum; + +/* FMC interrupt flags */ +typedef enum { + /* interrupt flags in STAT0 register */ + FMC_BANK0_INT_FLAG_PGSERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 1U), /*!< flash bank0 program sequence error interrupt flag */ + FMC_BANK0_INT_FLAG_PGERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 2U), /*!< flash bank0 program error interrupt flag */ + FMC_BANK0_INT_FLAG_PGAERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 3U), /*!< flash bank0 program alignment error interrupt flag */ + FMC_BANK0_INT_FLAG_WPERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 4U), /*!< flash bank0 erase/program protection error interrupt flag */ + FMC_BANK0_INT_FLAG_END = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 12U, FMC_STAT0_REG_OFFSET, 5U), /*!< flash bank0 end of operation interrupt flag */ + FMC_BANK0_INT_FLAG_CBCMDERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 6U), /*!< flash bank0 checked area by the check blank command is all 0xFF or not interrupt flag */ + FMC_BANK0_INT_FLAG_RSTERR = FMC_REGIDX_BIT2(FMC_CTL0_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 15U), /*!< flash bank0 BOR/POR or system reset during erase/program interrupt flag */ + /* interrupt flags in STAT1 register */ + FMC_BANK1_INT_FLAG_PGSERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 1U), /*!< flash bank1 program sequence error interrupt flag */ + FMC_BANK1_INT_FLAG_PGERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 2U), /*!< flash bank1 program error interrupt flag */ + FMC_BANK1_INT_FLAG_PGAERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 3U), /*!< flash bank1 program alignment error interrupt flag */ + FMC_BANK1_INT_FLAG_WPERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 4U), /*!< flash bank1 erase/program protection error interrupt flag */ + FMC_BANK1_INT_FLAG_END = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 12U, FMC_STAT0_REG_OFFSET, 5U), /*!< flash bank1 end of operation interrupt flag */ + FMC_BANK1_INT_FLAG_CBCMDERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 6U), /*!< flash bank1 checked area by the check blank command is all 0xFF or not interrupt flag */ + FMC_BANK1_INT_FLAG_RSTERR = FMC_REGIDX_BIT2(FMC_CTL1_REG_OFFSET, 10U, FMC_STAT0_REG_OFFSET, 15U), /*!< flash bank1 BOR/POR or system reset during erase/program interrupt flag */ + /* interrupt flags in ECCCS register */ + FMC_INT_FLAG_OB1ECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 26U), /*!< option bytes 1 two bits error detect interrupt flag */ + FMC_INT_FLAG_OB0ECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 27U), /*!< option bytes 0 two bits error detect interrupt flag */ + FMC_INT_FLAG_EPECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 29U), /*!< EEPROM two bits error detect interrupt flag */ + FMC_INT_FLAG_ECCCOR = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 24U, FMC_ECCCS_REG_OFFSET, 30U), /*!< one bit error detected and correct interrupt flag */ + FMC_INT_FLAG_ECCDET = FMC_REGIDX_BIT2(FMC_ECCCS_REG_OFFSET, 25U, FMC_ECCCS_REG_OFFSET, 31U) /*!< two bits error detect interrupt flag */ +} fmc_interrupt_flag_enum; + +/* FMC interrupt */ +typedef enum { + /* interrupt in CTL0 register */ + FMC_BANK0_INT_ERR = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 10U), /*!< FMC bank0 error interrupt */ + FMC_BANK0_INT_END = FMC_REGIDX_BIT(FMC_CTL0_REG_OFFSET, 12U), /*!< FMC bank0 end of operation interrupt */ + /* interrupt in CTL1 register */ + FMC_BANK1_INT_ERR = FMC_REGIDX_BIT(FMC_CTL1_REG_OFFSET, 10U), /*!< FMC bank1 error interrupt */ + FMC_BANK1_INT_END = FMC_REGIDX_BIT(FMC_CTL1_REG_OFFSET, 12U), /*!< FMC bank1 end of operation interrupt */ + /* interrupt in ECCCS register */ + FMC_INT_ECCCOR = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 24U), /*!< FMC one bit error correct interrupt */ + FMC_INT_ECCDET = FMC_REGIDX_BIT(FMC_ECCCS_REG_OFFSET, 25U) /*!< FMC two bits error interrupt */ +} fmc_interrupt_enum; + +/* unlock key */ +#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ +#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ + +/* wait state counter value */ +#define WS_WSCNT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define WS_WSCNT_0 WS_WSCNT(0) /*!< 0 wait state added */ +#define WS_WSCNT_1 WS_WSCNT(1) /*!< 1 wait state added */ +#define WS_WSCNT_2 WS_WSCNT(2) /*!< 2 wait state added */ +#define WS_WSCNT_3 WS_WSCNT(3) /*!< 3 wait state added */ + +/* shared SRAM command */ +#define CTL1_SRAMCMD(regval) (BITS(24,25) & ((uint32_t)(regval) << 24)) +#define FASTPG_SRAM_CMD CTL1_SRAMCMD(1) /*!< set fast PG RAM mode */ +#define BASIC_SRAM_CMD CTL1_SRAMCMD(2) /*!< set basic RAM mode */ +#define EEPROM_SRAM_CMD CTL1_SRAMCMD(3) /*!< set EEPROM RAM mode */ + +/* option bytes security protection level in FMC_OBSTAT register */ +#define OB_OBSTAT_PLEVEL_NO ((uint8_t)0x00U) /*!< no security protection */ +#define OB_OBSTAT_PLEVEL_LOW ((uint8_t)0x01U) /*!< low security protection */ +#define OB_OBSTAT_PLEVEL_HIGH ((uint8_t)0x03U) /*!< high security protection */ + +/* option bytes read protection configuration */ +#define FMC_NSPC ((uint16_t)0x5AA5U) /*!< no security protection */ +#define FMC_LSPC ((uint16_t)0x44BBU) /*!< low security protection, any value except 0xA5 or 0xCC */ +#define FMC_HSPC ((uint16_t)0x33CCU) /*!< high security protection */ + +/* option bytes software/hardware free watchdog timer */ +#define OB_FWDGT_HW ((uint16_t)0x0100U) /*!< hardware free watchdog timer */ +#define OB_FWDGT_SW ((uint16_t)0x0001U) /*!< software free watchdog timer */ + +/* option bytes reset or not entering deep sleep mode */ +#define OB_DEEPSLEEP_RST ((uint16_t)0x0200U) /*!< generate a reset instead of entering deepsleep mode */ +#define OB_DEEPSLEEP_NRST ((uint16_t)0x0002U) /*!< no reset when entering deepsleep mode */ + +/* option bytes reset or not entering standby mode */ +#define OB_STDBY_RST ((uint16_t)0x0400U) /*!< generate a reset instead of entering standby mode */ +#define OB_STDBY_NRST ((uint16_t)0x0004U) /*!< no reset when entering deepsleep mode */ + +/* option bytes boot from bank0 or bank1 when configured boot from main flash */ +#define OB_BOOT_FROM_BANK1 ((uint16_t)0x0800U) /*!< boot from bank1 or bank0 if bank1 is void, when configured boot from main memory */ +#define OB_BOOT_FROM_BANK0 ((uint16_t)0x0008U) /*!< boot from bank0, when configured boot from main memory */ + +/* option bytes OTA configuration */ +#define OB_BOOT_OTA_ENABLE ((uint16_t)0x1000U) /*!< when configured boot from main memory, if the BB is 0, all data will be copied from bank1 to bank0 and then boot from bank0 */ +#define OB_BOOT_OTA_DISABLE ((uint16_t)0x0010U) /*!< no effect */ + +/* option bytes brownout configuration */ +#define OB_BOR_DISABLE ((uint16_t)0x0080U) /*!< disable brown out */ +#define OB_BOR_ENABLE ((uint16_t)0x8000U) /*!< enable brown out, brownout threshold 2.6V */ + +/* option bytes 1 lock value in FMC_OB1CS register */ +#define OB1CS_OB1_LKVAL(regval) (BITS(16,31) & ((uint32_t)(regval) << 16)) +#define OB1CS_OB1_LK OB1CS_OB1_LKVAL((uint16_t)0x33CCU) /*!< option byte1 cannot be modified */ +#define OB1CS_OB1_NOT_LK OB1CS_OB1_LKVAL((uint16_t)0x00FFU) /*!< option byte1 is not locked */ + +/* option bytes 1 shared RAM init mode in FMC_OB1CS register */ +#define OB1CS_EPLOAD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define OB1CS_EPLOAD_NOT_LOAD_EPDATA OB1CS_EPLOAD((uint16_t)0x00U) /*!< shared SRAM is not loaded with valid EEPROM data during FMC reset */ +#define OB1CS_EPLOAD_LOAD_EPDATA OB1CS_EPLOAD((uint16_t)0x01U) /*!< shared SRAM is loaded with valid EEPROM data during FMC reset */ + +/* option bytes 1 EEPROM size in FMC_OB1CS register */ +#define OB1CS_EPSIZE(regval) (BITS(8, 11) & ((uint32_t)(regval) << 8)) +#define OB1CS_EPSIZE_NONE OB1CS_EPSIZE((uint8_t)0x0FU) /*!< no EEPROM */ +#define OB1CS_EPSIZE_4K OB1CS_EPSIZE((uint8_t)0x08U) /*!< 4KB EEPROM, 384K flash or 256K flash */ +#define OB1CS_EPSIZE_2K OB1CS_EPSIZE((uint8_t)0x04U) /*!< 2KB EEPROM, 128K flash */ +#define OB1CS_EPSIZE_1K OB1CS_EPSIZE((uint8_t)0x02U) /*!< 1KB EEPROM, 64K flash */ + +/* option bytes 1 extend flash block allocation in FMC_OB1CS register */ +/* 384K flash or 256K flash */ +#define OB1CS_EFALC(regval) (BITS(4, 7) & ((uint32_t)(regval) << 4)) +#define OB1CS_DF_64K_EF_0K OB1CS_EFALC((uint8_t)0x00U) /*!< data flash size is 64KB, EEPROM backup size is 0KB */ +#define OB1CS_DF_48K_EF_16K OB1CS_EFALC((uint8_t)0x03U) /*!< data flash size is 48KB, EEPROM backup size is 16KB */ +#define OB1CS_DF_32K_EF_32K OB1CS_EFALC((uint8_t)0x04U) /*!< data flash size is 32KB, EEPROM backup size is 32KB */ +#define OB1CS_DF_16K_EF_48K OB1CS_EFALC((uint8_t)0x05U) /*!< data flash size is 16KB, EEPROM backup size is 48KB */ +#define OB1CS_DF_0K_EF_64K OB1CS_EFALC((uint8_t)0x08U) /*!< data flash size is 0KB, EEPROM backup size is 64KB */ +#define OB1CS_DF_EF_INVALID OB1CS_EFALC((uint8_t)0x0FU) /*!< data flash and EEPROM backup are invalid */ +/* 128K flash */ +#define OB1CS_DF_32K_EF_0K OB1CS_EFALC((uint8_t)0x01U) /*!< data flash size is 64KB, EEPROM backup size is 0KB */ +#define OB1CS_DF_8K_EF_24K OB1CS_EFALC((uint8_t)0x06U) /*!< data flash size is 48KB, EEPROM backup size is 16KB */ +#define OB1CS_DF_0K_EF_32K OB1CS_EFALC((uint8_t)0x09U) /*!< data flash size is 32KB, EEPROM backup size is 32KB */ +#define OB1CS_DF_16K_EF_16K OB1CS_EFALC((uint8_t)0x0BU) /*!< data flash size is 16KB, EEPROM backup size is 48KB */ +#define OB1CS_DF_24K_EF_8K OB1CS_EFALC((uint8_t)0x0CU) /*!< data flash size is 0KB, EEPROM backup size is 64KB */ +/* 64K flash */ +#define OB1CS_DF_16K_EF_0K OB1CS_EFALC((uint8_t)0x02U) /*!< data flash size is 64KB, EEPROM backup size is 0KB */ +#define OB1CS_DF_4K_EF_12K OB1CS_EFALC((uint8_t)0x07U) /*!< data flash size is 48KB, EEPROM backup size is 16KB */ +#define OB1CS_DF_0K_EF_16K OB1CS_EFALC((uint8_t)0x0AU) /*!< data flash size is 32KB, EEPROM backup size is 32KB */ +#define OB1CS_DF_8K_EF_8K OB1CS_EFALC((uint8_t)0x0DU) /*!< data flash size is 16KB, EEPROM backup size is 48KB */ +#define OB1CS_DF_12K_EF_4K OB1CS_EFALC((uint8_t)0x0EU) /*!< data flash size is 0KB, EEPROM backup size is 64KB */ + +#define BANK0_BASE_ADDRESS ((uint32_t)0x08000000U) /*!< FMC bank0 base address */ +#define BANK0_SIZE ((uint32_t)0x00040000U) /*!< FMC bank0 size */ +#define BANK1_BASE_ADDRESS ((uint32_t)(BANK0_BASE_ADDRESS + BANK0_SIZE)) /*!< FMC bank1 base address */ +#define OB_WORD_CNT ((uint8_t)0x06U) /*!< word count of option bytes */ +#define OB_DOUBLEWORD_CNT ((uint8_t)0x03U) /*!< double-word count of option bytes */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x00FF0000U) /*!< count to judge of FMC timeout */ +#define DOUBLEWORD_CNT_IN_ROW ((uint8_t)0x20U) /*!< double-word count in one row data */ +#define CBCMDLEN_OF_ONE_ROW ((uint8_t)0x05U) /*!< CBCMD read length of one row data */ + +/* function declarations */ +/* FMC programming functions */ +/* unlock the main flash operation */ +void fmc_unlock(void); +/* unlock the main flash bank0 operation */ +void fmc_bank0_unlock(void); +/* unlock the main flash bank1 operation */ +void fmc_bank1_unlock(void); +/* lock the main flash operation */ +void fmc_lock(void); +/* lock the main flash bank0 operation */ +void fmc_bank0_lock(void); +/* lock the main flash bank1 operation */ +void fmc_bank1_lock(void); + +/* set the wait state counter value */ +void fmc_wscnt_set(uint8_t wscnt); +/* enable pre-fetch */ +void fmc_prefetch_enable(void); +/* disable pre-fetch */ +void fmc_prefetch_disable(void); +/* enable cache */ +void fmc_cache_enable(void); +/* disable cache */ +void fmc_cache_disable(void); +/* enable cache reset if cache is disabled */ +void fmc_cache_reset_enable(void); +/* disable cache reset */ +void fmc_cache_reset_disable(void); +/* flash goto power-down mode when MCU enters deepsleep mode */ +void fmc_powerdown_mode_set(void); +/* flash goto sleep mode when MCU enters deepsleep mode */ +void fmc_sleep_mode_set(void); +/* configure shared SRAM mode */ +void fmc_sram_mode_config(fmc_sram_mode_enum sram_mode); +/* get shared SRAM mode */ +fmc_sram_mode_enum fmc_sram_mode_get(void); + +/* check whether flash page is blank or not by check blank command */ +fmc_state_enum fmc_blank_check(uint32_t address, uint8_t length); +/* erase main flash page */ +fmc_state_enum fmc_page_erase(uint32_t page_address); +/* erase flash bank0 */ +fmc_state_enum fmc_bank0_mass_erase(void); +/* erase flash bank1 */ +fmc_state_enum fmc_bank1_mass_erase(void); +/* erase the data flash */ +fmc_state_enum fmc_dflash_mass_erase(void); +/* erase whole chip */ +fmc_state_enum fmc_mass_erase(void); + +/* program a double word at the corresponding address in main flash */ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data); +/* FMC fast program one row data (32 double-word) starting at the corresponding address */ +fmc_state_enum fmc_fast_program(uint32_t address, uint64_t data[]); +/* program a double word at the corresponding address in OTP */ +fmc_state_enum otp_doubleword_program(uint32_t address, uint64_t data); +/* program a word at the corresponding address in EEPROM */ +fmc_state_enum eeprom_word_program(uint32_t address, uint32_t data); +/* read a word at the corresponding address in EEPROM */ +uint32_t eeprom_word_read(uint32_t address); + +/* FMC option bytes 0 functions */ +/* unlock the option bytes 0 operation */ +void ob_unlock(void); +/* lock the option bytes 0 operation */ +void ob_lock(void); +/* force to reload the option bytes 0 */ +void ob_reset(void); +/* erase the option bytes 0 */ +fmc_state_enum ob_erase(void); +/* enable option bytes 0 write protection */ +fmc_state_enum ob_write_protection_enable(fmc_area_enum wp_area, uint32_t ob_wp); +/* configure security protection */ +fmc_state_enum ob_security_protection_config(uint16_t ob_spc); +/* program the FMC user option bytes 0 */ +fmc_state_enum ob_user_write(uint16_t ob_user); +/* program the FMC data option bytes 0 */ +fmc_state_enum ob_data_program(uint16_t ob_data); +/* get the value of FMC option bytes OB_USER in FMC_OBSTAT register */ +uint8_t ob_user_get(void); +/* get the value of FMC option bytes OB_DATA in FMC_OBSTAT register */ +uint16_t ob_data_get(void); +/* get the value of FMC option bytes BK0WP in FMC_WP0 register */ +uint32_t ob_write_protection_get(void); +/* get the value of FMC option bytes BK1WP in FMC_WP1 register */ +uint8_t ob_bk1_write_protection_get(void); +/* get the value of FMC option bytes DFWP in FMC_WP1 register */ +uint8_t ob_df_write_protection_get(void); +/* get the value of FMC option bytes EPWP in FMC_WP1 register */ +uint8_t ob_ep_write_protection_get(void); +/* get the value of FMC option bytes 0 security protection level (PLEVEL) in FMC_OBSTAT register */ +uint8_t ob_plevel_get(void); + +/* FMC option bytes 1 functions */ +/* configure lock value in option bytes 1 */ +fmc_state_enum ob1_lock_config(uint32_t lk_value); +/* configure the EPLOAD value of option bytes 1 loaded after the system reset */ +fmc_state_enum ob1_epload_config(uint32_t epload); +/* configure option bytes 1 EEPROM parameters */ +fmc_state_enum ob1_eeprom_parameter_config(uint32_t efalc, uint32_t epsize); +/* get data flash size in byte unit */ +uint32_t dflash_size_get(void); +/* get EEPROM backup size in byte unit */ +uint32_t eeprom_backup_size_get(void); +/* get EEPROM size in byte unit */ +uint32_t eeprom_size_get(void); + +/* interrupt & flag functions */ +/* get FMC flag status */ +FlagStatus fmc_flag_get(fmc_flag_enum flag); +/* clear FMC flag status */ +void fmc_flag_clear(fmc_flag_enum flag); +/* enable FMC interrupt */ +void fmc_interrupt_enable(fmc_interrupt_enum interrupt); +/* disable FMC interrupt */ +void fmc_interrupt_disable(fmc_interrupt_enum interrupt); +/* get FMC interrupt flag status */ +FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum int_flag); +/* clear FMC interrupt flag status */ +void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum int_flag); + +#endif /* GD32A50X_FMC_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_fwdgt.h b/gd32a50x/standard_peripheral/include/gd32a50x_fwdgt.h new file mode 100644 index 0000000..33e62e4 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_fwdgt.h @@ -0,0 +1,123 @@ +/*! + \file gd32fxxx_fwdgt.h + \brief definitions for the FWDGT + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + + +#ifndef GD32A50X_FWDGT_H +#define GD32A50X_FWDGT_H + +#include "gd32a50x.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE /*!< FWDGT base address */ + +/* 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_RLD_RLD bit field */ +/* write value to FWDGT_WND_WND bit field */ +#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_WND_WND bit field */ + +/* 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 /* GD32A50X_FWDGT_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_gpio.h b/gd32a50x/standard_peripheral/include/gd32a50x_gpio.h new file mode 100644 index 0000000..079559d --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_gpio.h @@ -0,0 +1,390 @@ +/*! + \file gd32a50x_gpio.h + \brief definitions for the GPIO + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_GPIO_H +#define GD32A50X_GPIO_H + +#include "gd32a50x.h" + +/* GPIOx(x=A,B,C,D,E,F) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) /*!< GPIOA bsae address */ +#define GPIOB (GPIO_BASE + 0x00000400U) /*!< GPIOB bsae address */ +#define GPIOC (GPIO_BASE + 0x00000800U) /*!< GPIOC bsae address */ +#define GPIOD (GPIO_BASE + 0x00000C00U) /*!< GPIOD bsae address */ +#define GPIOE (GPIO_BASE + 0x00001000U) /*!< GPIOE bsae address */ +#define GPIOF (GPIO_BASE + 0x00001400U) /*!< GPIOF bsae 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 BITS(0, 1) /*!< pin 0 output max speed bits */ +#define GPIO_OSPD_OSPD1 BITS(2, 3) /*!< pin 1 output max speed bits */ +#define GPIO_OSPD_OSPD2 BITS(4, 5) /*!< pin 2 output max speed bits */ +#define GPIO_OSPD_OSPD3 BITS(6, 7) /*!< pin 3 output max speed bits */ +#define GPIO_OSPD_OSPD4 BITS(8, 9) /*!< pin 4 output max speed bits */ +#define GPIO_OSPD_OSPD5 BITS(10, 11) /*!< pin 5 output max speed bits */ +#define GPIO_OSPD_OSPD6 BITS(12, 13) /*!< pin 6 output max speed bits */ +#define GPIO_OSPD_OSPD7 BITS(14, 15) /*!< pin 7 output max speed bits */ +#define GPIO_OSPD_OSPD8 BITS(16, 17) /*!< pin 8 output max speed bits */ +#define GPIO_OSPD_OSPD9 BITS(18, 19) /*!< pin 9 output max speed bits */ +#define GPIO_OSPD_OSPD10 BITS(20, 21) /*!< pin 10 output max speed bits */ +#define GPIO_OSPD_OSPD11 BITS(22, 23) /*!< pin 11 output max speed bits */ +#define GPIO_OSPD_OSPD12 BITS(24, 25) /*!< pin 12 output max speed bits */ +#define GPIO_OSPD_OSPD13 BITS(26, 27) /*!< pin 13 output max speed bits */ +#define GPIO_OSPD_OSPD14 BITS(28, 29) /*!< pin 14 output max speed bits */ +#define GPIO_OSPD_OSPD15 BITS(30, 31) /*!< pin 15 output max speed bits */ + +/* GPIO_PUD */ +#define GPIO_PUD_PUD0 BITS(0, 1) /*!< pin 0 pull-up or pull-down bits */ +#define GPIO_PUD_PUD1 BITS(2, 3) /*!< pin 1 pull-up or pull-down bits */ +#define GPIO_PUD_PUD2 BITS(4, 5) /*!< pin 2 pull-up or pull-down bits */ +#define GPIO_PUD_PUD3 BITS(6, 7) /*!< pin 3 pull-up or pull-down bits */ +#define GPIO_PUD_PUD4 BITS(8, 9) /*!< pin 4 pull-up or pull-down bits */ +#define GPIO_PUD_PUD5 BITS(10, 11) /*!< pin 5 pull-up or pull-down bits */ +#define GPIO_PUD_PUD6 BITS(12, 13) /*!< pin 6 pull-up or pull-down bits */ +#define GPIO_PUD_PUD7 BITS(14, 15) /*!< pin 7 pull-up or pull-down bits */ +#define GPIO_PUD_PUD8 BITS(16, 17) /*!< pin 8 pull-up or pull-down bits */ +#define GPIO_PUD_PUD9 BITS(18, 19) /*!< pin 9 pull-up or pull-down bits */ +#define GPIO_PUD_PUD10 BITS(20, 21) /*!< pin 10 pull-up or pull-down bits */ +#define GPIO_PUD_PUD11 BITS(22, 23) /*!< pin 11 pull-up or pull-down bits */ +#define GPIO_PUD_PUD12 BITS(24, 25) /*!< pin 12 pull-up or pull-down bits */ +#define GPIO_PUD_PUD13 BITS(26, 27) /*!< pin 13 pull-up or pull-down bits */ +#define GPIO_PUD_PUD14 BITS(28, 29) /*!< pin 14 pull-up or pull-down bits */ +#define GPIO_PUD_PUD15 BITS(30, 31) /*!< pin 15 pull-up or pull-down bits */ + +/* GPIO_ISTAT */ +#define GPIO_ISTAT_ISTAT0 BIT(0) /*!< pin 0 input status */ +#define GPIO_ISTAT_ISTAT1 BIT(1) /*!< pin 1 input status */ +#define GPIO_ISTAT_ISTAT2 BIT(2) /*!< pin 2 input status */ +#define GPIO_ISTAT_ISTAT3 BIT(3) /*!< pin 3 input status */ +#define GPIO_ISTAT_ISTAT4 BIT(4) /*!< pin 4 input status */ +#define GPIO_ISTAT_ISTAT5 BIT(5) /*!< pin 5 input status */ +#define GPIO_ISTAT_ISTAT6 BIT(6) /*!< pin 6 input status */ +#define GPIO_ISTAT_ISTAT7 BIT(7) /*!< pin 7 input status */ +#define GPIO_ISTAT_ISTAT8 BIT(8) /*!< pin 8 input status */ +#define GPIO_ISTAT_ISTAT9 BIT(9) /*!< pin 9 input status */ +#define GPIO_ISTAT_ISTAT10 BIT(10) /*!< pin 10 input status */ +#define GPIO_ISTAT_ISTAT11 BIT(11) /*!< pin 11 input status */ +#define GPIO_ISTAT_ISTAT12 BIT(12) /*!< pin 12 input status */ +#define GPIO_ISTAT_ISTAT13 BIT(13) /*!< pin 13 input status */ +#define GPIO_ISTAT_ISTAT14 BIT(14) /*!< pin 14 input status */ +#define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ + +/* GPIO_OCTL */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0, 3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4, 7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8, 11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12, 15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16, 19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20, 23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24, 27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28, 31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0, 3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4, 7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8, 11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12, 15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16, 19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20, 23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24, 27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28, 31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +/* GPIO_TG */ +#define GPIO_TG_TG0 BIT(0) /*!< pin 0 toggle bit */ +#define GPIO_TG_TG1 BIT(1) /*!< pin 1 toggle bit */ +#define GPIO_TG_TG2 BIT(2) /*!< pin 2 toggle bit */ +#define GPIO_TG_TG3 BIT(3) /*!< pin 3 toggle bit */ +#define GPIO_TG_TG4 BIT(4) /*!< pin 4 toggle bit */ +#define GPIO_TG_TG5 BIT(5) /*!< pin 5 toggle bit */ +#define GPIO_TG_TG6 BIT(6) /*!< pin 6 toggle bit */ +#define GPIO_TG_TG7 BIT(7) /*!< pin 7 toggle bit */ +#define GPIO_TG_TG8 BIT(8) /*!< pin 8 toggle bit */ +#define GPIO_TG_TG9 BIT(9) /*!< pin 9 toggle bit */ +#define GPIO_TG_TG10 BIT(10) /*!< pin 10 toggle bit */ +#define GPIO_TG_TG11 BIT(11) /*!< pin 11 toggle bit */ +#define GPIO_TG_TG12 BIT(12) /*!< pin 12 toggle bit */ +#define GPIO_TG_TG13 BIT(13) /*!< pin 13 toggle bit */ +#define GPIO_TG_TG14 BIT(14) /*!< pin 14 toggle bit */ +#define GPIO_TG_TG15 BIT(15) /*!< pin 15 toggle bit */ + +/* constants definitions */ +typedef FlagStatus bit_status; + +/* output mode definitions */ +#define CTL_CLTR(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_MODE_INPUT CTL_CLTR(0) /*!< input mode */ +#define GPIO_MODE_OUTPUT CTL_CLTR(1) /*!< output mode */ +#define GPIO_MODE_AF CTL_CLTR(2) /*!< alternate function mode */ +#define GPIO_MODE_ANALOG CTL_CLTR(3) /*!< analog mode */ + +/* pull-up/pull-down definitions */ +#define PUD_PUPD(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0)) +#define GPIO_PUPD_NONE PUD_PUPD(0) /*!< floating mode, no pull-up and pull-down resistors */ +#define GPIO_PUPD_PULLUP PUD_PUPD(1) /*!< with pull-up resistor */ +#define GPIO_PUPD_PULLDOWN PUD_PUPD(2) /*!< with pull-down resistor */ + +/* GPIO pin definitions */ +#define GPIO_PIN_0 BIT(0) /*!< GPIO pin 0 */ +#define GPIO_PIN_1 BIT(1) /*!< GPIO pin 1 */ +#define GPIO_PIN_2 BIT(2) /*!< GPIO pin 2 */ +#define GPIO_PIN_3 BIT(3) /*!< GPIO pin 3 */ +#define GPIO_PIN_4 BIT(4) /*!< GPIO pin 4 */ +#define GPIO_PIN_5 BIT(5) /*!< GPIO pin 5 */ +#define GPIO_PIN_6 BIT(6) /*!< GPIO pin 6 */ +#define GPIO_PIN_7 BIT(7) /*!< GPIO pin 7 */ +#define GPIO_PIN_8 BIT(8) /*!< GPIO pin 8 */ +#define GPIO_PIN_9 BIT(9) /*!< GPIO pin 9 */ +#define GPIO_PIN_10 BIT(10) /*!< GPIO pin 10 */ +#define GPIO_PIN_11 BIT(11) /*!< GPIO pin 11 */ +#define GPIO_PIN_12 BIT(12) /*!< GPIO pin 12 */ +#define GPIO_PIN_13 BIT(13) /*!< GPIO pin 13 */ +#define GPIO_PIN_14 BIT(14) /*!< GPIO pin 14 */ +#define GPIO_PIN_15 BIT(15) /*!< GPIO pin 15 */ +#define GPIO_PIN_ALL BITS(0, 15) /*!< GPIO pin all */ + +/* GPIO mode configuration values */ +#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (2U * (n)))) +#define GPIO_MODE_MASK(n) ((uint32_t)((uint32_t)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) ((uint32_t)((uint32_t)(0x3U) << (2U * (n)))) + +/* GPIO output speed values */ +#define GPIO_OSPEED_SET(n, speed) ((uint32_t)((uint32_t)(speed) << (2U * (n)))) +#define GPIO_OSPEED_MASK(n) ((uint32_t)((uint32_t)(0x3U) << (2U * (n)))) + +/* GPIO output type */ +#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */ + +/* GPIO output max speed value */ +#define OSPD_OSPD0(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_2MHZ OSPD_OSPD0(0) /*!< output max speed 2MHz */ +#define GPIO_OSPEED_10MHZ OSPD_OSPD0(1) /*!< output max speed 10MHz */ +#define GPIO_OSPEED_50MHZ OSPD_OSPD0(3) /*!< output max speed 50MHz */ + +/* GPIO alternate function values */ +#define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n)))) +#define GPIO_AFR_MASK(n) ((uint32_t)((uint32_t)(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 */ + +/* 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 /* GD32A50X_GPIO_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_i2c.h b/gd32a50x/standard_peripheral/include/gd32a50x_i2c.h new file mode 100644 index 0000000..8189728 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_i2c.h @@ -0,0 +1,401 @@ +/*! + \file gd32a50x_i2c.h + \brief definitions for the I2C + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_I2C_H +#define GD32A50X_I2C_H + +#include "gd32a50x.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_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_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22))) +#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define I2C_CTL0_REG_OFFSET ((uint32_t)0x00000000U) /*!< CTL0 register offset */ +#define I2C_STAT_REG_OFFSET ((uint32_t)0x00000018U) /*!< STAT register offset */ + +/* I2C interrupt flags */ +typedef enum { + I2C_INT_FLAG_TI = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 1U, I2C_STAT_REG_OFFSET, 1U), /*!< transmit interrupt flag */ + I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 2U, I2C_STAT_REG_OFFSET, 2U), /*!< I2C_RDATA is not empty during receiving interrupt flag */ + I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 3U, I2C_STAT_REG_OFFSET, 3U), /*!< address received matches in slave mode interrupt flag */ + I2C_INT_FLAG_NACK = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 4U, I2C_STAT_REG_OFFSET, 4U), /*!< not acknowledge interrupt flag */ + I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 5U, I2C_STAT_REG_OFFSET, 5U), /*!< stop condition detected in slave mode interrupt flag */ + I2C_INT_FLAG_TC = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 6U, I2C_STAT_REG_OFFSET, 6U), /*!< transfer complete in master mode interrupt flag */ + I2C_INT_FLAG_TCR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 6U, I2C_STAT_REG_OFFSET, 7U), /*!< transfer complete reload interrupt flag */ + I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 8U), /*!< bus error interrupt flag */ + I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 9U), /*!< arbitration lost interrupt flag */ + I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 10U), /*!< overrun/underrun error in slave mode interrupt flag */ + I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 11U), /*!< PEC error interrupt flag */ + I2C_INT_FLAG_TIMEOUT = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 12U), /*!< timeout interrupt flag */ + I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL0_REG_OFFSET, 7U, I2C_STAT_REG_OFFSET, 13U) /*!< SMBus Alert interrupt flag */ +} i2c_interrupt_flag_enum; + +/* I2C DMA constants definitions */ +#define I2C_DMA_TRANSMIT ((uint32_t)0x00000000U) /*!< I2C transmit data use DMA */ +#define I2C_DMA_RECEIVE ((uint32_t)0x00000001U) /*!< I2C receive data use DMA */ + +/* I2C interrupt enable or disable */ +#define I2C_INT_ERR I2C_CTL0_ERRIE /*!< error interrupt enable */ +#define I2C_INT_TC I2C_CTL0_TCIE /*!< transfer complete interrupt enable */ +#define I2C_INT_STPDET I2C_CTL0_STPDETIE /*!< stop detection interrupt enable */ +#define I2C_INT_NACK I2C_CTL0_NACKIE /*!< not acknowledge received interrupt enable */ +#define I2C_INT_ADDM I2C_CTL0_ADDMIE /*!< address match interrupt enable */ +#define I2C_INT_RBNE I2C_CTL0_RBNEIE /*!< receive interrupt enable */ +#define I2C_INT_TI I2C_CTL0_TIE /*!< transmit interrupt enable */ + +/* I2C transfer direction in master mode */ +#define I2C_MASTER_TRANSMIT ((uint32_t)0x00000000U) /*!< I2C master transmit */ +#define I2C_MASTER_RECEIVE I2C_CTL1_TRDIR /*!< I2C master receive */ + +/* address mode for the I2C slave */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address:7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address:10 bits */ + +/* the length of filter spikes */ +#define FILTER_DISABLE ((uint32_t)0x00000000U) /*!< digital filter is disabled */ +#define FILTER_LENGTH_1 ((uint32_t)0x00000001U) /*!< digital filter is enabled and filter spikes with a length of up to 1 tI2CCLK */ +#define FILTER_LENGTH_2 ((uint32_t)0x00000002U) /*!< digital filter is enabled and filter spikes with a length of up to 2 tI2CCLK */ +#define FILTER_LENGTH_3 ((uint32_t)0x00000003U) /*!< digital filter is enabled and filter spikes with a length of up to 3 tI2CCLK */ +#define FILTER_LENGTH_4 ((uint32_t)0x00000004U) /*!< digital filter is enabled and filter spikes with a length of up to 4 tI2CCLK */ +#define FILTER_LENGTH_5 ((uint32_t)0x00000005U) /*!< digital filter is enabled and filter spikes with a length of up to 5 tI2CCLK */ +#define FILTER_LENGTH_6 ((uint32_t)0x00000006U) /*!< digital filter is enabled and filter spikes with a length of up to 6 tI2CCLK */ +#define FILTER_LENGTH_7 ((uint32_t)0x00000007U) /*!< digital filter is enabled and filter spikes with a length of up to 7 tI2CCLK */ +#define FILTER_LENGTH_8 ((uint32_t)0x00000008U) /*!< digital filter is enabled and filter spikes with a length of up to 8 tI2CCLK */ +#define FILTER_LENGTH_9 ((uint32_t)0x00000009U) /*!< digital filter is enabled and filter spikes with a length of up to 9 tI2CCLK */ +#define FILTER_LENGTH_10 ((uint32_t)0x0000000AU) /*!< digital filter is enabled and filter spikes with a length of up to 10 tI2CCLK */ +#define FILTER_LENGTH_11 ((uint32_t)0x0000000BU) /*!< digital filter is enabled and filter spikes with a length of up to 11 tI2CCLK */ +#define FILTER_LENGTH_12 ((uint32_t)0x0000000CU) /*!< digital filter is enabled and filter spikes with a length of up to 12 tI2CCLK */ +#define FILTER_LENGTH_13 ((uint32_t)0x0000000DU) /*!< digital filter is enabled and filter spikes with a length of up to 13 tI2CCLK */ +#define FILTER_LENGTH_14 ((uint32_t)0x0000000EU) /*!< digital filter is enabled and filter spikes with a length of up to 14 tI2CCLK */ +#define FILTER_LENGTH_15 ((uint32_t)0x0000000FU) /*!< digital filter is enabled and filter spikes with a length of up to 15 tI2CCLK */ + +/* defines which bits of register ADDRESS[7:1] are compared with an incoming address byte */ +#define ADDRESS_BIT1_COMPARE ((uint32_t)0x00000200U) /*!< address bit1 needs compare */ +#define ADDRESS_BIT2_COMPARE ((uint32_t)0x00000400U) /*!< address bit2 needs compare */ +#define ADDRESS_BIT3_COMPARE ((uint32_t)0x00000800U) /*!< address bit3 needs compare */ +#define ADDRESS_BIT4_COMPARE ((uint32_t)0x00001000U) /*!< address bit4 needs compare */ +#define ADDRESS_BIT5_COMPARE ((uint32_t)0x00002000U) /*!< address bit5 needs compare */ +#define ADDRESS_BIT6_COMPARE ((uint32_t)0x00004000U) /*!< address bit6 needs compare */ +#define ADDRESS_BIT7_COMPARE ((uint32_t)0x00008000U) /*!< address bit7 needs compare */ + +/* defines which bits of ADDRESS2[7:1] are compared with an incoming address byte, and which bits are masked (don't care) */ +#define ADDRESS2_NO_MASK ((uint32_t)0x00000000U) /*!< no mask, all the bits must be compared */ +#define ADDRESS2_MASK_BIT1 ((uint32_t)0x00000001U) /*!< ADDRESS2[1] is masked, only ADDRESS2[7:2] are compared */ +#define ADDRESS2_MASK_BIT1_2 ((uint32_t)0x00000002U) /*!< ADDRESS2[2:1] is masked, only ADDRESS2[7:3] are compared */ +#define ADDRESS2_MASK_BIT1_3 ((uint32_t)0x00000003U) /*!< ADDRESS2[3:1] is masked, only ADDRESS2[7:4] are compared */ +#define ADDRESS2_MASK_BIT1_4 ((uint32_t)0x00000004U) /*!< ADDRESS2[4:1] is masked, only ADDRESS2[7:5] are compared */ +#define ADDRESS2_MASK_BIT1_5 ((uint32_t)0x00000005U) /*!< ADDRESS2[5:1] is masked, only ADDRESS2[7:6] are compared */ +#define ADDRESS2_MASK_BIT1_6 ((uint32_t)0x00000006U) /*!< ADDRESS2[6:1] is masked, only ADDRESS2[7] are compared */ +#define ADDRESS2_MASK_ALL ((uint32_t)0x00000007U) /*!< all the ADDRESS2[7:1] bits are masked */ + +/* idle clock timeout detection */ +#define BUSTOA_DETECT_SCL_LOW ((uint32_t)0x00000000U) /*!< BUSTOA is used to detect SCL low timeout */ +#define BUSTOA_DETECT_IDLE I2C_TIMEOUT_TOIDLE /*!< BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle */ + +/* I2C flag definitions */ +#define I2C_FLAG_TBE I2C_STAT_TBE /*!< I2C_TDATA is empty during transmitting */ +#define I2C_FLAG_TI I2C_STAT_TI /*!< transmit interrupt */ +#define I2C_FLAG_RBNE I2C_STAT_RBNE /*!< I2C_RDATA is not empty during receiving */ +#define I2C_FLAG_ADDSEND I2C_STAT_ADDSEND /*!< address received matches in slave mode */ +#define I2C_FLAG_NACK I2C_STAT_NACK /*!< not acknowledge flag */ +#define I2C_FLAG_STPDET I2C_STAT_STPDET /*!< STOP condition detected in slave mode */ +#define I2C_FLAG_TC I2C_STAT_TC /*!< transfer complete in master mode */ +#define I2C_FLAG_TCR I2C_STAT_TCR /*!< transfer complete reload */ +#define I2C_FLAG_BERR I2C_STAT_BERR /*!< bus error */ +#define I2C_FLAG_LOSTARB I2C_STAT_LOSTARB /*!< arbitration lost */ +#define I2C_FLAG_OUERR I2C_STAT_OUERR /*!< overrun/underrun error in slave mode */ +#define I2C_FLAG_PECERR I2C_STAT_PECERR /*!< PEC error */ +#define I2C_FLAG_TIMEOUT I2C_STAT_TIMEOUT /*!< timeout flag */ +#define I2C_FLAG_SMBALT I2C_STAT_SMBALT /*!< SMBus Alert */ +#define I2C_FLAG_I2CBSY I2C_STAT_I2CBSY /*!< busy flag */ +#define I2C_FLAG_TR I2C_STAT_TR /*!< whether the I2C is a transmitter or a receiver in slave mode */ + +/* function declarations */ +/* initialization functions */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure the timing parameters */ +void i2c_timing_config(uint32_t i2c_periph, uint32_t psc, uint32_t scl_dely, uint32_t sda_dely); +/* configure digital noise filter */ +void i2c_digital_noise_filter_config(uint32_t i2c_periph, uint32_t filter_length); +/* enable analog noise filter */ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph); +/* disable analog noise filter */ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph); +/* configure the SCL high and low period of clock in master mode */ +void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll); +/* configure i2c slave address and transfer direction in master mode */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction); + +/* application function declarations */ +/* 10-bit address header executes read direction only in master receive mode */ +void i2c_address10_header_enable(uint32_t i2c_periph); +/* 10-bit address header executes complete sequence in master receive mode */ +void i2c_address10_header_disable(uint32_t i2c_periph); +/* enable 10-bit addressing mode in master mode */ +void i2c_address10_enable(uint32_t i2c_periph); +/* disable 10-bit addressing mode in master mode */ +void i2c_address10_disable(uint32_t i2c_periph); +/* enable I2C automatic end mode in master mode */ +void i2c_automatic_end_enable(uint32_t i2c_periph); +/* disable I2C automatic end mode in master mode */ +void i2c_automatic_end_disable(uint32_t i2c_periph); +/* enable the response to a general call */ +void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph); +/* disable the response to a general call */ +void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph); +/* enable to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_enable(uint32_t i2c_periph); +/* disable to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_disable(uint32_t i2c_periph); +/* configure i2c slave address */ +void i2c_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_format); +/* define which bits of ADDRESS[7:1] need to compare with the incoming address byte */ +void i2c_address_bit_compare_config(uint32_t i2c_periph, uint32_t compare_bits); +/* disable i2c address in slave mode */ +void i2c_address_disable(uint32_t i2c_periph); +/* configure i2c second slave address */ +void i2c_second_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_mask); +/* disable i2c second address in slave mode */ +void i2c_second_address_disable(uint32_t i2c_periph); +/* get received match address in slave mode */ +uint32_t i2c_recevied_address_get(uint32_t i2c_periph); +/* enable slave byte control */ +void i2c_slave_byte_control_enable(uint32_t i2c_periph); +/* disable slave byte control */ +void i2c_slave_byte_control_disable(uint32_t i2c_periph); +/* generate a NACK in slave mode */ +void i2c_nack_enable(uint32_t i2c_periph); +/* generate an ACK in slave mode */ +void i2c_nack_disable(uint32_t i2c_periph); +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data */ +void i2c_data_transmit(uint32_t i2c_periph, uint32_t data); +/* I2C receive data */ +uint32_t i2c_data_receive(uint32_t i2c_periph); +/* enable I2C reload mode */ +void i2c_reload_enable(uint32_t i2c_periph); +/* disable I2C reload mode */ +void i2c_reload_disable(uint32_t i2c_periph); +/* configure number of bytes to be transferred */ +void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint32_t byte_number); +/* enable I2C DMA for transmission or reception */ +void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma); +/* disable I2C DMA for transmission or reception */ +void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma); +/* I2C transfers PEC value */ +void i2c_pec_transfer(uint32_t i2c_periph); +/* enable I2C PEC calculation */ +void i2c_pec_enable(uint32_t i2c_periph); +/* disable I2C PEC calculation */ +void i2c_pec_disable(uint32_t i2c_periph); +/* get packet error checking value */ +uint32_t i2c_pec_value_get(uint32_t i2c_periph); +/* enable SMBus alert */ +void i2c_smbus_alert_enable(uint32_t i2c_periph); +/* disable SMBus alert */ +void i2c_smbus_alert_disable(uint32_t i2c_periph); +/* enable SMBus device default address */ +void i2c_smbus_default_addr_enable(uint32_t i2c_periph); +/* disable SMBus device default address */ +void i2c_smbus_default_addr_disable(uint32_t i2c_periph); +/* enable SMBus host address */ +void i2c_smbus_host_addr_enable(uint32_t i2c_periph); +/* disable SMBus host address */ +void i2c_smbus_host_addr_disable(uint32_t i2c_periph); +/* enable extended clock timeout detection */ +void i2c_extented_clock_timeout_enable(uint32_t i2c_periph); +/* disable extended clock timeout detection */ +void i2c_extented_clock_timeout_disable(uint32_t i2c_periph); +/* enable clock timeout detection */ +void i2c_clock_timeout_enable(uint32_t i2c_periph); +/* disable clock timeout detection */ +void i2c_clock_timeout_disable(uint32_t i2c_periph); +/* configure bus timeout B */ +void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout); +/* configure bus timeout A */ +void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout); +/* configure idle clock timeout detection */ +void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout); + +/* interrupt & flag functions */ +/* get I2C flag status */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag); +/* clear I2C flag status */ +void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t interrupt); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t interrupt); +/* get I2C interrupt flag status */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); +/* clear I2C interrupt flag status */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); + +#endif /* GD32A50X_I2C_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_libopt.h b/gd32a50x/standard_peripheral/include/gd32a50x_libopt.h new file mode 100644 index 0000000..37f6acf --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_libopt.h @@ -0,0 +1,61 @@ +/*! + \file gd32a50x_libopt.h + \brief library optional for gd32a50x + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32A50X_LIBOPT_H +#define GD32A50X_LIBOPT_H + +#include "gd32a50x_adc.h" +#include "gd32a50x_bkp.h" +#include "gd32a50x_can.h" +#include "gd32a50x_cmp.h" +#include "gd32a50x_crc.h" +#include "gd32a50x_dac.h" +#include "gd32a50x_dbg.h" +#include "gd32a50x_dma.h" +#include "gd32a50x_exti.h" +#include "gd32a50x_fmc.h" +#include "gd32a50x_fwdgt.h" +#include "gd32a50x_gpio.h" +#include "gd32a50x_i2c.h" +#include "gd32a50x_mfcom.h" +#include "gd32a50x_misc.h" +#include "gd32a50x_pmu.h" +#include "gd32a50x_rcu.h" +#include "gd32a50x_spi.h" +#include "gd32a50x_syscfg.h" +#include "gd32a50x_timer.h" +#include "gd32a50x_trigsel.h" +#include "gd32a50x_usart.h" +#include "gd32a50x_wwdgt.h" +#include "gd32a50x_rtc.h" + +#endif /* GD32A50X_LIBOPT_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_mfcom.h b/gd32a50x/standard_peripheral/include/gd32a50x_mfcom.h new file mode 100644 index 0000000..1090ec8 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_mfcom.h @@ -0,0 +1,452 @@ +/*! + \file gd32a50x_mfcom.h + \brief MFCOM driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50X +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_MFCOM_H +#define GD32A50X_MFCOM_H + +#include "gd32a50x.h" + +/* MFCOM definitions */ +#define MFCOM MFCOM_BASE /*!< MFCOM base address */ + +/* registers definitions */ +#define MFCOM_CTL REG32(MFCOM + 0x00000000U) /*!< MFCOM control register */ +#define MFCOM_PINDATA REG32(MFCOM + 0x00000004U) /*!< MFCOM pin data register */ +#define MFCOM_SSTAT REG32(MFCOM + 0x00000008U) /*!< MFCOM shifter status register */ +#define MFCOM_SERR REG32(MFCOM + 0x0000000CU) /*!< MFCOM shifter error register */ +#define MFCOM_TMSTAT REG32(MFCOM + 0x00000010U) /*!< MFCOM timer status register */ +#define MFCOM_SSIEN REG32(MFCOM + 0x00000018U) /*!< MFCOM shifter status interrupt enable register */ +#define MFCOM_SEIEN REG32(MFCOM + 0x0000001CU) /*!< MFCOM shifter error interrupt enable register */ +#define MFCOM_TMSIEN REG32(MFCOM + 0x00000020U) /*!< MFCOM timer status interrupt enable register */ +#define MFCOM_SSDMAEN REG32(MFCOM + 0x00000028U) /*!< MFCOM shifter status dma enable register */ +#define MFCOM_SCTL(x) REG32(MFCOM + 0x00000080U + (x)*4U) /*!< MFCOM shifter x control register */ +#define MFCOM_SCFG(x) REG32(MFCOM + 0x00000100U + (x)*4U) /*!< MFCOM shifter x configuration register */ +#define MFCOM_SBUF(x) REG32(MFCOM + 0x00000200U + (x)*4U) /*!< MFCOM shifter buffer x register */ +#define MFCOM_SBUFBIS(x) REG32(MFCOM + 0x00000280U + (x)*4U) /*!< MFCOM shifter buffer x bit swapped register */ +#define MFCOM_SBUFBYS(x) REG32(MFCOM + 0x00000300U + (x)*4U) /*!< MFCOM shifter buffer x byte swapped register */ +#define MFCOM_SBUFBBS(x) REG32(MFCOM + 0x00000380U + (x)*4U) /*!< MFCOM shifter buffer x bit byte swapped register */ +#define MFCOM_TMCTL(x) REG32(MFCOM + 0x00000400U + (x)*4U) /*!< MFCOM timer x control register */ +#define MFCOM_TMCFG(x) REG32(MFCOM + 0x00000480U + (x)*4U) /*!< MFCOM timer x configuration register */ +#define MFCOM_TMCMP(x) REG32(MFCOM + 0x00000500U + (x)*4U) /*!< MFCOM timer x compare register */ + +/* bits definitions */ +/* MFCOM_CTL */ +#define MFCOM_CTL_MFCOMEN BIT(0) /*!< MFCOM enable */ +#define MFCOM_CTL_SWRSTEN BIT(1) /*!< software reset enable */ + +/* MFCOM_PINDATA */ +#define MFCOM_PINDATA_PDATA BITS(0,7) /*!< input data of pins */ + +/* MFCOM_SSTAT */ +#define MFCOM_SSTAT_SSTAT BITS(0,3) /*!< shifter x status flag */ + +/* MFCOM_SERR */ +#define MFCOM_SERR_SERR BITS(0,3) /*!< shifter x error flags */ + +/* MFCOM_TMSTAT */ +#define MFCOM_TMSTAT_TMSTAT BITS(0,3) /*!< timer x status flags */ + +/* MFCOM_SSIEN */ +#define MFCOM_SSIEN_SSIEN BITS(0,3) /*!< shifter status interrupt enable */ + +/* MFCOM_TMSIEN */ +#define MFCOM_TMSIEN_TMSIEN BITS(0,3) /*!< timer status interrupt enable */ + +/* MFCOM_SSDMAEN */ +#define MFCOM_SSDMAEN_SSDMAEN BITS(0,3) /*!< shifter status DMA enable */ + +/* MFCOM_SCTLx */ +#define MFCOM_SCTL_SMOD BITS(0,2) /*!< shifter mode */ +#define MFCOM_SCTL_SPPL BIT(7) /*!< shifter pin polarity */ +#define MFCOM_SCTL_SPSEL BITS(8,10) /*!< shifter pin select */ +#define MFCOM_SCTL_SPCFG BITS(16,17) /*!< shifter pin configuration */ +#define MFCOM_SCTL_TMPL BIT(23) /*!< timer polarity */ +#define MFCOM_SCTL_TMSEL BITS(24,25) /*!< timer select */ + +/* MFCOM_SCFGx */ +#define MFCOM_SCFG_SSTART BITS(0,1) /*!< shifter start bit */ +#define MFCOM_SCFG_SSTOP BITS(4,5) /*!< shifter stop bit */ +#define MFCOM_SCFG_INSRC BIT(8) /*!< input source */ + +/* MFCOM_SBUFx */ +#define MFCOM_SBUFx_SBUF BITS(0,31) /*!< shift buffer */ + +/* MFCOM_SBUFBISx */ +#define MFCOM_SBUFBISx_SBUFBIS BITS(0,31) /*!< shift buffer bit swapped */ + +/* MFCOM_SBUFBYSx */ +#define MFCOM_SBUFBYSx_SBUFBYS BITS(0,31) /*!< shift buffer byte swapped */ + +/* MFCOM_SBUFBBSx */ +#define MFCOM_SBUFBBSx_SBUFBBS BITS(0,31) /*!< shift buffer bit byte swapped */ + +/* MFCOM_TMCTLx */ +#define MFCOM_TMCTL_TMMOD BITS(0,1) /*!< timer mode */ +#define MFCOM_TMCTL_TMPPL BIT(7) /*!< timer pin polarity */ +#define MFCOM_TMCTL_TMPSEL BITS(8,10) /*!< timer pin select */ +#define MFCOM_TMCTL_TMPCFG BITS(16,17) /*!< timer pin configuration */ +#define MFCOM_TMCTL_TRIGSRC BIT(22) /*!< trigger source */ +#define MFCOM_TMCTL_TRIGPL BIT(23) /*!< trigger polarity */ +#define MFCOM_TMCTL_TRIGSEL BITS(24,27) /*!< trigger select */ + +/* MFCOM_TMCFGx */ +#define MFCOM_TMCFG_TMSTART BIT(1) /*!< timer start bit */ +#define MFCOM_TMCFG_TMSTOP BITS(4,5) /*!< timer stop bit */ +#define MFCOM_TMCFG_TMEN BITS(8,10) /*!< timer enable source */ +#define MFCOM_TMCFG_TMDIS BITS(12,14) /*!< timer disable source */ +#define MFCOM_TMCFG_TMRST BITS(16,18) /*!< timer reset source */ +#define MFCOM_TMCFG_TMDEC BITS(20,21) /*!< timer decrement source */ +#define MFCOM_TMCFG_TMOUT BITS(24,25) /*!< timer output select */ + +/* MFCOM_TMCMPx */ +#define MFCOM_TMCMPx_TMCVALUE BITS(0,31) /*!< timer compare value */ + +/* constants definitions */ +/* MFCOM timer init parameter struct definitions */ +typedef struct +{ + /* trigger */ + uint32_t trigger_select; /*!< the internal trigger selection */ + uint32_t trigger_polarity; /*!< trigger polarity */ + /* pin */ + uint32_t pin_config; /*!< timer pin configuration */ + uint32_t pin_select; /*!< timer pin number select */ + uint32_t pin_polarity; /*!< timer pin polarity */ + /* timer */ + uint32_t mode; /*!< timer work mode */ + uint32_t output; /*!< configures the initial state of the timer output and + whether it is affected by the timer reset */ + uint32_t decrement; /*!< configures the source of the timer decrement and the + source of the shift clock */ + uint32_t reset; /*!< configures the condition that causes the timer counter + (and optionally the timer output) to be reset */ + uint32_t disable; /*!< configures the condition that causes the timer to be + disabled and stop decrementing */ + uint32_t enable; /*!< configures the condition that causes the timer to be + enabled and start decrementing */ + uint32_t stopbit; /*!< timer stop bit generation */ + uint32_t startbit; /*!< timer start bit generation */ + uint32_t compare; /*!< value for timer compare x register */ +}mfcom_timer_parameter_struct; + +/* MFCOM shifter init parameter struct definitions */ +typedef struct +{ + /* timer */ + uint32_t timer_select; /*!< selects which timer is used for controlling the + logic/shift register and generating the shift clock */ + uint32_t timer_polarity; /*!< timer polarity */ + /* pin */ + uint32_t pin_config; /*!< shifter pin configuration */ + uint32_t pin_select; /*!< shifter pin number select */ + uint32_t pin_polarity; /*!< shifter pin polarity */ + /* shifter */ + uint32_t mode; /*!< configures the mode of the shifter */ + uint32_t input_source; /*!< selects the input source for the shifter */ + uint32_t stopbit; /*!< shifter stop bit */ + uint32_t startbit; /*!< shifter start bit */ +}mfcom_shifter_parameter_struct; + +/* MFCOM timer trigger source */ +#define TMCTL_TRIGSEL(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U)) +#define MFCOM_TIMER_TRGSEL_PIN0 (TMCTL_TRIGSEL(0)|MFCOM_TMCTL_TRIGSRC) /*!< pin 0 input selected */ +#define MFCOM_TIMER_TRGSEL_SHIFTER0 (TMCTL_TRIGSEL(1)|MFCOM_TMCTL_TRIGSRC) /*!< shifter 0 status flag selected */ +#define MFCOM_TIMER_TRGSEL_PIN1 (TMCTL_TRIGSEL(2)|MFCOM_TMCTL_TRIGSRC) /*!< pin 1 selected */ +#define MFCOM_TIMER_TRGSEL_TIMER0 (TMCTL_TRIGSEL(3)|MFCOM_TMCTL_TRIGSRC) /*!< timer 0 trigger output selected */ +#define MFCOM_TIMER_TRGSEL_PIN2 (TMCTL_TRIGSEL(4)|MFCOM_TMCTL_TRIGSRC) /*!< pin 2 selected */ +#define MFCOM_TIMER_TRGSEL_SHIFTER1 (TMCTL_TRIGSEL(5)|MFCOM_TMCTL_TRIGSRC) /*!< shifter 1 status flag selected */ +#define MFCOM_TIMER_TRGSEL_PIN3 (TMCTL_TRIGSEL(6)|MFCOM_TMCTL_TRIGSRC) /*!< pin 3 selected */ +#define MFCOM_TIMER_TRGSEL_TIMER1 (TMCTL_TRIGSEL(7)|MFCOM_TMCTL_TRIGSRC) /*!< timer 1 trigger output selected */ +#define MFCOM_TIMER_TRGSEL_PIN4 (TMCTL_TRIGSEL(8)|MFCOM_TMCTL_TRIGSRC) /*!< pin 4 selected */ +#define MFCOM_TIMER_TRGSEL_SHIFTER2 (TMCTL_TRIGSEL(9)|MFCOM_TMCTL_TRIGSRC) /*!< shifter 2 status flag selected */ +#define MFCOM_TIMER_TRGSEL_PIN5 (TMCTL_TRIGSEL(10)|MFCOM_TMCTL_TRIGSRC) /*!< pin 5 selected */ +#define MFCOM_TIMER_TRGSEL_TIMER2 (TMCTL_TRIGSEL(11)|MFCOM_TMCTL_TRIGSRC) /*!< timer 2 trigger output selected */ +#define MFCOM_TIMER_TRGSEL_PIN6 (TMCTL_TRIGSEL(12)|MFCOM_TMCTL_TRIGSRC) /*!< pin 6 selected */ +#define MFCOM_TIMER_TRGSEL_SHIFTER3 (TMCTL_TRIGSEL(13)|MFCOM_TMCTL_TRIGSRC) /*!< shifter 3 status flag selected */ +#define MFCOM_TIMER_TRGSEL_PIN7 (TMCTL_TRIGSEL(14)|MFCOM_TMCTL_TRIGSRC) /*!< pin 7 selected */ +#define MFCOM_TIMER_TRGSEL_TIMER3 (TMCTL_TRIGSEL(15)|MFCOM_TMCTL_TRIGSRC) /*!< timer 3 trigger output selected */ +#define MFCOM_TIMER_TRGSEL_EXTERNAL0 TMCTL_TRIGSEL(0) /*!< external trigger0 selected */ +#define MFCOM_TIMER_TRGSEL_EXTERNAL1 TMCTL_TRIGSEL(1) /*!< external trigger1 selected */ +#define MFCOM_TIMER_TRGSEL_EXTERNAL2 TMCTL_TRIGSEL(2) /*!< external trigger2 selected */ +#define MFCOM_TIMER_TRGSEL_EXTERNAL3 TMCTL_TRIGSEL(3) /*!< external trigger3 selected */ + +/* MFCOM timer trigger polarity */ +#define MFCOM_TIMER_TRGPOL_ACTIVE_HIGH ((uint32_t)0x00000000U) /*!< active high */ +#define MFCOM_TIMER_TRGPOL_ACTIVE_LOW MFCOM_TMCTL_TRIGPL /*!< active low */ + +/* MFCOM timer pin config */ +#define TMCTL_TMPCFG(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define MFCOM_TIMER_PINCFG_INPUT TMCTL_TMPCFG(0) /*!< pin input */ +#define MFCOM_TIMER_PINCFG_OPENDRAIN TMCTL_TMPCFG(1) /*!< pin open drain */ +#define MFCOM_TIMER_PINCFG_BIDI TMCTL_TMPCFG(2) /*!< pin cascade input/output */ +#define MFCOM_TIMER_PINCFG_OUTPUT TMCTL_TMPCFG(3) /*!< pin output */ + +/* MFCOM timer pin select */ +#define TMCTL_TMPSEL(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) +#define MFCOM_TIMER_PINSEL_PIN0 TMCTL_TMPSEL(0) /*!< timer Pin 0 selected */ +#define MFCOM_TIMER_PINSEL_PIN1 TMCTL_TMPSEL(1) /*!< timer Pin 1 selected */ +#define MFCOM_TIMER_PINSEL_PIN2 TMCTL_TMPSEL(2) /*!< timer Pin 2 selected */ +#define MFCOM_TIMER_PINSEL_PIN3 TMCTL_TMPSEL(3) /*!< timer Pin 3 selected */ +#define MFCOM_TIMER_PINSEL_PIN4 TMCTL_TMPSEL(4) /*!< timer Pin 4 selected */ +#define MFCOM_TIMER_PINSEL_PIN5 TMCTL_TMPSEL(5) /*!< timer Pin 5 selected */ +#define MFCOM_TIMER_PINSEL_PIN6 TMCTL_TMPSEL(6) /*!< timer Pin 6 selected */ +#define MFCOM_TIMER_PINSEL_PIN7 TMCTL_TMPSEL(7) /*!< timer Pin 7 selected */ + +/* MFCOM timer pin polarity */ +#define MFCOM_TIMER_PINPOL_ACTIVE_HIGH ((uint32_t)0x00000000U) /*!< active high */ +#define MFCOM_TIMER_PINPOL_ACTIVE_LOW MFCOM_TMCTL_TMPPL /*!< active low */ + +/* MFCOM timer mode */ +#define TMCTL_TMMOD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define MFCOM_TIMER_DISABLE TMCTL_TMMOD(0) /*!< timer disabled. */ +#define MFCOM_TIMER_BAUDMODE TMCTL_TMMOD(1) /*!< dual 8-bit counters baud/bit mode */ +#define MFCOM_TIMER_PWMMODE TMCTL_TMMOD(2) /*!< dual 8-bit counters PWM mode */ +#define MFCOM_TIMER_16BITCOUNTER TMCTL_TMMOD(3) /*!< single 16-bit counter mode */ + +/* MFCOM timer output */ +#define TMCFG_TMOUT(regval) (BITS(24,25) & ((uint32_t)(regval) << 24U)) +#define MFCOM_TIMER_OUT_HIGH_EN TMCFG_TMOUT(0) /*!< logic one when enabled and is not affected by timer reset */ +#define MFCOM_TIMER_OUT_LOW_EN TMCFG_TMOUT(1) /*!< logic zero when enabled and is not affected by timer reset */ +#define MFCOM_TIMER_OUT_HIGH_EN_RESET TMCFG_TMOUT(2) /*!< logic one when enabled and on timer reset */ +#define MFCOM_TIMER_OUT_LOW_EN_RESET TMCFG_TMOUT(3) /*!< logic zero when enabled and on timer reset */ + +/* MFCOM timer decrement */ +#define TMCFG_TMDEC(regval) (BITS(20,21) & ((uint32_t)(regval) << 20U)) +#define MFCOM_TIMER_DEC_CLK_SHIFT_OUT TMCFG_TMDEC(0) /*!< decrement counter on MFCOM clock, shift clock equals timer output */ +#define MFCOM_TIMER_DEC_TRIG_SHIFT_OUT TMCFG_TMDEC(1) /*!< decrement counter on trigger input (both edges), shift clock equals timer output */ +#define MFCOM_TIMER_DEC_PIN_SHIFT_PIN TMCFG_TMDEC(2) /*!< decrement counter on pin input (both edges), shift clock equals Pin input */ +#define MFCOM_TIMER_DEC_TRIG_SHIFT_TRIG TMCFG_TMDEC(3) /*!< decrement counter on trigger input (both edges), shift clock equals trigger input */ + +/* MFCOM timer reset */ +#define TMCFG_TMRST(regval) (BITS(16,18) & ((uint32_t)(regval) << 16U)) +#define MFCOM_TIMER_RESET_NEVER TMCFG_TMRST(0) /*!< timer never reset */ +#define MFCOM_TIMER_RESET_PIN_TIMOUT TMCFG_TMRST(2) /*!< timer reset on timer pin equal to timer output */ +#define MFCOM_TIMER_RESET_TRIG_TIMOUT TMCFG_TMRST(3) /*!< timer reset on timer trigger equal to timer output */ +#define MFCOM_TIMER_RESET_PIN_RISING TMCFG_TMRST(4) /*!< timer reset on timer pin rising edge */ +#define MFCOM_TIMER_RESET_TRIG_RISING TMCFG_TMRST(6) /*!< timer reset on trigger rising edge */ +#define MFCOM_TIMER_RESET_TRIG_BOTH TMCFG_TMRST(7) /*!< timer reset on trigger rising or falling edge */ + +/* MFCOM timer disable */ +#define TMCFG_TMDIS(regval) (BITS(12,14) & ((uint32_t)(regval) << 12U)) +#define MFCOM_TIMER_DISMODE_NEVER TMCFG_TMDIS(0) /*!< timer never disabled */ +#define MFCOM_TIMER_DISMODE_PRE_TIMDIS TMCFG_TMDIS(1) /*!< timer disabled on timer x-1 disable */ +#define MFCOM_TIMER_DISMODE_COMPARE TMCFG_TMDIS(2) /*!< timer disabled on timer compare */ +#define MFCOM_TIMER_DISMODE_COMPARE_TRIGLOW TMCFG_TMDIS(3) /*!< timer disabled on timer compare and trigger Low */ +#define MFCOM_TIMER_DISMODE_PINBOTH TMCFG_TMDIS(4) /*!< timer disabled on pin rising or falling edge */ +#define MFCOM_TIMER_DISMODE_PINBOTH_TRIGHIGH TMCFG_TMDIS(5) /*!< timer disabled on pin rising or falling edge provided trigger is high */ +#define MFCOM_TIMER_DISMODE_TRIGFALLING TMCFG_TMDIS(6) /*!< timer disabled on trigger falling edge */ + +/* MFCOM timer enable */ +#define TMCFG_TMEN(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) +#define MFCOM_TIMER_ENMODE_ALWAYS TMCFG_TMEN(0) /*!< timer always enabled */ +#define MFCOM_TIMER_ENMODE_PRE_TIMEN TMCFG_TMEN(1) /*!< timer enabled on timer x-1 enable */ +#define MFCOM_TIMER_ENMODE_TRIGHIGH TMCFG_TMEN(2) /*!< timer enabled on trigger high */ +#define MFCOM_TIMER_ENMODE_TRIGHIGH_PINHIGH TMCFG_TMEN(3) /*!< timer enabled on trigger high and Pin high */ +#define MFCOM_TIMER_ENMODE_PINRISING TMCFG_TMEN(4) /*!< timer enabled on pin rising edge */ +#define MFCOM_TIMER_ENMODE_PINRISING_TRIGHIGH TMCFG_TMEN(5) /*!< timer enabled on pin rising edge and trigger high */ +#define MFCOM_TIMER_ENMODE_TRIGRISING TMCFG_TMEN(6) /*!< timer enabled on trigger rising edge */ +#define MFCOM_TIMER_ENMODE_TRIGBOTH TMCFG_TMEN(7) /*!< timer enabled on trigger rising or falling edge */ + +/* MFCOM timer stopbit */ +#define TMCFG_TMSTOP(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define MFCOM_TIMER_STOPBIT_DISABLE TMCFG_TMSTOP(0) /*!< stop bit disabled */ +#define MFCOM_TIMER_STOPBIT_TIMCMP TMCFG_TMSTOP(1) /*!< stop bit is enabled on timer compare */ +#define MFCOM_TIMER_STOPBIT_TIMDIS TMCFG_TMSTOP(2) /*!< stop bit is enabled on timer disable */ +#define MFCOM_TIMER_STOPBIT_TIMCMP_TIMDIS TMCFG_TMSTOP(3) /*!< stop bit is enabled on timer compare and timer disable */ + +/* MFCOM timer startbit */ +#define MFCOM_TIMER_STARTBIT_DISABLE ((uint32_t)0x00000000U) /*!< Start bit disabled */ +#define MFCOM_TIMER_STARTBIT_ENABLE MFCOM_TMCFG_TMSTART /*!< Start bit enabled */ + +/* MFCOM shifter timer select */ +#define SCTL_TMSEL(regval) (BITS(24,25) & ((uint32_t)(regval) << 24U)) +#define MFCOM_SHIFTER_TIMER0 SCTL_TMSEL(0) /*!< timer0 selected */ +#define MFCOM_SHIFTER_TIMER1 SCTL_TMSEL(1) /*!< timer1 selected */ +#define MFCOM_SHIFTER_TIMER2 SCTL_TMSEL(2) /*!< timer2 selected */ +#define MFCOM_SHIFTER_TIMER3 SCTL_TMSEL(3) /*!< timer3 selected */ + +/* type of timer polarity for shifter control */ +#define MFCOM_SHIFTER_TIMPOL_ACTIVE_HIGH ((uint32_t)0x00000000U) /*!< shift on positive edge of shift clock */ +#define MFCOM_SHIFTER_TIMPOL_ACTIVE_LOW MFCOM_SCTL_TMPL /*!< shift on negative edge of shift clock */ + +/* MFCOM shifter pin config */ +#define SCTL_SPCFG(regval) (BITS(16,17) & ((uint32_t)(regval) << 16U)) +#define MFCOM_SHIFTER_PINCFG_INPUT SCTL_SPCFG(0) /*!< pin input */ +#define MFCOM_SHIFTER_PINCFG_OPENDRAIN SCTL_SPCFG(1) /*!< pin open drain */ +#define MFCOM_SHIFTER_PINCFG_BIDI SCTL_SPCFG(2) /*!< pin cascade input/output */ +#define MFCOM_SHIFTER_PINCFG_OUTPUT SCTL_SPCFG(3) /*!< pin output */ + +/* MFCOM shifter pin select */ +#define SCTL_SPSEL(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) +#define MFCOM_SHIFTER_PINSEL_PIN0 SCTL_SPSEL(0) /*!< shifter pin 0 selected */ +#define MFCOM_SHIFTER_PINSEL_PIN1 SCTL_SPSEL(1) /*!< shifter pin 1 selected */ +#define MFCOM_SHIFTER_PINSEL_PIN2 SCTL_SPSEL(2) /*!< shifter pin 2 selected */ +#define MFCOM_SHIFTER_PINSEL_PIN3 SCTL_SPSEL(3) /*!< shifter pin 3 selected */ +#define MFCOM_SHIFTER_PINSEL_PIN4 SCTL_SPSEL(4) /*!< shifter pin 4 selected */ +#define MFCOM_SHIFTER_PINSEL_PIN5 SCTL_SPSEL(5) /*!< shifter pin 5 selected */ +#define MFCOM_SHIFTER_PINSEL_PIN6 SCTL_SPSEL(6) /*!< shifter pin 6 selected */ +#define MFCOM_SHIFTER_PINSEL_PIN7 SCTL_SPSEL(7) /*!< shifter pin 7 selected */ + +/* MFCOM shifter pin polarity */ +#define MFCOM_SHIFTER_PINPOL_ACTIVE_HIGH ((uint32_t)0x00000000U) /*!< active high */ +#define MFCOM_SHIFTER_PINPOL_ACTIVE_LOW MFCOM_SCTL_SPPL /*!< active low */ + +/* MFCOM shifter mode */ +#define SCTL_SMOD(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define MFCOM_SHIFTER_DISABLE SCTL_SMOD(0) /*!< shifter is disabled */ +#define MFCOM_SHIFTER_RECEIVE SCTL_SMOD(1) /*!< receive mode */ +#define MFCOM_SHIFTER_TRANSMIT SCTL_SMOD(2) /*!< transmit mode */ +#define MFCOM_SHIFTER_MATCH_STORE SCTL_SMOD(4) /*!< match store mode */ +#define MFCOM_SHIFTER_MATCH_CONTINUOUS SCTL_SMOD(5) /*!< match continuous mode */ + +/* MFCOM shifter input source */ +#define MFCOM_SHIFTER_INSRC_PIN ((uint32_t)0x00000000U) /*!< shifter input from pin */ +#define MFCOM_SHIFTER_INSRC_NEXTSHIFTER MFCOM_SCFG_INSRC /*!< shifter input from shifter x+1 */ + +/* MFCOM shifter stopbit */ +#define SCFG_SSTOP(regval) (BITS(4,5) & ((uint32_t)(regval) << 4U)) +#define MFCOM_SHIFTER_STOPBIT_DISABLE SCFG_SSTOP(0) /*!< disable shifter stop bit */ +#define MFCOM_SHIFTER_STOPBIT_LOW SCFG_SSTOP(2) /*!< set shifter stop bit to logic low level */ +#define MFCOM_SHIFTER_STOPBIT_HIGH SCFG_SSTOP(3) /*!< set shifter stop bit to logic high level */ + +/* MFCOM shifter startbit */ +#define SCFG_SSTART(regval) (BITS(0,1) & ((uint32_t)(regval) << 0U)) +#define MFCOM_SHIFTER_STARTBIT_DISABLE SCFG_SSTART(0) /*!< disable shifter start bit, transmitter loads data on enable */ +#define MFCOM_SHIFTER_STARTBIT_DISABLE_TXEN SCFG_SSTART(1) /*!< disable shifter start bit, transmitter loads data on first shift */ +#define MFCOM_SHIFTER_STARTBIT_LOW SCFG_SSTART(2) /*!< set shifter start bit to logic low level */ +#define MFCOM_SHIFTER_STARTBIT_HIGH SCFG_SSTART(3) /*!< set shifter start bit to logic high level */ + +/* MFCOM shifter enum */ +#define MFCOM_SHIFTER_0 ((uint32_t)0x00000000U) /*!< MFCOM shifter0 */ +#define MFCOM_SHIFTER_1 ((uint32_t)0x00000001U) /*!< MFCOM shifter1 */ +#define MFCOM_SHIFTER_2 ((uint32_t)0x00000002U) /*!< MFCOM shifter2 */ +#define MFCOM_SHIFTER_3 ((uint32_t)0x00000003U) /*!< MFCOM shifter3 */ + +/* MFCOM timer enum */ +#define MFCOM_TIMER_0 ((uint32_t)0x00000000U) /*!< MFCOM timer0 */ +#define MFCOM_TIMER_1 ((uint32_t)0x00000001U) /*!< MFCOM timer1 */ +#define MFCOM_TIMER_2 ((uint32_t)0x00000002U) /*!< MFCOM timer2 */ +#define MFCOM_TIMER_3 ((uint32_t)0x00000003U) /*!< MFCOM timer3 */ + +/* MFCOM read write mode enum */ +#define MFCOM_RWMODE_NORMAL ((uint32_t)0x00000000U) /*!< read and write in normal mode */ +#define MFCOM_RWMODE_BITSWAP ((uint32_t)0x00000001U) /*!< read and write in bit swapped mode */ +#define MFCOM_RWMODE_BYTESWAP ((uint32_t)0x00000002U) /*!< read and write in byte swapped mode */ +#define MFCOM_RWMODE_BITBYTESWAP ((uint32_t)0x00000003U) /*!< read and write in bit byte swapped mode */ + +/* function declarations */ +/* reset MFCOM */ +void mfcom_deinit(void); +/* software reset */ +void mfcom_software_reset(void); +/* enable MFCOM function */ +void mfcom_enable(void); +/* disable MFCOM function */ +void mfcom_disable(void); +/* initialize mfcom_timer_parameter_struct with the default values */ +void mfcom_timer_struct_para_init(mfcom_timer_parameter_struct* init_struct); +/* initialize mfcom_shifter_parameter_struct with the default values */ +void mfcom_shifter_struct_para_init(mfcom_shifter_parameter_struct* init_struct); + +/* initialize MFCOM timer */ +void mfcom_timer_init(uint32_t timer, mfcom_timer_parameter_struct* init_struct); +/* initialize MFCOM shifter */ +void mfcom_shifter_init(uint32_t shifter, mfcom_shifter_parameter_struct* init_struct); + +/* configure timer pin mode */ +void mfcom_timer_pin_config(uint32_t timer, uint32_t mode); +/* configure shifter pin mode */ +void mfcom_shifter_pin_config(uint32_t shifter, uint32_t mode); +/* enable MFCOM timer in specific mode */ +void mfcom_timer_enable(uint32_t timer, uint32_t timermode); +/* enable MFCOM shifter in specific mode */ +void mfcom_shifter_enable(uint32_t shifter, uint32_t shiftermode); +/* disable MFCOM timer */ +void mfcom_timer_disable(uint32_t timer); +/* disable MFCOM shifter */ +void mfcom_shifter_disable(uint32_t shifter); + +/* set the timer compare value */ +void mfcom_timer_cmpvalue_set(uint32_t timer, uint32_t compare); +/* get the timer compare value */ +uint32_t mfcom_timer_cmpvalue_get(uint32_t timer); +/* set the timer disable source */ +void mfcom_timer_dismode_set(uint32_t timer, uint32_t dismode); + +/* set the shifter stopbit */ +void mfcom_shifter_stopbit_set(uint32_t shifter, uint32_t stopbit); +/* write MFCOM shifter buffer */ +void mfcom_buffer_write(uint32_t shifter, uint32_t data, uint32_t rwmode); +/* read MFCOM shifter buffer */ +uint32_t mfcom_buffer_read(uint32_t shifter, uint32_t rwmode); +/* get MFCOM shifter flag */ +FlagStatus mfcom_shifter_flag_get(uint32_t shifter); +/* get MFCOM shifter error flag */ +FlagStatus mfcom_shifter_error_flag_get(uint32_t shifter); +/* get MFCOM timer flag */ +FlagStatus mfcom_timer_flag_get(uint32_t timer); + +/* get MFCOM shifter interrupt flag */ +FlagStatus mfcom_shifter_interrupt_flag_get(uint32_t shifter); +/* get MFCOM shifter error interrupt flag */ +FlagStatus mfcom_shifter_error_interrupt_flag_get(uint32_t shifter); +/* get MFCOM timer interrupt flag */ +FlagStatus mfcom_timer_interrupt_flag_get(uint32_t timer); + +/* clear MFCOM shifter flag */ +void mfcom_shifter_flag_clear(uint32_t shifter); +/* clear MFCOM shifter error flag */ +void mfcom_shifter_error_flag_clear(uint32_t shifter); +/* clear MFCOM timer flag */ +void mfcom_timer_flag_clear(uint32_t timer); + +/* enable MFCOM shifter interrupt */ +void mfcom_shifter_interrupt_enable(uint32_t shifter); +/* enable MFCOM shifter error interrupt */ +void mfcom_shifter_error_interrupt_enable(uint32_t shifter); +/* enable MFCOM timer interrupt */ +void mfcom_timer_interrupt_enable(uint32_t timer); +/* enable MFCOM shifter dma */ +void mfcom_shifter_dma_enable(uint32_t shifter); + +/* disable MFCOM shifter interrupt */ +void mfcom_shifter_interrupt_disable(uint32_t shifter); +/* disable MFCOM shifter error interrupt */ +void mfcom_shifter_error_interrupt_disable(uint32_t shifter); +/* disable MFCOM timer interrupt */ +void mfcom_timer_interrupt_disable(uint32_t timer); +/* disable MFCOM shifter dma */ +void mfcom_shifter_dma_disable(uint32_t shifter); + +#endif /* GD32A50X_MFCOM_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_misc.h b/gd32a50x/standard_peripheral/include/gd32a50x_misc.h new file mode 100644 index 0000000..8d6bb15 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_misc.h @@ -0,0 +1,93 @@ +/*! + \file gd32a50x_misc.h + \brief definitions for the MISC + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_MISC_H +#define GD32A50X_MISC_H + +#include "gd32a50x.h" + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80) + +/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */ +#define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/* priority group - define the pre-emption priority and the subpriority */ +#define NVIC_PRIGROUP_PRE0_SUB4 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */ +#define NVIC_PRIGROUP_PRE1_SUB3 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */ +#define NVIC_PRIGROUP_PRE2_SUB2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */ +#define NVIC_PRIGROUP_PRE3_SUB1 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */ +#define NVIC_PRIGROUP_PRE4_SUB0 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */ + +/* choose the method to enter or exit the lowpower mode */ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ + +/* function declarations */ +/* set the priority group */ +void nvic_priority_group_set(uint32_t nvic_prigroup); + +/* enable NVIC request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority); +/* disable NVIC request */ +void nvic_irq_disable(IRQn_Type nvic_irq); +/* initiates a system reset request to reset the MCU */ +void nvic_system_reset(void); + +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); + +/* set the state of the low power mode */ +void system_lowpower_set(uint8_t lowpower_mode); +/* reset the state of the low power mode */ +void system_lowpower_reset(uint8_t lowpower_mode); + +/* set the systick clock source */ +void systick_clksource_set(uint32_t systick_clksource); + +#endif /* GD32A50X_MISC_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_pmu.h b/gd32a50x/standard_peripheral/include/gd32a50x_pmu.h new file mode 100644 index 0000000..5b608b9 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_pmu.h @@ -0,0 +1,165 @@ +/*! + \file gd32a50x_pmu.h + \brief definitions for the PMU + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_PMU_H +#define GD32A50X_PMU_H + +#include "gd32a50x.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00000000U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x00000004U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL_OVDEN BIT(14) /*!< over voltage detector enable */ +#define PMU_CTL_OVDT BIT(15) /*!< over voltage detector threshold */ +#define PMU_CTL_LDEN BIT(18) /*!< low-driver mode enable in deep-sleep mode */ +#define PMU_CTL_SRAMSW1 BIT(20) /*!< SRAM1(16KB~32KB) power switch in deep-sleep mode */ +#define PMU_CTL_SRAMSW2 BIT(21) /*!< SRAM2(32KB~48KB) power switch in deep-sleep mode */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_OVDF BIT(3) /*!< over voltage detector status flag */ +#define PMU_CS_WUPEN0 BIT(8) /*!< wakeup pin 0 enable */ +#define PMU_CS_WUPEN1 BIT(9) /*!< wakeup pin 1 enable */ + +/* constants definitions */ +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO normal work when PMU enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deepsleep mode */ + +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval)<<5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.9V */ +#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 3.1V */ +#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 3.3V */ +#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 3.5V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 4.0V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 4.2V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 4.4V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 4.6V */ + +/* PMU over voltage detector threshold definitions */ +#define CTL_OVDT(regval) (BIT(15)&((uint32_t)(regval)<<15)) +#define PMU_OVDT_0 CTL_OVDT(0) /*!< voltage threshold is 5.0V */ +#define PMU_OVDT_1 CTL_OVDT(1) /*!< voltage threshold is 5.5V */ + +/* PMU flag definitions */ +#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ +#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ +#define PMU_FLAG_LVD PMU_CS_LVDF /*!< lvd flag status */ +#define PMU_FLAG_OVD PMU_CS_OVDF /*!< ovd flag status */ + +/* PMU WKUP pin definitions */ +#define PMU_WAKEUP_PIN0 PMU_CS_WUPEN0 /*!< WKUP Pin 0 (PA0) enable */ +#define PMU_WAKEUP_PIN1 PMU_CS_WUPEN1 /*!< WKUP Pin 1 (PC13) enable */ + +/* low-driver mode in deep-sleep mode */ +#define PMU_LOWDRIVER_DISABLE ((uint32_t)0x00000000U) /*!< low-driver mode disable in deep-sleep mode */ +#define PMU_LOWDRIVER_ENABLE PMU_CTL_LDEN /*!< low-driver mode enable in deep-sleep mode */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP ((uint8_t)0x00U) /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY ((uint8_t)0x01U) /*!< standby flag reset */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ + +/* function declarations */ +/* reset PMU registers */ +void pmu_deinit(void); + +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* disable PMU lvd */ +void pmu_lvd_disable(void); +/* select over voltage detector threshold */ +void pmu_ovd_select(uint32_t ovdt_n); +/* disable PMU ovd */ +void pmu_ovd_disable(void); + +/* enable low-driver mode in deep-sleep mode */ +void pmu_lowdriver_mode_enable(void); +/* disable low-driver mode in deep-sleep mode */ +void pmu_lowdriver_mode_disable(void); +/* SRAM1 power off in deep-sleep mode */ +void pmu_sram1_poweroff_mode_enable(void); +/* SRAM1 power on in deep-sleep mode */ +void pmu_sram1_poweroff_mode_disable(void); +/* SRAM2 power off in deep-sleep mode */ +void pmu_sram2_poweroff_mode_enable(void); +/* SRAM2 power on in deep-sleep mode */ +void pmu_sram2_poweroff_mode_disable(void); + +/* set PMU mode */ +/* PMU work in sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work in deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo, uint32_t lowdrive, uint8_t deepsleepmodecmd); +/* PMU work in standby mode */ +void pmu_to_standbymode(void); + +/* wakeup pin related functions */ +/* 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 registers in backup domain */ +void pmu_backup_write_enable(void); +/* disable write access to the registers in backup domain */ +void pmu_backup_write_disable(void); + +/* flag functions */ +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag); + +#endif /* GD32A50X_PMU_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_rcu.h b/gd32a50x/standard_peripheral/include/gd32a50x_rcu.h new file mode 100644 index 0000000..2f1903c --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_rcu.h @@ -0,0 +1,761 @@ +/*! + \file gd32a50x_rcu.h + \brief definitions for the RCU + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_RCU_H +#define GD32A50X_RCU_H + +#include "gd32a50x.h" + +/* RCU definitions */ +#define RCU RCU_BASE /*!< RCU base address */ + +/* registers definitions */ +#define RCU_CTL REG32(RCU + 0x00000000U) /*!< control register */ +#define RCU_CFG0 REG32(RCU + 0x00000004U) /*!< clock configuration register 0 */ +#define RCU_INT REG32(RCU + 0x00000008U) /*!< clock interrupt register */ +#define RCU_APB2RST REG32(RCU + 0x0000000CU) /*!< APB2 reset register */ +#define RCU_APB1RST REG32(RCU + 0x00000010U) /*!< APB1 reset register */ +#define RCU_AHBEN REG32(RCU + 0x00000014U) /*!< AHB1 enable register */ +#define RCU_APB2EN REG32(RCU + 0x00000018U) /*!< APB2 enable register */ +#define RCU_APB1EN REG32(RCU + 0x0000001CU) /*!< APB1 enable register */ +#define RCU_BDCTL REG32(RCU + 0x00000020U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x00000024U) /*!< reset source / clock register */ +#define RCU_AHBRST REG32(RCU + 0x00000028U) /*!< AHB reset register */ +#define RCU_CFG1 REG32(RCU + 0x0000002CU) /*!< clock configuration register 1 */ +#define RCU_CFG2 REG32(RCU + 0x00000030U) /*!< clock configuration register 2 */ +#define RCU_VKEY REG32(RCU + 0x00000100U) /*!< voltage key register */ +#define RCU_DSV REG32(RCU + 0x00000134U) /*!< deep-sleep mode voltage register */ + +/* bits definitions */ +/* RCU_CTL */ +#define RCU_CTL_IRC8MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL_IRC8MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */ +#define RCU_CTL_IRC8MADJ BITS(3,7) /*!< internal 8M RC oscillator clock trim adjust value */ +#define RCU_CTL_IRC8MCALIB BITS(8,15) /*!< internal 8M RC oscillator calibration value */ +#define RCU_CTL_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL_PLLMEN BIT(20) /*!< PLL clock monitor enable */ +#define RCU_CTL_LCKMEN BIT(21) /*!< LXTAL clock monitor enable */ +#define RCU_CTL_HXTALSCAL BIT(22) /*!< HXTAL frequency scale select */ +#define RCU_CTL_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL_PLLSTB BIT(25) /*!< PLL clock stabilization flag */ + +/* RCU_CFG0 */ +#define RCU_CFG0_SCS BITS(0,1) /*!< system clock switch */ +#define RCU_CFG0_SCSS BITS(2,3) /*!< system clock switch status */ +#define RCU_CFG0_AHBPSC BITS(4,7) /*!< AHB prescaler selection */ +#define RCU_CFG0_APB1PSC BITS(8,10) /*!< APB1 prescaler selection */ +#define RCU_CFG0_APB2PSC BITS(11,13) /*!< APB2 prescaler selection */ +#define RCU_CFG0_PLLSEL BIT(16) /*!< PLL clock source selection */ +#define RCU_CFG0_DPLL BIT(17) /*!< double PLL clock */ +#define RCU_CFG0_PLLMF BITS(18,21) /*!< PLL clock multiplication factor */ +#define RCU_CFG0_CKOUTSEL BITS(24,26) /*!< CKOUT clock source selection */ +#define RCU_CFG0_PLLMF_4 BIT(27) /*!< bit 4 of PLLMF */ +#define RCU_CFG0_CKOUTDIV BITS(28,30) /*!< CK_OUT divider which the CK_OUT frequency can be reduced */ +#define RCU_CFG0_PLLDV BIT(31) /*!< CK_PLL divide by 1 or 2 for CK_OUT */ + +/* RCU_INT */ +#define RCU_INT_IRC40KSTBIF BIT(0) /*!< IRC40K stabilization interrupt flag */ +#define RCU_INT_LXTALSTBIF BIT(1) /*!< LXTAL stabilization interrupt flag */ +#define RCU_INT_IRC8MSTBIF BIT(2) /*!< IRC8M stabilization interrupt flag */ +#define RCU_INT_HXTALSTBIF BIT(3) /*!< HXTAL stabilization interrupt flag */ +#define RCU_INT_PLLSTBIF BIT(4) /*!< PLL stabilization interrupt flag */ +#define RCU_INT_LCKMIF BIT(5) /*!< LXTAL clock monitor interrupt flag */ +#define RCU_INT_PLLMIF BIT(6) /*!< PLL clock monitor interrupt flag */ +#define RCU_INT_CKMIF BIT(7) /*!< HXTAL clock stuck interrupt flag */ +#define RCU_INT_IRC40KSTBIE BIT(8) /*!< IRC40K stabilization interrupt enable */ +#define RCU_INT_LXTALSTBIE BIT(9) /*!< LXTAL stabilization interrupt enable */ +#define RCU_INT_IRC8MSTBIE BIT(10) /*!< IRC8M stabilization interrupt enable */ +#define RCU_INT_HXTALSTBIE BIT(11) /*!< HXTAL stabilization interrupt enable */ +#define RCU_INT_PLLSTBIE BIT(12) /*!< PLL stabilization interrupt enable */ +#define RCU_INT_LCKMIE BIT(13) /*!< LXTAL clock monitor interrupt enable */ +#define RCU_INT_PLLMIE BIT(14) /*!< PLL clock monitor interrupt enable */ +#define RCU_INT_IRC40KSTBIC BIT(16) /*!< IRC40K stabilization interrupt clear */ +#define RCU_INT_LXTALSTBIC BIT(17) /*!< LXTAL stabilization interrupt clear */ +#define RCU_INT_IRC8MSTBIC BIT(18) /*!< IRC8M stabilization interrupt clear */ +#define RCU_INT_HXTALSTBIC BIT(19) /*!< HXTAL stabilization interrupt clear */ +#define RCU_INT_PLLSTBIC BIT(20) /*!< PLL stabilization interrupt clear */ +#define RCU_INT_LCKMIC BIT(21) /*!< LXTAL clock monitor interrupt clear */ +#define RCU_INT_PLLMIC BIT(22) /*!< PLL clock monitor interrupt clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL clock stuck interrupt clear */ + +/* RCU_APB2RST */ +#define RCU_APB2RST_CFGRST BIT(0) /*!< system configuration reset */ +#define RCU_APB2RST_CMPRST BIT(1) /*!< comparator reset */ +#define RCU_APB2RST_ADC0RST BIT(9) /*!< ADC0 reset */ +#define RCU_APB2RST_ADC1RST BIT(10) /*!< ADC1 reset */ +#define RCU_APB2RST_TIMER0RST BIT(11) /*!< TIMER0 reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_TIMER7RST BIT(13) /*!< TIMER7 reset */ +#define RCU_APB2RST_USART0RST BIT(14) /*!< USART0 reset */ +#define RCU_APB2RST_TIMER19RST BIT(20) /*!< TIMER19 reset */ +#define RCU_APB2RST_TIMER20RST BIT(21) /*!< TIMER20 reset */ +#define RCU_APB2RST_CAN0RST BIT(30) /*!< CAN0 reset */ +#define RCU_APB2RST_CAN1RST BIT(31) /*!< CAN1 reset */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER1RST BIT(0) /*!< TIMER1 reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 reset */ +#define RCU_APB1RST_TIMER6RST BIT(5) /*!< TIMER6 reset */ +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< WWDGT reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_USART2RST BIT(18) /*!< USART2 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#define RCU_APB1RST_PMURST BIT(28) /*!< PMU reset */ +#define RCU_APB1RST_DACRST BIT(29) /*!< DAC reset */ + +/* RCU_AHBEN */ +#define RCU_AHBEN_DMA0EN BIT(0) /*!< DMA0 clock enable */ +#define RCU_AHBEN_DMA1EN BIT(1) /*!< DMA1 clock enable */ +#define RCU_AHBEN_SRAMSPEN BIT(2) /*!< SRAM clock enable when sleep mode */ +#define RCU_AHBEN_DMAMUXEN BIT(3) /*!< DMAMUX clock enable */ +#define RCU_AHBEN_FMCSPEN BIT(4) /*!< FMC clock enable when sleep mode */ +#define RCU_AHBEN_CRCEN BIT(6) /*!< CRC clock enable */ +#define RCU_AHBEN_MFCOMEN BIT(14) /*!< MFCOM clock enable */ +#define RCU_AHBEN_PAEN BIT(17) /*!< GPIOA clock enable */ +#define RCU_AHBEN_PBEN BIT(18) /*!< GPIOB clock enable */ +#define RCU_AHBEN_PCEN BIT(19) /*!< GPIOC clock enable */ +#define RCU_AHBEN_PDEN BIT(20) /*!< GPIOD clock enable */ +#define RCU_AHBEN_PEEN BIT(21) /*!< GPIOE clock enable */ +#define RCU_AHBEN_PFEN BIT(22) /*!< GPIOF clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_CFGEN BIT(0) /*!< System configuration clock enable */ +#define RCU_APB2EN_CMPEN BIT(1) /*!< Comparator clock enable */ +#define RCU_APB2EN_ADC0EN BIT(9) /*!< ADC0 clock enable */ +#define RCU_APB2EN_ADC1EN BIT(10) /*!< ADC1 clock enable */ +#define RCU_APB2EN_TIMER0EN BIT(11) /*!< TIMER0 clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_TIMER7EN BIT(13) /*!< TIMER7 clock enable */ +#define RCU_APB2EN_USART0EN BIT(14) /*!< USART0 clock enable */ +#define RCU_APB2EN_TIMER19EN BIT(20) /*!< TIMER19 clock enable */ +#define RCU_APB2EN_TIMER20EN BIT(21) /*!< TIMER20 clock enable */ +#define RCU_APB2EN_TRIGSELEN BIT(29) /*!< TRIGSEL clock enable */ +#define RCU_APB2EN_CAN0EN BIT(30) /*!< CAN0 clock enable */ +#define RCU_APB2EN_CAN1EN BIT(31) /*!< CAN1 clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER1EN BIT(0) /*!< TIMER1 clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 clock enable */ +#define RCU_APB1EN_TIMER6EN BIT(5) /*!< TIMER6 clock enable */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< WWDGT clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_USART2EN BIT(18) /*!< USART2 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#define RCU_APB1EN_BKPEN BIT(27) /*!< Back-up interface clock enable */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< PMU clock enable */ +#define RCU_APB1EN_DACEN BIT(29) /*!< DAC clock enable */ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< low speed crystal oscillator stabilization flag */ +#define RCU_BDCTL_LXTALBPS BIT(2) /*!< LXTAL bypass mode enable */ +#define RCU_BDCTL_LXTALDRI BITS(3,4) /*!< LXTAL drive capability */ +#define RCU_BDCTL_RTCSRC BITS(8,9) /*!< RTC clock entry selection */ +#define RCU_BDCTL_RTCEN BIT(15) /*!< RTC clock enable */ +#define RCU_BDCTL_BKPRST BIT(16) /*!< backup domain reset */ + +/* RCU_RSTSCK */ +#define RCU_RSTSCK_IRC40KEN BIT(0) /*!< IRC40K enable */ +#define RCU_RSTSCK_IRC40KSTB BIT(1) /*!< IRC40K stabilization flag */ +#define RCU_RSTSCK_LOCKUPRSTEN BIT(10) /*!< CPU Lock-Up reset enable */ +#define RCU_RSTSCK_LVDRSTEN BIT(11) /*!< low voltage detection reset enable */ +#define RCU_RSTSCK_ECCRSTEN BIT(12) /*!< ECC 2 bits error reset enable*/ +#define RCU_RSTSCK_LOHRSTEN BIT(13) /*!< lost of HXTAL reset enable */ +#define RCU_RSTSCK_LOPRSTEN BIT(14) /*!< lost of PLL reset enable */ +#define RCU_RSTSCK_BORRSTF BIT(17) /*!< BOR reset flag */ +#define RCU_RSTSCK_LOCKUPRSTF BIT(18) /*!< CPU Lock-Up error reset flag */ +#define RCU_RSTSCK_LVDRSTF BIT(19) /*!< low Voltage detect error reset flag */ +#define RCU_RSTSCK_ECCRSTF BIT(20) /*!< two bit ECC error reset flag */ +#define RCU_RSTSCK_LOHRSTF BIT(21) /*!< lost of HXTAL error reset flag */ +#define RCU_RSTSCK_LOPRSTF BIT(22) /*!< lost of PLL error reset flag */ +#define RCU_RSTSCK_V11RSTF BIT(23) /*!< 1.1V domain power reset flag */ +#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */ +#define RCU_RSTSCK_OBLRSTF BIT(25) /*!< option byte loader reset flag */ +#define RCU_RSTSCK_EPRSTF BIT(26) /*!< external pin reset flag */ +#define RCU_RSTSCK_PORRSTF BIT(27) /*!< power reset flag */ +#define RCU_RSTSCK_SWRSTF BIT(28) /*!< software reset flag */ +#define RCU_RSTSCK_FWDGTRSTF BIT(29) /*!< free watchdog timer reset flag */ +#define RCU_RSTSCK_WWDGTRSTF BIT(30) /*!< window watchdog timer reset flag */ +#define RCU_RSTSCK_LPRSTF BIT(31) /*!< low-power reset flag */ + +/* RCU_AHBRST */ +#define RCU_AHBRST_DMA0RST BIT(0) /*!< DMA0 reset */ +#define RCU_AHBRST_DMA1RST BIT(1) /*!< DMA1 reset */ +#define RCU_AHBRST_DMAMUXRST BIT(3) /*!< DMAMUX reset */ +#define RCU_AHBRST_CRCRST BIT(6) /*!< CRC reset */ +#define RCU_AHBRST_MFCOMRST BIT(14) /*!< MFCOM reset */ +#define RCU_AHBRST_PARST BIT(17) /*!< GPIO port A reset */ +#define RCU_AHBRST_PBRST BIT(18) /*!< GPIO port B reset */ +#define RCU_AHBRST_PCRST BIT(19) /*!< GPIO port C reset */ +#define RCU_AHBRST_PDRST BIT(20) /*!< GPIO port D reset */ +#define RCU_AHBRST_PERST BIT(21) /*!< GPIO port E reset */ +#define RCU_AHBRST_PFRST BIT(22) /*!< GPIO port F reset */ + +/* RCU_CFG1 */ +#define RCU_CFG1_PREDV BITS(0,3) /*!< CK_HXTAL divider previous PLL */ + +/* RCU_CFG2 */ +#define RCU_CFG2_USART0SEL BITS(0,1) /*!< USART0 clock source selection */ +#define RCU_CFG2_USART1SEL BITS(4,5) /*!< USART1 clock source selection */ +#define RCU_CFG2_USART2SEL BITS(6,7) /*!< USART2 clock source selection */ +#define RCU_CFG2_CAN0SEL BITS(12,13) /*!< CAN0 clock source selection */ +#define RCU_CFG2_CAN1SEL BITS(14,15) /*!< CAN1 clock source selection */ +#define RCU_CFG2_ADCPSC BITS(27,31) /*!< ADC prescaler selection */ + +/* RCU_VKEY */ +#define RCU_VKEY_UNLOCK 0x1A2B3C4DU /*!< the key of RCU_DSV register */ +/* RCU_VKEY */ +#define RCU_VKEY_KEY BITS(0,31) +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,1) /*!< Deep-sleep mode voltage selection */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph) >> 6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) + +/* register offset */ +/* peripherals enable */ +#define AHBEN_REG_OFFSET 0x00000014U /*!< AHB enable register offset */ +#define APB1EN_REG_OFFSET 0x0000001CU /*!< APB1 enable register offset */ +#define APB2EN_REG_OFFSET 0x00000018U /*!< APB2 enable register offset */ + +/* peripherals reset */ +#define AHBRST_REG_OFFSET 0x00000028U /*!< AHB reset register offset */ +#define APB1RST_REG_OFFSET 0x00000010U /*!< APB1 reset register offset */ +#define APB2RST_REG_OFFSET 0x0000000CU /*!< APB2 reset register offset */ +#define RSTSCK_REG_OFFSET 0x00000024U /*!< reset source/clock register offset */ + +/* clock control */ +#define CTL_REG_OFFSET 0x00000000U /*!< control register offset */ +#define BDCTL_REG_OFFSET 0x00000020U /*!< backup domain control register offset */ + +/* clock stabilization and stuck interrupt */ +#define INT_REG_OFFSET 0x00000008U /*!< clock interrupt register offset */ + +/* configuration register */ +#define CFG0_REG_OFFSET 0x00000004U /*!< clock configuration register 0 offset */ +#define CFG1_REG_OFFSET 0x0000002CU /*!< clock configuration register 1 offset */ + +/* peripheral clock enable */ +typedef enum { + /* AHB peripherals */ + RCU_DMA0 = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 0U), /*!< DMA0 clock */ + RCU_DMA1 = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 1U), /*!< DMA1 clock */ + RCU_DMAMUX = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 3U), /*!< DMAMUX clock */ + RCU_CRC = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 6U), /*!< CRC clock */ + RCU_MFCOM = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 14U), /*!< MFCOM clock */ + RCU_GPIOA = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 17U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 18U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 19U), /*!< GPIOC clock */ + RCU_GPIOD = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 20U), /*!< GPIOD clock */ + RCU_GPIOE = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 21U), /*!< GPIOE clock */ + RCU_GPIOF = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 22U), /*!< GPIOF clock */ + /* APB2 peripherals */ + RCU_SYSCFG = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 0U), /*!< SYSCFG clock */ + RCU_CMP = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 1U), /*!< CMP clock */ + RCU_ADC0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 9U), /*!< ADC0 clock */ + RCU_ADC1 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 10U), /*!< ADC1 clock */ + RCU_TIMER0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 11U), /*!< TIMER0 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 12U), /*!< SPI0 clock */ + RCU_TIMER7 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 13U), /*!< TIMER7 clock */ + RCU_USART0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 14U), /*!< USART0 clock */ + RCU_TIMER19 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 20U), /*!< TIMER19 clock */ + RCU_TIMER20 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 21U), /*!< TIMER20 clock */ + RCU_TRIGSEL = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 29U), /*!< TRIGSEL clock */ + RCU_CAN0 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 30U), /*!< CAN0 clock */ + RCU_CAN1 = RCU_REGIDX_BIT(APB2EN_REG_OFFSET, 31U), /*!< CAN1 clock */ + /* APB1 peripherals */ + RCU_TIMER1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 0U), /*!< TIMER1 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 4U), /*!< TIMER5 clock */ + RCU_TIMER6 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 5U), /*!< TIMER6 clock */ + RCU_WWDGT = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 14U), /*!< SPI1 clock */ + RCU_USART1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 17U), /*!< USART1 clock */ + RCU_USART2 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 18U), /*!< USART2 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 22U), /*!< I2C1 clock */ + RCU_BKP = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 27U), /*!< BKP clock */ + RCU_PMU = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 28U), /*!< PMU clock */ + RCU_DAC = RCU_REGIDX_BIT(APB1EN_REG_OFFSET, 29U), /*!< DAC clock */ + RCU_RTC = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 15U), /*!< RTC clock */ +} rcu_periph_enum; + + +/* peripherals reset */ +typedef enum { + /* AHB peripherals */ + RCU_DMA0RST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 0U), /*!< DMA0 clock reset */ + RCU_DMA1RST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 1U), /*!< DMA1 clock reset */ + RCU_DMAMUXRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 3U), /*!< DMAMUX clock reset */ + RCU_CRCRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 6U), /*!< CRC clock reset */ + RCU_MFCOMRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 14U), /*!< MFCOM clock reset */ + RCU_GPIOARST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 17U), /*!< GPIOA clock reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 18U), /*!< GPIOB clock reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 19U), /*!< GPIOC clock reset */ + RCU_GPIODRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 20U), /*!< GPIOD clock reset */ + RCU_GPIOERST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 21U), /*!< GPIOE clock reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(AHBRST_REG_OFFSET, 22U), /*!< GPIOF clock reset */ + /* APB2 peripherals */ + RCU_SYSCFGRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 0U), /*!< system configuration reset */ + RCU_CMPRST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 1U), /*!< Comparator reset */ + RCU_ADC0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 9U), /*!< ADC0 clock reset */ + RCU_ADC1RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 10U), /*!< ADC1 clock reset */ + RCU_TIMER0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 11U), /*!< TIMER0 clock reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 12U), /*!< SPI0 clock reset */ + RCU_TIMER7RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 13U), /*!< TIMER7 clock reset */ + RCU_USART0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 14U), /*!< USART0 clock reset */ + RCU_TIMER19RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 20U), /*!< TIMER19 clock reset */ + RCU_TIMER20RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 21U), /*!< TIMER20 clock reset */ + RCU_CAN0RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 30U), /*!< CAN0 clock reset */ + RCU_CAN1RST = RCU_REGIDX_BIT(APB2RST_REG_OFFSET, 31U), /*!< CAN1 clock reset */ + /* APB1 peripherals */ + RCU_TIMER1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 0U), /*!< TIMER1 clock reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 4U), /*!< TIMER5 clock reset */ + RCU_TIMER6RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 5U), /*!< TIMER6 clock reset */ + RCU_WWDGTRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 11U), /*!< WWDGT clock reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 14U), /*!< SPI1 clock reset */ + RCU_USART1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 17U), /*!< USART1 clock reset */ + RCU_USART2RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 18U), /*!< USART2 clock reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 21U), /*!< I2C0 clock reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 22U), /*!< I2C1 clock reset */ + RCU_PMURST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 28U), /*!< PMU clock reset */ + RCU_DACRST = RCU_REGIDX_BIT(APB1RST_REG_OFFSET, 29U), /*!< DAC clock reset */ +} rcu_periph_reset_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum { + /* AHB peripherals */ + RCU_SRAM_SLP = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 2U), /*!< SRAM clock */ + RCU_FMC_SLP = RCU_REGIDX_BIT(AHBEN_REG_OFFSET, 4U), /*!< FMC clock */ +} rcu_periph_sleep_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum { + /* clock stabilization flags */ + RCU_FLAG_IRC8MSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 1U), /*!< IRC8M stabilization flag */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 17U), /*!< HXTAL stabilization flag */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(CTL_REG_OFFSET, 25U), /*!< PLL stabilization flag */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 1U), /*!< LXTAL stabilization flag */ + /* reset source flags */ + RCU_FLAG_IRC40KSTB = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 1U), /*!< IRC40K stabilization flag */ + RCU_FLAG_BORRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 17U), /*!< BOR reset flag */ + RCU_FLAG_LOCKUPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 18U), /*!< CPU LOCK UP error reset flag */ + RCU_FLAG_LVDRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 19U), /*!< low voltage detect error reset flag */ + RCU_FLAG_ECCRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 20U), /*!< 2 bits ECC error reset flag */ + RCU_FLAG_LOHRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 21U), /*!< lost of HXTAL error reset flag */ + RCU_FLAG_LOPRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 22U), /*!< lost of PLL error reset flag */ + RCU_FLAG_V11RST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 23U), /*!< 1.1V domain Power reset flag */ + RCU_FLAG_OBLRST = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 25U), /*!< 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), /*!< software 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 */ +} rcu_flag_enum; + +/* clock stabilization and ckm interrupt flags */ +typedef enum { + RCU_INT_FLAG_IRC40KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 0U), /*!< IRC40K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 1U), /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC8MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 2U), /*!< IRC8M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 4U), /*!< PLL stabilization interrupt flag */ + RCU_INT_FLAG_LCKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 5U), /*!< LXTAL clock monitor interrupt flag */ + RCU_INT_FLAG_PLLM = RCU_REGIDX_BIT(INT_REG_OFFSET, 6U), /*!< PLL clock monitor interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 7U), /*!< HXTAL clock stuck interrupt flag */ +} rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum { + RCU_INT_FLAG_IRC40KSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 16U), /*!< IRC40K stabilization interrupt flag clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 17U), /*!< LXTAL stabilization interrupt flag clear */ + RCU_INT_FLAG_IRC8MSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 18U), /*!< IRC8M stabilization interrupt flag clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 19U), /*!< HXTAL stabilization interrupt flag clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 20U), /*!< PLL stabilization interrupt flag clear */ + RCU_INT_FLAG_LCKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 21U), /*!< LXTAL clock monitor interrupt clear */ + RCU_INT_FLAG_PLLM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 22U), /*!< PLL clock monitor interrupt clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(INT_REG_OFFSET, 23U), /*!< CKM interrupt flag clear */ +} rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum { + RCU_INT_IRC40KSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 8U), /*!< IRC40K stabilization interrupt enable */ + RCU_INT_LXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 9U), /*!< LXTAL stabilization interrupt enable */ + RCU_INT_IRC8MSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 10U), /*!< IRC8M stabilization interrupt enable */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 11U), /*!< HXTAL stabilization interrupt enable */ + RCU_INT_PLLSTB = RCU_REGIDX_BIT(INT_REG_OFFSET, 12U), /*!< PLL stabilization interrupt enable */ + RCU_INT_LCKM = RCU_REGIDX_BIT(INT_REG_OFFSET, 13U), /*!< LXTAL clock monitor interrupt enable */ + RCU_INT_PLLM = RCU_REGIDX_BIT(INT_REG_OFFSET, 14U), /*!< PLL clock monitor interrupt enable */ +} rcu_int_enum; + +/* oscillator types */ +typedef enum { + RCU_HXTAL = RCU_REGIDX_BIT(CTL_REG_OFFSET, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(BDCTL_REG_OFFSET, 0U), /*!< LXTAL */ + RCU_IRC8M = RCU_REGIDX_BIT(CTL_REG_OFFSET, 0U), /*!< IRC8M */ + RCU_IRC40K = RCU_REGIDX_BIT(RSTSCK_REG_OFFSET, 0U), /*!< IRC40K */ + RCU_PLL_CK = RCU_REGIDX_BIT(CTL_REG_OFFSET, 24U), /*!< PLL */ +} rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum { + CK_SYS = 0, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB1, /*!< APB1 clock */ + CK_APB2, /*!< APB2 clock */ + CK_USART0, /*!< USART0 clock */ + CK_USART1, /*!< USART1 clock */ + CK_USART2, /*!< USART2 clock */ +} rcu_clock_freq_enum; + +/* HXTAL frequency scale select */ +#define HXTAL_SCALE_2M_TO_8M 0x00000000U /*!< HXTAL scale is 2M-8MHz */ +#define HXTAL_SCALE_8M_TO_40M RCU_CTL_HXTALSCAL /*!< HXTAL scale is 8M-40MHz */ + +/* RCU_CFG0 register bit define */ +/* system clock source select */ +#define CFG0_SCS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_CKSYSSRC_IRC8M CFG0_SCS(0) /*!< system clock source select IRC8M */ +#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */ +#define RCU_CKSYSSRC_PLL CFG0_SCS(2) /*!< system clock source select PLL */ + +/* system clock source select status */ +#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define RCU_SCSS_IRC8M CFG0_SCSS(0) /*!< system clock source select IRC8M */ +#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select HXTAL */ +#define RCU_SCSS_PLL CFG0_SCSS(2) /*!< system clock source select PLL */ + +/* AHB prescaler selection */ +#define CFG0_AHBPSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define RCU_AHB_CKSYS_DIV1 CFG0_AHBPSC(0) /*!< AHB prescaler select CK_SYS */ +#define RCU_AHB_CKSYS_DIV2 CFG0_AHBPSC(8) /*!< AHB prescaler select CK_SYS/2 */ +#define RCU_AHB_CKSYS_DIV4 CFG0_AHBPSC(9) /*!< AHB prescaler select CK_SYS/4 */ +#define RCU_AHB_CKSYS_DIV8 CFG0_AHBPSC(10) /*!< AHB prescaler select CK_SYS/8 */ +#define RCU_AHB_CKSYS_DIV16 CFG0_AHBPSC(11) /*!< AHB prescaler select CK_SYS/16 */ +#define RCU_AHB_CKSYS_DIV64 CFG0_AHBPSC(12) /*!< AHB prescaler select CK_SYS/64 */ +#define RCU_AHB_CKSYS_DIV128 CFG0_AHBPSC(13) /*!< AHB prescaler select CK_SYS/128 */ +#define RCU_AHB_CKSYS_DIV256 CFG0_AHBPSC(14) /*!< AHB prescaler select CK_SYS/256 */ +#define RCU_AHB_CKSYS_DIV512 CFG0_AHBPSC(15) /*!< AHB prescaler select CK_SYS/512 */ + +/* APB1 prescaler selection */ +#define CFG0_APB1PSC(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) +#define RCU_APB1_CKAHB_DIV1 CFG0_APB1PSC(0) /*!< APB1 prescaler select CK_AHB */ +#define RCU_APB1_CKAHB_DIV2 CFG0_APB1PSC(4) /*!< APB1 prescaler select CK_AHB/2 */ +#define RCU_APB1_CKAHB_DIV4 CFG0_APB1PSC(5) /*!< APB1 prescaler select CK_AHB/4 */ +#define RCU_APB1_CKAHB_DIV8 CFG0_APB1PSC(6) /*!< APB1 prescaler select CK_AHB/8 */ +#define RCU_APB1_CKAHB_DIV16 CFG0_APB1PSC(7) /*!< APB1 prescaler select CK_AHB/16 */ + +/* APB2 prescaler selection */ +#define CFG0_APB2PSC(regval) (BITS(11,13) & ((uint32_t)(regval) << 11)) +#define RCU_APB2_CKAHB_DIV1 CFG0_APB2PSC(0) /*!< APB2 prescaler select CK_AHB */ +#define RCU_APB2_CKAHB_DIV2 CFG0_APB2PSC(4) /*!< APB2 prescaler select CK_AHB/2 */ +#define RCU_APB2_CKAHB_DIV4 CFG0_APB2PSC(5) /*!< APB2 prescaler select CK_AHB/4 */ +#define RCU_APB2_CKAHB_DIV8 CFG0_APB2PSC(6) /*!< APB2 prescaler select CK_AHB/8 */ +#define RCU_APB2_CKAHB_DIV16 CFG0_APB2PSC(7) /*!< APB2 prescaler select CK_AHB/16 */ + +/* RCU system reset */ +#define RCU_SYSRST_LOCKUP RCU_RSTSCK_LOCKUPRSTEN /*!< CPU lock-up reset */ +#define RCU_SYSRST_LVD RCU_RSTSCK_LVDRSTEN /*!< low voltage detect reset */ +#define RCU_SYSRST_ECC RCU_RSTSCK_ECCRSTEN /*!< ECC 2 bits error reset */ +#define RCU_SYSRST_LOH RCU_RSTSCK_LOHRSTEN /*!< lost of HXTAL error reset */ +#define RCU_SYSRST_LOP RCU_RSTSCK_LOPRSTEN /*!< lost of PLL reset */ + +/* ADC prescaler select */ +#define CFG2_ADCPSC(regval) (BITS(27,31) & ((uint32_t)(regval) << 27)) +#define RCU_CKADC_CKAHB_DIV2 CFG2_ADCPSC(0) /*!< ADC prescaler select CK_AHB/2 */ +#define RCU_CKADC_CKAHB_DIV3 CFG2_ADCPSC(1) /*!< ADC prescaler select CK_AHB/3 */ +#define RCU_CKADC_CKAHB_DIV4 CFG2_ADCPSC(2) /*!< ADC prescaler select CK_AHB/4 */ +#define RCU_CKADC_CKAHB_DIV5 CFG2_ADCPSC(3) /*!< ADC prescaler select CK_AHB/5 */ +#define RCU_CKADC_CKAHB_DIV6 CFG2_ADCPSC(4) /*!< ADC prescaler select CK_AHB/6 */ +#define RCU_CKADC_CKAHB_DIV7 CFG2_ADCPSC(5) /*!< ADC prescaler select CK_AHB/7 */ +#define RCU_CKADC_CKAHB_DIV8 CFG2_ADCPSC(6) /*!< ADC prescaler select CK_AHB/8 */ +#define RCU_CKADC_CKAHB_DIV9 CFG2_ADCPSC(7) /*!< ADC prescaler select CK_AHB/9 */ +#define RCU_CKADC_CKAHB_DIV10 CFG2_ADCPSC(8) /*!< ADC prescaler select CK_AHB/10 */ +#define RCU_CKADC_CKAHB_DIV11 CFG2_ADCPSC(9) /*!< ADC prescaler select CK_AHB/11 */ +#define RCU_CKADC_CKAHB_DIV12 CFG2_ADCPSC(10) /*!< ADC prescaler select CK_AHB/12 */ +#define RCU_CKADC_CKAHB_DIV13 CFG2_ADCPSC(11) /*!< ADC prescaler select CK_AHB/13 */ +#define RCU_CKADC_CKAHB_DIV14 CFG2_ADCPSC(12) /*!< ADC prescaler select CK_AHB/14 */ +#define RCU_CKADC_CKAHB_DIV15 CFG2_ADCPSC(13) /*!< ADC prescaler select CK_AHB/15 */ +#define RCU_CKADC_CKAHB_DIV16 CFG2_ADCPSC(14) /*!< ADC prescaler select CK_AHB/16 */ +#define RCU_CKADC_CKAHB_DIV17 CFG2_ADCPSC(15) /*!< ADC prescaler select CK_AHB/17 */ +#define RCU_CKADC_CKAHB_DIV18 CFG2_ADCPSC(16) /*!< ADC prescaler select CK_AHB/18 */ +#define RCU_CKADC_CKAHB_DIV19 CFG2_ADCPSC(17) /*!< ADC prescaler select CK_AHB/19 */ +#define RCU_CKADC_CKAHB_DIV20 CFG2_ADCPSC(18) /*!< ADC prescaler select CK_AHB/20 */ +#define RCU_CKADC_CKAHB_DIV21 CFG2_ADCPSC(19) /*!< ADC prescaler select CK_AHB/21 */ +#define RCU_CKADC_CKAHB_DIV22 CFG2_ADCPSC(20) /*!< ADC prescaler select CK_AHB/22 */ +#define RCU_CKADC_CKAHB_DIV23 CFG2_ADCPSC(21) /*!< ADC prescaler select CK_AHB/23 */ +#define RCU_CKADC_CKAHB_DIV24 CFG2_ADCPSC(22) /*!< ADC prescaler select CK_AHB/24 */ +#define RCU_CKADC_CKAHB_DIV25 CFG2_ADCPSC(23) /*!< ADC prescaler select CK_AHB/25 */ +#define RCU_CKADC_CKAHB_DIV26 CFG2_ADCPSC(24) /*!< ADC prescaler select CK_AHB/26 */ +#define RCU_CKADC_CKAHB_DIV27 CFG2_ADCPSC(25) /*!< ADC prescaler select CK_AHB/27 */ +#define RCU_CKADC_CKAHB_DIV28 CFG2_ADCPSC(26) /*!< ADC prescaler select CK_AHB/28 */ +#define RCU_CKADC_CKAHB_DIV29 CFG2_ADCPSC(27) /*!< ADC prescaler select CK_AHB/29 */ +#define RCU_CKADC_CKAHB_DIV30 CFG2_ADCPSC(28) /*!< ADC prescaler select CK_AHB/30 */ +#define RCU_CKADC_CKAHB_DIV31 CFG2_ADCPSC(29) /*!< ADC prescaler select CK_AHB/31 */ +#define RCU_CKADC_CKAHB_DIV32 CFG2_ADCPSC(30) /*!< ADC prescaler select CK_AHB/32 */ + +/* PLL clock source selection */ +#define RCU_PLLSRC_IRC8M_DIV2 ((uint32_t)0x00000000U) /*!< IRC8M/2 clock is selected as clock source of PLL */ +#define RCU_PLLSRC_HXTAL RCU_CFG0_PLLSEL /*!< HXTAL is selected as clock source of PLL */ + +/* PLL clock multiplication factor */ +#define PLLMF_4 RCU_CFG0_PLLMF_4 /*!< bit 4 of PLLMF */ +#define CFG0_PLLMF(regval) (BITS(18,21) & ((uint32_t)(regval) << 18)) +#define RCU_PLL_MUL2 CFG0_PLLMF(0) /*!< PLL clock source multiply by 2 */ +#define RCU_PLL_MUL3 CFG0_PLLMF(1) /*!< PLL clock source multiply by 3 */ +#define RCU_PLL_MUL4 CFG0_PLLMF(2) /*!< PLL clock source multiply by 4 */ +#define RCU_PLL_MUL5 CFG0_PLLMF(3) /*!< PLL clock source multiply by 5 */ +#define RCU_PLL_MUL6 CFG0_PLLMF(4) /*!< PLL clock source multiply by 6 */ +#define RCU_PLL_MUL7 CFG0_PLLMF(5) /*!< PLL clock source multiply by 7 */ +#define RCU_PLL_MUL8 CFG0_PLLMF(6) /*!< PLL clock source multiply by 8 */ +#define RCU_PLL_MUL9 CFG0_PLLMF(7) /*!< PLL clock source multiply by 9 */ +#define RCU_PLL_MUL10 CFG0_PLLMF(8) /*!< PLL clock source multiply by 10 */ +#define RCU_PLL_MUL11 CFG0_PLLMF(9) /*!< PLL clock source multiply by 11 */ +#define RCU_PLL_MUL12 CFG0_PLLMF(10) /*!< PLL clock source multiply by 12 */ +#define RCU_PLL_MUL13 CFG0_PLLMF(11) /*!< PLL clock source multiply by 13 */ +#define RCU_PLL_MUL14 CFG0_PLLMF(12) /*!< PLL clock source multiply by 14 */ +#define RCU_PLL_MUL15 CFG0_PLLMF(13) /*!< PLL clock source multiply by 15 */ +#define RCU_PLL_MUL16 CFG0_PLLMF(14) /*!< PLL clock source multiply by 16 */ +#define RCU_PLL_MUL17 (PLLMF_4 | CFG0_PLLMF(0)) /*!< PLL clock source multiply by 17 */ +#define RCU_PLL_MUL18 (PLLMF_4 | CFG0_PLLMF(1)) /*!< PLL clock source multiply by 18 */ +#define RCU_PLL_MUL19 (PLLMF_4 | CFG0_PLLMF(2)) /*!< PLL clock source multiply by 19 */ +#define RCU_PLL_MUL20 (PLLMF_4 | CFG0_PLLMF(3)) /*!< PLL clock source multiply by 20 */ +#define RCU_PLL_MUL21 (PLLMF_4 | CFG0_PLLMF(4)) /*!< PLL clock source multiply by 21 */ +#define RCU_PLL_MUL22 (PLLMF_4 | CFG0_PLLMF(5)) /*!< PLL clock source multiply by 22 */ +#define RCU_PLL_MUL23 (PLLMF_4 | CFG0_PLLMF(6)) /*!< PLL clock source multiply by 23 */ +#define RCU_PLL_MUL24 (PLLMF_4 | CFG0_PLLMF(7)) /*!< PLL clock source multiply by 24 */ +#define RCU_PLL_MUL25 (PLLMF_4 | CFG0_PLLMF(8)) /*!< PLL clock source multiply by 25 */ +#define RCU_PLL_MUL26 (PLLMF_4 | CFG0_PLLMF(9)) /*!< PLL clock source multiply by 26 */ +#define RCU_PLL_MUL27 (PLLMF_4 | CFG0_PLLMF(10)) /*!< PLL clock source multiply by 27 */ +#define RCU_PLL_MUL28 (PLLMF_4 | CFG0_PLLMF(11)) /*!< PLL clock source multiply by 28 */ +#define RCU_PLL_MUL29 (PLLMF_4 | CFG0_PLLMF(12)) /*!< PLL clock source multiply by 29 */ +#define RCU_PLL_MUL30 (PLLMF_4 | CFG0_PLLMF(13)) /*!< PLL clock source multiply by 30 */ +#define RCU_PLL_MUL31 (PLLMF_4 | CFG0_PLLMF(14)) /*!< PLL clock source multiply by 31 */ + +/* CKOUT Clock source selection */ +#define CFG0_CKOUTSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUTSRC_NONE CFG0_CKOUTSEL(0) /*!< no clock is selected */ +#define RCU_CKOUTSRC_IRC40K CFG0_CKOUTSEL(2) /*!< IRC40K is selected as CK_OUT clock source */ +#define RCU_CKOUTSRC_LXTAL CFG0_CKOUTSEL(3) /*!< LXTAL is selected as CK_OUT clock source */ +#define RCU_CKOUTSRC_CKSYS CFG0_CKOUTSEL(4) /*!< system clock is selected as CK_OUT clock source */ +#define RCU_CKOUTSRC_IRC8M CFG0_CKOUTSEL(5) /*!< IRC8M is selected as CK_OUT clock source */ +#define RCU_CKOUTSRC_HXTAL CFG0_CKOUTSEL(6) /*!< HXTAL is selected as CK_OUT clock source */ +#define RCU_CKOUTSRC_CKPLL_DIV1 (RCU_CFG0_PLLDV | CFG0_CKOUTSEL(7)) /*!< CK_PLL is selected as CK_OUT clock source */ +#define RCU_CKOUTSRC_CKPLL_DIV2 CFG0_CKOUTSEL(7) /*!< CK_PLL/2 is selected as CK_OUT clock source */ + +/* CK_OUT divider */ +#define CFG0_CKOUTDIV(regval) (BITS(28,30) & ((uint32_t)(regval) << 28)) +#define RCU_CKOUT_DIV1 CFG0_CKOUTDIV(0) /*!< CK_OUT is divided by 1 */ +#define RCU_CKOUT_DIV2 CFG0_CKOUTDIV(1) /*!< CK_OUT is divided by 2 */ +#define RCU_CKOUT_DIV4 CFG0_CKOUTDIV(2) /*!< CK_OUT is divided by 4 */ +#define RCU_CKOUT_DIV8 CFG0_CKOUTDIV(3) /*!< CK_OUT is divided by 8 */ +#define RCU_CKOUT_DIV16 CFG0_CKOUTDIV(4) /*!< CK_OUT is divided by 16 */ +#define RCU_CKOUT_DIV32 CFG0_CKOUTDIV(5) /*!< CK_OUT is divided by 32 */ +#define RCU_CKOUT_DIV64 CFG0_CKOUTDIV(6) /*!< CK_OUT is divided by 64 */ +#define RCU_CKOUT_DIV128 CFG0_CKOUTDIV(7) /*!< CK_OUT is divided by 128 */ + +/* LXTAL drive capability */ +#define BDCTL_LXTALDRI(regval) (BITS(3,4) & ((uint32_t)(regval) << 3)) +#define RCU_LXTAL_LOWDRI BDCTL_LXTALDRI(0) /*!< lower driving capability */ +#define RCU_LXTAL_MED_LOWDRI BDCTL_LXTALDRI(1) /*!< medium low driving capability */ +#define RCU_LXTAL_MED_HIGHDRI BDCTL_LXTALDRI(2) /*!< medium high driving capability */ +#define RCU_LXTAL_HIGHDRI BDCTL_LXTALDRI(3) /*!< higher driving capability */ + +/* RTC clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define RCU_RTCSRC_NONE BDCTL_RTCSRC(0) /*!< no clock is selected */ +#define RCU_RTCSRC_LXTAL BDCTL_RTCSRC(1) /*!< LXTAL is selected as RTC clock source */ +#define RCU_RTCSRC_IRC40K BDCTL_RTCSRC(2) /*!< IRC40K is selected as RTC clock source */ +#define RCU_RTCSRC_HXTAL_DIV_128 BDCTL_RTCSRC(3) /*!< HXTAL/128 is selected as RTC clock source */ + +/* PREDV0 division factor */ +#define CFG1_PREDV(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define RCU_PREDV_DIV1 CFG1_PREDV(0) /*!< PREDV input clock source not divided */ +#define RCU_PREDV_DIV2 CFG1_PREDV(1) /*!< PREDV input clock source divided by 2 */ +#define RCU_PREDV_DIV3 CFG1_PREDV(2) /*!< PREDV input clock source divided by 3 */ +#define RCU_PREDV_DIV4 CFG1_PREDV(3) /*!< PREDV input clock source divided by 4 */ +#define RCU_PREDV_DIV5 CFG1_PREDV(4) /*!< PREDV input clock source divided by 5 */ +#define RCU_PREDV_DIV6 CFG1_PREDV(5) /*!< PREDV input clock source divided by 6 */ +#define RCU_PREDV_DIV7 CFG1_PREDV(6) /*!< PREDV input clock source divided by 7 */ +#define RCU_PREDV_DIV8 CFG1_PREDV(7) /*!< PREDV input clock source divided by 8 */ +#define RCU_PREDV_DIV9 CFG1_PREDV(8) /*!< PREDV input clock source divided by 9 */ +#define RCU_PREDV_DIV10 CFG1_PREDV(9) /*!< PREDV input clock source divided by 10 */ +#define RCU_PREDV_DIV11 CFG1_PREDV(10) /*!< PREDV input clock source divided by 11 */ +#define RCU_PREDV_DIV12 CFG1_PREDV(11) /*!< PREDV input clock source divided by 12 */ +#define RCU_PREDV_DIV13 CFG1_PREDV(12) /*!< PREDV input clock source divided by 13 */ +#define RCU_PREDV_DIV14 CFG1_PREDV(13) /*!< PREDV input clock source divided by 14 */ +#define RCU_PREDV_DIV15 CFG1_PREDV(14) /*!< PREDV input clock source divided by 15 */ +#define RCU_PREDV_DIV16 CFG1_PREDV(15) /*!< PREDV input clock source divided by 16 */ + +/* deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_0_8 DSV_DSLPVS(0) /*!< core voltage is 0.8V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(1) /*!< core voltage is 0.9V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(2) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_1 DSV_DSLPVS(3) /*!< core voltage is 1.1V in deep-sleep mode */ + +/* USART clock source selection */ +#define CFG2_USART0SRC(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_USARTSRC_HXTAL CFG2_USART0SRC(0) /*!< CK_HXTAL is selected as USART clock source */ +#define RCU_USARTSRC_CKSYS CFG2_USART0SRC(1) /*!< CK_SYS is selected as USART clock source */ +#define RCU_USARTSRC_LXTAL CFG2_USART0SRC(2) /*!< CK_LXTAL is selected as USART clock source */ +#define RCU_USARTSRC_IRC8M CFG2_USART0SRC(3) /*!< CK_IRC8M is selected as USART clock source */ + +/* CAN clock source selection */ +#define CFG2_CAN0SRC(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define RCU_CANSRC_HXTAL CFG2_CAN0SRC(0) /*!< CK_HXTAL is selected as CAN clock source */ +#define RCU_CANSRC_PCLK2 CFG2_CAN0SRC(1) /*!< PCLK2 is selected as CAN clock source */ +#define RCU_CANSRC_PCLK2_DIV_2 CFG2_CAN0SRC(2) /*!< PCLK2/2 is selected as CAN clock source */ +#define RCU_CANSRC_IRC8M CFG2_CAN0SRC(3) /*!< CK_IRC8M is selected as CAN clock source */ + + +/* function declarations */ +/* peripherals clock configure functions */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* 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); +/* enable the peripherals clock when in sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when in sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the BKP domain control register */ +void rcu_bkp_reset_enable(void); +/* disable the BKP domain control register reset */ +void rcu_bkp_reset_disable(void); + +/* system and peripherals clock source, system reset configure functions */ +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB1 prescaler selection */ +void rcu_apb1_clock_config(uint32_t ck_apb1); +/* configure the APB2 prescaler selection */ +void rcu_apb2_clock_config(uint32_t ck_apb2); +/* configure the CK_OUT clock source and divider */ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div); +/* configure the PLL clock source selection and PLL multiply factor */ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul); +/* enable double PLL clock */ +void rcu_double_pll_enable(void); +/* disable double PLL clock */ +void rcu_double_pll_disable(void); +/* enable RCU system reset */ +void rcu_system_reset_enable(uint32_t reset_source); +/* disable RCU system reset */ +void rcu_system_reset_disable(uint32_t reset_source); +/* configure the ADC division factor */ +void rcu_adc_clock_config(uint32_t adc_psc); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +/* configure the USART clock source selection */ +void rcu_usart_clock_config(uint32_t usart_periph, uint32_t usart_clock_source); +/* configure the CAN clock source selection */ +void rcu_can_clock_config(uint32_t can_periph, uint32_t can_clock_source); + +/* LXTAL, IRC8M, PLL and other oscillator configure functions */ +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); +/* wait for oscillator stabilization flags is SET or oscillator startup is timeout */ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci); +/* turn on the oscillator */ +void rcu_osci_on(rcu_osci_type_enum osci); +/* turn off the oscillator */ +void rcu_osci_off(rcu_osci_type_enum osci); +/* enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* configure the HXTAL frequency scale select */ +void rcu_hxtal_frequency_scale_select(uint32_t hxtal_scal); +/* configure the HXTAL divider used as input of PLL */ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv); +/* set the IRC8M adjust value */ +void rcu_irc8m_adjust_value_set(uint32_t irc8m_adjval); + +/* clock monitor configure functions */ +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); +/* enable the LXTAL clock monitor */ +void rcu_lxtal_clock_monitor_enable(void); +/* disable the LXTAL clock monitor */ +void rcu_lxtal_clock_monitor_disable(void); +/* enable the PLL clock monitor */ +void rcu_pll_clock_monitor_enable(void); +/* disable the PLL clock monitor */ +void rcu_pll_clock_monitor_disable(void); + +/* voltage configure and clock frequency get functions */ +/* unlock the voltage key */ +void rcu_voltage_key_unlock(void); +/* set the deep sleep mode voltage */ +void rcu_deepsleep_voltage_set(uint32_t dsvol); +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +/* flag & interrupt functions */ +/* get the clock stabilization and peripheral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum interrupt); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum interrupt); +#endif /* GD32A50X_RCU_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_rtc.h b/gd32a50x/standard_peripheral/include/gd32a50x_rtc.h new file mode 100644 index 0000000..a7a9789 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_rtc.h @@ -0,0 +1,142 @@ +/*! + \file gd32a50x_rtc.h + \brief definitions for the RTC + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_RTC_H +#define GD32A50X_RTC_H + +#include "gd32a50x.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_INTEN REG32(RTC + 0x00U) /*!< interrupt enable register */ +#define RTC_CTL REG32(RTC + 0x04U) /*!< control register */ +#define RTC_PSCH REG32(RTC + 0x08U) /*!< prescaler high register */ +#define RTC_PSCL REG32(RTC + 0x0CU) /*!< prescaler low register */ +#define RTC_DIVH REG32(RTC + 0x10U) /*!< divider high register */ +#define RTC_DIVL REG32(RTC + 0x14U) /*!< divider low register */ +#define RTC_CNTH REG32(RTC + 0x18U) /*!< counter high register */ +#define RTC_CNTL REG32(RTC + 0x1CU) /*!< counter low register */ +#define RTC_ALRMH REG32(RTC + 0x20U) /*!< alarm high register */ +#define RTC_ALRML REG32(RTC + 0x24U) /*!< alarm low register */ + +/* bits definitions */ +/* RTC_INTEN */ +#define RTC_INTEN_SCIE BIT(0) /*!< second interrupt enable */ +#define RTC_INTEN_ALRMIE BIT(1) /*!< alarm interrupt enable */ +#define RTC_INTEN_OVIE BIT(2) /*!< overflow interrupt enable */ + +/* RTC_CTL */ +#define RTC_CTL_SCIF BIT(0) /*!< second interrupt flag */ +#define RTC_CTL_ALRMIF BIT(1) /*!< alarm interrupt flag */ +#define RTC_CTL_OVIF BIT(2) /*!< overflow interrupt flag */ +#define RTC_CTL_RSYNF BIT(3) /*!< registers synchronized flag */ +#define RTC_CTL_CMF BIT(4) /*!< configuration mode flag */ +#define RTC_CTL_LWOFF BIT(5) /*!< last write operation finished flag */ + +/* RTC_PSC */ +#define RTC_PSCH_PSC BITS(0, 3) /*!< prescaler high value */ +#define RTC_PSCL_PSC BITS(0, 15) /*!< prescaler low value */ + +/* RTC_DIV */ +#define RTC_DIVH_DIV BITS(0, 3) /*!< divider high value */ +#define RTC_DIVL_DIV BITS(0, 15) /*!< divider low value */ + +/* RTC_CNT */ +#define RTC_CNTH_CNT BITS(0, 15) /*!< counter high value */ +#define RTC_CNTL_CNT BITS(0, 15) /*!< counter low value */ + +/* RTC_ALRM */ +#define RTC_ALRMH_ALRM BITS(0, 15) /*!< alarm high value */ +#define RTC_ALRML_ALRM BITS(0, 15) /*!< alarm low value */ + +/* constants definitions */ +#define RTC_HIGH_VALUE 0x000F0000U /*!< RTC high value */ +#define RTC_LOW_VALUE 0x0000FFFFU /*!< RTC low value */ + +/* RTC interrupt definitions */ +#define RTC_INT_SECOND RTC_INTEN_SCIE /*!< second interrupt enable */ +#define RTC_INT_ALARM RTC_INTEN_ALRMIE /*!< alarm interrupt enable */ +#define RTC_INT_OVERFLOW RTC_INTEN_OVIE /*!< overflow interrupt enable */ + +/* RTC interrupt flag definitions */ +#define RTC_INT_FLAG_SECOND RTC_CTL_SCIF /*!< second interrupt flag */ +#define RTC_INT_FLAG_ALARM RTC_CTL_ALRMIF /*!< alarm interrupt flag */ +#define RTC_INT_FLAG_OVERFLOW RTC_CTL_OVIF /*!< overflow interrupt flag */ + +/* RTC flag definitions */ +#define RTC_FLAG_SECOND RTC_CTL_SCIF /*!< second interrupt flag */ +#define RTC_FLAG_ALARM RTC_CTL_ALRMIF /*!< alarm interrupt flag */ +#define RTC_FLAG_OVERFLOW RTC_CTL_OVIF /*!< overflow interrupt flag */ +#define RTC_FLAG_RSYN RTC_CTL_RSYNF /*!< registers synchronized flag */ +#define RTC_FLAG_LWOF RTC_CTL_LWOFF /*!< last write operation finished flag */ + +/* function declarations */ +/* enter RTC configuration mode */ +void rtc_configuration_mode_enter(void); +/* exit RTC configuration mode */ +void rtc_configuration_mode_exit(void); + +/* wait RTC last write operation finished flag set */ +void rtc_lwoff_wait(void); +/* wait RTC registers synchronized flag set */ +void rtc_register_sync_wait(void); + +/* get RTC counter value */ +uint32_t rtc_counter_get(void); +/* set RTC counter value */ +void rtc_counter_set(uint32_t cnt); + +/* set RTC prescaler value */ +void rtc_prescaler_set(uint32_t psc); +/* set RTC alarm value */ +void rtc_alarm_config(uint32_t alarm); +/* get RTC divider value */ +uint32_t rtc_divider_get(void); + +/* enable RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disable RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); +/* get RTC flag status */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear RTC flag status */ +void rtc_flag_clear(uint32_t flag); +/* get RTC interrupt flag status */ +FlagStatus rtc_interrupt_flag_get(uint32_t flag); +/* clear RTC interrupt flag status */ +void rtc_interrupt_flag_clear(uint32_t flag); + +#endif /* GD32A50X_RTC_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_spi.h b/gd32a50x/standard_peripheral/include/gd32a50x_spi.h new file mode 100644 index 0000000..a122fb1 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_spi.h @@ -0,0 +1,375 @@ +/*! + \file gd32a50x_spi.h + \brief definitions for the SPI + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_SPI_H +#define GD32A50X_SPI_H +#include "gd32a50x.h" + +/* SPIx(x=0,1) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE +#define I2S1_ADD I2S_ADD_BASE + +/* 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 SPI0) */ + +/* I2S_ADD registers definitions */ +#define I2S_ADD_CTL0(i2sx_add) REG32((i2sx_add) + 0x00000000U) /*!< I2S_ADD control register 0 */ +#define I2S_ADD_CTL1(i2sx_add) REG32((i2sx_add) + 0x00000004U) /*!< I2S_ADD control register 1*/ +#define I2S_ADD_STAT(i2sx_add) REG32((i2sx_add) + 0x00000008U) /*!< I2S_ADD status register */ +#define I2S_ADD_DATA(i2sx_add) REG32((i2sx_add) + 0x0000000CU) /*!< I2S_ADD data register */ +#define I2S_ADD_CRCPOLY(i2sx_add) REG32((i2sx_add) + 0x00000010U) /*!< I2S_ADD CRC polynomial register */ +#define I2S_ADD_RCRC(i2sx_add) REG32((i2sx_add) + 0x00000014U) /*!< I2S_ADD receive CRC register */ +#define I2S_ADD_TCRC(i2sx_add) REG32((i2sx_add) + 0x00000018U) /*!< I2S_ADD transmit CRC register */ +#define I2S_ADD_I2SCTL(i2sx_add) REG32((i2sx_add) + 0x0000001CU) /*!< I2S_ADD I2S control register */ +#define I2S_ADD_I2SPSC(i2sx_add) REG32((i2sx_add) + 0x00000020U) /*!< I2S_ADD I2S clock prescaler register */ + +/* bits definitions */ +/* SPI_CTL0 */ +#define SPI_CTL0_CKPH BIT(0) /*!< clock phase selection*/ +#define SPI_CTL0_CKPL BIT(1) /*!< clock polarity selection */ +#define SPI_CTL0_MSTMOD BIT(2) /*!< master mode enable */ +#define SPI_CTL0_PSC BITS(3,5) /*!< master clock prescaler selection */ +#define SPI_CTL0_SPIEN BIT(6) /*!< SPI enable*/ +#define SPI_CTL0_LF BIT(7) /*!< LSB first mode */ +#define SPI_CTL0_SWNSS BIT(8) /*!< NSS pin selection in NSS software mode */ +#define SPI_CTL0_SWNSSEN BIT(9) /*!< NSS software mode selection */ +#define SPI_CTL0_RO BIT(10) /*!< receive only */ +#define SPI_CTL0_FF16 BIT(11) /*!< data frame size */ +#define SPI_CTL0_CRCNT BIT(12) /*!< CRC next transfer */ +#define SPI_CTL0_CRCEN BIT(13) /*!< CRC calculation enable */ +#define SPI_CTL0_BDOEN BIT(14) /*!< bidirectional transmit output enable*/ +#define SPI_CTL0_BDEN BIT(15) /*!< bidirectional enable */ + +/* SPI_CTL1 */ +#define SPI_CTL1_DMAREN BIT(0) /*!< receive buffer DMA enable */ +#define SPI_CTL1_DMATEN BIT(1) /*!< transmit buffer DMA enable */ +#define SPI_CTL1_NSSDRV BIT(2) /*!< drive NSS output */ +#define SPI_CTL1_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 */ + +/* SPI_STAT */ +#define SPI_STAT_RBNE BIT(0) /*!< receive buffer not empty */ +#define SPI_STAT_TBE BIT(1) /*!< transmit buffer empty */ +#define SPI_STAT_I2SCH BIT(2) /*!< I2S channel side */ +#define SPI_STAT_TXURERR BIT(3) /*!< I2S transmission underrun error bit */ +#define SPI_STAT_CRCERR BIT(4) /*!< SPI CRC error bit */ +#define SPI_STAT_CONFERR BIT(5) /*!< SPI configuration error bit */ +#define SPI_STAT_RXORERR BIT(6) /*!< SPI reception overrun error bit */ +#define SPI_STAT_TRANS BIT(7) /*!< transmitting on-going bit */ +#define SPI_STAT_FERR BIT(8) /*!< format error bit */ + +/* SPI_DATA */ +#define SPI_DATA_DATA BITS(0,15) /*!< data transfer register */ + +/* SPI_CRCPOLY */ +#define SPI_CRCPOLY_CPR BITS(0,15) /*!< CRC polynomial register */ + +/* SPI_RCRC */ +#define SPI_RCRC_RCR BITS(0,15) /*!< RX CRC register */ + +/* SPI_TCRC */ +#define SPI_TCRC_TCR BITS(0,15) /*!< 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 available in SPI0) */ +#define SPI_QCTL_QMOD BIT(0) /*!< quad-SPI mode enable */ +#define SPI_QCTL_QRD BIT(1) /*!< quad-SPI mode read select */ +#define SPI_QCTL_IO23_DRV BIT(2) /*!< drive SPI_IO2 and SPI_IO3 enable */ + +/* constants definitions */ +/* SPI and I2S parameter struct definitions */ +typedef struct +{ + uint32_t device_mode; /*!< SPI master or slave */ + uint32_t trans_mode; /*!< SPI transtype */ + uint32_t frame_size; /*!< SPI frame size */ + uint32_t nss; /*!< SPI NSS control by handware or software */ + uint32_t endian; /*!< SPI big endian or little endian */ + uint32_t clock_polarity_phase; /*!< SPI clock phase and polarity */ + uint32_t prescale; /*!< SPI prescale factor */ +}spi_parameter_struct; + +/* SPI mode definitions */ +#define SPI_MASTER (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS) /*!< SPI as master */ +#define SPI_SLAVE ((uint32_t)0x00000000U) /*!< SPI as slave */ + +/* SPI bidirectional transfer direction */ +#define SPI_BIDIRECTIONAL_TRANSMIT SPI_CTL0_BDOEN /*!< SPI work in transmit-only mode */ +#define SPI_BIDIRECTIONAL_RECEIVE (~SPI_CTL0_BDOEN) /*!< SPI work in receive-only mode */ + +/* SPI transmit type */ +#define SPI_TRANSMODE_FULLDUPLEX ((uint32_t)0x00000000U) /*!< SPI receive and send data at fullduplex communication */ +#define SPI_TRANSMODE_RECEIVEONLY SPI_CTL0_RO /*!< SPI only receive data */ +#define SPI_TRANSMODE_BDRECEIVE SPI_CTL0_BDEN /*!< bidirectional receive data */ +#define SPI_TRANSMODE_BDTRANSMIT (SPI_CTL0_BDEN | SPI_CTL0_BDOEN) /*!< bidirectional transmit data*/ + +/* SPI frame size */ +#define SPI_FRAMESIZE_16BIT SPI_CTL0_FF16 /*!< SPI frame size is 16 bits */ +#define SPI_FRAMESIZE_8BIT ((uint32_t)0x00000000U) /*!< SPI frame size is 8 bits */ + +/* SPI NSS control mode */ +#define SPI_NSS_SOFT SPI_CTL0_SWNSSEN /*!< SPI NSS control by sofrware */ +#define SPI_NSS_HARD ((uint32_t)0x00000000U) /*!< SPI NSS control by hardware */ + +/* SPI transmit way */ +#define SPI_ENDIAN_MSB ((uint32_t)0x00000000U) /*!< SPI transmit way is big endian: transmit MSB first */ +#define SPI_ENDIAN_LSB SPI_CTL0_LF /*!< SPI transmit way is little endian: transmit LSB first */ + +/* SPI clock 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 prescaler factor */ +#define CTL0_PSC(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define SPI_PSC_2 CTL0_PSC(0) /*!< SPI clock prescaler factor is 2 */ +#define SPI_PSC_4 CTL0_PSC(1) /*!< SPI clock prescaler factor is 4 */ +#define SPI_PSC_8 CTL0_PSC(2) /*!< SPI clock prescaler factor is 8 */ +#define SPI_PSC_16 CTL0_PSC(3) /*!< SPI clock prescaler factor is 16 */ +#define SPI_PSC_32 CTL0_PSC(4) /*!< SPI clock prescaler factor is 32 */ +#define SPI_PSC_64 CTL0_PSC(5) /*!< SPI clock prescaler factor is 64 */ +#define SPI_PSC_128 CTL0_PSC(6) /*!< SPI clock prescaler factor is 128 */ +#define SPI_PSC_256 CTL0_PSC(7) /*!< SPI clock prescaler factor is 256 */ + +/* I2S audio sample rate */ +#define I2S_AUDIOSAMPLE_8K ((uint32_t)8000U) /*!< I2S audio sample rate is 8KHz */ +#define I2S_AUDIOSAMPLE_11K ((uint32_t)11025U) /*!< I2S audio sample rate is 11KHz */ +#define I2S_AUDIOSAMPLE_16K ((uint32_t)16000U) /*!< I2S audio sample rate is 16KHz */ +#define I2S_AUDIOSAMPLE_22K ((uint32_t)22050U) /*!< I2S audio sample rate is 22KHz */ +#define I2S_AUDIOSAMPLE_32K ((uint32_t)32000U) /*!< I2S audio sample rate is 32KHz */ +#define I2S_AUDIOSAMPLE_44K ((uint32_t)44100U) /*!< I2S audio sample rate is 44KHz */ +#define I2S_AUDIOSAMPLE_48K ((uint32_t)48000U) /*!< I2S audio sample rate is 48KHz */ +#define I2S_AUDIOSAMPLE_96K ((uint32_t)96000U) /*!< I2S audio sample rate is 96KHz */ +#define I2S_AUDIOSAMPLE_192K ((uint32_t)192000U) /*!< I2S audio sample rate is 192KHz */ + +/* I2S frame format */ +#define I2SCTL_DTLEN(regval) (BITS(1,2) & ((uint32_t)(regval) << 1)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 32 bit and channel length is 32 bit */ + +/* I2S master clock output */ +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */ + +/* I2S operation mode */ +#define I2SCTL_I2SOPMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */ + +/* I2S clock polarity */ +#define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ +#define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ + +/* SPI DMA constants definitions */ +#define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ + +/* SPI CRC constants definitions */ +#define SPI_CRC_TX ((uint8_t)0x00U) /*!< SPI transmit CRC value */ +#define SPI_CRC_RX ((uint8_t)0x01U) /*!< SPI receive CRC value */ + +/* SPI/I2S interrupt enable/disable constants definitions */ +#define SPI_I2S_INT_TBE 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 I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */ +#define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x06U) /*!< format error interrupt flag */ + +/* SPI/I2S flag definitions */ +#define SPI_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define SPI_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define SPI_FLAG_CRCERR SPI_STAT_CRCERR /*!< CRC error flag */ +#define SPI_FLAG_CONFERR SPI_STAT_CONFERR /*!< mode config error flag */ +#define SPI_FLAG_RXORERR SPI_STAT_RXORERR /*!< receive overrun error flag */ +#define SPI_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define SPI_FLAG_FERR SPI_STAT_FERR /*!< format error flag */ + +/* SPI flag definitions */ +#define I2S_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define I2S_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define I2S_FLAG_CH SPI_STAT_I2SCH /*!< channel side flag */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error flag */ +#define I2S_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define I2S_FLAG_FERR SPI_STAT_FERR /*!< format error flag */ + +/* function declarations */ +/* SPI deinitialization and initialization functions */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize the parameters of SPI structure with the default values */ +void spi_struct_para_init(spi_parameter_struct *spi_struct); +/* initialize SPI parameters */ +void spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* I2S initialization functions */ +/* 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); + +/* DMA functions */ +/* enable SPI DMA */ +void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma); + +/* communication functions */ +/* configure SPI data frame format */ +void 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); +/* 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); + +/* 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 */ +/* 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); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +#endif /* GD32A50X_SPI_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_syscfg.h b/gd32a50x/standard_peripheral/include/gd32a50x_syscfg.h new file mode 100644 index 0000000..275a0ee --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_syscfg.h @@ -0,0 +1,301 @@ +/*! + \file gd32a50x_syscfg.h + \brief definitions for the SYSCFG + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_SYSCFG_H +#define GD32A50X_SYSCFG_H + +#include "gd32a50x.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00000000U) /*!< system configuration register 0 */ +#define SYSCFG_CFG1 REG32(SYSCFG + 0x00000004U) /*!< system configuration register 1 */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x00000008U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0000000CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x00000010U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x00000014U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_CFG2 REG32(SYSCFG + 0x00000018U) /*!< system configuration register 2 */ +#define SYSCFG_STAT REG32(SYSCFG + 0x0000001CU) /*!< system status register */ +#define SYSCFG_CFG3 REG32(SYSCFG + 0x00000028U) /*!< system configuration register 3 */ +#define SYSCFG_TIMERINSEL REG32(SYSCFG + 0x0000002CU) /*!< TIMER input source selection register */ + +/* bits definitions */ +/* SYSCFG_CFG0 */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,1) /*!< SYSCFG memory remap configuration */ +#define SYSCFG_CFG0_PA9_PA12_RMP BIT(4) /*!< PA9 and PA12 remapping bit for small packages (32 pins) */ +#define SYSCFG_CFG0_BOOT0_PF0_RMP BIT(6) /*!< BOOT0 and PF0 remapping bit */ + +/* SYSCFG_CFG1 */ +#define SYSCFG_CFG1_ADC1CH14RMP BIT(28) /*!< ADC1 channel 14 remapping bit */ +#define SYSCFG_CFG1_ADC1CH15RMP BIT(29) /*!< ADC1 channel 15 remapping bit */ +#define SYSCFG_CFG1_ADC0CH8RMP BIT(30) /*!< ADC0 channel 8 remapping bit */ +#define SYSCFG_CFG1_ADC0CH9RMP BIT(31) /*!< ADC0 channel 9 remapping bit */ + +/* SYSCFG_EXTISS0 */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,3) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,7) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,11) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,15) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 */ +#define SYSCFG_EXTISS1_EXTI4_SS BITS(0,3) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BITS(4,7) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,11) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,15) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 */ +#define SYSCFG_EXTISS2_EXTI8_SS BITS(0,3) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BITS(4,7) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BITS(8,11) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BITS(12,15) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 */ +#define SYSCFG_EXTISS3_EXTI12_SS BITS(0,3) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,7) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,11) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,15) /*!< EXTI 15 configuration */ + +/* SSYSCFG_CFG2 */ +#define SYSCFG_CFG2_LOCKUP_LOCK BIT(0) /*!< Cortex-M33 LOCKUP output lock bit */ +#define SYSCFG_CFG2_SRAM_ECC_ERROR_LOCK BIT(1) /*!< SRAM ECC check error lock bit */ +#define SYSCFG_CFG2_LVD_LOCK BIT(2) /*!< LVD lock bit */ + +/* SYSCFG_STAT */ +#define SYSCFG_STAT_SRAMECCMEIF BIT(0) /*!< SRAM multi-bits non-correction event flag */ +#define SYSCFG_STAT_SRAMECCSEIF BIT(1) /*!< SRAM single bit correction event flag */ +#define SYSCFG_STAT_FLASHECCIF BIT(2) /*!< Flash ECC NMI interrupt flag */ +#define SYSCFG_STAT_CKMNMIIF BIT(3) /*!< HXTAL clock moniotor NMI interrupt flag */ +#define SYSCFG_STAT_NMIPINIF BIT(4) /*!< NMI interrupt flag from nmi pin */ + +/* SSYSCFG_CFG3 */ +#define SYSCFG_CFG3_SRAMECCMEIE BIT(0) /*!< SRAM multi-bits non-correction NMI interrupt enable */ +#define SYSCFG_CFG3_SRAMECCSEIE BIT(1) /*!< SRAM single bit correction interrupt enable */ +#define SYSCFG_CFG3_FLASHECCIE BIT(2) /*!< Flash ECC NMI interrupt enable */ +#define SYSCFG_CFG3_CKMNMIIE BIT(3) /*!< HXTAL clock moniotor NMI interrupt enable */ +#define SYSCFG_CFG3_NMIPINIE BIT(4) /*!< NMI pin interrupt enable */ +#define SYSCFG_CFG3_SRAMECCSERRBITS BITS(12,17) /*!< which one bit has an SRAM ECC single-bit correctable error */ +#define SYSCFG_CFG3_SRAMECCEADDR BITS(18,31) /*!< record the faulting system address (Address[15:0] >> 2) where the last SRAM ECC event on SRAM occurred. */ + +/* SYSCFG_TIMERINSEL */ +#define SYSCFG_TIMERINSEL_TIMER7_CH0N_SEL BIT(0) /*!< TIMER7 channel 0 complementary input selection */ +#define SYSCFG_TIMERINSEL_TIMER20_BKIN3_SEL BIT(2) /*!< TIMER20 break input 3 selection */ +#define SYSCFG_TIMERINSEL_TIMER20_BKIN2_SEL BIT(3) /*!< TIMER20 break input 2 selection */ +#define SYSCFG_TIMERINSEL_TIMER20_BKIN1_SEL BIT(4) /*!< TIMER20 break input 1 selection */ +#define SYSCFG_TIMERINSEL_TIMER20_BKIN0_SEL BIT(5) /*!< TIMER20 break input 0 selection */ +#define SYSCFG_TIMERINSEL_TIMER19_BKIN3_SEL BIT(6) /*!< TIMER19 break input 3 selection */ +#define SYSCFG_TIMERINSEL_TIMER19_BKIN2_SEL BIT(7) /*!< TIMER19 break input 2 selection */ +#define SYSCFG_TIMERINSEL_TIMER19_BKIN1_SEL BIT(8) /*!< TIMER19 break input 1 selection */ +#define SYSCFG_TIMERINSEL_TIMER19_BKIN0_SEL BIT(9) /*!< TIMER19 break input 0 selection */ +#define SYSCFG_TIMERINSEL_TIMER7_BKIN3_SEL BIT(14) /*!< TIMER7 break input 3 selection */ +#define SYSCFG_TIMERINSEL_TIMER7_BKIN2_SEL BIT(15) /*!< TIMER7 break input 2 selection */ +#define SYSCFG_TIMERINSEL_TIMER7_BKIN1_SEL BIT(16) /*!< TIMER7 break input 1 selection */ +#define SYSCFG_TIMERINSEL_TIMER7_BKIN0_SEL BIT(17) /*!< TIMER7 break input 0 selection */ +#define SYSCFG_TIMERINSEL_TIMER0_BKIN3_SEL BIT(18) /*!< TIMER0 break input 3 selection */ +#define SYSCFG_TIMERINSEL_TIMER0_BKIN2_SEL BIT(19) /*!< TIMER0 break input 2 selection */ +#define SYSCFG_TIMERINSEL_TIMER0_BKIN1_SEL BIT(20) /*!< TIMER0 break input 1 selection */ +#define SYSCFG_TIMERINSEL_TIMER0_BKIN0_SEL BIT(21) /*!< TIMER0 break input 0 selection */ +#define SYSCFG_TIMERINSEL_TIMER20_ETI_SEL BITS(22,23) /*!< TIMER20 external trigger selection */ +#define SYSCFG_TIMERINSEL_TIMER19_ETI_SEL BITS(24,25) /*!< TIMER19 external trigger selection */ +#define SYSCFG_TIMERINSEL_TIMER7_ETI_SEL BITS(28,29) /*!< TIMER7 external trigger selection */ +#define SYSCFG_TIMERINSEL_TIMER0_ETI_SEL BITS(30,31) /*!< TIMER0 external trigger selection */ + +/* 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 */ + +/* PA9/PA12 remap definitions */ +#define SYSCFG_PA9_PA12_REMAP SYSCFG_CFG0_PA9_PA12_RMP /*!< PA9/PA12 pins are mapping on PA10/PA11 pins */ + +/* PF0/BOOT0 remap definitions */ +#define SYSCFG_BOOT0_REMAP_PF0 SYSCFG_CFG0_BOOT0_PF0_RMP /*!< PF0 pin is mapping on the BOOT0 pin */ + +/* 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_GPIOE ((uint8_t)0x04U) /*!< EXTI GPIOE configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ + +/* EXTI source pin definitions */ +#define EXTI_SOURCE_PIN0 ((uint8_t)0x00U) /*!< EXTI GPIO pin0 configuration */ +#define EXTI_SOURCE_PIN1 ((uint8_t)0x01U) /*!< EXTI GPIO pin1 configuration */ +#define EXTI_SOURCE_PIN2 ((uint8_t)0x02U) /*!< EXTI GPIO pin2 configuration */ +#define EXTI_SOURCE_PIN3 ((uint8_t)0x03U) /*!< EXTI GPIO pin3 configuration */ +#define EXTI_SOURCE_PIN4 ((uint8_t)0x04U) /*!< EXTI GPIO pin4 configuration */ +#define EXTI_SOURCE_PIN5 ((uint8_t)0x05U) /*!< EXTI GPIO pin5 configuration */ +#define EXTI_SOURCE_PIN6 ((uint8_t)0x06U) /*!< EXTI GPIO pin6 configuration */ +#define EXTI_SOURCE_PIN7 ((uint8_t)0x07U) /*!< EXTI GPIO pin7 configuration */ +#define EXTI_SOURCE_PIN8 ((uint8_t)0x08U) /*!< EXTI GPIO pin8 configuration */ +#define EXTI_SOURCE_PIN9 ((uint8_t)0x09U) /*!< EXTI GPIO pin9 configuration */ +#define EXTI_SOURCE_PIN10 ((uint8_t)0x0AU) /*!< EXTI GPIO pin10 configuration */ +#define EXTI_SOURCE_PIN11 ((uint8_t)0x0BU) /*!< EXTI GPIO pin11 configuration */ +#define EXTI_SOURCE_PIN12 ((uint8_t)0x0CU) /*!< EXTI GPIO pin12 configuration */ +#define EXTI_SOURCE_PIN13 ((uint8_t)0x0DU) /*!< EXTI GPIO pin13 configuration */ +#define EXTI_SOURCE_PIN14 ((uint8_t)0x0EU) /*!< EXTI GPIO pin14 configuration */ +#define EXTI_SOURCE_PIN15 ((uint8_t)0x0FU) /*!< EXTI GPIO pin15 configuration */ + +/* lock definitions */ +#define SYSCFG_LOCK_LOCKUP SYSCFG_CFG2_LOCKUP_LOCK /*!< LOCKUP output lock */ +#define SYSCFG_LOCK_SRAM_ECC_ERROR SYSCFG_CFG2_SRAM_ECC_ERROR_LOCK /*!< SRAM ECC error lock */ +#define SYSCFG_LOCK_LVD SYSCFG_CFG2_LVD_LOCK /*!< LVD lock */ + +/* TIMER external trigger definitions */ +#define TIMER_ETI_TRG0 ((uint8_t)0x00U) /*!< TIMER external trigger 0 */ +#define TIMER_ETI_TRG1 ((uint8_t)0x01U) /*!< TIMER external trigger 1 */ +#define TIMER_ETI_TRG2 ((uint8_t)0x02U) /*!< TIMER external trigger 2 */ +#define TIMER_ETI_TRG_NONE ((uint8_t)0x03U) /*!< do not seclet TIMER external trigger source */ + +/* TIMERx break input y */ +#define TIMER20_BKIN3_TRIG SYSCFG_TIMERINSEL_TIMER20_BKIN3_SEL /*!< TIMER20 break input 3 selection */ +#define TIMER20_BKIN2_TRIG SYSCFG_TIMERINSEL_TIMER20_BKIN2_SEL /*!< TIMER20 break input 2 selection */ +#define TIMER20_BKIN1_TRIG SYSCFG_TIMERINSEL_TIMER20_BKIN1_SEL /*!< TIMER20 break input 1 selection */ +#define TIMER20_BKIN0_TRIG SYSCFG_TIMERINSEL_TIMER20_BKIN0_SEL /*!< TIMER20 break input 0 selection */ +#define TIMER19_BKIN3_TRIG SYSCFG_TIMERINSEL_TIMER19_BKIN3_SEL /*!< TIMER19 break input 3 selection */ +#define TIMER19_BKIN2_TRIG SYSCFG_TIMERINSEL_TIMER19_BKIN2_SEL /*!< TIMER19 break input 2 selection */ +#define TIMER19_BKIN1_TRIG SYSCFG_TIMERINSEL_TIMER19_BKIN1_SEL /*!< TIMER19 break input 1 selection */ +#define TIMER19_BKIN0_TRIG SYSCFG_TIMERINSEL_TIMER19_BKIN0_SEL /*!< TIMER19 break input 0 selection */ +#define TIMER7_BKIN3_TRIG SYSCFG_TIMERINSEL_TIMER7_BKIN3_SEL /*!< TIMER7 break input 3 selection */ +#define TIMER7_BKIN2_TRIG SYSCFG_TIMERINSEL_TIMER7_BKIN2_SEL /*!< TIMER7 break input 2 selection */ +#define TIMER7_BKIN1_TRIG SYSCFG_TIMERINSEL_TIMER7_BKIN1_SEL /*!< TIMER7 break input 1 selection */ +#define TIMER7_BKIN0_TRIG SYSCFG_TIMERINSEL_TIMER7_BKIN0_SEL /*!< TIMER7 break input 0 selection */ +#define TIMER0_BKIN3_TRIG SYSCFG_TIMERINSEL_TIMER0_BKIN3_SEL /*!< TIMER0 break input 3 selection */ +#define TIMER0_BKIN2_TRIG SYSCFG_TIMERINSEL_TIMER0_BKIN2_SEL /*!< TIMER0 break input 2 selection */ +#define TIMER0_BKIN1_TRIG SYSCFG_TIMERINSEL_TIMER0_BKIN1_SEL /*!< TIMER0 break input 1 selection */ +#define TIMER0_BKIN0_TRIG SYSCFG_TIMERINSEL_TIMER0_BKIN0_SEL /*!< TIMER0 break input 0 selection */ + +/* TIMER7 channel0 complementary input source definitions */ +#define TIMER7CH0N_TIMER7CH0_TIMER0CH0_IN SYSCFG_TIMERINSEL_TIMER7_CH0N_SEL /*!< exclusive or of TIMER7_CH0_IN,TIMER7_CH0N_IN,and TIMER0_CH0_IN */ +#define TIMER7_CH0N_IN (~SYSCFG_TIMERINSEL_TIMER7_CH0N_SEL) /*!< TIMER7_CH0N_IN */ + +/* SYSCFG flag definitions */ +#define SYSCFG_FLAG_SRAMECCMERR SYSCFG_STAT_SRAMECCMEIF /*!< SRAM multi-bits non-correction ECC error flag */ +#define SYSCFG_FLAG_SRAMECCSERR SYSCFG_STAT_SRAMECCSEIF /*!< SRAM single bit correction ECC error flag */ +#define SYSCFG_FLAG_FLASHECCERR SYSCFG_STAT_FLASHECCIF /*!< FLASH ECC NMI error flag */ +#define SYSCFG_FLAG_CKMNMIERR SYSCFG_STAT_CKMNMIIF /*!< HXTAL clock monitor NMI error flag */ +#define SYSCFG_FLAG_NMIPINERR SYSCFG_STAT_NMIPINIF /*!< NMI pin error flag */ + +/* SYSCFG interrupt flag constants definitions */ +#define SYSCFG_INT_FLAG_SRAMECCMERR SYSCFG_STAT_SRAMECCMEIF /*!< SRAM multi-bits non-correction ECC error interrupt flag */ +#define SYSCFG_INT_FLAG_SRAMECCSERR SYSCFG_STAT_SRAMECCSEIF /*!< SRAM single bit correction ECC error interrupt flag */ +#define SYSCFG_INT_FLAG_FLASHECCERR SYSCFG_STAT_FLASHECCIF /*!< FLASH ECC NMI error interrupt flag */ +#define SYSCFG_INT_FLAG_CKMNMIERR SYSCFG_STAT_CKMNMIIF /*!< HXTAL clock monitor NMI error interrupt flag */ +#define SYSCFG_INT_FLAG_NMIPINERR SYSCFG_STAT_NMIPINIF /*!< NMI pin error interrupt flag */ + +/* SYSCFG interrupt enable/disable constants definitions */ +#define SYSCFG_INT_SRAMECCME SYSCFG_CFG3_SRAMECCMEIE /*!< SRAM multi-bits non-correction ECC error */ +#define SYSCFG_INT_SRAMECCSE SYSCFG_CFG3_SRAMECCSEIE /*!< SRAM single bit correction ECC error */ +#define SYSCFG_INT_FLASHECCE SYSCFG_CFG3_FLASHECCIE /*!< FLASH ECC NMI error */ +#define SYSCFG_INT_CKMNMI SYSCFG_CFG3_CKMNMIIE /*!< receive buffer not empty interrupt */ +#define SYSCFG_INT_NMIPIN SYSCFG_CFG3_NMIPINIE /*!< HXTAL clock monitor NMI error */ + +typedef enum { + ADC1_IN14_REMAP = 1, /*!< ADC1 channel 14 remapping */ + ADC1_IN15_REMAP, /*!< ADC1 channel 15 remapping */ + ADC0_IN8_REMAP, /*!< ADC0 channel 8 remapping */ + ADC0_IN9_REMAP /*!< ADC0 channel 9 remapping */ +} syscfg_adcx_chy_enum; + +typedef enum { + TIMER0SEL = 1, /*!< select TIMER0 */ + TIMER7SEL, /*!< select TIMER7 */ + TIMER19SEL, /*!< select TIMER19 */ + TIMER20SEL, /*!< select TIMER20 */ +} syscfg_timersel_enum; + +/* function declarations */ +/* initialization functions */ +/* reset the SYSCFG registers */ +void syscfg_deinit(void); + +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); + +/* enable remap pin function */ +void syscfg_pin_remap_enable(uint32_t remap_pin); +/* disable remap pin function */ +void syscfg_pin_remap_disable(uint32_t remap_pin); +/* configure ADC channel GPIO pin remap function */ +void syscfg_adc_ch_remap_config(syscfg_adcx_chy_enum adcx_iny_remap, ControlStatus newvalue); + +/* select TIMER external trigger source */ +void syscfg_timer_eti_sel(syscfg_timersel_enum timer_num, uint32_t eti_num); +/* select TRIGSEL as TIMER break input source */ +void syscfg_timer_bkin_select_trigsel(uint32_t bkin_source); +/* select GPIO as TIMER break input source */ +void syscfg_timer_bkin_select_gpio(uint32_t bkin_source); +/* select TIMER7 channel0 complementary input source */ +void syscfg_timer7_ch0n_select(uint32_t timer7_ch0n_in); + +/* configure TIMER0/7/19/20 break input to the selected parameter connection */ +void syscfg_lock_config(uint32_t syscfg_lock); + +/* flag and interrupt functions */ +/* get SYSCFG flags */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag); +/* clear SYSCFG flags */ +void syscfg_flag_clear(uint32_t syscfg_flag); +/* enable SYSCFG interrupts */ +void syscfg_interrupt_enable(uint32_t interrupt); +/* disable SYSCFG interrupts */ +void syscfg_interrupt_disable(uint32_t interrupt); +/* get SYSCFG interrupt flag status */ +FlagStatus syscfg_interrupt_flag_get(uint32_t interrupt); +/* get the current boot mode */ +uint8_t syscfg_bootmode_get(void); +/* get the address where SRAM ECC error occur on */ +uint16_t syscfg_sram_ecc_address_get(void); +/* get the bit which has SRAM ECC signle error */ +uint8_t syscfg_sram_ecc_bit_get(void); + +#endif /* GD32A50X_SYSCFG_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_timer.h b/gd32a50x/standard_peripheral/include/gd32a50x_timer.h new file mode 100644 index 0000000..47a598b --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_timer.h @@ -0,0 +1,1135 @@ +/*! + \file gd32a50x_timer.h + \brief definitions for the TIMER + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_TIMER_H +#define GD32A50X_TIMER_H + +#include "gd32a50x.h" + +/* TIMERx(x=0,1,5,6,7,19,20) definitions */ +#define TIMER0 (TIMER_BASE + 0x00012C00U) /*!< TIMER0 base address */ +#define TIMER1 TIMER_BASE /*!< TIMER1 base address */ +#define TIMER5 (TIMER_BASE + 0x00001000U) /*!< TIMER5 base address */ +#define TIMER6 (TIMER_BASE + 0x00001400U) /*!< TIMER6 base address */ +#define TIMER7 (TIMER_BASE + 0x00013400U) /*!< TIMER7 base address */ +#define TIMER19 (TIMER_BASE + 0x00015000U) /*!< TIMER19 base address */ +#define TIMER20 (TIMER_BASE + 0x00015400U) /*!< TIMER20 base address */ + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00000000U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x00000004U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x00000008U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0000000CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x00000010U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x00000014U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x00000018U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x0000001CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x00000020U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x00000024U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x00000028U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x0000002CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x00000030U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x00000034U) /*!< TIMER channel 0 capture or compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x00000038U) /*!< TIMER channel 1 capture or compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x0000003CU) /*!< TIMER channel 2 capture or compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x00000040U) /*!< TIMER channel 3 capture or compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x00000044U) /*!< TIMER channel complementary protection register */ +#define TIMER_MCHCTL0(timerx) REG32((timerx) + 0x00000048U) /*!< TIMER multi mode channel control register 0 */ +#define TIMER_MCHCTL1(timerx) REG32((timerx) + 0x0000004CU) /*!< TIMER multi mode channel control register 1 */ +#define TIMER_MCHCTL2(timerx) REG32((timerx) + 0x00000050U) /*!< TIMER multi mode channel control register 2 */ +#define TIMER_IRMP(timerx) REG32((timerx) + 0x00000050U) /*!< TIMER channel input remap register (only for TIMER1) */ +#define TIMER_MCH0CV(timerx) REG32((timerx) + 0x00000054U) /*!< TIMER multi mode channel 0 capture or compare value register */ +#define TIMER_MCH1CV(timerx) REG32((timerx) + 0x00000058U) /*!< TIMER multi mode channel 1 capture or compare value register */ +#define TIMER_MCH2CV(timerx) REG32((timerx) + 0x0000005CU) /*!< TIMER multi mode channel 2 capture or compare value register */ +#define TIMER_MCH3CV(timerx) REG32((timerx) + 0x00000060U) /*!< TIMER multi mode channel 3 capture or compare value register */ +#define TIMER_CH0COMV_ADD(timerx) REG32((timerx) + 0x00000064U) /*!< TIMER channel 0 additional compare value register */ +#define TIMER_CH1COMV_ADD(timerx) REG32((timerx) + 0x00000068U) /*!< TIMER channel 1 additional compare value register */ +#define TIMER_CH2COMV_ADD(timerx) REG32((timerx) + 0x0000006CU) /*!< TIMER channel 2 additional compare value register */ +#define TIMER_CH3COMV_ADD(timerx) REG32((timerx) + 0x00000070U) /*!< TIMER channel 3 additional compare value register */ +#define TIMER_CTL2(timerx) REG32((timerx) + 0x00000074U) /*!< TIMER control register 2 */ +#define TIMER_BRKCFG(timerx) REG32((timerx) + 0x00000078U) /*!< TIMER break configuration register */ +#define TIMER_FCCHP0(timerx) REG32((timerx) + 0x0000007CU) /*!< TIMER free complementary channel protection register 0 */ +#define TIMER_FCCHP1(timerx) REG32((timerx) + 0x00000080U) /*!< TIMER free complementary channel protection register 1 */ +#define TIMER_FCCHP2(timerx) REG32((timerx) + 0x00000084U) /*!< TIMER free complementary channel protection register 2 */ +#define TIMER_FCCHP3(timerx) REG32((timerx) + 0x00000088U) /*!< TIMER free complementary channel protection register 3 */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x000000E0U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x000000E4U) /*!< TIMER DMA transfer buffer register */ +#define TIMER_CFG(timerx) REG32((timerx) + 0x000000FCU) /*!< TIMER configuration register */ + +/* bits definitions */ +/* TIMER_CTL0 */ +#define TIMER_CTL0_CEN BIT(0) /*!< TIMER counter enable */ +#define TIMER_CTL0_UPDIS BIT(1) /*!< update disable */ +#define TIMER_CTL0_UPS BIT(2) /*!< update source */ +#define TIMER_CTL0_SPM BIT(3) /*!< single pulse mode */ +#define TIMER_CTL0_DIR BIT(4) /*!< timer counter direction */ +#define TIMER_CTL0_CAM BITS(5,6) /*!< counter aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ + +/* 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_ISO3N BIT(15) /*!< idle state of channel 3 complementary output */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_SMC BITS(0,2) /*!< slave mode control */ +#define TIMER_SMCFG_TRGS (BITS(4,6)| BIT(31)) /*!< trigger selection */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ +#define TIMER_SMCFG_TRGS_BIT3 BIT(31) /*!< Trigger selection bit 3 */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_CMTIE BIT(5) /*!< commutation interrupt request enable */ +#define TIMER_DMAINTEN_TRGIE BIT(6) /*!< trigger interrupt enable */ +#define TIMER_DMAINTEN_BRKIE BIT(7) /*!< break interrupt enable */ +#define TIMER_DMAINTEN_UPDEN BIT(8) /*!< update DMA request enable */ +#define TIMER_DMAINTEN_CH0DEN BIT(9) /*!< channel 0 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< commutation DMA request enable */ +#define TIMER_DMAINTEN_TRGDEN BIT(14) /*!< trigger DMA request enable */ +#define TIMER_DMAINTEN_MCH0IE BIT(20) /*!< multi mode channel 0 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH1IE BIT(21) /*!< multi mode channel 1 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH2IE BIT(22) /*!< multi mode channel 2 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH3IE BIT(23) /*!< multi mode channel 3 capture or compare interrupt enable */ +#define TIMER_DMAINTEN_MCH0DEN BIT(24) /*!< multi mode channel 0 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_MCH1DEN BIT(25) /*!< multi mode channel 1 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_MCH2DEN BIT(26) /*!< multi mode channel 2 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_MCH3DEN BIT(27) /*!< multi mode channel 3 capture or compare DMA request enable */ +#define TIMER_DMAINTEN_CH0COMADDIE BIT(28) /*!< channel 0 additional compare interrupt enable */ +#define TIMER_DMAINTEN_CH1COMADDIE BIT(29) /*!< channel 1 additional compare interrupt enable */ +#define TIMER_DMAINTEN_CH2COMADDIE BIT(30) /*!< channel 2 additional compare interrupt enable */ +#define TIMER_DMAINTEN_CH3COMADDIE BIT(31) /*!< channel 3 additional compare interrupt enable */ + +/* TIMER_INTF */ +#define TIMER_INTF_UPIF BIT(0) /*!< update interrupt flag */ +#define TIMER_INTF_CH0IF BIT(1) /*!< channel 0 capture or compare interrupt flag */ +#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 capture or compare interrupt flag */ +#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 capture or compare interrupt flag */ +#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 capture or compare interrupt flag */ +#define TIMER_INTF_CMTIF BIT(5) /*!< channel commutation interrupt flag */ +#define TIMER_INTF_TRGIF BIT(6) /*!< trigger interrupt flag */ +#define TIMER_INTF_BRKIF BIT(7) /*!< break interrupt flag */ +#define TIMER_INTF_CH0OF BIT(9) /*!< channel 0 over capture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 over capture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 over capture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 over capture flag */ +#define TIMER_INTF_MCH0IF BIT(20) /*!< multi mode channel 0 capture or compare interrupt flag */ +#define TIMER_INTF_MCH1IF BIT(21) /*!< multi mode channel 1 capture or compare interrupt flag */ +#define TIMER_INTF_MCH2IF BIT(22) /*!< multi mode channel 2 capture or compare interrupt flag */ +#define TIMER_INTF_MCH3IF BIT(23) /*!< multi mode channel 3 capture or compare interrupt flag */ +#define TIMER_INTF_MCH0OF BIT(24) /*!< multi mode channel 0 over capture flag */ +#define TIMER_INTF_MCH1OF BIT(25) /*!< multi mode channel 1 over capture flag */ +#define TIMER_INTF_MCH2OF BIT(26) /*!< multi mode channel 2 over capture flag */ +#define TIMER_INTF_MCH3OF BIT(27) /*!< multi mode channel 3 over capture flag */ +#define TIMER_INTF_CH0COMADDIF BIT(28) /*!< channel 0 additional compare interrupt flag */ +#define TIMER_INTF_CH1COMADDIF BIT(29) /*!< channel 1 additional compare interrupt flag */ +#define TIMER_INTF_CH2COMADDIF BIT(30) /*!< channel 2 additional compare interrupt flag */ +#define TIMER_INTF_CH3COMADDIF BIT(31) /*!< channel 3 additional compare interrupt flag */ + +/* TIMER_SWEVG */ +#define TIMER_SWEVG_UPG BIT(0) /*!< update event generate */ +#define TIMER_SWEVG_CH0G BIT(1) /*!< channel 0 capture or compare event generation */ +#define TIMER_SWEVG_CH1G BIT(2) /*!< channel 1 capture or compare event generation */ +#define TIMER_SWEVG_CH2G BIT(3) /*!< channel 2 capture or compare event generation */ +#define TIMER_SWEVG_CH3G BIT(4) /*!< channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CMTG BIT(5) /*!< channel commutation event generation */ +#define TIMER_SWEVG_TRGG BIT(6) /*!< trigger event generation */ +#define TIMER_SWEVG_BRKG BIT(7) /*!< break event generation */ +#define TIMER_SWEVG_MCH0G BIT(20) /*!< multi mode channel 0 capture or compare event generation */ +#define TIMER_SWEVG_MCH1G BIT(21) /*!< multi mode channel 1 capture or compare event generation */ +#define TIMER_SWEVG_MCH2G BIT(22) /*!< multi mode channel 2 capture or compare event generation */ +#define TIMER_SWEVG_MCH3G BIT(23) /*!< multi mode channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CH0COMADDG BIT(28) /*!< channel 0 additional compare event generation */ +#define TIMER_SWEVG_CH1COMADDG BIT(29) /*!< channel 1 additional compare event generation */ +#define TIMER_SWEVG_CH2COMADDG BIT(30) /*!< channel 2 additional compare event generation */ +#define TIMER_SWEVG_CH3COMADDG BIT(31) /*!< channel 3 additional compare event generation */ + +/* TIMER_CHCTL0 */ +/* output compare mode */ +#define TIMER_CHCTL0_CH0MS (TIMER_CHCTL0_CH0MS_BIT2 | BITS(0,1)) /*!< channel 0 mode selection */ +#define TIMER_CHCTL0_CH0COMSEN BIT(3) /*!< channel 0 output compare shadow enable */ +#define TIMER_CHCTL0_CH0COMCTL BITS(4,6) /*!< channel 0 output compare control */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS (TIMER_CHCTL0_CH1MS_BIT2 | BITS(8,9)) /*!< channel 1 mode selection */ +#define TIMER_CHCTL0_CH1COMSEN BIT(11) /*!< channel 1 output compare shadow enable */ +#define TIMER_CHCTL0_CH1COMCTL BITS(12,14) /*!< channel 1 output compare control */ +#define TIMER_CHCTL0_CH1COMCEN BIT(15) /*!< channel 1 output compare clear enable */ +#define TIMER_CHCTL0_CH0COMADDSEN BIT(28) /*!< channel 0 additional compare output shadow enable */ +#define TIMER_CHCTL0_CH1COMADDSEN BIT(29) /*!< channel 1 additional compare output shadow enable */ +#define TIMER_CHCTL0_CH0MS_BIT2 BIT(30) /*!< channel 0 I/O mode selection */ +#define TIMER_CHCTL0_CH1MS_BIT2 BIT(31) /*!< channel 1 I/O mode selection */ +/* 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 (TIMER_CHCTL1_CH2MS_BIT2 | BITS(0,1)) /*!< channel 2 mode selection */ +#define TIMER_CHCTL1_CH2COMSEN BIT(3) /*!< channel 2 output compare shadow enable */ +#define TIMER_CHCTL1_CH2COMCTL BITS(4,6) /*!< channel 2 output compare control */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS (TIMER_CHCTL1_CH3MS_BIT2 | BITS(8,9)) /*!< channel 3 mode selection */ +#define TIMER_CHCTL1_CH3COMSEN BIT(11) /*!< channel 3 output compare shadow enable */ +#define TIMER_CHCTL1_CH3COMCTL BITS(12,14) /*!< channel 3 output compare control */ +#define TIMER_CHCTL1_CH3COMCEN BIT(15) /*!< channel 3 output compare clear enable */ +#define TIMER_CHCTL1_CH2COMADDSEN BIT(28) /*!< channel 2 additional compare output shadow enable */ +#define TIMER_CHCTL1_CH3COMADDSEN BIT(29) /*!< channel 3 additional compare output shadow enable */ +#define TIMER_CHCTL1_CH2MS_BIT2 BIT(30) /*!< channel 2 I/O mode selection */ +#define TIMER_CHCTL1_CH3MS_BIT2 BIT(31) /*!< channel 3 I/O mode selection */ +/* input capture mode */ +#define TIMER_CHCTL1_CH2CAPPSC BITS(2,3) /*!< channel 2 input capture prescaler */ +#define TIMER_CHCTL1_CH2CAPFLT BITS(4,7) /*!< channel 2 input capture filter control */ +#define TIMER_CHCTL1_CH3CAPPSC BITS(10,11) /*!< channel 3 input capture prescaler */ +#define TIMER_CHCTL1_CH3CAPFLT BITS(12,15) /*!< channel 3 input capture filter control */ + +/* TIMER_CHCTL2 */ +#define TIMER_CHCTL2_CH0EN BIT(0) /*!< channel 0 capture or compare function enable */ +#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 capture or compare function polarity */ +#define TIMER_CHCTL2_CH0NEN BIT(2) /*!< channel 0 complementary output enable */ +#define TIMER_CHCTL2_CH0NP BIT(3) /*!< channel 0 complementary output polarity */ +#define TIMER_CHCTL2_CH1EN BIT(4) /*!< channel 1 capture or compare function enable */ +#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 capture or compare function polarity */ +#define TIMER_CHCTL2_CH1NEN BIT(6) /*!< channel 1 complementary output enable */ +#define TIMER_CHCTL2_CH1NP BIT(7) /*!< channel 1 complementary output polarity */ +#define TIMER_CHCTL2_CH2EN BIT(8) /*!< channel 2 capture or compare function enable */ +#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 capture or compare function polarity */ +#define TIMER_CHCTL2_CH2NEN BIT(10) /*!< channel 2 complementary output enable */ +#define TIMER_CHCTL2_CH2NP BIT(11) /*!< channel 2 complementary output polarity */ +#define TIMER_CHCTL2_CH3EN BIT(12) /*!< channel 3 capture or compare function enable */ +#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 capture or compare function polarity */ +#define TIMER_CHCTL2_CH3NEN BIT(14) /*!< channel 3 complementary output enable */ +#define TIMER_CHCTL2_CH3NP BIT(15) /*!< channel 3 complementary output polarity */ + +#define TIMER_CHCTL2_MCH0EN BIT(2) /*!< multi mode channel 0 capture or compare function enable */ +#define TIMER_CHCTL2_MCH0P BIT(3) /*!< multi mode channel 0 complementary output polarity */ +#define TIMER_CHCTL2_MCH1EN BIT(6) /*!< multi mode channel 1 capture or compare function enable */ +#define TIMER_CHCTL2_MCH1P BIT(7) /*!< multi mode channel 1 complementary output polarity */ +#define TIMER_CHCTL2_MCH2EN BIT(10) /*!< multi mode channel 2 capture or compare function enable */ +#define TIMER_CHCTL2_MCH2P BIT(11) /*!< multi mode channel 2 complementary output polarity */ +#define TIMER_CHCTL2_MCH3EN BIT(14) /*!< multi mode channel 3 capture or compare function enable */ +#define TIMER_CHCTL2_MCH3P BIT(15) /*!< multi mode channel 3 complementary output polarity */ + +/* TIMER_CNT */ +#define TIMER_CNT_CNT BITS(0,15) /*!< 16 bit timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL BITS(0,15) /*!< 16 bit counter auto reload value */ + +/* TIMER_CREP */ +#define TIMER_CREP_CREP BITS(0,7) /*!< counter repetition value */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL BITS(0,15) /*!< 16 bit capture or compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_MCHCTL0 */ +/* output compare mode */ +#define TIMER_MCHCTL0_MCH0MS (BITS(0,1) | BIT(30)) /*!< multi mode channel 0 I/O mode selection */ +#define TIMER_MCHCTL0_MCH0COMSEN BIT(3) /*!< multi mode channel 0 output compare shadow enable */ +#define TIMER_MCHCTL0_MCH0COMCTL BITS(4,6) /*!< multi mode channel 0 compare output control */ +#define TIMER_MCHCTL0_MCH0COMCEN BIT(7) /*!< multi mode channel 0 output compare clear enable */ +#define TIMER_MCHCTL0_MCH1MS (BITS(8,9) | BIT(31)) /*!< multi mode channel 1 I/O mode selection */ +#define TIMER_MCHCTL0_MCH1COMSEN BIT(11) /*!< multi mode channel 1 output compare shadow enable */ +#define TIMER_MCHCTL0_MCH1COMCTL BITS(12,14) /*!< multi mode channel 1 compare output control */ +#define TIMER_MCHCTL0_MCH1COMCEN BIT(15) /*!< multi mode channel 1 output compare clear enable */ +/* input capture mode */ +#define TIMER_MCHCTL0_MCH0CAPPSC BITS(2,3) /*!< multi mode channel 0 input capture prescaler */ +#define TIMER_MCHCTL0_MCH0CAPFLT BITS(4,7) /*!< multi mode channel 0 input capture filter control */ +#define TIMER_MCHCTL0_MCH1CAPPSC BITS(10,11) /*!< multi mode channel 1 input capture prescaler */ +#define TIMER_MCHCTL0_MCH1CAPFLT BITS(12,15) /*!< multi mode channel 1 input capture filter control */ + +/* TIMER_MCHCTL1 */ +/* output compare mode */ +#define TIMER_MCHCTL1_MCH2MS (BITS(0,1) | BIT(30)) /*!< multi mode channel 2 I/O mode selection */ +#define TIMER_MCHCTL1_MCH2COMSEN BIT(3) /*!< multi mode channel 2 output compare shadow enable */ +#define TIMER_MCHCTL1_MCH2COMCTL BITS(4,6) /*!< multi mode channel 2 compare output control */ +#define TIMER_MCHCTL1_MCH2COMCEN BIT(7) /*!< multi mode channel 2 output compare clear enable */ +#define TIMER_MCHCTL1_MCH3MS (BITS(8,9) | BIT(31)) /*!< multi mode channel 3 I/O mode selection */ +#define TIMER_MCHCTL1_MCH3COMSEN BIT(11) /*!< multi mode channel 3 output compare shadow enable */ +#define TIMER_MCHCTL1_MCH3COMCTL BITS(12,14) /*!< multi mode channel 3 compare output control */ +#define TIMER_MCHCTL1_MCH3COMCEN BIT(15) /*!< multi mode channel 3 output compare clear enable */ +/* input capture mode */ +#define TIMER_MCHCTL1_MCH2CAPPSC BITS(2,3) /*!< multi mode channel 2 input capture prescaler */ +#define TIMER_MCHCTL1_MCH2CAPFLT BITS(4,7) /*!< multi mode channel 2 input capture filter control */ +#define TIMER_MCHCTL1_MCH3CAPPSC BITS(10,11) /*!< multi mode channel 3 input capture prescaler */ +#define TIMER_MCHCTL1_MCH3CAPFLT BITS(12,15) /*!< multi mode channel 3 input capture filter control */ + +/* TIMER_MCHCTL2 */ +#define TIMER_MCHCTL2_MCH0FP BITS(0,1) /*!< multi mode channel 0 capture or compare function polarity */ +#define TIMER_MCHCTL2_MCH1FP BITS(2,3) /*!< multi mode channel 1 capture or compare function polarity */ +#define TIMER_MCHCTL2_MCH2FP BITS(4,5) /*!< multi mode channel 2 capture or compare function polarity */ +#define TIMER_MCHCTL2_MCH3FP BITS(6,7) /*!< multi mode channel 3 capture or compare function polarity */ + +/* TIMER_IRMP */ +#define TIMER1_IRMP_CI0_RMP BITS(0,1) /*!< TIMER1 channel 0 input remap */ + +/* TIMER_MCH0CV */ +#define TIMER_MCH0CV_MCH0VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 0 */ + +/* TIMER_MCH1CV */ +#define TIMER_MCH1CV_MCH1VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 1 */ + +/* TIMER_MCH2CV */ +#define TIMER_MCH2CV_MCH2VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 2 */ + +/* TIMER_MCH3CV */ +#define TIMER_MCH3CV_MCH3VAL BITS(0,15) /*!< 16 bit capture or compare value of multi mode channel 3 */ + +/* TIMER_CH0COMV_ADD */ +#define TIMER_CH0COMV_ADD_CH0COMVAL BITS(0,15) /*!< additional compare value of channel 0 */ + +/* TIMER_CH1COMV_ADD */ +#define TIMER_CH1COMV_ADD_CH0COMVAL BITS(0,15) /*!< additional compare value of channel 1 */ + +/* TIMER_CH2COMV_ADD */ +#define TIMER_CH2COMV_ADD_CH0COMVAL BITS(0,15) /*!< additional compare value of channel 2 */ + +/* TIMER_CH3COMV_ADD */ +#define TIMER_CH3COMV_ADD_CH0COMVAL BITS(0,15) /*!< additional compare value of channel 3 */ + +/* TIMER_CTL2 */ +#define TIMER_CTL2_DTIENCH0 BIT(0) /*!< dead time inserted enable for channel 0 and channel 0N */ +#define TIMER_CTL2_DTIENCH1 BIT(1) /*!< dead time inserted enable for channel 1 and channel 1N */ +#define TIMER_CTL2_DTIENCH2 BIT(2) /*!< dead time inserted enable for channel 2 and channel 2N */ +#define TIMER_CTL2_DTIENCH3 BIT(3) /*!< dead time inserted enable for channel 3 and channel 3N */ +#define TIMER_CTL2_BRKENCH0 BIT(4) /*!< break control enable for channel 0 and multi mode channel 0 */ +#define TIMER_CTL2_BRKENCH1 BIT(5) /*!< break control enable for channel 1 and multi mode channel 1 */ +#define TIMER_CTL2_BRKENCH2 BIT(6) /*!< break control enable for channel 2 and multi mode channel 2 */ +#define TIMER_CTL2_BRKENCH3 BIT(7) /*!< break control enable for channel 3 and multi mode channel 3 */ +#define TIMER_CTL2_CH0OMPSEL BITS(8,9) /*!< channel 0 output march pulse select */ +#define TIMER_CTL2_CH1OMPSEL BITS(10,11) /*!< channel 1 output march pulse select */ +#define TIMER_CTL2_CH2OMPSEL BITS(12,13) /*!< channel 2 output march pulse select */ +#define TIMER_CTL2_CH3OMPSEL BITS(14,15) /*!< channel 3 output march pulse select */ +#define TIMER_CTL2_MCH0MSEL BITS(20,21) /*!< multi mode channel 0 mode select */ +#define TIMER_CTL2_MCH1MSEL BITS(22,23) /*!< multi mode channel 1 mode select */ +#define TIMER_CTL2_MCH2MSEL BITS(24,25) /*!< multi mode channel 2 mode select */ +#define TIMER_CTL2_MCH3MSEL BITS(26,27) /*!< multi mode channel 3 mode select */ +#define TIMER_CTL2_CH0CPWMEN BIT(28) /*!< channel 0 composite PWM mode enable */ +#define TIMER_CTL2_CH1CPWMEN BIT(29) /*!< channel 1 composite PWM mode enable */ +#define TIMER_CTL2_CH2CPWMEN BIT(30) /*!< channel 2 composite PWM mode enable */ +#define TIMER_CTL2_CH3CPWMEN BIT(31) /*!< channel 3 composite PWM mode enable */ + +/* TIMER_BRKCFG */ +#define TIMER_BRKCFG_BRK0F BITS(0,3) /*!< BRKIN0 input signal filter */ +#define TIMER_BRKCFG_BRK1F BITS(4,7) /*!< BRKIN1 input signal filter */ +#define TIMER_BRKCFG_BRK2F BITS(8,11) /*!< BRKIN2 input signal filter */ +#define TIMER_BRKCFG_BRK3F BITS(12,15) /*!< BRKIN3 input signal filter */ +#define TIMER_BRKCFG_BRK0EN BIT(24) /*!< BRKIN0 input signal enable */ +#define TIMER_BRKCFG_BRK0P BIT(25) /*!< BRKIN0 input signal polarity */ +#define TIMER_BRKCFG_BRK1EN BIT(26) /*!< BRKIN1 input signal enable */ +#define TIMER_BRKCFG_BRK1P BIT(27) /*!< BRKIN1 input signal polarity */ +#define TIMER_BRKCFG_BRK2EN BIT(28) /*!< BRKIN2 input signal enable */ +#define TIMER_BRKCFG_BRK2P BIT(29) /*!< BRKIN2 input signal polarity */ +#define TIMER_BRKCFG_BRK3EN BIT(30) /*!< BRKIN3 input signal enable */ +#define TIMER_BRKCFG_BRK3P BIT(31) /*!< BRKIN3 input signal polarity */ + +/* TIMER_FCCHP0 */ +#define TIMER_FCCHP0_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP0_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP0_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP0_FCCHP0EN BIT(31) /*!< free complementary channel protection register 0 enable */ + +/* TIMER_FCCHP1 */ +#define TIMER_FCCHP1_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP1_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP1_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP1_FCCHP1EN BIT(31) /*!< free complementary channel protection register 1 enable */ + +/* TIMER_FCCHP2 */ +#define TIMER_FCCHP2_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP2_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP2_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP2_FCCHP2EN BIT(31) /*!< free complementary channel protection register 2 enable */ + +/* TIMER_FCCHP3 */ +#define TIMER_FCCHP3_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_FCCHP3_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_FCCHP3_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_FCCHP3_FCCHP3EN BIT(31) /*!< free complementary channel protection register 3 enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,5) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,13) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,31) /*!< DMA transfer buffer address */ + +/* 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 */ + uint8_t repetitioncounter; /*!< the counter repetition value */ +} timer_parameter_struct; + +/* break parameter struct definitions */ +typedef struct { + uint16_t runoffstate; /*!< run mode off-state */ + uint16_t ideloffstate; /*!< idle mode off-state */ + uint16_t deadtime; /*!< dead time */ + uint16_t breakpolarity; /*!< break polarity */ + uint16_t outputautostate; /*!< output automatic enable */ + uint16_t protectmode; /*!< complementary register protect control */ + uint16_t breakstate; /*!< break enable */ +} timer_break_parameter_struct; + +/* channel output parameter struct definitions */ +typedef struct { + uint16_t outputstate; /*!< channel output state */ + uint16_t outputnstate; /*!< channel complementary output state */ + uint16_t ocpolarity; /*!< channel output polarity */ + uint16_t ocnpolarity; /*!< channel complementary output polarity */ + uint16_t ocidlestate; /*!< idle state of channel output */ + uint16_t ocnidlestate; /*!< idle state of channel complementary output */ +} timer_oc_parameter_struct; + +/* multi mode channel output parameter struct definitions */ +typedef struct { + uint16_t outputmode; /*!< multi mode channel output mode selection */ + uint16_t outputstate; /*!< multi mode channel output state */ + uint16_t ocpolarity; /*!< multi mode channel output polarity */ +} timer_omc_parameter_struct; + +/* channel input parameter struct definitions */ +typedef struct { + uint16_t icpolarity; /*!< channel input polarity */ + uint16_t icselection; /*!< channel input mode selection */ + uint16_t icprescaler; /*!< channel input capture prescaler */ + uint16_t icfilter; /*!< channel input capture filter control */ +} timer_ic_parameter_struct; + +/* break external input parameter struct definitions */ +typedef struct { + uint32_t filter; /*!< break external input filter */ + uint32_t enable; /*!< break external input enable */ + uint32_t polarity; /*!< break external input polarity */ +} timer_break_ext_input_struct; + +/* channel free complementary parameter struct definitions */ +typedef struct { + uint32_t freecomstate; /*!< free complementary channel protection enable */ + uint32_t runoffstate; /*!< run mode off-state */ + uint32_t ideloffstate; /*!< idle mode off-state */ + uint32_t deadtime; /*!< dead time */ +} timer_free_complementary_parameter_struct; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 capture or compare interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 capture or compare interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 capture or compare interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 capture or compare interrupt */ +#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */ +#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */ +#define TIMER_INT_MCH0 TIMER_DMAINTEN_MCH0IE /*!< multi mode channel 0 capture or compare interrupt */ +#define TIMER_INT_MCH1 TIMER_DMAINTEN_MCH1IE /*!< multi mode channel 1 capture or compare interrupt */ +#define TIMER_INT_MCH2 TIMER_DMAINTEN_MCH2IE /*!< multi mode channel 2 capture or compare interrupt */ +#define TIMER_INT_MCH3 TIMER_DMAINTEN_MCH3IE /*!< multi mode channel 3 capture or compare interrupt */ +#define TIMER_INT_CH0COMADD TIMER_DMAINTEN_CH0COMADDIE /*!< channel 0 additional compare interrupt */ +#define TIMER_INT_CH1COMADD TIMER_DMAINTEN_CH1COMADDIE /*!< channel 1 additional compare interrupt */ +#define TIMER_INT_CH2COMADD TIMER_DMAINTEN_CH2COMADDIE /*!< channel 2 additional compare interrupt */ +#define TIMER_INT_CH3COMADD TIMER_DMAINTEN_CH3COMADDIE /*!< channel 3 additional compare interrupt */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INT_UP /*!< update interrupt flag */ +#define TIMER_INT_FLAG_CH0 TIMER_INT_CH0 /*!< channel 0 interrupt flag */ +#define TIMER_INT_FLAG_CH1 TIMER_INT_CH1 /*!< channel 1 interrupt flag */ +#define TIMER_INT_FLAG_CH2 TIMER_INT_CH2 /*!< channel 2 interrupt flag */ +#define TIMER_INT_FLAG_CH3 TIMER_INT_CH3 /*!< channel 3 interrupt flag */ +#define TIMER_INT_FLAG_CMT TIMER_INT_CMT /*!< channel commutation interrupt flag */ +#define TIMER_INT_FLAG_TRG TIMER_INT_TRG /*!< trigger interrupt flag */ +#define TIMER_INT_FLAG_BRK TIMER_INT_BRK /*!< break interrupt flag */ +#define TIMER_INT_FLAG_MCH0 TIMER_INT_MCH0 /*!< multi mode channel 0 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_MCH1 TIMER_INT_MCH1 /*!< multi mode channel 1 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_MCH2 TIMER_INT_MCH2 /*!< multi mode channel 2 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_MCH3 TIMER_INT_MCH3 /*!< multi mode channel 3 capture or compare interrupt flag */ +#define TIMER_INT_FLAG_CH0COMADD TIMER_INT_CH0COMADD /*!< channel 0 additional compare interrupt flag */ +#define TIMER_INT_FLAG_CH1COMADD TIMER_INT_CH1COMADD /*!< channel 1 additional compare interrupt flag */ +#define TIMER_INT_FLAG_CH2COMADD TIMER_INT_CH2COMADD /*!< channel 2 additional compare interrupt flag */ +#define TIMER_INT_FLAG_CH3COMADD TIMER_INT_CH3COMADD /*!< channel 3 additional compare interrupt flag */ + +/* TIMER flag */ +#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */ +#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 capture or compare flag */ +#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 capture or compare flag */ +#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 capture or compare flag */ +#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 capture or compare flag */ +#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation flag */ +#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */ +#define TIMER_FLAG_BRK TIMER_INTF_BRKIF /*!< break flag */ +#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */ +#define TIMER_FLAG_MCH0 TIMER_INTF_MCH0IF /*!< multi mode channel 0 capture or compare flag */ +#define TIMER_FLAG_MCH1 TIMER_INTF_MCH1IF /*!< multi mode channel 1 capture or compare flag */ +#define TIMER_FLAG_MCH2 TIMER_INTF_MCH2IF /*!< multi mode channel 2 capture or compare flag */ +#define TIMER_FLAG_MCH3 TIMER_INTF_MCH3IF /*!< multi mode channel 3 capture or compare flag */ +#define TIMER_FLAG_MCH0O TIMER_INTF_MCH0OF /*!< multi mode channel 0 overcapture flag */ +#define TIMER_FLAG_MCH1O TIMER_INTF_MCH1OF /*!< multi mode channel 1 overcapture flag */ +#define TIMER_FLAG_MCH2O TIMER_INTF_MCH2OF /*!< multi mode channel 2 overcapture flag */ +#define TIMER_FLAG_MCH3O TIMER_INTF_MCH3OF /*!< multi mode channel 3 overcapture flag */ +#define TIMER_FLAG_CH0COMADD TIMER_INTF_CH0COMADDIF /*!< channel 0 additional compare interrupt flag */ +#define TIMER_FLAG_CH1COMADD TIMER_INTF_CH1COMADDIF /*!< channel 1 additional compare interrupt flag */ +#define TIMER_FLAG_CH2COMADD TIMER_INTF_CH2COMADDIF /*!< channel 2 additional compare interrupt flag */ +#define TIMER_FLAG_CH3COMADD TIMER_INTF_CH3COMADDIF /*!< channel 3 additional compare interrupt flag */ + +/* TIMER DMA source */ +#define TIMER_DMA_UPD TIMER_DMAINTEN_UPDEN /*!< update DMA request */ +#define TIMER_DMA_CH0D TIMER_DMAINTEN_CH0DEN /*!< channel 0 capture or compare DMA request */ +#define TIMER_DMA_CH1D TIMER_DMAINTEN_CH1DEN /*!< channel 1 capture or compare DMA request */ +#define TIMER_DMA_CH2D TIMER_DMAINTEN_CH2DEN /*!< channel 2 capture or compare DMA request */ +#define TIMER_DMA_CH3D TIMER_DMAINTEN_CH3DEN /*!< channel 3 capture or compare DMA request */ +#define TIMER_DMA_CMTD TIMER_DMAINTEN_CMTDEN /*!< commutation DMA request */ +#define TIMER_DMA_TRGD TIMER_DMAINTEN_TRGDEN /*!< trigger DMA request */ +#define TIMER_DMA_MCH0D TIMER_DMAINTEN_MCH0DEN /*!< multi mode channel 0 capture or compare DMA request */ +#define TIMER_DMA_MCH1D TIMER_DMAINTEN_MCH1DEN /*!< multi mode channel 1 capture or compare DMA request */ +#define TIMER_DMA_MCH2D TIMER_DMAINTEN_MCH2DEN /*!< multi mode channel 2 capture or compare DMA request */ +#define TIMER_DMA_MCH3D TIMER_DMAINTEN_MCH3DEN /*!< multi mode channel 3 capture or compare DMA request */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT TIMER_CTL1_DMAS /*!< DMA request of channel n is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint32_t)0x00000000U) /*!< DMA request of channel n is sent when channel n event occurs */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_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_MCHCTL0 DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_MCHCTL0 */ +#define TIMER_DMACFG_DMATA_MCHCTL1 DMACFG_DMATA(19) /*!< DMA transfer address is TIMER_MCHCTL1 */ +#define TIMER_DMACFG_DMATA_MCHCTL2 DMACFG_DMATA(20) /*!< DMA transfer address is TIMER_MCHCTL2 */ +#define TIMER_DMACFG_DMATA_MCH0CV DMACFG_DMATA(21) /*!< DMA transfer address is TIMER_MCH0CV */ +#define TIMER_DMACFG_DMATA_MCH1CV DMACFG_DMATA(22) /*!< DMA transfer address is TIMER_MCH1CV */ +#define TIMER_DMACFG_DMATA_MCH2CV DMACFG_DMATA(23) /*!< DMA transfer address is TIMER_MCH2CV */ +#define TIMER_DMACFG_DMATA_MCH3CV DMACFG_DMATA(24) /*!< DMA transfer address is TIMER_MCH3CV */ +#define TIMER_DMACFG_DMATA_CH0COMV_ADD DMACFG_DMATA(25) /*!< DMA transfer address is TIMER_CH0COMV_ADD */ +#define TIMER_DMACFG_DMATA_CH1COMV_ADD DMACFG_DMATA(26) /*!< DMA transfer address is TIMER_CH1COMV_ADD */ +#define TIMER_DMACFG_DMATA_CH2COMV_ADD DMACFG_DMATA(27) /*!< DMA transfer address is TIMER_CH2COMV_ADD */ +#define TIMER_DMACFG_DMATA_CH3COMV_ADD DMACFG_DMATA(28) /*!< DMA transfer address is TIMER_CH3COMV_ADD */ +#define TIMER_DMACFG_DMATA_CTL2 DMACFG_DMATA(29) /*!< DMA transfer address is TIMER_CTL2 */ +#define TIMER_DMACFG_DMATA_BRKCFG DMACFG_DMATA(30) /*!< DMA transfer address is TIMER_BRKCFG */ +#define TIMER_DMACFG_DMATA_FCCHP0 DMACFG_DMATA(31) /*!< DMA transfer address is TIMER_FCCHP0 */ +#define TIMER_DMACFG_DMATA_FCCHP1 DMACFG_DMATA(32) /*!< DMA transfer address is TIMER_FCCHP1 */ +#define TIMER_DMACFG_DMATA_FCCHP2 DMACFG_DMATA(33) /*!< DMA transfer address is TIMER_FCCHP2 */ +#define TIMER_DMACFG_DMATA_FCCHP3 DMACFG_DMATA(34) /*!< DMA transfer address is TIMER_FCCHP3 */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8,13) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ +#define TIMER_DMACFG_DMATC_19TRANSFER DMACFG_DMATC(18) /*!< DMA transfer 19 times */ +#define TIMER_DMACFG_DMATC_20TRANSFER DMACFG_DMATC(19) /*!< DMA transfer 20 times */ +#define TIMER_DMACFG_DMATC_21TRANSFER DMACFG_DMATC(20) /*!< DMA transfer 21 times */ +#define TIMER_DMACFG_DMATC_22TRANSFER DMACFG_DMATC(21) /*!< DMA transfer 22 times */ +#define TIMER_DMACFG_DMATC_23TRANSFER DMACFG_DMATC(22) /*!< DMA transfer 23 times */ +#define TIMER_DMACFG_DMATC_24TRANSFER DMACFG_DMATC(23) /*!< DMA transfer 24 times */ +#define TIMER_DMACFG_DMATC_25TRANSFER DMACFG_DMATC(24) /*!< DMA transfer 25 times */ +#define TIMER_DMACFG_DMATC_26TRANSFER DMACFG_DMATC(25) /*!< DMA transfer 26 times */ +#define TIMER_DMACFG_DMATC_27TRANSFER DMACFG_DMATC(26) /*!< DMA transfer 27 times */ +#define TIMER_DMACFG_DMATC_28TRANSFER DMACFG_DMATC(27) /*!< DMA transfer 28 times */ +#define TIMER_DMACFG_DMATC_29TRANSFER DMACFG_DMATC(28) /*!< DMA transfer 29 times */ +#define TIMER_DMACFG_DMATC_30TRANSFER DMACFG_DMATC(29) /*!< DMA transfer 30 times */ +#define TIMER_DMACFG_DMATC_31TRANSFER DMACFG_DMATC(30) /*!< DMA transfer 31 times */ +#define TIMER_DMACFG_DMATC_32TRANSFER DMACFG_DMATC(31) /*!< DMA transfer 32 times */ +#define TIMER_DMACFG_DMATC_33TRANSFER DMACFG_DMATC(32) /*!< DMA transfer 33 times */ +#define TIMER_DMACFG_DMATC_34TRANSFER DMACFG_DMATC(33) /*!< DMA transfer 34 times */ +#define TIMER_DMACFG_DMATC_35TRANSFER DMACFG_DMATC(34) /*!< DMA transfer 35 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG TIMER_SWEVG_UPG /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G TIMER_SWEVG_CH0G /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G TIMER_SWEVG_CH1G /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G TIMER_SWEVG_CH2G /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G TIMER_SWEVG_CH3G /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG TIMER_SWEVG_CMTG /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG TIMER_SWEVG_TRGG /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG TIMER_SWEVG_BRKG /*!< break event generation */ +#define TIMER_EVENT_SRC_MCH0G TIMER_SWEVG_MCH0G /*!< multi mode channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_MCH1G TIMER_SWEVG_MCH1G /*!< multi mode channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_MCH2G TIMER_SWEVG_MCH2G /*!< multi mode channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_MCH3G TIMER_SWEVG_MCH3G /*!< multi mode channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH0COMADDG TIMER_SWEVG_CH0COMADDG /*!< channel 0 additional compare event generation */ +#define TIMER_EVENT_SRC_CH1COMADDG TIMER_SWEVG_CH1COMADDG /*!< channel 1 additional compare event generation */ +#define TIMER_EVENT_SRC_CH2COMADDG TIMER_SWEVG_CH2COMADDG /*!< channel 2 additional compare event generation */ +#define TIMER_EVENT_SRC_CH3COMADDG TIMER_SWEVG_CH3COMADDG /*!< channel 3 additional compare event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5,6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW TIMER_SWEVG_UPG /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000000U) /*!< the prescaler is loaded at the next update event */ + +/* count direction */ +#define TIMER_COUNTER_UP ((uint16_t)0x0000U) /*!< counter up direction */ +#define TIMER_COUNTER_DOWN ((uint16_t)TIMER_CTL0_DIR) /*!< counter down direction */ + +/* specify division ratio between TIMER clock and dead-time and sampling clock */ +#define CTL0_CKDIV(regval) ((uint16_t)(BITS(8,9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CKDIV_DIV1 CTL0_CKDIV(0) /*!< clock division value is 1, fDTS = fTIMER_CK */ +#define TIMER_CKDIV_DIV2 CTL0_CKDIV(1) /*!< clock division value is 2, fDTS = fTIMER_CK/2 */ +#define TIMER_CKDIV_DIV4 CTL0_CKDIV(2) /*!< clock division value is 4, fDTS = fTIMER_CK/4 */ + +/* single pulse mode */ +#define TIMER_SP_MODE_SINGLE TIMER_CTL0_SPM /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000000U) /*!< repetitive pulse mode */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR TIMER_CTL0_UPS /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000000U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ + +/* run mode off-state configure */ +#define TIMER_ROS_STATE_ENABLE ((uint32_t)TIMER_CCHP_ROS) /*!< when POEN bit is set, the channel output signals(CHx_O/MCHx) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_ROS_STATE_DISABLE ((uint32_t)0x00000000U) /*!< when POEN bit is set, the channel output signals(CHx_O/MCHx) are disabled */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint32_t)TIMER_CCHP_IOS) /*!< when POEN bit is reset, the channel output signals(CHx_O/MCHx) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_IOS_STATE_DISABLE ((uint32_t)0x00000000U) /*!< when POEN bit is reset, the channel output signals(CHx_O/MCHx) are disabled */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint32_t)0x00000000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint32_t)TIMER_CCHP_BRKP) /*!< break input polarity is high */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint32_t)TIMER_CCHP_OAEN) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint32_t)0x00000000U) /*!< output automatic disable */ + +/* complementary register protect control */ +#define CCHP_PROT(regval) ((uint16_t)(BITS(8,9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CCHP_PROT_OFF CCHP_PROT(0) /*!< protect disable */ +#define TIMER_CCHP_PROT_0 CCHP_PROT(1) /*!< PROT mode 0 */ +#define TIMER_CCHP_PROT_1 CCHP_PROT(2) /*!< PROT mode 1 */ +#define TIMER_CCHP_PROT_2 CCHP_PROT(3) /*!< PROT mode 2 */ + +/* break input enable */ +#define TIMER_BREAK_ENABLE ((uint16_t)TIMER_CCHP_BRKEN) /*!< break input enable */ +#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */ + +/* free complementary channel protection configure */ +#define TIMER_FCCHP_STATE_ENABLE ((uint32_t)TIMER_FCCHP0_FCCHP0EN) /*!< free complementary channel protection enable */ +#define TIMER_FCCHP_STATE_DISABLE ((uint32_t)0x00000000U) /*!< free complementary channel protection disable */ + +/* TIMER external break input source */ +#define TIMER_BREAKINPUT_BRK0 ((uint16_t)0x0000U) /*!< TIMER break external input 0 */ +#define TIMER_BREAKINPUT_BRK1 ((uint16_t)0x0001U) /*!< TIMER break external input 1 */ +#define TIMER_BREAKINPUT_BRK2 ((uint16_t)0x0002U) /*!< TIMER break external input 2 */ +#define TIMER_BREAKINPUT_BRK3 ((uint16_t)0x0003U) /*!< TIMER break external input 3 */ + +/* TIMER Break external input polarity*/ +#define TIMER_BRKIN_POLARITY_LOW ((uint16_t)0x0000U) /*!< TIMER break external input polarity is active low */ +#define TIMER_BRKIN_POLARITY_HIGH ((uint16_t)0x0001U) /*!< TIMER break external input polarity is active high */ + +/* TIMER channel n(n=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel 0 */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1 */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2 */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3 */ +#define TIMER_CH_0N ((uint16_t)0x0010U) /*!< TIMER complementary output channel 0 */ +#define TIMER_CH_1N ((uint16_t)0x0011U) /*!< TIMER complementary output channel 1 */ +#define TIMER_CH_2N ((uint16_t)0x0012U) /*!< TIMER complementary output channel 2 */ +#define TIMER_CH_3N ((uint16_t)0x0013U) /*!< TIMER complementary output channel 3 */ +#define TIMER_MCH_0 ((uint16_t)0x0010U) /*!< TIMER multi mode channel 0 */ +#define TIMER_MCH_1 ((uint16_t)0x0011U) /*!< TIMER multi mode channel 1 */ +#define TIMER_MCH_2 ((uint16_t)0x0012U) /*!< TIMER multi mode channel 2 */ +#define TIMER_MCH_3 ((uint16_t)0x0013U) /*!< TIMER multi mode channel 3 */ + +/* channel enable state */ +#define TIMER_CCX_ENABLE ((uint16_t)0x0001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint16_t)0x0000U) /*!< channel disable */ + +/* channel complementary output enable state */ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* multi mode channel enable state */ +#define TIMER_MCCX_ENABLE ((uint16_t)0x0004U) /*!< multi mode channel enable */ +#define TIMER_MCCX_DISABLE ((uint16_t)0x0000U) /*!< multi mode channel disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* multi mode channel output polarity */ +#define TIMER_OMC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< multi mode channel output polarity is high */ +#define TIMER_OMC_POLARITY_LOW ((uint16_t)0x0001U) /*!< multi mode channel output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)0x0100U) /*!< idle state of channel output is high */ +#define TIMER_OC_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel output is low */ + +/* idle state of channel complementary output */ +#define TIMER_OCN_IDLE_STATE_HIGH ((uint16_t)0x0200U) /*!< idle state of channel complementary output is high */ +#define TIMER_OCN_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel complementary output is low */ + +/* idle state of multi mode channel output */ +#define TIMER_OMC_IDLE_STATE_HIGH ((uint16_t)0x0100U) /*!< idle state of multi mode channel output is high */ +#define TIMER_OMC_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of multi mode channel output is low */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM mode 0 */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM mode 1 */ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output compare shadow enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output compare shadow disable */ + +/* channel output compare clear enable */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define TIMER_UPDATECTL_CCU ((uint32_t)0x00000000U) /*!< the shadow registers update by when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI TIMER_CTL1_CCUC /*!< 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 n is configured as input and icy is mapped on CIy / CINy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel n is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel n is configured as input and icy is mapped on ITS */ +#define TIMER_IC_SELECTION_PAIR ((uint16_t)0x0004U) /*!< channel n is configured as input and icy is mapped on the other channel of same pair */ + +/* channel input capture prescaler */ +#define TIMER_IC_PSC_DIV1 ((uint16_t)0x0000U) /*!< no prescaler */ +#define TIMER_IC_PSC_DIV2 ((uint16_t)0x0004U) /*!< divided by 2 */ +#define TIMER_IC_PSC_DIV4 ((uint16_t)0x0008U) /*!< divided by 4 */ +#define TIMER_IC_PSC_DIV8 ((uint16_t)0x000CU) /*!< divided by 8 */ + +/* trigger selection */ +#define SMCFG_TRGSEL(regval) ((BITS(4,6) & ((uint32_t)(regval) << 4U)) | (BIT(31) & ((uint32_t)(regval) << 28U))) +#define TIMER_SMCFG_TRGSEL_ITI0 SMCFG_TRGSEL(0) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI1 SMCFG_TRGSEL(1) /*!< internal trigger 1 */ +#define TIMER_SMCFG_TRGSEL_ITI2 SMCFG_TRGSEL(2) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 SMCFG_TRGSEL(3) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED SMCFG_TRGSEL(4) /*!< TI0 edge detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 SMCFG_TRGSEL(5) /*!< filtered channel 0 input */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 SMCFG_TRGSEL(6) /*!< filtered channel 1 input */ +#define TIMER_SMCFG_TRGSEL_ETIFP SMCFG_TRGSEL(7) /*!< filtered external trigger input */ +#define TIMER_SMCFG_TRGSEL_CI2FE2 SMCFG_TRGSEL(8) /*!< filtered channel 2 input */ +#define TIMER_SMCFG_TRGSEL_CI3FE3 SMCFG_TRGSEL(9) /*!< filtered channel 3 input */ +#define TIMER_SMCFG_TRGSEL_MCI0FEM0 SMCFG_TRGSEL(10) /*!< filtered multi mode channel 0 input */ +#define TIMER_SMCFG_TRGSEL_MCI1FEM1 SMCFG_TRGSEL(11) /*!< filtered multi mode channel 1 input */ +#define TIMER_SMCFG_TRGSEL_MCI2FEM2 SMCFG_TRGSEL(12) /*!< filtered multi mode channel 2 input */ +#define TIMER_SMCFG_TRGSEL_MCI3FEM3 SMCFG_TRGSEL(13) /*!< filtered multi mode channel 3 input */ + +/* 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 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 */ + +/* slave mode control */ +#define SMCFG_SMC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define TIMER_SLAVE_MODE_DISABLE SMCFG_SMC(0) /*!< slave mode disable */ +#define TIMER_ENCODER_MODE0 SMCFG_SMC(1) /*!< encoder mode 0 */ +#define TIMER_ENCODER_MODE1 SMCFG_SMC(2) /*!< encoder mode 1 */ +#define TIMER_ENCODER_MODE2 SMCFG_SMC(3) /*!< encoder mode 2 */ +#define TIMER_SLAVE_MODE_RESTART SMCFG_SMC(4) /*!< restart mode */ +#define TIMER_SLAVE_MODE_PAUSE SMCFG_SMC(5) /*!< pause mode */ +#define TIMER_SLAVE_MODE_EVENT SMCFG_SMC(6) /*!< event mode */ +#define TIMER_SLAVE_MODE_EXTERNAL0 SMCFG_SMC(7) /*!< external clock mode 0 */ + +/* master slave mode selection */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE TIMER_SMCFG_MSM /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000000U) /*!< master slave mode disable */ + +/* external trigger prescaler */ +#define SMCFG_ETPSC(regval) (BITS(12,13) & ((uint32_t)(regval) << 12U)) +#define TIMER_EXT_TRI_PSC_OFF SMCFG_ETPSC(0) /*!< no divided */ +#define TIMER_EXT_TRI_PSC_DIV2 SMCFG_ETPSC(1) /*!< divided by 2 */ +#define TIMER_EXT_TRI_PSC_DIV4 SMCFG_ETPSC(2) /*!< divided by 4 */ +#define TIMER_EXT_TRI_PSC_DIV8 SMCFG_ETPSC(3) /*!< divided by 8 */ + +/* external trigger polarity */ +#define TIMER_ETP_FALLING TIMER_SMCFG_ETP /*!< active low or falling edge active */ +#define TIMER_ETP_RISING ((uint32_t)0x00000000U) /*!< active high or rising edge active */ + +/* channel 0 trigger input selection */ +#define TIMER_HALLINTERFACE_ENABLE TIMER_CTL1_TI0S /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode disable */ + +/* TIMER1 channel 0 input remap */ +#define TIMER1_IRMP(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0U)) +#define TIMER1_CI0_RMP_GPIO TIMER1_IRMP(0) /*!< TIMER1 channel 0 input remap to GPIO pin */ +#define TIMER1_CI0_RMP_LXTAL TIMER1_IRMP(1) /*!< TIMER1 channel 0 input remap to LXTAL */ +#define TIMER1_CI0_RMP_HXTAL TIMER1_IRMP(2) /*!< TIMER1 channel 0 input remap to HXTAL/128 */ +#define TIMER1_CI0_RMP_CKOUT0SEL TIMER1_IRMP(3) /*!< TIMER1 channel 0 input remap to CKOUT0SEL */ + +/* TIMER write CHxVAL register selection */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)TIMER_CFG_CHVSEL) /*!< write CHxVAL register selection enable */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CHxVAL register selection disable */ + +/* TIMER output value selection enable */ +#define TIMER_OUTSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< output value selection enable */ +#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection disable */ + +/* channel additional output compare shadow enable */ +#define TIMER_ADD_SHADOW_ENABLE ((uint16_t)0x0001U) /*!< channel additional output shadow state enable */ +#define TIMER_ADD_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel additional output shadow state disable */ + +/* channel output compare shadow enable */ +#define TIMER_OMC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< multi mode channel output shadow state enable */ +#define TIMER_OMC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< multi mode channel output shadow state disable */ + +/* channel output compare clear enable */ +#define TIMER_OMC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< multi mode channel output clear function enable */ +#define TIMER_OMC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< multi mode channel output clear function disable */ + +/* TIMER output value selection */ +#define TIMER_PULSE_OUTPUT_NORMAL ((uint16_t)0x0000U) /*!< channel output normal */ +#define TIMER_PULSE_OUTPUT_CNT_UP ((uint16_t)0x0001U) /*!< pulse output only when counting up */ +#define TIMER_PULSE_OUTPUT_CNT_DOWN ((uint16_t)0x0002U) /*!< pulse output only when counting down */ +#define TIMER_PULSE_OUTPUT_CNT_BOTH ((uint16_t)0x0003U) /*!< pulse output when counting up or down */ +#define TIMER_PULSE_OUTPUT_MASK ((uint16_t)0x0003U) /*!< pulse output mode mask */ + +/* multi mode channel input capture polarity */ +#define TIMER_IMC_POLARITY_RISING ((uint16_t)0x0000U) /*!< multi mode channel input capture rising edge */ +#define TIMER_IMC_POLARITY_FALLING ((uint16_t)0x0001U) /*!< multi mode channel input capture falling edge */ +#define TIMER_IMC_POLARITY_BOTH_EDGE ((uint16_t)0x0003U) /*!< multi mode channel input capture both edge */ + +/* TIMER multi mode channel mode selection */ +#define TIMER_MCH_MODE_INDEPENDENTLY ((uint16_t)0x0000U) /*!< multi mode channel work in independently mode */ +#define TIMER_MCH_MODE_MIRRORED ((uint16_t)0x0001U) /*!< multi mode channel work in mirrored output mode */ +#define TIMER_MCH_MODE_COMPLEMENTARY ((uint16_t)0x0003U) /*!< multi mode channel work in complementary output mode */ +#define TIMER_MCH_MODE_MASK ((uint16_t)0x0003U) /*!< multi mode channel mode mask */ + +/* function declarations */ +/* TIMER timebase */ +/* deinit a TIMER */ +void timer_deinit(uint32_t timer_periph); +/* initialize TIMER init parameter struct */ +void timer_struct_para_init(timer_parameter_struct *initpara); +/* initialize TIMER counter */ +void timer_init(uint32_t timer_periph, timer_parameter_struct *initpara); +/* enable a TIMER */ +void timer_enable(uint32_t timer_periph); +/* disable a TIMER */ +void timer_disable(uint32_t timer_periph); +/* enable the auto reload shadow function */ +void timer_auto_reload_shadow_enable(uint32_t timer_periph); +/* disable the auto reload shadow function */ +void timer_auto_reload_shadow_disable(uint32_t timer_periph); +/* enable the update event */ +void timer_update_event_enable(uint32_t timer_periph); +/* disable the update event */ +void timer_update_event_disable(uint32_t timer_periph); +/* set TIMER counter alignment mode */ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned); +/* set TIMER counter up direction */ +void timer_counter_up_direction(uint32_t timer_periph); +/* set TIMER counter down direction */ +void timer_counter_down_direction(uint32_t timer_periph); + +/* configure TIMER prescaler */ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint32_t pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t 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 */ +uint32_t timer_counter_read(uint32_t timer_periph); +/* read TIMER prescaler value */ +uint16_t timer_prescaler_read(uint32_t timer_periph); +/* configure TIMER single pulse mode */ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint32_t update); +/* configure channel commutation control shadow register */ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure TIMER channel control shadow register update control */ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint32_t ccuctl); + +/* TIMER DMA and event */ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph, uint32_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint32_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_t dma_request); +/* configure the TIMER DMA transfer */ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth); +/* software generate events */ +void timer_event_software_generate(uint32_t timer_periph, uint32_t event); + +/* TIMER channel complementary protection */ +/* initialize TIMER break parameter struct */ +void timer_break_struct_para_init(timer_break_parameter_struct *breakpara); +/* configure TIMER break function */ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara); +/* enable TIMER break function */ +void timer_break_enable(uint32_t timer_periph); +/* disable TIMER break function */ +void timer_break_disable(uint32_t timer_periph); +/* enable TIMER output automatic function */ +void timer_automatic_output_enable(uint32_t timer_periph); +/* disable TIMER output automatic function */ +void timer_automatic_output_disable(uint32_t timer_periph); +/* configure TIMER primary output function */ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue); + +/* TIMER channel output */ +/* initialize TIMER channel output parameter struct */ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara); +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct *ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse); +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear); +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state); +/* configure TIMER channel complementary output enable state */ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate); + +/* TIMER channel input */ +/* initialize TIMER channel input parameter struct */ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct *icpara); +/* configure TIMER input capture parameter */ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpara); +/* configure TIMER channel input capture prescaler value */ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler); +/* read TIMER channel capture compare register value */ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel); +/* configure TIMER input pwm capture function */ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpwm); +/* configure TIMER hall sensor mode */ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode); + +/* TIMER multi mode channel */ +/* initialize TIMER multi mode channel output parameter struct */ +void timer_multi_mode_channel_output_parameter_struct_init(timer_omc_parameter_struct *omcpara); +/* configure TIMER multi mode channel output function */ +void timer_multi_mode_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_omc_parameter_struct *omcpara); +/* multi mode channel mode select */ +void timer_multi_mode_channel_mode_config(uint32_t timer_periph, uint32_t channel, uint32_t multi_mode_sel); + +/* TIMER master and slave mode */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger); +/* select TIMER slave mode */ +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode); +/* configure TIMER master slave mode */ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave); +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER quadrature decoder mode */ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity); +/* configure TIMER internal clock mode */ +void timer_internal_clock_config(uint32_t timer_periph); +/* configure TIMER the internal trigger as external clock input */ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger); +/* configure TIMER the external trigger as external clock input */ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 0 */ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 1 */ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); + +/* TIMER configure */ +/* configure TIMER channel input remap function */ +void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap); +/* 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 TIMER output match pulse selection */ +void timer_output_match_pulse_select(uint32_t timer_periph, uint32_t channel, uint16_t pulsesel); + +/* TIMER composite PWM mode */ +/* configure the TIMER composite PWM mode */ +void timer_channel_composite_pwm_mode_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue); +/* configure the TIMER composite PWM mode output pulse value */ +void timer_channel_composite_pwm_mode_output_pulse_value_config(uint32_t timer_periph, uint32_t channel, uint32_t pulse, uint32_t add_pulse); +/* configure TIMER channel additional compare value */ +void timer_channel_additional_compare_value_config(uint32_t timer_periph, uint16_t channel, uint32_t value); +/* configure TIMER channel additional output shadow function */ +void timer_channel_additional_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t aocshadow); + +/* TIMER break external inputs */ +/* initialize TIMER break external input parameter struct */ +void timer_break_external_input_struct_para_init(timer_break_ext_input_struct *breakinpara); +/* configure TIMER break external input polarity */ +void timer_break_external_input_config(uint32_t timer_periph, uint32_t break_input, timer_break_ext_input_struct *breakinpara); +/* break external input enable */ +void timer_break_external_input_enable(uint32_t timer_periph, uint32_t break_input); +/* break external input disable */ +void timer_break_external_input_disable(uint32_t timer_periph, uint32_t break_input); +/* configure TIMER break external input polarity */ +void timer_break_external_input_polarity_config(uint32_t timer_periph, uint32_t break_input, uint32_t polarity); + +/* TIMER channel free complementary protection */ +/* configure the TIMER channel break function */ +void timer_channel_break_control_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue); +/* configure the TIMER channel dead time function */ +void timer_channel_dead_time_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue); +/* initialize TIMER channel free complementary parameter struct with a default value */ +void timer_free_complementary_struct_para_init(timer_free_complementary_parameter_struct *freecompara); +/* configure channel free complementary protection */ +void timer_channel_free_complementary_config(uint32_t timer_periph, uint16_t channel, timer_free_complementary_parameter_struct *fcpara); + +/* TIMER interrupt and flag */ +/* get TIMER flags */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flags */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER interrupt flags */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t int_flag); +/* clear TIMER interrupt flags */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t int_flag); + +#endif /* GD32A50X_TIMER_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_trigsel.h b/gd32a50x/standard_peripheral/include/gd32a50x_trigsel.h new file mode 100644 index 0000000..f6dff24 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_trigsel.h @@ -0,0 +1,210 @@ +/*! + \file gd32a50x_trigsel.h + \brief definitions for the TRIGSEL + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_TRIGSEL_H +#define GD32A50X_TRIGSEL_H + +#include "gd32a50x.h" + +/* TRIGSEL definitions */ +#define TRIGSEL TRIGSEL_BASE /*!< TRIGSEL base address */ + +/* register definitions */ +#define TRIGSEL_EXTOUT0 REG32((TRIGSEL) + 0x00000000U) /*!< TRIGSEL trigger selection for EXTOUT0 register */ +#define TRIGSEL_EXTOUT1 REG32((TRIGSEL) + 0x00000004U) /*!< TRIGSEL trigger selection for EXTOUT1 register */ +#define TRIGSEL_ADC0 REG32((TRIGSEL) + 0x00000008U) /*!< TRIGSEL trigger selection for ADC0 register */ +#define TRIGSEL_ADC1 REG32((TRIGSEL) + 0x0000000CU) /*!< TRIGSEL trigger selection for ADC1 register */ +#define TRIGSEL_DAC REG32((TRIGSEL) + 0x00000010U) /*!< TRIGSEL trigger selection for DAC register */ +#define TRIGSEL_TIMER0IN REG32((TRIGSEL) + 0x00000014U) /*!< TRIGSEL trigger selection for TIMER0_ITI register */ +#define TRIGSEL_TIMER0BRKIN REG32((TRIGSEL) + 0x00000018U) /*!< TRIGSEL trigger selection for TIMER0_BRKIN register */ +#define TRIGSEL_TIMER7IN REG32((TRIGSEL) + 0x0000001CU) /*!< TRIGSEL trigger selection for TIMER7_ITI register */ +#define TRIGSEL_TIMER7BRKIN REG32((TRIGSEL) + 0x00000020U) /*!< TRIGSEL trigger selection for TIMER7_BRKIN register */ +#define TRIGSEL_TIMER19IN REG32((TRIGSEL) + 0x00000024U) /*!< TRIGSEL trigger selection for TIMER19_ITI register */ +#define TRIGSEL_TIMER19BRKIN REG32((TRIGSEL) + 0x00000028U) /*!< TRIGSEL trigger selection for TIMER19_BRKIN register */ +#define TRIGSEL_TIMER20IN REG32((TRIGSEL) + 0x0000002CU) /*!< TRIGSEL trigger selection for TIMER20_ITI register */ +#define TRIGSEL_TIMER20BRKIN REG32((TRIGSEL) + 0x00000030U) /*!< TRIGSEL trigger selection for TIMER20_BRKIN register */ +#define TRIGSEL_TIMER1IN REG32((TRIGSEL) + 0x00000034U) /*!< TRIGSEL trigger selection for TIMER1_ITI register */ +#define TRIGSEL_MFCOM REG32((TRIGSEL) + 0x00000038U) /*!< TRIGSEL trigger selection for MFCOM register */ +#define TRIGSEL_CAN0 REG32((TRIGSEL) + 0x0000003CU) /*!< TRIGSEL trigger selection for CAN0 register */ +#define TRIGSEL_CAN1 REG32((TRIGSEL) + 0x00000040U) /*!< TRIGSEL trigger selection for CAN1 register */ + +/* bits definitions */ +#define TRIGSEL_TARGET_INSEL0 BITS(0, 6) /*!< trigger input source selection for output0 */ +#define TRIGSEL_TARGET_INSEL1 BITS(8, 14) /*!< trigger input source selection for output1 */ +#define TRIGSEL_TARGET_INSEL2 BITS(16, 22) /*!< trigger input source selection for output2 */ +#define TRIGSEL_TARGET_INSEL3 BITS(24, 30) /*!< trigger input source selection for output3 */ +#define TRIGSEL_TARGET_LK BIT(31) /*!< TRIGSEL register lock */ + +/* constants definitions */ +/* trigger source definitions */ +typedef enum +{ + TRIGSEL_INPUT_0 = ((uint8_t)0x00U), /*!< trigger input source 0 */ + TRIGSEL_INPUT_1 = ((uint8_t)0x01U), /*!< trigger input source 1 */ + TRIGSEL_INPUT_TRIGSEL_IN0 = ((uint8_t)0x02U), /*!< trigger input source TRIGSEL_IN0 pin */ + TRIGSEL_INPUT_TRIGSEL_IN1 = ((uint8_t)0x03U), /*!< trigger input source TRIGSEL_IN1 pin */ + TRIGSEL_INPUT_TRIGSEL_IN2 = ((uint8_t)0x04U), /*!< trigger input source TRIGSEL_IN2 pin */ + TRIGSEL_INPUT_TRIGSEL_IN3 = ((uint8_t)0x05U), /*!< trigger input source TRIGSEL_IN3 pin */ + TRIGSEL_INPUT_TRIGSEL_IN4 = ((uint8_t)0x06U), /*!< trigger input source TRIGSEL_IN4 pin */ + TRIGSEL_INPUT_TRIGSEL_IN5 = ((uint8_t)0x07U), /*!< trigger input source TRIGSEL_IN5 pin */ + TRIGSEL_INPUT_TRIGSEL_IN6 = ((uint8_t)0x08U), /*!< trigger input source TRIGSEL_IN6 pin */ + TRIGSEL_INPUT_TRIGSEL_IN7 = ((uint8_t)0x09U), /*!< trigger input source TRIGSEL_IN7 pin */ + TRIGSEL_INPUT_TRIGSEL_IN8 = ((uint8_t)0x0AU), /*!< trigger input source TRIGSEL_IN8 pin */ + TRIGSEL_INPUT_TRIGSEL_IN9 = ((uint8_t)0x0BU), /*!< trigger input source TRIGSEL_IN9 pin */ + TRIGSEL_INPUT_TRIGSEL_IN10 = ((uint8_t)0x0CU), /*!< trigger input source TRIGSEL_IN10 pin */ + TRIGSEL_INPUT_TRIGSEL_IN11 = ((uint8_t)0x0DU), /*!< trigger input source TRIGSEL_IN11 pin */ + TRIGSEL_INPUT_CMP_OUT = ((uint8_t)0x0EU), /*!< trigger input source CMP_OUT */ + TRIGSEL_INPUT_LXTAL_TRG = ((uint8_t)0x10U), /*!< trigger input source LXTAL_TRG */ + TRIGSEL_INPUT_TIMER1_CH0 = ((uint8_t)0x11U), /*!< trigger input source timer1 channel 0 */ + TRIGSEL_INPUT_TIMER1_CH1 = ((uint8_t)0x12U), /*!< trigger input source timer1 channel 1 */ + TRIGSEL_INPUT_TIMER1_CH2 = ((uint8_t)0x13U), /*!< trigger input source timer1 channel 2 */ + TRIGSEL_INPUT_TIMER1_CH3 = ((uint8_t)0x14U), /*!< trigger input source timer1 channel 3 */ + TRIGSEL_INPUT_TIMER1_TRGO = ((uint8_t)0x15U), /*!< trigger input source timer1 TRGO */ + TRIGSEL_INPUT_TIMER0_CH0 = ((uint8_t)0x16U), /*!< trigger input source timer0 channel 0 */ + TRIGSEL_INPUT_TIMER0_CH1 = ((uint8_t)0x17U), /*!< trigger input source timer0 channel 1 */ + TRIGSEL_INPUT_TIMER0_CH2 = ((uint8_t)0x18U), /*!< trigger input source timer0 channel 2 */ + TRIGSEL_INPUT_TIMER0_CH3 = ((uint8_t)0x19U), /*!< trigger input source timer0 channel 3 */ + TRIGSEL_INPUT_TIMER0_MCH0 = ((uint8_t)0x1AU), /*!< trigger input source timer0 multi mode channel 0 */ + TRIGSEL_INPUT_TIMER0_MCH1 = ((uint8_t)0x1BU), /*!< trigger input source timer0 multi mode channel 1 */ + TRIGSEL_INPUT_TIMER0_MCH2 = ((uint8_t)0x1CU), /*!< trigger input source timer0 multi mode channel 2 */ + TRIGSEL_INPUT_TIMER0_MCH3 = ((uint8_t)0x1DU), /*!< trigger input source timer0 multi mode channel 3 */ + TRIGSEL_INPUT_TIMER0_TRGO = ((uint8_t)0x1EU), /*!< trigger input source timer0 TRGO */ + TRIGSEL_INPUT_TIMER7_CH0 = ((uint8_t)0x1FU), /*!< trigger input source timer7 channel 0 */ + TRIGSEL_INPUT_TIMER7_CH1 = ((uint8_t)0x20U), /*!< trigger input source timer7 channel 1 */ + TRIGSEL_INPUT_TIMER7_CH2 = ((uint8_t)0x21U), /*!< trigger input source timer7 channel 2 */ + TRIGSEL_INPUT_TIMER7_CH3 = ((uint8_t)0x22U), /*!< trigger input source timer7 channel 3 */ + TRIGSEL_INPUT_TIMER7_MCH0 = ((uint8_t)0x23U), /*!< trigger input source timer7 multi mode channel 0 */ + TRIGSEL_INPUT_TIMER7_MCH1 = ((uint8_t)0x24U), /*!< trigger input source timer7 multi mode channel 1 */ + TRIGSEL_INPUT_TIMER7_MCH2 = ((uint8_t)0x25U), /*!< trigger input source timer7 multi mode channel 2 */ + TRIGSEL_INPUT_TIMER7_MCH3 = ((uint8_t)0x26U), /*!< trigger input source timer7 multi mode channel 3 */ + TRIGSEL_INPUT_TIMER7_TRGO = ((uint8_t)0x27U), /*!< trigger input source timer7 TRGO */ + TRIGSEL_INPUT_TIMER19_CH0 = ((uint8_t)0x28U), /*!< trigger input source timer19 channel 0 */ + TRIGSEL_INPUT_TIMER19_CH1 = ((uint8_t)0x29U), /*!< trigger input source timer19 channel 1 */ + TRIGSEL_INPUT_TIMER19_CH2 = ((uint8_t)0x2AU), /*!< trigger input source timer19 channel 2 */ + TRIGSEL_INPUT_TIMER19_CH3 = ((uint8_t)0x2BU), /*!< trigger input source timer19 channel 3 */ + TRIGSEL_INPUT_TIMER19_MCH0 = ((uint8_t)0x2CU), /*!< trigger input source timer19 multi mode channel 0 */ + TRIGSEL_INPUT_TIMER19_MCH1 = ((uint8_t)0x2DU), /*!< trigger input source timer19 multi mode channel 1 */ + TRIGSEL_INPUT_TIMER19_MCH2 = ((uint8_t)0x2EU), /*!< trigger input source timer19 multi mode channel 2 */ + TRIGSEL_INPUT_TIMER19_MCH3 = ((uint8_t)0x2FU), /*!< trigger input source timer19 multi mode channel 3 */ + TRIGSEL_INPUT_TIMER19_TRGO = ((uint8_t)0x30U), /*!< trigger input source timer19 TRGO */ + TRIGSEL_INPUT_TIMER20_CH0 = ((uint8_t)0x31U), /*!< trigger input source timer20 channel 0 */ + TRIGSEL_INPUT_TIMER20_CH1 = ((uint8_t)0x32U), /*!< trigger input source timer20 channel 1 */ + TRIGSEL_INPUT_TIMER20_CH2 = ((uint8_t)0x33U), /*!< trigger input source timer20 channel 2 */ + TRIGSEL_INPUT_TIMER20_CH3 = ((uint8_t)0x34U), /*!< trigger input source timer20 channel 3 */ + TRIGSEL_INPUT_TIMER20_MCH0 = ((uint8_t)0x35U), /*!< trigger input source timer20 multi mode channel 0 */ + TRIGSEL_INPUT_TIMER20_MCH1 = ((uint8_t)0x36U), /*!< trigger input source timer20 multi mode channel 1 */ + TRIGSEL_INPUT_TIMER20_MCH2 = ((uint8_t)0x37U), /*!< trigger input source timer20 multi mode channel 2 */ + TRIGSEL_INPUT_TIMER20_MCH3 = ((uint8_t)0x38U), /*!< trigger input source timer20 multi mode channel 3 */ + TRIGSEL_INPUT_TIMER20_TRGO = ((uint8_t)0x39U), /*!< trigger input source timer20 TRGO */ + TRIGSEL_INPUT_TIMER5_TRGO = ((uint8_t)0x3AU), /*!< trigger input source timer5 TRGO */ + TRIGSEL_INPUT_TIMER6_TRGO = ((uint8_t)0x3BU), /*!< trigger input source timer6 TRGO */ + TRIGSEL_INPUT_MFCOM_TRIG0 = ((uint8_t)0x3CU), /*!< trigger input source MFCOM TRIG0 */ + TRIGSEL_INPUT_MFCOM_TRIG1 = ((uint8_t)0x3DU), /*!< trigger input source MFCOM TRIG1 */ + TRIGSEL_INPUT_MFCOM_TRIG2 = ((uint8_t)0x3EU), /*!< trigger input source MFCOM TRIG2 */ + TRIGSEL_INPUT_MFCOM_TRIG3 = ((uint8_t)0x3FU), /*!< trigger input source MFCOM TRIG3 */ + TRIGSEL_INPUT_RTC_ALARM = ((uint8_t)0x40U), /*!< trigger input source RTC alarm */ + TRIGSEL_INPUT_RTC_SECOND = ((uint8_t)0x41U), /*!< trigger input source RTC second */ + TRIGSEL_INPUT_TRIGSEL_IN12 = ((uint8_t)0x42U), /*!< trigger input source TRIGSEL_IN12 pin */ + TRIGSEL_INPUT_TRIGSEL_IN13 = ((uint8_t)0x43U), /*!< trigger input source TRIGSEL_IN13 pin */ +}trigsel_source_enum; + +/* target peripheral definitions */ +typedef enum +{ + TRIGSEL_OUTPUT_TRIGSEL_OUT0 = ((uint8_t)0x00U), /*!< output target peripheral TRIGSEL_OUT0 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT1 = ((uint8_t)0x01U), /*!< output target peripheral TRIGSEL_OUT1 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT2 = ((uint8_t)0x02U), /*!< output target peripheral TRIGSEL_OUT2 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT3 = ((uint8_t)0x03U), /*!< output target peripheral TRIGSEL_OUT3 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT4 = ((uint8_t)0x04U), /*!< output target peripheral TRIGSEL_OUT4 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT5 = ((uint8_t)0x05U), /*!< output target peripheral TRIGSEL_OUT5 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT6 = ((uint8_t)0x06U), /*!< output target peripheral TRIGSEL_OUT6 pin */ + TRIGSEL_OUTPUT_TRIGSEL_OUT7 = ((uint8_t)0x07U), /*!< output target peripheral TRIGSEL_OUT7 pin */ + TRIGSEL_OUTPUT_ADC0_RTTRG = ((uint8_t)0x08U), /*!< output target peripheral ADC0_RTTRG */ + TRIGSEL_OUTPUT_ADC1_RTTRG = ((uint8_t)0x0CU), /*!< output target peripheral ADC1_RTTRG */ + TRIGSEL_OUTPUT_DAC_EXTRIG = ((uint8_t)0x10U), /*!< output target peripheral DAC_EXTRIG */ + TRIGSEL_OUTPUT_TIMER0_ITI0 = ((uint8_t)0x14U), /*!< output target peripheral TIMER0_ITI0 */ + TRIGSEL_OUTPUT_TIMER0_ITI1 = ((uint8_t)0x15U), /*!< output target peripheral TIMER0_ITI1 */ + TRIGSEL_OUTPUT_TIMER0_ITI2 = ((uint8_t)0x16U), /*!< output target peripheral TIMER0_ITI2 */ + TRIGSEL_OUTPUT_TIMER0_ITI3 = ((uint8_t)0x17U), /*!< output target peripheral TIMER0_ITI3 */ + TRIGSEL_OUTPUT_TIMER0_BRKIN0 = ((uint8_t)0x18U), /*!< output target peripheral TIMER0_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER0_BRKIN1 = ((uint8_t)0x19U), /*!< output target peripheral TIMER0_BRKIN1 */ + TRIGSEL_OUTPUT_TIMER0_BRKIN2 = ((uint8_t)0x1AU), /*!< output target peripheral TIMER0_BRKIN2 */ + TRIGSEL_OUTPUT_TIMER0_BRKIN3 = ((uint8_t)0x1BU), /*!< output target peripheral TIMER0_BRKIN3 */ + TRIGSEL_OUTPUT_TIMER7_ITI0 = ((uint8_t)0x1CU), /*!< output target peripheral TIMER7_ITI0 */ + TRIGSEL_OUTPUT_TIMER7_ITI1 = ((uint8_t)0x1DU), /*!< output target peripheral TIMER7_ITI1 */ + TRIGSEL_OUTPUT_TIMER7_ITI2 = ((uint8_t)0x1EU), /*!< output target peripheral TIMER7_ITI2 */ + TRIGSEL_OUTPUT_TIMER7_ITI3 = ((uint8_t)0x1FU), /*!< output target peripheral TIMER7_ITI3 */ + TRIGSEL_OUTPUT_TIMER7_BRKIN0 = ((uint8_t)0x20U), /*!< output target peripheral TIMER7_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER7_BRKIN1 = ((uint8_t)0x21U), /*!< output target peripheral TIMER7_BRKIN1 */ + TRIGSEL_OUTPUT_TIMER7_BRKIN2 = ((uint8_t)0x22U), /*!< output target peripheral TIMER7_BRKIN2 */ + TRIGSEL_OUTPUT_TIMER7_BRKIN3 = ((uint8_t)0x23U), /*!< output target peripheral TIMER7_BRKIN3 */ + TRIGSEL_OUTPUT_TIMER19_ITI0 = ((uint8_t)0x24U), /*!< output target peripheral TIMER19_ITI0 */ + TRIGSEL_OUTPUT_TIMER19_ITI1 = ((uint8_t)0x25U), /*!< output target peripheral TIMER19_ITI1 */ + TRIGSEL_OUTPUT_TIMER19_ITI2 = ((uint8_t)0x26U), /*!< output target peripheral TIMER19_ITI2 */ + TRIGSEL_OUTPUT_TIMER19_ITI3 = ((uint8_t)0x27U), /*!< output target peripheral TIMER19_ITI3 */ + TRIGSEL_OUTPUT_TIMER19_BRKIN0 = ((uint8_t)0x28U), /*!< output target peripheral TIMER19_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER19_BRKIN1 = ((uint8_t)0x29U), /*!< output target peripheral TIMER19_BRKIN1 */ + TRIGSEL_OUTPUT_TIMER19_BRKIN2 = ((uint8_t)0x2AU), /*!< output target peripheral TIMER19_BRKIN2 */ + TRIGSEL_OUTPUT_TIMER19_BRKIN3 = ((uint8_t)0x2BU), /*!< output target peripheral TIMER19_BRKIN3 */ + TRIGSEL_OUTPUT_TIMER20_ITI0 = ((uint8_t)0x2CU), /*!< output target peripheral TIMER20_ITI0 */ + TRIGSEL_OUTPUT_TIMER20_ITI1 = ((uint8_t)0x2DU), /*!< output target peripheral TIMER20_ITI1 */ + TRIGSEL_OUTPUT_TIMER20_ITI2 = ((uint8_t)0x2EU), /*!< output target peripheral TIMER20_ITI2 */ + TRIGSEL_OUTPUT_TIMER20_ITI3 = ((uint8_t)0x2FU), /*!< output target peripheral TIMER20_ITI3 */ + TRIGSEL_OUTPUT_TIMER20_BRKIN0 = ((uint8_t)0x30U), /*!< output target peripheral TIMER20_BRKIN0 */ + TRIGSEL_OUTPUT_TIMER20_BRKIN1 = ((uint8_t)0x31U), /*!< output target peripheral TIMER20_BRKIN1 */ + TRIGSEL_OUTPUT_TIMER20_BRKIN2 = ((uint8_t)0x32U), /*!< output target peripheral TIMER20_BRKIN2 */ + TRIGSEL_OUTPUT_TIMER20_BRKIN3 = ((uint8_t)0x33U), /*!< output target peripheral TIMER20_BRKIN3 */ + TRIGSEL_OUTPUT_TIMER1_ITI0 = ((uint8_t)0x34U), /*!< output target peripheral TIMER1_ITI0 */ + TRIGSEL_OUTPUT_TIMER1_ITI1 = ((uint8_t)0x35U), /*!< output target peripheral TIMER1_ITI1 */ + TRIGSEL_OUTPUT_TIMER1_ITI2 = ((uint8_t)0x36U), /*!< output target peripheral TIMER1_ITI2 */ + TRIGSEL_OUTPUT_TIMER1_ITI3 = ((uint8_t)0x37U), /*!< output target peripheral TIMER1_ITI3 */ + TRIGSEL_OUTPUT_MFCOM_TRG_TIMER0 = ((uint8_t)0x38U), /*!< output target peripheral MFCOM_TRG_TIMER0 */ + TRIGSEL_OUTPUT_MFCOM_TRG_TIMER1 = ((uint8_t)0x39U), /*!< output target peripheral MFCOM_TRG_TIMER1 */ + TRIGSEL_OUTPUT_MFCOM_TRG_TIMER2 = ((uint8_t)0x3AU), /*!< output target peripheral MFCOM_TRG_TIMER2 */ + TRIGSEL_OUTPUT_MFCOM_TRG_TIMER3 = ((uint8_t)0x3BU), /*!< output target peripheral MFCOM_TRG_TIMER3 */ + TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK = ((uint8_t)0x3CU), /*!< output target peripheral CAN0_EX_TIME_TICK */ + TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK = ((uint8_t)0x40U), /*!< output target peripheral CAN1_EX_TIME_TICK */ +}trigsel_periph_enum; + +/* function declarations */ +/* set the trigger input signal for target peripheral */ +void trigsel_init(trigsel_periph_enum target_periph, trigsel_source_enum trigger_source); +/* get the trigger input signal for target peripheral */ +uint8_t trigsel_trigger_source_get(trigsel_periph_enum target_periph); +/* lock the trigger register */ +void trigsel_register_lock_set(trigsel_periph_enum target_periph); +/* get the trigger register lock status */ +FlagStatus trigsel_register_lock_get(trigsel_periph_enum target_periph); + +#endif /* GD32A50X_TRIGSEL_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_usart.h b/gd32a50x/standard_peripheral/include/gd32a50x_usart.h new file mode 100644 index 0000000..9df7f98 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_usart.h @@ -0,0 +1,593 @@ +/*! + \file gd32a50x_usart.h + \brief definitions for the USART + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_USART_H +#define GD32A50X_USART_H + +#include "gd32a50x.h" + +#define USART1 USART_BASE +#define USART2 (USART_BASE + 0x00000400U) +#define USART0 (USART_BASE + 0x0000F400U) + +/* 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) /*!< enable USART */ +#define USART_CTL0_UESM BIT(1) /*!< enable USART in deep-sleep mode */ +#define USART_CTL0_REN BIT(2) /*!< enable receiver */ +#define USART_CTL0_TEN BIT(3) /*!< enable transmitter */ +#define USART_CTL0_IDLEIE BIT(4) /*!< enable idle line detected interrupt */ +#define USART_CTL0_RBNEIE BIT(5) /*!< renable ead data buffer not empty interrupt and overrun error interrupt */ +#define USART_CTL0_TCIE BIT(6) /*!< enable transmission complete interrupt */ +#define USART_CTL0_TBEIE BIT(7) /*!< enable transmitter register empty interrupt */ +#define USART_CTL0_PERRIE BIT(8) /*!< enable parity error interrupt */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< enable parity control */ +#define USART_CTL0_WM0 BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_MEN BIT(13) /*!< enable mute mode */ +#define USART_CTL0_AMIE BIT(14) /*!< enable address match interrupt */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_DED BITS(16,20) /*!< enable driver deassertion time */ +#define USART_CTL0_DEA BITS(21,25) /*!< enable driver assertion time */ +#define USART_CTL0_RTIE BIT(26) /*!< enable receiver timeout interrupt */ +#define USART_CTL0_EBIE BIT(27) /*!< enable end of block interrupt */ +#define USART_CTL0_WM1 BIT(28) /*!< enable driver assertion time */ + +/* 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_RTEN BIT(23) /*!< receiver timeout enable */ +#define USART_CTL1_ADDR_DATA BITS(24,31) /*!< address of the USART terminal */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< enable error interrupt in multibuffer communication */ +#define USART_CTL2_IREN BIT(1) /*!< enable IrDA mode */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< enable half-duplex */ +#define USART_CTL2_NKEN BIT(4) /*!< enable NACK in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< enable smartcard mode */ +#define USART_CTL2_DENR BIT(6) /*!< enable DMA for reception */ +#define USART_CTL2_DENT BIT(7) /*!< enable DMA for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< enable RTS */ +#define USART_CTL2_CTSEN BIT(9) /*!< enable CTS */ +#define USART_CTL2_CTSIE BIT(10) /*!< enable CTS interrupt */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit mode */ +#define USART_CTL2_OVRD BIT(12) /*!< disable overrun */ +#define USART_CTL2_DDRE BIT(13) /*!< disable DMA on reception error */ +#define USART_CTL2_DEM BIT(14) /*!< enable driver mode */ +#define USART_CTL2_DEP BIT(15) /*!< enable driver polarity mode */ +#define USART_CTL2_SCRTNUM BITS(17,19) /*!< smartcard auto-retry number */ +#define USART_CTL2_WUM BITS(20,21) /*!< wakeup mode from deep-sleep mode */ +#define USART_CTL2_WUIE BIT(22) /*!< enable wakeup from deep-sleep mode interrupt */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer of baud-rate divider */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_CMD */ +#define USART_CMD_SBKCMD BIT(1) /*!< send break command */ +#define USART_CMD_MMCMD BIT(2) /*!< mute mode command */ +#define USART_CMD_RXFCMD BIT(3) /*!< receive data flush command */ +#define USART_CMD_TXFCMD BIT(4) /*!< transmit data flush request */ + +/* USARTx_STAT */ +#define USART_STAT_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT_IDLEF BIT(4) /*!< idle line detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty */ +#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_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) /*!< clear parity error */ +#define USART_INTC_FEC BIT(1) /*!< clear frame error flag */ +#define USART_INTC_NEC BIT(2) /*!< clear noise detected */ +#define USART_INTC_OREC BIT(3) /*!< clear overrun error */ +#define USART_INTC_IDLEC BIT(4) /*!< clear idle line detected */ +#define USART_INTC_TCC BIT(6) /*!< clear transmission complete */ +#define USART_INTC_LBDC BIT(8) /*!< clear LIN break detected */ +#define USART_INTC_CTSC BIT(9) /*!< clear CTS change */ +#define USART_INTC_RTC BIT(11) /*!< clear receiver timeout */ +#define USART_INTC_EBC BIT(12) /*!< clear end of timeout */ +#define USART_INTC_AMC BIT(17) /*!< clear address match */ +#define USART_INTC_WUC BIT(20) /*!< clear wakeup from deep-sleep mode */ + +/* 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) /*!< enable receive FIFO */ +#define USART_RFCS_RFFIE BIT(9) /*!< enable receive FIFO full interrupt */ +#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 0x00000000U /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET 0x00000004U /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET 0x00000008U /*!< CTL2 register offset */ +#define USART_STAT_REG_OFFSET 0x0000001CU /*!< STAT register offset */ +#define USART_CHC_REG_OFFSET 0x000000C0U /*!< CHC register offset */ +#define USART_RFCS_REG_OFFSET 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_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; + +/* enable or disable USART interrupt */ +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; + +/* configure USART invert */ +typedef enum { + /* data bit level inversion */ + USART_DINV_ENABLE, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ + /* swap TX/RX pins */ + USART_SWAP_ENABLE, /*!< swap TX/RX pins */ + USART_SWAP_DISABLE, /*!< not swap TX/RX pins */ +}usart_invert_enum; + +/* configure USART receiver */ +#define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ +#define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ + +/* configure USART transmitter */ +#define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) +#define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ +#define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ + +/* USART parity bits definitions */ +#define CTL0_PM(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define USART_PM_NONE CTL0_PM(0) /*!< no parity */ +#define USART_PM_EVEN CTL0_PM(2) /*!< even parity */ +#define USART_PM_ODD CTL0_PM(3) /*!< odd parity */ + +/* USART wakeup method in mute mode */ +#define CTL0_WM(regval1, regval2) ((BIT(11) & ((uint32_t)(regval1) << 11)) | (BIT(28) & ((uint32_t)(regval2) << 28))) +#define USART_WM_IDLE CTL0_WM(0, 0) /*!< idle line */ +#define USART_WM_ADDR CTL0_WM(1, 0) /*!< address match */ +#define USART_WM_DATA CTL0_WM(1, 1) /*!< data 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 CTL1_STB(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define USART_STB_1BIT CTL1_STB(0) /*!< 1 bit */ +#define USART_STB_0_5BIT CTL1_STB(1) /*!< 0.5 bit */ +#define USART_STB_2BIT CTL1_STB(2) /*!< 2 bits */ +#define USART_STB_1_5BIT CTL1_STB(3) /*!< 1.5 bits */ + +/* USART data is transmitted/received with the LSB/MSB first */ +#define CTL1_MSBF(regval) (BIT(19) & ((uint32_t)(regval) << 19)) +#define USART_MSBF_LSB CTL1_MSBF(0) /*!< LSB first */ +#define USART_MSBF_MSB CTL1_MSBF(1) /*!< MSB first */ + +/* enable USART IrDA low-power */ +#define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ +#define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ + +/* configure USART DMA */ +#define CTL2_RECEIVE_DMAEN(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define CTL2_TRANSMIT_DMAEN(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_RECEIVE_DMA_ENABLE CTL2_RECEIVE_DMAEN(1) /*!< enable DMA request for reception */ +#define USART_RECEIVE_DMA_DISABLE CTL2_RECEIVE_DMAEN(0) /*!< disable DMA request for reception */ +#define USART_TRANSMIT_DMA_ENABLE CTL2_TRANSMIT_DMAEN(1) /*!< enable DMA request for transmission */ +#define USART_TRANSMIT_DMA_DISABLE CTL2_TRANSMIT_DMAEN(0) /*!< disable DMA request for transmission */ + +/* configure USART RTS hardware flow control */ +#define CTL2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CTL2_RTSEN(1) /*!< enable RTS hardware flow control */ +#define USART_RTS_DISABLE CTL2_RTSEN(0) /*!< disable RTS hardware flow control */ + +/* configure USART CTS hardware flow control */ +#define CTL2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CTL2_CTSEN(1) /*!< enable CTS hardware flow control */ +#define USART_CTS_DISABLE CTL2_CTSEN(0) /*!< disable CTS hardware flow control */ + +/* configure USART one sample bit method */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1BIT CTL2_OSB(1) /*!< 1 sample bit */ +#define USART_OSB_3BIT CTL2_OSB(0) /*!< 3 sample bits */ + +/* USART driver enable polarity mode */ +#define CTL2_DEP(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_DEP_HIGH CTL2_DEP(0) /*!< DE signal is active high */ +#define USART_DEP_LOW CTL2_DEP(1) /*!< DE signal is active low */ + +/* USART wakeup mode from deep-sleep mode */ +#define CTL2_WUM(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define USART_WUM_ADDR CTL2_WUM(0) /*!< WUF active on address match */ +#define USART_WUM_STARTB CTL2_WUM(2) /*!< WUF active on start bit */ +#define USART_WUM_RBNE CTL2_WUM(3) /*!< WUF active on RBNE */ + +/* USART hardware flow control coherence mode */ +#define CHC_HCM(regval) (BIT(0) & ((uint32_t)(regval) << 0)) +#define USART_HCM_NONE CHC_HCM(0) /*!< nRTS signal equals to the rxne status register */ +#define USART_HCM_EN CHC_HCM(1) /*!< nRTS signal is set when the last data bit has been sampled */ + +/* function declarations */ +/* initialization functions */ +/* reset USART */ +void usart_deinit(uint32_t usart_periph); +/* configure USART baud rate value */ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval); +/* configure USART parity function */ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg); +/* configure USART word length */ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen); +/* configure USART stop bit length */ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen); +/* enable USART */ +void usart_enable(uint32_t usart_periph); +/* disable USART */ +void usart_disable(uint32_t usart_periph); +/* configure USART transmitter */ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig); +/* configure USART receiver */ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig); + +/* USART normal mode communication */ +/* data is transmitted/received with the LSB/MSB first */ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf); +/* configure USART inverted */ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara); +/* enable the USART overrun function */ +void usart_overrun_enable(uint32_t usart_periph); +/* disable the USART overrun function */ +void usart_overrun_disable(uint32_t usart_periph); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* configure sample bit method */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb); +/* enable receiver timeout */ +void usart_receiver_timeout_enable(uint32_t usart_periph); +/* disable receiver timeout */ +void usart_receiver_timeout_disable(uint32_t usart_periph); +/* configure receiver timeout threshold */ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout); +/* USART transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint16_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); +/* enable USART command */ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype); + +/* multi-processor communication */ +/* 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, uint32_t guat); +/* enable smartcard mode */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* disable smartcard mode */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* enable NACK in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* disable NACK in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* enable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph); +/* disable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph); +/* configure smartcard auto-retry number */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); +/* configure block length */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler in USART IrDA low-power or smartcard mode */ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc); +/* configure IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); + +/* hardware flow communication */ +/* configure hardware flow control RTS */ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig); +/* configure hardware flow control CTS */ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig); + +/* coherence control */ +/* configure hardware flow control coherence mode */ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm); + +/* enable RS485 driver */ +void usart_rs485_driver_enable(uint32_t usart_periph); +/* disable RS485 driver */ +void usart_rs485_driver_disable(uint32_t usart_periph); +/* configure driver enable assertion time */ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime); +/* configure driver enable de-assertion time */ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime); +/* configure driver enable polarity mode */ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep); + +/* USART DMA */ +/* configure USART DMA reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint8_t dmaconfig); +/* configure USART DMA transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint8_t dmaconfig); +/* 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 USART status */ +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 /* GD32A50X_USART_H */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_wwdgt.h b/gd32a50x/standard_peripheral/include/gd32a50x_wwdgt.h new file mode 100644 index 0000000..7224669 --- /dev/null +++ b/gd32a50x/standard_peripheral/include/gd32a50x_wwdgt.h @@ -0,0 +1,91 @@ +/*! + \file gd32fxxx_wwdgt.h + \brief definitions for the WWDGT + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#ifndef GD32A50X_WWDGT_H +#define GD32A50X_WWDGT_H + +#include "gd32a50x.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE /*!< WWDGT base address */ + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00000000U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x00000004U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x00000008U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC BITS(7,8) /*!< WWDGT prescaler divider value */ +#define WWDGT_CFG_EWIE BIT(9) /*!< WWDGT early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< WWDGT early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval) (BITS(7,8) & ((uint32_t)(regval) << 7U)) /*!< write value to WWDGT_CFG_PSC bit field */ +#define WWDGT_CFG_PSC_DIV1 ((uint32_t)CFG_PSC(0)) /*!< the time base of WWDGT = (PCLK1/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 ((uint32_t)CFG_PSC(1)) /*!< the time base of WWDGT = (PCLK1/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 ((uint32_t)CFG_PSC(2)) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 ((uint32_t)CFG_PSC(3)) /*!< the time base of WWDGT = (PCLK1/4096)/8 */ + +/* WWDGT_CTL register value */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CTL_CNT bit field */ +/* WWDGT_CFG register value */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CFG_WIN bit field */ + +/* function declarations */ +/* reset the WWDGT configuration */ +void wwdgt_deinit(void); +/* start the WWDGT counter */ +void wwdgt_enable(void); + +/* configure the WWDGT counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* 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 /* GD32A50X_WWDGT_H */ diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_adc.c b/gd32a50x/standard_peripheral/source/gd32a50x_adc.c new file mode 100644 index 0000000..329a922 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_adc.c @@ -0,0 +1,987 @@ +/*! + \file gd32a50x_adc.c + \brief ADC driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_adc.h" + +/*! + \brief reset ADC + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_deinit(uint32_t adc_periph) +{ + switch(adc_periph){ + case ADC0: + rcu_periph_reset_enable(RCU_ADC0RST); + rcu_periph_reset_disable(RCU_ADC0RST); + break; + case ADC1: + rcu_periph_reset_enable(RCU_ADC1RST); + rcu_periph_reset_disable(RCU_ADC1RST); + break; + default: + break; + } +} + +/*! + \brief enable ADC interface + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_enable(uint32_t adc_periph) +{ + if(0U == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_disable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON); +} + +/*! + \brief ADC calibration and reset calibration + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_calibration_enable(uint32_t adc_periph) +{ + /* reset the selected ADC calibration registers */ + ADC_CTL1(adc_periph) |= (uint32_t) ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while((ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)){ + } + /* enable ADC calibration process */ + ADC_CTL1(adc_periph) |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while((ADC_CTL1(adc_periph) & ADC_CTL1_CLB)){ + } +} + +/*! + \brief enable DMA request + \param[in] adc_periph: ADCx, x=0 + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief disable DMA request + \param[in] adc_periph: ADCx,x=0 + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(uint32_t adc_periph) +{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief enable the temperature sensor channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_enable(void) +{ + /* enable the temperature sensor and vrefint channel */ + ADC_CTL1(ADC0) |= ADC_CTL1_TSVEN; +} + +/*! + \brief disable the temperature sensor channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_disable(void) +{ + /* disable the temperature sensor and vrefint channel */ + ADC_CTL1(ADC0) &= ~ADC_CTL1_TSVEN; +} + +/*! + \brief enable vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_vrefint_enable(void) +{ + ADC_CTL1(ADC0) |= ADC_CTL1_INREFEN; +} + +/*! + \brief disable vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_vrefint_disable(void) +{ + ADC_CTL1(ADC0) &= ~ADC_CTL1_INREFEN; +} + +/*! + \brief configure ADC discontinuous mode + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular and inserted channel + \param[in] length: number of conversions in discontinuous mode,the number can be 1..8 + for regular channel, the number has no effect for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length) +{ + ADC_CTL0(adc_periph) &= ~((uint32_t)( ADC_CTL0_DISRC | ADC_CTL0_DISIC )); + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure the number of conversions in discontinuous mode */ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM); + ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - 1U)); + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + default: + break; + } +} + +/*! + \brief configure the ADC0 sync mode + \param[in] mode: ADC0 mode + only one parameter can be selected which is shown as below: + \arg ADC_MODE_FREE: all the ADCs work independently + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel + inserted parallel mode + \arg ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel + trigger rotation mode + \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in combined inserted parallel + follow-up fast mode + \arg ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in combined inserted parallel + follow-up slow mode + \arg ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode only + \arg ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode only + \arg ADC_DAUL_REGULAL_FOLLOWUP_FAST: ADC0 and ADC1 work in follow-up fast mode only + \arg ADC_DAUL_REGULAL_FOLLOWUP_SLOW: ADC0 and ADC1 work in follow-up slow mode only + \arg ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode only + \param[out] none + \retval none +*/ +void adc_mode_config(uint32_t mode) +{ + ADC_CTL0(ADC0) &= ~((uint32_t)ADC_CTL0_SYNCM); + ADC_CTL0(ADC0) |= mode; +} + +/*! + \brief configure ADC special function + \param[in] adc_periph: ADCx, x=0,1 + \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 channel group convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_special_function_config(uint32_t adc_periph , uint32_t function , ControlStatus newvalue) +{ + if(newvalue){ + /* enable ADC scan mode */ + if(0U != (function & ADC_SCAN_MODE)){ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_SCAN_MODE; + } + /* enable ADC inserted channel group convert automatically */ + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0(adc_periph) |= (uint32_t)ADC_INSERTED_CHANNEL_AUTO; + } + /* enable ADC continuous mode */ + if(0U != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CONTINUOUS_MODE; + } + }else{ + /* disable ADC scan mode */ + if(0U != (function & ADC_SCAN_MODE)){ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_SCAN_MODE); + } + /* disable ADC inserted channel group convert automatically */ + if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_INSERTED_CHANNEL_AUTO); + } + /* disable ADC continuous mode */ + if(0U != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CONTINUOUS_MODE); + } + } +} + +/*! + \brief configure ADC data alignment + \param[in] adc_periph: ADCx, x=0,1 + \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 adc_periph , uint32_t data_alignment) +{ + if(ADC_DATAALIGN_RIGHT != data_alignment){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_DAL; + }else{ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief configure the length of regular channel group or inserted channel group + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: the length of the channel + regular channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure the length of regular channel group */ + ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length-1U)); + break; + case ADC_INSERTED_CHANNEL: + /* configure the length of inserted channel group */ + ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length-1U)); + break; + default: + break; + } +} + +/*! + \brief configure ADC regular channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] rank: the regular group 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..17)(x=16 and x=17 are only for ADC0): ADC Channelx + \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_14POINT5: 14.5 cycles + \arg ADC_SAMPLETIME_27POINT5: 27.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_83POINT5: 83.5 cycles + \arg ADC_SAMPLETIME_111POINT5: 111.5 cycles + \arg ADC_SAMPLETIME_143POINT5: 143.5 cycles + \arg ADC_SAMPLETIME_479POINT5: 479.5 cycles + \param[out] none + \retval none +*/ +void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint32_t rsq,sampt; + + /* configure ADC regular sequence */ + if(rank < 6U){ + rsq = ADC_RSQ2(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank))); + rsq |= ((uint32_t)adc_channel << (5U*rank)); + ADC_RSQ2(adc_periph) = rsq; + }else if(rank < 12U){ + rsq = ADC_RSQ1(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U)))); + rsq |= ((uint32_t)adc_channel << (5U*(rank-6U))); + ADC_RSQ1(adc_periph) = rsq; + }else if(rank < 16U){ + rsq = ADC_RSQ0(adc_periph); + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U)))); + rsq |= ((uint32_t)adc_channel << (5U*(rank-12U))); + ADC_RSQ0(adc_periph) = rsq; + }else{ + } + + /* configure ADC sampling time */ + if(adc_channel < 10U){ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel))); + sampt |= (uint32_t)(sample_time << (3U*adc_channel)); + ADC_SAMPT1(adc_periph) = sampt; + }else if(adc_channel < 18U){ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U)))); + sampt |= (uint32_t)(sample_time << (3U*(adc_channel-10U))); + ADC_SAMPT0(adc_periph) = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure ADC inserted channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..17)(x=16 and x=17 are only for ADC0): ADC Channelx + \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_14POINT5: 14.5 cycles + \arg ADC_SAMPLETIME_27POINT5: 27.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_83POINT5: 83.5 cycles + \arg ADC_SAMPLETIME_111POINT5: 111.5 cycles + \arg ADC_SAMPLETIME_143POINT5: 143.5 cycles + \arg ADC_SAMPLETIME_479POINT5: 479.5 cycles + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq, sampt; + + /* get inserted channel group length */ + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U); + + /* the channel number is written to these bits to select a channel as the nth conversion in the inserted channel group */ + isq = ADC_ISQ(adc_periph); + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (5U * ((3U + rank) - inserted_length)))); + isq |= ((uint32_t)adc_channel << (5U * ((3U + rank) - inserted_length))); + ADC_ISQ(adc_periph) = isq; + + /* ADC sampling time config */ + if(adc_channel < 10U){ + sampt = ADC_SAMPT1(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*adc_channel))); + sampt |= (uint32_t) sample_time << (3U*adc_channel); + ADC_SAMPT1(adc_periph) = sampt; + }else if(adc_channel < 18U){ + sampt = ADC_SAMPT0(adc_periph); + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(adc_channel-10U)))); + sampt |= ((uint32_t)sample_time << (3U*(adc_channel-10U))); + ADC_SAMPT0(adc_periph) = sampt; + }else{ + } +} + +/*! + \brief configure ADC inserted channel offset + \param[in] adc_periph: ADCx, x=0,1 + \param[in] inserted_channel : insert channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel3 + \param[in] offset : the offset data + \param[out] none + \retval none +*/ +void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U); + num = (uint32_t)3U - ((uint32_t)inserted_length - (uint32_t)inserted_channel); + + if(num <= 3U){ + /* calculate the offset of the register */ + num = num * 4U; + /* configure the offset of the selected channels */ + REG32((adc_periph) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief configure ADC external trigger + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, ControlStatus newvalue) +{ + if(newvalue){ + /* external trigger enable for regular channel */ + if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ETERC; + } + /* external trigger enable for inserted channel */ + if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ETEIC; + } + }else{ + /* external trigger disable for regular channel */ + if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETERC); + } + /* external trigger disable for inserted channel */ + if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETEIC); + } + } +} + +/*! + \brief configure ADC external trigger source + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] external_trigger_source: regular or inserted group trigger source + only one parameter can be selected which is shown as below: + for regular channel: + \arg ADC0_1_EXTTRIG_REGULAR_TRIGSEL: TRIGSEL select + \arg ADC0_1_EXTTRIG_REGULAR_NONE: software trigger + for inserted channel: + \arg ADC0_1_EXTTRIG_INSERTED_TRIGSEL: TRIGSEL select + \arg ADC0_1_EXTTRIG_INSERTED_NONE: software trigger + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source) +{ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + /* external trigger select for regular channel */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + /* external trigger select for inserted channel */ + ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief enable ADC software trigger + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group) +{ + /* enable regular group channel software trigger */ + if(0U != (adc_channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST; + } + /* enable inserted channel group software trigger */ + if(0U != (adc_channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWICST; + } +} + +/*! + \brief read ADC regular group data register + \param[in] adc_periph: ADCx, x=0,1 + \param[in] none + \param[out] none + \retval the conversion value: 0~0xFFFF +*/ +uint16_t adc_regular_data_read(uint32_t adc_periph) +{ + return (uint16_t)(ADC_RDATA(adc_periph)); +} + +/*! + \brief read ADC inserted group data register + \param[in] adc_periph: ADCx, x=0,1 + \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 channel0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel3 + \param[out] none + \retval the conversion value: 0~0xFFFF +*/ +uint16_t adc_inserted_data_read(uint32_t adc_periph , uint8_t inserted_channel) +{ + uint32_t idata; + /* read the data of the selected channel */ + switch(inserted_channel){ + case ADC_INSERTED_CHANNEL_0: + idata = ADC_IDATA0(adc_periph); + break; + case ADC_INSERTED_CHANNEL_1: + idata = ADC_IDATA1(adc_periph); + break; + case ADC_INSERTED_CHANNEL_2: + idata = ADC_IDATA2(adc_periph); + break; + case ADC_INSERTED_CHANNEL_3: + idata = ADC_IDATA3(adc_periph); + break; + default: + idata = 0U; + break; + } + return (uint16_t)idata; +} + +/*! + \brief read the last ADC0 and ADC1 conversion result data in sync mode + \param[in] none + \param[out] none + \retval the conversion value: 0~0xFFFFFFFF +*/ +uint32_t adc_sync_mode_convert_value_read(void) +{ + /* return conversion value */ + return ADC_RDATA(ADC0); +} + +/*! + \brief configure ADC analog watchdog 0 single channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x: ADC Channelx(x=0..17)(x=16 and x=17 are only for ADC0) + \param[out] none + \retval none +*/ +void adc_watchdog0_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel) +{ + ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC | ADC_CTL0_WD0CHSEL); + + ADC_CTL0(adc_periph) |= (uint32_t)adc_channel; + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC); +} + +/*! + \brief configure ADC analog watchdog 0 group channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel_group: the channel group use analog watchdog 0 + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog0_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group) +{ + ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC); + /* select the group */ + switch(adc_channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_RWD0EN; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_IWD0EN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN); + break; + default: + break; + } +} + +/*! + \brief disable ADC analog watchdog 0 + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_watchdog0_disable(uint32_t adc_periph) +{ + ADC_CTL0(adc_periph) &= (uint32_t)~(ADC_CTL0_RWD0EN | ADC_CTL0_IWD0EN | ADC_CTL0_WD0SC | ADC_CTL0_WD0CHSEL); +} + +/*! + \brief configure ADC analog watchdog 1 channel + \param[in] adc_periph: ADCx, x=0,1 + \param[in] adc_channel: the channel use analog watchdog 1 + one or more parameters can be selected which is shown as below: + \arg ADC_AWD1_SELECTION_CHANNEL_x, ADC_AWD1_SELECTION_CHANNEL_ALL: ADC channel analog watchdog 1/2 selection + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_watchdog1_channel_config(uint32_t adc_periph, uint32_t adc_channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + ADC_WD1SR(adc_periph) |= (uint32_t)adc_channel; + }else{ + ADC_WD1SR(adc_periph) &= ~((uint32_t)adc_channel); + } +} + +/*! + \brief disable ADC analog watchdog 1 + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_watchdog1_disable(uint32_t adc_periph) +{ + ADC_WD1SR(adc_periph) &= (uint32_t)~(ADC_WD1SR_AWD1CS); +} + +/*! + \brief configure ADC analog watchdog 0 threshold + \param[in] adc_periph: ADCx, x=0,1 + \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 adc_periph, uint16_t low_threshold, uint16_t high_threshold) +{ + ADC_WDLT0(adc_periph) = (uint32_t)WDLT0_WDLT0(low_threshold); + ADC_WDHT0(adc_periph) = (uint32_t)WDHT0_WDHT0(high_threshold); +} + +/*! + \brief configure ADC analog watchdog 1 threshold + \param[in] adc_periph: ADCx, x=0,1 + \param[in] low_threshold: analog watchdog 1 low threshold, 0..255 + \param[in] high_threshold: analog watchdog 1 high threshold, 0..255 + \param[out] none + \retval none +*/ +void adc_watchdog1_threshold_config(uint32_t adc_periph, uint8_t low_threshold, uint8_t high_threshold) +{ + ADC_WDT1(adc_periph) &= ~((uint32_t)(ADC_WDT1_WDLT1 | ADC_WDT1_WDHT1)); + /* configure ADC analog watchdog 1 threshold */ + ADC_WDT1(adc_periph) |= (uint32_t)WDT1_WDLT1(low_threshold); + ADC_WDT1(adc_periph) |= (uint32_t)WDT1_WDHT1(high_threshold); +} + +/*! + \brief configure ADC resolution + \param[in] adc_periph: ADCx, x=0,1 + \param[in] resolution: ADC resolution + only one parameter can be selected which is shown as below: + \arg ADC_RESOLUTION_12B: 12-bit ADC resolution + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution + \param[out] none + \retval none +*/ +void adc_resolution_config(uint32_t adc_periph, uint32_t resolution) +{ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_DRES); + ADC_OVSAMPCTL(adc_periph) |= (uint32_t)resolution; +} + +/*! + \brief configure ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1 + \param[in] mode: ADC oversampling mode + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger + \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger + \param[in] shift: ADC oversampling shift + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift + \param[in] ratio: ADC oversampling ratio + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint8_t ratio) +{ + /* configure ADC oversampling mode */ + if(ADC_OVERSAMPLING_ONE_CONVERT == mode){ + ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS; + }else{ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + /* configure the shift and ratio */ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio); +} + +/*! + \brief enable ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(uint32_t adc_periph) +{ + ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief disable ADC oversample mode + \param[in] adc_periph: ADCx, x=0,1 + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(uint32_t adc_periph) +{ + ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} + +/*! + \brief get the ADC flag + \param[in] adc_periph: ADCx, x=0,1 + \param[in] flag: the ADC flag bits + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WDE0: analog watchdog 0 event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \arg ADC_FLAG_WDE1: analog watchdog 1 event flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t flag) +{ + FlagStatus reval = RESET; + if(ADC_STAT(adc_periph) & flag){ + reval = SET; + } + return reval; +} + +/*! + \brief clear the ADC flag + \param[in] adc_periph: ADCx, x=0,1 + \param[in] flag: the ADC flag + one or more parameters can be selected which is shown as below: + \arg ADC_FLAG_WDE0: analog watchdog 0 event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \arg ADC_FLAG_WDE1: analog watchdog 1 event flag + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t adc_periph , uint32_t flag) +{ + ADC_STAT(adc_periph) = ~((uint32_t)flag); +} + +/*! + \brief enable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1,2 + \param[in] interrupt: the ADC interrupt + one or more parameters can be selected which is shown as below: + \arg ADC_INT_WDE0: analog watchdog 0 interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_WDE1: analog watchdog 1 interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t adc_periph , uint32_t interrupt) +{ + switch(interrupt){ + /* enable analog watchdog 0 interrupt */ + case ADC_INT_WDE0: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_WDE0IE; + break; + /* enable end of group conversion interrupt */ + case ADC_INT_EOC: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_EOCIE; + break; + /* enable end of inserted group conversion interrupt */ + case ADC_INT_EOIC: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_EOICIE; + break; + /* enable analog watchdog 1 interrupt */ + case ADC_INT_WDE1: + ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_WDE1IE; + break; + default: + break; + } +} + +/*! + \brief disable ADC interrupt + \param[in] adc_periph: ADCx, x=0,1 + \param[in] interrupt: the ADC interrupt flag + one or more parameters can be selected which is shown as below: + \arg ADC_INT_WDE0: analog watchdog 0 interrupt flag + \arg ADC_INT_EOC: end of group conversion interrupt flag + \arg ADC_INT_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_WDE1: analog watchdog 1 interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t adc_periph, uint32_t interrupt) +{ + switch(interrupt){ + /* disable analog watchdog 0 interrupt */ + case ADC_INT_WDE0: + ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_WDE0IE; + break; + /* disable end of group conversion interrupt */ + case ADC_INT_EOC: + ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_EOCIE; + break; + /* disable end of inserted group conversion interrupt */ + case ADC_INT_EOIC: + ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_EOICIE; + break; + /* disable analog watchdog 1 interrupt */ + case ADC_INT_WDE1: + ADC_CTL0(adc_periph) &= ~(uint32_t)ADC_CTL0_WDE1IE; + break; + default: + break; + } +} + +/*! + \brief get ADC interrupt flag + \param[in] adc_periph: ADCx, x=0,1 + \param[in] int_flag: the ADC interrupt + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE0: analog watchdog 0 interrupt flag + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt + \arg ADC_INT_FLAG_WDE1: analog watchdog 1 interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t adc_periph , uint32_t int_flag) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + /* check the interrupt bits */ + switch(int_flag){ + case ADC_INT_FLAG_WDE0: + state = ADC_STAT(adc_periph) & ADC_STAT_WDE0; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDE0IE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + state = ADC_STAT(adc_periph) & ADC_STAT_EOC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + state = ADC_STAT(adc_periph) & ADC_STAT_EOIC; + if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_WDE1: + state = ADC_STAT(adc_periph) & ADC_STAT_WDE1; + if((ADC_CTL0(adc_periph) & ADC_CTL0_WDE1IE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear ADC interrupt flag + \param[in] adc_periph: ADCx, x=0,1 + \param[in] int_flag: the ADC interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE0: analog watchdog 0 interrupt flag + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag + \arg ADC_INT_FLAG_WDE1: analog watchdog 1 interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t int_flag) +{ + ADC_STAT(adc_periph) = ~((uint32_t)int_flag); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_bkp.c b/gd32a50x/standard_peripheral/source/gd32a50x_bkp.c new file mode 100644 index 0000000..139c8ab --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_bkp.c @@ -0,0 +1,346 @@ +/*! + \file gd32a50x_bkp.c + \brief BKP driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_bkp.h" + +#define TAMPER_FLAG_SHIFT ((uint8_t)0x08U) + +/*! + \brief reset BKP registers + \param[in] none + \param[out] none + \retval none +*/ +void bkp_deinit(void) +{ + /* reset BKP domain register */ + rcu_bkp_reset_enable(); + rcu_bkp_reset_disable(); +} + +/*! + \brief write BKP data register + \param[in] register_number: refer to bkp_data_register_enum + only one parameter can be selected which is shown as below: + \arg BKP_DATA_x(x = 0..9): BKP data register number x + \param[in] data: the data to be write in BKP data register + \param[out] none + \retval none +*/ +void bkp_data_write(bkp_data_register_enum register_number, uint16_t data) +{ + if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){ + BKP_DATA0_9(register_number-1U) = data; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief read BKP data register + \param[in] register_number: refer to bkp_data_register_enum + only one parameter can be selected which is shown as below: + \arg BKP_DATA_x(x = 0..9): BKP data register number x + \param[out] none + \retval data of BKP data register +*/ +uint16_t bkp_data_read(bkp_data_register_enum register_number) +{ + uint16_t data = 0U; + + /* get the data from the BKP data register */ + if((register_number >= BKP_DATA_0) && (register_number <= BKP_DATA_9)){ + data = BKP_DATA0_9(register_number-1U); + }else{ + /* illegal parameters */ + } + return data; +} + +/*! + \brief enable RTC clock calibration output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_calibration_output_enable(void) +{ + BKP_OCTL |= (uint16_t)BKP_OCTL_COEN; +} + +/*! + \brief disable RTC clock calibration output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_calibration_output_disable(void) +{ + BKP_OCTL &= (uint16_t)~BKP_OCTL_COEN; +} + +/*! + \brief enable RTC alarm or second signal output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_signal_output_enable(void) +{ + BKP_OCTL |= (uint16_t)BKP_OCTL_ASOEN; +} + +/*! + \brief disable RTC alarm or second signal output + \param[in] none + \param[out] none + \retval none +*/ +void bkp_rtc_signal_output_disable(void) +{ + BKP_OCTL &= (uint16_t)~BKP_OCTL_ASOEN; +} + +/*! + \brief select RTC output + \param[in] outputsel: RTC output selection + only one parameter can be selected which is shown as below: + \arg RTC_OUTPUT_ALARM_PULSE: RTC alarm pulse is selected as the RTC output + \arg RTC_OUTPUT_SECOND_PULSE: RTC second pulse is selected as the RTC output + \param[out] none + \retval none +*/ +void bkp_rtc_output_select(uint16_t outputsel) +{ + uint16_t ctl = 0U; + + ctl = BKP_OCTL; + ctl &= (uint16_t)~BKP_OCTL_ROSEL; + ctl |= outputsel; + BKP_OCTL = ctl; +} + +/*! + \brief select RTC clock output + \param[in] clocksel: RTC clock output selection + only one parameter can be selected which is shown as below: + \arg RTC_CLOCK_DIV_64: RTC clock div 64 + \arg RTC_CLOCK_DIV_1: RTC clock + \param[out] none + \retval none +*/ +void bkp_rtc_clock_output_select(uint16_t clocksel) +{ + uint16_t ctl = 0U; + + ctl = BKP_OCTL; + ctl &= (uint16_t)~BKP_OCTL_CCOSEL; + ctl |= clocksel; + BKP_OCTL = ctl; +} + +/*! + \brief RTC clock calibration direction + \param[in] direction: RTC clock calibration direction + only one parameter can be selected which is shown as below: + \arg RTC_CLOCK_SLOWED_DOWN: RTC clock slow down + \arg RTC_CLOCK_SPEED_UP: RTC clock speed up + \param[out] none + \retval none +*/ +void bkp_rtc_clock_calibration_direction(uint16_t direction) +{ + uint16_t ctl = 0U; + + ctl = BKP_OCTL; + ctl &= (uint16_t)~BKP_OCTL_CALDIR; + ctl |= direction; + BKP_OCTL = ctl; +} + +/*! + \brief set RTC clock calibration value + \param[in] value: RTC clock calibration value + only one parameter can be selected which is shown as below: + \arg 0x00 - 0x7F + \param[out] none + \retval none +*/ +void bkp_rtc_calibration_value_set(uint8_t value) +{ + uint16_t ctl; + + ctl = BKP_OCTL; + ctl &= (uint16_t)~BKP_OCTL_RCCV; + ctl |= (uint16_t)OCTL_RCCV(value); + BKP_OCTL = ctl; +} + +/*! + \brief select OSC32IN pin + \param[in] inputpin: OSC32IN pin selection + only one parameter can be selected which is shown as below: + \arg OSC32IN_PC13: OSC32IN pin is PC13 + \arg OSC32IN_PC14: OSC32IN pin is PC14 + \param[out] none + \retval none +*/ +void bkp_osc32in_pin_select(uint16_t inputpin) +{ + uint16_t ctl = 0U; + + ctl = BKP_TPCTL; + ctl &= (uint16_t)~BKP_TPCTL_PCSEL; + ctl |= inputpin; + BKP_TPCTL = ctl; +} + +/*! + \brief enable tamper pin detection + \param[in] none + \param[out] none + \retval none +*/ +void bkp_tamper_detection_enable(void) +{ + BKP_TPCTL |= (uint16_t)BKP_TPCTL_TPEN; +} + +/*! + \brief disable tamper pin detection + \param[in] none + \param[out] none + \retval none +*/ +void bkp_tamper_detection_disable(void) +{ + BKP_TPCTL &= (uint16_t)~BKP_TPCTL_TPEN; +} + +/*! + \brief set tamper pin active level + \param[in] level: tamper active level + only one parameter can be selected which is shown as below: + \arg TAMPER_PIN_ACTIVE_HIGH: the tamper pin is active high + \arg TAMPER_PIN_ACTIVE_LOW: the tamper pin is active low + \param[out] none + \retval none +*/ +void bkp_tamper_active_level_set(uint16_t level) +{ + uint16_t ctl = 0U; + + ctl = BKP_TPCTL; + ctl &= (uint16_t)~BKP_TPCTL_TPAL; + ctl |= level; + BKP_TPCTL = ctl; +} + +/*! + \brief enable tamper pin interrupt + \param[in] none + \param[out] none + \retval none +*/ +void bkp_tamper_interrupt_enable(void) +{ + BKP_TPCS |= (uint16_t)BKP_TPCS_TPIE; +} + +/*! + \brief disable tamper pin interrupt + \param[in] none + \param[out] none + \retval none +*/ +void bkp_tamper_interrupt_disable(void) +{ + BKP_TPCS &= (uint16_t)~BKP_TPCS_TPIE; +} + +/*! + \brief get bkp flag state + \param[in] flag: + \arg BKP_FLAG_TAMPER: tamper event flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus bkp_flag_get(uint16_t flag) +{ + if(0U != (BKP_TPCS & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear BKP flag state + \param[in] flag: + \arg BKP_FLAG_TAMPER: tamper event flag + \param[out] none + \retval none +*/ +void bkp_flag_clear(uint16_t flag) +{ + BKP_TPCS |= (uint16_t)(flag >> TAMPER_FLAG_SHIFT); +} + +/*! + \brief get BKP interrupt flag state + \param[in] flag + \arg BKP_INT_FLAG_TAMPER: tamper interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus bkp_interrupt_flag_get(uint16_t flag) +{ + if(0U != (BKP_TPCS & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear BKP interrupt flag state + \param[in] flag: + \arg BKP_INT_FLAG_TAMPER: tamper interrupt flag + \param[out] none + \retval none +*/ +void bkp_interrupt_flag_clear(uint16_t flag) +{ + BKP_TPCS |= (uint16_t)(flag >> TAMPER_FLAG_SHIFT); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_can.c b/gd32a50x/standard_peripheral/source/gd32a50x_can.c new file mode 100644 index 0000000..20690c4 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_can.c @@ -0,0 +1,1844 @@ +/*! + \file gd32a50x_can.c + \brief CAN driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_can.h" + +/* DLC to data size in bytes definitions */ +static const uint8_t dlc_to_databytes[16] = {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U}; + +/* computes the maximum payload size (in bytes), given a dlc */ +static uint32_t can_payload_size_compute(uint32_t dlc_value); +/* swap data to little endian */ +static void can_data_to_little_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len); +/* swap data to big endian */ +static void can_data_to_big_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len); +/* computes the dlc field value, given a payload size (in bytes) */ +static uint32_t can_dlc_value_compute(uint32_t payload_size); + +/*! + \brief deinitialize CAN + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_deinit(uint32_t can_periph) +{ + if(CAN0 == can_periph) { + /* reset CAN0 */ + rcu_periph_reset_enable(RCU_CAN0RST); + rcu_periph_reset_disable(RCU_CAN0RST); + } + if(CAN1 == can_periph) { + /* reset CAN1 */ + rcu_periph_reset_enable(RCU_CAN1RST); + rcu_periph_reset_disable(RCU_CAN1RST); + } +} + +/*! + \brief reset CAN internal state machines and CAN registers + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_software_reset(uint32_t can_periph) +{ + uint32_t timeout = CAN_DELAY; + + /* reset internal state machines and CAN registers */ + CAN_CTL0(can_periph) |= CAN_CTL0_SWRST; + /* wait reset complete */ + while((CAN_CTL0(can_periph) & CAN_CTL0_SWRST) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_SWRST) { + return ERROR; + } + return SUCCESS; +} + +/*! + \brief CAN module initialization + \param[in] can_periph: CANx(x=0,1) + \param[in] can_parameter_init: can parameter struct + internal_counter_source: CAN_TIMER_SOURCE_BIT_CLOCK, CAN_TIMER_SOURCE_EXTERNAL_TIME_TICK + self_reception: ENABLE, DISABLE + mb_tx_order: CAN_TX_HIGH_PRIORITY_MB_FIRST, CAN_TX_LOW_NUM_MB_FIRST + mb_tx_abort_enable: ENABLE, DISABLE + local_priority_enable: ENABLE, DISABLE + mb_rx_ide_rtr_type: CAN_IDE_RTR_COMPARED, CAN_IDE_RTR_FILTERED + mb_remote_frame: CAN_GEN_REMOTE_RESPONSE_FRAME, CAN_STORE_REMOTE_REQUEST_FRAME + rx_private_filter_queue_enable: ENABLE, DISABLE + edge_filter_enable: ENABLE, DISABLE + protocol_exception_enable: ENABLE, DISABLE + rx_filter_order: CAN_RX_FILTER_ORDER_FIFO_FIRST, CAN_RX_FILTER_ORDER_MAILBOX_FIRST + memory_size: CAN_MEMSIZE_1_UNIT, CAN_MEMSIZE_2_UNIT, CAN_MEMSIZE_3_UNIT, CAN_MEMSIZE_4_UNIT, + CAN_MEMSIZE_5_UNIT, CAN_MEMSIZE_6_UNIT, CAN_MEMSIZE_7_UNIT, CAN_MEMSIZE_8_UNIT, + CAN_MEMSIZE_9_UNIT, CAN_MEMSIZE_10_UNIT, CAN_MEMSIZE_11_UNIT, CAN_MEMSIZE_12_UNIT, + CAN_MEMSIZE_13_UNIT, CAN_MEMSIZE_14_UNIT, CAN_MEMSIZE_15_UNIT, CAN_MEMSIZE_16_UNIT, + CAN_MEMSIZE_17_UNIT, CAN_MEMSIZE_18_UNIT, CAN_MEMSIZE_19_UNIT, CAN_MEMSIZE_20_UNIT, + CAN_MEMSIZE_21_UNIT, CAN_MEMSIZE_22_UNIT, CAN_MEMSIZE_23_UNIT, CAN_MEMSIZE_24_UNIT, + CAN_MEMSIZE_25_UNIT, CAN_MEMSIZE_26_UNIT, CAN_MEMSIZE_27_UNIT, CAN_MEMSIZE_28_UNIT, + CAN_MEMSIZE_29_UNIT, CAN_MEMSIZE_30_UNIT, CAN_MEMSIZE_31_UNIT, CAN_MEMSIZE_32_UNIT + mb_public_filter: 0x00000000 ~ 0xFFFFFFFF + prescaler: 1~1024 + resync_jump_width: 1~32 + prop_time_segment: 1~64 + time_segment_1: 1~32 + time_segment_2: 1~32 + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_init(uint32_t can_periph, can_parameter_struct *can_parameter_init) +{ + uint32_t i; + uint32_t *canram = (uint32_t *)(CAN_RAM(can_periph)); + + /* clear CAN RAM */ + for(i = 0U; i < CAN_MAX_RAM_SIZE; i++) { + canram[i] = 0U; + } + /* reset CAN_RFIFOMPFx */ + for(i = 0U; i < CAN_MAX_MAILBOX_NUM; i++) { + CAN_RFIFOMPF(can_periph, i) = 0x00000000U; + } + + /* reset internal state machines and CAN registers */ + if(ERROR == can_software_reset(can_periph)) { + return ERROR; + } + + /* reset CAN_INTEN */ + CAN_INTEN(can_periph) = 0U; + /* reset CAN_STAT */ + CAN_STAT(can_periph) = (uint32_t)0xFFFFFFFFU; + CAN_TIMER(can_periph); + while(CAN_STAT(can_periph) & CAN_STAT_MS5_RFNE) { + CAN_STAT(can_periph) = CAN_STAT_MS5_RFNE; + } + + /* clear register bits */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_RFEN | CAN_CTL0_FDEN | CAN_CTL0_SRDIS | CAN_CTL0_LAPRIOEN | CAN_CTL0_MST | CAN_CTL0_RPFQEN | CAN_CTL0_MSZ); + CAN_CTL2(can_periph) &= ~(CAN_CTL2_ITSRC | CAN_CTL2_IDERTR_RMF | CAN_CTL2_RRFRMS | CAN_CTL2_RFO | CAN_CTL2_EFDIS | CAN_CTL2_PREEN); + CAN_CTL1(can_periph) &= ~CAN_CTL1_MTO; + CAN_BT(can_periph) &= ~(CAN_BT_BAUDPSC | CAN_BT_SJW | CAN_BT_PTS | CAN_BT_PBS1 | CAN_BT_PBS2); + + /* set self reception */ + if((uint8_t)DISABLE == can_parameter_init->self_reception) { + CAN_CTL0(can_periph) |= CAN_CTL0_SRDIS; + } + /* enable local arbitration priority */ + if((uint8_t)ENABLE == can_parameter_init->local_priority_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_LAPRIOEN; + } + /* set rx private filters and mailbox queue */ + if((uint8_t)ENABLE == can_parameter_init->rx_private_filter_queue_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_RPFQEN; + } + /* configure edge filtering */ + if((uint32_t)DISABLE == can_parameter_init->edge_filter_enable) { + CAN_CTL2(can_periph) |= CAN_CTL2_EFDIS; + } + /* configure protocol exception */ + if((uint32_t)ENABLE == can_parameter_init->protocol_exception_enable) { + CAN_CTL2(can_periph) |= CAN_CTL2_PREEN; + } + /* set mailbox stop transmission */ + if((uint8_t)ENABLE == can_parameter_init->mb_tx_abort_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_MST; + } + + /* set internal counter source */ + CAN_CTL2(can_periph) |= can_parameter_init->internal_counter_source; + /* set mailbox arbitration process order */ + CAN_CTL1(can_periph) |= can_parameter_init->mb_tx_order; + /* set IDE and RTR field filter type */ + CAN_CTL2(can_periph) |= can_parameter_init->mb_rx_ide_rtr_type; + /* configure remote request frame */ + CAN_CTL2(can_periph) |= can_parameter_init->mb_remote_frame; + /* set mailbox public filter */ + CAN_RMPUBF(can_periph) = can_parameter_init->mb_public_filter; + /* configure receive filter order */ + CAN_CTL2(can_periph) |= can_parameter_init->rx_filter_order; + /* set memory size */ + CAN_CTL0(can_periph) |= can_parameter_init->memory_size; + /* set time segment */ + CAN_BT(can_periph) |= (uint32_t)(BT_BAUDPSC(can_parameter_init->prescaler - 1U) | + BT_SJW((uint32_t)can_parameter_init->resync_jump_width - 1U) | + BT_PTS((uint32_t)can_parameter_init->prop_time_segment - 1U) | + BT_PBS1((uint32_t)can_parameter_init->time_segment_1 - 1U) | + BT_PBS2((uint32_t)can_parameter_init->time_segment_2 - 1U)); + + return SUCCESS; +} + +/*! + \brief initialize CAN parameter structure with a default value + \param[in] type: the type of CAN parameter struct + only one parameter can be selected which is shown as below: + \arg CAN_INIT_STRUCT: the CAN initial struct + \arg CAN_FD_INIT_STRUCT: the CAN FD initial struct + \arg CAN_FIFO_INIT_STRUCT: the CAN FIFO initial struct + \arg CAN_PN_MODE_INIT_STRUCT: the CAN Pretended Networking mode initial struct + \arg CAN_PN_MODE_FILTER_STRUCT: the CAN Pretended Networking mode filter struct + \arg CAN_MDSC_STRUCT: mailbox descriptor strcut + \arg CAN_FDES_STRUCT: Rx fifo descriptor strcut + \arg CAN_FIFO_ID_FILTER_STRUCT: Rx fifo id filter strcut + \arg CAN_CRC_STRUCT: CRC strcut + \arg CAN_ERRCNT_STRUCT: error counter strcut + \param[in] p_struct: the pointer of the specific struct + \param[out] none + \retval none +*/ +void can_struct_para_init(can_struct_type_enum type, void *p_struct) +{ + /* get type of the struct */ + switch(type) { + /* used for initialize can_parameter_struct */ + case CAN_INIT_STRUCT: + ((can_parameter_struct *)p_struct)->self_reception = (uint8_t)DISABLE; + ((can_parameter_struct *)p_struct)->internal_counter_source = CAN_TIMER_SOURCE_BIT_CLOCK; + ((can_parameter_struct *)p_struct)->mb_tx_order = CAN_TX_HIGH_PRIORITY_MB_FIRST; + ((can_parameter_struct *)p_struct)->mb_tx_abort_enable = (uint8_t)ENABLE; + ((can_parameter_struct *)p_struct)->local_priority_enable = (uint8_t)DISABLE; + ((can_parameter_struct *)p_struct)->mb_rx_ide_rtr_type = CAN_IDE_RTR_COMPARED; + ((can_parameter_struct *)p_struct)->mb_remote_frame = CAN_STORE_REMOTE_REQUEST_FRAME; + ((can_parameter_struct *)p_struct)->rx_private_filter_queue_enable = (uint8_t)DISABLE; + ((can_parameter_struct *)p_struct)->edge_filter_enable = (uint32_t)DISABLE; + ((can_parameter_struct *)p_struct)->protocol_exception_enable = (uint32_t)DISABLE; + ((can_parameter_struct *)p_struct)->rx_filter_order = CAN_RX_FILTER_ORDER_FIFO_FIRST; + ((can_parameter_struct *)p_struct)->memory_size = CAN_MEMSIZE_32_UNIT; + ((can_parameter_struct *)p_struct)->mb_public_filter = 0xFFFFFFFFU; + ((can_parameter_struct *)p_struct)->prescaler = 0x00000001U; + ((can_parameter_struct *)p_struct)->resync_jump_width = 0x01U; + ((can_parameter_struct *)p_struct)->prop_time_segment = 0x01U; + ((can_parameter_struct *)p_struct)->time_segment_1 = 0x01U; + ((can_parameter_struct *)p_struct)->time_segment_2 = 0x01U; + break; + /* used for initialize can_fd_parameter_struct */ + case CAN_FD_INIT_STRUCT: + ((can_fd_parameter_struct *)p_struct)->iso_can_fd_enable = (uint32_t)DISABLE; + ((can_fd_parameter_struct *)p_struct)->bitrate_switch_enable = (uint32_t)ENABLE; + ((can_fd_parameter_struct *)p_struct)->mailbox_data_size = CAN_MAILBOX_DATA_SIZE_8_BYTES; + ((can_fd_parameter_struct *)p_struct)->tdc_enable = (uint32_t)DISABLE; + ((can_fd_parameter_struct *)p_struct)->tdc_offset = 0x00U; + ((can_fd_parameter_struct *)p_struct)->prescaler = 0x00000001U; + ((can_fd_parameter_struct *)p_struct)->resync_jump_width = 0x01U; + ((can_fd_parameter_struct *)p_struct)->prop_time_segment = 0x00U; + ((can_fd_parameter_struct *)p_struct)->time_segment_1 = 0x01U; + ((can_fd_parameter_struct *)p_struct)->time_segment_2 = 0x01U; + break; + /* used for initialize can_fifo_parameter_struct */ + case CAN_FIFO_INIT_STRUCT: + ((can_fifo_parameter_struct *)p_struct)->dma_enable = (uint8_t)DISABLE; + ((can_fifo_parameter_struct *)p_struct)->filter_format_and_number = CAN_RXFIFO_FILTER_A_NUM_8; + ((can_fifo_parameter_struct *)p_struct)->fifo_public_filter = 0xFFFFFFFFU; + break; + /* used for initialize can_pn_mode_config_struct */ + case CAN_PN_MODE_INIT_STRUCT: + ((can_pn_mode_config_struct *)p_struct)->timeout_int = (uint32_t)DISABLE; + ((can_pn_mode_config_struct *)p_struct)->match_int = (uint32_t)DISABLE; + ((can_pn_mode_config_struct *)p_struct)->num_matches = 0x01U; + ((can_pn_mode_config_struct *)p_struct)->match_timeout = 0x0000U; + ((can_pn_mode_config_struct *)p_struct)->frame_filter = CAN_PN_FRAME_FILTERING_ID; + ((can_pn_mode_config_struct *)p_struct)->id_filter = CAN_PN_ID_FILTERING_EXACT; + ((can_pn_mode_config_struct *)p_struct)->data_filter = CAN_PN_DATA_FILTERING_EXACT; + break; + /* used for initialize can_pn_mode_filter_struct */ + case CAN_PN_MODE_FILTER_STRUCT: + ((can_pn_mode_filter_struct *)p_struct)->remote_frame = (uint32_t)RESET; + ((can_pn_mode_filter_struct *)p_struct)->extended_frame = (uint32_t)RESET; + ((can_pn_mode_filter_struct *)p_struct)->id = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->dlc_high_threshold = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->dlc_low_threshold = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->payload[0] = 0x00000000U; + ((can_pn_mode_filter_struct *)p_struct)->payload[1] = 0x00000000U; + break; + /* used for initialize can_mailbox_descriptor_struct */ + case CAN_MDSC_STRUCT: + ((can_mailbox_descriptor_struct *)p_struct)->timestamp = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->dlc = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->rtr = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->ide = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->srr = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->reserve1 = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->code = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->reserve2 = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->esi = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->brs = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->fdf = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->id = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->prio = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->data = (void *)0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->data_bytes = 0x00000000U; + ((can_mailbox_descriptor_struct *)p_struct)->padding = 0x0000U; + break; + /* used for initialize can_rx_fifo_struct */ + case CAN_FDES_STRUCT: + ((can_rx_fifo_struct *)p_struct)->timestamp = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->dlc = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->rtr = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->ide = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->srr = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->idhit = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->id = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->data[0] = 0x00000000U; + ((can_rx_fifo_struct *)p_struct)->data[1] = 0x00000000U; + break; + /* used for initialize can_rx_fifo_id_filter_struct */ + case CAN_FIFO_ID_FILTER_STRUCT: + ((can_rx_fifo_id_filter_struct *)p_struct)->remote_frame = 0x00000000U; + ((can_rx_fifo_id_filter_struct *)p_struct)->extended_frame = 0x00000000U; + ((can_rx_fifo_id_filter_struct *)p_struct)->id = 0x00000000U; + break; + /* used for initialize can_crc_struct */ + case CAN_CRC_STRUCT: + ((can_crc_struct *)p_struct)->classical_frm_mb_number = 0x00000000U; + ((can_crc_struct *)p_struct)->classical_frm_transmitted_crc = 0x00000000U; + ((can_crc_struct *)p_struct)->classical_fd_frm_mb_number = 0x00000000U; + ((can_crc_struct *)p_struct)->classical_fd_frm_transmitted_crc = 0x00000000U; + break; + /* used for initialize can_crc_struct */ + case CAN_ERRCNT_STRUCT: + ((can_error_counter_struct *)p_struct)->fd_data_phase_rx_errcnt = 0x00U; + ((can_error_counter_struct *)p_struct)->fd_data_phase_tx_errcnt = 0x00U; + ((can_error_counter_struct *)p_struct)->rx_errcnt = 0x00U; + ((can_error_counter_struct *)p_struct)->tx_errcnt = 0x00U; + break; + default: + break; + } +} + +/*! + \brief configure receive fifo/mailbox private filter + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index + \param[in] filter_data: filter data to configure + \param[out] none + \retval none +*/ +void can_private_filter_config(uint32_t can_periph, uint32_t index, uint32_t filter_data) +{ + CAN_RFIFOMPF(can_periph, index) = filter_data; +} + +/*! + \brief enter the corresponding mode + \param[in] can_periph: CANx(x=0,1) + \param[in] mode: the mode to enter + only one parameter can be selected which is shown as below: + \arg CAN_NORMAL_MODE: normal mode + \arg CAN_MONITOR_MODE: monitor mode + \arg CAN_LOOPBACK_SILENT_MODE: loopback mode + \arg CAN_INACTIVE_MODE: inactive mode + \arg CAN_DISABLE_MODE: disable mode + \arg CAN_PN_MODE: Pretended Networking mode + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum mode) +{ + uint32_t timeout; + ErrStatus ret = SUCCESS; + + /* enter INACTIVE mode */ + /* exit can_disable mode */ + CAN_CTL0(can_periph) &= ~CAN_CTL0_CANDIS; + /* enter inactive mode */ + CAN_CTL0(can_periph) |= CAN_CTL0_HALT | CAN_CTL0_INAMOD; + /* exit Pretended Networking mode */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_PNEN | CAN_CTL0_PNMOD); + timeout = CAN_DELAY; + /* wait for inactive mode state */ + while(((CAN_CTL0_NRDY | CAN_CTL0_INAS) != (CAN_CTL0(can_periph) & (CAN_CTL0_NRDY | CAN_CTL0_INAS))) && (timeout)) { + timeout--; + } + if((CAN_CTL0_NRDY | CAN_CTL0_INAS) != (CAN_CTL0(can_periph) & (CAN_CTL0_NRDY | CAN_CTL0_INAS))) { + return ERROR; + } + + /* configure the modes */ + switch(mode) { + case CAN_NORMAL_MODE: + CAN_CTL1(can_periph) &= ~(CAN_CTL1_LSCMOD | CAN_CTL1_MMOD); + break; + case CAN_MONITOR_MODE: + CAN_CTL1(can_periph) &= ~CAN_CTL1_LSCMOD; + CAN_CTL1(can_periph) |= CAN_CTL1_MMOD; + break; + case CAN_LOOPBACK_SILENT_MODE: + CAN_CTL1(can_periph) &= ~CAN_CTL1_MMOD; + CAN_CTL0(can_periph) &= ~CAN_CTL0_SRDIS; + CAN_FDCTL(can_periph) &= ~CAN_FDCTL_TDCEN; + CAN_CTL1(can_periph) |= CAN_CTL1_LSCMOD; + break; + case CAN_INACTIVE_MODE: + break; + case CAN_DISABLE_MODE: + CAN_CTL0(can_periph) |= CAN_CTL0_CANDIS; + break; + case CAN_PN_MODE: + CAN_CTL0(can_periph) |= (CAN_CTL0_PNEN | CAN_CTL0_PNMOD); + break; + default: + break; + } + + /* exit INACTIVE mode */ + if(CAN_INACTIVE_MODE != mode) { + /* exit inactive mode */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_HALT | CAN_CTL0_INAMOD); + timeout = CAN_DELAY; + while((CAN_CTL0(can_periph) & CAN_CTL0_INAS) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_INAS) { + return ERROR; + } + } + + if(CAN_PN_MODE == mode) { + timeout = CAN_DELAY; + while((0U == (CAN_CTL0(can_periph) & CAN_CTL0_PNS)) && (timeout)) { + timeout--; + } + if(0U == (CAN_CTL0(can_periph) & CAN_CTL0_PNS)) { + return ERROR; + } + } + return ret; +} + +/*! + \brief get operation mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval can_operation_modes_enum +*/ +can_operation_modes_enum can_operation_mode_get(uint32_t can_periph) +{ + uint32_t reg; + can_operation_modes_enum state = CAN_NORMAL_MODE; + + reg = CAN_CTL0(can_periph); + reg &= (CAN_CTL0_NRDY | CAN_CTL0_INAS | CAN_CTL0_PNS | CAN_CTL0_LPS); + + if((CAN_CTL0_NRDY | CAN_CTL0_LPS) == reg) { + state = CAN_DISABLE_MODE; + } else if((CAN_CTL0_NRDY | CAN_CTL0_INAS) == reg) { + state = CAN_INACTIVE_MODE; + } else if(0U == reg) { + if(CAN_CTL1(can_periph)&CAN_CTL1_MMOD) { + state = CAN_MONITOR_MODE; + } else if(CAN_CTL1(can_periph)&CAN_CTL1_LSCMOD) { + state = CAN_LOOPBACK_SILENT_MODE; + } else { + state = CAN_NORMAL_MODE; + } + } else if(CAN_CTL0_PNS == reg) { + state = CAN_PN_MODE; + } else { + /* should not get here */ + } + + return state; +} + +/*! + \brief exit inactive mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_inactive_mode_exit(uint32_t can_periph) +{ + uint32_t timeout; + + /* exit inactive mode */ + CAN_CTL0(can_periph) &= ~CAN_CTL0_HALT; + timeout = CAN_DELAY; + while((CAN_CTL0(can_periph) & CAN_CTL0_INAS) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_INAS) { + return ERROR; + } else { + return SUCCESS; + } +} + +/*! + \brief exit Pretended Networking mode + \param[in] can_periph: CANx(x=0,1) + \param[in] none + \param[out] none + \retval ERROR or SUCCESS +*/ +ErrStatus can_pn_mode_exit(uint32_t can_periph) +{ + uint32_t timeout; + + CAN_CTL0(can_periph) &= ~(CAN_CTL0_PNEN | CAN_CTL0_PNMOD); + timeout = CAN_DELAY; + while((CAN_CTL0(can_periph) & CAN_CTL0_PNS) && (timeout)) { + timeout--; + } + if(CAN_CTL0(can_periph) & CAN_CTL0_PNS) { + return ERROR; + } else { + return SUCCESS; + } +} + +/*! + \brief can FD initialize + \param[in] can_periph: CANx(x=0,1) + \param[in] can_fd_para_init: can fd parameter struct + iso_can_fd_enable: ENABLE, DISABLE + bitrate_switch_enable: ENABLE, DISABLE + mailbox_data_size: CAN_MAILBOX_DATA_SIZE_8_BYTES, CAN_MAILBOX_DATA_SIZE_16_BYTES, + CAN_MAILBOX_DATA_SIZE_32_BYTES, CAN_MAILBOX_DATA_SIZE_64_BYTES + tdc_enable: ENABLE, DISABLE + tdc_offset: 0 ~ 31 + prescaler: 1~1024 + resync_jump_width: 1~8 + prop_time_segment: 0~31 + time_segment_1: 1~8 + time_segment_2: 2~8 + \param[out] none + \retval none +*/ +void can_fd_config(uint32_t can_periph, can_fd_parameter_struct *can_fd_para_init) +{ + /* clear register bits, then enable FD mode */ + CAN_CTL0(can_periph) &= ~CAN_CTL0_RFEN; + CAN_CTL1(can_periph) &= ~CAN_CTL1_BSPMOD; + CAN_CTL2(can_periph) &= ~CAN_CTL2_ISO; + CAN_FDCTL(can_periph) &= ~(CAN_FDCTL_BRSEN | CAN_FDCTL_MDSZ | CAN_FDCTL_TDCEN | CAN_FDCTL_TDCO); + CAN_FDBT(can_periph) &= ~(CAN_FDBT_DBAUDPSC | CAN_FDBT_DSJW | CAN_FDBT_DPTS | CAN_FDBT_DPBS1 | CAN_FDBT_DPBS2); + CAN_CTL0(can_periph) |= CAN_CTL0_FDEN; + + /* support ISO or non-ISO mode */ + if((uint32_t)ENABLE == can_fd_para_init->iso_can_fd_enable) { + CAN_CTL2(can_periph) |= CAN_CTL2_ISO; + } + /* set TDC parameter */ + if((uint32_t)ENABLE == can_fd_para_init->tdc_enable) { + CAN_FDCTL(can_periph) |= CAN_FDCTL_TDCEN; + } + /* set data bit rate */ + if((uint32_t)ENABLE == can_fd_para_init->bitrate_switch_enable) { + CAN_FDCTL(can_periph) |= CAN_FDCTL_BRSEN; + } + + /* set mailbox data size */ + CAN_FDCTL(can_periph) |= can_fd_para_init->mailbox_data_size; + /* configure FD bit timing */ + CAN_FDBT(can_periph) |= (uint32_t)(FDBT_DBAUDPSC(can_fd_para_init->prescaler - 1U) | + FDBT_DSJW((uint32_t)can_fd_para_init->resync_jump_width - 1U) | + FDBT_DPTS(can_fd_para_init->prop_time_segment) | + FDBT_DPBS1((uint32_t)can_fd_para_init->time_segment_1 - 1U) | + FDBT_DPBS2((uint32_t)can_fd_para_init->time_segment_2 - 1U)); + /* configure transmitter delay compensation offset */ + CAN_FDCTL(can_periph) |= FDCTL_TDCO(can_fd_para_init->tdc_offset); +} + +/*! + \brief enable bit rate switching + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_bitrate_switch_enable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) |= CAN_FDCTL_BRSEN; +} + +/*! + \brief disable bit rate switching + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_bitrate_switch_disable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) &= ~CAN_FDCTL_BRSEN; +} + +/*! + \brief get transmitter delay compensation value + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval 0 - 0x3F +*/ +uint32_t can_tdc_get(uint32_t can_periph) +{ + uint32_t reg = 0U; + + reg = CAN_FDCTL(can_periph); + + return GET_FDCTL_TDCV(reg); +} + +/*! + \brief enable transmitter delay compensation + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_tdc_enable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) |= CAN_FDCTL_TDCEN; +} + +/*! + \brief disable transmitter delay compensation + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_tdc_disable(uint32_t can_periph) +{ + CAN_FDCTL(can_periph) &= ~CAN_FDCTL_TDCEN; +} + +/*! + \brief configure rx FIFO + \param[in] can_periph: CANx(x=0,1) + \param[in] can_fifo_para_init: fifo parameter struct + dma_enable: ENABLE, DISABLE + filter_format_and_number: CAN_RXFIFO_FILTER_A_NUM_8, CAN_RXFIFO_FILTER_A_NUM_16, CAN_RXFIFO_FILTER_A_NUM_24, CAN_RXFIFO_FILTER_A_NUM_32, + CAN_RXFIFO_FILTER_A_NUM_40, CAN_RXFIFO_FILTER_A_NUM_48, CAN_RXFIFO_FILTER_A_NUM_56, CAN_RXFIFO_FILTER_A_NUM_64, + CAN_RXFIFO_FILTER_A_NUM_72, CAN_RXFIFO_FILTER_A_NUM_80, CAN_RXFIFO_FILTER_A_NUM_88, CAN_RXFIFO_FILTER_A_NUM_96, CAN_RXFIFO_FILTER_A_NUM_104, + CAN_RXFIFO_FILTER_B_NUM_16, CAN_RXFIFO_FILTER_B_NUM_32, CAN_RXFIFO_FILTER_B_NUM_48, CAN_RXFIFO_FILTER_B_NUM_64, + CAN_RXFIFO_FILTER_B_NUM_80, CAN_RXFIFO_FILTER_B_NUM_96, CAN_RXFIFO_FILTER_B_NUM_112, CAN_RXFIFO_FILTER_B_NUM_128, + CAN_RXFIFO_FILTER_B_NUM_144, CAN_RXFIFO_FILTER_B_NUM_160, CAN_RXFIFO_FILTER_B_NUM_176, CAN_RXFIFO_FILTER_B_NUM_192, CAN_RXFIFO_FILTER_B_NUM_208, + CAN_RXFIFO_FILTER_C_NUM_32, CAN_RXFIFO_FILTER_C_NUM_64, CAN_RXFIFO_FILTER_C_NUM_96, CAN_RXFIFO_FILTER_C_NUM_128, + CAN_RXFIFO_FILTER_C_NUM_160, CAN_RXFIFO_FILTER_C_NUM_192, CAN_RXFIFO_FILTER_C_NUM_224, CAN_RXFIFO_FILTER_C_NUM_256, + CAN_RXFIFO_FILTER_C_NUM_288, CAN_RXFIFO_FILTER_C_NUM_320, CAN_RXFIFO_FILTER_C_NUM_352, CAN_RXFIFO_FILTER_C_NUM_384, CAN_RXFIFO_FILTER_C_NUM_416, + CAN_RXFIFO_FILTER_D + fifo_public_filter: 0x00000000 ~ 0xFFFFFFFF + \param[out] none + \retval none +*/ +void can_rx_fifo_config(uint32_t can_periph, can_fifo_parameter_struct *can_fifo_para_init) +{ + uint32_t num; + + /* clear register bits, disable FD mode, then enable rx FIFO mode */ + CAN_CTL0(can_periph) &= ~(CAN_CTL0_FDEN | CAN_CTL0_DMAEN | CAN_CTL0_FS); + CAN_CTL2(can_periph) &= ~CAN_CTL2_RFFN; + CAN_CTL0(can_periph) |= CAN_CTL0_RFEN; + + /* clear FIFO status */ + CAN_STAT(can_periph) = (uint32_t)0xFFFFFFFFU; + while(CAN_STAT(can_periph) & CAN_STAT_MS5_RFNE) { + CAN_STAT(can_periph) = CAN_STAT_MS5_RFNE; + } + + /* set DMA mode */ + if((uint8_t)ENABLE == can_fifo_para_init->dma_enable) { + CAN_CTL0(can_periph) |= CAN_CTL0_DMAEN; + } + + /* configure filter format */ + CAN_CTL0(can_periph) |= (can_fifo_para_init->filter_format_and_number & CAN_CTL0_FS); + /* configure filter number */ + CAN_CTL2(can_periph) |= (can_fifo_para_init->filter_format_and_number & CAN_CTL2_RFFN); + /* configure fifo public fiter */ + CAN_RFIFOPUBF(can_periph) = can_fifo_para_init->fifo_public_filter; + /* configure fifo private fiter */ + if(!(CAN_CTL0(can_periph) & CAN_CTL0_RPFQEN)) { + for(num = 0U; num < CAN_MAX_MAILBOX_NUM; num++) { + CAN_RFIFOMPF(can_periph, num) = can_fifo_para_init->fifo_public_filter; + } + } +} + +/*! + \brief configure rx FIFO filter table + \param[in] can_periph: CANx(x=0,1) + \param[in] id_filter_table: id filter table struct + remote_frame: CAN_DATA_FRAME_ACCEPTED, CAN_REMOTE_FRAME_ACCEPTED + extended_frame: CAN_STANDARD_FRAME_ACCEPTED, CAN_EXTENDED_FRAME_ACCEPTED + id: 11 bits for standard frame, 29 bits for extended frame + \param[out] none + \retval none +*/ +void can_rx_fifo_filter_table_config(uint32_t can_periph, can_rx_fifo_id_filter_struct id_filter_table[]) +{ + /* set rx FIFO ID filter table elements */ + uint32_t i = 0U, j = 0U, num_of_filters = 0U; + uint32_t val = 0U; + uint32_t id_format = 0U; + uint32_t *filter_table = (uint32_t *)(uint32_t)(CAN_RAM(can_periph) + 0x00000060U); + + num_of_filters = (GET_CTL2_RFFN(CAN_CTL2(can_periph)) + 1U) * 8U; + id_format = CAN_CTL0(can_periph) & CAN_CTL0_FS; + + switch(id_format) { + case(CAN_FIFO_FILTER_FORMAT_A): + /* one full id (standard and extended) per id filter table element */ + for(i = 0U; i < num_of_filters; i++) { + val = 0U; + + if(CAN_REMOTE_FRAME_ACCEPTED == id_filter_table[i].remote_frame) { + val |= CAN_FDESX_RTR_A; + } + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[i].extended_frame) { + val |= CAN_FDESX_IDE_A; + val |= (uint32_t)FIFO_FILTER_ID_EXD_A(id_filter_table[i].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_A(id_filter_table[i].id); + } + filter_table[i] = val; + } + break; + case(CAN_FIFO_FILTER_FORMAT_B): + /* two full standard id or two partial 14-bit (standard and extended) id */ + j = 0U; + for(i = 0U; i < num_of_filters; i++) { + val = 0U; + + if(CAN_REMOTE_FRAME_ACCEPTED == id_filter_table[j].remote_frame) { + val |= CAN_FDESX_RTR_B0; + } + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= CAN_FDESX_IDE_B0; + val |= (uint32_t)FIFO_FILTER_ID_EXD_B0(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_B0(id_filter_table[j].id); + } + j++; + + if(CAN_REMOTE_FRAME_ACCEPTED == id_filter_table[j].remote_frame) { + val |= CAN_FDESX_RTR_B1; + } + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= CAN_FDESX_IDE_B1; + val |= (uint32_t)FIFO_FILTER_ID_EXD_B1(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_B1(id_filter_table[j].id); + } + j++; + + filter_table[i] = val; + } + break; + case(CAN_FIFO_FILTER_FORMAT_C): + /* four partial 8-bit standard id per id filter table element */ + j = 0U; + for(i = 0U; i < num_of_filters; i++) { + val = 0U; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C0(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C0(id_filter_table[j].id); + } + j++; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C1(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C1(id_filter_table[j].id); + } + j++; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C2(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C2(id_filter_table[j].id); + } + j++; + if(CAN_EXTENDED_FRAME_ACCEPTED == id_filter_table[j].extended_frame) { + val |= (uint32_t)FIFO_FILTER_ID_EXD_C3(id_filter_table[j].id); + } else { + val |= (uint32_t)FIFO_FILTER_ID_STD_C3(id_filter_table[j].id); + } + j++; + + filter_table[i] = val; + } + break; + case(CAN_FIFO_FILTER_FORMAT_D): + /* all frames rejected */ + break; + default: + /* should not get here */ + break; + } +} + +/*! + \brief read rx FIFO data + \param[in] can_periph: CANx(x=0,1) + \param[out] rx_fifo: rx FIFO struct + \retval none +*/ +void can_rx_fifo_read(uint32_t can_periph, can_rx_fifo_struct *rx_fifo) +{ + uint32_t *rx_fifo_addr = (uint32_t *)rx_fifo; + uint32_t *can_mb = (uint32_t *)CAN_RAM(can_periph); + + /* read FIFO descriptor 0 */ + rx_fifo_addr[0] = can_mb[0]; + rx_fifo_addr[1] = can_mb[1]; + rx_fifo->data[0] = can_mb[2]; + rx_fifo->data[1] = can_mb[3]; + + /* clear FIFO status */ + CAN_STAT(can_periph) = CAN_STAT_MS5_RFNE; + + /* read FIFO id field */ + if(rx_fifo->ide) { + rx_fifo->id = GET_FDES1_ID_EXD(rx_fifo->id); + } else { + rx_fifo->id = GET_FDES1_ID_STD(rx_fifo->id); + } + + /* read FIFO data */ + can_data_to_little_endian_swap(rx_fifo->data, rx_fifo->data, rx_fifo->dlc); +} + +/*! + \brief get rx FIFO filter matching number + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval filter number +*/ +uint32_t can_rx_fifo_filter_matching_number_get(uint32_t can_periph) +{ + return GET_RFIFOIFMN_IDFMN(CAN_RFIFOIFMN(can_periph)); +} + +/*! + \brief clear rx FIFO + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_rx_fifo_clear(uint32_t can_periph) +{ + CAN_STAT(can_periph) = CAN_STAT_MS0_RFC; +} + +/*! + \brief get mailbox RAM address + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index, 0-31 + \param[out] none + \retval pointer to the mailbox address +*/ +uint32_t *can_ram_address_get(uint32_t can_periph, uint32_t index) +{ + uint32_t payload_size; + uint32_t *address; + + /* if CAN FD mode is enabled */ + if(CAN_CTL0(can_periph) & CAN_CTL0_FDEN) { + payload_size = (uint32_t)1U << (GET_FDCTL_MDSZ(CAN_FDCTL(can_periph)) + 3U); + } else { + payload_size = 8U; + } + address = (uint32_t *)(uint32_t)(CAN_RAM(can_periph) + (payload_size + 8U) * index); + + return address; +} + +/*! + \brief configure mailbox + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[in] mdpara: mailbox descriptor struct + rtr: 0, 1 + ide: 0, 1 + id: 0 - 0x1FFFFFFF + code: CAN_MB_RX_STATUS_INACTIVE, CAN_MB_RX_STATUS_FULL, CAN_MB_RX_STATUS_EMPTY, + CAN_MB_RX_STATUS_OVERRUN, CAN_MB_RX_STATUS_RANSWER, CAN_MB_RX_STATUS_BUSY, + CAN_MB_TX_STATUS_INACTIVE, CAN_MB_TX_STATUS_ABORT, CAN_MB_TX_STATUS_DATA + data_bytes: 0 - 64 + data: point to the data + esi: 0, 1 + fdf: 0, 1 + brs: 0, 1 + prio: 0 - 7 + \param[out] none + \retval none +*/ +void can_mailbox_config(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara) +{ + uint32_t dlc; + uint32_t mdes0 = 0U; + uint32_t length; + uint32_t *mdes; + + /* clear mailbox status */ + CAN_STAT(can_periph) = STAT_MS(index); + + /* get mailbox base address */ + mdes = can_ram_address_get(can_periph, index); + mdes[0] = 0U; + mdes[1] = 0U; + mdes[2] = 0U; + mdes[3] = 0U; + + /* set RTR bit */ + if(mdpara->rtr) { + mdes0 |= CAN_MDES0_RTR; + } + + /* set IDE bit and ID field */ + if(mdpara->ide) { + mdes0 |= CAN_MDES0_IDE; + mdes0 |= CAN_MDES0_SRR; + mdes[1] |= MDES1_ID_EXD(mdpara->id); + } else { + mdes[1] |= MDES1_ID_STD(mdpara->id); + } + + /* set CODE field */ + mdes0 |= MDES0_CODE(mdpara->code); + + if(mdpara->code != CAN_MB_RX_STATUS_EMPTY) { + /* copy user's buffer into the mailbox data area */ + if(mdpara->data_bytes) { + dlc = can_dlc_value_compute(mdpara->data_bytes); + mdes0 |= MDES0_DLC(dlc); + length = (uint32_t)1U << (GET_FDCTL_MDSZ(CAN_FDCTL(can_periph)) + 3U); + if(mdpara->data_bytes < length) { + length = mdpara->data_bytes; + } + can_data_to_big_endian_swap(&mdes[2], mdpara->data, length); + } + + /* prepare mailbox for transmission */ + if(CAN_MB_TX_STATUS_DATA == mdpara->code) { + /* set ESI bit */ + if(mdpara->esi) { + mdes0 |= CAN_MDES0_ESI; + } + /* set FDF and BRS bit */ + if(mdpara->fdf) { + mdes0 |= CAN_MDES0_FDF; + if(mdpara->brs) { + mdes0 |= CAN_MDES0_BRS; + } + mdes0 &= ~CAN_MDES0_RTR; + } + } + + /* set PRIO field */ + mdes[1] |= MDES1_PRIO(mdpara->prio); + } + + /* set mailbox descriptor 0 */ + mdes[0] = mdes0; +} + +/*! + \brief abort mailbox transmit + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_transmit_abort(uint32_t can_periph, uint32_t index) +{ + uint32_t mdes0; + uint32_t *mdes; + + /* abort transmit mailbox */ + mdes = can_ram_address_get(can_periph, index); + mdes0 = mdes[0]; + mdes0 &= ~CAN_MDES0_CODE; + mdes0 |= MDES0_CODE(CAN_MB_TX_STATUS_ABORT); + mdes[0] = mdes0; +} + +/*! + \brief inactive transmit mailbox + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_transmit_inactive(uint32_t can_periph, uint32_t index) +{ + uint32_t mdes0; + uint32_t *mdes; + + /* inactive transmit mailbox */ + mdes = can_ram_address_get(can_periph, index); + mdes0 = mdes[0]; + mdes0 &= ~CAN_MDES0_CODE; + mdes0 |= MDES0_CODE(CAN_MB_TX_STATUS_INACTIVE); + mdes[0] = mdes0; +} + +/*! + \brief read receive mailbox data + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] mdpara: mailbox descriptor struct + \retval ERROR or SUCCESS +*/ +ErrStatus can_mailbox_receive_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara) +{ + uint32_t i; + uint32_t cnt; + uint32_t timeout; + uint32_t *mdes = can_ram_address_get(can_periph, index); + uint32_t *mdaddr = (uint32_t *)mdpara; + + /* wait mailbox data ready */ + timeout = CAN_DELAY; + while((mdes[0] & MDES0_CODE(CAN_MB_RX_STATUS_BUSY)) && (timeout)) { + timeout--; + } + if(mdes[0] & MDES0_CODE(CAN_MB_RX_STATUS_BUSY)) { + return ERROR; + } + + /* get mailbox descriptor 0 */ + mdaddr[0] = mdes[0]; + mdaddr[1] = mdes[1]; + mdpara->data_bytes = can_payload_size_compute(mdpara->dlc); + cnt = (mdpara->data_bytes + 3U) / 4U; + mdaddr = mdpara->data; + mdes += 2U; + for(i = 0U; i < cnt; i++) { + mdaddr[i] = mdes[i]; + } + + /* clear mailbox status */ + CAN_STAT(can_periph) = STAT_MS(index); + /* unlock mailbox */ + CAN_TIMER(can_periph); + + /* get mailbox ID */ + if(mdpara->ide) { + mdpara->id = GET_MDES1_ID_EXD(mdpara->id); + } else { + mdpara->id = GET_MDES1_ID_STD(mdpara->id); + } + + /* get mailbox data */ + if(mdpara->data_bytes) { + can_data_to_little_endian_swap(mdpara->data, mdpara->data, mdpara->data_bytes); + } + + return SUCCESS; +} + +/*! + \brief lock the receive mailbox + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_receive_lock(uint32_t can_periph, uint32_t index) +{ + uint32_t *mdes; + + mdes = can_ram_address_get(can_periph, index); + REG32((uint32_t)mdes); +} + +/*! + \brief unlock the receive mailbox + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_mailbox_receive_unlock(uint32_t can_periph) +{ + CAN_TIMER(can_periph); +} + +/*! + \brief inactive the receive mailbox + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_mailbox_receive_inactive(uint32_t can_periph, uint32_t index) +{ + uint32_t mdes0; + uint32_t *mdes; + + /* inactive receive mailbox */ + mdes = can_ram_address_get(can_periph, index); + mdes0 = mdes[0]; + mdes0 &= ~CAN_MDES0_CODE; + mdes0 |= MDES0_CODE(CAN_MB_RX_STATUS_INACTIVE); + mdes[0] = mdes0; +} + +/*! + \brief get mailbox code value + \param[in] can_periph: CANx(x=0,1) + \param[in] index: mailbox index(0~31) + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval mailbox code +*/ +uint32_t can_mailbox_code_get(uint32_t can_periph, uint32_t index) +{ + uint32_t code; + uint32_t *mdes; + + mdes = can_ram_address_get(can_periph, index); + code = GET_MDES0_CODE(mdes[0]); + + return code; +} + +/*! + \brief configure error counter + \param[in] can_periph: CANx(x=0,1) + \param[in] errcnt_struct + fd_data_phase_rx_errcnt: 0-255 + fd_data_phase_tx_errcnt: 0-255 + rx_errcnt: 0-255 + tx_errcnt: 0-255 + \retval none +*/ +void can_error_counter_config(uint32_t can_periph, can_error_counter_struct *errcnt_struct) +{ + CAN_ERR0(can_periph) = ERR0_REFCNT(errcnt_struct->fd_data_phase_rx_errcnt) | ERR0_TEFCNT(errcnt_struct->fd_data_phase_tx_errcnt) | \ + ERR0_RECNT(errcnt_struct->rx_errcnt) | ERR0_TECNT(errcnt_struct->tx_errcnt); +} + +/*! + \brief get error counter + \param[in] can_periph: CANx(x=0,1) + \param[out] errcnt_struct + fd_data_phase_rx_errcnt: 0-255 + fd_data_phase_tx_errcnt: 0-255 + rx_errcnt: 0-255 + tx_errcnt: 0-255 + \retval none +*/ +void can_error_counter_get(uint32_t can_periph, can_error_counter_struct *errcnt_struct) +{ + uint32_t reg = 0U; + + reg = CAN_ERR0(can_periph); + errcnt_struct->fd_data_phase_rx_errcnt = (uint8_t)GET_ERR0_REFCNT(reg); + errcnt_struct->fd_data_phase_tx_errcnt = (uint8_t)GET_ERR0_TEFCNT(reg); + errcnt_struct->rx_errcnt = (uint8_t)GET_ERR0_RECNT(reg); + errcnt_struct->tx_errcnt = (uint8_t)GET_ERR0_TECNT(reg); +} + +/*! + \brief get error state indicator + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval CAN_ERROR_STATE_ACTIVE, CAN_ERROR_STATE_PASSIVE or CAN_ERROR_STATE_BUS_OFF +*/ +can_error_state_enum can_error_state_get(uint32_t can_periph) +{ + uint32_t reg; + + reg = GET_ERR1_ERRSI(CAN_ERR1(can_periph)); + if(reg >= (uint32_t)CAN_ERROR_STATE_BUS_OFF) { + reg = (uint32_t)CAN_ERROR_STATE_BUS_OFF; + } + + return (can_error_state_enum)reg; +} + +/*! + \brief get mailbox CRC value + \param[in] can_periph: CANx(x=0,1) + \param[out] crc_struct: + classical_frm_mb_number: 0 - 0x1F + classical_frm_transmitted_crc: 0 - 0x7FFF + classical_fd_frm_mb_number: 0 - 0x1F + classical_fd_frm_transmitted_crc: 0 - 0x1FFFFF + \retval none +*/ +void can_crc_get(uint32_t can_periph, can_crc_struct *crc_struct) +{ + uint32_t reg1 = 0U, reg2 = 0U; + + reg1 = CAN_CRCC(can_periph); + reg2 = CAN_CRCCFD(can_periph); + crc_struct->classical_frm_mb_number = GET_CRCC_ANTM(reg1); + crc_struct->classical_frm_transmitted_crc = GET_CRCC_CRCTC(reg1); + crc_struct->classical_fd_frm_mb_number = GET_CRCCFD_ANTM(reg2); + crc_struct->classical_fd_frm_transmitted_crc = GET_CRCCFD_CRCTCI(reg2); +} + +/*! + \brief configure Pretended Networking mode parameter + \param[in] can_periph: CANx(x=0,1) + \param[in] pnmod_config: Pretended Networking mode config struct + timeout_int: ENABLE, DISABLE + match_int: ENABLE, DISABLE + num_matches: 1 ~ 255 + match_timeout: 0 ~ 0xFFFF + frame_filter: CAN_PN_FRAME_FILTERING_ID, CAN_PN_FRAME_FILTERING_ID_DATA + CAN_PN_FRAME_FILTERING_ID_NMM, CAN_PN_FRAME_FILTERING_ID_DATA_NMM + id_filter: CAN_PN_ID_FILTERING_EXACT, CAN_PN_ID_FILTERING_GREATER + CAN_PN_ID_FILTERING_SMALLER, CAN_PN_ID_FILTERING_RANGE + data_filter: CAN_PN_DATA_FILTERING_EXACT, CAN_PN_DATA_FILTERING_GREATER + CAN_PN_DATA_FILTERING_SMALLER, CAN_PN_DATA_FILTERING_RANGE + \param[out] none + \retval none +*/ +void can_pn_mode_config(uint32_t can_periph, can_pn_mode_config_struct *pnmod_config) +{ + uint32_t tmp; + + /* configure specific Pretended Networking mode settings */ + tmp = CAN_PN_CTL0(can_periph); + tmp &= ~(CAN_PN_CTL0_FFT | CAN_PN_CTL0_IDFT | CAN_PN_CTL0_DATAFT | + CAN_PN_CTL0_NMM | CAN_PN_CTL0_WMIE | CAN_PN_CTL0_WTOIE); + tmp |= (uint32_t)PN_CTL0_WTOIE(pnmod_config->timeout_int) | PN_CTL0_WMIE(pnmod_config->match_int) | \ + PN_CTL0_NMM(pnmod_config->num_matches) | PN_CTL0_DATAFT(pnmod_config->data_filter) | \ + PN_CTL0_IDFT(pnmod_config->id_filter) | PN_CTL0_FFT(pnmod_config->frame_filter); + + CAN_PN_CTL0(can_periph) = tmp; + + /* set timeout value */ + CAN_PN_TO(can_periph) &= ~CAN_PN_TO_WTO; + CAN_PN_TO(can_periph) |= (uint32_t)PN_TO_WTO(pnmod_config->match_timeout); + + /* enable Pretended Networking mode */ + CAN_CTL0(can_periph) |= CAN_CTL0_PNMOD; +} + +/*! + \brief configure Pretended Networking mode filter + \param[in] can_periph: CANx(x=0,1) + \param[in] expect: Pretended Networking mode struct of expected wakeup frame + remote_frame: SET, RESET + extended_frame: SET, RESET + id: 0x00000000~0x1FFFFFFF + dlc_high_threshold: 0~8 + dlc_low_threshold: 0~8 + payload[0]: 0x00000000~0xFFFFFFFF + payload[1]: 0x00000000~0xFFFFFFFF + \param[in] filter: Pretended Networking mode struct of filter data + remote_frame: SET, RESET + extended_frame: SET, RESET + id: 0x00000000~0x1FFFFFFF + dlc_high_threshold: 0~8 + dlc_low_threshold: 0~8 + payload[0]: 0x00000000~0xFFFFFFFF + payload[1]: 0x00000000~0xFFFFFFFF + \param[out] none + \retval none +*/ +void can_pn_mode_filter_config(uint32_t can_periph, can_pn_mode_filter_struct *expect, can_pn_mode_filter_struct *filter) +{ + uint32_t reg, temp; + + /* set filter identifier 0 */ + reg = 0U; + if((uint32_t)SET == expect->extended_frame) { + reg |= CAN_PN_EID0_EIDE; + reg |= (uint32_t)PN_EID0_EIDF_ELT_EXD(expect->id); + } else { + reg |= (uint32_t)PN_EID0_EIDF_ELT_STD(expect->id); + } + if((uint32_t)SET == expect->remote_frame) { + reg |= CAN_PN_EID0_ERTR; + } + CAN_PN_EID0(can_periph) = reg; + + temp = CAN_PN_CTL0(can_periph); + /* ID field 1 is used when ID filtering type is EXACT or RANGE */ + if(((temp & CAN_PN_CTL0_IDFT) == CAN_PN_ID_FILTERING_EXACT) || + ((temp & CAN_PN_CTL0_IDFT) == CAN_PN_ID_FILTERING_RANGE)) { + /* set filter identifier 1 */ + reg = 0U; + if((uint32_t)SET == filter->extended_frame) { + reg |= CAN_PN_IFEID1_IDEFD; + reg |= (uint32_t)PN_IFEID1_IDEFD_EXD(filter->id); + } else { + reg |= (uint32_t)PN_IFEID1_IDEFD_STD(filter->id); + } + if((uint32_t)SET == filter->remote_frame) { + reg |= CAN_PN_IFEID1_RTRFD; + } + CAN_PN_IFEID1(can_periph) = reg; + } + + /* data field is used when frame filtering type is not MATCH or MATCH NMM */ + if(((temp & CAN_PN_CTL0_FFT) == CAN_PN_FRAME_FILTERING_ID_DATA) || + ((temp & CAN_PN_CTL0_FFT) == CAN_PN_FRAME_FILTERING_ID_DATA_NMM)) { + /* set filter data payload 0 */ + CAN_PN_EDLC(can_periph) = PN_EDLC_DLCEHT(expect->dlc_high_threshold) | PN_EDLC_DLCELT(expect->dlc_low_threshold); + CAN_PN_EDL0(can_periph) = ((expect->payload[0] << 24U) & CAN_PN_EDL0_DB0ELT) | + ((expect->payload[0] << 8U) & CAN_PN_EDL0_DB1ELT) | + ((expect->payload[0] >> 8U) & CAN_PN_EDL0_DB2ELT) | + ((expect->payload[0] >> 24U) & CAN_PN_EDL0_DB3ELT); + CAN_PN_EDL1(can_periph) = ((expect->payload[1] << 24U) & CAN_PN_EDL1_DB4ELT) | + ((expect->payload[1] << 8U) & CAN_PN_EDL1_DB5ELT) | + ((expect->payload[1] >> 8U) & CAN_PN_EDL1_DB6ELT) | + ((expect->payload[1] >> 24U) & CAN_PN_EDL1_DB7ELT); + + /* data field 1 is used when data filtering type is EXACT or RANGE */ + if(((temp & CAN_PN_CTL0_DATAFT) == CAN_PN_DATA_FILTERING_EXACT) + || ((temp & CAN_PN_CTL0_DATAFT) == CAN_PN_DATA_FILTERING_RANGE)) { + /* set filter data payload 1 */ + CAN_PN_DF0EDH0(can_periph) = ((filter->payload[0] << 24U) & CAN_PN_DF0EDH0_DB0FD_EHT) | + ((filter->payload[0] << 8U) & CAN_PN_DF0EDH0_DB1FD_EHT) | + ((filter->payload[0] >> 8U) & CAN_PN_DF0EDH0_DB2FD_EHT) | + ((filter->payload[0] >> 24U) & CAN_PN_DF0EDH0_DB3FD_EHT); + CAN_PN_DF1EDH1(can_periph) = ((filter->payload[1] << 24U) & CAN_PN_DF1EDH1_DB4FD_EHT) | + ((filter->payload[1] << 8U) & CAN_PN_DF1EDH1_DB5FD_EHT) | + ((filter->payload[1] >> 8U) & CAN_PN_DF1EDH1_DB6FD_EHT) | + ((filter->payload[1] >> 24U) & CAN_PN_DF1EDH1_DB7FD_EHT); + } + } +} + + +/*! + \brief get matching message counter of Pretended Networking mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval 0~255 or -1 +*/ +int32_t can_pn_mode_num_of_match_get(uint32_t can_periph) +{ + int32_t ret = 0; + uint32_t reg = 0U; + + reg = CAN_PN_STAT(can_periph); + if(0U != (reg & CAN_PN_STAT_MMCNTS)) { + ret = (int32_t)(uint32_t)GET_PN_STAT_MMCNT(reg); + } else { + ret = -1; + } + return ret; +} + +/*! + \brief get matching message + \param[in] can_periph: CANx(x=0,1) + \param[in] index: Pretended Networking mailbox index + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] mdpara: wakeup message information + \retval none +*/ +void can_pn_mode_data_read(uint32_t can_periph, uint32_t index, can_mailbox_descriptor_struct *mdpara) +{ + uint32_t *mdaddr = (uint32_t *)mdpara; + uint32_t *pnram = (uint32_t *)(uint32_t)(CAN_PN_RAM(can_periph) + index * 16U); + + mdaddr[0] = pnram[0]; + mdaddr[1] = pnram[1]; + /* get mailbox ID */ + if(0U != mdpara->ide) { + mdpara->id = GET_MDES1_ID_EXD(mdpara->id); + } else { + mdpara->id = GET_MDES1_ID_STD(mdpara->id); + } + mdpara->data_bytes = mdpara->dlc; + if(mdpara->data_bytes) { + can_data_to_little_endian_swap(mdpara->data, &pnram[2], mdpara->data_bytes); + } +} + +/*! + \brief enable self reception + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_self_reception_enable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) &= ~CAN_CTL0_SRDIS; +} + +/*! + \brief disable self reception + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_self_reception_disable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) |= CAN_CTL0_SRDIS; +} + +/*! + \brief enable transmit abort + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_transmit_abort_enable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) |= CAN_CTL0_MST; +} + +/*! + \brief disable transmit abort + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_transmit_abort_disable(uint32_t can_periph) +{ + CAN_CTL0(can_periph) &= ~CAN_CTL0_MST; +} + +/*! + \brief enable auto bus off recovery mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_auto_busoff_recovery_enable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) &= ~CAN_CTL1_ABORDIS; +} + +/*! + \brief disable auto bus off recovery mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_auto_busoff_recovery_disable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) |= CAN_CTL1_ABORDIS; +} + +/*! + \brief enable time sync mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_sync_enable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) |= CAN_CTL1_TSYNC; +} + +/*! + \brief disable time sync mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_time_sync_disable(uint32_t can_periph) +{ + CAN_CTL1(can_periph) &= ~CAN_CTL1_TSYNC; +} + +/*! + \brief enable edge filter mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_edge_filter_mode_enable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) &= ~CAN_CTL2_EFDIS; +} + +/*! + \brief disable edge filter mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_edge_filter_mode_disable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) |= CAN_CTL2_EFDIS; +} + +/*! + \brief enable protocol exception detection mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_ped_mode_enable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) |= CAN_CTL2_PREEN; +} + +/*! + \brief disable protocol exception detection mode + \param[in] can_periph: CANx(x=0,1) + \param[out] none + \retval none +*/ +void can_ped_mode_disable(uint32_t can_periph) +{ + CAN_CTL2(can_periph) &= ~CAN_CTL2_PREEN; +} + +/*! + \brief configure arbitation delay bits + \param[in] can_periph: CANx(x=0,1) + \param[in] delay_bits: delay bits + only one parameter can be selected which is shown as below: + \arg 0 - 31 + \param[out] none + \retval none +*/ +void can_arbitation_delay_bits_config(uint32_t can_periph, uint32_t delay_bits) +{ + CAN_CTL2(can_periph) &= ~CAN_CTL2_ASD; + CAN_CTL2(can_periph) |= (uint32_t)CTL2_ASD(delay_bits); +} + +/*! + \brief configure bit sampling mode + \param[in] can_periph: CANx(x=0,1) + \param[in] sampling_mode: bit sampling mode + only one parameter can be selected which is shown as below: + \arg CAN_BSP_MODE_ONE_SAMPLE: one sample for received bit + \arg CAN_BSP_MODE_TRHEE_SAMPLES: three samples for received bit + \param[out] none + \retval none +*/ +void can_bsp_mode_config(uint32_t can_periph, uint32_t sampling_mode) +{ + if(CAN_BSP_MODE_ONE_SAMPLE == sampling_mode) { + CAN_CTL1(can_periph) &= ~CAN_CTL1_BSPMOD; + } else { + CAN_CTL1(can_periph) |= CAN_CTL1_BSPMOD; + } +} + +/*! + \brief get CAN flag + \param[in] can_periph: CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_CAN_PN: Pretended Networking state flag + \arg CAN_FLAG_SOFT_RST: software reset flag + \arg CAN_FLAG_ERR_SUMMARY: error summary flag + \arg CAN_FLAG_BUSOFF: bus off flag + \arg CAN_FLAG_RECEIVING: receiving state flag + \arg CAN_FLAG_TRANSMITTING: transmitting state flag + \arg CAN_FLAG_IDLE: IDLE state flag + \arg CAN_FLAG_RX_WARNING: receive warning flag + \arg CAN_FLAG_TX_WARNING: transmit warning flag + \arg CAN_FLAG_STUFF_ERR: stuff error flag + \arg CAN_FLAG_FORM_ERR: form error flag + \arg CAN_FLAG_CRC_ERR: CRC error flag + \arg CAN_FLAG_ACK_ERR: ACK error flag + \arg CAN_FLAG_BIT_DOMINANT_ERR: bit dominant error flag + \arg CAN_FLAG_BIT_RECESSIVE_ERR: bit recessive error flag + \arg CAN_FLAG_SYNC_ERR: synchronization flag + \arg CAN_FLAG_BUSOFF_RECOVERY: bus off recovery flag + \arg CAN_FLAG_ERR_SUMMARY_FD: fd error summary flag + \arg CAN_FLAG_ERR_OVERRUN: error overrun flag + \arg CAN_FLAG_STUFF_ERR_FD: stuff error in FD data phase flag + \arg CAN_FLAG_FORM_ERR_FD: form error in FD data phase flag + \arg CAN_FLAG_CRC_ERR_FD: CRC error in FD data phase flag + \arg CAN_FLAG_BIT_DOMINANT_ERR_FD: bit dominant error in FD data phase flag + \arg CAN_FLAG_BIT_RECESSIVE_ERR_FD: bit recessive error in FD data phase flag + \arg CAN_FLAG_MBx(x=0~31): mailbox x flag + \arg CAN_FLAG_FIFO_AVAILABLE: fifo available flag + \arg CAN_FLAG_FIFO_WARNING: fifo warning flag + \arg CAN_FLAG_FIFO_OVERFLOW: fifo overflow flag + \arg CAN_FLAG_WAKEUP_MATCH: Pretended Networking match flag + \arg CAN_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup flag + \arg CAN_FLAG_TDC_OUT_OF_RANGE: transmitter delay is out of compensation range flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag) +{ + if(CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear CAN flag + \param[in] can_periph: CANx(x=0,1) + \param[in] flag: CAN flags, refer to can_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_FLAG_ERR_SUMMARY: error summary flag + \arg CAN_FLAG_BUSOFF: bus off flag + \arg CAN_FLAG_BUSOFF_RECOVERY: bus off recovery flag + \arg CAN_FLAG_ERR_SUMMARY_FD: fd error summary flag + \arg CAN_FLAG_ERR_OVERRUN: error overrun flag + \arg CAN_FLAG_MBx(x=0~31): mailbox x flag + \arg CAN_FLAG_FIFO_AVAILABLE: fifo available flag + \arg CAN_FLAG_FIFO_WARNING: fifo warning flag + \arg CAN_FLAG_FIFO_OVERFLOW: fifo overflow flag + \arg CAN_FLAG_WAKEUP_MATCH: Pretended Networking match flag + \arg CAN_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup flag + \arg CAN_FLAG_TDC_OUT_OF_RANGE: transmitter delay is out of compensation range flag + \param[out] none + \retval none +*/ +void can_flag_clear(uint32_t can_periph, can_flag_enum flag) +{ + if(CAN_FLAG_TDC_OUT_OF_RANGE == flag) { + CAN_FDCTL(can_periph) |= CAN_FDCTL_TDCS; + } else { + CAN_REG_VAL(can_periph, flag) = BIT(CAN_BIT_POS(flag)); + } +} + +/*! + \brief enable CAN interrupt + \param[in] can_periph: CANx(x=0,1) + \param[in] interrupt: CAN interrupt, refer to can_interrupt_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_ERR_SUMMARY: error interrupt + \arg CAN_INT_RX_WARNING: receive warning interrupt + \arg CAN_INT_TX_WARNING: transmit warning interrupt + \arg CAN_INT_BUSOFF: bus off interrupt + \arg CAN_INT_BUSOFF_RECOVERY: bus off recovery interrupt + \arg CAN_INT_ERR_SUMMARY_FD: fd error interrupt + \arg CAN_INT_MBx(x=0~31): mailbox x interrupt + \arg CAN_INT_FIFO_AVAILABLE: fifo availabe interrupt + \arg CAN_INT_FIFO_WARNING: fifo warning interrupt + \arg CAN_INT_FIFO_OVERFLOW: fifo overflow interrupt + \arg CAN_INT_WAKEUP_MATCH: Pretended Networking match interrupt + \arg CAN_INT_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt + \param[out] none + \retval none +*/ +void can_interrupt_enable(uint32_t can_periph, can_interrupt_enum interrupt) +{ + /* enable receive or transmit warning error interrupt should enable error warning in CTL0 register */ + if((CAN_INT_RX_WARNING == interrupt) + || (CAN_INT_TX_WARNING == interrupt)) { + CAN_CTL0(can_periph) |= CAN_CTL0_WERREN; + } + + CAN_REG_VAL(can_periph, interrupt) |= BIT(CAN_BIT_POS(interrupt)); +} + +/*! + \brief disable CAN interrupt + \param[in] can_periph: CANx(x=0,1) + \param[in] interrupt: CAN interrupt, refer to can_interrupt_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_ERR_SUMMARY: error interrupt + \arg CAN_INT_RX_WARNING: receive warning interrupt + \arg CAN_INT_TX_WARNING: transmit warning interrupt + \arg CAN_INT_BUSOFF: bus off interrupt + \arg CAN_INT_BUSOFF_RECOVERY: bus off recovery interrupt + \arg CAN_INT_ERR_SUMMARY_FD: fd error interrupt + \arg CAN_INT_MBx(x=0~31): mailbox x interrupt + \arg CAN_INT_FIFO_AVAILABLE: fifo available interrupt + \arg CAN_INT_FIFO_WARNING: fifo warning interrupt + \arg CAN_INT_FIFO_OVERFLOW: fifo overflow interrupt + \arg CAN_INT_WAKEUP_MATCH: Pretended Networking match interrupt + \arg CAN_INT_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt + \param[out] none + \retval none +*/ +void can_interrupt_disable(uint32_t can_periph, can_interrupt_enum interrupt) +{ + CAN_REG_VAL(can_periph, interrupt) &= ~BIT(CAN_BIT_POS(interrupt)); +} + +/*! + \brief get CAN interrupt flag + \param[in] can_periph: CANx(x=0,1) + \param[in] int_flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_ERR_SUMMARY: error summary interrupt flag + \arg CAN_INT_FLAG_BUSOFF: bus off interrupt flag + \arg CAN_INT_FLAG_RX_WARNING: receive warning interrupt flag + \arg CAN_INT_FLAG_TX_WARNING: transmit warning interrupt flag + \arg CAN_INT_FLAG_BUSOFF_RECOVERY: bus off recovery interrupt flag + \arg CAN_INT_FLAG_ERR_SUMMARY_FD: fd error summary interrupt flag + \arg CAN_INT_FLAG_MBx(x=0~31): mailbox x interrupt flag + \arg CAN_INT_FLAG_FIFO_AVAILABLE: fifo available interrupt flag + \arg CAN_INT_FLAG_FIFO_WARNING: fifo warning interrupt flag + \arg CAN_INT_FLAG_FIFO_OVERFLOW: fifo overflow interrupt flag + \arg CAN_INT_FLAG_WAKEUP_MATCH: Pretended Networking match interrupt flag + \arg CAN_INT_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum int_flag) +{ + if(CAN_REG_VAL(can_periph, int_flag) & BIT(CAN_BIT_POS(int_flag))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear CAN interrupt flag + \param[in] can_periph: CANx(x=0,1) + \param[in] int_flag: CAN interrupt flags, refer to can_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg CAN_INT_FLAG_ERR_SUMMARY: error summary interrupt flag + \arg CAN_INT_FLAG_BUSOFF: bus off interrupt flag + \arg CAN_INT_FLAG_RX_WARNING: receive warning interrupt flag + \arg CAN_INT_FLAG_TX_WARNING: transmit warning interrupt flag + \arg CAN_INT_FLAG_BUSOFF_RECOVERY: bus off recovery interrupt flag + \arg CAN_INT_FLAG_ERR_SUMMARY_FD: fd error summary interrupt flag + \arg CAN_INT_FLAG_MBx(x=0~31): mailbox x interrupt flag + \arg CAN_INT_FLAG_FIFO_AVAILABLE: fifo availabe interrupt flag + \arg CAN_INT_FLAG_FIFO_WARNING: fifo warning interrupt flag + \arg CAN_INT_FLAG_FIFO_OVERFLOW: fifo overflow interrupt flag + \arg CAN_INT_FLAG_WAKEUP_MATCH: Pretended Networking match interrupt flag + \arg CAN_INT_FLAG_WAKEUP_TIMEOUT: Pretended Networking timeout wakeup interrupt flag + \param[out] none + \retval none +*/ +void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum int_flag) +{ + CAN_REG_VAL(can_periph, int_flag) = BIT(CAN_BIT_POS(int_flag)); +} + +/*! + \brief computes the maximum payload size (in bytes), given a dlc + \param[in] dlc_value: dlc value + \param[out] none + \retval payload_size +*/ +static uint32_t can_payload_size_compute(uint32_t dlc_value) +{ + uint8_t ret = 0U; + + if(dlc_value <= 15U) { + ret = dlc_to_databytes[dlc_value]; + } + + return (uint32_t)ret; +} + +/*! + \brief swap data to little endian + \param[in] src: data source address + \param[in] len: data length be byte + \param[out] dest: data destination address + \retval none +*/ +static void can_data_to_little_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len) +{ + volatile uint32_t i = 0U; + uint32_t cnt; + uint32_t temp_src = 0U; + + /* get the word length of the data */ + cnt = (len + 3U) / 4U; + /* change each word from big endian to little endian */ + for(i = 0U; i < cnt; i++) { + temp_src = src[i]; + dest[i] = ((uint32_t)(temp_src >> 24U) & 0x000000FFU) | + ((uint32_t)(temp_src >> 8U) & 0x0000FF00U) | + ((uint32_t)(temp_src << 8U) & 0x00FF0000U) | + ((uint32_t)(temp_src << 24U) & 0xFF000000U); + } + + cnt = len % 4U; + if(cnt) { + dest[i - 1U] &= ((uint32_t)1U << (cnt * 8U)) - 1U; + } +} + +/*! + \brief swap data to big endian + \param[in] src: data source address + \param[in] len: data length be byte + \param[out] dest: data destination address + \retval none +*/ +static void can_data_to_big_endian_swap(uint32_t dest[], uint32_t src[], uint32_t len) +{ + volatile uint32_t i = 0U; + uint32_t cnt; + uint32_t temp_src = 0U; + + /* get the word length of the data */ + cnt = (len + 3U) / 4U; + for(i = 0U; i < cnt; i++) { + /* change each word from little endian to big endian */ + temp_src = src[i]; + dest[i] = ((uint32_t)(temp_src >> 24U) & 0x000000FFU) | + ((uint32_t)(temp_src >> 8U) & 0x0000FF00U) | + ((uint32_t)(temp_src << 8U) & 0x00FF0000U) | + ((uint32_t)(temp_src << 24U) & 0xFF000000U); + } + + cnt = len % 4U; + if(cnt) { + dest[i - 1U] &= ~(((uint32_t)1U << ((4U - cnt) * 8U)) - 1U); + } +} + +/*! + \brief computes the DLC field value, given a payload size (in bytes) + \param[in] payload_size: payload size + \param[out] none + \retval DLC value +*/ +static uint32_t can_dlc_value_compute(uint32_t payload_size) +{ + uint32_t ret = 8U; + + if(payload_size <= 8U) { + ret = payload_size; + } else if(payload_size <= 24U) { + ret = (payload_size - 9U) / 4U + 9U; + } else if(payload_size <= 64U) { + ret = (payload_size - 17U) / 16U + 13U; + } else { + ret = 8U; + } + + return ret; +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_cmp.c b/gd32a50x/standard_peripheral/source/gd32a50x_cmp.c new file mode 100644 index 0000000..fe6f197 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_cmp.c @@ -0,0 +1,238 @@ +/*! + \file gd32a50x_cmp.c + \brief CMP driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_cmp.h" + +/*! + \brief deinitialize comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_deinit(void) +{ + rcu_periph_reset_enable(RCU_CMPRST); + rcu_periph_reset_disable(RCU_CMPRST); +} + +/*! + \brief initialize comparator mode + \param[in] operating_mode + \arg CMP_HIGHSPEED: high speed mode + \arg CMP_MIDDLESPEED: medium speed mode + \arg CMP_LOWSPEED: low speed mode + \param[in] inverting_input + \arg CMP_1_4VREFINT: CMP inverting input VREFINT *1/4 + \arg CMP_1_2VREFINT: CMP inverting input VREFINT *1/2 + \arg CMP_3_4VREFINT: CMP inverting input VREFINT *3/4 + \arg CMP_VREFINT: CMP inverting input VREFINT + \arg CMP_DAC_OUT: CMP inverting input DAC_OUT(PA4¡¢PA5) + \arg CMP_IM_PC11: CMP inverting input PC11 + \arg CMP_IM_PC10: CMP inverting input PC10 + \arg CMP_IM_PB8: CMP inverting input PB8 + \arg CMP_IM_PA0: CMP inverting input PA0 + \arg CMP_IM_PA3: CMP inverting input PA3 + \arg CMP_IM_PA4: CMP inverting input PA4 + \arg CMP_IM_PA5: CMP inverting input PA5 + \arg CMP_IM_PA6: CMP inverting input PA6 + \param[in] plus_input + \arg CMP_IP_PC11: CMP plus input PC11 + \arg CMP_IP_PC10: CMP plus input PC10 + \arg CMP_IP_PB8: CMP plus input PB8 + \arg CMP_IP_PA0: CMP plus input PA0 + \arg CMP_IP_PA3: CMP plus input PA3 + \arg CMP_IP_PA4: CMP plus input PA4 + \arg CMP_IP_PA5: CMP plus input PA5 + \arg CMP_IP_PA6: CMP plus input PA6 + \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(operating_mode_enum operating_mode, cmp_inverting_input_enum inverting_input, cmp_plus_input_enum plus_input, + cmp_hysteresis_enum output_hysteresis) +{ + uint32_t cmp_cs = 0U; + cmp_cs = CMP_CS; + /* initialize comparator mode */ + cmp_cs &= ~(uint32_t)(CMP_CS_PM | CMP_CS_MESEL | CMP_CS_MISEL | CMP_CS_PSEL | CMP_CS_HST); + cmp_cs |= (uint32_t)(CS_CMPPM(operating_mode) | CS_CMPMSEL(inverting_input) | CS_CMPPSEL(plus_input) | CS_CMPHST(output_hysteresis)); + CMP_CS = cmp_cs; +} + +/*! + \brief initialize comparator output + \param[in] none + \param[in] output_selection + \arg CMP_OUTPUT_NONE: output no selection + \arg CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture + \arg CMP_OUTPUT_TIMER7IC0: TIMER 7 channel0 input capture + \param[in] output_polarity + \arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted + \arg CMP_OUTPUT_POLARITY_NOINVERTED: output is not inverted + \param[out] none + \retval none +*/ +void cmp_output_init(cmp_output_enum output_selection, cmp_output_inv_enum output_polarity) +{ + uint32_t cmp_cs = 0U; + cmp_cs = CMP_CS; + /* initialize comparator output */ + cmp_cs &= ~(uint32_t)CMP_CS_OSEL; + cmp_cs |= (uint32_t)CS_CMPOSEL(output_selection); + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity) { + cmp_cs |= (uint32_t)CMP_CS_PL; + } else { + cmp_cs &= ~(uint32_t)CMP_CS_PL; + } + CMP_CS = cmp_cs; +} + +/*! + \brief initialize comparator blanking function + \param[in] none + \param[in] blanking_source_selection + \arg CMP_BLANKING_NONE: output no selection + \arg CMP_BLANKING_TIMER0_OC1: TIMER 0 output channel1 + \arg CMP_BLANKING_TIMER7_OC1: TIMER 7 output channel1 + \arg CMP_BLANKING_TIMER1_OC1: TIMER 1 output channel1 + \param[out] none + \retval none +*/ +void cmp_outputblank_init(blanking_source_enum blanking_source_selection) +{ + uint32_t cmp_cs = 0U; + cmp_cs = CMP_CS; + cmp_cs &= ~(uint32_t)CMP_CS_BLK; + cmp_cs |= (uint32_t)CS_CMPBLK(blanking_source_selection); + CMP_CS = cmp_cs; +} + +/*! + \brief enable comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_enable(void) +{ + CMP_CS |= (uint32_t)CMP_CS_EN; +} + +/*! + \brief disable comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_disable(void) +{ + CMP_CS &= ~(uint32_t)CMP_CS_EN; +} + +/*! + \brief enable the voltage scaler + \param[in] none + \param[out] none + \retval none +*/ +void cmp_voltage_scaler_enable(void) +{ + CMP_CS |= (uint32_t)CMP_CS_SEN; +} + +/*! + \brief disable the voltage scaler + \param[in] none + \param[out] none + \retval none +*/ +void cmp_voltage_scaler_disable(void) +{ + CMP_CS &= ~(uint32_t)CMP_CS_SEN; +} + +/*! + \brief enable the scaler bridge + \param[in] none + \param[out] none + \retval none +*/ +void cmp_scaler_bridge_enable(void) +{ + CMP_CS |= (uint32_t)CMP_CS_BEN; +} + +/*! + \brief disable the scaler bridge + \param[in] none + \param[out] none + \retval none +*/ +void cmp_scaler_bridge_disable(void) +{ + CMP_CS &= ~(uint32_t)CMP_CS_BEN; +} + +/*! + \brief lock the comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_lock_enable(void) +{ + /* lock CMP */ + CMP_CS |= (uint32_t)CMP_CS_LK; +} + +/*! + \brief get output level + \param[in] none + \param[out] none + \retval the output level +*/ +cmp_output_state_enum cmp_output_level_get(void) +{ + /* get output level of CMP */ + if(CMP_CS & CMP_CS_OT) { + return CMP_OUTPUTLEVEL_HIGH; + } else { + return CMP_OUTPUTLEVEL_LOW; + } +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_crc.c b/gd32a50x/standard_peripheral/source/gd32a50x_crc.c new file mode 100644 index 0000000..5535c74 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_crc.c @@ -0,0 +1,241 @@ +/*! + \file gd32a50x_crc.c + \brief CRC driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_crc.h" + +/*! + \brief deinit CRC calculation unit + \param[in] none + \param[out] none + \retval none +*/ +void crc_deinit(void) +{ + CRC_IDATA = (uint32_t)0xFFFFFFFFU; + CRC_DATA = (uint32_t)0xFFFFFFFFU; + CRC_FDATA = (uint32_t)0x00000000U; + CRC_POLY = (uint32_t)0x04C11DB7U; + CRC_CTL = CRC_CTL_RST; +} + +/*! + \brief enable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_enable(void) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O); + CRC_CTL |= (uint32_t)CRC_CTL_REV_O; +} + +/*! + \brief disable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_disable(void) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O); +} + +/*! + \brief reset data register to the value of initialization data register + \param[in] none + \param[out] none + \retval none +*/ +void crc_data_register_reset(void) +{ + CRC_CTL |= (uint32_t)CRC_CTL_RST; +} + +/*! + \brief read the data register + \param[in] none + \param[out] none + \retval 32-bit value of the data register +*/ +uint32_t crc_data_register_read(void) +{ + uint32_t data; + data = CRC_DATA; + return (data); +} + +/*! + \brief read the free data register + \param[in] none + \param[out] none + \retval 8-bit value of the free data register +*/ +uint8_t crc_free_data_register_read(void) +{ + uint8_t fdata; + fdata = (uint8_t)CRC_FDATA; + return (fdata); +} + +/*! + \brief write the free data register + \param[in] free_data: specify 8-bit data + \param[out] none + \retval none +*/ +void crc_free_data_register_write(uint8_t free_data) +{ + CRC_FDATA = (uint32_t)free_data; +} + +/*! + \brief write the initialization data register + \param[in] init_data:specify 32-bit data + \param[out] none + \retval none +*/ +void crc_init_data_register_write(uint32_t init_data) +{ + CRC_IDATA = (uint32_t)init_data; +} + +/*! + \brief configure the CRC input data function + \param[in] data_reverse: specify input data reverse function + only one parameter can be selected which is shown as below: + \arg CRC_INPUT_DATA_NOT: input data is not reversed + \arg CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits + \arg CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits + \arg CRC_INPUT_DATA_WORD: input data is reversed on 32 bits + \param[out] none + \retval none +*/ +void crc_input_data_reverse_config(uint32_t data_reverse) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I); + CRC_CTL |= (uint32_t)data_reverse; +} + +/*! + \brief configure the CRC size of polynomial function + \param[in] poly_size: size of polynomial + only one parameter can be selected which is shown as below: + \arg CRC_CTL_PS_32: 32-bit polynomial for CRC calculation + \arg CRC_CTL_PS_16: 16-bit polynomial for CRC calculation + \arg CRC_CTL_PS_8: 8-bit polynomial for CRC calculation + \arg CRC_CTL_PS_7: 7-bit polynomial for CRC calculation + \param[out] none + \retval none +*/ +void crc_polynomial_size_set(uint32_t poly_size) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_PS); + CRC_CTL |= (uint32_t)poly_size; +} + +/*! + \brief configure the CRC polynomial value function + \param[in] poly: configurable polynomial value + \param[out] none + \retval none +*/ +void crc_polynomial_set(uint32_t poly) +{ + CRC_POLY &= (uint32_t)(~CRC_POLY_POLY); + CRC_POLY = poly; +} + +/*! + \brief CRC calculate single data + \param[in] sdata: specify input data + \param[in] data_format: input data format + only one parameter can be selected which is shown as below: + \arg INPUT_FORMAT_WORD: input data in word format + \arg INPUT_FORMAT_HALFWORD: input data in half-word format + \arg INPUT_FORMAT_BYTE: input data in byte format + \param[out] none + \retval CRC calculate value +*/ +uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format) +{ + if(INPUT_FORMAT_WORD == data_format) { + REG32(CRC) = sdata; + } else if(INPUT_FORMAT_HALFWORD == data_format) { + REG16(CRC) = (uint16_t)sdata; + } else { + REG8(CRC) = (uint8_t)sdata; + } + + return(CRC_DATA); +} + +/*! + \brief CRC calculate a data array + \param[in] array: pointer to the input data array + \param[in] size: size of the array + \param[in] data_format: input data format + only one parameter can be selected which is shown as below: + \arg INPUT_FORMAT_WORD: input data in word format + \arg INPUT_FORMAT_HALFWORD: input data in half-word format + \arg INPUT_FORMAT_BYTE: input data in byte format + \param[out] none + \retval CRC calculate value +*/ +uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format) +{ + uint8_t *data8; + uint16_t *data16; + uint32_t *data32; + uint32_t index; + + if(INPUT_FORMAT_WORD == data_format) { + data32 = (uint32_t *)array; + for(index = 0U; index < size; index++) { + REG32(CRC) = data32[index]; + } + } else if(INPUT_FORMAT_HALFWORD == data_format) { + data16 = (uint16_t *)array; + for(index = 0U; index < size; index++) { + REG16(CRC) = data16[index]; + } + } else { + data8 = (uint8_t *)array; + for(index = 0U; index < size; index++) { + REG8(CRC) = data8[index]; + } + } + + return (CRC_DATA); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_dac.c b/gd32a50x/standard_peripheral/source/gd32a50x_dac.c new file mode 100644 index 0000000..fa79d7f --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_dac.c @@ -0,0 +1,426 @@ +/*! + \file gd32fxxx_dac.c + \brief DAC driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_dac.h" + +/* DAC register bit offset */ +#define OUT1_REG_OFFSET ((uint32_t)0x00000010U) +#define DH_12BIT_OFFSET ((uint32_t)0x00000010U) +#define DH_8BIT_OFFSET ((uint32_t)0x00000008U) + +/*! + \brief deinitialize DAC + \param[in] none + \param[out] none + \retval none +*/ +void dac_deinit(void) +{ + rcu_periph_reset_enable(RCU_DACRST); + rcu_periph_reset_disable(RCU_DACRST); +} + +/*! + \brief enable DAC + \param[in] none + \param[out] none + \retval none +*/ +void dac_enable(void) +{ + DAC_CTL |= DAC_CTL_DEN; +} + +/*! + \brief disable DAC + \param[in] none + \param[out] none + \retval none +*/ +void dac_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DEN; +} + +/*! + \brief enable DAC DMA function + \param[in] none + \param[out] none + \retval none +*/ +void dac_dma_enable(void) +{ + DAC_CTL |= DAC_CTL_DDMAEN; +} + +/*! + \brief disable DAC DMA function + \param[in] none + \param[out] none + \retval none +*/ +void dac_dma_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DDMAEN; +} + +/*! + \brief enable DAC output buffer + \param[in] none + \param[out] none + \retval none +*/ +void dac_output_buffer_enable(void) +{ + DAC_CTL &= ~DAC_CTL_DBOFF; +} + +/*! + \brief disable DAC output buffer + \param[in] none + \param[out] none + \retval none +*/ +void dac_output_buffer_disable(void) +{ + DAC_CTL |= DAC_CTL_DBOFF; +} + +/*! + \brief get DAC output value + \param[in] none + \param[out] none + \retval DAC output data: 0~4095 +*/ +uint16_t dac_output_value_get(void) +{ + uint16_t data = 0U; + data = (uint16_t)OUT_DO; + + return data; +} + +/*! + \brief set DAC data holding register value + \param[in] dac_align: DAC data alignment mode + only one parameter can be selected which is shown as below: + \arg DAC_ALIGN_12B_R: 12-bit right-aligned data + \arg DAC_ALIGN_12B_L: 12-bit left-aligned data + \arg DAC_ALIGN_8B_R: 8-bit right-aligned data + \param[in] data: data to be loaded, 0~4095 + \param[out] none + \retval none +*/ +void dac_data_set(uint32_t dac_align, uint16_t data) +{ + switch(dac_align){ + /* 12-bit right-aligned data */ + case DAC_ALIGN_12B_R: + OUT_R12DH = data; + break; + /* 12-bit left-aligned data */ + case DAC_ALIGN_12B_L: + OUT_L12DH = data; + break; + /* 8-bit right-aligned data */ + case DAC_ALIGN_8B_R: + OUT_R8DH = data; + break; + default: + break; + } +} + +/*! + \brief enable DAC trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac_trigger_enable(void) +{ + DAC_CTL |= DAC_CTL_DTEN; +} + +/*! + \brief disable DAC trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac_trigger_disable(void) +{ + DAC_CTL &= ~DAC_CTL_DTEN; +} + +/*! + \brief configure DAC trigger source + \param[in] triggersource: external triggers of DAC + only one parameter can be selected which is shown as below: + \arg DAC_TRIGGER_EXTRIG: TRIGSEL trigger + \arg DAC_TRIGGER_SOFTWARE: software trigger + \param[out] none + \retval none +*/ +void dac_trigger_source_config(uint32_t triggersource) +{ + /* configure DAC trigger source */ + DAC_CTL &= (uint32_t)(~DAC_CTL_DTSEL); + DAC_CTL |= triggersource; +} + +/*! + \brief enable DAC software trigger + \param[in] none + \retval none +*/ +void dac_software_trigger_enable(void) +{ + DAC_SWT |= DAC_SWT_SWTR; +} + +/*! + \brief disable DAC software trigger + \param[in] none + \param[out] none + \retval none +*/ +void dac_software_trigger_disable(void) +{ + DAC_SWT &= ~DAC_SWT_SWTR; +} + +/*! + \brief configure DAC wave mode + \param[in] wave_mode: DAC wave mode + only one parameter can be selected which is shown as below: + \arg DAC_WAVE_DISABLE: wave mode disable + \arg DAC_WAVE_MODE_LFSR: LFSR noise mode + \arg DAC_WAVE_MODE_TRIANGLE: triangle noise mode + \param[out] none + \retval none +*/ +void dac_wave_mode_config(uint32_t wave_mode) +{ + /* configure DAC wave mode */ + DAC_CTL &= ~DAC_CTL_DWM; + DAC_CTL |= wave_mode; +} + +/*! + \brief configure DAC wave bit width + \param[in] bit_width: DAC noise wave bit width + only one parameter can be selected which is shown as below: + \arg DAC_WAVE_BIT_WIDTH_1: bit width of the wave signal is 1 + \arg DAC_WAVE_BIT_WIDTH_2: bit width of the wave signal is 2 + \arg DAC_WAVE_BIT_WIDTH_3: bit width of the wave signal is 3 + \arg DAC_WAVE_BIT_WIDTH_4: bit width of the wave signal is 4 + \arg DAC_WAVE_BIT_WIDTH_5: bit width of the wave signal is 5 + \arg DAC_WAVE_BIT_WIDTH_6: bit width of the wave signal is 6 + \arg DAC_WAVE_BIT_WIDTH_7: bit width of the wave signal is 7 + \arg DAC_WAVE_BIT_WIDTH_8: bit width of the wave signal is 8 + \arg DAC_WAVE_BIT_WIDTH_9: bit width of the wave signal is 9 + \arg DAC_WAVE_BIT_WIDTH_10: bit width of the wave signal is 10 + \arg DAC_WAVE_BIT_WIDTH_11: bit width of the wave signal is 11 + \arg DAC_WAVE_BIT_WIDTH_12: bit width of the wave signal is 12 + \param[out] none + \retval none +*/ +void dac_wave_bit_width_config(uint32_t bit_width) +{ + /* configure DAC wave bit width */ + DAC_CTL &= ~DAC_CTL_DWBW; + DAC_CTL |= bit_width; +} + +/*! + \brief configure DAC LFSR noise mode + \param[in] unmask_bits: LFSR noise unmask bits + only one parameter can be selected which is shown as below: + \arg DAC_LFSR_BIT0: unmask the LFSR bit0 + \arg DAC_LFSR_BITS1_0: unmask the LFSR bits[1:0] + \arg DAC_LFSR_BITS2_0: unmask the LFSR bits[2:0] + \arg DAC_LFSR_BITS3_0: unmask the LFSR bits[3:0] + \arg DAC_LFSR_BITS4_0: unmask the LFSR bits[4:0] + \arg DAC_LFSR_BITS5_0: unmask the LFSR bits[5:0] + \arg DAC_LFSR_BITS6_0: unmask the LFSR bits[6:0] + \arg DAC_LFSR_BITS7_0: unmask the LFSR bits[7:0] + \arg DAC_LFSR_BITS8_0: unmask the LFSR bits[8:0] + \arg DAC_LFSR_BITS9_0: unmask the LFSR bits[9:0] + \arg DAC_LFSR_BITS10_0: unmask the LFSR bits[10:0] + \arg DAC_LFSR_BITS11_0: unmask the LFSR bits[11:0] + \param[out] none + \retval none +*/ +void dac_lfsr_noise_config(uint32_t unmask_bits) +{ + /* configure DAC LFSR noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW; + DAC_CTL |= unmask_bits; +} + +/*! + \brief configure DAC triangle noise mode + \param[in] amplitude: the amplitude of the triangle + only one parameter can be selected which is shown as below: + \arg DAC_TRIANGLE_AMPLITUDE_1: triangle amplitude is 1 + \arg DAC_TRIANGLE_AMPLITUDE_3: triangle amplitude is 3 + \arg DAC_TRIANGLE_AMPLITUDE_7: triangle amplitude is 7 + \arg DAC_TRIANGLE_AMPLITUDE_15: triangle amplitude is 15 + \arg DAC_TRIANGLE_AMPLITUDE_31: triangle amplitude is 31 + \arg DAC_TRIANGLE_AMPLITUDE_63: triangle amplitude is 63 + \arg DAC_TRIANGLE_AMPLITUDE_127: triangle amplitude is 127 + \arg DAC_TRIANGLE_AMPLITUDE_255: triangle amplitude is 255 + \arg DAC_TRIANGLE_AMPLITUDE_511: triangle amplitude is 511 + \arg DAC_TRIANGLE_AMPLITUDE_1023: triangle amplitude is 1023 + \arg DAC_TRIANGLE_AMPLITUDE_2047: triangle amplitude is 2047 + \arg DAC_TRIANGLE_AMPLITUDE_4095: triangle amplitude is 4095 + \param[out] none + \retval none +*/ +void dac_triangle_noise_config(uint32_t amplitude) +{ + /* configure DAC triangle noise mode */ + DAC_CTL &= ~DAC_CTL_DWBW; + DAC_CTL |= amplitude; +} + +/*! + \brief get DAC flag + \param[in] dac_flag: DAC flag + only one parameter can be selected which is shown as below: + \arg DAC_FLAG_DDUDR: DMA underrun flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dac_flag_get(uint32_t flag) +{ + /* check DAC flag */ + if(DAC_FLAG_DDUDR == flag){ + if(0U != (DAC_STAT & DAC_STAT_DDUDR)){ + return SET; + } + } + return RESET; +} + +/*! + \brief clear DAC flag + \param[in] flag: DAC flag + only one parameter can be selected which is shown as below: + \arg DAC_FLAG_DDUDR: DMA underrun flag + \param[out] none + \retval none +*/ +void dac_flag_clear(uint32_t flag) +{ + /* clear DAC_OUT0 flag */ + if(DAC_FLAG_DDUDR == flag){ + DAC_STAT |= (uint32_t)DAC_STAT_DDUDR; + } +} + +/*! + \brief enable DAC interrupt + \param[in] interrupt: the DAC interrupt + only one parameter can be selected which is shown as below: + \arg DAC_INT_DDUDRIE: DMA underrun interrupt enable + \param[out] none + \retval none +*/ +void dac_interrupt_enable(uint32_t interrupt) +{ + /* enable DAC interrupt */ + if(DAC_INT_DDUDRIE == interrupt){ + DAC_CTL |= (uint32_t)DAC_CTL_DDUDRIE; + } +} + +/*! + \brief disable DAC interrupt + \param[in] interrupt: the DAC interrupt + only one parameter can be selected which is shown as below: + \arg DAC_INT_DDUDRIE: DMA underrun interrupt disable + \param[out] none + \retval none +*/ +void dac_interrupt_disable(uint32_t interrupt) +{ + /* disable DAC interrupt */ + if(DAC_INT_DDUDRIE == interrupt){ + DAC_CTL &= (uint32_t)(~DAC_CTL_DDUDRIE); + } +} + +/*! + \brief get DAC interrupt flag + \param[in] int_flag: DAC interrupt flag + only one parameter can be selected which is shown as below: + \arg DAC_INT_FLAG_DDUDR: DMA underrun interrupt flag + \param[out] none + \retval the state of DAC interrupt flag(SET or RESET) +*/ +FlagStatus dac_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t reg1 = 0U, reg2 = 0U; + + /* check DAC interrupt flag */ + if(DAC_INT_FLAG_DDUDR == int_flag){ + reg1 = DAC_STAT & DAC_STAT_DDUDR; + reg2 = DAC_CTL & DAC_CTL_DDUDRIE; + } + + /*get DAC interrupt flag status */ + if((0U != reg1) && (0U != reg2)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DAC interrupt flag + \param[in] int_flag: DAC interrupt flag + only one parameter can be selected which is shown as below: + \arg DAC_INT_FLAG_DDUDR: DMA underrun interrupt flag + \param[out] none + \retval none +*/ +void dac_interrupt_flag_clear(uint32_t int_flag) +{ + /* clear DAC interrupt flag */ + if(DAC_INT_FLAG_DDUDR == int_flag){ + DAC_STAT |= (uint32_t)DAC_STAT_DDUDR; + } +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_dbg.c b/gd32a50x/standard_peripheral/source/gd32a50x_dbg.c new file mode 100644 index 0000000..4d0fda1 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_dbg.c @@ -0,0 +1,126 @@ +/*! + \file gd32a50x_dbg.c + \brief DBG driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_dbg.h" + +#define DBG_RESET_VAL ((uint32_t)0x00000000U) /*!< DBG reset value */ + +/*! + \brief deinitialize the DBG + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL = DBG_RESET_VAL; +} + +/*! + \brief read DBG_ID code register + \param[in] none + \param[out] none + \retval DBG_ID code +*/ +uint32_t dbg_id_get(void) +{ + return DBG_ID; +} + +/*! + \brief enable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + 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_CTL |= dbg_low_power; +} + +/*! + \brief disable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + one or more parameters can be selected which are shown as below: + \arg DBG_LOW_POWER_SLEEP: do not keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: do not keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: do not keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL &= ~dbg_low_power; +} + +/*! + \brief enable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which 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_I2Cx_HOLD (x=0,1): hold I2Cx smbus timeout when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,5,6,7,19,20): hold TIMERx counter when core is halted + \arg DBG_MFCOM_HOLD : hold MFCOM counter when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: refer to dbg_periph_enum + only one parameter can be selected which 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_I2Cx_HOLD (x=0,1): hold I2Cx smbus timeout when core is halted + \arg DBG_TIMERx_HOLD (x=0,1,5,6,7,19,20): hold TIMERx counter when core is halted + \arg DBG_MFCOM_HOLD : hold MFCOM counter when core is halted + \arg DBG_CANx_HOLD (x=0,1): hold CANx 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/gd32a50x/standard_peripheral/source/gd32a50x_dma.c b/gd32a50x/standard_peripheral/source/gd32a50x_dma.c new file mode 100644 index 0000000..75e4346 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_dma.c @@ -0,0 +1,1245 @@ +/*! + \file gd32a50x_dma.c + \brief DMA driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_dma.h" +#include + +#define DMA_WRONG_HANDLE while(1){} + +/* DMA functions */ +/*! + \brief deinitialize DMA channel registers + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is deinitialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(dma_periph, channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHMADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_INTC(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); +} + +/*! + \brief initialize the parameters of DMA struct with the default values + \param[in] init_struct: the initialization data needed to initialize DMA channel + \param[out] none + \retval none +*/ +void dma_struct_para_init(dma_parameter_struct* init_struct) +{ + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* 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 + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel is initialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \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_DAC_CH0, DMA_REQUEST_I2C1_RX + DMA_REQUEST_I2C1_TX, DMA_REQUEST_I2C0_RX, DMA_REQUEST_I2C0_TX, DMA_REQUESR_SSTAT0 + DMA_REQUESR_SSTAT1, DMA_REQUESR_SSTAT2, DMA_REQUESR_SSTAT3, 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_TI + DMA_REQUEST_TIMER0_UP, DMA_REQUEST_TIMER0_CO, DMA_REQUEST_TIMER0_MCH0, DMA_REQUEST_TIMER0_MCH1 + DMA_REQUEST_TIMER0_MCH2, DMA_REQUEST_TIMER0_MCH3, DMA_REQUEST_TIMER1_CH0, DMA_REQUEST_TIMER1_CH1 + DMA_REQUEST_TIMER1_CH2, DMA_REQUEST_TIMER1_CH3, DMA_REQUEST_TIMER1_TI, DMA_REQUEST_TIMER1_UP + DMA_REQUEST_TIMER7_CH0, DMA_REQUEST_TIMER7_CH1, DMA_REQUEST_TIMER7_CH2, DMA_REQUEST_TIMER7_CH3 + DMA_REQUEST_TIMER7_TI, DMA_REQUEST_TIMER7_UP, DMA_REQUEST_TIMER7_CO, DMA_REQUEST_TIMER7_MCH0 + DMA_REQUEST_TIMER7_MCH1, DMA_REQUEST_TIMER7_MCH2, DMA_REQUEST_TIMER7_MCH3, DMA_REQUEST_CAN1 + DMA_REQUEST_CAN0, DMA_REQUEST_USART0_RX, DMA_REQUEST_USART0_TX, DMA_REQUEST_USART1_RX + DMA_REQUEST_USART1_TX, DMA_REQUEST_USART2_RX, DMA_REQUEST_USART2_TX, DMA_REQUEST_TIMER5_UP + DMA_REQUEST_TIMER6_UP, DMA_REQUEST_TIMER19_CH0, DMA_REQUEST_TIMER19_CH1, DMA_REQUEST_TIMER19_CH2 + DMA_REQUEST_TIMER19_CH3, DMA_REQUEST_TIMER19_TI, DMA_REQUEST_TIMER19_UP, DMA_REQUEST_TIMER19_CO + DMA_REQUEST_TIMER19_MCH0, DMA_REQUEST_TIMER19_MCH1, DMA_REQUEST_TIMER19_MCH2, DMA_REQUEST_TIMER19_MCH3 + DMA_REQUEST_TIMER20_CH0, DMA_REQUEST_TIMER20_CH1, DMA_REQUEST_TIMER20_CH2, DMA_REQUEST_TIMER20_CH3 + DMA_REQUEST_TIMER20_TI, DMA_REQUEST_TIMER20_UP, DMA_REQUEST_TIMER20_CO, DMA_REQUEST_TIMER20_MCH0 + DMA_REQUEST_TIMER20_MCH1, DMA_REQUEST_TIMER20_MCH2, DMA_REQUEST_TIMER20_MCH3 + \param[out] none + \retval none +*/ +void dma_init(uint32_t dma_periph, dma_channel_enum channelx, dma_parameter_struct* init_struct) +{ + uint32_t ctl; + + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + dma_channel_disable(dma_periph, channelx); + + /* configure peripheral base address */ + DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr; + + /* configure memory base address */ + DMA_CHMADDR(dma_periph, channelx) = init_struct->memory_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(dma_periph, channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK); + + /* configure peripheral transfer width, memory transfer width, channel priotity */ + ctl = DMA_CHCTL(dma_periph, channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO); + ctl |= (init_struct->periph_width | init_struct->memory_width | init_struct->priority); + DMA_CHCTL(dma_periph, channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; + } else { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure the direction of data transfer */ + if(DMA_PERIPHERAL_TO_MEMORY == init_struct->direction) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR; + } + + if(DMA0 == dma_periph) { + DMAMUX_RM_CHXCFG((uint32_t)channelx) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG((uint32_t)channelx) |= init_struct->request; + } else { + DMAMUX_RM_CHXCFG((uint32_t)channelx + 7U ) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG((uint32_t)channelx + 7U ) |= init_struct->request; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable memory to memory mode + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_M2M; +} + +/*! + \brief disable memory to memory mode + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_M2M; +} + +/*! + \brief enable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief set DMA peripheral base address + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set peripheral base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address) +{ + DMA_CHPADDR(dma_periph, channelx) = address; +} + +/*! + \brief set DMA memory base address + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set memory base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \param[in] address: memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address) +{ + DMA_CHMADDR(dma_periph, channelx) = address; +} + +/*! + \brief set the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[in] number: the number of remaining data to be transferred by the DMA + \param[out] none + \retval none +*/ +void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number) +{ + DMA_CHCNT(dma_periph, channelx) = (number & DMA_CHANNEL_CNT_MASK); +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval the number of remaining data to be transferred by the DMA +*/ +uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx) +{ + return (uint32_t)DMA_CHCNT(dma_periph, channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[in] priority: priority level of this channel + only one parameter can be selected which is shown as below: + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer data width of memory + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mwidth) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= mwidth; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief configure transfer data width of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pwidth) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(dma_periph, channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= pwidth; + DMA_CHCTL(dma_periph, channelx) = ctl; +} + +/*! + \brief enable next address increasement algorithm of memory + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_memory_increase_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA; +} + +/*! + \brief disable next address increasement algorithm of memory + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_memory_increase_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA; +} + +/*! + \brief enable next address increasement algorithm of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_periph_increase_enable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA; +} + +/*! + \brief disable next address increasement algorithm of peripheral + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \param[out] none + \retval none +*/ +void dma_periph_increase_disable(uint32_t dma_periph, dma_channel_enum channelx) +{ + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t direction) +{ + if(DMA_PERIPHERAL_TO_MEMORY == direction) { + DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief check DMA flag is set or not + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + FlagStatus reval; + + if(0U != (DMA_INTF(dma_periph) & DMA_FLAG_ADD(flag, channelx))) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief clear a DMA channel flag + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC(dma_periph) |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief enable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(dma_periph, channelx) |= source; +} + +/*! + \brief disable DMA interrupt + \param[in] dma_periph: DMAx(x=0,1) + \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..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(dma_periph, channelx) &= ~source; +} + +/*! + \brief check DMA flag and interrupt enable bit is set or not + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + switch(int_flag) { + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF(dma_periph) & DMA_FLAG_ADD(int_flag, channelx); + interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_ERRIE; + break; + default: + break; + } + + if(interrupt_flag && interrupt_enable) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear a DMA channel interrupt flag + \param[in] dma_periph: DMAx(x=0,1) + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..6 for DMA0, x = 0..4 for DMA1) + \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(uint32_t dma_periph, dma_channel_enum channelx, uint32_t int_flag) +{ + DMA_INTC(dma_periph) |= DMA_FLAG_ADD(int_flag, channelx); +} + +/* DMAMUX functions */ +/*! + \brief initialize the parameters of DMAMUX synchronization mode structure with the default values + \param[in] none + \param[out] init_struct: the initialization data needed to initialize DMAMUX request multiplexer channel synchronization mode + \retval none +*/ +void dmamux_sync_struct_para_init(dmamux_sync_parameter_struct *init_struct) +{ + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* set the DMAMUX synchronization struct with the default values */ + init_struct->sync_id = DMAMUX_SYNC_EVTX_OUT0; + init_struct->sync_polarity = DMAMUX_SYNC_RISING; + init_struct->request_number = 1U; +} + +/*! + \brief initialize DMAMUX request multiplexer channel synchronization mode + \param[in] channelx: specify which DMAMUX request multiplexer channel is initialized + only one parameter can be selected which is shown as below: + \arg DMAMUX_MULTIPLEXER_CHx(x=0..11) + \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_EVTX_OUT0, DMAMUX_SYNC_EVTX_OUT1, DMAMUX_SYNC_EVTX_OUT2, DMAMUX_SYNC_EVTX_OUT3, + DMAMUX_SYNC_TIMER20_CH0_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) +{ + uint32_t cfg; + + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* disable synchronization mode and event generation for DMA request forward number configuration */ + DMAMUX_RM_CHXCFG(channelx) &= ~(DMAMUX_RM_CHXCFG_SYNCEN | DMAMUX_RM_CHXCFG_EVGEN); + + /* configure synchronization input identification, synchronization input polarity, number of DMA requests to forward */ + cfg = DMAMUX_RM_CHXCFG(channelx); + cfg &= ~(DMAMUX_RM_CHXCFG_SYNCID | DMAMUX_RM_CHXCFG_NBR | DMAMUX_RM_CHXCFG_SYNCP); + cfg |= (init_struct->sync_polarity | (init_struct->sync_id) | RM_CHXCFG_NBR(init_struct->request_number - 1U)); + DMAMUX_RM_CHXCFG(channelx) = cfg; +} + +/*! + \brief enable synchronization mode + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MULTIPLEXER_CHx(x=0..11) + \param[out] none + \retval none +*/ +void dmamux_synchronization_enable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) |= DMAMUX_RM_CHXCFG_SYNCEN; +} + +/*! + \brief disable synchronization mode + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MULTIPLEXER_CHx(x=0..11) + \param[out] none + \retval none +*/ +void dmamux_synchronization_disable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) &= (~DMAMUX_RM_CHXCFG_SYNCEN); +} + +/*! + \brief enable event generation + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MULTIPLEXER_CHx(x=0..11) + \param[out] none + \retval none +*/ +void dmamux_event_generation_enable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) |= DMAMUX_RM_CHXCFG_EVGEN; +} + +/*! + \brief disable event generation + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MULTIPLEXER_CHx(x=0..11) + \param[out] none + \retval none +*/ +void dmamux_event_generation_disable(dmamux_multiplexer_channel_enum channelx) +{ + DMAMUX_RM_CHXCFG(channelx) &= (~DMAMUX_RM_CHXCFG_EVGEN); +} + +/*! + \brief initialize the parameters of DMAMUX request generator structure with the default values + \param[in] init_struct: the initialization data needed to initialize DMAMUX request generator channel + \param[out] none + \retval none +*/ +void dmamux_gen_struct_para_init(dmamux_gen_parameter_struct *init_struct) +{ + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* set the DMAMUX request generator structure with the default values */ + init_struct->trigger_id = DMAMUX_TRIGGER_EVTX_OUT0; + init_struct->trigger_polarity = DMAMUX_GEN_RISING; + init_struct->request_number = 1U; +} + +/*! + \brief initialize DMAMUX request generator channel + \param[in] channelx: specify which DMAMUX request generator channel is initialized + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..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_EVTX_OUT0, DMAMUX_TRIGGER_EVTX_OUT0, DMAMUX_TRIGGER_EVTX_OUT0, DMAMUX_TRIGGER_EVTX_OUT0, + DMAMUX_TRIGGER_TIMER20_CH0_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) +{ + uint32_t cfg; + + if(NULL == init_struct) { + DMA_WRONG_HANDLE + } + + /* disable DMAMUX request generator channel for DMA request generation number configuration */ + DMAMUX_RG_CHXCFG(channelx) &= ~(DMAMUX_RG_CHXCFG_RGEN); + + /* configure trigger input identification, trigger polarity, number of DMA requests to be generated */ + cfg = DMAMUX_RG_CHXCFG(channelx); + cfg &= ~(DMAMUX_RG_CHXCFG_TID | DMAMUX_RG_CHXCFG_NBRG | DMAMUX_RG_CHXCFG_RGTP); + cfg |= (RG_CHXCFG_NBRG(init_struct->request_number - 1U) | init_struct->trigger_id | init_struct->trigger_polarity); + DMAMUX_RG_CHXCFG(channelx) = cfg; +} + +/*! + \brief enable DMAMUX request generator channel + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..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 + \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 + \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..11) + \param[in] polarity: synchronization input polarity + only one parameter can be selected which is shown as below: + \arg DMAMUX_SYNC_NO_EVENT: no event detection + \arg DMAMUX_SYNC_RISING: rising edge + \arg DMAMUX_SYNC_FALLING: falling edge + \arg DMAMUX_SYNC_RISING_FALLING: rising and falling edges + \param[out] none + \retval none +*/ +void dmamux_synchronization_polarity_config(dmamux_multiplexer_channel_enum channelx, uint32_t polarity) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_SYNCP; + DMAMUX_RM_CHXCFG(channelx) |= polarity; +} + +/*! + \brief configure number of DMA requests to forward + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..6) + \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); +} + +/*! + \brief configure synchronization input identification + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..11) + \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_EVTX_OUT0: synchronization input is Evtx_out0 + \arg DMAMUX_SYNC_EVTX_OUT1: synchronization input is Evtx_out1 + \arg DMAMUX_SYNC_EVTX_OUT2: synchronization input is Evtx_out2 + \arg DMAMUX_SYNC_EVTX_OUT3: synchronization input is Evtx_out3 + \arg DMAMUX_SYNC_TIMER20_CH0_O: synchronization input is TIMER20_CH0_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) |= id; +} + +/*! + \brief configure multiplexer input identification + \param[in] channelx: specify which DMAMUX request multiplexer channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_MUXCHx(x=0..11) + \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_DAC_CH0: DMAMUX DAC_CH0 request + \arg DMA_REQUEST_I2C1_RX: DMAMUX I2C1 RX request + \arg DMA_REQUEST_I2C1_TX: DMAMUX I2C1 TX request + \arg DMA_REQUEST_I2C0_RX: DMAMUX I2C0 RX request + \arg DMA_REQUEST_I2C0_TX: DMAMUX I2C0 TX request + \arg DMA_REQUESR_SSTAT0: DMAMUX SSTAT0 request + \arg DMA_REQUESR_SSTAT1: DMAMUX SSTAT1 request + \arg DMA_REQUESR_SSTAT2: DMAMUX SSTAT2 request + \arg DMA_REQUESR_SSTAT3: DMAMUX SSTAT3 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_TI: DMAMUX TIMER0 TI request + \arg DMA_REQUEST_TIMER0_UP: DMAMUX TIMER0 UP request + \arg DMA_REQUEST_TIMER0_CO: DMAMUX TIMER0 CO request + \arg DMA_REQUEST_TIMER0_MCH0: DMAMUX TIMER0 MCH0 request + \arg DMA_REQUEST_TIMER0_MCH1: DMAMUX TIMER0 MCH1 request + \arg DMA_REQUEST_TIMER0_MCH2: DMAMUX TIMER0 MCH2 request + \arg DMA_REQUEST_TIMER0_MCH3: DMAMUX TIMER0 MCH3 request + \arg DMA_REQUEST_TIMER1_CH0: DMAMUX TIMER1 CH0 request + \arg DMA_REQUEST_TIMER1_CH1: DMAMUX TIMER1 CH1 request + \arg DMA_REQUEST_TIMER1_CH2: DMAMUX TIMER1 CH2 request + \arg DMA_REQUEST_TIMER1_CH3: DMAMUX TIMER1 CH3 request + \arg DMA_REQUEST_TIMER1_TI: DMAMUX TIMER1 TI request + \arg DMA_REQUEST_TIMER1_UP: DMAMUX TIMER1 UP request + \arg DMA_REQUEST_TIMER7_CH0: DMAMUX TIMER7 CH0 request + \arg DMA_REQUEST_TIMER7_CH1: DMAMUX TIMER7 CH1 request + \arg DMA_REQUEST_TIMER7_CH2: DMAMUX TIMER7 CH2 request + \arg DMA_REQUEST_TIMER7_CH3: DMAMUX TIMER7 CH3 request + \arg DMA_REQUEST_TIMER7_TI: DMAMUX TIMER7 TI request + \arg DMA_REQUEST_TIMER7_UP: DMAMUX TIMER7 UP request + \arg DMA_REQUEST_TIMER7_CO: DMAMUX TIMER7 CO request + \arg DMA_REQUEST_TIMER7_MCH0: DMAMUX TIMER7 MCH0 request + \arg DMA_REQUEST_TIMER7_MCH1: DMAMUX TIMER7 MCH1 request + \arg DMA_REQUEST_TIMER7_MCH2: DMAMUX TIMER7 MCH2 request + \arg DMA_REQUEST_TIMER7_MCH3: DMAMUX TIMER7 MCH3 request + \arg DMA_REQUEST_CAN1: DMAMUX CAN1 request + \arg DMA_REQUEST_CAN0: DMAMUX CAN0 request + \arg DMA_REQUEST_USART0_RX: DMAMUX USART0 RX request + \arg DMA_REQUEST_USART0_TX: DMAMUX USART0 TX request + \arg DMA_REQUEST_USART1_RX: DMAMUX USART1 RX request + \arg DMA_REQUEST_USART1_TX: DMAMUX USART1 TX request + \arg DMA_REQUEST_USART2_RX: DMAMUX USART2 RX request + \arg DMA_REQUEST_USART2_TX: DMAMUX USART2 TX request + \arg DMA_REQUEST_TIMER5_UP: DMAMUX TIMER5 UP request + \arg DMA_REQUEST_TIMER6_UP: DMAMUX TIMER6 UP request + \arg DMA_REQUEST_TIMER19_CH0: DMAMUX TIMER19 CH0 request + \arg DMA_REQUEST_TIMER19_CH1: DMAMUX TIMER19 CH1 request + \arg DMA_REQUEST_TIMER19_CH2: DMAMUX TIMER19 CH2 request + \arg DMA_REQUEST_TIMER19_CH3: DMAMUX TIMER19 CH3 request + \arg DMA_REQUEST_TIMER19_TI: DMAMUX TIMER19 TI request + \arg DMA_REQUEST_TIMER19_UP: DMAMUX TIMER19 UP request + \arg DMA_REQUEST_TIMER19_CO: DMAMUX TIMER19 CO request + \arg DMA_REQUEST_TIMER19_MCH0: DMAMUX TIMER19 MCH0 request + \arg DMA_REQUEST_TIMER19_MCH1: DMAMUX TIMER19 MCH1 request + \arg DMA_REQUEST_TIMER19_MCH2: DMAMUX TIMER19 MCH2 request + \arg DMA_REQUEST_TIMER19_MCH3: DMAMUX TIMER19 MCH3 request + \arg DMA_REQUEST_TIMER20_CH0: DMAMUX TIMER20 CH0 request + \arg DMA_REQUEST_TIMER20_CH1: DMAMUX TIMER20 CH1 request + \arg DMA_REQUEST_TIMER20_CH2: DMAMUX TIMER20 CH2 request + \arg DMA_REQUEST_TIMER20_CH3: DMAMUX TIMER20 CH3 request + \arg DMA_REQUEST_TIMER20_TI: DMAMUX TIMER20 TI request + \arg DMA_REQUEST_TIMER20_UP: DMAMUX TIMER20 UP request + \arg DMA_REQUEST_TIMER20_CO: DMAMUX TIMER20 CO request + \arg DMA_REQUEST_TIMER20_MCH0: DMAMUX TIMER20 MCH0 request + \arg DMA_REQUEST_TIMER20_MCH1: DMAMUX TIMER20 MCH1 request + \arg DMA_REQUEST_TIMER20_MCH2: DMAMUX TIMER20 MCH2 request + \arg DMA_REQUEST_TIMER20_MCH3: DMAMUX TIMER20 MCH3 request + \param[out] none + \retval none +*/ +void dmamux_request_id_config(dmamux_multiplexer_channel_enum channelx, uint32_t id) +{ + DMAMUX_RM_CHXCFG(channelx) &= ~DMAMUX_RM_CHXCFG_MUXID; + DMAMUX_RM_CHXCFG(channelx) |= id; +} + +/*! + \brief configure trigger input polarity + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..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; +} + +/*! + \brief configure number of DMA requests to be generated + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..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) |= (number - 1U); +} + +/*! + \brief configure trigger input identification + \param[in] channelx: specify which DMAMUX request generator channel is configured + only one parameter can be selected which is shown as below: + \arg DMAMUX_GENCHx(x=0..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_EVTX_OUT0: trigger input is Evtx_out0 + \arg DMAMUX_TRIGGER_EVTX_OUT0: trigger input is Evtx_out1 + \arg DMAMUX_TRIGGER_EVTX_OUT0: trigger input is Evtx_out2 + \arg DMAMUX_TRIGGER_EVTX_OUT0: trigger input is Evtx_out3 + \arg DMAMUX_TRIGGER_TIMER20_CH0_O: trigger input is TIMER20_CH0_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; +} + +/*! + \brief get DMAMUX flag + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun flag + \arg DMAMUX_FLAG_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; + + if(0U != (DMAMUX_REG_VAL(flag) & BIT(DMAMUX_BIT_POS(flag)))) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMAMUX flag + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun flag + \arg DMAMUX_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun flag + \arg DMAMUX_FLAG_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 enable DMAMUX interrupt + \param[in] interrupt: specify which interrupt to enable + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt + \arg DMAMUX_INT_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 + \param[in] interrupt: specify which interrupt to disable + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt + \arg DMAMUX_INT_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt + \arg DMAMUX_INT_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)); +} + +/*! + \brief get DMAMUX interrupt flag + \param[in] int_flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_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; + uint32_t intenable = 0U, flagstatus = 0U; + + /* get the interrupt enable bit status */ + intenable = (DMAMUX_REG_VAL2(int_flag) & BIT(DMAMUX_BIT_POS2(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (DMAMUX_REG_VAL(int_flag) & BIT(DMAMUX_BIT_POS(int_flag))); + + if(flagstatus && intenable) { + reval = SET; + } else { + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMAMUX interrupt flag + \param[in] int_flag: flag type + only one parameter can be selected which is shown as below: + \arg DMAMUX_INT_FLAG_MUXCH0_SO: DMAMUX request multiplexer channel 0 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH1_SO: DMAMUX request multiplexer channel 1 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH2_SO: DMAMUX request multiplexer channel 2 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH3_SO: DMAMUX request multiplexer channel 3 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH4_SO: DMAMUX request multiplexer channel 4 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH5_SO: DMAMUX request multiplexer channel 5 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH6_SO: DMAMUX request multiplexer channel 6 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH7_SO: DMAMUX request multiplexer channel 7 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH8_SO: DMAMUX request multiplexer channel 8 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH9_SO: DMAMUX request multiplexer channel 9 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH10_SO: DMAMUX request multiplexer channel 10 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_MUXCH11_SO: DMAMUX request multiplexer channel 11 synchronization overrun interrupt flag + \arg DMAMUX_INT_FLAG_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)); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_exti.c b/gd32a50x/standard_peripheral/source/gd32a50x_exti.c new file mode 100644 index 0000000..42f8108 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_exti.c @@ -0,0 +1,252 @@ +/*! + \file gd32a50x_exti.c + \brief EXTI driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_exti.h" + +/*! + \brief deinitialize the EXTI + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of all the EXTI registers */ + EXTI_INTEN = (uint32_t)0x00000000U; + EXTI_EVEN = (uint32_t)0x00000000U; + EXTI_RTEN = (uint32_t)0x00000000U; + EXTI_FTEN = (uint32_t)0x00000000U; + EXTI_SWIEV = (uint32_t)0x00000000U; +} + +/*! + \brief initialize the EXTI + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[in] mode: interrupt or event mode, refer to exti_mode_enum + only one parameter can be selected which is shown as below: + \arg EXTI_INTERRUPT: interrupt mode + \arg EXTI_EVENT: event mode + \param[in] trig_type: interrupt trigger type, refer to exti_trig_type_enum + only one parameter can be selected which is shown as below: + \arg EXTI_TRIG_RISING: rising edge trigger + \arg EXTI_TRIG_FALLING: falling trigger + \arg EXTI_TRIG_BOTH: rising and falling trigger + \arg EXTI_TRIG_NONE: without rising edge or falling edge trigger + \param[out] none + \retval none +*/ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type) +{ + /* reset the EXTI line x */ + EXTI_INTEN &= ~(uint32_t)linex; + EXTI_EVEN &= ~(uint32_t)linex; + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + + /* set the EXTI mode and enable the interrupts or events from EXTI line x */ + switch(mode){ + case EXTI_INTERRUPT: + EXTI_INTEN |= (uint32_t)linex; + break; + case EXTI_EVENT: + EXTI_EVEN |= (uint32_t)linex; + break; + default: + break; + } + + /* set the EXTI trigger type */ + switch(trig_type){ + case EXTI_TRIG_RISING: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + break; + case EXTI_TRIG_FALLING: + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN |= (uint32_t)linex; + break; + case EXTI_TRIG_BOTH: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN |= (uint32_t)linex; + break; + case EXTI_TRIG_NONE: + default: + break; + } +} + +/*! + \brief enable the interrupts from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_enable(exti_line_enum linex) +{ + EXTI_INTEN |= (uint32_t)linex; +} + +/*! + \brief disable the interrupt from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(uint32_t)linex; +} + +/*! + \brief enable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (uint32_t)linex; +} + +/*! + \brief disable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t)linex; +} + +/*! + \brief enable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_enable(exti_line_enum linex) +{ + EXTI_SWIEV |= (uint32_t)linex; +} + +/*! + \brief disable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): 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 pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if(0U != (EXTI_PD & (uint32_t)linex)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI line x pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): 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 flag when the interrupt flag is set + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + uint32_t flag_left, flag_right; + + flag_left = EXTI_PD & (uint32_t)linex; + flag_right = EXTI_INTEN & (uint32_t)linex; + + if((0U != flag_left) && (0U != flag_right)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI line x pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..24): 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/gd32a50x/standard_peripheral/source/gd32a50x_fmc.c b/gd32a50x/standard_peripheral/source/gd32a50x_fmc.c new file mode 100644 index 0000000..0c78d0d --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_fmc.c @@ -0,0 +1,2175 @@ +/*! + \file gd32a50x_fmc.c + \brief FMC driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_fmc.h" + +/* FMC mask */ +#define LOW_8BITS_MASK ((uint32_t)0x000000FFU) /*!< the 0-7 bits mask of a word */ +#define HIGH_8BITS_MASK ((uint32_t)0x0000FF00U) /*!< the 8-15 bits mask of a word */ +#define LOW_8BITS_MASK1 ((uint32_t)0x00FF0000U) /*!< the 16-23 bits mask of a word */ +#define HIGH_8BITS_MASK1 ((uint32_t)0xFF000000U) /*!< the 24-31 bits mask of a word */ +#define LOW_16BITS_MASK ((uint32_t)0x0000FFFFU) /*!< the 0-15 bits mask of a word */ +#define HIGH_16BITS_MASK ((uint32_t)0xFFFF0000U) /*!< the 16-31 bits mask of a word */ +#define ECCCS_FLAG_MASK ((uint32_t)0xEC000000U) /*!< flag mask in ECCCS register */ +#define ECCCS_ERROR_MASK ((uint32_t)0x00F10000U) /*!< error flag mask in ECCCS register */ + +/* FMC register bit offset */ +#define CTL_CBCMDLEN_OFFSET ((uint32_t)0x0000001DU) /*!< CBCMDLEN offset in FMC_CTL register */ +#define OBSTAT_PLEVEL_OFFSET ((uint32_t)0x00000001U) /*!< PLEVEL offset in FMC_OBSTAT register */ +#define OBSTAT_USER_OFFSET ((uint32_t)0x00000008U) /*!< USER offset in FMC_OBSTAT register */ +#define OBSTAT_DATA_OFFSET ((uint32_t)0x00000010U) /*!< DATA offset in FMC_OBSTAT register */ +#define WP1_BK1WP_OFFSET ((uint32_t)0x00000000U) /*!< BK1WP offset in FMC_WP1 register */ +#define WP1_DFWP_OFFSET ((uint32_t)0x00000008U) /*!< DFWP offset in FMC_WP1 register */ +#define WP1_EPWP_OFFSET ((uint32_t)0x00000010U) /*!< EPWP offset in FMC_WP1 register */ +#define ECCCS_REG_OFFSET ((uint32_t)0x00000004U) /*!< ECCCS register offset */ + +/* return the FMC bank0 state */ +static fmc_state_enum fmc_bank0_state_get(void); +/* return the FMC bank1 state */ +static fmc_state_enum fmc_bank1_state_get(void); +/* check FMC bank0 ready or not */ +static fmc_state_enum fmc_bank0_ready_wait(uint32_t timeout); +/* check FMC bank1 ready or not */ +static fmc_state_enum fmc_bank1_ready_wait(uint32_t timeout); +/* wait shared SRAM mode to be ready */ +static void fmc_sram_mode_ready_wait(uint32_t ready_flag); + +/*! + \brief unlock the main flash operation + 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_CTL0 & FMC_CTL0_LK))) { + /* write the FMC bank0 key */ + FMC_KEY0 = UNLOCK_KEY0; + FMC_KEY0 = UNLOCK_KEY1; + } + + if((0U != (FMC_CTL1 & FMC_CTL1_LK))) { + /* write the FMC bank1 key */ + FMC_KEY1 = UNLOCK_KEY0; + FMC_KEY1 = UNLOCK_KEY1; + } +} + +/*! + \brief unlock the main flash bank0 operation + it is better to used in pairs with fmc_bank0_lock + \param[in] none + \param[out] none + \retval none +*/ +void fmc_bank0_unlock(void) +{ + if((0U != (FMC_CTL0 & FMC_CTL0_LK))) { + /* write the FMC bank0 key */ + FMC_KEY0 = UNLOCK_KEY0; + FMC_KEY0 = UNLOCK_KEY1; + } +} + +/*! + \brief unlock the main flash bank1 operation + it is better to used in pairs with fmc_bank1_lock + \param[in] none + \param[out] none + \retval none +*/ +void fmc_bank1_unlock(void) +{ + if((0U != (FMC_CTL1 & FMC_CTL1_LK))) { + /* write the FMC bank1 key */ + FMC_KEY1 = UNLOCK_KEY0; + FMC_KEY1 = UNLOCK_KEY1; + } +} + +/*! + \brief lock the main flash operation + 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 bank0 LK bit*/ + FMC_CTL0 |= FMC_CTL0_LK; + + /* set the bank1 LK bit*/ + FMC_CTL1 |= FMC_CTL1_LK; +} + +/*! + \brief lock the main flash bank0 operation + it is better to used in pairs with fmc_bank0_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_bank0_lock(void) +{ + /* set the LK bit*/ + FMC_CTL0 |= FMC_CTL0_LK; +} + +/*! + \brief lock the main flash bank1 operation + it is better to used in pairs with fmc_bank1_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_bank1_lock(void) +{ + /* set the LK bit*/ + FMC_CTL1 |= FMC_CTL1_LK; +} + +/*! + \brief set the wait state counter value + \param[in] wscnt: wait state counter value + only one parameter can be selected which is shown as below: + \arg WS_WSCNT_0: 0 wait state added + \arg WS_WSCNT_1: 1 wait state added + \arg WS_WSCNT_2: 2 wait state added + \arg WS_WSCNT_3: 3 wait state added + \param[out] none + \retval none +*/ +void fmc_wscnt_set(uint8_t wscnt) +{ + uint32_t reg; + + reg = FMC_WS; + /* set the wait state counter value */ + reg &= ~FMC_WS_WSCNT; + FMC_WS = (reg | wscnt); +} + +/*! + \brief enable pre-fetch + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_enable(void) +{ + FMC_WS |= FMC_WS_PFEN; +} + +/*! + \brief disable pre-fetch + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_disable(void) +{ + FMC_WS &= ~FMC_WS_PFEN; +} + +/*! + \brief enable cache + \param[in] none + \param[out] none + \retval none +*/ +void fmc_cache_enable(void) +{ + FMC_WS |= FMC_WS_IDCEN; +} + +/*! + \brief disable cache + \param[in] none + \param[out] none + \retval none +*/ +void fmc_cache_disable(void) +{ + FMC_WS &= ~FMC_WS_IDCEN; +} + +/*! + \brief enable cache reset if cache is disabled + \param[in] none + \param[out] none + \retval none +*/ +void fmc_cache_reset_enable(void) +{ + FMC_WS |= FMC_WS_IDRST; +} + +/*! + \brief disable cache reset + \param[in] none + \param[out] none + \retval none +*/ +void fmc_cache_reset_disable(void) +{ + FMC_WS &= ~FMC_WS_IDRST; +} + +/*! + \brief flash goto power-down mode when MCU enters deepsleep mode + \param[in] none + \param[out] none + \retval none +*/ +void fmc_powerdown_mode_set(void) +{ + FMC_WS &= ~FMC_WS_SLEEP_SLP; +} + +/*! + \brief flash goto sleep mode when MCU enters deepsleep mode + \param[in] none + \param[out] none + \retval none +*/ +void fmc_sleep_mode_set(void) +{ + FMC_WS |= FMC_WS_SLEEP_SLP; +} + +/*! + \brief configure shared SRAM mode + \param[in] sram_mode: shared SRAM mode + only one parameter can be selected which is shown as below: + \arg FASTPG_SRAM_MODE: fast program SRAM mode + \arg BASIC_SRAM_MODE: basic SRAM mode + \arg EEPROM_SRAM_MODE: EEPROM SRAM mode + \param[out] none + \retval none +*/ +void fmc_sram_mode_config(fmc_sram_mode_enum sram_mode) +{ + fmc_sram_mode_enum curr_mode; + + curr_mode = fmc_sram_mode_get(); + FMC_CTL1 &= ~FMC_CTL1_SRAMCMD; + if((EEPROM_SRAM_MODE == sram_mode) && (EEPROM_SRAM_MODE != curr_mode)) { + /* set shared SRAM to EEPROM SRAM mode*/ + FMC_CTL1 |= EEPROM_SRAM_CMD; + fmc_sram_mode_ready_wait(FMC_WS_ERAMRDY); + } else if((BASIC_SRAM_MODE == sram_mode) && (BASIC_SRAM_MODE != curr_mode)) { + /* set shared SRAM to basic SRAM mode*/ + FMC_CTL1 |= BASIC_SRAM_CMD; + fmc_sram_mode_ready_wait(FMC_WS_BRAMRDY); + } else if((FASTPG_SRAM_MODE == sram_mode) && (FASTPG_SRAM_MODE != curr_mode)) { + /* set shared SRAM to fast program SRAM mode*/ + FMC_CTL1 |= FASTPG_SRAM_CMD; + fmc_sram_mode_ready_wait(FMC_WS_PRAMRDY); + } else { + /* illegal parameters */ + } +} + +/*! + \brief get shared SRAM mode + \param[in] none + \param[out] none + \retval sram_mode: shared SRAM mode + \arg NO_SRAM_MODE: SRAM mode is not configured + \arg FASTPG_SRAM_MODE: fast PG SRAM mode + \arg BASIC_SRAM_MODE: basic SRAM mode + \arg EEPROM_SRAM_MODE: EEPROM SRAM mode +*/ +fmc_sram_mode_enum fmc_sram_mode_get(void) +{ + fmc_sram_mode_enum sram_mode; + + if(0U != (FMC_WS & FMC_WS_ERAMRDY)) { + /* SRAM is in EEPROM SRAM mode*/ + sram_mode = EEPROM_SRAM_MODE; + } else if(0U != (FMC_WS & FMC_WS_BRAMRDY)) { + /* SRAM is in basic SRAM mode*/ + sram_mode = BASIC_SRAM_MODE; + } else if(0U != (FMC_WS & FMC_WS_PRAMRDY)) { + /* SRAM is in fast program SRAM mode*/ + sram_mode = FASTPG_SRAM_MODE; + } else { + sram_mode = NO_SRAM_MODE; + } + + return sram_mode; +} + +/*! + \brief check whether flash page is blank or not by check blank command + \param[in] address: start address to check + \param[in] length: the read length is 2^length double words, the flash area to be checked must be in one page and should not exceed 1KB boundary + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_blank_check(uint32_t address, uint8_t length) +{ + fmc_state_enum fmc_state; + + if((address >= BANK0_BASE_ADDRESS) && (address < BANK1_BASE_ADDRESS)) { + /* start check blank command */ + FMC_ADDR0 = address; + FMC_CTL0 &= ~FMC_CTL0_CBCMDLEN; + FMC_CTL0 |= (uint32_t)length << CTL_CBCMDLEN_OFFSET; + FMC_CTL0 |= FMC_CTL0_CBCMD; + FMC_CTL0 |= FMC_CTL0_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the CBCMD bit */ + FMC_CTL0 &= ~FMC_CTL0_CBCMD; + } else { + /* start check blank command */ + FMC_ADDR1 = address; + FMC_CTL1 &= ~FMC_CTL1_CBCMDLEN; + FMC_CTL1 |= (uint32_t)length << CTL_CBCMDLEN_OFFSET; + FMC_CTL1 |= FMC_CTL1_CBCMD; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the CBCMD bit */ + FMC_CTL1 &= ~FMC_CTL1_CBCMD; + } + + return fmc_state; +} + +/*! + \brief erase main flash page + \param[in] page_address: target page start address + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_page_erase(uint32_t page_address) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((page_address >= BANK0_BASE_ADDRESS) && (page_address < BANK1_BASE_ADDRESS)) { + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start page erase */ + FMC_CTL0 |= FMC_CTL0_PER; + FMC_ADDR0 = page_address; + FMC_CTL0 |= FMC_CTL0_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PER bit */ + FMC_CTL0 &= ~FMC_CTL0_PER; + } + } else { + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + if(FMC_READY == fmc_state) { + /* start page erase */ + FMC_CTL1 |= FMC_CTL1_PER; + FMC_ADDR1 = page_address; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PER bit */ + FMC_CTL1 &= ~FMC_CTL1_PER; + } + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief erase flash bank0 + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_bank0_mass_erase(void) +{ + fmc_state_enum fmc_state; + + /* wait for the FMC ready */ + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start chip erase */ + FMC_CTL0 |= FMC_CTL0_MER; + FMC_CTL0 |= FMC_CTL0_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bit */ + FMC_CTL0 &= ~FMC_CTL0_MER; + } + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief erase flash bank1 + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_bank1_mass_erase(void) +{ + fmc_state_enum fmc_state; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start chip erase */ + FMC_CTL1 |= FMC_CTL1_MER; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bit */ + FMC_CTL1 &= ~FMC_CTL1_MER; + } + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief erase the data flash + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_dflash_mass_erase(void) +{ + fmc_state_enum fmc_state; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start data flash erase */ + FMC_CTL1 |= FMC_CTL1_MERDF; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MERDF bit */ + FMC_CTL1 &= ~FMC_CTL1_MERDF; + } + + return fmc_state; +} + +/*! + \brief erase whole chip + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state; + + /* mass erase flash bank0 */ + fmc_state = fmc_bank0_mass_erase(); + + /* return the bank0 abnormal state */ + if(FMC_READY != fmc_state) { + return fmc_state; + } + + /* mass erase flash bank1 */ + fmc_state = fmc_bank1_mass_erase(); + + /* return the bank1 abnormal state */ + if(FMC_READY != fmc_state) { + return fmc_state; + } + + /* mass erase data flash */ + fmc_state = fmc_dflash_mass_erase(); + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a double word at the corresponding address in main flash + \param[in] address: address to program, apply to bank0, bank1 and data flash + \param[in] data: double word to program + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data) +{ + uint32_t data0, data1; + fmc_state_enum fmc_state; + + if((address >= BANK0_BASE_ADDRESS) && (address < BANK1_BASE_ADDRESS)) { + /* wait for the FMC ready */ + fmc_state = fmc_bank0_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_CTL0 |= FMC_CTL0_PG; + REG32(address) = data0; + REG32(address + 4U) = data1; + + /* wait for the FMC ready */ + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL0 &= ~FMC_CTL0_PG; + } + } else { + /* wait for the FMC ready */ + fmc_state = fmc_bank1_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_CTL1 |= FMC_CTL1_PG; + REG32(address) = data0; + REG32(address + 4U) = data1; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL1 &= ~FMC_CTL1_PG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief FMC fast program one row data (32 double-word) starting at the corresponding address + \param[in] address: address to program + \param[in] data: data buffer to program + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum fmc_fast_program(uint32_t address, uint64_t data[]) +{ + uint8_t index; + fmc_state_enum fmc_state; + fmc_sram_mode_enum sram_mode; + uint8_t cache_en = 0U; + + /* get shared SRAM mode */ + sram_mode = fmc_sram_mode_get(); + + /* set shared SRAM to fast program mode */ + if(FASTPG_SRAM_MODE != sram_mode) { + fmc_sram_mode_config(FASTPG_SRAM_MODE); + } + + /* check the row (32 double-word) in flash to confirm all data in flash is all 0xFF */ + fmc_state = fmc_blank_check(address, CBCMDLEN_OF_ONE_ROW); + if(FMC_CBCMDERR == fmc_state) { + /* flash is not erased */ + return FMC_PGERR; + } + /* flush the cache if it is enabled */ + if(FMC_WS & FMC_WS_IDCEN) { + cache_en = 1U; + fmc_cache_disable(); + } + fmc_cache_reset_enable(); + fmc_cache_reset_disable(); + + if((address >= BANK0_BASE_ADDRESS) && (address < BANK1_BASE_ADDRESS)) { + /* wait for the FMC ready */ + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* set the FSTPG bit to start program */ + FMC_CTL0 |= FMC_CTL0_FSTPG; + + /* program the row data */ + for(index = 0U; index < DOUBLEWORD_CNT_IN_ROW; index++) { + REG32(address) = (uint32_t)(data[index] & 0x00000000FFFFFFFFU); + REG32(address + 4U) = (uint32_t)(data[index] >> 32U); + address += 8U; + } + /* set START bit to launch fast program operation to flash */ + FMC_CTL0 |= FMC_CTL0_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank0_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the FSTPG bit */ + FMC_CTL0 &= ~FMC_CTL0_FSTPG; + } + } else { + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* set the FSTPG bit to start program */ + FMC_CTL1 |= FMC_CTL1_FSTPG; + + /* program the row data */ + for(index = 0U; index < DOUBLEWORD_CNT_IN_ROW; index++) { + REG32(address) = (uint32_t)(data[index] & 0x00000000FFFFFFFFU); + REG32(address + 4U) = (uint32_t)(data[index] >> 32U); + address += 8U; + } + + /* set START bit to launch fast program operation to flash */ + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the FSTPG bit */ + FMC_CTL1 &= ~FMC_CTL1_FSTPG; + } + } + if(1U == cache_en) { + fmc_cache_enable(); + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a double word at the corresponding address in OTP + \param[in] address: address to program + \param[in] data: double word to write + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum otp_doubleword_program(uint32_t address, uint64_t data) +{ + uint32_t data0, data1; + fmc_state_enum fmc_state; + + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + data0 = (uint32_t)(data & 0xFFFFFFFFU); + data1 = (uint32_t)((data >> 32U) & 0xFFFFFFFFU); + + /* configure program width */ + if(FMC_READY == fmc_state) { + /* set the PG bit to start program */ + FMC_CTL1 |= FMC_CTL1_PG; + REG32(address) = data0; + REG32(address + 4U) = data1; + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL1 &= ~FMC_CTL1_PG; + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a word at the corresponding address in EEPROM + \param[in] address: address to program + \param[in] data: word to write + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +fmc_state_enum eeprom_word_program(uint32_t address, uint32_t data) +{ + fmc_sram_mode_enum sram_mode; + fmc_state_enum fmc_state; + + /* get shared SRAM mode */ + sram_mode = fmc_sram_mode_get(); + + /* set Shared SRAM to EEPROM RAM mode */ + if(EEPROM_SRAM_MODE != sram_mode) { + fmc_sram_mode_config(EEPROM_SRAM_MODE); + } + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* configure program width */ + if(FMC_READY == fmc_state) { + REG32(address) = data; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief read a word at the corresponding address in EEPROM + \param[in] address: address to read + \param[in] none + \param[out] none + \retval word data readout +*/ +uint32_t eeprom_word_read(uint32_t address) +{ + uint32_t data; + fmc_sram_mode_enum sram_mode; + + /* get shared SRAM mode */ + sram_mode = fmc_sram_mode_get(); + + /* set shared SRAM to EEPROM RAM mode */ + if(EEPROM_SRAM_MODE != sram_mode) { + fmc_sram_mode_config(EEPROM_SRAM_MODE); + } + + data = REG32(address); + + /* return data */ + return data; +} + +/*! + \brief unlock the option bytes 0 operation + 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_CTL1 & FMC_CTL1_OBWEN)) { + /* write the FMC key */ + FMC_OBKEY = UNLOCK_KEY0; + FMC_OBKEY = UNLOCK_KEY1; + } + + /* wait until OBWEN bit is set by hardware */ + while(0U == (FMC_CTL1 & FMC_CTL1_OBWEN)) { + } +} + +/*! + \brief lock the option bytes 0 operation + 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_CTL1 &= ~FMC_CTL1_OBWEN; +} + +/*! + \brief force to reload the option bytes 0 + \param[in] none + \param[out] none + \retval none +*/ +void ob_reset(void) +{ + /* set the OBRLD bit */ + FMC_CTL1 |= FMC_CTL1_OBRLD; +} + +/*! + \brief erase the option bytes 0 + programmer must ensure FMC & option bytes are both unlocked before calling this function + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB_HSPC: FMC is under high security protection +*/ +fmc_state_enum ob_erase(void) +{ + uint32_t temp_spc_user; + fmc_state_enum fmc_state; + + temp_spc_user = OB_SPC_USER; + + /* check the option bytes security protection value */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) { + return FMC_OB_HSPC; + } + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start erase the option bytes */ + FMC_CTL1 |= FMC_CTL1_OB0ER; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + + /* set the OB0PG bit */ + FMC_CTL1 |= FMC_CTL1_OB0PG; + + /* restore the previous security protection configuration */ + OB_SPC_USER = (temp_spc_user & LOW_8BITS_MASK) | LOW_8BITS_MASK1; + OB_DATA = 0xFFFFFFFFU; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the OB0PG bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0PG; + } else { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable option bytes 0 write protection + \param[in] wp_area: write protection area + only one parameter can be selected which is shown as below: + \arg BANK0_AREA: main flash bank0 write protection area + \arg BANK1_AREA: main flash bank1 write protection area + \arg DATA_FLASH_AREA: data flash write protection area + \arg EEPROM_AREA: EEPROM write protection area + \param[in] ob_wp: write protection configuration data. Notice that set the bit to 1 if you want to protect + the corresponding pages. The lowest 8 bits is valid in area except bank0. + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB_HSPC: FMC is under high security protection +*/ +fmc_state_enum ob_write_protection_enable(fmc_area_enum wp_area, uint32_t ob_wp) +{ + uint32_t i; + uint32_t op_byte[OB_WORD_CNT] = {0U}; + fmc_state_enum fmc_state; + + /* check the option bytes security protection value */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) { + return FMC_OB_HSPC; + } + + /* read option bytes */ + for(i = 0U; i < OB_WORD_CNT; i++) { + op_byte[i] = OP_BYTE(i); + } + + ob_wp = (uint32_t)(~ob_wp); + if(BANK0_AREA == wp_area) { + /* configure write protection to main flash bank0 area */ + op_byte[2] &= (ob_wp & LOW_8BITS_MASK) | ((ob_wp & HIGH_8BITS_MASK) << 8); + op_byte[3] &= ((ob_wp & LOW_8BITS_MASK1) >> 16) | ((ob_wp & HIGH_8BITS_MASK1) >> 8); + } else if(BANK1_AREA == wp_area) { + /* configure write protection to main flash bank1 area */ + op_byte[4] &= (uint32_t)((ob_wp & LOW_8BITS_MASK) | HIGH_16BITS_MASK); + } else if(DATA_FLASH_AREA == wp_area) { + /* configure write protection to data flash area */ + op_byte[4] &= (uint32_t)(((ob_wp & LOW_8BITS_MASK) << 16U) | LOW_16BITS_MASK); + } else if(EEPROM_AREA == wp_area) { + /* configure write protection to EEPROM area */ + op_byte[5] &= (uint32_t)(ob_wp & LOW_8BITS_MASK); + } else { + /* illegal parameters */ + } + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start erase the option bytes */ + FMC_CTL1 |= FMC_CTL1_OB0ER; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + + /* enable the option bytes programming */ + FMC_CTL1 |= FMC_CTL1_OB0PG; + + /* write option bytes */ + for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) { + OP_BYTE(i * 2U) = op_byte[i * 2U]; + OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U]; + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + if(FMC_READY != fmc_state) { + break; + } + } + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the OB0PG bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0PG; + } else { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + } + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure security protection + \param[in] ob_spc: specify security protection code + 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, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB_HSPC: FMC is under high security protection +*/ +fmc_state_enum ob_security_protection_config(uint16_t ob_spc) +{ + uint32_t i; + uint32_t op_byte[OB_WORD_CNT] = {0U}; + fmc_state_enum fmc_state; + + /* check the option bytes security protection value */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) { + return FMC_OB_HSPC; + } + /* read option bytes */ + for(i = 0U; i < OB_WORD_CNT; i++) { + op_byte[i] = OP_BYTE(i); + } + + op_byte[0] = ((uint32_t)(ob_spc)) | ((op_byte[0] & HIGH_16BITS_MASK)); + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start erase the option bytes */ + FMC_CTL1 |= FMC_CTL1_OB0ER; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + + /* enable the option bytes programming */ + FMC_CTL1 |= FMC_CTL1_OB0PG; + + /* write option bytes */ + for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) { + OP_BYTE(i * 2U) = op_byte[i * 2U]; + OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U]; + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + if(FMC_READY != fmc_state) { + break; + } + } + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the OB0PG bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0PG; + } else { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + } + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC user option bytes 0 + 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. + the function ob_erase is used to set all the bits to be 1. + \param[in] ob_user: user option bytes + one or more (bitwise OR) parameters can be selected which are shown as below: + \arg OB_FWDGT_HW/OB_FWDGT_SW: free watchdog mode + \arg OB_DEEPSLEEP_RST/OB_DEEPSLEEP_NRST: generate a reset or enter deep-sleep mode + \arg OB_STDBY_RST/OB_STDBY_NRST: generate a reset or enter standby mode + \arg OB_BOOT_FROM_BANK1/OB_BOOT_FROM_BANK0: boot mdoe + \arg OB_BOOT_OTA_ENABLE/OB_BOOT_OTA_DISABLE: OTA mdoe + \arg OB_BOR_DISABLE/OB_BOR_ENABLE: BOR on/off + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB_HSPC: FMC is under high security protection +*/ +fmc_state_enum ob_user_write(uint16_t ob_user) +{ + uint32_t i; + uint32_t op_byte[OB_WORD_CNT] = {0U}; + uint8_t ob_user_0, ob_user_1, ob_user_temp; + + /* check the option bytes security protection value */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) { + return FMC_OB_HSPC; + } + + ob_user_0 = (uint8_t)(ob_user >> 8U); + ob_user_1 = (uint8_t)(ob_user & 0xFFU); + + /* read option bytes */ + for(i = 0U; i < OB_WORD_CNT; i++) { + op_byte[i] = OP_BYTE(i); + } + + ob_user_temp = (uint8_t)(op_byte[0] >> 16U); + ob_user_temp |= ob_user_1; + ob_user_temp &= (uint8_t)(~ob_user_0); + + op_byte[0] = ((uint32_t)ob_user_temp << 16U) | ((op_byte[0] & LOW_16BITS_MASK)); + + /* check whether FMC is ready or not */ + fmc_state_enum fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start erase the option bytes */ + FMC_CTL1 |= FMC_CTL1_OB0ER; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + + /* enable the option bytes programming */ + FMC_CTL1 |= FMC_CTL1_OB0PG; + + /* write option bytes */ + for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) { + OP_BYTE(i * 2U) = op_byte[i * 2U]; + OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U]; + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + if(FMC_READY != fmc_state) { + break; + } + } + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the OB0PG bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0PG; + } else { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC data option bytes 0 + programmer must ensure FMC & option bytes are both unlocked before calling this function + \param[in] ob_data: the data to be programmed, OB_DATA[0:15] + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB_HSPC: FMC is under high security protection +*/ +fmc_state_enum ob_data_program(uint16_t ob_data) +{ + uint32_t i; + uint32_t val; + uint32_t op_byte[OB_WORD_CNT] = {0U}; + fmc_state_enum fmc_state = FMC_READY; + + val = OB_SPC; + /* check the option bytes security protection value */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_plevel_get()) { + return FMC_OB_HSPC; + } + + /* read option bytes */ + for(i = 0U; i < OB_WORD_CNT; i++) { + op_byte[i] = OP_BYTE(i); + } + + val = (uint32_t)(ob_data & LOW_8BITS_MASK); + val |= ((uint32_t)ob_data & HIGH_8BITS_MASK) << 8U; + op_byte[1] = val; + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* start erase the option bytes */ + FMC_CTL1 |= FMC_CTL1_OB0ER; + FMC_CTL1 |= FMC_CTL1_START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + /* set the OB0PG bit */ + FMC_CTL1 |= FMC_CTL1_OB0PG; + + /* write option bytes */ + for(i = 0U; i < OB_DOUBLEWORD_CNT; i++) { + OP_BYTE(i * 2U) = op_byte[i * 2U]; + OP_BYTE(i * 2U + 1U) = op_byte[i * 2U + 1U]; + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + if(FMC_READY != fmc_state) { + break; + } + } + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the OB0PG bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0PG; + } else { + /* reset the OB0ER bit */ + FMC_CTL1 &= ~FMC_CTL1_OB0ER; + } + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get the value of FMC option bytes OB_USER in FMC_OBSTAT register + \param[in] none + \param[out] none + \retval the option bytes USER value +*/ +uint8_t ob_user_get(void) +{ + return (uint8_t)((FMC_OBSTAT & FMC_OBSTAT_USER) >> OBSTAT_USER_OFFSET); +} + +/*! + \brief get the value of FMC option bytes OB_DATA in FMC_OBSTAT register + \param[in] none + \param[out] none + \retval the option bytes DATA value +*/ +uint16_t ob_data_get(void) +{ + return (uint16_t)((FMC_OBSTAT & FMC_OBSTAT_DATA) >> OBSTAT_DATA_OFFSET); +} + +/*! + \brief get the value of FMC option bytes BK0WP in FMC_WP0 register + \param[in] none + \param[out] none + \retval the option bytes BK0WP value +*/ +uint32_t ob_write_protection_get(void) +{ + return (uint32_t)(FMC_WP0); +} + +/*! + \brief get the value of FMC option bytes BK1WP in FMC_WP1 register + \param[in] none + \param[out] none + \retval the option bytes BK1WP value +*/ +uint8_t ob_bk1_write_protection_get(void) +{ + return (uint8_t)((FMC_WP1 & FMC_WP1_BK1WP) >> WP1_BK1WP_OFFSET); +} + +/*! + \brief get the value of FMC option bytes DFWP in FMC_WP1 register + \param[in] none + \param[out] none + \retval the option bytes DFWP value +*/ +uint8_t ob_df_write_protection_get(void) +{ + return (uint8_t)((FMC_WP1 & FMC_WP1_DFWP) >> WP1_DFWP_OFFSET); +} + +/*! + \brief get the value of FMC option bytes EPWP in FMC_WP1 register + \param[in] none + \param[out] none + \retval the option bytes EPWP value +*/ +uint8_t ob_ep_write_protection_get(void) +{ + return (uint8_t)((FMC_WP1 & FMC_WP1_EPWP) >> WP1_EPWP_OFFSET); +} + +/*! + \brief get the value of FMC option bytes 0 security protection level (PLEVEL) in FMC_OBSTAT register + \param[in] none + \param[out] none + \retval the value of PLEVEL + \arg OB_OBSTAT_PLEVEL_NO: no security protection + \arg OB_OBSTAT_PLEVEL_LOW: low security protection + \arg OB_OBSTAT_PLEVEL_HIGH: high security protection +*/ +uint8_t ob_plevel_get(void) +{ + return (uint8_t)((FMC_OBSTAT & FMC_OBSTAT_PLEVEL) >> OBSTAT_PLEVEL_OFFSET); +} + +/*! + \brief configure lock value in option bytes 1 + programmer must ensure FMC & option bytes are both unlocked before calling this function + \param[in] lk_value: the LK value to be programmed (OB1_LK_VALUE) + only one parameter can be selected which is shown as below: + \arg OB1CS_OB1_LK: when configured as OB1CS_OB1_LK, the option bytes 1 cannot be modified any more + \arg OB1CS_OB1_NOT_LK: option bytes 1 is not locked + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB1_LK: option bytes 1 is locked +*/ +fmc_state_enum ob1_lock_config(uint32_t lk_value) +{ + uint32_t reg; + + /* check the option bytes 1 lock status */ + if(0U != (FMC_OB1CS & FMC_OB1CS_OB1LK)) { + return FMC_OB1_LK; + } + + reg = FMC_OB1CS; + reg &= ~FMC_OB1CS_LKVAL; + reg |= lk_value; + + /* wait for the FMC ready */ + fmc_state_enum fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* write the value to LKVAL in FMC_OB1CS register */ + FMC_OB1CS = reg; + + /* set the OB1START bit */ + FMC_OB1CS |= FMC_OB1CS_OB1START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure the EPLOAD value of option bytes 1 loaded after the system reset + programmer must ensure FMC & option bytes are both unlocked before calling this function + \param[in] epload: EPLOAD value to be programmed + only one parameter can be selected which is shown as below: + \arg OB1CS_EPLOAD_NOT_LOAD_EPDATA: shared SRAM is not loaded with valid EEPROM data during FMC reset + \arg OB1CS_EPLOAD_LOAD_EPDATA: shared SRAM is loaded with valid EEPROM data during FMC reset + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB1_LK: option bytes 1 is locked +*/ +fmc_state_enum ob1_epload_config(uint32_t epload) +{ + uint32_t reg; + fmc_state_enum fmc_state = FMC_READY; + + /* check the option bytes 1 lock status */ + if(0U != (FMC_OB1CS & FMC_OB1CS_OB1LK)) { + return FMC_OB1_LK; + } + + reg = FMC_OB1CS; + reg &= ~FMC_OB1CS_EPLOAD; + reg |= epload; + + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* write the value to EPLOAD in FMC_OB1CS register */ + FMC_OB1CS = reg; + + /* set the OB1START bit */ + FMC_OB1CS |= FMC_OB1CS_OB1START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the OB1START bit */ + FMC_OB1CS &= ~FMC_OB1CS_OB1START; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure option bytes 1 EEPROM parameters + programmer must ensure FMC & option bytes are both unlocked before calling this function + \param[in] efalc: EFALC value to be programmed + only one parameter can be selected which is shown as below: + \arg OB1CS_DF_64K_EF_0K: data flash size is 64KB, EEPROM backup size is 0KB + \arg OB1CS_DF_48K_EF_16K: data flash size is 48KB, EEPROM backup size is 16KB + \arg OB1CS_DF_32K_EF_32K: data flash size is 32KB, EEPROM backup size is 32KB + \arg OB1CS_DF_16K_EF_48K: data flash size is 16KB, EEPROM backup size is 48KB + \arg OB1CS_DF_0K_EF_64K: data flash size is 0KB, EEPROM backup size is 64KB + \arg OB1CS_DF_EF_INVALID: data flash and EEPROM backup are invalid + \arg OB1CS_DF_32K_EF_0K: data flash size is 32KB, EEPROM backup size is 0KB + \arg OB1CS_DF_8K_EF_24K: data flash size is 8KB, EEPROM backup size is 24KB + \arg OB1CS_DF_0K_EF_32K: data flash size is 0KB, EEPROM backup size is 32KB + \arg OB1CS_DF_16K_EF_16K: data flash size is 16KB, EEPROM backup size is 16KB + \arg OB1CS_DF_24K_EF_8K: data flash size is 24KB, EEPROM backup size is 8KB + \arg OB1CS_DF_16K_EF_0K: data flash size is 16KB, EEPROM backup size is 0KB + \arg OB1CS_DF_4K_EF_12K: data flash size is 4KB, EEPROM backup size is 12KB + \arg OB1CS_DF_0K_EF_16K: data flash size is 0KB, EEPROM backup size is 16KB + \arg OB1CS_DF_8K_EF_8K: data flash size is 8KB, EEPROM backup size is 8KB + \arg OB1CS_DF_12K_EF_4K: data flash size is 12KB, EEPROM backup size is 4KB + \param[in] epsize: EPSIZE value to be programmed + only one parameter can be selected which is shown as below: + \arg OB1CS_EPSIZE_NONE: no EEPROM + \arg OB1CS_EPSIZE_4K: 4KB EEPROM + \arg OB1CS_EPSIZE_2K: 2KB EEPROM + \arg OB1CS_EPSIZE_1K: 1KB EEPROM + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error + \arg FMC_OB1_LK: option bytes 1 is locked +*/ +fmc_state_enum ob1_eeprom_parameter_config(uint32_t efalc, uint32_t epsize) +{ + uint32_t reg; + fmc_state_enum fmc_state; + + /* check the option bytes security protection value */ + if(0U != (FMC_OB1CS & FMC_OB1CS_OB1LK)) { + return FMC_OB1_LK; + } + /* configure the EFALC and EPSIZE */ + reg = FMC_OB1CS; + reg &= ~FMC_OB1CS_EFALC; + reg |= efalc; + reg &= ~FMC_OB1CS_EPSIZE; + reg |= epsize; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state) { + /* write the value to EPSIZE and EFALC in FMC_OB1CS register */ + FMC_OB1CS = reg; + + /* set the OB1START bit */ + FMC_OB1CS |= FMC_OB1CS_OB1START; + + /* wait for the FMC ready */ + fmc_state = fmc_bank1_ready_wait(FMC_TIMEOUT_COUNT); + /* reset the OB1START bit */ + FMC_OB1CS &= ~FMC_OB1CS_OB1START; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get data flash size in byte unit + \param[in] none + \param[out] none + \retval data flash byte count +*/ +uint32_t dflash_size_get(void) +{ + uint32_t efalc_value; + uint32_t dflash_size = 0U; + + /* get EFALC value in option bytes 1 */ + efalc_value = FMC_OB1CS & FMC_OB1CS_EFALC; + + switch(efalc_value) { + case OB1CS_DF_64K_EF_0K: + dflash_size = 64U * 0x400U; + break; + case OB1CS_DF_48K_EF_16K: + dflash_size = 48U * 0x400U; + break; + case OB1CS_DF_32K_EF_32K: + dflash_size = 32U * 0x400U; + break; + case OB1CS_DF_16K_EF_48K: + dflash_size = 16U * 0x400U; + break; + case OB1CS_DF_0K_EF_64K: + dflash_size = 0x00000000U; + break; + case OB1CS_DF_EF_INVALID: + dflash_size = 0x00000000U; + break; + case OB1CS_DF_32K_EF_0K: + dflash_size = 32U * 0x400U; + break; + case OB1CS_DF_8K_EF_24K: + dflash_size = 8U * 0x400U; + break; + case OB1CS_DF_0K_EF_32K: + dflash_size = 0x00000000U; + break; + case OB1CS_DF_16K_EF_16K: + dflash_size = 16U * 0x400U; + break; + case OB1CS_DF_24K_EF_8K: + dflash_size = 24U * 0x400U; + break; + case OB1CS_DF_16K_EF_0K: + dflash_size = 16U * 0x400U; + break; + case OB1CS_DF_4K_EF_12K: + dflash_size = 4U * 0x400U; + break; + case OB1CS_DF_0K_EF_16K: + dflash_size = 0x00000000U; + break; + case OB1CS_DF_8K_EF_8K: + dflash_size = 8U * 0x400U; + break; + case OB1CS_DF_12K_EF_4K: + dflash_size = 12U * 0x400U; + break; + default: + break; + } + + return dflash_size; +} + +/*! + \brief get EEPROM backup size in byte unit + \param[in] none + \param[out] none + \retval EEPROM backup byte count +*/ +uint32_t eeprom_backup_size_get(void) +{ + uint32_t efalc_value; + uint32_t eeprom_backup_size = 0U; + + /* get EFALC value in option bytes 1 */ + efalc_value = FMC_OB1CS & FMC_OB1CS_EFALC; + + switch(efalc_value) { + case OB1CS_DF_64K_EF_0K: + eeprom_backup_size = 0x00000000U; + break; + case OB1CS_DF_48K_EF_16K: + eeprom_backup_size = 16U * 0x400U; + break; + case OB1CS_DF_32K_EF_32K: + eeprom_backup_size = 32U * 0x400U; + break; + case OB1CS_DF_16K_EF_48K: + eeprom_backup_size = 48U * 0x400U; + break; + case OB1CS_DF_0K_EF_64K: + eeprom_backup_size = 64U * 0x400U; + break; + case OB1CS_DF_EF_INVALID: + eeprom_backup_size = 0x00000000U; + break; + case OB1CS_DF_32K_EF_0K: + eeprom_backup_size = 0x00000000U; + break; + case OB1CS_DF_8K_EF_24K: + eeprom_backup_size = 24U * 0x400U; + break; + case OB1CS_DF_0K_EF_32K: + eeprom_backup_size = 0x00000000U; + break; + case OB1CS_DF_16K_EF_16K: + eeprom_backup_size = 16U * 0x400U; + break; + case OB1CS_DF_24K_EF_8K: + eeprom_backup_size = 8U * 0x400U; + break; + case OB1CS_DF_16K_EF_0K: + eeprom_backup_size = 0x00000000U; + break; + case OB1CS_DF_4K_EF_12K: + eeprom_backup_size = 12U * 0x400U; + break; + case OB1CS_DF_0K_EF_16K: + eeprom_backup_size = 16U * 0x400U; + break; + case OB1CS_DF_8K_EF_8K: + eeprom_backup_size = 8U * 0x400U; + break; + case OB1CS_DF_12K_EF_4K: + eeprom_backup_size = 4U * 0x400U; + break; + default: + break; + } + + return eeprom_backup_size; +} + +/*! + \brief get EEPROM size in byte unit + \param[in] none + \param[out] none + \retval EEPROM byte count +*/ +uint32_t eeprom_size_get(void) +{ + uint32_t epsize_value; + uint32_t eeprom_size = 0U; + + /* get EPSIZE value in option bytes 1 */ + epsize_value = FMC_OB1CS & FMC_OB1CS_EPSIZE; + + switch(epsize_value) { + case OB1CS_EPSIZE_NONE: + eeprom_size = 0x000000000U; + break; + case OB1CS_EPSIZE_4K: + eeprom_size = 4U * 0x400U; + break; + case OB1CS_EPSIZE_2K: + eeprom_size = 2U * 0x400U; + break; + case OB1CS_EPSIZE_1K: + eeprom_size = 0x400U; + break; + default: + break; + } + + return eeprom_size; +} + +/*! + \brief get FMC flag status + \param[in] flag: FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_BANK0_FLAG_BUSY: flash bank0 busy flag + \arg FMC_BANK0_FLAG_PGSERR: flash bank0 program sequence error flag + \arg FMC_BANK0_FLAG_PGERR: flash bank0 program error flag + \arg FMC_BANK0_FLAG_PGAERR: flash bank0 program alignment error flag + \arg FMC_BANK0_FLAG_WPERR: flash bank0 erase/program protection error flag + \arg FMC_BANK0_FLAG_END: flash bank0 end of operation flag + \arg FMC_BANK0_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not flag + \arg FMC_BANK0_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program flag + \arg FMC_BANK1_FLAG_BUSY: flash bank1 busy flag + \arg FMC_BANK1_FLAG_PGSERR: flash bank1 program sequence error flag + \arg FMC_BANK1_FLAG_PGERR: flash bank1 program error flag + \arg FMC_BANK1_FLAG_PGAERR: flash bank1 program alignment error flag + \arg FMC_BANK1_FLAG_WPERR: flash bank1 erase/program protection error flag + \arg FMC_BANK1_FLAG_END: flash bank1 end of operation flag + \arg FMC_BANK1_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not flag + \arg FMC_BANK1_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program flag + \arg FMC_FLAG_BK0ECC: an ECC bit error is detected in bank 0 flag + \arg FMC_FLAG_OB0ECC: an ECC bit error is detected in option byte 0 flag + \arg FMC_FLAG_BK1ECC: an ECC bit error is detected in bank 1 flag + \arg FMC_FLAG_SYSECC: an ECC bit error is detected in system memory flag + \arg FMC_FLAG_DFECC: an ECC bit error is detected in data flash flag + \arg FMC_FLAG_OTPECC: an ECC bit error is detected in OTP flag + \arg FMC_FLAG_OB1ECCDET: option bytes 1 two bit error detect flag + \arg FMC_FLAG_OB0ECCDET: option bytes 0 two bit error detect flag + \arg FMC_FLAG_EPECCDET: EEPROM two bits error detect flag + \arg FMC_FLAG_ECCCOR: one bit error detected and correct flag + \arg FMC_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect flag + \arg FMC_FLAG_OBERR: option bytes 0 error flag + \arg FMC_FLAG_OB1ERR: option bytes 1 read error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(fmc_flag_enum flag) +{ + /* check if an ECC bit error is detected in bank 0 */ + if(FMC_FLAG_BK0ECC == flag) { + if(0U != (FMC_REG_VAL(flag) & ECCCS_ERROR_MASK)) { + return RESET; + } else { + return SET; + } + } else { + /* get other flag */ + if(0U != (FMC_REG_VAL(flag) & BIT(FMC_BIT_POS(flag)))) { + return SET; + } else { + return RESET; + } + } +} + +/*! + \brief clear FMC flag status + \param[in] flag: FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_BANK0_FLAG_PGSERR: flash bank0 program sequence error flag + \arg FMC_BANK0_FLAG_PGERR: flash bank0 program error flag + \arg FMC_BANK0_FLAG_PGAERR: flash bank0 program alignment error flag + \arg FMC_BANK0_FLAG_WPERR: flash bank0 erase/program protection error flag + \arg FMC_BANK0_FLAG_END: flash bank0 end of operation flag + \arg FMC_BANK0_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not flag + \arg FMC_BANK0_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program flag + \arg FMC_BANK1_FLAG_PGSERR: flash bank1 program sequence error flag + \arg FMC_BANK1_FLAG_PGERR: flash bank1 program error flag + \arg FMC_BANK1_FLAG_PGAERR: flash bank1 program alignment error flag + \arg FMC_BANK1_FLAG_WPERR: flash bank1 erase/program protection error flag + \arg FMC_BANK1_FLAG_END: flash bank1 end of operation flag + \arg FMC_BANK1_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not flag + \arg FMC_BANK1_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program flag + \arg FMC_FLAG_OB1ECCDET: option bytes 1 two bit error detect flag + \arg FMC_FLAG_OB0ECCDET: option bytes 0 two bit error detect flag + \arg FMC_FLAG_EPECCDET: EEPROM two bits error detect flag + \arg FMC_FLAG_ECCCOR: one bit error detected and correct flag + \arg FMC_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +void fmc_flag_clear(fmc_flag_enum flag) +{ + uint32_t reg_offset, reg; + + reg_offset = ((uint32_t)(flag) & 0x0000FFFFU) >> 6U; + /* clear the flags in ECCCS register */ + if(ECCCS_REG_OFFSET == reg_offset) { + reg = FMC_REG_VAL(flag); + reg &= ~ECCCS_FLAG_MASK; + reg |= BIT(FMC_BIT_POS(flag)); + FMC_REG_VAL(flag) = reg; + } else { + /* clear the flags in STAT0/STAT1 register */ + FMC_REG_VAL(flag) = BIT(FMC_BIT_POS(flag)); + } +} + +/*! + \brief enable FMC interrupt + \param[in] interrupt: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_BANK0_INT_ERR: FMC bank0 error interrupt + \arg FMC_BANK0_INT_END: FMC bank0 end of operation interrupt + \arg FMC_BANK1_INT_ERR: FMC bank1 error interrupt + \arg FMC_BANK1_INT_END: FMC bank1 end of operation interrupt + \arg FMC_INT_ECCCOR: FMC one bit error correct interrupt + \arg FMC_INT_ECCDET: FMC two bits error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(fmc_interrupt_enum interrupt) +{ + uint32_t reg_offset, reg; + + reg_offset = ((uint32_t)(interrupt) & 0x0000FFFFU) >> 6U; + /* enable interrupt in ECCCS register */ + if(ECCCS_REG_OFFSET == reg_offset) { + reg = FMC_REG_VAL(interrupt); + reg &= ~ECCCS_FLAG_MASK; + reg |= BIT(FMC_BIT_POS(interrupt)); + FMC_REG_VAL(interrupt) = reg; + } else { + /* enable interrupt in CTL0/CTL1 register */ + FMC_REG_VAL(interrupt) |= BIT(FMC_BIT_POS(interrupt)); + } +} + +/*! + \brief disable FMC interrupt + \param[in] interrupt: the FMC interrupt source + only one parameter can be selected which is shown as below: + \arg FMC_BANK0_INT_ERR: FMC bank0 error interrupt + \arg FMC_BANK0_INT_END: FMC bank0 end of operation interrupt + \arg FMC_BANK1_INT_ERR: FMC bank1 error interrupt + \arg FMC_BANK1_INT_END: FMC bank1 end of operation interrupt + \arg FMC_INT_ECCCOR: FMC one bit error correct interrupt + \arg FMC_INT_ECCDET: FMC two bits error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(fmc_interrupt_enum interrupt) +{ + uint32_t reg_offset, reg; + + reg_offset = ((uint32_t)(interrupt) & 0x0000FFFFU) >> 6U; + /* disable interrupt in ECCCS register */ + if(ECCCS_REG_OFFSET == reg_offset) { + reg = FMC_REG_VAL(interrupt); + reg &= ~ECCCS_FLAG_MASK; + reg &= ~BIT(FMC_BIT_POS(interrupt)); + FMC_REG_VAL(interrupt) = reg; + } else { + /* disable interrupt in CTL0/CTL1 register */ + FMC_REG_VAL(interrupt) &= ~BIT(FMC_BIT_POS(interrupt)); + } +} + +/*! + \brief get FMC interrupt flag status + \param[in] flag: FMC interrupt flag + only one parameter can be selected which is shown as below: + \arg FMC_BANK0_INT_FLAG_PGSERR: flash bank0 program sequence error intrrupt flag + \arg FMC_BANK0_INT_FLAG_PGERR: flash bank0 program error intrrupt flag + \arg FMC_BANK0_INT_FLAG_PGAERR: flash bank0 program alignment error intrrupt flag + \arg FMC_BANK0_INT_FLAG_WPERR: flash bank0 erase/program protection error intrrupt flag + \arg FMC_BANK0_INT_FLAG_END: flash bank0 end of operation intrrupt flag + \arg FMC_BANK0_INT_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not intrrupt flag + \arg FMC_BANK0_INT_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program intrrupt flag + \arg FMC_BANK1_INT_FLAG_PGSERR: flash bank1 program sequence error intrrupt flag + \arg FMC_BANK1_INT_FLAG_PGERR: flash bank1 program error intrrupt flag + \arg FMC_BANK1_INT_FLAG_PGAERR: flash bank1 program alignment error intrrupt flag + \arg FMC_BANK1_INT_FLAG_WPERR: flash bank1 erase/program protection error intrrupt flag + \arg FMC_BANK1_INT_FLAG_END: flash bank1 end of operation intrrupt flag + \arg FMC_BANK1_INT_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not intrrupt flag + \arg FMC_BANK1_INT_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program intrrupt flag + \arg FMC_INT_FLAG_OB1ECCDET: option bytes 1 two bit error detect intrrupt flag + \arg FMC_INT_FLAG_OB0ECCDET: option bytes 0 two bit error detect intrrupt flag + \arg FMC_INT_FLAG_EPECCDET: EEPROM two bits error detect intrrupt flag + \arg FMC_INT_FLAG_ECCCOR: one bit error detected and correct intrrupt flag + \arg FMC_INT_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect intrrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_interrupt_flag_get(fmc_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (FMC_REG_VAL(int_flag) & BIT(FMC_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (FMC_REG_VAL2(int_flag) & BIT(FMC_BIT_POS2(int_flag))); + + if(flagstatus && intenable) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear FMC interrupt flag status + \param[in] flag: FMC interrupt flag + only one parameter can be selected which is shown as below: + \arg FMC_BANK0_INT_FLAG_PGSERR: flash bank0 program sequence error intrrupt flag + \arg FMC_BANK0_INT_FLAG_PGERR: flash bank0 program error intrrupt flag + \arg FMC_BANK0_INT_FLAG_PGAERR: flash bank0 program alignment error intrrupt flag + \arg FMC_BANK0_INT_FLAG_WPERR: flash bank0 erase/program protection error intrrupt flag + \arg FMC_BANK0_INT_FLAG_END: flash bank0 end of operation intrrupt flag + \arg FMC_BANK0_INT_FLAG_CBCMDERR: flash bank0 checked area by the check blank command is all 0xFF or not intrrupt flag + \arg FMC_BANK0_INT_FLAG_RSTERR: flash bank0 BOR/POR or system reset during erase/program intrrupt flag + \arg FMC_BANK1_INT_FLAG_PGSERR: flash bank1 program sequence error intrrupt flag + \arg FMC_BANK1_INT_FLAG_PGERR: flash bank1 program error intrrupt flag + \arg FMC_BANK1_INT_FLAG_PGAERR: flash bank1 program alignment error intrrupt flag + \arg FMC_BANK1_INT_FLAG_WPERR: flash bank1 erase/program protection error intrrupt flag + \arg FMC_BANK1_INT_FLAG_END: flash bank1 end of operation intrrupt flag + \arg FMC_BANK1_INT_FLAG_CBCMDERR: flash bank1 checked area by the check blank command is all 0xFF or not intrrupt flag + \arg FMC_BANK1_INT_FLAG_RSTERR: flash bank1 BOR/POR or system reset during erase/program intrrupt flag + \arg FMC_INT_FLAG_OB1ECCDET: option bytes 1 two bit error detect intrrupt flag + \arg FMC_INT_FLAG_OB0ECCDET: option bytes 0 two bit error detect intrrupt flag + \arg FMC_INT_FLAG_EPECCDET: EEPROM two bits error detect intrrupt flag + \arg FMC_INT_FLAG_ECCCOR: one bit error detected and correct intrrupt flag + \arg FMC_INT_FLAG_ECCDET: OTP/data flash/system memory/bank1 two bit error detect intrrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +void fmc_interrupt_flag_clear(fmc_interrupt_flag_enum int_flag) +{ + uint32_t reg_offset, reg; + + reg_offset = (uint32_t)(int_flag) >> 22U; + /* clear the intrrupt flag in ECCCS register */ + if(ECCCS_REG_OFFSET == reg_offset) { + reg = FMC_REG_VAL2(int_flag); + reg &= ~ECCCS_FLAG_MASK; + reg |= BIT(FMC_BIT_POS2(int_flag)); + FMC_REG_VAL2(int_flag) = reg; + } else { + /* clear the intrrupt flag in STAT0/STAT1 register */ + FMC_REG_VAL2(int_flag) = BIT(FMC_BIT_POS2(int_flag)); + } +} + +/*! + \brief get FMC bank0 state + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +static fmc_state_enum fmc_bank0_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_BUSY)) { + fmc_state = FMC_BUSY; + } else { + if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_WPERR)) { + fmc_state = FMC_WPERR; + } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_PGERR)) { + fmc_state = FMC_PGERR; + } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_PGSERR)) { + fmc_state = FMC_PGSERR; + } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_PGAERR)) { + fmc_state = FMC_PGAERR; + } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_CBCMDERR)) { + fmc_state = FMC_CBCMDERR; + } else if((uint32_t)0x00U != (FMC_STAT0 & FMC_STAT0_RSTERR)) { + fmc_state = FMC_RSTERR; + } else { + /* illegal parameters */ + } + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get FMC bank1 state + \param[in] none + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +static fmc_state_enum fmc_bank1_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_BUSY)) { + fmc_state = FMC_BUSY; + } else { + if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_WPERR)) { + fmc_state = FMC_WPERR; + } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_PGERR)) { + fmc_state = FMC_PGERR; + } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_PGSERR)) { + fmc_state = FMC_PGSERR; + } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_PGAERR)) { + fmc_state = FMC_PGAERR; + } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_CBCMDERR)) { + fmc_state = FMC_CBCMDERR; + } else if((uint32_t)0x00U != (FMC_STAT1 & FMC_STAT1_RSTERR)) { + fmc_state = FMC_RSTERR; + } else { + /* illegal parameters */ + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC bank0 is ready or not + \param[in] timeout: timeout count + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +static fmc_state_enum fmc_bank0_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do { + /* get FMC state */ + fmc_state = fmc_bank0_state_get(); + timeout--; + } while((FMC_BUSY == fmc_state) && (0U != timeout)); + + if(FMC_BUSY == fmc_state) { + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC bank1 is ready or not + \param[in] timeout: timeout count + \param[out] none + \retval state of FMC, refer to fmc_state_enum + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGSERR: program sequence error + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_CBCMDERR: the checked area not blank error + \arg FMC_RSTERR: BOR/POR or system reset during flash erase/program error +*/ +static fmc_state_enum fmc_bank1_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do { + /* get FMC state */ + fmc_state = fmc_bank1_state_get(); + timeout--; + } while((FMC_BUSY == fmc_state) && (0U != timeout)); + + if(FMC_BUSY == fmc_state) { + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief wait shared SRAM mode to be ready + \param[in] ready_flag: sram mode ready bit + \arg FMC_WS_ERAMRDY: EEPROM SRAM ready bit + \arg FMC_WS_BRAMRDY: basic SRAM ready bit + \arg FMC_WS_PRAMRDY: fast PG SRAM ready bit + \param[out] none + \retval none +*/ +static void fmc_sram_mode_ready_wait(uint32_t ready_flag) +{ + while(1) { + if(0U != (FMC_WS & ready_flag)) { + break; + } + } +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_fwdgt.c b/gd32a50x/standard_peripheral/source/gd32a50x_fwdgt.c new file mode 100644 index 0000000..d3045c4 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_fwdgt.c @@ -0,0 +1,243 @@ +/*! + \file gd32fxxx_fwdgt.c + \brief FWDGT driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_fwdgt.h" + +/*! + \brief enable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_enable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; +} + +/*! + \brief disable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_disable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE; +} + +/*! + \brief start the FWDGT counter + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the FWDGT counter prescaler value + \param[in] prescaler_value: specify prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = 0U; + + /* enable write access to FWDGT_PSC */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + } while((--timeout > (uint32_t)0) && (0U != flag_status)); + + if(0U != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_value; + + return SUCCESS; +} + +/*! + \brief configure the FWDGT counter reload value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value) +{ + uint32_t timeout = FWDGT_RLD_TIMEOUT; + uint32_t flag_status = 0U; + + /* 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) && (0U != flag_status)); + + if (0U != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + return SUCCESS; +} + +/*! + \brief configure the FWDGT counter window value + \param[in] window_value: specify window value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_window_value_config(uint16_t window_value) +{ + uint32_t time_index = FWDGT_WND_TIMEOUT; + uint32_t flag_status = 0U; + + /* enable write access to FWDGT_WND */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the WUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_WUD; + }while((--time_index > 0U) && (0U != flag_status)); + + if (0U != flag_status){ + return ERROR; + } + + FWDGT_WND = WND_WND(window_value); + + return SUCCESS; +} + +/*! + \brief reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief configure counter reload value, and prescaler divider value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[in] prescaler_div: FWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = 0U; + + /* 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) && (0U != flag_status)); + + if (0U != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && (0U != flag_status)); + + if (0U != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + only one parameter can be selected which is shown as below: + \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going + \arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fwdgt_flag_get(uint16_t flag) +{ + if (0U != (FWDGT_STAT & flag)){ + return SET; + } + return RESET; +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_gpio.c b/gd32a50x/standard_peripheral/source/gd32a50x_gpio.c new file mode 100644 index 0000000..3afdec6 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_gpio.c @@ -0,0 +1,414 @@ +/*! + \file gd32a50x_gpio.c + \brief GPIO driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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 GPIOE: + /* reset GPIOE */ + rcu_periph_reset_enable(RCU_GPIOERST); + rcu_periph_reset_disable(RCU_GPIOERST); + break; + case GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO mode + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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){ + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode); + + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, pull_up_down); + } + } + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +/*! + \brief set GPIO output type and speed + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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_2MHZ: output max speed 2MHz + \arg GPIO_OSPEED_10MHZ: output max speed 10MHz + \arg GPIO_OSPEED_50MHZ: output max speed 50MHz + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin) +{ + uint16_t i; + uint32_t ospeed; + + if(GPIO_OTYPE_OD == otype){ + GPIO_OMODE(gpio_periph) |= (uint32_t)pin; + }else{ + GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin); + } + + /* get the specified pin output speed bits value */ + ospeed = GPIO_OSPD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if(((uint32_t)1U << i) & pin){ + /* clear the specified pin output speed bits */ + ospeed &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeed |= GPIO_OSPEED_SET(i,speed); + } + } + GPIO_OSPD(gpio_periph) = ospeed; +} + +/*! + \brief set GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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; +} + +/*! + \brief reset GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BC(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief write data to the specified GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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; + }else{ + GPIO_BC(gpio_periph) = (uint32_t)pin; + } +} + +/*! + \brief write data to the specified GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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) +{ + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO port input status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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) +{ + if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO port output status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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 + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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: SYSTEM + \arg GPIO_AF_1: TIMER0, TIMER1, TIMER7, TIMER19, TIMER20 + \arg GPIO_AF_2: TIMER0, TIMER1, TIMER7, TIMER19, TIMER20 + \arg GPIO_AF_3: TIMER7, TIMER19, I2C0 + \arg GPIO_AF_4: SPI0, SPI1, I2S1, USART1 + \arg GPIO_AF_5: USART0, USART2, MFCOM, SPI1, I2C1 + \arg GPIO_AF_6: CAN0, CAN1, MFCOM, TRIGSEL + \arg GPIO_AF_7: TRIGSEL, CMP, MFCOM + \arg GPIO_AF_8: + \arg GPIO_AF_9: 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){ + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i,alt_func_num); + } + } + + for(i = 8U;i < 16U;i++){ + if(((uint32_t)1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U,alt_func_num); + } + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} + +/*! + \brief lock GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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; + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + lock = GPIO_LOCK(gpio_periph); + lock = GPIO_LOCK(gpio_periph); +} + +/*! + \brief toggle GPIO pin status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,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; +} + +/*! + \brief toggle GPIO port status + \param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,D,E,F) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_i2c.c b/gd32a50x/standard_peripheral/source/gd32a50x_i2c.c new file mode 100644 index 0000000..22bc8d9 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_i2c.c @@ -0,0 +1,949 @@ +/*! + \file gd32a50x_i2c.c + \brief I2C driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_i2c.h" + +/* I2C register bit mask */ +#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */ +#define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */ + +/* I2C register bit offset */ +#define CTL0_DNF_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of DNF in I2C_CTL0 */ +#define CTL1_BYTENUM_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BYTENUM in I2C_CTL1 */ +#define STAT_READDR_OFFSET ((uint32_t)0x00000011U) /*!< bit offset of READDR in I2C_STAT */ +#define TIMING_SCLL_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of SCLL in I2C_TIMING */ +#define TIMING_SCLH_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of SCLH in I2C_TIMING */ +#define TIMING_SDADELY_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SDADELY in I2C_TIMING */ +#define TIMING_SCLDELY_OFFSET ((uint32_t)0x00000014U) /*!< bit offset of SCLDELY in I2C_TIMING */ +#define TIMING_PSC_OFFSET ((uint32_t)0x0000001CU) /*!< bit offset of PSC in I2C_TIMING */ +#define SADDR1_ADDMSK_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of ADDMSK in I2C_SADDR1 */ +#define TIMEOUT_BUSTOB_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BUSTOB in I2C_TIMEOUT */ + +/*! + \brief reset I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph) { + case I2C0: + /* reset I2C0 */ + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + /* reset I2C1 */ + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; + default: + break; + } +} + +/*! + \brief configure the timing parameters + \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 + \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) +{ + I2C_CTL0(i2c_periph) &= (uint32_t)(~I2C_CTL0_DNF); + I2C_CTL0(i2c_periph) |= (uint32_t)(filter_length << CTL0_DNF_OFFSET); +} + +/*! + \brief enable analog noise filter + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_ANOFF; +} + +/*! + \brief disable analog noise filter + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_analog_noise_filter_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ANOFF; +} + +/*! + \brief configure the SCL high and low period of clock in master mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] sclh: 0-0x000000FF, SCL high period + \param[in] scll: 0-0x000000FF, SCL low period + \param[out] none + \retval none +*/ +void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll) +{ + /* clear SCLH, SCLL bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLH; + I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLL; + /* mask SCLH, SCLL bits in I2C_TIMING register */ + sclh = (uint32_t)(sclh << TIMING_SCLH_OFFSET) & I2C_TIMING_SCLH; + scll = (uint32_t)(scll << TIMING_SCLL_OFFSET) & I2C_TIMING_SCLL; + /* write SCLH, SCLL bits in I2C_TIMING register */ + I2C_TIMING(i2c_periph) |= (sclh | scll); +} + +/*! + \brief configure i2c slave address and transfer direction in master mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] address: 0-0x3FF except reserved address, I2C slave address to be sent + \param[in] trans_direction: I2C transfer direction in master mode + only one parameter can be selected which is shown as below: + \arg I2C_MASTER_TRANSMIT: master transmit + \arg I2C_MASTER_RECEIVE: master receive + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction) +{ + /* configure slave address */ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_SADDRESS; + I2C_CTL1(i2c_periph) |= address; + /* configure transfer direction */ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_TRDIR; + I2C_CTL1(i2c_periph) |= trans_direction; +} + +/*! + \brief 10-bit address header executes read direction only in master receive mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_header_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_HEAD10R; +} + +/*! + \brief 10-bit address header executes complete sequence in master receive mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_header_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_HEAD10R; +} + +/*! + \brief enable 10-bit addressing mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_ADD10EN; +} + +/*! + \brief disable 10-bit addressing mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address10_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_ADD10EN; +} + +/*! + \brief enable I2C automatic end mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_automatic_end_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_AUTOEND; +} + +/*! + \brief disable I2C automatic end mode in master mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_automatic_end_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_AUTOEND; +} + +/*! + \brief enable the response to a general call + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_GCEN; +} + +/*! + \brief disable the response to a general call + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_GCEN; +} + +/*! + \brief enable to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SS; +} + +/*! + \brief disable to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SS; +} + +/*! + \brief configure i2c slave address + \param[in] i2c_periph: I2Cx(x=0,1) + \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; + I2C_SADDR0(i2c_periph) = (addr_format | address); + /* enable i2c address in slave mode */ + I2C_SADDR0(i2c_periph) |= I2C_SADDR0_ADDRESSEN; +} + +/*! + \brief define which bits of ADDRESS[7:1] need to compare with the incoming address byte + \param[in] i2c_periph: I2Cx(x=0,1) + \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) +{ + I2C_CTL2(i2c_periph) &= ~I2C_CTL2_ADDM; + I2C_CTL2(i2c_periph) |= compare_bits; +} + +/*! + \brief disable i2c address in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_address_disable(uint32_t i2c_periph) +{ + I2C_SADDR0(i2c_periph) &= ~I2C_SADDR0_ADDRESSEN; +} + +/*! + \brief configure i2c second slave address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] address: I2C address + \param[in] addr_mask: the bits not need to compare + one or more 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] */ + address = address & I2C_ADDRESS2_MASK; + I2C_SADDR1(i2c_periph) |= address; + /* configure ADDRESS2[7:1] mask */ + I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDMSK2; + I2C_SADDR1(i2c_periph) |= (uint32_t)(addr_mask << SADDR1_ADDMSK_OFFSET); + /* enable i2c second address in slave mode */ + I2C_SADDR1(i2c_periph) |= I2C_SADDR1_ADDRESS2EN; +} + +/*! + \brief disable i2c second address in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_second_address_disable(uint32_t i2c_periph) +{ + I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDRESS2EN; +} + +/*! + \brief get received match address in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval received match address +*/ +uint32_t i2c_recevied_address_get(uint32_t i2c_periph) +{ + return (uint32_t)((I2C_STAT(i2c_periph) & I2C_STAT_READDR) >> STAT_READDR_OFFSET); +} + +/*! + \brief enable slave byte control + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_slave_byte_control_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SBCTL; +} + +/*! + \brief disable slave byte control + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_slave_byte_control_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SBCTL; +} + +/*! + \brief generate a NACK in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_nack_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_NACKEN; +} + +/*! + \brief generate an ACK in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_nack_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_NACKEN; +} + +/*! + \brief enable I2C + \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 + \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 + \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 + \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 + \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, uint32_t data) +{ + I2C_TDATA(i2c_periph) = (I2C_TDATA_TDATA & data); +} + +/*! + \brief I2C receive data + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval received data +*/ +uint32_t i2c_data_receive(uint32_t i2c_periph) +{ + return (I2C_RDATA(i2c_periph) & I2C_RDATA_RDATA); +} + +/*! + \brief enable I2C reload mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_reload_enable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_RELOAD; +} + +/*! + \brief disable I2C reload mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_reload_disable(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) &= ~I2C_CTL1_RELOAD; +} + +/*! + \brief configure number of bytes to be transferred + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] byte_number: 0x0-0xFF, number of bytes to be transferred + \param[out] none + \retval none +*/ +void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint32_t byte_number) +{ + I2C_CTL1(i2c_periph) &= (uint32_t)(~I2C_CTL1_BYTENUM); + I2C_CTL1(i2c_periph) |= (uint32_t)(byte_number << CTL1_BYTENUM_OFFSET); +} + +/*! + \brief enable I2C DMA for transmission or reception + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dma: I2C DMA + only one parameter can be selected which is shown as below: + \arg I2C_DMA_TRANSMIT: transmit data using DMA + \arg I2C_DMA_RECEIVE: receive data using DMA + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma) +{ + if(I2C_DMA_TRANSMIT == dma) { + I2C_CTL0(i2c_periph) |= I2C_CTL0_DENT; + } else { + I2C_CTL0(i2c_periph) |= I2C_CTL0_DENR; + } +} + +/*! + \brief disable I2C DMA for transmission or reception + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dma: I2C DMA + only one parameter can be selected which is shown as below: + \arg I2C_DMA_TRANSMIT: transmit data using DMA + \arg I2C_DMA_RECEIVE: receive data using DMA + \param[out] none + \retval none +*/ +void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma) +{ + if(I2C_DMA_TRANSMIT == dma) { + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENT; + } else { + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENR; + } +} + +/*! + \brief I2C transfers PEC value + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_pec_transfer(uint32_t i2c_periph) +{ + I2C_CTL1(i2c_periph) |= I2C_CTL1_PECTRANS; +} + +/*! + \brief enable I2C PEC calculation + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_pec_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_PECEN; +} + +/*! + \brief disable I2C PEC calculation + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_pec_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_PECEN; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1) + \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 + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_smbus_alert_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBALTEN; +} + +/*! + \brief disable SMBus alert + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_smbus_alert_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBALTEN; +} + +/*! + \brief enable SMBus device default address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_smbus_default_addr_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBDAEN; +} + +/*! + \brief disable SMBus device default address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_smbus_default_addr_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBDAEN; +} + +/*! + \brief enable SMBus Host address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_smbus_host_addr_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBHAEN; +} + +/*! + \brief disable SMBus Host address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] none + \param[out] none + \retval none +*/ +void i2c_smbus_host_addr_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBHAEN; +} + +/*! + \brief enable extended clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_extented_clock_timeout_enable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_EXTOEN; +} + +/*! + \brief disable extended clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_extented_clock_timeout_disable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_EXTOEN; +} + +/*! + \brief enable clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_clock_timeout_enable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_TOEN; +} + +/*! + \brief disable clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_clock_timeout_disable(uint32_t i2c_periph) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOEN; +} + +/*! + \brief configure bus timeout B + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] timeout: bus timeout B + \param[out] none + \retval none +*/ +void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOB; + I2C_TIMEOUT(i2c_periph) |= (uint32_t)(timeout << TIMEOUT_BUSTOB_OFFSET); +} + +/*! + \brief configure bus timeout A + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] timeout: bus timeout A + \param[out] none + \retval none +*/ +void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOA; + I2C_TIMEOUT(i2c_periph) |= timeout; +} + +/*! + \brief configure idle clock timeout detection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] timeout: bus timeout A + \arg BUSTOA_DETECT_SCL_LOW: BUSTOA is used to detect SCL low timeout + \arg BUSTOA_DETECT_IDLE: BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle + \param[out] none + \retval none +*/ +void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout) +{ + I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOIDLE; + I2C_TIMEOUT(i2c_periph) |= timeout; +} + +/*! + \brief get I2C flag status + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] flag: I2C flags + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_TBE: I2C_TDATA is empty during transmitting + \arg I2C_FLAG_TI: transmit interrupt + \arg I2C_FLAG_RBNE: I2C_RDATA is not empty during receiving + \arg I2C_FLAG_ADDSEND: address received matches in slave mode + \arg I2C_FLAG_NACK: not acknowledge flag + \arg I2C_FLAG_STPDET: STOP condition detected in slave mode + \arg I2C_FLAG_TC: transfer complete in master mode + \arg I2C_FLAG_TCR: transfer complete reload + \arg I2C_FLAG_BERR: bus error + \arg I2C_FLAG_LOSTARB: arbitration Lost + \arg I2C_FLAG_OUERR: overrun/underrun error in slave mode + \arg I2C_FLAG_PECERR: PEC error + \arg I2C_FLAG_TIMEOUT: timeout flag + \arg I2C_FLAG_SMBALT: SMBus Alert + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver in slave mode + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag) +{ + if(0U != (I2C_STAT(i2c_periph) & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear I2C flag status + \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; +} + +/*! + \brief enable I2C interrupt + \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; +} + +/*! + \brief disable I2C interrupt + \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; +} + +/*! + \brief get I2C interrupt flag status + \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) +{ + uint32_t ret1 = 0U; + uint32_t ret2 = 0U; + + /* get the status of interrupt enable bit */ + ret1 = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag))); + /* get the status of interrupt flag */ + ret2 = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag))); + if(ret1 && ret2) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear I2C interrupt flag status + \param[in] i2c_periph: I2Cx(x=0,1) + \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/gd32a50x/standard_peripheral/source/gd32a50x_mfcom.c b/gd32a50x/standard_peripheral/source/gd32a50x_mfcom.c new file mode 100644 index 0000000..29e5e81 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_mfcom.c @@ -0,0 +1,772 @@ +/*! + \file gd32a50x_mfcom.c + \brief MFCOM driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50X +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_mfcom.h" + +/*! + \brief reset MFCOM + \param[in] none + \param[out] none + \retval none +*/ +void mfcom_deinit(void) +{ + /* reset MFCOM */ + rcu_periph_reset_enable(RCU_MFCOMRST); + rcu_periph_reset_disable(RCU_MFCOMRST); +} + +/*! + \brief software reset + \param[in] none + \param[out] none + \retval none +*/ +void mfcom_software_reset(void) +{ + MFCOM_CTL |= MFCOM_CTL_SWRSTEN; + MFCOM_CTL &= ~MFCOM_CTL_SWRSTEN; +} + + +/*! + \brief enable MFCOM function + \param[in] none + \param[out] none + \retval none +*/ +void mfcom_enable(void) +{ + MFCOM_CTL |= MFCOM_CTL_MFCOMEN; +} + +/*! + \brief disable MFCOM function + \param[in] none + \param[out] none + \retval none +*/ +void mfcom_disable(void) +{ + MFCOM_CTL &= ~MFCOM_CTL_MFCOMEN; +} + +/*! + \brief initialize mfcom_timer_parameter_struct with the default values + \param[in] init_struct: the initialization timer parameter need + \param[out] none + \retval none +*/ +void mfcom_timer_struct_para_init(mfcom_timer_parameter_struct* init_struct) +{ + /* set the mfcom_timer_parameter_struct with the default values */ + init_struct->trigger_select = MFCOM_TIMER_TRGSEL_PIN0; + init_struct->trigger_polarity = MFCOM_TIMER_TRGPOL_ACTIVE_HIGH; + init_struct->pin_config = MFCOM_TIMER_PINCFG_INPUT; + init_struct->pin_select = MFCOM_TIMER_PINSEL_PIN0; + init_struct->pin_polarity = MFCOM_TIMER_PINPOL_ACTIVE_HIGH; + init_struct->mode = MFCOM_TIMER_DISABLE; + init_struct->output = MFCOM_TIMER_OUT_HIGH_EN; + init_struct->decrement = MFCOM_TIMER_DEC_CLK_SHIFT_OUT; + init_struct->reset = MFCOM_TIMER_RESET_NEVER; + init_struct->disable = MFCOM_TIMER_DISMODE_NEVER; + init_struct->enable = MFCOM_TIMER_ENMODE_ALWAYS; + init_struct->stopbit = MFCOM_TIMER_STOPBIT_DISABLE; + init_struct->startbit = MFCOM_TIMER_STARTBIT_DISABLE; + init_struct->compare = 0U; +} + +/*! + \brief initialize mfcom_shifter_parameter_struct with the default values + \param[in] init_struct: the initialization shifter parameter need + \param[out] none + \retval none +*/ +void mfcom_shifter_struct_para_init(mfcom_shifter_parameter_struct* init_struct) +{ + /* set the mfcom_shifter_parameter_struct with the default values */ + init_struct->timer_select = MFCOM_SHIFTER_TIMER0; + init_struct->timer_polarity = MFCOM_SHIFTER_TIMPOL_ACTIVE_HIGH; + init_struct->pin_config = MFCOM_SHIFTER_PINCFG_INPUT; + init_struct->pin_select = MFCOM_SHIFTER_PINSEL_PIN0; + init_struct->pin_polarity = MFCOM_SHIFTER_PINPOL_ACTIVE_HIGH; + init_struct->mode = MFCOM_SHIFTER_DISABLE; + init_struct->input_source = MFCOM_SHIFTER_INSRC_PIN; + init_struct->stopbit = MFCOM_SHIFTER_STOPBIT_DISABLE; + init_struct->startbit = MFCOM_SHIFTER_STARTBIT_DISABLE; +} + +/*! + \brief initialize MFCOM timer parameter + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[in] init_struct: the initialization timer parameter need + \arg trigger_select: MFCOM_TIMER_TRGSEL_PIN0 MFCOM_TIMER_TRGSEL_SHIFTER0 + MFCOM_TIMER_TRGSEL_PIN1 MFCOM_TIMER_TRGSEL_TIMER0 + MFCOM_TIMER_TRGSEL_PIN2 MFCOM_TIMER_TRGSEL_SHIFTER1 + MFCOM_TIMER_TRGSEL_PIN3 MFCOM_TIMER_TRGSEL_TIMER1 + MFCOM_TIMER_TRGSEL_PIN4 MFCOM_TIMER_TRGSEL_SHIFTER2 + MFCOM_TIMER_TRGSEL_PIN5 MFCOM_TIMER_TRGSEL_TIMER2 + MFCOM_TIMER_TRGSEL_PIN6 MFCOM_TIMER_TRGSEL_SHIFTER3 + MFCOM_TIMER_TRGSEL_PIN7 MFCOM_TIMER_TRGSEL_TIMER3 + MFCOM_TIMER_TRGSEL_EXTERNAL0 MFCOM_TIMER_TRGSEL_EXTERNAL1 + MFCOM_TIMER_TRGSEL_EXTERNAL2 MFCOM_TIMER_TRGSEL_EXTERNAL3 + + trigger_polarity: MFCOM_TIMER_TRGPOL_ACTIVE_HIGH + MFCOM_TIMER_TRGPOL_ACTIVE_LOW + + pin_config: MFCOM_TIMER_PINCFG_INPUT MFCOM_TIMER_PINCFG_OPENDRAIN + MFCOM_TIMER_PINCFG_BIDI MFCOM_TIMER_PINCFG_OUTPUT + + pin_select: MFCOM_TIMER_PINSEL_PIN0 MFCOM_TIMER_PINSEL_PIN1 + MFCOM_TIMER_PINSEL_PIN2 MFCOM_TIMER_PINSEL_PIN3 + MFCOM_TIMER_PINSEL_PIN4 MFCOM_TIMER_PINSEL_PIN5 + MFCOM_TIMER_PINSEL_PIN6 MFCOM_TIMER_PINSEL_PIN7 + + pin_polarity: MFCOM_TIMER_PINPOL_ACTIVE_HIGH + MFCOM_TIMER_PINPOL_ACTIVE_LOW + + mode: MFCOM_TIMER_DISABLE MFCOM_TIMER_BAUDMODE + MFCOM_TIMER_PWMMODE MFCOM_TIMER_16BITCOUNTER + + output: MFCOM_TIMER_OUT_HIGH_EN MFCOM_TIMER_OUT_LOW_EN + MFCOM_TIMER_OUT_HIGH_EN_RESET MFCOM_TIMER_OUT_LOW_EN_RESET + + decrement: MFCOM_TIMER_DEC_CLK_SHIFT_OUT MFCOM_TIMER_DEC_TRIG_SHIFT_OUT + MFCOM_TIMER_DEC_PIN_SHIFT_PIN MFCOM_TIMER_DEC_TRIG_SHIFT_TRIG + + reset: MFCOM_TIMER_RESET_NEVER MFCOM_TIMER_RESET_PIN_TIMOUT + MFCOM_TIMER_RESET_TRIG_TIMOUT MFCOM_TIMER_RESET_PIN_RISING + MFCOM_TIMER_RESET_TRIG_RISING MFCOM_TIMER_RESET_TRIG_BOTH + + disable: MFCOM_TIMER_DISMODE_NEVER MFCOM_TIMER_DISMODE_PRE_TIMDIS + MFCOM_TIMER_DISMODE_COMPARE MFCOM_TIMER_DISMODE_COMPARE_TRIGLOW + MFCOM_TIMER_DISMODE_PINBOTH MFCOM_TIMER_DISMODE_PINBOTH_TRIGHIGH + MFCOM_TIMER_DISMODE_TRIGFALLING + + enable: MFCOM_TIMER_ENMODE_ALWAYS MFCOM_TIMER_ENMODE_PRE_TIMEN + MFCOM_TIMER_ENMODE_TRIGHIGH MFCOM_TIMER_ENMODE_TRIGHIGH_PINHIGH + MFCOM_TIMER_ENMODE_PINRISING MFCOM_TIMER_ENMODE_PINRISING_TRIGHIGH + MFCOM_TIMER_ENMODE_TRIGRISING MFCOM_TIMER_ENMODE_TRIGBOTH + + stopbit: MFCOM_TIMER_STOPBIT_DISABLE MFCOM_TIMER_STOPBIT_TIMCMP + MFCOM_TIMER_STOPBIT_TIMDIS MFCOM_TIMER_STOPBIT_TIMCMP_TIMDIS + + startbit: MFCOM_TIMER_STARTBIT_DISABLE + MFCOM_TIMER_STARTBIT_ENABLE + + compare: compare value + \param[out] none + \retval none +*/ +void mfcom_timer_init(uint32_t timer, mfcom_timer_parameter_struct* init_struct) +{ + /* configure compare value */ + MFCOM_TMCMP(timer) = (uint32_t)init_struct->compare; + /* configure timer output/decrement/reset/disable/enable/stopbit/startbit */ + MFCOM_TMCFG(timer) = init_struct->output | init_struct->decrement | init_struct->reset | init_struct->disable | init_struct->enable | init_struct->stopbit | init_struct->startbit; + + /* configure pin trigger_select/trigger_polarity/pin_config/pin_select/pin_polarity/mode */ + MFCOM_TMCTL(timer) = init_struct->trigger_select | init_struct->trigger_polarity | init_struct->pin_config | init_struct->pin_select | init_struct->pin_polarity | init_struct->mode; +} + +/*! + \brief initialize MFCOM shifter parameter + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[in] init_struct: the initialization shifter parameter need + \arg timer_select: MFCOM_SHIFTER_TIMER0 MFCOM_SHIFTER_TIMER1 + MFCOM_SHIFTER_TIMER2 MFCOM_SHIFTER_TIMER3 + + timer_polarity: MFCOM_SHIFTER_TIMPOL_ACTIVE_HIGH + MFCOM_SHIFTER_TIMPOL_ACTIVE_LOW + + pin_config: MFCOM_SHIFTER_PINCFG_INPUT MFCOM_SHIFTER_PINCFG_OPENDRAIN + MFCOM_SHIFTER_PINCFG_BIDI MFCOM_SHIFTER_PINCFG_OUTPUT + + pin_select: MFCOM_SHIFTER_PINSEL_PIN0 MFCOM_SHIFTER_PINSEL_PIN1 + MFCOM_SHIFTER_PINSEL_PIN2 MFCOM_SHIFTER_PINSEL_PIN3 + MFCOM_SHIFTER_PINSEL_PIN4 MFCOM_SHIFTER_PINSEL_PIN5 + MFCOM_SHIFTER_PINSEL_PIN6 MFCOM_SHIFTER_PINSEL_PIN7 + + pin_polarity: MFCOM_SHIFTER_PINPOL_ACTIVE_HIGH + MFCOM_SHIFTER_PINPOL_ACTIVE_LOW + + mode: MFCOM_SHIFTER_DISABLE MFCOM_SHIFTER_RECEIVE + MFCOM_SHIFTER_TRANSMIT MFCOM_SHIFTER_MATCH_STORE + MFCOM_SHIFTER_MATCH_CONTINUOUS + + input_source: MFCOM_SHIFTER_INSRC_PIN + MFCOM_SHIFTER_INSRC_NEXTSHIFTER + + stopbit: MFCOM_SHIFTER_STOPBIT_DISABLE MFCOM_SHIFTER_STOPBIT_LOW + MFCOM_SHIFTER_STOPBIT_HIGH + + startbit: MFCOM_SHIFTER_STARTBIT_DISABLE MFCOM_SHIFTER_STARTBIT_DISABLE_TXEN + MFCOM_SHIFTER_STARTBIT_LOW MFCOM_SHIFTER_STARTBIT_HIGH + \param[out] none + \retval none +*/ +void mfcom_shifter_init(uint32_t shifter, mfcom_shifter_parameter_struct* init_struct) +{ + /* configure shifter input_source/stopbit/startbit */ + MFCOM_SCFG(shifter) = init_struct->input_source | init_struct->stopbit | init_struct->startbit; + + /* configure shifter timer_select/timer_polarity/pin_config/pin_select/pin_polarity/mode */ + MFCOM_SCTL(shifter) = init_struct->timer_select | init_struct->timer_polarity | init_struct->pin_config | init_struct->pin_select | init_struct->pin_polarity | init_struct->mode; +} + +/*! + \brief configure timer pin mode + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[in] outputmode: + \arg MFCOM_TIMER_PINCFG_INPUT: pin input + \arg MFCOM_TIMER_PINCFG_OPENDRAIN: pin open drain or bidirectional output enable + \arg MFCOM_TIMER_PINCFG_BIDI: pin bidirectional output data + \arg MFCOM_TIMER_PINCFG_OUTPUT: pin output + \param[out] none + \retval none +*/ +void mfcom_timer_pin_config(uint32_t timer, uint32_t mode) +{ + uint32_t temp; + temp = MFCOM_TMCTL(timer); + + /* clear timer pin configuration bits */ + temp &= ~MFCOM_TMCTL_TMPCFG; + + /* set timer pin outputmode */ + temp |= mode; + MFCOM_TMCTL(timer) = temp; +} + +/*! + \brief configure shifter pin mode + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[in] outputmode: + \arg MFCOM_SHIFTER_PINCFG_INPUT: pin input + \arg MFCOM_SHIFTER_PINCFG_OPENDRAIN: pin open drain or bidirectional output enable + \arg MFCOM_SHIFTER_PINCFG_BIDI: pin bidirectional output data + \arg MFCOM_SHIFTER_PINCFG_OUTPUT: pin output + \param[out] none + \retval none +*/ +void mfcom_shifter_pin_config(uint32_t shifter, uint32_t mode) +{ + uint32_t temp; + temp = MFCOM_SCTL(shifter); + + /* clear shifter pin configuration bits */ + temp &= ~MFCOM_SCTL_SPCFG; + + /* set shifter pin outputmode */ + temp |= mode; + MFCOM_SCTL(shifter) = temp; +} + +/*! + \brief enable MFCOM timer in specific mode + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[in] timermode: + \arg MFCOM_TIMER_DISABLE: timer disabled + \arg MFCOM_TIMER_BAUDMODE: dual 8-bit counters baud/bit mode + \arg MFCOM_TIMER_PWMMODE: dual 8-bit counters PWM mode + \arg MFCOM_TIMER_16BITCOUNTER: single 16-bit counter mode + \param[out] none + \retval none +*/ +void mfcom_timer_enable(uint32_t timer, uint32_t timermode) +{ + uint32_t temp; + temp = MFCOM_TMCTL(timer); + + /* clear timer mode bits */ + temp &= ~MFCOM_TMCTL_TMMOD; + + /* set timer mode */ + temp |= timermode; + MFCOM_TMCTL(timer) = temp; +} + +/*! + \brief enable MFCOM shifter in specific mode + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[in] shiftermode: + \arg MFCOM_SHIFTER_DISABLE: shifter is disabled + \arg MFCOM_SHIFTER_RECEIVE: receive mode + \arg MFCOM_SHIFTER_TRANSMIT: transmit mode + \arg MFCOM_SHIFTER_MATCH_STORE: match store mode + \arg MFCOM_SHIFTER_MATCH_CONTINUOUS: match continuous mode + \param[out] none + \retval none +*/ +void mfcom_shifter_enable(uint32_t shifter, uint32_t shiftermode) +{ + uint32_t temp; + temp = MFCOM_SCTL(shifter); + + /* clear shifter mode bits */ + temp &= ~MFCOM_SCTL_SMOD; + + /* set shifter mode */ + temp |= shiftermode; + MFCOM_SCTL(shifter) = temp; +} + +/*! + \brief disable MFCOM timer + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_timer_disable(uint32_t timer) +{ + MFCOM_TMCTL(timer) &= ~MFCOM_TMCTL_TMMOD; +} + +/*! + \brief disable MFCOM shifter + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_disable(uint32_t shifter) +{ + MFCOM_SCTL(shifter) &= ~MFCOM_SCTL_SMOD; +} + +/*! + \brief set MFCOM timer compare value + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[in] compare: timer compare value + \param[out] none + \retval none +*/ +void mfcom_timer_cmpvalue_set(uint32_t timer, uint32_t compare) +{ + MFCOM_TMCMP(timer) = compare; +} + +/*! + \brief get MFCOM timer compare value + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[out] timer compare value + \retval none +*/ +uint32_t mfcom_timer_cmpvalue_get(uint32_t timer) +{ + return MFCOM_TMCMP(timer); +} + +/*! + \brief set MFCOM timer disable mode + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[in] dismode: configure conditions that can disable timers and stop decrement. + \arg MFCOM_TIMER_DISMODE_NEVER: timer never disabled + \arg MFCOM_TIMER_DISMODE_PRE_TIMDIS: timer disabled on timer x-1 disable + \arg MFCOM_TIMER_DISMODE_COMPARE: timer disabled on timer compare + \arg MFCOM_TIMER_DISMODE_COMPARE_TRIGLOW: timer disabled on timer compare and trigger Low + \arg MFCOM_TIMER_DISMODE_PINBOTH: timer disabled on pin rising or falling edge + \arg MFCOM_TIMER_DISMODE_PINBOTH_TRIGHIGH timer disabled on pin rising or falling edge provided trigger is high + \arg MFCOM_TIMER_DISMODE_TRIGFALLING timer disabled on trigger falling edge + \param[out] none + \retval none +*/ +void mfcom_timer_dismode_set(uint32_t timer, uint32_t dismode) +{ + uint32_t temp; + temp = MFCOM_TMCFG(timer); + + /* clear timer disable bits */ + temp &= ~MFCOM_TMCFG_TMDIS; + + /* set timer disable mode */ + temp |= dismode; + MFCOM_TMCFG(timer) = temp; +} + +/*! + \brief set MFCOM shifter stopbit + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[in] stopbit: shifter stop bit + \arg MFCOM_SHIFTER_STOPBIT_DISABLE: disable shifter stop bit + \arg MFCOM_SHIFTER_STOPBIT_LOW: set shifter stop bit to logic low level + \arg MFCOM_SHIFTER_STOPBIT_HIGH: set shifter stop bit to logic high level + \param[out] none + \retval none +*/ +void mfcom_shifter_stopbit_set(uint32_t shifter, uint32_t stopbit) +{ + uint32_t temp; + temp = MFCOM_SCFG(shifter); + + /* clear shifter stop bit */ + temp &= ~MFCOM_SCFG_SSTOP; + + /* set shifter stop bit */ + temp |= stopbit; + MFCOM_SCFG(shifter) = temp; +} + +/*! + \brief write MFCOM shifter buffer + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[in] data: 32-bit data + \param[in] rwmode: MFCOM read write mode + \arg MFCOM_RWMODE_NORMAL: read and write in normal mode + \arg MFCOM_RWMODE_BITSWAP: read and write in bit swapped mode + \arg MFCOM_RWMODE_BYTESWAP: read and write in byte swapped mode + \arg MFCOM_RWMODE_BITBYTESWAP: read and write in bit byte swapped mode + \param[out] none + \retval none +*/ +void mfcom_buffer_write(uint32_t shifter, uint32_t data, uint32_t rwmode) +{ + switch (rwmode){ + case MFCOM_RWMODE_NORMAL: + /* write MFCOM shift buffer in MFCOM_RWMODE_NORMAL mode */ + MFCOM_SBUF(shifter) = data; + break; + case MFCOM_RWMODE_BITSWAP: + /* write MFCOM shift buffer in MFCOM_RWMODE_BITSWAP mode */ + MFCOM_SBUFBIS(shifter) = data; + break; + case MFCOM_RWMODE_BYTESWAP: + /* write MFCOM shift buffer in MFCOM_RWMODE_BYTESWAP mode */ + MFCOM_SBUFBYS(shifter) = data; + break; + case MFCOM_RWMODE_BITBYTESWAP: + /* write MFCOM shift buffer in MFCOM_RWMODE_BITBYTESWAP mode */ + MFCOM_SBUFBBS(shifter) = data; + break; + default: + break; + } +} + +/*! + \brief read MFCOM shifter buffer + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[in] rwmode: MFCOM read write mode + \arg MFCOM_RWMODE_NORMAL: read and write in normal mode + \arg MFCOM_RWMODE_BITSWAP: read and write in bit swapped mode + \arg MFCOM_RWMODE_BYTESWAP: read and write in byte swapped mode + \arg MFCOM_RWMODE_BITBYTESWAP: read and write in bit byte swapped mode + \param[out] none + \retval data: 32-bit data +*/ +uint32_t mfcom_buffer_read(uint32_t shifter, uint32_t rwmode) +{ + uint32_t data; + switch (rwmode){ + case MFCOM_RWMODE_NORMAL: + /* read MFCOM shift buffer in MFCOM_RWMODE_NORMAL mode */ + data = MFCOM_SBUF(shifter); + break; + case MFCOM_RWMODE_BITSWAP: + /* read MFCOM shift buffer in MFCOM_RWMODE_BITSWAP mode */ + data = MFCOM_SBUFBIS(shifter); + break; + case MFCOM_RWMODE_BYTESWAP: + /* read MFCOM shift buffer in MFCOM_RWMODE_BYTESWAP mode */ + data = MFCOM_SBUFBYS(shifter); + break; + case MFCOM_RWMODE_BITBYTESWAP: + /* read MFCOM shift buffer in MFCOM_RWMODE_BITBYTESWAP mode */ + data = MFCOM_SBUFBBS(shifter); + break; + default: + data = 0U; + break; + } + return data; +} + +/*! + \brief get MFCOM shifter flag + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mfcom_shifter_flag_get(uint32_t shifter) +{ + if(0U != (MFCOM_SSTAT & ((uint32_t)1U << shifter))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get MFCOM shifter error flag + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mfcom_shifter_error_flag_get(uint32_t shifter) +{ + if(0U != (MFCOM_SERR & ((uint32_t)1U << shifter))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get MFCOM timer flag + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mfcom_timer_flag_get(uint32_t timer) +{ + if(0U != (MFCOM_TMSTAT & ((uint32_t)1U << timer))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get MFCOM shifter interrupt flag + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mfcom_shifter_interrupt_flag_get(uint32_t shifter) +{ + uint32_t interrupt_flag, interrupt_enable; + + interrupt_flag = MFCOM_SSTAT & ((uint32_t)1U << shifter); + interrupt_enable = MFCOM_SSIEN & ((uint32_t)1U << shifter); + + /* judge shifter interrupt flag state */ + if(interrupt_flag & interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get MFCOM shifter error interrupt flag + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mfcom_shifter_error_interrupt_flag_get(uint32_t shifter) +{ + uint32_t interrupt_flag, interrupt_enable; + + interrupt_flag = MFCOM_SERR & ((uint32_t)1U << shifter); + interrupt_enable = MFCOM_SEIEN & ((uint32_t)1U << shifter); + + /* judge shifter error interrupt flag state */ + if(interrupt_flag & interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get MFCOM timer interrupt flag + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus mfcom_timer_interrupt_flag_get(uint32_t timer) +{ + uint32_t interrupt_flag, interrupt_enable; + + interrupt_flag = MFCOM_TMSTAT & ((uint32_t)1U << timer); + interrupt_enable = MFCOM_TMSIEN & ((uint32_t)1U << timer); + + /* judge timer interrupt flag state */ + if(interrupt_flag & interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear MFCOM shifter flag + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_flag_clear(uint32_t shifter) +{ + MFCOM_SSTAT = ((uint32_t)1U << shifter); +} + +/*! + \brief clear MFCOM shifter error flag + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_error_flag_clear(uint32_t shifter) +{ + MFCOM_SERR = ((uint32_t)1U << shifter); +} + +/*! + \brief clear MFCOM timer flag + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_timer_flag_clear(uint32_t timer) +{ + MFCOM_TMSTAT = ((uint32_t)1U << timer); +} + +/*! + \brief enable MFCOM shifter interrupt + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_interrupt_enable(uint32_t shifter) +{ + MFCOM_SSIEN |= ((uint32_t)1U << shifter); +} + +/*! + \brief enable MFCOM shifter error interrupt + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_error_interrupt_enable(uint32_t shifter) +{ + MFCOM_SEIEN |= ((uint32_t)1U << shifter); +} + +/*! + \brief enable MFCOM timer interrupt + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_timer_interrupt_enable(uint32_t timer) +{ + MFCOM_TMSIEN |= ((uint32_t)1U << timer); +} + +/*! + \brief enable MFCOM shifter dma + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_dma_enable(uint32_t shifter) +{ + MFCOM_SSDMAEN |= ((uint32_t)1U << shifter); +} + +/*! + \brief disable MFCOM shifter interrupt + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_interrupt_disable(uint32_t shifter) +{ + MFCOM_SSIEN &= ~((uint32_t)1U << shifter); +} + +/*! + \brief disable MFCOM shifter error interrupt + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_error_interrupt_disable(uint32_t shifter) +{ + MFCOM_SEIEN &= ~((uint32_t)1U << shifter); +} + +/*! + \brief disable MFCOM timer interrupt + \param[in] timer: MFCOM timer number + \arg MFCOM_TIMER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_timer_interrupt_disable(uint32_t timer) +{ + MFCOM_TMSIEN &= ~((uint32_t)1U << timer); +} + +/*! + \brief disable MFCOM shifter dma + \param[in] shifter: MFCOM shifter number + \arg MFCOM_SHIFTER_x(x=0..3) + \param[out] none + \retval none +*/ +void mfcom_shifter_dma_disable(uint32_t shifter) +{ + MFCOM_SSDMAEN &= ~((uint32_t)1U << shifter); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_misc.c b/gd32a50x/standard_peripheral/source/gd32a50x_misc.c new file mode 100644 index 0000000..84298d0 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_misc.c @@ -0,0 +1,183 @@ +/*! + \file gd32a50x_misc.c + \brief MISC driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_misc.h" + +/*! + \brief set the priority group + \param[in] nvic_prigroup: the NVIC priority group + \arg NVIC_PRIGROUP_PRE0_SUB4:0 bits for pre-emption priority 4 bits for subpriority + \arg NVIC_PRIGROUP_PRE1_SUB3:1 bits for pre-emption priority 3 bits for subpriority + \arg NVIC_PRIGROUP_PRE2_SUB2:2 bits for pre-emption priority 2 bits for subpriority + \arg NVIC_PRIGROUP_PRE3_SUB1:3 bits for pre-emption priority 1 bits for subpriority + \arg NVIC_PRIGROUP_PRE4_SUB0:4 bits for pre-emption priority 0 bits for subpriority + \param[out] none + \retval none +*/ +void nvic_priority_group_set(uint32_t nvic_prigroup) +{ + /* set the priority group value */ + SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup; +} + +/*! + \brief enable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[in] nvic_irq_pre_priority: the pre-emption priority needed to set + \param[in] nvic_irq_sub_priority: the subpriority needed to set + \param[out] none + \retval none +*/ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, + uint8_t nvic_irq_sub_priority) +{ + uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U; + /* use the priority group value to get the temp_pre and the temp_sub */ + if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE0_SUB4){ + temp_pre=0U; + temp_sub=0x4U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE1_SUB3){ + temp_pre=1U; + temp_sub=0x3U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE2_SUB2){ + temp_pre=2U; + temp_sub=0x2U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE3_SUB1){ + temp_pre=3U; + temp_sub=0x1U; + }else if(((SCB->AIRCR) & (uint32_t)0x700U)==NVIC_PRIGROUP_PRE4_SUB0){ + temp_pre=4U; + temp_sub=0x0U; + }else{ + nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); + temp_pre=2U; + temp_sub=0x2U; + } + /* get the temp_priority to fill the NVIC->IP register */ + temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre); + temp_priority |= (uint32_t)nvic_irq_sub_priority &((uint32_t)0x0FU >> (0x4U - temp_sub)); + temp_priority = temp_priority << 0x04U; + NVIC->IPR[nvic_irq] = (uint8_t)temp_priority; + /* enable the selected IRQ */ + NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU); +} + +/*! + \brief disable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(IRQn_Type nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC_DisableIRQ(nvic_irq); +} + +/*! + \brief initiates a system reset request to reset the MCU + \param[in] none + \param[out] none + \retval none +*/ +void nvic_system_reset(void) +{ + NVIC_SystemReset(); +} + +/*! + \brief set the NVIC vector table base address + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \are NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: Vector Table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); + __DSB(); +} + +/*! + \brief set the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up + by all the enable and disable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_set(uint8_t lowpower_mode) +{ + SCB->SCR |= (uint32_t)lowpower_mode; +} + +/*! + \brief reset the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be + woke up by the enable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_reset(uint8_t lowpower_mode) +{ + SCB->SCR &= (~(uint32_t)lowpower_mode); +} + +/*! + \brief set the systick clock source + \param[in] systick_clksource: the systick clock source needed to choose + \arg SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK + \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8 + \param[out] none + \retval none +*/ +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){ + /* set the systick clock source from HCLK */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + }else{ + /* set the systick clock source from HCLK/8 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; + } +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_pmu.c b/gd32a50x/standard_peripheral/source/gd32a50x_pmu.c new file mode 100644 index 0000000..c40340c --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_pmu.c @@ -0,0 +1,375 @@ +/*! + \file gd32a50x_pmu.c + \brief PMU driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_pmu.h" + +/*! + \brief reset PMU register + \param[in] none + \param[out] none + \retval none +*/ +void pmu_deinit(void) +{ + /* reset PMU */ + rcu_periph_reset_enable(RCU_PMURST); + rcu_periph_reset_disable(RCU_PMURST); +} + +/*! + \brief select low voltage detector threshold + \param[in] lvdt_n: + only one parameter can be selected which is shown as below: + \arg PMU_LVDT_0: voltage threshold is 2.9V + \arg PMU_LVDT_1: voltage threshold is 3.1V + \arg PMU_LVDT_2: voltage threshold is 3.3V + \arg PMU_LVDT_3: voltage threshold is 3.5V + \arg PMU_LVDT_4: voltage threshold is 4.0V + \arg PMU_LVDT_5: voltage threshold is 4.2V + \arg PMU_LVDT_6: voltage threshold is 4.4V + \arg PMU_LVDT_7: voltage threshold is 4.6V + \param[out] none + \retval none +*/ +void pmu_lvd_select(uint32_t lvdt_n) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; + /* clear LVDT bits */ + PMU_CTL &= ~PMU_CTL_LVDT; + /* set LVDT bits according to lvdt_n */ + PMU_CTL |= lvdt_n; + /* enable LVD */ + PMU_CTL |= PMU_CTL_LVDEN; +} + +/*! + \brief disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief select over voltage detector threshold + \param[in] ovdt_n: + only one parameter can be selected which is shown as below: + \arg PMU_OVDT_0: voltage threshold is 5.0V + \arg PMU_OVDT_1: voltage threshold is 5.5V + \param[out] none + \retval none +*/ +void pmu_ovd_select(uint32_t ovdt_n) +{ + /* disable OVD */ + PMU_CTL &= ~PMU_CTL_OVDEN; + /* clear OVDT bits */ + PMU_CTL &= ~PMU_CTL_OVDT; + /* set OVDT bits according to ovdt_n */ + PMU_CTL |= ovdt_n; + /* enable OVD */ + PMU_CTL |= PMU_CTL_OVDEN; +} + +/*! + \brief disable PMU ovd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_ovd_disable(void) +{ + /* disable OVD */ + PMU_CTL &= ~PMU_CTL_OVDEN; +} + +/*! + \brief enable low-driver mode in deep-sleep mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lowdriver_mode_enable(void) +{ + PMU_CTL |= PMU_CTL_LDEN; +} + +/*! + \brief disable low-driver mode in deep-sleep mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lowdriver_mode_disable(void) +{ + PMU_CTL &= ~PMU_CTL_LDEN; +} + +/*! + \brief SRAM1 power off in deep-sleep mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_sram1_poweroff_mode_enable(void) +{ + PMU_CTL |= PMU_CTL_SRAMSW1; +} + +/*! + \brief SRAM1 power on in deep-sleep mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_sram1_poweroff_mode_disable(void) +{ + PMU_CTL &= ~PMU_CTL_SRAMSW1; +} + +/*! + \brief SRAM2 power off in deep-sleep mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_sram2_poweroff_mode_enable(void) +{ + PMU_CTL |= PMU_CTL_SRAMSW2; +} + +/*! + \brief SRAM2 power on in deep-sleep mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_sram2_poweroff_mode_disable(void) +{ + PMU_CTL &= ~PMU_CTL_SRAMSW2; +} + +/*! + \brief PMU work in sleep mode + \param[in] sleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M33 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 deepsleep mode + \param[in] ldo: + only one parameter can be selected which is shown as below: + \arg PMU_LDO_NORMAL: LDO work in normal power mode when pmu enter deepsleep mode + \arg PMU_LDO_LOWPOWER: LDO work in low power mode when pmu enter deepsleep mode + \param[in] lowdrive: + only one parameter can be selected which is shown as below: + \arg PMU_LOWDRIVER_ENABLE: low-driver mode enable in deep-sleep mode + \arg PMU_LOWDRIVER_DISABLE: low-driver mode disable in deep-sleep mode + \param[in] deepsleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint32_t ldo, uint32_t lowdrive, uint8_t deepsleepmodecmd) +{ + /* flash goto sleep mode when MCU enters deepsleep mode */ + REG32(0x40022000) |= (uint32_t)(1<<14); + + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP | PMU_CTL_LDEN)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= (ldo | lowdrive); + + /* set sleepdeep bit of Cortex-M33 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd) { + __WFI(); + } else { + __SEV(); + __WFE(); + __WFE(); + } + + /* reset sleepdeep bit of Cortex-M33 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief pmu work in standby mode + \param[in] none + \param[out] none + \retval none +*/ +void pmu_to_standbymode(void) +{ + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* set sleepdeep bit of Cortex-M33 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + REG32(0xE000E010U) &= 0x00010004U; + REG32(0xE000E180U) = 0XFFFFFFF7U; + REG32(0xE000E184U) = 0XFFFFFFFFU; + REG32(0xE000E188U) = 0xFFFFFFFFU; + + /* select WFI or WFE command to enter standby mode */ + __WFI(); +} + +/*! + \brief enable wakeup pin + \param[in] 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) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin) +{ + PMU_CS |= wakeup_pin; +} + +/*! + \brief disable wakeup pin + \param[in] 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) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin) +{ + PMU_CS &= ~(wakeup_pin); +} + +/*! + \brief enable write access to the registers in backup domain + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief disable write access to the registers in backup domain + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief get flag state + \param[in] flag: + 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_LVD: lvd flag + \arg PMU_FLAG_OVD: ovd flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag) +{ + if(0U != (PMU_CS & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear flag bit + \param[in] flag: + only one parameter can be selected which is shown as below: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag) +{ + switch(flag) { + case PMU_FLAG_RESET_WAKEUP: + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + break; + case PMU_FLAG_RESET_STANDBY: + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + break; + default: + break; + } +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_rcu.c b/gd32a50x/standard_peripheral/source/gd32a50x_rcu.c new file mode 100644 index 0000000..b4fa5be --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_rcu.c @@ -0,0 +1,1151 @@ +/*! + \file gd32a50x_rcu.c + \brief RCU driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_rcu.h" + +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0x000FFFFFU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x03FFFFFFU) + +/* RCU IRC8M adjust value mask and offset*/ +#define RCU_IRC8M_ADJUST_MASK ((uint8_t)0x1FU) +#define RCU_IRC8M_ADJUST_OFFSET ((uint32_t)3U) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC8M */ + RCU_CTL |= RCU_CTL_IRC8MEN; + if(ERROR == rcu_osci_stab_wait(RCU_IRC8M)) { + while(1) { + } + } + + RCU_CFG0 &= ~RCU_CFG0_SCS; + while((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_IRC8M) { + } + /* reset CTL register */ + RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN | RCU_CTL_HXTALSCAL | RCU_CTL_LCKMEN | RCU_CTL_PLLMEN); + RCU_CTL &= ~RCU_CTL_HXTALBPS; + /* reset CFG0 register */ + RCU_CFG0 = 0x00020000U; + /* reset INT and CFG1 and CFG2 register */ + RCU_INT = 0x00FF0000U; + RCU_CFG1 = 0x00000000U; + RCU_CFG2 = 0x00000000U; +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_DMAMUX: DMAMUX clock + \arg RCU_CRC: CRC clock + \arg RCU_GPIOx (x=A,B,C,D,E,F): GPIO ports clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_CMP: CMP clock + \arg RCU_ADCx (x=0,1): ADCx clock + \arg RCU_TIMERx (x=0,1,5,6,7,19,20): TIMER clock + \arg RCU_SPIx (x=0,1): SPIx clock + \arg RCU_USARTx (x=0,1,2): USARTx clock + \arg RCU_MFCOM: MFCOM clock + \arg RCU_TRIGSEL: TRIGSEL clock + \arg RCU_CANx (x=0,1): CANx clock + \arg RCU_I2Cx (x=0,1): I2Cx clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_BKP: BKP clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC 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 + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_DMAx (x=0,1): DMA clock + \arg RCU_DMAMUX: DMAMUX clock + \arg RCU_CRC: CRC clock + \arg RCU_GPIOx (x=A,B,C,D,E,F): GPIO ports clock + \arg RCU_SYSCFG: SYSCFG clock + \arg RCU_CMP: CMP clock + \arg RCU_ADCx (x=0,1): ADCx clock + \arg RCU_TIMERx (x=0,1,5,6,7,19,20): TIMER clock + \arg RCU_SPIx (x=0,1): SPIx clock + \arg RCU_USARTx (x=0,1,2): USARTx clock + \arg RCU_MFCOM: MFCOM clock + \arg RCU_TRIGSEL: TRIGSEL clock + \arg RCU_CANx (x=0,1): CANx clock + \arg RCU_I2Cx (x=0,1): I2Cx clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_BKP: BKP clock + \arg RCU_PMU: PMU clock + \arg RCU_DAC: DAC 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 reset the peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_DMAxRST (x=0,1): DMA reset enable + \arg RCU_DMAMUXRST: DMAMUX reset enable + \arg RCU_MFCOMRST: MFCOM reset enable + \arg RCU_CRCRST: CRC reset enable + \arg RCU_GPIOxRST (x=A,B,C,D,E,F): GPIO ports reset enable + \arg RCU_SYSCFGRST: SYSCFG reset enable + \arg RCU_CMPRST: CMP reset enable + \arg RCU_ADCxRST (x=0,1): ADCx reset enable + \arg RCU_TIMERxRST (x=0,1,5,6,7,19,20): TIMER reset enable + \arg RCU_SPIxRST (x=0,1): SPIx reset enable + \arg RCU_USARTxRST (x=0,1,2): USARTx reset enable + \arg RCU_CANxRST (x=0,1): CANx reset enable + \arg RCU_I2CxRST(x=0,1): I2Cx reset enable + \arg RCU_WWDGTRST: WWDGT reset enable + \arg RCU_PMURST: PMU reset enable + \arg RCU_DACRST: DAC reset enable + \param[out] none + \retval none +*/ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief disable reset the peripheral + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_DMAxRST (x=0,1): DMA reset enable + \arg RCU_DMAMUXRST: DMAMUX reset enable + \arg RCU_MFCOMRST: MFCOM reset enable + \arg RCU_CRCRST: CRC reset enable + \arg RCU_GPIOxRST (x=A,B,C,D,E,F): GPIO ports reset enable + \arg RCU_SYSCFGRST: SYSCFG reset enable + \arg RCU_CMPRST: CMP reset enable + \arg RCU_ADCxRST (x=0,1): ADCx reset enable + \arg RCU_TIMERxRST (x=0,1,5,6,7,19,20): TIMER reset enable + \arg RCU_SPIxRST (x=0,1): SPIx reset enable + \arg RCU_USARTxRST (x=0,1,2): USARTx reset enable + \arg RCU_CANxRST (x=0,1): CANx reset enable + \arg RCU_I2CxRST(x=0,1): I2Cx reset enable + \arg RCU_WWDGTRST: WWDGT reset enable + \arg RCU_PMURST: PMU reset enable + \arg RCU_DACRST: DAC reset enable + \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 enable the peripherals clock when in sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM 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 in sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM 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 BKP domain control register + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP domain control register reset + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_disable(void) +{ + RCU_BDCTL &= ~RCU_BDCTL_BKPRST; +} + +/*! + \brief configure the system clock source + \param[in] ck_sys: system clock source select + only one parameter can be selected which is shown as below: + \arg RCU_CKSYSSRC_IRC8M: select CK_IRC8M as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_PLL: select CK_PLL as the CK_SYS source + \param[out] none + \retval none +*/ +void rcu_system_clock_source_config(uint32_t ck_sys) +{ + uint32_t reg; + reg = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + reg &= ~RCU_CFG0_SCS; + RCU_CFG0 = (reg | ck_sys); +} + +/*! + \brief get the system clock source + \param[in] none + \param[out] none + \retval which clock is selected as CK_SYS source + \arg RCU_SCSS_IRC8M: CK_IRC8M is selected as the CK_SYS source + \arg RCU_SCSS_HXTAL: CK_HXTAL is selected as the CK_SYS source + \arg RCU_SCSS_PLL: CK_PLL is selected as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & RCU_CFG0_SCSS); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512 + \param[out] none + \retval none +*/ +void rcu_ahb_clock_config(uint32_t ck_ahb) +{ + uint32_t reg; + reg = RCU_CFG0; + /* reset the AHBPSC bits and set according to ck_ahb */ + reg &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (reg | ck_ahb); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1 + \arg RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1 + \param[out] none + \retval none +*/ +void rcu_apb1_clock_config(uint32_t ck_apb1) +{ + uint32_t reg; + reg = RCU_CFG0; + /* reset the APB1PSC and set according to ck_apb1 */ + reg &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (reg | ck_apb1); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2 + \arg RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2 + \param[out] none + \retval none +*/ +void rcu_apb2_clock_config(uint32_t ck_apb2) +{ + uint32_t reg; + reg = RCU_CFG0; + /* reset the APB2PSC and set according to ck_apb2 */ + reg &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (reg | ck_apb2); +} + +/*! + \brief configure the CK_OUT clock source + \param[in] ckout0_src: CK_OUT clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUTSRC_NONE: no clock selected + \arg RCU_CKOUTSRC_IRC40K£ºIRC40K selected + \arg RCU_CKOUTSRC_LXTAL£º LXTAL selected + \arg RCU_CKOUTSRC_CKSYS: system clock selected + \arg RCU_CKOUTSRC_IRC8M: high speed 8M internal oscillator clock selected + \arg RCU_CKOUTSRC_HXTAL: HXTAL selected + \arg RCU_CKOUTSRC_CKPLL_DIV1: CK_PLL selected + \arg RCU_CKOUTSRC_CKPLL_DIV2: CK_PLL/2 selected + \param[in] ckout_div: CK_OUT divider + \arg RCU_CKOUT_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div) +{ + uint32_t ckout = 0U; + ckout = RCU_CFG0; + /* reset the CKOUTSEL, CKOUTDIV and PLLDV bits and set according to ckout_src and ckout_div */ + ckout &= ~(RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); + RCU_CFG0 = (ckout | ckout_src | ckout_div); +} + +/*! + \brief configure the PLL clock source selection and PLL multiply factor + \param[in] pll_src: PLL clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PLLSRC_IRC8M_DIV2: select CK_IRC8M/2 as PLL source clock + \arg RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock + \param[in] pll_mul: PLL multiply factor + only one parameter can be selected which is shown as below: + \arg RCU_PLL_MULx(x=2..32): PLL source clock * x + \param[out] none + \retval none +*/ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul) +{ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); + RCU_CFG0 |= (pll_src | pll_mul); +} + +/*! + \brief enable double PLL clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_double_pll_enable(void) +{ + RCU_CFG0 &= ~RCU_CFG0_DPLL; +} + +/*! + \brief disable double PLL clock + \param[in] none + \param[out] none + \retval none +*/ +void rcu_double_pll_disable(void) +{ + RCU_CFG0 |= RCU_CFG0_DPLL; +} + +/*! + \brief enable RCU system reset + \param[in] reset_source: reset source + one or more parameters can be selected which is shown as below: + \arg RCU_SYSRST_LOCKUP: CPU lock-up reset + \arg RCU_SYSRST_LVD: low voltage detection reset + \arg RCU_SYSRST_ECC: ECC 2 bits error reset + \arg RCU_SYSRST_LOH: lost of HXTAL reset + \arg RCU_SYSRST_LOP: lost of PLL reset + \param[out] none + \retval none +*/ +void rcu_system_reset_enable(uint32_t reset_source) +{ + RCU_RSTSCK |= reset_source; +} + +/*! + \brief disable RCU system reset + \param[in] reset_source: reset source + one or more parameters can be selected which is shown as below: + \arg RCU_SYSRST_LOCKUP: CPU lock-up reset + \arg RCU_SYSRST_LVD: low voltage detection reset + \arg RCU_SYSRST_ECC: ECC 2 bits error reset + \arg RCU_SYSRST_LOH: lost of HXTAL reset + \arg RCU_SYSRST_LOP: lost of PLL reset + \param[out] none + \retval none +*/ +void rcu_system_reset_disable(uint32_t reset_source) +{ + RCU_RSTSCK &= ~reset_source; +} + +/*! + \brief configure the ADC prescaler factor + \param[in] adc_psc: ADC prescaler factor + only one parameter can be selected which is shown as below: + \arg RCU_CKADC_CKAHB_DIVx (x=2,3,...,32): ADC prescaler select CK_AHB/(x) + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(uint32_t adc_psc) +{ + uint32_t reg; + /* reset the ADCPSC bits */ + reg = RCU_CFG2; + reg &= ~RCU_CFG2_ADCPSC; + /* set the ADC prescaler factor */ + reg |= adc_psc & RCU_CFG2_ADCPSC; + /* set the register */ + RCU_CFG2 = reg; +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_RTCSRC_NONE: no clock selected + \arg RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock + \arg RCU_RTCSRC_IRC40K: CK_IRC40K selected as RTC source clock + \arg RCU_RTCSRC_HXTAL_DIV_128: CK_HXTAL/128 selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + uint32_t reg; + reg = RCU_BDCTL; + /* reset the RTCSRC bits and set according to rtc_clock_source */ + reg &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL = (reg | rtc_clock_source); +} + +/*! + \brief configure the USART clock source selection + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] usart_clock_source: USART clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_USARTSRC_HXTAL: HXTAL clock selected as USART source clock + \arg RCU_USARTSRC_CKSYS: system clock selected as USART source clock + \arg RCU_USARTSRC_LXTAL: LXTAL clock selected as USART source clock + \arg RCU_USARTSRC_IRC8M: IRC8M clock selected as USART source clock + \param[out] none + \retval none +*/ +void rcu_usart_clock_config(uint32_t usart_periph, uint32_t usart_clock_source) +{ + uint32_t reg; + reg = RCU_CFG2; + switch(usart_periph) { + case USART0: + /* reset the USART0SEL bit and set according to usart_clock_source */ + reg &= ~RCU_CFG2_USART0SEL; + RCU_CFG2 = (reg | usart_clock_source); + break; + case USART1: + /* reset the USART1SEL bit and set according to usart_clock_source */ + reg &= ~RCU_CFG2_USART1SEL; + RCU_CFG2 = (reg | (uint32_t)(usart_clock_source << 4U)); + break; + case USART2: + /* reset the USART2SEL bit and set according to usart_clock_source */ + reg &= ~RCU_CFG2_USART2SEL; + RCU_CFG2 = (reg | (uint32_t)(usart_clock_source << 6U)); + break; + default: + break; + } +} + +/*! + \brief configure the CAN clock source selection + \param[in] can_periph: CANx(x=0,1) + \param[in] can_clock_source: CAN clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CANSRC_HXTAL: HXTAL clock selected as CAN source clock + \arg RCU_CANSRC_PCLK2: PCLK2 clock selected as CAN source clock + \arg RCU_CANSRC_PCLK2_DIV_2: PCLK2/2 clock selected as CAN source clock + \arg RCU_CANSRC_IRC8M: IRC8M clock selected as CAN source clock + \param[out] none + \retval none +*/ +void rcu_can_clock_config(uint32_t can_periph, uint32_t can_clock_source) +{ + uint32_t reg; + reg = RCU_CFG2; + switch(can_periph) { + case CAN0: + /* reset the CAN0SEL bits and set according to can_clock_source */ + reg &= ~RCU_CFG2_CAN0SEL; + RCU_CFG2 = (reg | can_clock_source); + break; + case CAN1: + /* reset the CAN1SEL bits and set according to can_clock_source */ + reg &= ~RCU_CFG2_CAN1SEL; + RCU_CFG2 = (reg | (uint32_t)(can_clock_source << 2U)); + break; + default: + break; + } +} + +/*! + \brief configure the LXTAL drive capability + \param[in] lxtal_dricap: drive capability of LXTAL + only one parameter can be selected which is shown as below: + \arg RCU_LXTAL_LOWDRI: lower driving capability + \arg RCU_LXTAL_MED_LOWDRI: medium low driving capability + \arg RCU_LXTAL_MED_HIGHDRI: medium high driving capability + \arg RCU_LXTAL_HIGHDRI: higher driving capability + \param[out] none + \retval none +*/ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap) +{ + uint32_t reg; + reg = RCU_BDCTL; + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + reg &= ~RCU_BDCTL_LXTALDRI; + RCU_BDCTL = (reg | lxtal_dricap); +} + +/*! + \brief wait for oscillator stabilization flags is SET or oscillator startup is timeout + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M) + \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K) + \arg RCU_PLL_CK: phase locked loop(PLL) + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + + switch(osci) { + /* wait HXTAL stable */ + case RCU_HXTAL: + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + /* check whether flag is set 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 IRC8M stable */ + case RCU_IRC8M: + while((RESET == osci_stat) && (IRC8M_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_IRC8MSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC8MSTB)) { + reval = SUCCESS; + } + break; + /* wait IRC40K stable */ + case RCU_IRC40K: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_IRC40KSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC40KSTB)) { + reval = SUCCESS; + } + break; + /* wait PLL stable */ + case RCU_PLL_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)) { + osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)) { + reval = SUCCESS; + } + break; + default: + break; + } + /* return value */ + return reval; +} + +/*! + \brief turn on the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M) + \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K) + \arg RCU_PLL_CK: phase locked loop(PLL) + \param[out] none + \retval none +*/ +void rcu_osci_on(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief turn off the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \arg RCU_IRC8M: internal 8M RC oscillators(IRC8M) + \arg RCU_IRC40K: internal 40K RC oscillator(IRC40K) + \arg RCU_PLL_CK: phase locked loop(PLL) + \param[out] none + \retval none +*/ +void rcu_osci_off(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + + switch(osci) { + /* enable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg | RCU_CTL_HXTALBPS); + break; + /* enable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: high speed crystal oscillator(HXTAL) + \arg RCU_LXTAL: low speed crystal oscillator(LXTAL) + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + + switch(osci) { + /* disable HXTAL to bypass mode */ + case RCU_HXTAL: + reg = RCU_CTL; + RCU_CTL &= ~RCU_CTL_HXTALEN; + RCU_CTL = (reg & ~RCU_CTL_HXTALBPS); + break; + /* disable LXTAL to bypass mode */ + case RCU_LXTAL: + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg & ~RCU_BDCTL_LXTALBPS); + break; + default: + break; + } +} + +/*! + \brief HXTAL frequency scale select + \param[in] hxtal_scal: HXTAL frequency scale + only one parameter can be selected which is shown as below: + \arg HXTAL_SCALE_2M_TO_8M: HXTAL scale is 2-8MHz + \arg HXTAL_SCALE_8M_TO_40M: HXTAL scale is 8-40MHz + \param[out] none + \retval none +*/ +void rcu_hxtal_frequency_scale_select(uint32_t hxtal_scal) +{ + if(HXTAL_SCALE_2M_TO_8M == hxtal_scal) { + RCU_CTL &= ~RCU_CTL_HXTALSCAL; + } else { + RCU_CTL |= RCU_CTL_HXTALSCAL; + } +} + +/*! + \brief configure the HXTAL divider used as input of PLL + \param[in] hxtal_prediv: HXTAL previous PLL + only one parameter can be selected which is shown as below: + \arg RCU_PREDV_DIVx(x=1..16): HXTAL divided x used as input of PLL + \param[out] none + \retval none +*/ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv) +{ + uint32_t prediv = 0U; + prediv = RCU_CFG1; + /* reset the PREDV bits and set according to hxtal_prediv */ + prediv &= ~RCU_CFG1_PREDV; + RCU_CFG1 = (prediv | hxtal_prediv); +} + +/*! + \brief set the IRC8M adjust value + \param[in] irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F + \arg 0x00 - 0x1F + \param[out] none + \retval none +*/ +void rcu_irc8m_adjust_value_set(uint32_t irc8m_adjval) +{ + uint32_t reg; + reg = RCU_CTL; + /* reset the IRC8MADJ bits and set according to irc8m_adjval */ + reg &= ~RCU_CTL_IRC8MADJ; + RCU_CTL = (reg | ((irc8m_adjval & RCU_IRC8M_ADJUST_MASK) << RCU_IRC8M_ADJUST_OFFSET)); +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL |= RCU_CTL_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL &= ~RCU_CTL_CKMEN; +} + +/*! + \brief enable the LXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_clock_monitor_enable(void) +{ + RCU_CTL |= RCU_CTL_LCKMEN; +} + +/*! + \brief disable the LXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_lxtal_clock_monitor_disable(void) +{ + RCU_CTL &= ~RCU_CTL_LCKMEN; +} + +/*! + \brief enable the PLL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_pll_clock_monitor_enable(void) +{ + RCU_CTL |= RCU_CTL_PLLMEN; +} + +/*! + \brief disable the PLL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_pll_clock_monitor_disable(void) +{ + RCU_CTL &= ~RCU_CTL_PLLMEN; +} + +/*! + \brief unlock the voltage key + \param[in] none + \param[out] none + \retval none +*/ +void rcu_voltage_key_unlock(void) +{ + /* reset the KEY bits and set 0x1A2B3C4D */ + RCU_VKEY = ~RCU_VKEY_KEY; + RCU_VKEY = RCU_VKEY_UNLOCK; +} + +/*! + \brief deep-sleep mode voltage select + \param[in] dsvol: deep sleep mode voltage + only one parameter can be selected which is shown as below: + \arg RCU_DEEPSLEEP_V_0_8: the core voltage is 0.8V + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V + \arg RCU_DEEPSLEEP_V_1_1: the core voltage is 1.1V + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + /* reset the DSLPVS bits and set according to dsvol */ + RCU_DSV &= ~RCU_DSV_DSLPVS; + RCU_DSV |= dsvol; +} + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + only one parameter can be selected which is shown as below: + \arg CK_SYS: system clock frequency + \arg CK_AHB: AHB clock frequency + \arg CK_APB1: APB1 clock frequency + \arg CK_APB2: APB2 clock frequency + \arg CK_USART0: USART0 clock frequency + \arg CK_USART1: USART1 clock frequency + \arg CK_USART2: USART2 clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2, USART +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws, ck_freq = 0U; + uint32_t cksys_freq, ahb_freq, apb1_freq, apb2_freq; + uint32_t usart_freq = 0U; + uint32_t pllsel, pllmf, ck_src, idx, clk_exp; + uint32_t predv0; + + /* exponent of AHB, APB1 and APB2 clock divider */ + uint8_t ahb_exp[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + uint8_t apb1_exp[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + uint8_t apb2_exp[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + + sws = RCU_CFG0 & RCU_CFG0_SCSS; + switch(sws) { + /* IRC8M is selected as CK_SYS */ + case RCU_SCSS_IRC8M: + cksys_freq = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case RCU_SCSS_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case RCU_SCSS_PLL: + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL); + if(RCU_PLLSRC_HXTAL == pllsel) { + /* PLL clock source is HXTAL */ + ck_src = HXTAL_VALUE; + predv0 = (RCU_CFG1 & RCU_CFG1_PREDV) + 1U; + ck_src /= predv0; + } else { + /* PLL clock source is IRC8M/2 */ + ck_src = IRC8M_VALUE / 2U; + } + /* PLL multiplication factor */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf += ((RCU_CFG0 & RCU_CFG0_PLLMF_4) ? 15U : 0U); + pllmf += ((0xFU == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); + cksys_freq = ck_src * pllmf; + break; + /* IRC8M is selected as CK_SYS */ + default: + cksys_freq = IRC8M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + ahb_freq = cksys_freq >> clk_exp; + /* calculate APB1 clock frequency */ + idx = GET_BITS(RCU_CFG0, 8, 10); + clk_exp = apb1_exp[idx]; + apb1_freq = ahb_freq >> clk_exp; + /* calculate APB2 clock frequency */ + idx = GET_BITS(RCU_CFG0, 11, 13); + clk_exp = apb2_exp[idx]; + apb2_freq = ahb_freq >> clk_exp; + /* return the clocks frequency */ + switch(clock) { + case CK_SYS: + ck_freq = cksys_freq; + break; + case CK_AHB: + ck_freq = ahb_freq; + break; + case CK_APB1: + ck_freq = apb1_freq; + break; + case CK_APB2: + ck_freq = apb2_freq; + break; + case CK_USART0: + /* calculate USART0 clock frequency */ + if(RCU_USARTSRC_HXTAL == (RCU_CFG2 & RCU_CFG2_USART0SEL)) { + usart_freq = HXTAL_VALUE; + } else if(RCU_USARTSRC_CKSYS == (RCU_CFG2 & RCU_CFG2_USART0SEL)) { + usart_freq = cksys_freq; + } else if(RCU_USARTSRC_LXTAL == (RCU_CFG2 & RCU_CFG2_USART0SEL)) { + usart_freq = LXTAL_VALUE; + } else if(RCU_USARTSRC_IRC8M == (RCU_CFG2 & RCU_CFG2_USART0SEL)) { + usart_freq = IRC8M_VALUE; + } else { + } + ck_freq = usart_freq; + break; + case CK_USART1: + /* calculate USART1 clock frequency */ + if(RCU_USARTSRC_HXTAL == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART1SEL) >> 4U)) { + usart_freq = HXTAL_VALUE; + } else if(RCU_USARTSRC_CKSYS == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART1SEL) >> 4U)) { + usart_freq = cksys_freq; + } else if(RCU_USARTSRC_LXTAL == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART1SEL) >> 4U)) { + usart_freq = LXTAL_VALUE; + } else if(RCU_USARTSRC_IRC8M == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART1SEL) >> 4U)) { + usart_freq = IRC8M_VALUE; + } else { + } + ck_freq = usart_freq; + break; + case CK_USART2: + /* calculate USART2 clock frequency */ + if(RCU_USARTSRC_HXTAL == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART2SEL) >> 6U)) { + usart_freq = HXTAL_VALUE; + } else if(RCU_USARTSRC_CKSYS == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART2SEL) >> 6U)) { + usart_freq = cksys_freq; + } else if(RCU_USARTSRC_LXTAL == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART2SEL) >> 6U)) { + usart_freq = LXTAL_VALUE; + } else if(RCU_USARTSRC_IRC8M == (uint32_t)((uint32_t)(RCU_CFG2 & RCU_CFG2_USART2SEL) >> 6U)) { + usart_freq = IRC8M_VALUE; + } else { + } + ck_freq = usart_freq; + break; + default: + break; + } + return ck_freq; +} + +/*! + \brief get the clock stabilization and peripheral reset flags + \param[in] flag: the clock stabilization and peripheral reset flags, refer to rcu_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_FLAG_IRC8MSTB: IRC8M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC40KSTB: IRC40K stabilization flag + \arg RCU_FLAG_BORRST: BOR reset flag + \arg RCU_FLAG_LOCKUPRST: CPU LOCK UP error reset flag + \arg RCU_FLAG_LVDRST: low voltage detect error reset flag + \arg RCU_FLAG_ECCRST: 2 bits ECC error reset flag + \arg RCU_FLAG_LOHRST: lost of HXTAL error reset flag + \arg RCU_FLAG_LOPRST: lost of PLL error reset flag + \arg RCU_FLAG_V11RST: 1.1V domain Power reset flag + \arg RCU_FLAG_OBLRST: option byte loader reset flag + \arg RCU_FLAG_EPRST: external PIN reset flags + \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 + \param[out] none + \retval none +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + /* get the rcu flag */ + if(0U != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear all the reset flag + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief get the clock stabilization interrupt and ckm flags + \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB: IRC40K stabilization interrupt flag + \arg RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC8MSTB: IRC8M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag + \arg RCU_INT_FLAG_LCKM: LXTAL clock monitor interrupt flag + \arg RCU_INT_FLAG_PLLM: PLL clock monitor 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) +{ + /* get the rcu interrupt flag */ + if(0U != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB_CLR: IRC40K stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC8MSTB_CLR: IRC8M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear + \arg RCU_INT_FLAG_LCKM_CLR: LXTAL clock monitor interrupt flag clear + \arg RCU_INT_FLAG_PLLM_CLR: PLL clock monitor interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: HXTAL clock monitor interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag) +{ + RCU_REG_VAL(int_flag) |= BIT(RCU_BIT_POS(int_flag)); +} + +/*! + \brief enable the stabilization interrupt + \param[in] interrupt clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt + \arg RCU_INT_PLLSTB: PLL stabilization interrupt + \arg RCU_INT_LCKM: LXTAL clock monitor interrupt + \arg RCU_INT_PLLM: PLL clock monitor interrupt + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum interrupt) +{ + RCU_REG_VAL(interrupt) |= BIT(RCU_BIT_POS(interrupt)); +} + +/*! + \brief disable the stabilization interrupt + \param[in] interrupt clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt + \arg RCU_INT_PLLSTB: PLL stabilization interrupt + \arg RCU_INT_LCKM: LXTAL clock monitor interrupt + \arg RCU_INT_PLLM: PLL clock monitor interrupt + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum interrupt) +{ + RCU_REG_VAL(interrupt) &= ~BIT(RCU_BIT_POS(interrupt)); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_rtc.c b/gd32a50x/standard_peripheral/source/gd32a50x_rtc.c new file mode 100644 index 0000000..254ce9a --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_rtc.c @@ -0,0 +1,260 @@ +/*! + \file gd32a50x_rtc.c + \brief RTC driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_rtc.h" + +/*! + \brief enter RTC configuration mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_configuration_mode_enter(void) +{ + RTC_CTL |= RTC_CTL_CMF; +} + +/*! + \brief exit RTC configuration mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_configuration_mode_exit(void) +{ + RTC_CTL &= ~RTC_CTL_CMF; +} + +/*! + \brief wait RTC last write operation finished flag set + \param[in] none + \param[out] none + \retval none +*/ +void rtc_lwoff_wait(void) +{ + /* loop until LWOFF flag is set */ + while (0U == (RTC_CTL & RTC_CTL_LWOFF)){ + } +} + +/*! + \brief wait RTC registers synchronized flag set + \param[in] none + \param[out] none + \retval none +*/ +void rtc_register_sync_wait(void) +{ + /* clear RSYNF flag */ + RTC_CTL &= ~RTC_CTL_RSYNF; + /* loop until RSYNF flag is set */ + while (0U == (RTC_CTL & RTC_CTL_RSYNF)){ + } +} + +/*! + \brief get RTC counter value + \param[in] none + \param[out] none + \retval RTC counter value +*/ +uint32_t rtc_counter_get(void) +{ + uint32_t temp = 0x0U; + temp = RTC_CNTL; + temp |= (RTC_CNTH << 16); + return temp; +} + +/*! + \brief set RTC counter value + \param[in] cnt: RTC counter value + \param[out] none + \retval none +*/ +void rtc_counter_set(uint32_t cnt) +{ + rtc_configuration_mode_enter(); + /* set the RTC counter high bits */ + RTC_CNTH = cnt >> 16; + /* set the RTC counter low bits */ + RTC_CNTL = (cnt & RTC_LOW_VALUE); + rtc_configuration_mode_exit(); +} + +/*! + \brief set RTC prescaler value + \param[in] psc: RTC prescaler value + \param[out] none + \retval none +*/ +void rtc_prescaler_set(uint32_t psc) +{ + rtc_configuration_mode_enter(); + /* set the RTC prescaler high bits */ + RTC_PSCH = (psc & RTC_HIGH_VALUE) >> 16; + /* set the RTC prescaler low bits */ + RTC_PSCL = (psc & RTC_LOW_VALUE); + rtc_configuration_mode_exit(); +} + +/*! + \brief set RTC alarm value + \param[in] alarm: RTC alarm value + \param[out] none + \retval none +*/ +void rtc_alarm_config(uint32_t alarm) +{ + rtc_configuration_mode_enter(); + /* set the alarm high bits */ + RTC_ALRMH = alarm >> 16; + /* set the alarm low bits */ + RTC_ALRML = (alarm & RTC_LOW_VALUE); + rtc_configuration_mode_exit(); +} + +/*! + \brief get RTC divider value + \param[in] none + \param[out] none + \retval RTC divider value +*/ +uint32_t rtc_divider_get(void) +{ + uint32_t temp = 0x00U; + temp = (RTC_DIVH & RTC_DIVH_DIV) << 16; + temp |= RTC_DIVL; + return temp; +} + +/*! + \brief enable RTC interrupt + \param[in] interrupt: specify which interrupt to enbale + \arg RTC_INT_SECOND: second interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_OVERFLOW: overflow interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + RTC_INTEN |= interrupt; +} + +/*! + \brief disable RTC interrupt + \param[in] interrupt: specify which interrupt to disbale + \arg RTC_INT_SECOND: second interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_OVERFLOW: overflow interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + RTC_INTEN &= ~interrupt; +} + +/*! + \brief get RTC flag status + \param[in] flag: specify which flag status to get + \arg RTC_FLAG_SECOND: second interrupt flag + \arg RTC_FLAG_ALARM: alarm interrupt flag + \arg RTC_FLAG_OVERFLOW: overflow interrupt flag + \arg RTC_FLAG_RSYN: registers synchronized flag + \arg RTC_FLAG_LWOF: last write operation finished flag + \param[out] none + \retval SET or RESET +*/ +FlagStatus rtc_flag_get(uint32_t flag) +{ + if(0U != (RTC_CTL & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear RTC flag status + \param[in] flag: specify which flag status to clear + \arg RTC_FLAG_SECOND: second interrupt flag + \arg RTC_FLAG_ALARM: alarm interrupt flag + \arg RTC_FLAG_OVERFLOW: overflow interrupt flag + \arg RTC_FLAG_RSYN: registers synchronized flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(uint32_t flag) +{ + /* clear RTC flag */ + RTC_CTL &= ~flag; +} + +/*! + \brief get RTC interrupt flag status + \param[in] flag: specify which flag status to get + only one parameter can be selected which is shown as below: + \arg RTC_INT_FLAG_SECOND: second interrupt flag + \arg RTC_INT_FLAG_ALARM: alarm interrupt flag + \arg RTC_INT_FLAG_OVERFLOW: overflow interrupt flag + \param[out] none + \retval SET or RESET +*/ +FlagStatus rtc_interrupt_flag_get(uint32_t flag) +{ + if(0U != (RTC_CTL & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear RTC interrupt flag status + \param[in] flag: specify which flag status to clear + one or more parameters can be selected which are shown as below: + \arg RTC_INT_FLAG_SECOND: second interrupt flag + \arg RTC_INT_FLAG_ALARM: alarm interrupt flag + \arg RTC_INT_FLAG_OVERFLOW: overflow interrupt flag + \param[out] none + \retval none +*/ +void rtc_interrupt_flag_clear(uint32_t flag) +{ + /* clear RTC interrupt flag */ + RTC_CTL &= ~flag; +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_spi.c b/gd32a50x/standard_peripheral/source/gd32a50x_spi.c new file mode 100644 index 0000000..4507677 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_spi.c @@ -0,0 +1,803 @@ +/*! + \file gd32fa50x_spi.c + \brief SPI driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_spi.h" + +#define SPI_ERROR_HANDLE(s) do{}while(1) + +/* SPI/I2S parameter initialization mask */ +#define SPI_INIT_MASK ((uint32_t)0x00003040U) +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) +#define I2S_FULL_DUPLEX_MASK ((uint32_t)0x0000F040U) + +/* default value */ +#define SPI_I2SPSC_RESET ((uint32_t)0x00000002U) /*!< default value of SPI_I2SPSC register */ + +/* I2S clock source selection, multiplication and division mask */ +#define I2S1_CLOCK_SEL ((uint32_t)0x00020000U) /*!< I2S1 clock source selection */ +#define I2S2_CLOCK_SEL ((uint32_t)0x00040000U) /*!< I2S2 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 */ + +/*! + \brief reset SPI and I2S + \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 structure with the default values + \param[in] none + \param[out] spi_struct: the initialized structure spi_parameter_struct pointer + \retval none +*/ +void spi_struct_para_init(spi_parameter_struct *spi_struct) +{ + /* configure the SPI structure with the default values */ + spi_struct->device_mode = SPI_SLAVE; + spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_struct->frame_size = SPI_FRAMESIZE_8BIT; + spi_struct->nss = SPI_NSS_HARD; + spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + spi_struct->prescale = SPI_PSC_2; + spi_struct->endian = SPI_ENDIAN_MSB; +} + +/*! + \brief initialize SPI parameter + \param[in] spi_periph: SPIx(x=0,1) + \param[in] spi_struct: SPI parameter initialization stuct members of the structure + and the member values are shown as below: + device_mode: SPI_MASTER, SPI_SLAVE + trans_mode: SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY, + SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT + frame_size: SPI_FRAMESIZE_16BIT, SPI_FRAMESIZE_8BIT + nss: SPI_NSS_SOFT, SPI_NSS_HARD + endian: SPI_ENDIAN_MSB, SPI_ENDIAN_LSB + clock_polarity_phase: SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE + SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE + prescale: SPI_PSC_n (n=2,4,8,16,32,64,128,256) + \param[out] none + \retval none +*/ +void spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct) +{ + uint32_t reg = 0U; + reg = SPI_CTL0(spi_periph); + reg &= SPI_INIT_MASK; + + /* select SPI as master or slave */ + reg |= spi_struct->device_mode; + /* select SPI transfer mode */ + reg |= spi_struct->trans_mode; + /* select SPI frame size */ + reg |= spi_struct->frame_size; + /* select SPI NSS use hardware or software */ + reg |= spi_struct->nss; + /* select SPI LSB or MSB */ + reg |= spi_struct->endian; + /* select SPI polarity and phase */ + reg |= spi_struct->clock_polarity_phase; + /* select SPI prescale to adjust transmit speed */ + reg |= spi_struct->prescale; + + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg; + + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); +} + +/*! + \brief enable SPI + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief disable SPI + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief initialize I2S parameter + \param[in] spi_periph: SPI1 + \param[in] i2s_mode: I2S operation mode + only one parameter can be selected which is shown as below: + \arg I2S_MODE_SLAVETX: I2S slave transmit mode + \arg I2S_MODE_SLAVERX: I2S slave receive mode + \arg I2S_MODE_MASTERTX: I2S master transmit mode + \arg I2S_MODE_MASTERRX: I2S master receive mode + \param[in] i2s_standard: I2S standard + only one parameter can be selected which is shown as below: + \arg I2S_STD_PHILLIPS: I2S phillips standard + \arg I2S_STD_MSB: I2S MSB standard + \arg I2S_STD_LSB: I2S LSB standard + \arg I2S_STD_PCMSHORT: I2S PCM short standard + \arg I2S_STD_PCMLONG: I2S PCM long standard + \param[in] i2s_ckpl: I2S idle state clock polarity + only one parameter can be selected which is shown as below: + \arg I2S_CKPL_LOW: I2S clock polarity low level + \arg I2S_CKPL_HIGH: I2S clock polarity high level + \param[out] none + \retval none +*/ +void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl) +{ + uint32_t reg= 0U; + reg = SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)i2s_mode; + /* select I2S standard */ + reg |= (uint32_t)i2s_standard; + /* select I2S polarity */ + reg |= (uint32_t)i2s_ckpl; + + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief configure I2S prescaler + \param[in] spi_periph: SPI1 + \param[in] i2s_audiosample: I2S audio sample rate + only one parameter can be selected which is shown as below: + \arg I2S_AUDIOSAMPLE_8K: audio sample rate is 8KHz + \arg I2S_AUDIOSAMPLE_11K: audio sample rate is 11KHz + \arg I2S_AUDIOSAMPLE_16K: audio sample rate is 16KHz + \arg I2S_AUDIOSAMPLE_22K: audio sample rate is 22KHz + \arg I2S_AUDIOSAMPLE_32K: audio sample rate is 32KHz + \arg I2S_AUDIOSAMPLE_44K: audio sample rate is 44KHz + \arg I2S_AUDIOSAMPLE_48K: audio sample rate is 48KHz + \arg I2S_AUDIOSAMPLE_96K: audio sample rate is 96KHz + \arg I2S_AUDIOSAMPLE_192K: audio sample rate is 192KHz + \param[in] i2s_frameformat: I2S data length and channel length + only one parameter can be selected which is shown as below: + \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit + \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit + \param[in] i2s_mckout: I2S master clock output + only one parameter can be selected which is shown as below: + \arg I2S_MCKOUT_ENABLE: I2S master clock output enable + \arg I2S_MCKOUT_DISABLE: I2S master clock output disable + \param[out] none + \retval none +*/ +void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout) +{ + uint32_t i2sdiv = 2U, i2sof = 0U; + uint32_t clks = 0U; + uint32_t i2sclock = 0U; + + /* judge whether the audiosample is 0 */ + if(0U == i2s_audiosample){ + SPI_ERROR_HANDLE("the parameter can not be 0 \r\n"); + } + + /* deinitialize SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = SPI_I2SPSC_RESET; + + /* get the I2S clock source */ + if(SPI1 == ((uint32_t)spi_periph)) { + /* I2S1 clock source selection */ + clks = I2S1_CLOCK_SEL; + }else{ + /* I2S2 clock source selection */ + clks = I2S2_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 I2S clock 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 | i2sof | i2s_mckout); + + /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN)); + + /* configure data frame format */ + SPI_I2SCTL(spi_periph) |= (uint32_t)i2s_frameformat; +} + +/*! + \brief enable I2S + \param[in] spi_periph: SPI1 + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief disable I2S + \param[in] spi_periph: SPI1 + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \brief enable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_output_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV; +} + +/*! + \brief disable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_output_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV); +} + +/*! + \brief SPI NSS pin high level in software mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_internal_high(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS; +} + +/*! + \brief SPI NSS pin low level in software mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_internal_low(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS); +} + +/*! + \brief enable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1) + \param[in] spi_dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA + \arg SPI_DMA_RECEIVE: SPI receive data using DMA + \param[out] none + \retval none +*/ +void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma) +{ + if(SPI_DMA_TRANSMIT == spi_dma){ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + }else{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief disable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1) + \param[in] spi_dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA + \arg SPI_DMA_RECEIVE: SPI receive data using DMA + \param[out] none + \retval none +*/ +void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma) +{ + if(SPI_DMA_TRANSMIT == spi_dma){ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + }else{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI data frame format + \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_16BIT: SPI frame size is 16 bits + \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits + \param[out] none + \retval none +*/ +void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + /* clear SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16); + /* confige SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= (uint32_t)frame_format; +} + +/*! + \brief configure SPI bidirectional transfer direction + \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 + \param[out] none + \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 + \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) +{ + SPI_DATA(spi_periph) = (uint32_t)data; +} + +/*! + \brief SPI receive data + \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) +{ + return ((uint16_t)SPI_DATA(spi_periph)); +} +/*! + \brief set SPI CRC polynomial + \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) +{ + /* enable SPI CRC */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; + + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval 16-bit CRC polynomial +*/ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + return ((uint16_t)SPI_CRCPOLY(spi_periph)); +} + +/*! + \brief turn on CRC function + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief turn off CRC function + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN); +} + +/*! + \brief SPI next data is CRC value + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_next(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT; +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1) + \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) +{ + if(SPI_CRC_TX == crc){ + return ((uint16_t)(SPI_TCRC(spi_periph))); + }else{ + return ((uint16_t)(SPI_RCRC(spi_periph))); + } +} + +/*! + \brief enable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_ti_mode_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD; +} + +/*! + \brief disable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1) + \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 + \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 + \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 + \param[in] spi_periph: SPIx(only x=0) + \param[out] none + \retval none +*/ +void spi_quad_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief disable quad wire SPI + \param[in] spi_periph: SPIx(only x=0) + \param[out] none + \retval none +*/ +void spi_quad_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD); +} + +/*! + \brief enable quad wire SPI write + \param[in] spi_periph: SPIx(only x=0) + \param[out] none + \retval none +*/ +void spi_quad_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief enable quad wire SPI read + \param[in] spi_periph: SPIx(only x=0) + \param[out] none + \retval none +*/ +void spi_quad_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief enable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(only x=0) + \param[out] none + \retval none +*/ +void spi_quad_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + + /*! + \brief disable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(only x=0) + \param[out] none + \retval none +*/ + void spi_quad_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} + +/*! + \brief get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1) + \param[in] flag: SPI/I2S flag status + only one parameter can be selected which is shown as below: + \arg SPI_FLAG_TBE: transmit buffer empty flag + \arg SPI_FLAG_RBNE: receive buffer not empty flag + \arg SPI_FLAG_TRANS: transmit on-going flag + \arg SPI_FLAG_RXORERR: receive overrun error flag + \arg SPI_FLAG_CONFERR: mode config error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: format error flag + \arg I2S_FLAG_TBE: transmit buffer empty flag + \arg I2S_FLAG_RBNE: receive buffer not empty flag + \arg I2S_FLAG_TRANS: transmit on-going flag + \arg I2S_FLAG_RXORERR: overrun error flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_CH: channel side flag + \arg I2S_FLAG_FERR: format error flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag) +{ + if(RESET != (SPI_STAT(spi_periph) & flag)) { + return SET; + }else{ + return RESET; + } +} +/*! + \brief enable SPI and I2S interrupt + \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; +} + +/*! + \brief disable SPI and I2S interrupt + \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; +} + +/*! + \brief get SPI and I2S interrupt flag status + \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) +{ + uint32_t reg1 = SPI_STAT(spi_periph); + uint32_t reg2 = SPI_CTL1(spi_periph); + + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_FLAG_TBE: + reg1 = reg1 & SPI_STAT_TBE; + reg2 = reg2 & SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_FLAG_RBNE: + reg1 = reg1 & SPI_STAT_RBNE; + reg2 = reg2 & SPI_CTL1_RBNEIE; + break; + /* SPI/I2S overrun interrupt */ + case SPI_I2S_INT_FLAG_RXORERR: + reg1 = reg1 & SPI_STAT_RXORERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI config error interrupt */ + case SPI_INT_FLAG_CONFERR: + reg1 = reg1 & SPI_STAT_CONFERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI CRC error interrupt */ + case SPI_INT_FLAG_CRCERR: + reg1 = reg1 & SPI_STAT_CRCERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* I2S underrun error interrupt */ + case I2S_INT_FLAG_TXURERR: + reg1 = reg1 & SPI_STAT_TXURERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI/I2S format error interrupt */ + case SPI_I2S_INT_FLAG_FERR: + reg1 = reg1 & SPI_STAT_FERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + default : + break; + } + /*get SPI/I2S interrupt flag status */ + if((0U != reg1) && (0U != reg2)) { + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear SPI CRC error flag status + \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); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_syscfg.c b/gd32a50x/standard_peripheral/source/gd32a50x_syscfg.c new file mode 100644 index 0000000..58fa05a --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_syscfg.c @@ -0,0 +1,453 @@ +/*! + \file gd32a50x_syscfg.c + \brief SYSCFG driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_syscfg.h" + +/* SYSCFG parameter mask */ +#define SYSCFG_TIMER0_ETI_SEL_MASK (uint32_t)0x3FFFFFFFU /*!< mask value of SYSCFG_TIMER0_ETI_SEL bits */ +#define SYSCFG_TIMER7_ETI_SEL_MASK (uint32_t)0xCFFFFFFFU /*!< mask value of SYSCFG_TIMER7_ETI_SEL bits */ +#define SYSCFG_TIMER19_ETI_SEL_MASK (uint32_t)0xFCFFFFFFU /*!< mask value of SYSCFG_TIMER19_ETI_SEL bits */ +#define SYSCFG_TIMER20_ETI_SEL_MASK (uint32_t)0xFF3FFFFFU /*!< mask value of SYSCFG_TIMER20_ETI_SEL bits */ +#define SYSCFG_CFG0_BOOTMODE_MASK (uint8_t)0x03U /*!< mask value of SYSCFG_CFG0_BOOT_MODE bits */ + +/* SYSCFG parameter offset */ +#define SYSCFG_TIMER0_ETI_SEL_OFFSET (uint32_t)30U /*!< offset value of SYSCFG_TIMER0_ETI_SEL bits */ +#define SYSCFG_TIMER7_ETI_SEL_OFFSET (uint32_t)28U /*!< offset value of SYSCFG_TIMER7_ETI_SEL bits */ +#define SYSCFG_TIMER19_ETI_SEL_OFFSET (uint32_t)24U /*!< offset value of SYSCFG_TIMER19_ETI_SEL bits */ +#define SYSCFG_TIMER20_ETI_SEL_OFFSET (uint32_t)22U /*!< offset value of SYSCFG_TIMER20_ETI_SEL bits */ +#define SYSCFG_CFG3_SRAMECCEADDR_OFFSET (uint8_t)18U /*!< offset value of SYSCFG_CFG3_SRAMECCEADDR bits */ +#define SYSCFG_CFG3_SRAMECCSERRBIT_OFFSET (uint8_t)12U /*!< offset value of SYSCFG_CFG3_SRAMECCSERRBITS bits */ + +/*! + \brief reset the SYSCFG registers + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_SYSCFGRST); + rcu_periph_reset_disable(RCU_SYSCFGRST); +} + +/*! + \brief configure the GPIO pin as EXTI Line + \param[in] exti_port: specify the gpio port used in EXTI + only one parameter can be selected which is shown as below: + \arg EXTI_SOURCE_GPIOx(x = A,B,C,D,E,F): 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(for GPIOA\GPIOB\GPIOC\GPIOD\GPIOE, x = 0..15, for GPIOF, x = 0..7): 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 remap pin function + \param[in] remap_pin: specify pin + only one parameter can be selected which are shown as below: + \arg SYSCFG_PA9_PA12_REMAP: PA9/PA12 pins are mapping on PA10/PA11 pins + \arg SYSCFG_BOOT0_REMAP_PF0: PF0 pin is mapping on the BOOT0 pin + \param[out] none + \retval none +*/ +void syscfg_pin_remap_enable(uint32_t remap_pin) +{ + SYSCFG_CFG0 |= remap_pin; +} + +/*! + \brief disable remap pin function + \param[in] remap_pin: specify pin + only one parameter can be selected which are shown as below: + \arg SYSCFG_PA9_PA12_REMAP: PA9/PA12 pins are mapping on PA10/PA11 pins + \arg SYSCFG_BOOT0_REMAP_PF0: PF0 pin is mapping on the BOOT0 pin + \param[out] none + \retval none +*/ +void syscfg_pin_remap_disable(uint32_t remap_pin) +{ + SYSCFG_CFG0 &= ~remap_pin; +} + +/*! + \brief configure ADC channel GPIO pin remap function + \param[in] adcx_iny_remap: specify ADC channel + only one parameter can be returned which is shown as below: + \arg ADC1_IN14_REMAP: ADC1 channel 14 GPIO pin remap + \arg ADC1_IN15_REMAP: ADC1 channel 15 GPIO pin remap + \arg ADC0_IN8_REMAP: ADC0 channel 8 GPIO pin remap + \arg ADC0_IN9_REMAP: ADC0 channel 9 GPIO pin remap + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void syscfg_adc_ch_remap_config(syscfg_adcx_chy_enum adcx_iny_remap, ControlStatus newvalue) +{ + switch(adcx_iny_remap) { + case ADC1_IN14_REMAP: + /* configure ADC1 channel 14 pin remap function */ + if(ENABLE == newvalue) { + SYSCFG_CFG1 |= SYSCFG_CFG1_ADC1CH14RMP; + } else { + SYSCFG_CFG1 &= (~SYSCFG_CFG1_ADC1CH14RMP); + } + break; + case ADC1_IN15_REMAP: + /* configure ADC1 channel 15 pin remap function */ + if(ENABLE == newvalue) { + SYSCFG_CFG1 |= SYSCFG_CFG1_ADC1CH15RMP; + } else { + SYSCFG_CFG1 &= (~SYSCFG_CFG1_ADC1CH15RMP); + } + break; + case ADC0_IN8_REMAP: + /* configure ADC0 channel 8 pin remap function */ + if(ENABLE == newvalue) { + SYSCFG_CFG1 |= SYSCFG_CFG1_ADC0CH8RMP; + } else { + SYSCFG_CFG1 &= (~SYSCFG_CFG1_ADC0CH8RMP); + } + break; + case ADC0_IN9_REMAP: + /* configure ADC0 channel 9 pin remap function */ + if(ENABLE == newvalue) { + SYSCFG_CFG1 |= SYSCFG_CFG1_ADC0CH9RMP; + } else { + SYSCFG_CFG1 &= (~SYSCFG_CFG1_ADC0CH9RMP); + } + break; + default: + break; + } +} + +/*! + \brief select TIMER external trigger source + \param[in] timer_num: specify TIMER + only one parameter can be returned which is shown as below: + \arg TIMER0SEL: select TIMER0 + \arg TIMER7SEL: select TIMER7 + \arg TIMER19SEL: select TIMER19 + \arg TIMER20SEL: select TIMER20 + \param[in] etr_num: specify external trigger source + only one parameter can be returned which is shown as below: + \arg TIMER_ETI_TRGx (x = 0,1,2,3): TIMER external trigger source x + \arg TIMER_ETI_TRG_NONE: do not seclet TIMER external trigger source + \param[out] none + \retval none +*/ +void syscfg_timer_eti_sel(syscfg_timersel_enum timer_num, uint32_t eti_num) +{ + switch(timer_num) { + case TIMER0SEL: + /* select TIMER0 external trigger source */ + SYSCFG_TIMERINSEL &= SYSCFG_TIMER0_ETI_SEL_MASK; + SYSCFG_TIMERINSEL |= (eti_num << SYSCFG_TIMER0_ETI_SEL_OFFSET); + break; + case TIMER7SEL: + /* select TIMER7 external trigger source */ + SYSCFG_TIMERINSEL &= SYSCFG_TIMER7_ETI_SEL_MASK; + SYSCFG_TIMERINSEL |= (eti_num << SYSCFG_TIMER7_ETI_SEL_OFFSET); + break; + case TIMER19SEL: + /* select TIMER19 external trigger source */ + SYSCFG_TIMERINSEL &= SYSCFG_TIMER19_ETI_SEL_MASK; + SYSCFG_TIMERINSEL |= (eti_num << SYSCFG_TIMER19_ETI_SEL_OFFSET); + break; + case TIMER20SEL: + /* select TIMER20 external trigger source */ + SYSCFG_TIMERINSEL &= SYSCFG_TIMER20_ETI_SEL_MASK; + SYSCFG_TIMERINSEL |= (eti_num << SYSCFG_TIMER20_ETI_SEL_OFFSET); + break; + default: + break; + } +} + +/*! + \brief select TRIGSEL as TIMER break input source + \param[in] bkin_source: specify TIMER break input source + only one parameter can be selected which are shown as below: + \arg TIMERx_BKINy_TRIG (x=0,7,19,20 y=0,1,2,3):TIMERx break input y source select from TRIGSEL + \param[out] none + \retval none +*/ +void syscfg_timer_bkin_select_trigsel(uint32_t bkin_source) +{ + SYSCFG_TIMERINSEL |= (uint32_t)bkin_source; +} + +/*! + \brief select GPIO as TIMER break input source + \param[in] bkin_source: specify TIMER break input source + only one parameter can be selected which are shown as below: + \arg TIMERx_BKINy_TRIG (x=0,7,19,,20 y=0,1,2,3): TIMERx break input y source select from TRIGSEL + \param[out] none + \retval none +*/ +void syscfg_timer_bkin_select_gpio(uint32_t bkin_source) +{ + SYSCFG_TIMERINSEL &= ~(uint32_t)bkin_source; +} + +/*! + \brief select TIMER7 channel0 complementary input source + \param[in] timer7_ch0n_in: specify TIMER7 channel0 complementary input source + only one parameter can be returned which is shown as below: + \arg TIMER7CH0N_TIMER7CH0_TIMER0CH0_IN : select exclusive or of TIMER7_CH0_IN, TIMER7_CH0N_IN, and TIMER0_CH0_IN + \arg TIMER7_CH0N_IN : select TIMER7_CH0N_IN + \param[out] none + \retval none +*/ +void syscfg_timer7_ch0n_select(uint32_t timer7_ch0n_in) +{ + if(TIMER7CH0N_TIMER7CH0_TIMER0CH0_IN == timer7_ch0n_in) { + /* select exclusive or of TIMER7_CH0_IN, TIMER7_CH0N_IN, and TIMER0_CH0_IN */ + SYSCFG_TIMERINSEL |= SYSCFG_TIMERINSEL_TIMER7_CH0N_SEL; + } else { + /* select TIMER7_CH0N_IN */ + SYSCFG_TIMERINSEL &= TIMER7_CH0N_IN; + } +} + +/*! + \brief configure TIMER0/7/19/20 break input to the selected parameter connection + \param[in] syscfg_lock: specify the parameter to be connected + only one parameter can be selected which is shown as below: + \arg SYSCFG_LOCK_LOCKUP: Cortex-M33 lockup output connected to the break input + \arg SYSCFG_LOCK_SRAM_ECC_ERROR: SRAM ECC check error connected to the break input + \arg SYSCFG_LOCK_LVD: LVD interrupt connected to the break input + \param[out] none + \retval none +*/ +void syscfg_lock_config(uint32_t syscfg_lock) +{ + SYSCFG_CFG2 |= syscfg_lock; +} + +/*! + \brief get SYSCFG flags + \param[in] syscfg_flag: specify the flag in SYSCFG_STAT to check + only one parameter can be selected which is shown as below: + \arg SYSCFG_FLAG_SRAMECCMERR: SRAM multi-bits non-correction ECC error flag + \arg SYSCFG_FLAG_SRAMECCSERR: SRAM single bit correction ECC error flag + \arg SYSCFG_FLAG_FLASHECCERR: FLASH ECC NMI error flag + \arg SYSCFG_FLAG_CKMNMIERR: HXTAL clock monitor NMI error flag + \arg SYSCFG_FLAG_NMIPINERR: NMI pin error flag + \param[out] none + \retval the syscfg_flag state returned (SET or RESET) + */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag) +{ + if(SYSCFG_STAT & syscfg_flag) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear SYSCFG flags + \param[in] syscfg_flag: specify the flag in SYSCFG_STAT to check + only one parameter can be selected which is shown as below: + \arg SYSCFG_FLAG_SRAMECCMERR: SRAM multi-bits non-correction ECC error flag + \arg SYSCFG_FLAG_SRAMECCSERR: SRAM single bit correction ECC error flag + \arg SYSCFG_FLAG_FLASHECCERR: FLASH ECC NMI error flag + \arg SYSCFG_FLAG_CKMNMIERR: HXTAL clock monitor NMI error flag + \param[out] none + \retval none +*/ +void syscfg_flag_clear(uint32_t syscfg_flag) +{ + SYSCFG_STAT |= (uint32_t) syscfg_flag; +} + +/*! + \brief enable SYSCFG interrupts + \param[in] interrupt: specify the interrupt in SYSCFG_CFG3 + only one parameter can be selected which is shown as below: + \arg SYSCFG_INT_SRAMECCME: SRAM multi-bits non-correction ECC error interrupt + \arg SYSCFG_INT_SRAMECCSE: SRAM single bit correction ECC error interrupt + \arg SYSCFG_INT_FLASHECCE: FLASH ECC NMI error interrupt + \arg SYSCFG_INT_CKMNMI: HXTAL clock monitor NMI error interrupt + \arg SYSCFG_INT_NMIPIN: NMI pin error interrupt + \param[out] none + \retval none +*/ +void syscfg_interrupt_enable(uint32_t interrupt) +{ + SYSCFG_CFG3 |= (uint32_t)interrupt; +} + +/*! + \brief disable SYSCFG interrupts + \param[in] interrupt: specify the interrupt in SYSCFG_CFG3 + only one parameter can be selected which is shown as below: + \arg SYSCFG_INT_SRAMECCME: SRAM multi-bits non-correction ECC error interrupt + \arg SYSCFG_INT_SRAMECCSE: SRAM single bit correction ECC error interrupt + \arg SYSCFG_INT_FLASHECCE: FLASH ECC NMI error interrupt + \arg SYSCFG_INT_CKMNMI: HXTAL clock monitor NMI error interrupt + \arg SYSCFG_INT_NMIPIN: NMI pin error interrupt + \param[out] none + \retval none +*/ +void syscfg_interrupt_disable(uint32_t interrupt) +{ + SYSCFG_CFG3 &= (uint32_t)(~interrupt); +} + +/*! + \brief get SYSCFG interrupt flag status + \param[in] interrupt: specify the interrupt flag status + only one parameter can be selected which is shown as below: + \arg SYSCFG_INT_FLAG_SRAMECCMERR: SRAM multi-bits non-correction ECC error interrupt flag + \arg SYSCFG_INT_FLAG_SRAMECCSERR: SRAM single bit correction ECC error interrupt flag + \arg SYSCFG_INT_FLAG_FLASHECCERR: FLASH ECC NMI error interrupt flag + \arg SYSCFG_INT_FLAG_CKMNMIERR: HXTAL clock monitor NMI error interrupt flag + \arg SYSCFG_INT_FLAG_NMIPINERR: NMI pin error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus syscfg_interrupt_flag_get(uint32_t interrupt) +{ + uint32_t reg1 = SYSCFG_STAT; + uint32_t reg2 = SYSCFG_CFG3; + + switch(interrupt) { + /* SRAM multi-bits non-correction ECC error interrupt */ + case SYSCFG_INT_FLAG_SRAMECCMERR: + reg1 = reg1 & SYSCFG_STAT_SRAMECCMEIF; + reg2 = reg2 & SYSCFG_CFG3_SRAMECCMEIE; + break; + /* SRAM single bit correction ECC error interrupt */ + case SYSCFG_INT_FLAG_SRAMECCSERR: + reg1 = reg1 & SYSCFG_STAT_SRAMECCSEIF; + reg2 = reg2 & SYSCFG_CFG3_SRAMECCSEIE; + break; + /* FLASH ECC NMI error interrupt */ + case SYSCFG_INT_FLAG_FLASHECCERR: + reg1 = reg1 & SYSCFG_STAT_FLASHECCIF; + reg2 = reg2 & SYSCFG_CFG3_FLASHECCIE; + break; + /* HXTAL clock monitor NMI error interrupt */ + case SYSCFG_INT_FLAG_CKMNMIERR: + reg1 = reg1 & SYSCFG_STAT_CKMNMIIF; + reg2 = reg2 & SYSCFG_CFG3_CKMNMIIE; + break; + /* NMI pin error interrupt */ + case SYSCFG_INT_FLAG_NMIPINERR: + reg1 = reg1 & SYSCFG_STAT_NMIPINIF; + reg2 = reg2 & SYSCFG_CFG3_NMIPINIE; + break; + default : + break; + } + /*get SYSCFG interrupt flag status */ + if(reg1 && reg2) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief get the current boot mode + \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) +{ + return (uint8_t)(SYSCFG_CFG0 & SYSCFG_CFG0_BOOTMODE_MASK); +} + +/*! + \brief get the address where SRAM ECC error occur on + \param[in] none + \param[out] none + \retval uint16_t: the address where SRAM ECC error occur on +*/ +uint16_t syscfg_sram_ecc_address_get(void) +{ + return (uint16_t)(SYSCFG_CFG3 >> SYSCFG_CFG3_SRAMECCEADDR_OFFSET); +} + +/*! + \brief get the bit which has SRAM ECC signle error + \param[in] none + \param[out] none + \retval uint8_t: which bit has SRAM ECC signle error +*/ +uint8_t syscfg_sram_ecc_bit_get(void) +{ + return (uint8_t)((SYSCFG_CFG3 & SYSCFG_CFG3_SRAMECCSERRBITS) >> SYSCFG_CFG3_SRAMECCSERRBIT_OFFSET); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_timer.c b/gd32a50x/standard_peripheral/source/gd32a50x_timer.c new file mode 100644 index 0000000..4d2e792 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_timer.c @@ -0,0 +1,3035 @@ +/*! + \file gd32a50x_timer.c + \brief TIMER driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_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 */ + +/*! + \brief deinit a TIMER + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph) { + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER1: + /* reset TIMER1 */ + rcu_periph_reset_enable(RCU_TIMER1RST); + rcu_periph_reset_disable(RCU_TIMER1RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER6: + /* reset TIMER6 */ + rcu_periph_reset_enable(RCU_TIMER6RST); + rcu_periph_reset_disable(RCU_TIMER6RST); + break; + case TIMER7: + /* reset TIMER7 */ + rcu_periph_reset_enable(RCU_TIMER7RST); + rcu_periph_reset_disable(RCU_TIMER7RST); + break; + case TIMER19: + /* reset TIMER19 */ + rcu_periph_reset_enable(RCU_TIMER19RST); + rcu_periph_reset_disable(RCU_TIMER19RST); + break; + case TIMER20: + /* reset TIMER20 */ + rcu_periph_reset_enable(RCU_TIMER20RST); + rcu_periph_reset_disable(RCU_TIMER20RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER init parameter struct with a default value + \param[in] initpara: init parameter struct + \param[out] none + \retval none +*/ +void timer_struct_para_init(timer_parameter_struct *initpara) +{ + /* initialize the init parameter struct member with the default value */ + initpara->prescaler = 0U; + initpara->alignedmode = TIMER_COUNTER_EDGE; + initpara->counterdirection = TIMER_COUNTER_UP; + initpara->period = 65535U; + initpara->clockdivision = TIMER_CKDIV_DIV1; + initpara->repetitioncounter = 0U; +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \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~255 + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct *initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER1 == timer_periph) || (TIMER7 == timer_periph) + || (TIMER19 == timer_periph) || (TIMER20 == 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; + + /* configure the clock division value */ + if((TIMER5 != timer_periph) && (TIMER6 != timer_periph)) { + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= (~(uint32_t)TIMER_CTL0_CKDIV); + TIMER_CTL0(timer_periph) |= (uint32_t)(initpara->clockdivision & CLOCKDIVISION_MASK); + } + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || + (TIMER19 == timer_periph) || (TIMER20 == timer_periph)) { + /* configure the repetition counter value */ + TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter; + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; +} + +/*! + \brief enable a TIMER + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief disable a TIMER + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPDIS; +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] aligned: aligned mode + only one parameter can be selected which is shown as below: + \arg TIMER_COUNTER_EDGE: edge-aligned mode + \arg TIMER_COUNTER_CENTER_DOWN: center-aligned and counting down assert mode + \arg TIMER_COUNTER_CENTER_UP: center-aligned and counting up assert mode + \arg TIMER_COUNTER_CENTER_BOTH: center-aligned and counting up/down assert mode + \param[out] none + \retval none +*/ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned) +{ + TIMER_CTL0(timer_periph) &= (uint32_t)(~TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)aligned; +} + +/*! + \brief set TIMER counter up direction + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \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 + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] repetition: the counter repetition value, 0~255 + \param[out] none + \retval none +*/ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition) +{ + TIMER_CREP(timer_periph) = (uint32_t)repetition; +} + +/*! + \brief configure TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \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 + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \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 + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval counter value, 0~65535 +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[out] none + \retval prescaler register value, 0~65535 +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t)(TIMER_PSC(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] spmode: single pulse mode + only one parameter can be selected which is shown as below: + \arg TIMER_SP_MODE_SINGLE: single pulse mode + \arg TIMER_SP_MODE_REPETITIVE: repetitive pulse mode + \param[out] none + \retval none +*/ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode) +{ + if(TIMER_SP_MODE_SINGLE == spmode) { + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM; + } else if(TIMER_SP_MODE_REPETITIVE == spmode) { + TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM); + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] update: update source + 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 configure channel commutation control shadow register + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE; + } else { + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE); + } +} + +/*! + \brief configure TIMER channel control shadow register update control + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \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 enable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] dma: specify which DMA to enable + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA request, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_DMA_CH0D: channel 0 DMA request , TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CMTD: channel commutation DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_TRGD: trigger DMA request,TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_MCH0D: multi mode channel 0 DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_MCH1D: multi mode channel 1 DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_MCH2D: multi mode channel 2 DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_MCH3D: multi mode channel 3 DMA request, TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint32_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] dma: specify which DMA to disbale + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA request, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_DMA_CH0D: channel 0 DMA request , TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_CMTD: channel commutation DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_TRGD: trigger DMA request,TIMERx(x=0,1,7,19,20) + \arg TIMER_DMA_MCH0D: multi mode channel 0 DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_MCH1D: multi mode channel 1 DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_MCH2D: multi mode channel 2 DMA request, TIMERx(x=0,7,19,20) + \arg TIMER_DMA_MCH3D: multi mode channel 3 DMA request, TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint32_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] dma_request: channel DMA request source selection + only one parameter can be selected which is shown as below: + \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel n is sent when channel n event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel n is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint32_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + } else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request) { + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure the TIMER DMA transfer + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] dma_baseaddr: DMA access base address + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV, TIMERx(x=0,1,7,19,20) + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_MCHCTL0: DMA transfer address is TIMER_MCHCTL0, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_MCHCTL1: DMA transfer address is TIMER_MCHCTL1, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_MCHCTL2: DMA transfer address is TIMER_MCHCTL2, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_MCH0CV: DMA transfer address is TIMER_MCH0CV, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_MCH1CV: DMA transfer address is TIMER_MCH1CV, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_MCH2CV: DMA transfer address is TIMER_MCH2CV, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_MCH3CV: DMA transfer address is TIMER_MCH3CV, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_CH0COMV_ADD: DMA transfer address is TIMER_CH0COMV_ADD, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_CH1COMV_ADD: DMA transfer address is TIMER_CH1COMV_ADD, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_CH2COMV_ADD: DMA transfer address is TIMER_CH2COMV_ADD, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_CH3COMV_ADD: DMA transfer address is TIMER_CH3COMV_ADD, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_CTL2: DMA transfer address is TIMER_CTL2, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_BRKCFG: DMA transfer address is TIMER_BRKCFG, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_FCCHP0: DMA transfer address is TIMER_FCCHP0, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_FCCHP1: DMA transfer address is TIMER_FCCHP1, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_FCCHP2: DMA transfer address is TIMER_FCCHP2, TIMERx(x=0,7,19,20) + \arg TIMER_DMACFG_DMATA_FCCHP3: DMA transfer address is TIMER_FCCHP3, TIMERx(x=0,7,19,20) + \param[in] dma_lenth: access burst length + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1~35): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] event: the timer software event generation sources + one or more parameters can be selected which are shown as below: + \arg TIMER_EVENT_SRC_UPG: update event generation, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation, TIMERx(x=0,1,7,19,20) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation, TIMERx(x=0,1,7,19,20) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation, TIMERx(x=0,1,7,19,20) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation, TIMERx(x=0,1,7,19,20) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation, TIMERx(x=0,1,7,19,20) + \arg TIMER_EVENT_SRC_BRKG: break event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_MCH0G: multi mode channel 0 capture or compare event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_MCH1G: multi mode channel 1 capture or compare event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_MCH2G: multi mode channel 2 capture or compare event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_MCH3G: multi mode channel 3 capture or compare event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_CH0COMADDG: channel 0 additional compare event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_CH1COMADDG: channel 1 additional compare event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_CH2COMADDG: channel 2 additional compare event generation, TIMERx(x=0,7,19,20) + \arg TIMER_EVENT_SRC_CH3COMADDG: channel 3 additional compare event generation, TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint32_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief initialize TIMER break parameter struct with a default value + \param[in] breakpara: TIMER break parameter struct + \param[out] none + \retval none +*/ +void timer_break_struct_para_init(timer_break_parameter_struct *breakpara) +{ + /* initialize the break parameter struct member with the default value */ + breakpara->runoffstate = (uint16_t)TIMER_ROS_STATE_DISABLE; + breakpara->ideloffstate = (uint16_t)TIMER_IOS_STATE_DISABLE; + breakpara->deadtime = 0U; + breakpara->breakpolarity = (uint16_t)TIMER_BREAK_POLARITY_LOW; + breakpara->outputautostate = (uint16_t)TIMER_OUTAUTO_DISABLE; + breakpara->protectmode = (uint16_t)TIMER_CCHP_PROT_OFF; + breakpara->breakstate = (uint16_t)TIMER_BREAK_DISABLE; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE, TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE, TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + breakpolarity: TIMER_BREAK_POLARITY_LOW, TIMER_BREAK_POLARITY_HIGH + outputautostate: TIMER_OUTAUTO_ENABLE, TIMER_OUTAUTO_DISABLE + protectmode: TIMER_CCHP_PROT_OFF, TIMER_CCHP_PROT_0, TIMER_CCHP_PROT_1, TIMER_CCHP_PROT_2 + breakstate: TIMER_BREAK_ENABLE, TIMER_BREAK_DISABLE + \param[out] none + \retval none +*/ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara) +{ + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | + ((uint32_t)(breakpara->ideloffstate)) | + ((uint32_t)(breakpara->deadtime)) | + ((uint32_t)(breakpara->breakpolarity)) | + ((uint32_t)(breakpara->outputautostate)) | + ((uint32_t)(breakpara->protectmode)) | + ((uint32_t)(breakpara->breakstate))); +} + +/*! + \brief enable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief configure TIMER primary output function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \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 initialize TIMER channel output parameter struct with a default value + \param[in] ocpara: TIMER channel n output parameter struct + \param[out] none + \retval none +*/ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct *ocpara) +{ + /* initialize the channel output parameter struct member with the default value */ + ocpara->outputstate = TIMER_CCX_DISABLE; + ocpara->outputnstate = TIMER_CCXN_DISABLE; + ocpara->ocpolarity = TIMER_OC_POLARITY_HIGH; + ocpara->ocnpolarity = TIMER_OCN_POLARITY_HIGH; + ocpara->ocidlestate = TIMER_OC_IDLE_STATE_LOW; + ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \param[in] ocpara: TIMER channel output parameter struct + outputstate: TIMER_CCX_ENABLE, TIMER_CCX_DISABLE + outputnstate: TIMER_CCXN_ENABLE, TIMER_CCXN_DISABLE + ocpolarity: TIMER_OC_POLARITY_HIGH, TIMER_OC_POLARITY_LOW + ocnpolarity: TIMER_OCN_POLARITY_HIGH, TIMER_OCN_POLARITY_LOW + ocidlestate: TIMER_OC_IDLE_STATE_LOW, TIMER_OC_IDLE_STATE_HIGH + ocnidlestate: TIMER_OCN_IDLE_STATE_LOW, TIMER_OCN_IDLE_STATE_HIGH + \param[out] none + \retval none +*/ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct *ocpara) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputstate; + /* reset the CH0P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + /* set the CH0P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocpolarity; + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || + (TIMER19 == timer_periph) || (TIMER20 == timer_periph)) { + /* reset the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + /* set the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + + /* reset the MCH0P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0P); + /* set the MCH0P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity; + + /* reset the ISO0 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0); + /* set the ISO0 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate; + + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate; + } + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputstate) << 4U); + /* reset the CH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + /* set the CH1P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 4U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || + (TIMER19 == timer_periph) || (TIMER20 == timer_periph)) { + /* reset the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + /* set the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 4U); + /* reset the MCH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1P); + /* set the MCH1P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 4U); + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U); + /* reset the ISO1N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N); + /* set the ISO1N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 2U); + } + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputstate) << 8U); + /* reset the CH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + /* set the CH2P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 8U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || + (TIMER19 == timer_periph) || (TIMER20 == timer_periph)) { + /* reset the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + /* set the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 8U); + /* reset the MCH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2P); + /* set the MCH2P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 8U); + /* reset the ISO2 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2); + /* set the ISO2 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 4U); + /* reset the ISO2N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N); + /* set the ISO2N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 4U); + } + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputstate) << 12U); + /* reset the CH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + /* set the CH3P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 12U); + + if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || + (TIMER19 == timer_periph) || (TIMER20 == timer_periph)) { + /* reset the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + /* set the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 12U); + /* reset the MCH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3P); + /* set the MCH3P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 12U); + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 6U); + /* reset the ISO3N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3N); + /* set the ISO3N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 6U); + } + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] ocmode: channel output compare mode + only one parameter can be selected which is shown as below: + \arg TIMER_OC_MODE_TIMING: timing mode + \arg TIMER_OC_MODE_ACTIVE: active mode + \arg TIMER_OC_MODE_INACTIVE: inactive mode + \arg TIMER_OC_MODE_TOGGLE: toggle mode + \arg TIMER_OC_MODE_LOW: force low mode + \arg TIMER_OC_MODE_HIGH: force high mode + \arg TIMER_OC_MODE_PWM0: PWM mode 0 + \arg TIMER_OC_MODE_PWM1: PWM mode 1 + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0COMCTL); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1COMCTL); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2COMCTL); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3COMCTL); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] pulse: channel output pulse value + \param[out] none + \retval none +*/ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCH3CV(timer_periph) = (uint32_t)pulse; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] ocshadow: channel output compare shadow + only one parameter can be selected which is shown as below: + \arg TIMER_OC_SHADOW_ENABLE: channel output compare shadow enable + \arg TIMER_OC_SHADOW_DISABLE: channel output compare shadow disable + \arg TIMER_OMC_SHADOW_ENABLE: multi mode channel output compare shadow enable + \arg TIMER_OMC_SHADOW_DISABLE: multi mode channel output compare shadow disable + \param[out] none + \retval none +*/ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0COMSEN); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1COMSEN); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2COMSEN); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3COMSEN); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] occlear: channel output clear function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_CLEAR_ENABLE: channel output clear function enable + \arg TIMER_OC_CLEAR_DISABLE: channel output clear function disable + \arg TIMER_OMC_CLEAR_ENABLE: multi mode channel output clear function enable + \arg TIMER_OMC_CLEAR_DISABLE: multi mode channel output clear function disable + \param[out] none + \retval none +*/ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0COMCEN); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1COMCEN); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2COMCEN); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3COMCEN); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] ocpolarity: channel output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high + \arg TIMER_OC_POLARITY_LOW: channel output polarity is low + \arg TIMER_OMC_POLARITY_HIGH: multi mode channel output polarity is high + \arg TIMER_OMC_POLARITY_LOW: multi mode channel output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 12U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH0FP); + TIMER_MCHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH1FP); + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 2U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH2FP); + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4U); + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH3FP); + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 6U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,7,19,20)) + \param[in] ocnpolarity: channel complementary output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high + \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] state: TIMER channel enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable + \arg TIMER_MCCX_ENABLE: multi mode channel enable + \arg TIMER_MCCX_DISABLE: multi mode channel disable + \param[out] none + \retval none +*/ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)state; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 12U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state); + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(state << 4U)); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(state << 8U)); + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(state << 12U)); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,7,19,20)) + \param[in] ocnstate: TIMER channel complementary output enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 12U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER channel input parameter struct with a default value + \param[in] icpara: TIMER channel input parameter struct + \param[out] none + \retval none +*/ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct *icpara) +{ + /* initialize the channel input parameter struct member with the default value */ + icpara->icpolarity = TIMER_IC_POLARITY_RISING; + icpara->icselection = TIMER_IC_SELECTION_DIRECTTI; + icpara->icprescaler = TIMER_IC_PSC_DIV1; + icpara->icfilter = 0U; +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] icpara: TIMER channel input parameter struct + icpolarity: TIMER_IC_POLARITY_RISING, TIMER_IC_POLARITY_FALLING, TIMER_IC_POLARITY_BOTH_EDGE + icselection: TIMER_IC_SELECTION_DIRECTTI, TIMER_IC_SELECTION_INDIRECTTI, TIMER_IC_SELECTION_ITS, TIMER_IC_SELECTION_PAIR + icprescaler: TIMER_IC_PSC_DIV1, TIMER_IC_PSC_DIV2, TIMER_IC_PSC_DIV4, TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpara) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 28U); + } else { + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + } + + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 4U); + + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 29U); + } else { + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + } + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and MCH2P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P | TIMER_CHCTL2_MCH2P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 8U); + + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 28U); + } else { + TIMER_CHCTL1(timer_periph) |= (uint32_t)(icpara->icselection); + } + + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + + /* reset the CH3P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P | TIMER_CHCTL2_MCH3P)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 12U); + + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 29U); + } else { + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + } + + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + /* reset the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + + /* reset the MCH0FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH0FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= TIMER_IMC_POLARITY_RISING; + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= TIMER_IMC_POLARITY_FALLING; + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= TIMER_IMC_POLARITY_BOTH_EDGE; + break; + default: + break; + } + + /* reset the MCH0MS bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)icpara->icselection << 28U); + } else { + TIMER_MCHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + } + + /* reset the MCH0CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0CAPFLT); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH0EN; + break; + + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + /* reset the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + + /* reset the MCH1FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH1FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_RISING << 2U); + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_FALLING << 2U); + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 2U); + break; + default: + break; + } + /* reset the MCH1MS bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)icpara->icselection << 29U); + } else { + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)(icpara->icselection) << 8U); + } + + /* reset the MCH1CAPFLT bit */ + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1CAPFLT); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH1EN; + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + /* reset the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + + /* reset the MCH2FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH2FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_RISING << 4U); + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_FALLING << 4U); + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 4U); + break; + default: + break; + } + /* reset the MCH2MS bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)icpara->icselection << 28U); + } else { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)(icpara->icselection)); + } + + /* reset the MCH2CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2CAPFLT); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH2EN; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + /* reset the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + + /* reset the MCH3FP bits */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)(TIMER_MCHCTL2_MCH3FP)); + switch(icpara->icpolarity) { + case TIMER_IC_POLARITY_RISING: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_RISING << 6U); + break; + case TIMER_IC_POLARITY_FALLING: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_FALLING << 6U); + break; + case TIMER_IC_POLARITY_BOTH_EDGE: + TIMER_MCHCTL2(timer_periph) |= ((uint32_t)TIMER_IMC_POLARITY_BOTH_EDGE << 6U); + break; + default: + break; + } + /* reset the MCH3MS bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3MS); + if(TIMER_IC_SELECTION_PAIR == icpara->icselection) { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)icpara->icselection << 29U); + } else { + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)(icpara->icselection) << 8U); + } + + /* reset the MCH3CAPFLT bit */ + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3CAPFLT); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_MCH3EN; + break; + default: + break; + } + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, channel, (uint16_t)(icpara->icprescaler)); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] prescaler: channel input capture prescaler value + only one parameter can be selected which is shown as below: + \arg TIMER_IC_PSC_DIV1: no prescaler + \arg TIMER_IC_PSC_DIV2: divided by 2 + \arg TIMER_IC_PSC_DIV4: divided by 4 + \arg TIMER_IC_PSC_DIV8: divided by 8 + \param[out] none + \retval none +*/ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL0(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC); + TIMER_CHCTL1(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0CAPPSC); + TIMER_MCHCTL0(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1CAPPSC); + TIMER_MCHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2CAPPSC); + TIMER_MCHCTL1(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3CAPPSC); + TIMER_MCHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[out] none + \retval channel capture compare register value(0~65535) +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value = 0U; + + switch(channel) { + case TIMER_CH_0: + /* read TIMER_CH_0 capture compare register value */ + count_value = TIMER_CH0CV(timer_periph); + break; + case TIMER_CH_1: + /* read TIMER_CH_1 capture compare register value */ + count_value = TIMER_CH1CV(timer_periph); + break; + case TIMER_CH_2: + /* read TIMER_CH_2 capture compare register value */ + count_value = TIMER_CH2CV(timer_periph); + break; + case TIMER_CH_3: + /* read TIMER_CH_3 capture compare register value */ + count_value = TIMER_CH3CV(timer_periph); + break; + case TIMER_MCH_0: + /* read TIMER_MCH_0 capture compare register value */ + count_value = TIMER_MCH0CV(timer_periph); + break; + case TIMER_MCH_1: + /* read TIMER_MCH_1 capture compare register value */ + count_value = TIMER_MCH1CV(timer_periph); + break; + case TIMER_MCH_2: + /* read TIMER_MCH_2 capture compare register value */ + count_value = TIMER_MCH2CV(timer_periph); + break; + case TIMER_MCH_3: + /* read TIMER_MCH_3 capture compare register value */ + count_value = TIMER_MCH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \param[in] icpwm: TIMER channel input pwm parameter struct + icpolarity: TIMER_IC_POLARITY_RISING, TIMER_IC_POLARITY_FALLING + icselection: TIMER_IC_SELECTION_DIRECTTI, TIMER_IC_SELECTION_INDIRECTTI + icprescaler: TIMER_IC_PSC_DIV1, TIMER_IC_PSC_DIV2, TIMER_IC_PSC_DIV4, TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct *icpwm) +{ + uint16_t icpolarity = 0U; + uint16_t icselection = 0U; + + /* set channel input polarity */ + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity) { + icpolarity = TIMER_IC_POLARITY_FALLING; + } else { + icpolarity = TIMER_IC_POLARITY_RISING; + } + /* set channel input mode selection */ + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection) { + icselection = TIMER_IC_SELECTION_INDIRECTTI; + } else { + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == channel) { + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + /* set the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + /* set the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icselection << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + } else { + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + /* set the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + /* set the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] hallmode: + only one parameter can be selected which is shown as below: + \arg TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable + \arg TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable + \param[out] none + \retval none +*/ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode) +{ + if(TIMER_HALLINTERFACE_ENABLE == hallmode) { + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S; + } else if(TIMER_HALLINTERFACE_DISABLE == hallmode) { + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S; + } else { + /* illegal parameters */ + } +} + +/*! + \brief initialize TIMER multi mode channel output parameter struct + \param[in] omcpara: TIMER multi mode channel output parameter struct + \param[out] none + \retval none +*/ +void timer_multi_mode_channel_output_parameter_struct_init(timer_omc_parameter_struct *omcpara) +{ + /* initialize the multi mode channel output parameter struct with the default value */ + omcpara->outputmode = TIMER_MCH_MODE_COMPLEMENTARY; + omcpara->outputstate = TIMER_MCCX_DISABLE; + omcpara->ocpolarity = TIMER_OMC_POLARITY_LOW; +} + +/*! + \brief configure TIMER multi mode channel output function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] omcpara: TIMER multi mode channel output parameter struct + outputmode: TIMER_MCH_MODE_INDEPENDENTLY, TIMER_MCH_MODE_MIRRORED, TIMER_MCH_MODE_COMPLEMENTARY + outputstate: TIMER_MCCX_ENABLE, TIMER_MCCX_DISABLE + ocpolarity: TIMER_OMC_POLARITY_HIGH, TIMER_OMC_POLARITY_LOW + \param[out] none + \retval none +*/ +void timer_multi_mode_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_omc_parameter_struct *omcpara) +{ + switch(channel) { + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 20U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 20U); + /* reset the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH0EN); + /* set the MCH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputstate)); + + /* reset the MCH0FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH0FP); + /* set the MCH0FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)omcpara->ocpolarity; + + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH0MS); + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 22U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 22U); + /* reset the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH1EN); + /* set the MCH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputstate) << 4U); + + /* reset the MCH1FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH1FP); + /* set the MCH1FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->ocpolarity) << 2U); + + TIMER_MCHCTL0(timer_periph) &= (~(uint32_t)TIMER_MCHCTL0_MCH1MS); + break; + + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 24U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 24U); + /* reset the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH2EN); + /* set the MCH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputstate) << 8U); + + /* reset the MCH2FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH2FP); + /* set the MCH2FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->ocpolarity) << 4U); + + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH2MS); + break; + + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + TIMER_CTL2(timer_periph) &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 26U)); + TIMER_CTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputmode) << 26U); + /* reset the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_MCH3EN); + /* set the MCH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->outputstate) << 12U); + + /* reset the MCH3FP bit */ + TIMER_MCHCTL2(timer_periph) &= (~(uint32_t)TIMER_MCHCTL2_MCH3FP); + /* set the MCH3FP bit */ + TIMER_MCHCTL2(timer_periph) |= (uint32_t)((uint32_t)(omcpara->ocpolarity) << 6U); + + TIMER_MCHCTL1(timer_periph) &= (~(uint32_t)TIMER_MCHCTL1_MCH3MS); + + break; + default: + break; + } +} + +/*! + \brief multi mode channel mode select + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_MCH_0: TIMER multi mode channel 0(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_1: TIMER multi mode channel 1(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_2: TIMER multi mode channel 2(TIMERx(x=0,7,19,20)) + \arg TIMER_MCH_3: TIMER multi mode channel 3(TIMERx(x=0,7,19,20)) + \param[in] multi_mode_sel: multi mode channel mode selection + only one parameter can be selected which is shown as below: + \arg TIMER_MCH_MODE_INDEPENDENTLY: multi mode channel work in independently mode + \arg TIMER_MCH_MODE_MIRRORED: multi mode channel work in mirrored output mode + \arg TIMER_MCH_MODE_COMPLEMENTARY: multi mode channel work in complementary output mode + \param[out] none + \retval none +*/ +void timer_multi_mode_channel_mode_config(uint32_t timer_periph, uint32_t channel, uint32_t multi_mode_sel) +{ + uint32_t reg = TIMER_CTL2(timer_periph); + switch(channel) { + /* configure TIMER_MCH_0 */ + case TIMER_MCH_0: + reg &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 20U)); + reg |= (uint32_t)(multi_mode_sel << 20U); + break; + /* configure TIMER_MCH_1 */ + case TIMER_MCH_1: + reg &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 22U)); + reg |= (uint32_t)(multi_mode_sel << 22U); + break; + /* configure TIMER_MCH_2 */ + case TIMER_MCH_2: + reg &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 24U)); + reg |= (uint32_t)(multi_mode_sel << 24U); + break; + /* configure TIMER_MCH_3 */ + case TIMER_MCH_3: + reg &= (~(uint32_t)((uint32_t)TIMER_MCH_MODE_MASK << 26U)); + reg |= (uint32_t)(multi_mode_sel << 26U); + break; + default: + break; + } + TIMER_CTL2(timer_periph) = reg; +} + + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] intrigger: input trigger source + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered channel 0 input(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered channel 1 input(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_ETIFP: filtered external trigger input(TIMERx(x=0,1,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_CI2FE2: filtered channel 2 input(TIMERx(x=0,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_CI3FE3: filtered channel 3 input(TIMERx(x=0,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_MCI0FEM0: filtered multi mode channel 0 input(TIMERx(x=0,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_MCI1FEM1: filtered multi mode channel 1 input(TIMERx(x=0,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_MCI2FEM2: filtered multi mode channel 2 input(TIMERx(x=0,7,19,20)) + \arg TIMER_SMCFG_TRGSEL_MCI3FEM3: filtered multi mode channel 3 input(TIMERx(x=0,7,19,20)) + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger) +{ + uint32_t reg; + + reg = TIMER_SMCFG(timer_periph); + reg &= (~(uint32_t)TIMER_SMCFG_TRGS); + reg |= (uint32_t)intrigger; + TIMER_SMCFG(timer_periph) = reg; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] outrigger: trigger output source + 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,1,5,6,7,19,20)) + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal as trigger output(TIMERx(x=0,1,5,6,7,19,20)) + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0,1,5,6,7,19,20)) + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channel 0 as trigger output TRGO(TIMERx(x=0,1,7,19,20)) + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output(TIMERx(x=0,1,7,19,20)) + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output(TIMERx(x=0,1,7,19,20)) + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output(TIMERx(x=0,1,7,19,20)) + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output(TIMERx(x=0,1,7,19,20)) + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + uint32_t reg; + + reg = TIMER_CTL1(timer_periph); + reg &= (~(uint32_t)TIMER_CTL1_MMC); + reg |= (uint32_t)outrigger; + TIMER_CTL1(timer_periph) = reg; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] slavemode: slave mode + only one parameter can be selected which is shown as below: + \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable + \arg TIMER_ENCODER_MODE0: encoder mode 0 + \arg TIMER_ENCODER_MODE1: encoder mode 1 + \arg TIMER_ENCODER_MODE2: encoder mode 2 + \arg TIMER_SLAVE_MODE_RESTART: restart mode + \arg TIMER_SLAVE_MODE_PAUSE: pause mode + \arg TIMER_SLAVE_MODE_EVENT: event mode + \arg TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0 + \param[out] none + \retval none +*/ + +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) +{ + uint32_t reg; + + reg = TIMER_SMCFG(timer_periph); + reg &= (~(uint32_t)TIMER_SMCFG_SMC); + reg |= (uint32_t)slavemode; + TIMER_SMCFG(timer_periph) = reg; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] masterslave: master slave mode + only one parameter can be selected which is shown as below: + \arg TIMER_MASTER_SLAVE_MODE_ENABLE: master slave mode enable + \arg TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable + \param[out] none + \retval none +*/ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave) +{ + if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave) { + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM; + } else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave) { + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] extprescaler: external trigger prescaler + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: external trigger polarity + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC)); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extprescaler | extpolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << 8U); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] decomode: quadrature decoder mode + only one parameter can be selected which is shown as below: + \arg TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level + \arg TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level + \arg TIMER_ENCODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input + \param[in] ic0polarity: input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[in] ic1polarity: input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity) +{ + /* configure the quadrature decoder mode */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; + /* configure input capture selection */ + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS)) & ((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI | ((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + /* configure channel input capture polarity */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity | ((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] intrigger: internal trigger selection + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0 + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1 + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2 + \arg TIMER_SMCFG_TRGSEL_ITI3: internal trigger 3 + \param[out] none + \retval none +*/ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger) +{ + timer_input_trigger_source_select(timer_periph, intrigger); + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \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 channel 0 input + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered channel 1 input + \param[in] extpolarity: external input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: active high or rising edge active + \arg TIMER_IC_POLARITY_FALLING: active low or falling edge active + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity, uint32_t extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger) { + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_MCH1P)); + /* set the CH1P and MCH1P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)extpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + } else { + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_MCH0P)); + /* set the CH0P and MCH0P bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)extpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + } + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph, extrigger); + /* reset the SMC bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + /* set the SMC bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external clock mode0 + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] extprescaler: external trigger prescaler + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: external input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + /* reset the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS)); + /* set the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] extprescaler: external trigger prescaler + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: external input capture polarity + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_disable(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief configure TIMER channel input remap function + \param[in] timer_periph: TIMERx(x=1) + \param[in] remap: TIMER channel input remap + only one parameter can be selected which is shown as below: + \arg TIMER1_CI0_RMP_GPIO: TIMER1 channel 0 input remap to GPIO pin + \arg TIMER1_CI0_RMP_LXTAL: TIMER1 channel 0 input remap to LXTAL + \arg TIMER1_CI0_RMP_HXTAL: TIMER1 channel 0 input remap to HXTAL/128 + \arg TIMER1_CI0_RMP_CKOUT0SEL: TIMER1 channel 0 input remap to CKOUT0SEL + \param[out] none + \retval none +*/ +void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap) +{ + TIMER_IRMP(timer_periph) = (uint32_t)remap; +} + +/*! + \brief configure TIMER write CHxVAL register selection + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] ccsel: write CHxVAL register selection + only one parameter can be selected which is shown as below: + \arg TIMER_CHVSEL_DISABLE: no effect + \arg TIMER_CHVSEL_ENABLE: when write the CHxVAL register, if the write value is same as the CHxVAL value, the write access is ignored + \param[out] none + \retval none +*/ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel) +{ + if(TIMER_CHVSEL_ENABLE == ccsel) { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL; + } else if(TIMER_CHVSEL_DISABLE == ccsel) { + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER output value selection + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] outsel: output value selection + only one parameter can be selected which is shown as below: + \arg TIMER_OUTSEL_DISABLE: no effect + \arg TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel) +{ + if(TIMER_OUTSEL_ENABLE == outsel) { + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL; + } else if(TIMER_OUTSEL_DISABLE == outsel) { + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL; + } else { + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER output match pulse selection + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(x=0,7,19,20) + \arg TIMER_CH_1: TIMER channel 1(x=0,7,19,20) + \arg TIMER_CH_2: TIMER channel 2(x=0,7,19,20) + \arg TIMER_CH_3: TIMER channel 3(x=0,7,19,20) + \param[in] pulsesel: output match pulse selection + only one parameter can be selected which is shown as below: + \arg TIMER_PULSE_OUTPUT_NORMAL: channel output normal + \arg TIMER_PULSE_OUTPUT_CNT_UP: pulse output only when counting up + \arg TIMER_PULSE_OUTPUT_CNT_DOWN: pulse output only when counting down + \arg TIMER_PULSE_OUTPUT_CNT_BOTH: pulse output when counting up or down + \param[out] none + \retval none +*/ +void timer_output_match_pulse_select(uint32_t timer_periph, uint32_t channel, uint16_t pulsesel) +{ + uint32_t reg; + reg = TIMER_CTL2(timer_periph); + + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 8U)); + reg |= (uint32_t)((uint32_t)pulsesel << 8U); + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 10U)); + reg |= (uint32_t)((uint32_t)pulsesel << 10U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 12U)); + reg |= (uint32_t)((uint32_t)pulsesel << 12U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + reg &= (~(uint32_t)((uint32_t)TIMER_PULSE_OUTPUT_MASK << 14U)); + reg |= (uint32_t)((uint32_t)pulsesel << 14U); + break; + default: + break; + } + TIMER_CTL2(timer_periph) = reg; +} + +/*! + \brief configure the TIMER composite PWM mode + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(x=0,7,19,20) + \arg TIMER_CH_1: TIMER channel 1(x=0,7,19,20) + \arg TIMER_CH_2: TIMER channel 2(x=0,7,19,20) + \arg TIMER_CH_3: TIMER channel 3(x=0,7,19,20) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_composite_pwm_mode_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= (uint32_t)(TIMER_CTL2_CH0CPWMEN << channel); + } else { + TIMER_CTL2(timer_periph) &= (~(uint32_t)(TIMER_CTL2_CH0CPWMEN << channel)); + } +} + +/*! + \brief configure the TIMER composite PWM mode output pulse value + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(x=0,7,19,20) + \arg TIMER_CH_1: TIMER channel 1(x=0,7,19,20) + \arg TIMER_CH_2: TIMER channel 2(x=0,7,19,20) + \arg TIMER_CH_3: TIMER channel 3(x=0,7,19,20) + \param[in] pulse: channel compare value, 0~65535 + \param[in] add_pulse: channel additional compare value, 0~65535 + \param[out] none + \retval none +*/ +void timer_channel_composite_pwm_mode_output_pulse_value_config(uint32_t timer_periph, uint32_t channel, uint32_t pulse, uint32_t add_pulse) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + TIMER_CH0COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + TIMER_CH1COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + TIMER_CH2COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + TIMER_CH3COMV_ADD(timer_periph) = (uint32_t)add_pulse; + break; + default: + break; + } +} + + +/*! + \brief configure TIMER channel additional compare value + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(x=0,7,19,20) + \arg TIMER_CH_1: TIMER channel 1(x=0,7,19,20) + \arg TIMER_CH_2: TIMER channel 2(x=0,7,19,20) + \arg TIMER_CH_3: TIMER channel 3(x=0,7,19,20) + \param[in] value: channel additional compare value, 0~65535 + \param[out] none + \retval none +*/ +void timer_channel_additional_compare_value_config(uint32_t timer_periph, uint16_t channel, uint32_t value) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0COMV_ADD(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1COMV_ADD(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2COMV_ADD(timer_periph) = (uint32_t)value; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3COMV_ADD(timer_periph) = (uint32_t)value; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel additional output shadow function + \param[in] timer_periph: TIMERx(x=0,1,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,1,7,19,20)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,1,7,19,20)) + \param[in] aocshadow: channel additional output compare shadow + only one parameter can be selected which is shown as below: + \arg TIMER_ADD_SHADOW_ENABLE: channel additional output compare shadow enable + \arg TIMER_ADD_SHADOW_DISABLE: channel additional output compare shadow disable + \param[out] none + \retval none +*/ +void timer_channel_additional_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t aocshadow) +{ + switch(channel) { + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMADDSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 28U); + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMADDSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 29U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMADDSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 28U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMADDSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)aocshadow << 29U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER break external input parameter struct with a default value + \param[in] breakinpara: TIMER break external input parameter struct + \param[out] none + \retval none +*/ +void timer_break_external_input_struct_para_init(timer_break_ext_input_struct *breakinpara) +{ + /* initialize the break parameter struct member with the default value */ + breakinpara->filter = 0U; + breakinpara->enable = TIMER_IOS_STATE_DISABLE; + breakinpara->polarity = TIMER_BRKIN_POLARITY_LOW; +} + +/*! + \brief configure break external input + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] break_input: break external input + only one parameter can be selected which is shown as below: + \arg TIMER_BREAKINPUT_BRK0: TIMER break external input 0 + \arg TIMER_BREAKINPUT_BRK1: TIMER break external input 1 + \arg TIMER_BREAKINPUT_BRK2: TIMER break external input 2 + \arg TIMER_BREAKINPUT_BRK3: TIMER break external input 3 + \param[in] breakinpara: break external input parameter struct + filter:: 0~15 + enable: ENABLE or DISABLE + polarity: TIMER_BRKIN_POLARITY_HIGH, TIMER_BRKIN_POLARITY_LOW + \param[out] none + \retval none +*/ +void timer_break_external_input_config(uint32_t timer_periph, uint32_t break_input, timer_break_ext_input_struct *breakinpara) +{ + uint32_t reg = 0U; + reg = TIMER_BRKCFG(timer_periph); + reg &= (~(uint32_t)((0x03000000U << (break_input << 1U) | ((uint32_t)0x0000000FU << (break_input << 2U))))); + + reg |= ((breakinpara->filter << (break_input << 2U)) | + (breakinpara->enable << ((break_input << 1U) + 24U)) | + (breakinpara->polarity << ((break_input << 1U) + 25U))); + + TIMER_BRKCFG(timer_periph) = reg; +} + +/*! + \brief break external input enable + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] break_input: break external input + only one parameter can be selected which is shown as below: + \arg TIMER_BREAKINPUT_BRK0: TIMER break external input 0 + \arg TIMER_BREAKINPUT_BRK1: TIMER break external input 1 + \arg TIMER_BREAKINPUT_BRK2: TIMER break external input 2 + \arg TIMER_BREAKINPUT_BRK3: TIMER break external input 3 + \param[out] none + \retval none +*/ +void timer_break_external_input_enable(uint32_t timer_periph, uint32_t break_input) +{ + TIMER_BRKCFG(timer_periph) |= (uint32_t)(TIMER_BRKCFG_BRK0EN << (break_input << 1U)); +} + +/*! + \brief break external input disable + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] break_input: break external input + only one parameter can be selected which is shown as below: + \arg TIMER_BREAKINPUT_BRK0: TIMER break external input 0 + \arg TIMER_BREAKINPUT_BRK1: TIMER break external input 1 + \arg TIMER_BREAKINPUT_BRK2: TIMER break external input 2 + \arg TIMER_BREAKINPUT_BRK3: TIMER break external input 3 + \param[out] none + \retval none +*/ +void timer_break_external_input_disable(uint32_t timer_periph, uint32_t break_input) +{ + TIMER_BRKCFG(timer_periph) &= (~(uint32_t)(TIMER_BRKCFG_BRK0EN << (break_input << 1U))); +} + +/*! + \brief configure TIMER break external input polarity + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] break_input: break external input + only one parameter can be selected which is shown as below: + \arg TIMER_BREAKINPUT_BRK0: TIMER break external input 0(TIMERx(x=0,7,19,20) + \arg TIMER_BREAKINPUT_BRK1: TIMER break external input 1(TIMERx(x=0,7,19,20) + \arg TIMER_BREAKINPUT_BRK2: TIMER break external input 2(TIMERx(x=0,7,19,20) + \arg TIMER_BREAKINPUT_BRK3: TIMER break external input 3(TIMERx(x=0,7,19,20) + \param[in] polarity: break external input polarity + only one parameter can be selected which is shown as below: + \arg TIMER_BRKIN_POLARITY_HIGH: break external input polarity is high + \arg TIMER_BRKIN_POLARITY_LOW: break external input polarity is low + \param[out] none + \retval none +*/ +void timer_break_external_input_polarity_config(uint32_t timer_periph, uint32_t break_input, uint32_t polarity) +{ + if(polarity == TIMER_BRKIN_POLARITY_HIGH) { + TIMER_BRKCFG(timer_periph) |= (uint32_t)(TIMER_BRKCFG_BRK0P << (break_input << 1U)); + } else { + TIMER_BRKCFG(timer_periph) &= (~(uint32_t)(TIMER_BRKCFG_BRK0P << (break_input << 1U))); + } +} + +/*! + \brief configure the TIMER channel break function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \arg TIMER_CH_2: TIMER channel 2 + \arg TIMER_CH_3: TIMER channel 3 + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_break_control_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= (uint32_t)(TIMER_CTL2_BRKENCH0 << channel); + } else { + TIMER_CTL2(timer_periph) &= (~(uint32_t)(TIMER_CTL2_BRKENCH0 << channel)); + } +} + +/*! + \brief configure the TIMER channel free dead time function + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \arg TIMER_CH_2: TIMER channel 2 + \arg TIMER_CH_3: TIMER channel 3 + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_dead_time_config(uint32_t timer_periph, uint32_t channel, ControlStatus newvalue) +{ + if(ENABLE == newvalue) { + TIMER_CTL2(timer_periph) |= (uint32_t)(TIMER_CTL2_DTIENCH0 << channel); + } else { + TIMER_CTL2(timer_periph) &= (~(uint32_t)(TIMER_CTL2_DTIENCH0 << channel)); + } +} + +/*! + \brief initialize TIMER channel free complementary parameter struct with a default value + \param[in] none + \param[out] freecompara: TIMER channel free complementary parameter struct + \retval none +*/ +void timer_free_complementary_struct_para_init(timer_free_complementary_parameter_struct *freecompara) +{ + /* initialize the channel free complementary parameter struct member with the default value */ + freecompara->freecomstate = TIMER_FCCHP_STATE_DISABLE; + freecompara->runoffstate = TIMER_ROS_STATE_DISABLE; + freecompara->ideloffstate = TIMER_IOS_STATE_DISABLE; + freecompara->deadtime = 0U; +} + +/*! + \brief configure channel free complementary protection + \param[in] timer_periph: TIMERx(x=0,7,19,20) + \param[in] channel: TIMER channel + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0 + \arg TIMER_CH_1: TIMER channel 1 + \arg TIMER_CH_2: TIMER channel 2 + \arg TIMER_CH_3: TIMER channel 3 + \param[in] fcpara: TIMER channel free complementary parameter struct + freecomstate: TIMER_FCCHP_STATE_ENABLE, TIMER_FCCHP_STATE_DISABLE + runoffstate: TIMER_ROS_STATE_ENABLE, TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE, TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + \param[out] none + \retval none +*/ +void timer_channel_free_complementary_config(uint32_t timer_periph, uint16_t channel, timer_free_complementary_parameter_struct *fcpara) +{ + switch(channel) { + case TIMER_CH_0: + TIMER_FCCHP0(timer_periph) &= (~(uint32_t)(TIMER_FCCHP0_DTCFG | TIMER_FCCHP0_IOS | TIMER_FCCHP0_ROS | TIMER_FCCHP0_FCCHP0EN)); + TIMER_FCCHP0(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP0(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP0(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP0(timer_periph) |= fcpara->freecomstate; + break; + case TIMER_CH_1: + TIMER_FCCHP1(timer_periph) &= (~(uint32_t)(TIMER_FCCHP1_DTCFG | TIMER_FCCHP1_IOS | TIMER_FCCHP1_ROS | TIMER_FCCHP1_FCCHP1EN)); + TIMER_FCCHP1(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP1(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP1(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP1(timer_periph) |= fcpara->freecomstate; + break; + case TIMER_CH_2: + TIMER_FCCHP2(timer_periph) &= (~(uint32_t)(TIMER_FCCHP2_DTCFG | TIMER_FCCHP2_IOS | TIMER_FCCHP2_ROS | TIMER_FCCHP2_FCCHP2EN)); + TIMER_FCCHP2(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP2(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP2(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP2(timer_periph) |= fcpara->freecomstate; + break; + case TIMER_CH_3: + TIMER_FCCHP3(timer_periph) &= (~(uint32_t)(TIMER_FCCHP3_DTCFG | TIMER_FCCHP3_IOS | TIMER_FCCHP3_ROS | TIMER_FCCHP3_FCCHP3EN)); + TIMER_FCCHP3(timer_periph) |= fcpara->deadtime; + TIMER_FCCHP3(timer_periph) |= fcpara->ideloffstate; + TIMER_FCCHP3(timer_periph) |= fcpara->runoffstate; + TIMER_FCCHP3(timer_periph) |= fcpara->freecomstate; + break; + default: + break; + } +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] flag: the TIMER flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_FLAG_CH0: channel 0 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH1: channel 1 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH2: channel 2 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH3: channel 3 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_BRK: break flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_MCH0: multi mode channel 0 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH1: multi mode channel 1 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH2: multi mode channel 2 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH3: multi mode channel 3 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH0O: multi mode channel 0 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH1O: multi mode channel 1 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH2O: multi mode channel 2 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH3O: multi mode channel 3 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH0COMADD: channel 0 additional compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH1COMADD: channel 1 additional compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH2COMADD: channel 2 additional compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH3COMADD: channel 3 additional compare flag, TIMERx(x=0,7,19,20) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if((uint32_t)RESET != (TIMER_INTF(timer_periph) & flag)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] flag: the TIMER flags + one or more parameters can be selected which are shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_FLAG_CH0: channel 0 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH1: channel 1 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH2: channel 2 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH3: channel 3 capture or compare flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CMT: channel commutation flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_BRK: break flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_FLAG_MCH0: multi mode channel 0 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH1: multi mode channel 1 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH2: multi mode channel 2 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH3: multi mode channel 3 capture or compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH0O: multi mode channel 0 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH1O: multi mode channel 1 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH2O: multi mode channel 2 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_MCH3O: multi mode channel 3 overcapture flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH0COMADD: channel 0 additional compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH1COMADD: channel 1 additional compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH2COMADD: channel 2 additional compare flag, TIMERx(x=0,7,19,20) + \arg TIMER_FLAG_CH3COMADD: channel 3 additional compare flag, TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)flag); +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] interrupt: timer interrupt source + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_UP: update interrupt, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_INT_CH0: channel 0 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CH1: channel 1 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CH2: channel 2 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CH3: channel 3 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CMT: commutation interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_TRG: trigger interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_BRK: break interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH0: multi mode channel 0 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH1: multi mode channel 1 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH2: multi mode channel 2 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH3: multi mode channel 3 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH0COMADD: channel 0 additional compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH1COMADD: channel 1 additional compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH2COMADD: channel 2 additional compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH3COMADD: channel 3 additional compare interrupt, TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; +} + +/*! + \brief disable the TIMER interrupt + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] interrupt: timer interrupt source + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_UP: update interrupt, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_INT_CH0: channel 0 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CH1: channel 1 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CH2: channel 2 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CH3: channel 3 capture or compare interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_CMT: commutation interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_TRG: trigger interrupt, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_BRK: break interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH0: multi mode channel 0 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH1: multi mode channel 1 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH2: multi mode channel 2 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_MCH3: multi mode channel 3 capture or compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH0COMADD: channel 0 additional compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH1COMADD: channel 1 additional compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH2COMADD: channel 2 additional compare interrupt, TIMERx(x=0,7,19,20) + \arg TIMER_INT_CH3COMADD: channel 3 additional compare interrupt, TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get timer interrupt flags + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] int_flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_INT_FLAG_CH0: channel 0 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CH1: channel 1 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CH2: channel 2 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CH3: channel 3 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH0: multi mode channel 0 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH1: multi mode channel 1 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH2: multi mode channel 2 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH3: multi mode channel 3 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH0COMADD: channel 0 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH1COMADD: channel 1 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH2COMADD: channel 2 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH3COMADD: channel 3 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t int_flag) +{ + uint32_t val; + val = (TIMER_DMAINTEN(timer_periph) & int_flag); + if(((uint32_t)RESET != (TIMER_INTF(timer_periph) & int_flag)) && ((uint32_t)RESET != val)) { + return SET; + } else { + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flags + \param[in] timer_periph: TIMERx(x=0,1,5,6,7,19,20) + \param[in] int_flag: the timer interrupt flags + one or more parameters can be selected which are shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0,1,5,6,7,19,20) + \arg TIMER_INT_FLAG_CH0: channel 0 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CH1: channel 1 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CH2: channel 2 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CH3: channel 3 capture or compare interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0,1,7,19,20) + \arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH0: multi mode channel 0 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH1: multi mode channel 1 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH2: multi mode channel 2 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_MCH3: multi mode channel 3 capture or compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH0COMADD: channel 0 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH1COMADD: channel 1 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH2COMADD: channel 2 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \arg TIMER_INT_FLAG_CH3COMADD: channel 3 additional compare interrupt flag, TIMERx(x=0,7,19,20) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t int_flag) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)int_flag); +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_trigsel.c b/gd32a50x/standard_peripheral/source/gd32a50x_trigsel.c new file mode 100644 index 0000000..5d2e3df --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_trigsel.c @@ -0,0 +1,382 @@ +/*! + \file gd32a50x_trigsel.c + \brief TRIGSEL driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_trigsel.h" + +/* TRIGSEL target register redefine */ +#define TRIGSEL_TARGET_REG(target_periph) REG32(TRIGSEL + ((uint8_t)(target_periph) & BITS(2, 7))) /*!< target peripheral register */ +#define TRIGSEL_TARGET_PERIPH_SHIFT(target_periph) (((uint8_t)(target_periph) & BITS(0, 1)) << 3) /*!< bit shift in target peripheral register */ +#define TRIGSEL_TARGET_PERIPH_MASK(target_periph) ((uint32_t)(TRIGSEL_TARGET_INSEL0 << TRIGSEL_TARGET_PERIPH_SHIFT(target_periph))) /*!< bit mask in target peripheral register */ + +/*! + \brief set the trigger input signal for target peripheral + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_RTTRG: output target peripheral ADC0_RTTRG + \arg TRIGSEL_OUTPUT_ADC1_RTTRG: output target peripheral ADC1_RTTRG + \arg TRIGSEL_OUTPUT_DAC_EXTRIG: output target peripheral DAC_EXTRIG + \arg TRIGSEL_OUTPUT_TIMER0_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER0_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER0_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER0_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER7_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER7_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER7_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER7_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER20_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER20_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER20_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER20_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER1_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER1_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER1_ITI3 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER0 output target peripheral MFCOM_TRG_TIMER0 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER1 output target peripheral MFCOM_TRG_TIMER1 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER2 output target peripheral MFCOM_TRG_TIMER2 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER3 output target peripheral MFCOM_TRG_TIMER3 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK output target peripheral CAN1_EX_TIME_TICK + \param[in] trigger_source: trigger source value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_INPUT_0: trigger input source 0 + \arg TRIGSEL_INPUT_1: trigger input source 1 + \arg TRIGSEL_INPUT_TRIGSEL_IN0: trigger input source TRIGSEL_IN0 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN1: trigger input source TRIGSEL_IN1 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN2: trigger input source TRIGSEL_IN2 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN3: trigger input source TRIGSEL_IN3 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN4: trigger input source TRIGSEL_IN4 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN5: trigger input source TRIGSEL_IN5 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN6: trigger input source TRIGSEL_IN6 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN7: trigger input source TRIGSEL_IN7 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN8: trigger input source TRIGSEL_IN8 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN9: trigger input source TRIGSEL_IN9 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN10: trigger input source TRIGSEL_IN10 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN11: trigger input source TRIGSEL_IN11 pin + \arg TRIGSEL_INPUT_CMP_OUT: trigger input source CMP_OUT + \arg TRIGSEL_INPUT_LXTAL_TRG: trigger input source LSE_TRG + \arg TRIGSEL_INPUT_TIMER1_CH0: trigger input source timer1 channel 0 + \arg TRIGSEL_INPUT_TIMER1_CH1: trigger input source timer1 channel 1 + \arg TRIGSEL_INPUT_TIMER1_CH2: trigger input source timer1 channel 2 + \arg TRIGSEL_INPUT_TIMER1_CH3: trigger input source timer1 channel 3 + \arg TRIGSEL_INPUT_TIMER1_TRGO: trigger input source timer1 TRGO + \arg TRIGSEL_INPUT_TIMER0_CH0: trigger input source timer0 channel 0 + \arg TRIGSEL_INPUT_TIMER0_CH1: trigger input source timer0 channel 1 + \arg TRIGSEL_INPUT_TIMER0_CH2: trigger input source timer0 channel 2 + \arg TRIGSEL_INPUT_TIMER0_CH3: trigger input source timer0 channel 3 + \arg TRIGSEL_INPUT_TIMER0_MCH0: trigger input source timer0 channel 0N + \arg TRIGSEL_INPUT_TIMER0_MCH1: trigger input source timer0 channel 1N + \arg TRIGSEL_INPUT_TIMER0_MCH2: trigger input source timer0 channel 2N + \arg TRIGSEL_INPUT_TIMER0_MCH3: trigger input source timer0 channel 3N + \arg TRIGSEL_INPUT_TIMER0_TRGO: trigger input source timer0 TRGO + \arg TRIGSEL_INPUT_TIMER7_CH0: trigger input source timer7 channel 0 + \arg TRIGSEL_INPUT_TIMER7_CH1: trigger input source timer7 channel 1 + \arg TRIGSEL_INPUT_TIMER7_CH2: trigger input source timer7 channel 2 + \arg TRIGSEL_INPUT_TIMER7_CH3: trigger input source timer7 channel 3 + \arg TRIGSEL_INPUT_TIMER7_MCH0: trigger input source timer7 channel 0N + \arg TRIGSEL_INPUT_TIMER7_MCH1: trigger input source timer7 channel 1N + \arg TRIGSEL_INPUT_TIMER7_MCH2: trigger input source timer7 channel 2N + \arg TRIGSEL_INPUT_TIMER7_MCH3: trigger input source timer7 channel 3N + \arg TRIGSEL_INPUT_TIMER7_TRGO: trigger input source timer7 TRGO + \arg TRIGSEL_INPUT_TIMER19_CH0: trigger input source timer19 channel 0 + \arg TRIGSEL_INPUT_TIMER19_CH1: trigger input source timer19 channel 1 + \arg TRIGSEL_INPUT_TIMER19_CH2: trigger input source timer19 channel 2 + \arg TRIGSEL_INPUT_TIMER19_CH3: trigger input source timer19 channel 3 + \arg TRIGSEL_INPUT_TIMER19_MCH0: trigger input source timer19 channel 0N + \arg TRIGSEL_INPUT_TIMER19_MCH1: trigger input source timer19 channel 1N + \arg TRIGSEL_INPUT_TIMER19_MCH2: trigger input source timer19 channel 2N + \arg TRIGSEL_INPUT_TIMER19_MCH3: trigger input source timer19 channel 3N + \arg TRIGSEL_INPUT_TIMER19_TRGO: trigger input source timer19 TRGO + \arg TRIGSEL_INPUT_TIMER20_CH0: trigger input source timer20 channel 0 + \arg TRIGSEL_INPUT_TIMER20_CH1: trigger input source timer20 channel 1 + \arg TRIGSEL_INPUT_TIMER20_CH2: trigger input source timer20 channel 2 + \arg TRIGSEL_INPUT_TIMER20_CH3: trigger input source timer20 channel 3 + \arg TRIGSEL_INPUT_TIMER20_MCH0: trigger input source timer20 channel 0N + \arg TRIGSEL_INPUT_TIMER20_MCH1: trigger input source timer20 channel 1N + \arg TRIGSEL_INPUT_TIMER20_MCH2: trigger input source timer20 channel 2N + \arg TRIGSEL_INPUT_TIMER20_MCH3: trigger input source timer20 channel 3N + \arg TRIGSEL_INPUT_TIMER20_TRGO: trigger input source timer20 TRGO + \arg TRIGSEL_INPUT_TIMER5_TRGO: trigger input source timer5 TRGO + \arg TRIGSEL_INPUT_TIMER6_TRGO: trigger input source timer6 TRGO + \arg TRIGSEL_INPUT_MFCOM_TRIG0: trigger input source MFCOM TRIG0 + \arg TRIGSEL_INPUT_MFCOM_TRIG1: trigger input source MFCOM TRIG1 + \arg TRIGSEL_INPUT_MFCOM_TRIG2: trigger input source MFCOM TRIG2 + \arg TRIGSEL_INPUT_MFCOM_TRIG3: trigger input source MFCOM TRIG3 + \arg TRIGSEL_INPUT_RTC_ALARM: trigger input source RTC alarm + \arg TRIGSEL_INPUT_RTC_SECOND: trigger input source RTC second + \arg TRIGSEL_INPUT_TRIGSEL_IN12: trigger input source TRIGSEL_IN12 pin + \arg TRIGSEL_INPUT_TRIGSEL_IN13: trigger input source TRIGSEL_IN13 pin + \param[out] none + \retval none +*/ +void trigsel_init(trigsel_periph_enum target_periph, trigsel_source_enum trigger_source) +{ + /* if register write is enabled, set trigger source to target peripheral */ + if (RESET == trigsel_register_lock_get(target_periph)){ + TRIGSEL_TARGET_REG(target_periph) &= ~TRIGSEL_TARGET_PERIPH_MASK(target_periph); + TRIGSEL_TARGET_REG(target_periph) |= ((uint32_t)trigger_source << TRIGSEL_TARGET_PERIPH_SHIFT(target_periph)) & TRIGSEL_TARGET_PERIPH_MASK(target_periph); + } +} + +/*! + \brief get the trigger input signal for target peripheral + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_RTTRG: output target peripheral ADC0_RTTRG + \arg TRIGSEL_OUTPUT_ADC1_RTTRG: output target peripheral ADC1_RTTRG + \arg TRIGSEL_OUTPUT_DAC_EXTRIG: output target peripheral DAC_EXTRIG + \arg TRIGSEL_OUTPUT_TIMER0_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER0_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER0_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER0_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER7_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER7_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER7_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER7_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER20_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER20_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER20_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER20_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER1_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER1_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER1_ITI3 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER0 output target peripheral MFCOM_TRG_TIMER0 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER1 output target peripheral MFCOM_TRG_TIMER1 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER2 output target peripheral MFCOM_TRG_TIMER2 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER3 output target peripheral MFCOM_TRG_TIMER3 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK output target peripheral CAN1_EX_TIME_TICK + \param[out] none + \retval trigger_source: trigger source value(0~67) +*/ +uint8_t trigsel_trigger_source_get(trigsel_periph_enum target_periph) +{ + uint8_t trigger_source; + + trigger_source = (uint8_t)((TRIGSEL_TARGET_REG(target_periph) & TRIGSEL_TARGET_PERIPH_MASK(target_periph)) >> TRIGSEL_TARGET_PERIPH_SHIFT(target_periph)); + + return trigger_source; +} + +/*! + \brief lock the trigger register + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_RTTRG: output target peripheral ADC0_RTTRG + \arg TRIGSEL_OUTPUT_ADC1_RTTRG: output target peripheral ADC1_RTTRG + \arg TRIGSEL_OUTPUT_DAC_EXTRIG: output target peripheral DAC_EXTRIG + \arg TRIGSEL_OUTPUT_TIMER0_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER0_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER0_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER0_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER7_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER7_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER7_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER7_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER20_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER20_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER20_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER20_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER1_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER1_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER1_ITI3 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER0 output target peripheral MFCOM_TRG_TIMER0 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER1 output target peripheral MFCOM_TRG_TIMER1 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER2 output target peripheral MFCOM_TRG_TIMER2 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER3 output target peripheral MFCOM_TRG_TIMER3 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK output target peripheral CAN1_EX_TIME_TICK + \param[out] none + \retval none +*/ +void trigsel_register_lock_set(trigsel_periph_enum target_periph) +{ + /*!< lock target peripheral register */ + TRIGSEL_TARGET_REG(target_periph) |= TRIGSEL_TARGET_LK; +} + +/*! + \brief get the trigger register lock status + \param[in] target_periph: target peripheral value + only one parameter can be selected which is shown as below: + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin + \arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin + \arg TRIGSEL_OUTPUT_ADC0_RTTRG: output target peripheral ADC0_RTTRG + \arg TRIGSEL_OUTPUT_ADC1_RTTRG: output target peripheral ADC1_RTTRG + \arg TRIGSEL_OUTPUT_DAC_EXTRIG: output target peripheral DAC_EXTRIG + \arg TRIGSEL_OUTPUT_TIMER0_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER0_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER0_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER0_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER7_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER7_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER7_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER7_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER19_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER20_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER20_ITI1: output target peripheral TIMER0_ITI1 + \arg TRIGSEL_OUTPUT_TIMER20_ITI2: output target peripheral TIMER0_ITI2 + \arg TRIGSEL_OUTPUT_TIMER20_ITI3: output target peripheral TIMER0_ITI3 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN0 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN1 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN2 + \arg TRIGSEL_OUTPUT_TIMER20_BRKIN0: output target peripheral TIMER0_BRKIN3 + \arg TRIGSEL_OUTPUT_TIMER1_ITI0: output target peripheral TIMER0_ITI0 + \arg TRIGSEL_OUTPUT_TIMER1_ITI1: output target peripheral TIMER1_ITI1 + \arg TRIGSEL_OUTPUT_TIMER1_ITI2: output target peripheral TIMER1_ITI2 + \arg TRIGSEL_OUTPUT_TIMER1_ITI3: output target peripheral TIMER1_ITI3 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER0 output target peripheral MFCOM_TRG_TIMER0 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER1 output target peripheral MFCOM_TRG_TIMER1 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER2 output target peripheral MFCOM_TRG_TIMER2 + \arg TRIGSEL_OUTPUT_MFCOM_TRG_TIMER3 output target peripheral MFCOM_TRG_TIMER3 + \arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK output target peripheral CAN0_EX_TIME_TICK + \arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK output target peripheral CAN1_EX_TIME_TICK + \param[out] none + \retval SET or RESET +*/ +FlagStatus trigsel_register_lock_get(trigsel_periph_enum target_periph) +{ + if(0U != (TRIGSEL_TARGET_REG(target_periph) & TRIGSEL_TARGET_LK)){ + return SET; + }else{ + return RESET; + } +} diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_usart.c b/gd32a50x/standard_peripheral/source/gd32a50x_usart.c new file mode 100644 index 0000000..69c4f15 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_usart.c @@ -0,0 +1,1291 @@ +/*! + \file gd32a50x_usart.c + \brief USART driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + + +#include "gd32a50x_usart.h" + +/*! + \brief reset USART + \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 + \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, intdiv = 0U, fradiv = 0U, udiv = 0U; + switch(usart_periph){ + /* get clock frequency */ + case USART0: + /* get USART0 clock */ + uclk = rcu_clock_freq_get(CK_USART0); + break; + case USART1: + /* get USART1 clock */ + uclk = rcu_clock_freq_get(CK_USART1); + break; + case USART2: + /* get USART2 clock */ + uclk = rcu_clock_freq_get(CK_USART2); + break; + default: + break; + } + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + /* oversampling by 8, configure the value of USART_BAUD */ + udiv = ((2U * uclk) + (baudval / 2U)) / baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = (udiv >> 1U) & 0x00000007U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + }else{ + /* oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk + (baudval / 2U)) / baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = udiv & 0x0000000fU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] paritycfg: USART parity configure + only one parameter can be selected which is shown as below: + \arg USART_PM_NONE: no parity + \arg USART_PM_ODD: odd parity + \arg USART_PM_EVEN: even parity + \param[out] none + \retval none +*/ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 PM,PCEN bits */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); + /* configure USART parity mode */ + USART_CTL0(usart_periph) |= paritycfg; +} + +/*! + \brief configure USART word length + \param[in] usart_periph: USARTx(x=0,1,2) + \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; +} + +/*! + \brief configure USART stop bit length + \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; +} + +/*! + \brief enable USART + \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 + \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 + \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; +} + +/*! + \brief configure USART receiver + \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; +} + +/*! + \brief data is transmitted/received with the LSB/MSB first + \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) |= msbf; +} + +/*! + \brief configure USART inverted + \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 + \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 + \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 + \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; +} + +/*! + \brief configure the sample bit method + \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; +} + +/*! + \brief enable receiver timeout + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_RTEN; +} + +/*! + \brief disable receiver timeout + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN); +} + +/*! + \brief configure receiver timeout threshold + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] rtimeout: 0x00000000-0x00FFFFFF, receiver timeout value in terms of number of baud clocks + \param[out] none + \retval none +*/ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout) +{ + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= rtimeout; +} + +/*! + \brief USART transmit data function + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint16_t data) +{ + USART_TDATA(usart_periph) = (USART_TDATA_TDATA & (uint32_t)data); +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval data of received +*/ +uint16_t usart_data_receive(uint32_t usart_periph) +{ + return (uint16_t)(GET_BITS(USART_RDATA(usart_periph), 0U, 8U)); +} + +/*! + \brief enable USART command + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] cmdtype: command type + only one parameter can be selected which is shown as below: + \arg USART_CMD_SBKCMD: send break command + \arg USART_CMD_MMCMD: mute mode command + \arg USART_CMD_RXFCMD: receive data flush command + \arg USART_CMD_TXFCMD: transmit data flush request + \param[out] none + \retval none +*/ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype) +{ + USART_CMD(usart_periph) |= (cmdtype); +} + +/*! + \brief address of the USART terminal + \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_DATA); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR_DATA & (((uint32_t)addr) << 24)); +} + +/*! + \brief configure address detection mode + \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 + \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 + \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 + \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 match + \arg USART_WM_DATA: data match + \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_WM0 | USART_CTL0_WM1); + USART_CTL0(usart_periph) |= wmethod; +} + +/*! + \brief enable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief LIN break detection length + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] lblen: LIN break detection length + only one parameter can be selected which is shown as below: + \arg USART_LBLEN_10B: 10 bits break detection + \arg USART_LBLEN_11B: 11 bits break detection + \param[out] none + \retval none +*/ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= USART_CTL1_LBLEN & (lblen); +} + +/*! + \brief enable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_halfduplex_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_HDEN; +} + +/*! + \brief disable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_halfduplex_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable clock + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_clock_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable clock + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_clock_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN); +} + +/*! + \brief configure USART synchronous mode parameters + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] clen: last bit clock pulse + only one parameter can be selected which is shown as below: + \arg USART_CLEN_NONE: clock pulse of the last data bit (MSB) is not output to the CK pin + \arg USART_CLEN_EN: clock pulse of the last data bit (MSB) is output to the CK pin + \param[in] cph: clock phase + only one parameter can be selected which is shown as below: + \arg USART_CPH_1CK: first clock transition is the first data capture edge + \arg USART_CPH_2CK: second clock transition is the first data capture edge + \param[in] cpl: clock polarity + only one parameter can be selected which is shown as below: + \arg USART_CPL_LOW: steady low value on CK pin + \arg USART_CPL_HIGH: steady high value on CK pin + \param[out] none + \retval none +*/ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset USART_CTL1 CLEN,CPH,CPL bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + + USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen); + USART_CTL1(usart_periph) |= (USART_CTL1_CPH & cph); + USART_CTL1(usart_periph) |= (USART_CTL1_CPL & cpl); +} + +/*! + \brief configure guard time value in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] guat: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat) << 8)); +} + +/*! + \brief enable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief disable smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief enable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief disable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief enable early NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] scrtnum: 0x00000000-0x00000007, smartcard auto-retry number + \param[out] none + \retval none +*/ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCRTNUM); + USART_CTL2(usart_periph) |= (USART_CTL2_SCRTNUM & (scrtnum << 17)); +} + +/*! + \brief configure block length + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] bl: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << 24)); +} + +/*! + \brief enable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power or smartcard mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] psc: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= psc; +} + +/*! + \brief configure IrDA low-power + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] irlp: IrDA low-power or normal + only one parameter can be selected which is shown as below: + \arg USART_IRLP_LOW: low-power + \arg USART_IRLP_NORMAL: normal + \param[out] none + \retval none +*/ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP); + USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp); +} + +/*! + \brief configure hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] rtsconfig: enable or disable RTS + only one parameter can be selected which is shown as below: + \arg USART_RTS_ENABLE: enable RTS + \arg USART_RTS_DISABLE: disable RTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN); + USART_CTL2(usart_periph) |= rtsconfig; +} + +/*! + \brief configure hardware flow control CTS + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] ctsconfig: enable or disable CTS + only one parameter can be selected which is shown as below: + \arg USART_CTS_ENABLE: enable CTS + \arg USART_CTS_DISABLE: disable CTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_CTSEN); + USART_CTL2(usart_periph) |= ctsconfig; +} + + /*! + \brief configure hardware flow control coherence mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] hcm: + only one parameter can be selected which is shown as below: + \arg USART_HCM_NONE: nRTS signal equals to the rbne 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) |= hcm; +} + +/*! + \brief enable RS485 driver + \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 + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] deatime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DEA); + USART_CTL0(usart_periph) |= (USART_CTL0_DEA & ((deatime) << 21)); +} + +/*! + \brief configure driver enable de-assertion time + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] dedtime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DED); + USART_CTL0(usart_periph) |= (USART_CTL0_DED & ((dedtime) << 16)); +} + +/*! + \brief configure driver enable polarity mode + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] dmaconfig: USART DMA mode + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_DMA_ENABLE: enable USART DMA for reception + \arg USART_RECEIVE_DMA_DISABLE: disable USART DMA for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint8_t dmaconfig) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DENR); + USART_CTL2(usart_periph) |= (USART_CTL2_DENR & dmaconfig); +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] dmaconfig: USART DMA mode + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_DMA_ENABLE: enable USART DMA for transmission + \arg USART_TRANSMIT_DMA_DISABLE: disable USART DMA for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint8_t dmaconfig) +{ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DENT); + USART_CTL2(usart_periph) |= (USART_CTL2_DENT & dmaconfig); +} + +/*! + \brief disable DMA on reception error + \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 + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_wakeup_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UESM; +} + +/*! + \brief disable USART to wakeup the MCU from deep-sleep mode + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval none +*/ +void usart_wakeup_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM); +} + +/*! + \brief configure the USART wakeup mode from deep-sleep mode + \param[in] usart_periph: USARTx(x=0,1,2) + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \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 + \param[in] usart_periph: USARTx(x=0,1,2) + \param[out] none + \retval receive FIFO counter number +*/ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph) +{ + return (uint8_t)(GET_BITS(USART_RFCS(usart_periph), 12U, 14U)); +} + +/*! + \brief get USART status + \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_REA: receive enable acknowledge flag + \arg USART_FLAG_TEA: transmit enable acknowledge flag + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_RWU: receiver wakeup from mute mode + \arg USART_FLAG_SB: send break flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_CTS: CTS level + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_TBE: transmit data register empty + \arg USART_FLAG_TC: transmission completed + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_EPERR: early parity error flag + \arg USART_FLAG_RFFINT: receive FIFO full interrupt flag + \arg USART_FLAG_RFF: receive FIFO full flag + \arg USART_FLAG_RFE: receive FIFO empty flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) +{ + if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART status + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_TC: transmission complete flag + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_ORERR: overrun error flag + \arg USART_FLAG_NERR: noise detected flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_EPERR: early parity error flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + if(flag == USART_FLAG_RBNE){ + USART_CMD(usart_periph) |= USART_CMD_RXFCMD; + }else if(flag == USART_FLAG_EPERR){ + USART_CHC(usart_periph) &= ~USART_CHC_EPERR; + }else{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); + } + +} + +/*! + \brief enable USART interrupt + \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_EB: end of block interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt enable interrupt + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_RFF: receive FIFO full interrupt enable + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt) +{ + USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt)); +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] interrupt: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt enable interrupt + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_RFF: receive FIFO full interrupt enable + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt) +{ + USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt)); +} + +/*! + \brief get USART interrupt and flag status + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_EB: end of block interrupt and flag + \arg USART_INT_FLAG_RT: receiver timeout interrupt and flag + \arg USART_INT_FLAG_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 + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt and flag + \arg USART_INT_FLAG_CTS: CTS interrupt and flag + \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag))); + + if(flagstatus && intenable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART interrupt flag + \param[in] usart_periph: USARTx(x=0,1,2) + \param[in] int_flag: USART interrupt flag + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_EB: end of block flag + \arg USART_INT_FLAG_RT: receiver timeout flag + \arg USART_INT_FLAG_AM: address match flag + \arg USART_INT_FLAG_PERR: parity error flag + \arg USART_INT_FLAG_TC: transmission complete 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 flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_ERR_NERR: noise detected flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_FERR: frame error flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + if(USART_INT_FLAG_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/gd32a50x/standard_peripheral/source/gd32a50x_wwdgt.c b/gd32a50x/standard_peripheral/source/gd32a50x_wwdgt.c new file mode 100644 index 0000000..10cf040 --- /dev/null +++ b/gd32a50x/standard_peripheral/source/gd32a50x_wwdgt.c @@ -0,0 +1,125 @@ +/*! + \file gd32fxxx_wwdgt.c + \brief WWDGT driver + + \version 2022-01-30, V1.0.0, firmware for GD32A50x +*/ + +/* + Copyright (c) 2022, GigaDevice Semiconductor Inc. + + Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +*/ + +#include "gd32a50x_wwdgt.h" + +/*! + \brief reset the window watchdog timer configuration + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_deinit(void) +{ + rcu_periph_reset_enable(RCU_WWDGTRST); + rcu_periph_reset_disable(RCU_WWDGTRST); +} + +/*! + \brief start the WWDGT counter + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure the WWDGT counter value + \param[in] counter_value: 0x40 - 0x7F + \param[out] none + \retval none +*/ +void wwdgt_counter_update(uint16_t counter_value) +{ + WWDGT_CTL = (uint32_t)(CTL_CNT(counter_value)); +} + +/*! + \brief configure counter value, window value, and prescaler divider value + \param[in] counter: 0x40 - 0x7F + \param[in] window: 0x40 - 0x7F + \param[in] prescaler: WWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1 + \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2 + \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4 + \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8 + \param[out] none + \retval none +*/ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler) +{ + WWDGT_CTL = (uint32_t)(CTL_CNT(counter)); + WWDGT_CFG = (uint32_t)(CFG_WIN(window) | prescaler); +} + +/*! + \brief check early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus wwdgt_flag_get(void) +{ + if (0U != (WWDGT_STAT & WWDGT_STAT_EWIF)){ + return SET; + } + + return RESET; +} + +/*! + \brief clear early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_flag_clear(void) +{ + WWDGT_STAT = (uint32_t)RESET; +} + +/*! + \brief enable early wakeup interrupt of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_interrupt_enable(void) +{ + WWDGT_CFG |= WWDGT_CFG_EWIE; +} From 1a68a87097c7d37b96efe6c41a76a4e615b1e5cd Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 4 Dec 2022 13:02:22 +0800 Subject: [PATCH 2/8] hal: gd32a503: apply patches apply fllowing patches for hal: - drop I2CCLK_MAX/I2CCLK_MIN - add `gd32_` prefix for timer_init - add ifdef to BIT macro - remove nvic_vector_table_set function call - rename CAN_xxx_MODE to GD32_CAN_xxx_MODE Signed-off-by: YuLong Yao --- gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h | 2 + .../gd/gd32a50x/source/system_gd32a50x.c | 6 --- .../include/gd32a50x_can.h | 12 +++--- .../include/gd32a50x_i2c.h | 5 +++ .../include/gd32a50x_timer.h | 2 +- .../standard_peripheral/source/gd32a50x_can.c | 42 +++++++++---------- .../source/gd32a50x_timer.c | 2 +- 7 files changed, 36 insertions(+), 35 deletions(-) diff --git a/gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h b/gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h index b0f58a8..4a0f0ea 100644 --- a/gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h +++ b/gd32a50x/cmsis/gd/gd32a50x/include/gd32a50x.h @@ -190,7 +190,9 @@ typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; #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 /* BIT */ #define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) #define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) diff --git a/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c b/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c index e42cc91..9b0ad76 100644 --- a/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c +++ b/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c @@ -157,12 +157,6 @@ void SystemInit(void) RCU_BDCTL |= RCU_BDCTL_LXTALBPS; } } - -#ifdef VECT_TAB_SRAM - nvic_vector_table_set(NVIC_VECTTAB_RAM, VECT_TAB_OFFSET); -#else - nvic_vector_table_set(NVIC_VECTTAB_FLASH, VECT_TAB_OFFSET); -#endif } /*! diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_can.h b/gd32a50x/standard_peripheral/include/gd32a50x_can.h index 5d679b6..a3fcf28 100644 --- a/gd32a50x/standard_peripheral/include/gd32a50x_can.h +++ b/gd32a50x/standard_peripheral/include/gd32a50x_can.h @@ -724,12 +724,12 @@ typedef enum { /* operation modes */ typedef enum { - CAN_NORMAL_MODE = 0U, /*!< normal mode */ - CAN_MONITOR_MODE = 1U, /*!< monitor mode */ - CAN_LOOPBACK_SILENT_MODE = 2U, /*!< loopback mode */ - CAN_INACTIVE_MODE = 3U, /*!< inactive mode */ - CAN_DISABLE_MODE = 4U, /*!< disable mode */ - CAN_PN_MODE = 5U /*!< Pretended Networking mode */ + GD32_CAN_NORMAL_MODE = 0U, /*!< normal mode */ + GD32_CAN_MONITOR_MODE = 1U, /*!< monitor mode */ + GD32_CAN_LOOPBACK_SILENT_MODE = 2U, /*!< loopback mode */ + GD32_CAN_INACTIVE_MODE = 3U, /*!< inactive mode */ + GD32_CAN_DISABLE_MODE = 4U, /*!< disable mode */ + GD32_CAN_PN_MODE = 5U /*!< Pretended Networking mode */ } can_operation_modes_enum; /* initiliaze parameter type */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_i2c.h b/gd32a50x/standard_peripheral/include/gd32a50x_i2c.h index 8189728..966399c 100644 --- a/gd32a50x/standard_peripheral/include/gd32a50x_i2c.h +++ b/gd32a50x/standard_peripheral/include/gd32a50x_i2c.h @@ -269,6 +269,11 @@ typedef enum { #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 */ +#define I2CCLK_MAX ((uint32_t)0x0000003FU)/*!< i2cclk maximum value */ +#define I2CCLK_MIN ((uint32_t)0x00000002U)/*!< i2cclk minimum value for standard mode */ +#define I2CCLK_FM_MIN ((uint32_t)0x00000008U)/*!< i2cclk minimum value for fast mode */ +#define I2CCLK_FM_PLUS_MIN ((uint32_t)0x00000018U)/*!< i2cclk minimum value for fast mode plus */ + /* function declarations */ /* initialization functions */ /* reset I2C */ diff --git a/gd32a50x/standard_peripheral/include/gd32a50x_timer.h b/gd32a50x/standard_peripheral/include/gd32a50x_timer.h index 47a598b..c555a58 100644 --- a/gd32a50x/standard_peripheral/include/gd32a50x_timer.h +++ b/gd32a50x/standard_peripheral/include/gd32a50x_timer.h @@ -937,7 +937,7 @@ void timer_deinit(uint32_t timer_periph); /* initialize TIMER init parameter struct */ void timer_struct_para_init(timer_parameter_struct *initpara); /* initialize TIMER counter */ -void timer_init(uint32_t timer_periph, timer_parameter_struct *initpara); +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 */ diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_can.c b/gd32a50x/standard_peripheral/source/gd32a50x_can.c index 20690c4..ffd89bb 100644 --- a/gd32a50x/standard_peripheral/source/gd32a50x_can.c +++ b/gd32a50x/standard_peripheral/source/gd32a50x_can.c @@ -359,12 +359,12 @@ void can_private_filter_config(uint32_t can_periph, uint32_t index, uint32_t fil \param[in] can_periph: CANx(x=0,1) \param[in] mode: the mode to enter only one parameter can be selected which is shown as below: - \arg CAN_NORMAL_MODE: normal mode - \arg CAN_MONITOR_MODE: monitor mode - \arg CAN_LOOPBACK_SILENT_MODE: loopback mode - \arg CAN_INACTIVE_MODE: inactive mode - \arg CAN_DISABLE_MODE: disable mode - \arg CAN_PN_MODE: Pretended Networking mode + \arg GD32_CAN_NORMAL_MODE: normal mode + \arg GD32_CAN_MONITOR_MODE: monitor mode + \arg GD32_CAN_LOOPBACK_SILENT_MODE: loopback mode + \arg GD32_CAN_INACTIVE_MODE: inactive mode + \arg GD32_CAN_DISABLE_MODE: disable mode + \arg GD32_CAN_PN_MODE: Pretended Networking mode \param[out] none \retval ERROR or SUCCESS */ @@ -391,25 +391,25 @@ ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum /* configure the modes */ switch(mode) { - case CAN_NORMAL_MODE: + case GD32_CAN_NORMAL_MODE: CAN_CTL1(can_periph) &= ~(CAN_CTL1_LSCMOD | CAN_CTL1_MMOD); break; - case CAN_MONITOR_MODE: + case GD32_CAN_MONITOR_MODE: CAN_CTL1(can_periph) &= ~CAN_CTL1_LSCMOD; CAN_CTL1(can_periph) |= CAN_CTL1_MMOD; break; - case CAN_LOOPBACK_SILENT_MODE: + case GD32_CAN_LOOPBACK_SILENT_MODE: CAN_CTL1(can_periph) &= ~CAN_CTL1_MMOD; CAN_CTL0(can_periph) &= ~CAN_CTL0_SRDIS; CAN_FDCTL(can_periph) &= ~CAN_FDCTL_TDCEN; CAN_CTL1(can_periph) |= CAN_CTL1_LSCMOD; break; - case CAN_INACTIVE_MODE: + case GD32_CAN_INACTIVE_MODE: break; - case CAN_DISABLE_MODE: + case GD32_CAN_DISABLE_MODE: CAN_CTL0(can_periph) |= CAN_CTL0_CANDIS; break; - case CAN_PN_MODE: + case GD32_CAN_PN_MODE: CAN_CTL0(can_periph) |= (CAN_CTL0_PNEN | CAN_CTL0_PNMOD); break; default: @@ -417,7 +417,7 @@ ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum } /* exit INACTIVE mode */ - if(CAN_INACTIVE_MODE != mode) { + if(GD32_CAN_INACTIVE_MODE != mode) { /* exit inactive mode */ CAN_CTL0(can_periph) &= ~(CAN_CTL0_HALT | CAN_CTL0_INAMOD); timeout = CAN_DELAY; @@ -429,7 +429,7 @@ ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum } } - if(CAN_PN_MODE == mode) { + if(GD32_CAN_PN_MODE == mode) { timeout = CAN_DELAY; while((0U == (CAN_CTL0(can_periph) & CAN_CTL0_PNS)) && (timeout)) { timeout--; @@ -450,25 +450,25 @@ ErrStatus can_operation_mode_enter(uint32_t can_periph, can_operation_modes_enum can_operation_modes_enum can_operation_mode_get(uint32_t can_periph) { uint32_t reg; - can_operation_modes_enum state = CAN_NORMAL_MODE; + can_operation_modes_enum state = GD32_CAN_NORMAL_MODE; reg = CAN_CTL0(can_periph); reg &= (CAN_CTL0_NRDY | CAN_CTL0_INAS | CAN_CTL0_PNS | CAN_CTL0_LPS); if((CAN_CTL0_NRDY | CAN_CTL0_LPS) == reg) { - state = CAN_DISABLE_MODE; + state = GD32_CAN_DISABLE_MODE; } else if((CAN_CTL0_NRDY | CAN_CTL0_INAS) == reg) { - state = CAN_INACTIVE_MODE; + state = GD32_CAN_INACTIVE_MODE; } else if(0U == reg) { if(CAN_CTL1(can_periph)&CAN_CTL1_MMOD) { - state = CAN_MONITOR_MODE; + state = GD32_CAN_MONITOR_MODE; } else if(CAN_CTL1(can_periph)&CAN_CTL1_LSCMOD) { - state = CAN_LOOPBACK_SILENT_MODE; + state = GD32_CAN_LOOPBACK_SILENT_MODE; } else { - state = CAN_NORMAL_MODE; + state = GD32_CAN_NORMAL_MODE; } } else if(CAN_CTL0_PNS == reg) { - state = CAN_PN_MODE; + state = GD32_CAN_PN_MODE; } else { /* should not get here */ } diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_timer.c b/gd32a50x/standard_peripheral/source/gd32a50x_timer.c index 4d2e792..22fe6f5 100644 --- a/gd32a50x/standard_peripheral/source/gd32a50x_timer.c +++ b/gd32a50x/standard_peripheral/source/gd32a50x_timer.c @@ -118,7 +118,7 @@ void timer_struct_para_init(timer_parameter_struct *initpara) \param[out] none \retval none */ -void timer_init(uint32_t timer_periph, timer_parameter_struct *initpara) +void gd32_timer_init(uint32_t timer_periph, timer_parameter_struct *initpara) { /* configure the counter prescaler value */ TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; From 9027bfa7b45d04ba51070faab8b4190170456af3 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Wed, 14 Dec 2022 20:50:33 +0800 Subject: [PATCH 3/8] pinconfigs: gd32a503: add gd32a503 pin configurations Add pin configurations for the GD32A503XX series. Information has been taken from datasheet. Signed-off-by: YuLong Yao --- pinconfigs/gd32a503xx.yml | 722 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 722 insertions(+) create mode 100644 pinconfigs/gd32a503xx.yml diff --git a/pinconfigs/gd32a503xx.yml b/pinconfigs/gd32a503xx.yml new file mode 100644 index 0000000..aa0f936 --- /dev/null +++ b/pinconfigs/gd32a503xx.yml @@ -0,0 +1,722 @@ +# GD32A503XX pin definitions +# +# Sources: +# - GD32A503XX Datasheet (Revision 1.3) +# +# Pin codes: +# +# - 32 pins: K +# - 48 pins: C +# - 64 pins: R +# - 100 pins: V +# +# Memory codes: +# +# - 128Kb Flash, 24Kb SRAM: B +# - 256Kb Flash, 32Kb SRAM: C +# - 384Kb Flash, 48Kb SRAM: D +# +# Copyright (c) 2022 YuLong Yao +# SPDX-License-Identifier: Apache 2.0 + +model: af + +series: gd32a503 + +variants: + - pincode: K + memories: [B, C] + - pincode: C + memories: [B, C] + - pincode: R + memories: [B, C, D] + - pincode: V + memories: [B, C, D] + +pins: + PA0: + pincodes: [K, C, R, V] + afs: + TIMER0_CH3: 1 + EVENTOUT: 9 + PA1: + pincodes: [K, C, R, V] + afs: + CK_OUT0: 0 + TIMER0_MCH2: 1 + SPI0_NSS: 4 + TRIGSEL_IN0: 7 + EVENTOUT: 9 + PA2: + pincodes: [K, C, R, V] + afs: + TIMER0_CH2: 1 + SPI0_MOSI: 4 + TRIGSEL_IN1: 7 + EVENTOUT: 9 + PA3: + pincodes: [K, C, R, V] + afs: + ADC0_IN11: ANALOG + TIMER0_MCH1: 1 + TIMER1_CH3: 2 + USART0_TX: 5 + CAN0_TX: 6 + EVENTOUT: 9 + PA4: + pincodes: [K, C, R, V] + afs: + ADC0_IN10: ANALOG + TIMER0_CH1: 1 + USART0_RX: 5 + CAN0_RX: 6 + EVENTOUT: 9 + PA5: + pincodes: [K, C, R, V] + afs: + TIMER19_BRKIN3: 2 + USART2_TX: 5 + EVENTOUT: 9 + PA6: + pincodes: [K, C, R, V] + afs: + TIMER19_BRKIN2: 2 + USART2_RX: 5 + PA7: + pincodes: [K, C, R, V] + afs: + DAC_OUT: ANALOG + TIMER19_MCH1: 1 + TIMER1_CH1: 2 + TIMER19_BRKIN1: 3 + USART2_CK: 5 + TRIGSEL_IN7: 7 + EVENTOUT: 9 + PA8: + pincodes: [K, C, R, V] + afs: + ADC1_IN3: ANALOG + TIMER0_BRKIN0: 1 + TIMER20_MCH2: 2 + SPI1_NSS: 4 + I2S1_WS: 4 + MFCOM_D7: 5 + MFCOM_D5: 6 + TRIGSEL_IN4: 7 + EVENTOUT: 9 + PA9: + pincodes: [C, R, V] + afs: + ADC1_IN2: ANALOG + TIMER20_CH2: 1 + SPI1_MOSI: 4 + I2S1_SD: 4 + MFCOM_D6: 5 + MFCOM_D4: 6 + TRIGSEL_IN5: 7 + EVENTOUT: 9 + PA10: + pincodes: [K, C, R, V] + afs: + ADC1_IN1: ANALOG + TIMER20_MCH0: 1 + I2C0_SCL: 3 + USART0_TX: 5 + MFCOM_D5: 6 + EVENTOUT: 9 + PA11: + pincodes: [K, C, R, V] + afs: + ADC1_IN0: ANALOG + TIMER20_CH0: 1 + I2C0_SDA: 3 + USART0_RX: 5 + MFCOM_D4: 6 + TRIGSEL_IN13: 7 + EVENTOUT: 9 + PA12: + pincodes: [V] + afs: + TIMER20_MCH1: 1 + I2C0_SMBA: 3 + USART0_CK: 5 + EVENTOUT: 9 + PA13: + pincodes: [V] + afs: + TIMER20_CH1: 1 + I2C0_SDA: 3 + EVENTOUT: 9 + PA14: + pincodes: [V] + afs: + TIMER20_MCH0: 1 + I2C0_SCL: 3 + EVENTOUT: 9 + PA15: + pincodes: [V] + afs: + TIMER20_CH0: 1 + TRIGSEL_IN12: 7 + EVENTOUT: 9 + PB0: + pincodes: [V] + afs: + TIMER19_CH0: 1 + TIMER19_CH1: 2 + EVENTOUT: 9 + PB1: + pincodes: [C, R, V] + afs: + ADC0_IN9: ANALOG + TIMER0_MCH0: 1 + TIMER7_MCH3: 2 + EVENTOUT: 9 + PB2: + pincodes: [R, V] + afs: + ADC0_IN8: ANALOG + TIMER0_CH0: 1 + TIMER7_CH3: 2 + EVENTOUT: 9 + PB3: + pincodes: [K, C, R, V] + afs: + NJTRST: 0 + TIMER7_MCH2: 1 + SPI0_IO2: 4 + MFCOM_D1: 6 + EVENTOUT: 9 + PB4: + pincodes: [K, C, R, V] + afs: + JTDO: 0 + TIMER7_CH2: 1 + SPI0_IO3: 4 + MFCOM_D0: 6 + EVENTOUT: 9 + PB5: + pincodes: [R, V] + afs: + TIMER7_BRKIN1: 2 + I2C0_SMBA: 3 + SPI0_MISO: 4 + SPI1_NSS: 5 + I2S1_WS: 6 + EVENTOUT: 9 + PB6: + pincodes: [R, V] + afs: + TIMER7_BRKIN2: 2 + TIMER_ETI1: 3 + SPI0_SCK: 4 + SPI1_MOSI: 5 + I2S1_SD: 5 + EVENTOUT: 9 + PB7: + pincodes: [K, C, R, V] + afs: + JTDI: 0 + TIMER19_CH0: 1 + TIMER19_CH1: 2 + I2C1_SCL: 5 + EVENTOUT: 9 + PB8: + pincodes: [K, C, R, V] + afs: + JTCK: 0 + SWCLK: 0 + TIMER7_CH0: 1 + TIMER7_CH1: 2 + I2C1_SDA: 5 + EVENTOUT: 9 + PB9: + pincodes: [K, C, R, V] + afs: + JTMS: 0 + SWDIO: 0 + I2C1_SMBA: 5 + CMP_OUT: 7 + EVENTOUT: 9 + PB10: + pincodes: [V] + afs: + TIMER20_CH3: 1 + TIMER19_CH3: 2 + SPI0_IO3: 4 + USART2_CTS: 5 + EVENTOUT: 9 + PB11: + pincodes: [V] + afs: + TIMER20_MCH2: 1 + TIMER1_CH3: 2 + TRIGSEL_IN10: 7 + EVENTOUT: 9 + PB12: + pincodes: [V] + afs: + TIMER20_CH2: 1 + TRIGSEL_IN11: 7 + EVENTOUT: 9 + PB13: + pincodes: [K, C, R, V] + afs: + ADC0_IN5: ANALOG + ADC1_IN15: ANALOG + TIMER_ETI0: 0 + SPI0_MOSI: 4 + USART0_TX: 5 + CAN0_TX: 6 + EVENTOUT: 9 + PB14: + pincodes: [K, C, R, V] + afs: + ADC0_IN4: ANALOG + ADC1_IN14: ANALOG + TIMER1_CH2: 1 + SPI0_NSS: 3 + USART0_RX: 5 + CAN0_RX: 6 + EVENTOUT: 9 + PB15: + pincodes: [C, R, V] + afs: + TIMER7_BRKIN1: 2 + USART1_TX: 4 + USART0_RTS: 5 + USART0_DE: 5 + EVENTOUT: 9 + PC0: + pincodes: [K, C, R, V] + afs: + TIMER0_CH0: 1 + SPI0_SCK: 4 + EVENTOUT: 9 + PC1: + pincodes: [C, R, V] + afs: + TIMER0_MCH3: 1 + USART2_CTS: 5 + EVENTOUT: 9 + PC2: + pincodes: [V] + afs: + CK_OUT: 0 + TIMER19_MCH2: 1 + USART1_TX: 5 + EVENTOUT: 9 + PC3: + pincodes: [V] + afs: + TIMER19_CH2: 1 + USART1_RX: 5 + EVENTOUT: 9 + PC4: + pincodes: [V] + afs: + TIMER19_CH1: 1 + USART2_RTS: 5 + USART2_DE: 5 + EVENTOUT: 9 + PC5: + pincodes: [V] + afs: + TIMER19_MCH0: 1 + TIMER19_CH0: 2 + USART2_CTS: 5 + EVENTOUT: 9 + PC6: + pincodes: [V] + afs: + ADC1_IN9: ANALOG + ADC0_IN9: ANALOG + TIMER0_CH1: 1 + SPI1_SCK: 4 + I2S1_CK: 4 + EVENTOUT: 9 + PC7: + pincodes: [C, R, V] + afs: + ADC1_IN8: ANALOG + ADC0_IN8: ANALOG + TIMER0_MCH0: 1 + TIMER20_BRKIN1: 2 + I2S1_MCK: 4 + EVENTOUT: 9 + PC8: + pincodes: [R, V] + afs: + ADC1_IN7: ANALOG + TIMER0_CH0: 1 + TIMER20_BRKIN2: 2 + EVENTOUT: 9 + PC9: + pincodes: [R, V] + afs: + ADC1_IN6: ANALOG + TIMER0_BRKIN3: 1 + TIMER20_BRKIN3: 2 + EVENTOUT: 9 + PC10: + pincodes: [K, C, R, V] + afs: + ADC0_IN1: ANALOG + TIMER7_MCH0: 1 + TIMER7_CH0: 2 + I2C0_SDA: 3 + USART0_RTS: 5 + USART0_DE: 5 + MFCOM_D3: 6 + TRIGSEL_OUT0: 7 + EVENTOUT: 9 + PC11: + pincodes: [K, C, R, V] + afs: + ADC0_IN0: ANALOG + TIMER19_MCH0: 1 + TIMER19_CH0: 2 + I2C0_SCL: 3 + USART0_CTS: 5 + MFCOM_D2: 6 + TRIGSEL_OUT3: 7 + EVENTOUT: 9 + PC12: + pincodes: [C, R, V] + afs: + ADC1_IN5: ANALOG + TIMER20_MCH1: 1 + TIMER7_CH0: 2 + USART1_TX: 5 + CAN1_TX: 6 + EVENTOUT: 9 + PC13: + pincodes: [R, V] + afs: + CK_OUT: 0 + TIMER19_CH2: 1 + MFCOM_D4: 6 + TRIGSEL_OUT4: 7 + EVENTOUT: 9 + PC14: + pincodes: [V] + afs: + TIMER19_BRKIN0: 2 + EVENTOUT: 9 + PC15: + pincodes: [K, C, R, V] + afs: + TIMER_ETI2: 0 + TIMER19_MCH1: 1 + TIMER19_CH1: 2 + CAN0_TX: 6 + MFCOM_D7: 7 + EVENTOUT: 9 + PD0: + pincodes: [C, R, V] + afs: + ADC1_IN4: ANALOG + TIMER20_CH1: 1 + TIMER7_CH1: 2 + USART1_RX: 5 + CAN1_RX: 6 + EVENTOUT: 9 + PD1: + pincodes: [V] + afs: + ADC1_IN13: ANALOG + TIMER7_MCH1: 1 + SPI1_NSS: 4 + I2S1_WS: 4 + EVENTOUT: 9 + PD2: + pincodes: [V] + afs: + ADC1_IN12: ANALOG + TIMER7_CH1: 1 + SPI0_NSS: 4 + EVENTOUT: 9 + PD3: + pincodes: [R, V] + afs: + ADC1_IN11: ANALOG + TIMER20_MCH3: 1 + SPI0_NSS: 4 + USART1_RTS: 5 + USART1_DE: 5 + EVENTOUT: 9 + PD4: + pincodes: [R, V] + afs: + ADC1_IN10: ANALOG + TIMER20_CH3: 1 + TIMER1_CH2: 2 + SPI0_MOSI: 4 + USART1_CTS: 5 + EVENTOUT: 9 + PD5: + pincodes: [V] + afs: + TIMER0_BRKIN0: 7 + TIMER20_BRKIN1: 12 + TIMER7_BRKIN0: 12 + USART1_CK: 12 + EVENTOUT: 9 + PD6: + pincodes: [C, R, V] + afs: + TIMER7_MCH3: 1 + TIMER19_CH0: 2 + I2C1_SCL: 5 + CAN1_TX: 6 + EVENTOUT: 9 + PD7: + pincodes: [C, R, V] + afs: + TIMER7_CH3: 1 + TIMER19_CH1: 2 + I2C1_SDA: 5 + CAN1_RX: 6 + EVENTOUT: 9 + PD8: + pincodes: [C, R, V] + afs: + TIMER7_BRKIN0: 2 + USART1_RX: 4 + USART0_CTS: 5 + EVENTOUT: 9 + PD9: + pincodes: [K, C, R, V] + afs: + ADC0_IN3: ANALOG + TIMER0_BRKIN2: 2 + USART1_RTS: 5 + USART1_DE: 5 + EVENTOUT: 9 + PD10: + pincodes: [R, V] + afs: + ADC0_IN2: ANALOG + TIMER0_BRKIN1: 2 + SPI1_NSS: 4 + I2S1_WS: 4 + USART1_CTS: 5 + EVENTOUT: 9 + PD11: + pincodes: [R, V] + afs: + TIMER0_MCH3: 1 + TIMER20_BRKIN0: 2 + I2C1_SMBA: 5 + EVENTOUT: 9 + PD12: + pincodes: [V] + afs: + TIMER0_CH3: 1 + TIMER20_BRKIN0: 2 + EVENTOUT: 9 + PD13: + pincodes: [V] + afs: + TIMER0_MCH2: 1 + SPI1_NSS: 4 + I2S1_WS: 4 + EVENTOUT: 9 + PD14: + pincodes: [V] + afs: + ADC1_IN15: ANALOG + TIMER0_CH2: 1 + SPI1_MOSI: 4 + I2S1_SD: 4 + EVENTOUT: 9 + PD15: + pincodes: [V] + afs: + ADC1_IN14: ANALOG + TIMER0_MCH1: 1 + SPI1_MISO: 4 + EVENTOUT: 9 + PE0: + pincodes: [V] + afs: + TIMER20_BRKIN2: 1 + TIMER7_BRKIN3: 2 + USART2_TX: 5 + MFCOM_D7: 6 + EVENTOUT: 9 + PE1: + pincodes: [V] + afs: + TIMER20_BRKIN3: 1 + USART2_RX: 5 + MFCOM_D6: 6 + EVENTOUT: 9 + PE2: + pincodes: [V] + afs: + TIMER19_MCH3: 2 + USART1_RTS: 5 + USART1_DE: 5 + MFCOM_D3: 6 + TRIGSEL_OUT7: 7 + EVENTOUT: 9 + PE3: + pincodes: [V] + afs: + TIMER19_CH3: 0 + USART1_CTS: 12 + MFCOM_D2: 12 + TRIGSEL_OUT6: 12 + EVENTOUT: 9 + PE4: + pincodes: [C, R, V] + afs: + TIMER0_MCH1: 1 + TIMER19_MCH0: 2 + SPI1_MISO: 4 + MFCOM_D1: 6 + TRIGSEL_OUT2: 7 + EVENTOUT: 9 + PE5: + pincodes: [C, R, V] + afs: + TIMER0_CH1: 1 + TIMER19_CH0: 2 + SPI1_SCK: 4 + I2S1_CK: 4 + MFCOM_D0: 6 + TRIGSEL_OUT1: 7 + EVENTOUT: 9 + PE6: + pincodes: [R, V] + afs: + TIMER1_CH0: 1 + TIMER1_ETI: 1 + TIMER19_MCH2: 2 + I2S1_MCK: 4 + MFCOM_D5: 6 + TRIGSEL_OUT5: 7 + EVENTOUT: 9 + PE7: + pincodes: [V] + afs: + TIMER7_MCH2: 1 + TIMER19_BRKIN3: 2 + MFCOM_D0: 6 + EVENTOUT: 9 + PE8: + pincodes: [V] + afs: + TIMER7_CH2: 1 + TIMER19_BRKIN2: 2 + MFCOM_D1: 6 + EVENTOUT: 9 + PE9: + pincodes: [R, V] + afs: + ADC0_IN15: ANALOG + TIMER7_BRKIN3: 2 + EVENTOUT: 9 + PE10: + pincodes: [C, R, V] + afs: + ADC0_IN14: ANALOG + TIMER7_BRKIN2: 2 + I2C1_SCL: 5 + EVENTOUT: 9 + PE11: + pincodes: [C, R, V] + afs: + ADC0_IN13: ANALOG + TIMER7_MCH1: 1 + I2C1_SDA: 5 + TRIGSEL_IN8: 7 + EVENTOUT: 9 + PE12: + pincodes: [C, R, V] + afs: + ADC0_IN12: ANALOG + TIMER7_CH1: 1 + I2C1_SMBA: 5 + TRIGSEL_IN9: 7 + EVENTOUT: 9 + PE13: + pincodes: [K, C, R, V] + afs: + ADC0_IN7: ANALOG + TIMER7_MCH0: 1 + TIMER7_CH0: 2 + SPI0_MISO: 4 + TRIGSEL_IN2: 7 + EVENTOUT: 9 + PE14: + pincodes: [K, C, R, V] + afs: + ADC0_IN6: ANALOG + TIMER7_CH0: 1 + TIMER7_CH1: 2 + SPI0_SCK: 4 + TRIGSEL_IN3: 7 + EVENTOUT: 9 + PE15: + pincodes: [V] + afs: + TIMER20_MCH3: 1 + TIMER19_MCH3: 2 + SPI0_IO2: 4 + USART2_RTS: 5 + USART2_DE: 5 + EVENTOUT: 9 + PF0: + pincodes: [K, C, R, V] + afs: + TIMER19_CH1: 1 + CAN0_RX: 6 + MFCOM_D6: 7 + EVENTOUT: 9 + PF1: + pincodes: [V] + afs: + TIMER0_BRKIN1: 1 + TIMER19_BRKIN1: 2 + EVENTOUT: 9 + PF2: + pincodes: [R, V] + afs: + TIMER0_BRKIN0: 1 + TIMRE19_BRKIN0: 2 + USART2_RTS: 5 + USART2_DE: 5 + TRIGSEL_IN6: 6 + CMP_OUT: 7 + EVENTOUT: 9 + PF3: + pincodes: [V] + afs: + TIMER0_BRKIN3: 2 + USART2_TX: 5 + EVENTOUT: 9 + PF4: + pincodes: [V] + afs: + TIMER0_BRKIN2: 2 + USART2_RX: 5 + EVENTOUT: 9 + PF5: + pincodes: [K, C, R, V] + afs: + TIMER0_MCH0: 1 + SPI0_MISO: 4 + USART1_CTS: 5 + EVENTOUT: 9 + PF6: + pincodes: [K, C, R, V] + afs: + I2C0_SCL: 3 + EVENTOUT: 9 + PF7: + pincodes: [K, C, R, V] + afs: + I2C0_SDA: 3 + EVENTOUT: 9 From d6eb8af206d1bff131552501759ca59fde003473 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Wed, 14 Dec 2022 20:50:40 +0800 Subject: [PATCH 4/8] dt-bindings: pinctrl: gd32a503: add autogenerated files for GD32A503 Add autogenerated pinctrl files for GD32A503 series. Signed-off-by: YuLong Yao --- .../pinctrl/gd32a503c(b-c)xx-pinctrl.h | 823 ++++++++++ .../pinctrl/gd32a503k(b-c)xx-pinctrl.h | 563 +++++++ .../pinctrl/gd32a503r(b-c-d)xx-pinctrl.h | 1039 +++++++++++++ .../pinctrl/gd32a503v(b-c-d)xx-pinctrl.h | 1375 +++++++++++++++++ 4 files changed, 3800 insertions(+) create mode 100644 include/dt-bindings/pinctrl/gd32a503c(b-c)xx-pinctrl.h create mode 100644 include/dt-bindings/pinctrl/gd32a503k(b-c)xx-pinctrl.h create mode 100644 include/dt-bindings/pinctrl/gd32a503r(b-c-d)xx-pinctrl.h create mode 100644 include/dt-bindings/pinctrl/gd32a503v(b-c-d)xx-pinctrl.h diff --git a/include/dt-bindings/pinctrl/gd32a503c(b-c)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32a503c(b-c)xx-pinctrl.h new file mode 100644 index 0000000..5411015 --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32a503c(b-c)xx-pinctrl.h @@ -0,0 +1,823 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC0_IN0 */ +#define ADC0_IN0_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) + +/* ADC0_IN1 */ +#define ADC0_IN1_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) + +/* ADC0_IN10 */ +#define ADC0_IN10_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC0_IN11 */ +#define ADC0_IN11_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC0_IN12 */ +#define ADC0_IN12_PE12 \ + GD32_PINMUX_AF('E', 12, ANALOG) + +/* ADC0_IN13 */ +#define ADC0_IN13_PE11 \ + GD32_PINMUX_AF('E', 11, ANALOG) + +/* ADC0_IN14 */ +#define ADC0_IN14_PE10 \ + GD32_PINMUX_AF('E', 10, ANALOG) + +/* ADC0_IN3 */ +#define ADC0_IN3_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) + +/* ADC0_IN4 */ +#define ADC0_IN4_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) + +/* ADC0_IN5 */ +#define ADC0_IN5_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) + +/* ADC0_IN6 */ +#define ADC0_IN6_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) + +/* ADC0_IN7 */ +#define ADC0_IN7_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) + +/* ADC0_IN8 */ +#define ADC0_IN8_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) + +/* ADC0_IN9 */ +#define ADC0_IN9_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) + +/* ADC1_IN0 */ +#define ADC1_IN0_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) + +/* ADC1_IN1 */ +#define ADC1_IN1_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) + +/* ADC1_IN14 */ +#define ADC1_IN14_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) + +/* ADC1_IN15 */ +#define ADC1_IN15_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) + +/* ADC1_IN2 */ +#define ADC1_IN2_PA9 \ + GD32_PINMUX_AF('A', 9, ANALOG) + +/* ADC1_IN3 */ +#define ADC1_IN3_PA8 \ + GD32_PINMUX_AF('A', 8, ANALOG) + +/* ADC1_IN4 */ +#define ADC1_IN4_PD0 \ + GD32_PINMUX_AF('D', 0, ANALOG) + +/* ADC1_IN5 */ +#define ADC1_IN5_PC12 \ + GD32_PINMUX_AF('C', 12, ANALOG) + +/* ADC1_IN8 */ +#define ADC1_IN8_PC7 \ + GD32_PINMUX_AF('C', 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_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_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_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_PC0 \ + GD32_PINMUX_AF('C', 0, ANALOG) +#define ANALOG_PC1 \ + GD32_PINMUX_AF('C', 1, ANALOG) +#define ANALOG_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) +#define ANALOG_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) +#define ANALOG_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) +#define ANALOG_PC12 \ + GD32_PINMUX_AF('C', 12, ANALOG) +#define ANALOG_PC15 \ + GD32_PINMUX_AF('C', 15, ANALOG) +#define ANALOG_PD0 \ + GD32_PINMUX_AF('D', 0, ANALOG) +#define ANALOG_PD6 \ + GD32_PINMUX_AF('D', 6, ANALOG) +#define ANALOG_PD7 \ + GD32_PINMUX_AF('D', 7, ANALOG) +#define ANALOG_PD8 \ + GD32_PINMUX_AF('D', 8, ANALOG) +#define ANALOG_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) +#define ANALOG_PE4 \ + GD32_PINMUX_AF('E', 4, ANALOG) +#define ANALOG_PE5 \ + GD32_PINMUX_AF('E', 5, ANALOG) +#define ANALOG_PE10 \ + GD32_PINMUX_AF('E', 10, ANALOG) +#define ANALOG_PE11 \ + GD32_PINMUX_AF('E', 11, ANALOG) +#define ANALOG_PE12 \ + GD32_PINMUX_AF('E', 12, ANALOG) +#define ANALOG_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) +#define ANALOG_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) +#define ANALOG_PF0 \ + GD32_PINMUX_AF('F', 0, ANALOG) +#define ANALOG_PF5 \ + GD32_PINMUX_AF('F', 5, ANALOG) +#define ANALOG_PF6 \ + GD32_PINMUX_AF('F', 6, ANALOG) +#define ANALOG_PF7 \ + GD32_PINMUX_AF('F', 7, ANALOG) + +/* CAN0_RX */ +#define CAN0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF6) +#define CAN0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF6) +#define CAN0_RX_PF0 \ + GD32_PINMUX_AF('F', 0, AF6) + +/* CAN0_TX */ +#define CAN0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF6) +#define CAN0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF6) +#define CAN0_TX_PC15 \ + GD32_PINMUX_AF('C', 15, AF6) + +/* CAN1_RX */ +#define CAN1_RX_PD0 \ + GD32_PINMUX_AF('D', 0, AF6) +#define CAN1_RX_PD7 \ + GD32_PINMUX_AF('D', 7, AF6) + +/* CAN1_TX */ +#define CAN1_TX_PC12 \ + GD32_PINMUX_AF('C', 12, AF6) +#define CAN1_TX_PD6 \ + GD32_PINMUX_AF('D', 6, AF6) + +/* CK_OUT0 */ +#define CK_OUT0_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) + +/* CMP_OUT */ +#define CMP_OUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF7) + +/* DAC_OUT */ +#define DAC_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF9) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF9) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF9) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF9) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF9) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF9) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF9) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) +#define EVENTOUT_PA9 \ + GD32_PINMUX_AF('A', 9, AF9) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF9) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF9) +#define EVENTOUT_PB1 \ + GD32_PINMUX_AF('B', 1, AF9) +#define EVENTOUT_PB3 \ + GD32_PINMUX_AF('B', 3, AF9) +#define EVENTOUT_PB4 \ + GD32_PINMUX_AF('B', 4, AF9) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF9) +#define EVENTOUT_PB8 \ + GD32_PINMUX_AF('B', 8, AF9) +#define EVENTOUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF9) +#define EVENTOUT_PB13 \ + GD32_PINMUX_AF('B', 13, AF9) +#define EVENTOUT_PB14 \ + GD32_PINMUX_AF('B', 14, AF9) +#define EVENTOUT_PB15 \ + GD32_PINMUX_AF('B', 15, AF9) +#define EVENTOUT_PC0 \ + GD32_PINMUX_AF('C', 0, AF9) +#define EVENTOUT_PC1 \ + GD32_PINMUX_AF('C', 1, AF9) +#define EVENTOUT_PC7 \ + GD32_PINMUX_AF('C', 7, AF9) +#define EVENTOUT_PC10 \ + GD32_PINMUX_AF('C', 10, AF9) +#define EVENTOUT_PC11 \ + GD32_PINMUX_AF('C', 11, AF9) +#define EVENTOUT_PC12 \ + GD32_PINMUX_AF('C', 12, AF9) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF9) +#define EVENTOUT_PD0 \ + GD32_PINMUX_AF('D', 0, AF9) +#define EVENTOUT_PD6 \ + GD32_PINMUX_AF('D', 6, AF9) +#define EVENTOUT_PD7 \ + GD32_PINMUX_AF('D', 7, AF9) +#define EVENTOUT_PD8 \ + GD32_PINMUX_AF('D', 8, AF9) +#define EVENTOUT_PD9 \ + GD32_PINMUX_AF('D', 9, AF9) +#define EVENTOUT_PE4 \ + GD32_PINMUX_AF('E', 4, AF9) +#define EVENTOUT_PE5 \ + GD32_PINMUX_AF('E', 5, AF9) +#define EVENTOUT_PE10 \ + GD32_PINMUX_AF('E', 10, AF9) +#define EVENTOUT_PE11 \ + GD32_PINMUX_AF('E', 11, AF9) +#define EVENTOUT_PE12 \ + GD32_PINMUX_AF('E', 12, AF9) +#define EVENTOUT_PE13 \ + GD32_PINMUX_AF('E', 13, AF9) +#define EVENTOUT_PE14 \ + GD32_PINMUX_AF('E', 14, AF9) +#define EVENTOUT_PF0 \ + GD32_PINMUX_AF('F', 0, AF9) +#define EVENTOUT_PF5 \ + GD32_PINMUX_AF('F', 5, AF9) +#define EVENTOUT_PF6 \ + GD32_PINMUX_AF('F', 6, AF9) +#define EVENTOUT_PF7 \ + GD32_PINMUX_AF('F', 7, AF9) + +/* I2C0_SCL */ +#define I2C0_SCL_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define I2C0_SCL_PC11 \ + GD32_PINMUX_AF('C', 11, AF3) +#define I2C0_SCL_PF6 \ + GD32_PINMUX_AF('F', 6, AF3) + +/* I2C0_SDA */ +#define I2C0_SDA_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) +#define I2C0_SDA_PC10 \ + GD32_PINMUX_AF('C', 10, AF3) +#define I2C0_SDA_PF7 \ + GD32_PINMUX_AF('F', 7, AF3) + +/* I2C1_SCL */ +#define I2C1_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) +#define I2C1_SCL_PD6 \ + GD32_PINMUX_AF('D', 6, AF5) +#define I2C1_SCL_PE10 \ + GD32_PINMUX_AF('E', 10, AF5) + +/* I2C1_SDA */ +#define I2C1_SDA_PB8 \ + GD32_PINMUX_AF('B', 8, AF5) +#define I2C1_SDA_PD7 \ + GD32_PINMUX_AF('D', 7, AF5) +#define I2C1_SDA_PE11 \ + GD32_PINMUX_AF('E', 11, AF5) + +/* I2C1_SMBA */ +#define I2C1_SMBA_PB9 \ + GD32_PINMUX_AF('B', 9, AF5) +#define I2C1_SMBA_PE12 \ + GD32_PINMUX_AF('E', 12, AF5) + +/* I2S1_CK */ +#define I2S1_CK_PE5 \ + GD32_PINMUX_AF('E', 5, AF4) + +/* I2S1_MCK */ +#define I2S1_MCK_PC7 \ + GD32_PINMUX_AF('C', 7, AF4) + +/* I2S1_SD */ +#define I2S1_SD_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) + +/* I2S1_WS */ +#define I2S1_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) + +/* JTCK */ +#define JTCK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* JTDI */ +#define JTDI_PB7 \ + GD32_PINMUX_AF('B', 7, AF0) + +/* JTDO */ +#define JTDO_PB4 \ + GD32_PINMUX_AF('B', 4, AF0) + +/* JTMS */ +#define JTMS_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* MFCOM_D0 */ +#define MFCOM_D0_PB4 \ + GD32_PINMUX_AF('B', 4, AF6) +#define MFCOM_D0_PE5 \ + GD32_PINMUX_AF('E', 5, AF6) + +/* MFCOM_D1 */ +#define MFCOM_D1_PB3 \ + GD32_PINMUX_AF('B', 3, AF6) +#define MFCOM_D1_PE4 \ + GD32_PINMUX_AF('E', 4, AF6) + +/* MFCOM_D2 */ +#define MFCOM_D2_PC11 \ + GD32_PINMUX_AF('C', 11, AF6) + +/* MFCOM_D3 */ +#define MFCOM_D3_PC10 \ + GD32_PINMUX_AF('C', 10, AF6) + +/* MFCOM_D4 */ +#define MFCOM_D4_PA9 \ + GD32_PINMUX_AF('A', 9, AF6) +#define MFCOM_D4_PA11 \ + GD32_PINMUX_AF('A', 11, AF6) + +/* MFCOM_D5 */ +#define MFCOM_D5_PA8 \ + GD32_PINMUX_AF('A', 8, AF6) +#define MFCOM_D5_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) + +/* MFCOM_D6 */ +#define MFCOM_D6_PA9 \ + GD32_PINMUX_AF('A', 9, AF5) +#define MFCOM_D6_PF0 \ + GD32_PINMUX_AF('F', 0, AF7) + +/* MFCOM_D7 */ +#define MFCOM_D7_PA8 \ + GD32_PINMUX_AF('A', 8, AF5) +#define MFCOM_D7_PC15 \ + GD32_PINMUX_AF('C', 15, AF7) + +/* NJTRST */ +#define NJTRST_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) + +/* SPI0_IO2 */ +#define SPI0_IO2_PB3 \ + GD32_PINMUX_AF('B', 3, AF4) + +/* SPI0_IO3 */ +#define SPI0_IO3_PB4 \ + GD32_PINMUX_AF('B', 4, AF4) + +/* SPI0_MISO */ +#define SPI0_MISO_PE13 \ + GD32_PINMUX_AF('E', 13, AF4) +#define SPI0_MISO_PF5 \ + GD32_PINMUX_AF('F', 5, AF4) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI0_MOSI_PB13 \ + GD32_PINMUX_AF('B', 13, AF4) + +/* SPI0_NSS */ +#define SPI0_NSS_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define SPI0_NSS_PB14 \ + GD32_PINMUX_AF('B', 14, AF3) + +/* SPI0_SCK */ +#define SPI0_SCK_PC0 \ + GD32_PINMUX_AF('C', 0, AF4) +#define SPI0_SCK_PE14 \ + GD32_PINMUX_AF('E', 14, AF4) + +/* SPI1_MISO */ +#define SPI1_MISO_PE4 \ + GD32_PINMUX_AF('E', 4, AF4) + +/* SPI1_MOSI */ +#define SPI1_MOSI_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) + +/* SPI1_SCK */ +#define SPI1_SCK_PE5 \ + GD32_PINMUX_AF('E', 5, AF4) + +/* SWCLK */ +#define SWCLK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* SWDIO */ +#define SWDIO_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) + +/* TIMER0_BRKIN2 */ +#define TIMER0_BRKIN2_PD9 \ + GD32_PINMUX_AF('D', 9, AF2) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PC0 \ + GD32_PINMUX_AF('C', 0, AF1) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) +#define TIMER0_CH1_PE5 \ + GD32_PINMUX_AF('E', 5, AF1) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) + +/* TIMER0_MCH0 */ +#define TIMER0_MCH0_PB1 \ + GD32_PINMUX_AF('B', 1, AF1) +#define TIMER0_MCH0_PC7 \ + GD32_PINMUX_AF('C', 7, AF1) +#define TIMER0_MCH0_PF5 \ + GD32_PINMUX_AF('F', 5, AF1) + +/* TIMER0_MCH1 */ +#define TIMER0_MCH1_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) +#define TIMER0_MCH1_PE4 \ + GD32_PINMUX_AF('E', 4, AF1) + +/* TIMER0_MCH2 */ +#define TIMER0_MCH2_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) + +/* TIMER0_MCH3 */ +#define TIMER0_MCH3_PC1 \ + GD32_PINMUX_AF('C', 1, AF1) + +/* TIMER19_BRKIN1 */ +#define TIMER19_BRKIN1_PA7 \ + GD32_PINMUX_AF('A', 7, AF3) + +/* TIMER19_BRKIN2 */ +#define TIMER19_BRKIN2_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) + +/* TIMER19_BRKIN3 */ +#define TIMER19_BRKIN3_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) + +/* TIMER19_CH0 */ +#define TIMER19_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER19_CH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF2) +#define TIMER19_CH0_PD6 \ + GD32_PINMUX_AF('D', 6, AF2) +#define TIMER19_CH0_PE5 \ + GD32_PINMUX_AF('E', 5, AF2) + +/* TIMER19_CH1 */ +#define TIMER19_CH1_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER19_CH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) +#define TIMER19_CH1_PD7 \ + GD32_PINMUX_AF('D', 7, AF2) +#define TIMER19_CH1_PF0 \ + GD32_PINMUX_AF('F', 0, AF1) + +/* TIMER19_MCH0 */ +#define TIMER19_MCH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF1) +#define TIMER19_MCH0_PE4 \ + GD32_PINMUX_AF('E', 4, AF2) + +/* TIMER19_MCH1 */ +#define TIMER19_MCH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER19_MCH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER1_CH1 */ +#define TIMER1_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) + +/* TIMER1_CH2 */ +#define TIMER1_CH2_PB14 \ + GD32_PINMUX_AF('B', 14, AF1) + +/* TIMER1_CH3 */ +#define TIMER1_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) + +/* TIMER20_BRKIN1 */ +#define TIMER20_BRKIN1_PC7 \ + GD32_PINMUX_AF('C', 7, AF2) + +/* TIMER20_CH0 */ +#define TIMER20_CH0_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) + +/* TIMER20_CH1 */ +#define TIMER20_CH1_PD0 \ + GD32_PINMUX_AF('D', 0, AF1) + +/* TIMER20_CH2 */ +#define TIMER20_CH2_PA9 \ + GD32_PINMUX_AF('A', 9, AF1) + +/* TIMER20_MCH0 */ +#define TIMER20_MCH0_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) + +/* TIMER20_MCH1 */ +#define TIMER20_MCH1_PC12 \ + GD32_PINMUX_AF('C', 12, AF1) + +/* TIMER20_MCH2 */ +#define TIMER20_MCH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) + +/* TIMER7_BRKIN0 */ +#define TIMER7_BRKIN0_PD8 \ + GD32_PINMUX_AF('D', 8, AF2) + +/* TIMER7_BRKIN1 */ +#define TIMER7_BRKIN1_PB15 \ + GD32_PINMUX_AF('B', 15, AF2) + +/* TIMER7_BRKIN2 */ +#define TIMER7_BRKIN2_PE10 \ + GD32_PINMUX_AF('E', 10, AF2) + +/* TIMER7_CH0 */ +#define TIMER7_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF1) +#define TIMER7_CH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF2) +#define TIMER7_CH0_PC12 \ + GD32_PINMUX_AF('C', 12, AF2) +#define TIMER7_CH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF2) +#define TIMER7_CH0_PE14 \ + GD32_PINMUX_AF('E', 14, AF1) + +/* TIMER7_CH1 */ +#define TIMER7_CH1_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER7_CH1_PD0 \ + GD32_PINMUX_AF('D', 0, AF2) +#define TIMER7_CH1_PE12 \ + GD32_PINMUX_AF('E', 12, AF1) +#define TIMER7_CH1_PE14 \ + GD32_PINMUX_AF('E', 14, AF2) + +/* TIMER7_CH2 */ +#define TIMER7_CH2_PB4 \ + GD32_PINMUX_AF('B', 4, AF1) + +/* TIMER7_CH3 */ +#define TIMER7_CH3_PD7 \ + GD32_PINMUX_AF('D', 7, AF1) + +/* TIMER7_MCH0 */ +#define TIMER7_MCH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF1) +#define TIMER7_MCH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF1) + +/* TIMER7_MCH1 */ +#define TIMER7_MCH1_PE11 \ + GD32_PINMUX_AF('E', 11, AF1) + +/* TIMER7_MCH2 */ +#define TIMER7_MCH2_PB3 \ + GD32_PINMUX_AF('B', 3, AF1) + +/* TIMER7_MCH3 */ +#define TIMER7_MCH3_PB1 \ + GD32_PINMUX_AF('B', 1, AF2) +#define TIMER7_MCH3_PD6 \ + GD32_PINMUX_AF('D', 6, AF1) + +/* TIMER_ETI0 */ +#define TIMER_ETI0_PB13 \ + GD32_PINMUX_AF('B', 13, AF0) + +/* TIMER_ETI2 */ +#define TIMER_ETI2_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* TRIGSEL_IN0 */ +#define TRIGSEL_IN0_PA1 \ + GD32_PINMUX_AF('A', 1, AF7) + +/* TRIGSEL_IN1 */ +#define TRIGSEL_IN1_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) + +/* TRIGSEL_IN13 */ +#define TRIGSEL_IN13_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) + +/* TRIGSEL_IN2 */ +#define TRIGSEL_IN2_PE13 \ + GD32_PINMUX_AF('E', 13, AF7) + +/* TRIGSEL_IN3 */ +#define TRIGSEL_IN3_PE14 \ + GD32_PINMUX_AF('E', 14, AF7) + +/* TRIGSEL_IN4 */ +#define TRIGSEL_IN4_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) + +/* TRIGSEL_IN5 */ +#define TRIGSEL_IN5_PA9 \ + GD32_PINMUX_AF('A', 9, AF7) + +/* TRIGSEL_IN7 */ +#define TRIGSEL_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) + +/* TRIGSEL_IN8 */ +#define TRIGSEL_IN8_PE11 \ + GD32_PINMUX_AF('E', 11, AF7) + +/* TRIGSEL_IN9 */ +#define TRIGSEL_IN9_PE12 \ + GD32_PINMUX_AF('E', 12, AF7) + +/* TRIGSEL_OUT0 */ +#define TRIGSEL_OUT0_PC10 \ + GD32_PINMUX_AF('C', 10, AF7) + +/* TRIGSEL_OUT1 */ +#define TRIGSEL_OUT1_PE5 \ + GD32_PINMUX_AF('E', 5, AF7) + +/* TRIGSEL_OUT2 */ +#define TRIGSEL_OUT2_PE4 \ + GD32_PINMUX_AF('E', 4, AF7) + +/* TRIGSEL_OUT3 */ +#define TRIGSEL_OUT3_PC11 \ + GD32_PINMUX_AF('C', 11, AF7) + +/* USART0_CTS */ +#define USART0_CTS_PC11 \ + GD32_PINMUX_AF('C', 11, AF5) +#define USART0_CTS_PD8 \ + GD32_PINMUX_AF('D', 8, AF5) + +/* USART0_DE */ +#define USART0_DE_PB15 \ + GD32_PINMUX_AF('B', 15, AF5) +#define USART0_DE_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RTS */ +#define USART0_RTS_PB15 \ + GD32_PINMUX_AF('B', 15, AF5) +#define USART0_RTS_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RX */ +#define USART0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define USART0_RX_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define USART0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF5) + +/* USART0_TX */ +#define USART0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define USART0_TX_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define USART0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF5) + +/* USART1_CTS */ +#define USART1_CTS_PF5 \ + GD32_PINMUX_AF('F', 5, AF5) + +/* USART1_DE */ +#define USART1_DE_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) + +/* USART1_RTS */ +#define USART1_RTS_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) + +/* USART1_RX */ +#define USART1_RX_PD0 \ + GD32_PINMUX_AF('D', 0, AF5) +#define USART1_RX_PD8 \ + GD32_PINMUX_AF('D', 8, AF4) + +/* USART1_TX */ +#define USART1_TX_PB15 \ + GD32_PINMUX_AF('B', 15, AF4) +#define USART1_TX_PC12 \ + GD32_PINMUX_AF('C', 12, AF5) + +/* USART2_CK */ +#define USART2_CK_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) + +/* USART2_CTS */ +#define USART2_CTS_PC1 \ + GD32_PINMUX_AF('C', 1, AF5) + +/* USART2_RX */ +#define USART2_RX_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) + +/* USART2_TX */ +#define USART2_TX_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) diff --git a/include/dt-bindings/pinctrl/gd32a503k(b-c)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32a503k(b-c)xx-pinctrl.h new file mode 100644 index 0000000..d14bbf2 --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32a503k(b-c)xx-pinctrl.h @@ -0,0 +1,563 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC0_IN0 */ +#define ADC0_IN0_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) + +/* ADC0_IN1 */ +#define ADC0_IN1_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) + +/* ADC0_IN10 */ +#define ADC0_IN10_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC0_IN11 */ +#define ADC0_IN11_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC0_IN3 */ +#define ADC0_IN3_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) + +/* ADC0_IN4 */ +#define ADC0_IN4_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) + +/* ADC0_IN5 */ +#define ADC0_IN5_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) + +/* ADC0_IN6 */ +#define ADC0_IN6_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) + +/* ADC0_IN7 */ +#define ADC0_IN7_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) + +/* ADC1_IN0 */ +#define ADC1_IN0_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) + +/* ADC1_IN1 */ +#define ADC1_IN1_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) + +/* ADC1_IN14 */ +#define ADC1_IN14_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) + +/* ADC1_IN15 */ +#define ADC1_IN15_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) + +/* ADC1_IN3 */ +#define ADC1_IN3_PA8 \ + GD32_PINMUX_AF('A', 8, 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_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) +#define ANALOG_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) +#define ANALOG_PB3 \ + GD32_PINMUX_AF('B', 3, ANALOG) +#define ANALOG_PB4 \ + GD32_PINMUX_AF('B', 4, 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_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) +#define ANALOG_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) +#define ANALOG_PC0 \ + GD32_PINMUX_AF('C', 0, ANALOG) +#define ANALOG_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) +#define ANALOG_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) +#define ANALOG_PC15 \ + GD32_PINMUX_AF('C', 15, ANALOG) +#define ANALOG_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) +#define ANALOG_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) +#define ANALOG_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) +#define ANALOG_PF0 \ + GD32_PINMUX_AF('F', 0, ANALOG) +#define ANALOG_PF5 \ + GD32_PINMUX_AF('F', 5, ANALOG) +#define ANALOG_PF6 \ + GD32_PINMUX_AF('F', 6, ANALOG) +#define ANALOG_PF7 \ + GD32_PINMUX_AF('F', 7, ANALOG) + +/* CAN0_RX */ +#define CAN0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF6) +#define CAN0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF6) +#define CAN0_RX_PF0 \ + GD32_PINMUX_AF('F', 0, AF6) + +/* CAN0_TX */ +#define CAN0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF6) +#define CAN0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF6) +#define CAN0_TX_PC15 \ + GD32_PINMUX_AF('C', 15, AF6) + +/* CK_OUT0 */ +#define CK_OUT0_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) + +/* CMP_OUT */ +#define CMP_OUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF7) + +/* DAC_OUT */ +#define DAC_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF9) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF9) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF9) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF9) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF9) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF9) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF9) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF9) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF9) +#define EVENTOUT_PB3 \ + GD32_PINMUX_AF('B', 3, AF9) +#define EVENTOUT_PB4 \ + GD32_PINMUX_AF('B', 4, AF9) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF9) +#define EVENTOUT_PB8 \ + GD32_PINMUX_AF('B', 8, AF9) +#define EVENTOUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF9) +#define EVENTOUT_PB13 \ + GD32_PINMUX_AF('B', 13, AF9) +#define EVENTOUT_PB14 \ + GD32_PINMUX_AF('B', 14, AF9) +#define EVENTOUT_PC0 \ + GD32_PINMUX_AF('C', 0, AF9) +#define EVENTOUT_PC10 \ + GD32_PINMUX_AF('C', 10, AF9) +#define EVENTOUT_PC11 \ + GD32_PINMUX_AF('C', 11, AF9) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF9) +#define EVENTOUT_PD9 \ + GD32_PINMUX_AF('D', 9, AF9) +#define EVENTOUT_PE13 \ + GD32_PINMUX_AF('E', 13, AF9) +#define EVENTOUT_PE14 \ + GD32_PINMUX_AF('E', 14, AF9) +#define EVENTOUT_PF0 \ + GD32_PINMUX_AF('F', 0, AF9) +#define EVENTOUT_PF5 \ + GD32_PINMUX_AF('F', 5, AF9) +#define EVENTOUT_PF6 \ + GD32_PINMUX_AF('F', 6, AF9) +#define EVENTOUT_PF7 \ + GD32_PINMUX_AF('F', 7, AF9) + +/* I2C0_SCL */ +#define I2C0_SCL_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define I2C0_SCL_PC11 \ + GD32_PINMUX_AF('C', 11, AF3) +#define I2C0_SCL_PF6 \ + GD32_PINMUX_AF('F', 6, AF3) + +/* I2C0_SDA */ +#define I2C0_SDA_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) +#define I2C0_SDA_PC10 \ + GD32_PINMUX_AF('C', 10, AF3) +#define I2C0_SDA_PF7 \ + GD32_PINMUX_AF('F', 7, AF3) + +/* I2C1_SCL */ +#define I2C1_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) + +/* I2C1_SDA */ +#define I2C1_SDA_PB8 \ + GD32_PINMUX_AF('B', 8, AF5) + +/* I2C1_SMBA */ +#define I2C1_SMBA_PB9 \ + GD32_PINMUX_AF('B', 9, AF5) + +/* I2S1_WS */ +#define I2S1_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) + +/* JTCK */ +#define JTCK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* JTDI */ +#define JTDI_PB7 \ + GD32_PINMUX_AF('B', 7, AF0) + +/* JTDO */ +#define JTDO_PB4 \ + GD32_PINMUX_AF('B', 4, AF0) + +/* JTMS */ +#define JTMS_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* MFCOM_D0 */ +#define MFCOM_D0_PB4 \ + GD32_PINMUX_AF('B', 4, AF6) + +/* MFCOM_D1 */ +#define MFCOM_D1_PB3 \ + GD32_PINMUX_AF('B', 3, AF6) + +/* MFCOM_D2 */ +#define MFCOM_D2_PC11 \ + GD32_PINMUX_AF('C', 11, AF6) + +/* MFCOM_D3 */ +#define MFCOM_D3_PC10 \ + GD32_PINMUX_AF('C', 10, AF6) + +/* MFCOM_D4 */ +#define MFCOM_D4_PA11 \ + GD32_PINMUX_AF('A', 11, AF6) + +/* MFCOM_D5 */ +#define MFCOM_D5_PA8 \ + GD32_PINMUX_AF('A', 8, AF6) +#define MFCOM_D5_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) + +/* MFCOM_D6 */ +#define MFCOM_D6_PF0 \ + GD32_PINMUX_AF('F', 0, AF7) + +/* MFCOM_D7 */ +#define MFCOM_D7_PA8 \ + GD32_PINMUX_AF('A', 8, AF5) +#define MFCOM_D7_PC15 \ + GD32_PINMUX_AF('C', 15, AF7) + +/* NJTRST */ +#define NJTRST_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) + +/* SPI0_IO2 */ +#define SPI0_IO2_PB3 \ + GD32_PINMUX_AF('B', 3, AF4) + +/* SPI0_IO3 */ +#define SPI0_IO3_PB4 \ + GD32_PINMUX_AF('B', 4, AF4) + +/* SPI0_MISO */ +#define SPI0_MISO_PE13 \ + GD32_PINMUX_AF('E', 13, AF4) +#define SPI0_MISO_PF5 \ + GD32_PINMUX_AF('F', 5, AF4) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI0_MOSI_PB13 \ + GD32_PINMUX_AF('B', 13, AF4) + +/* SPI0_NSS */ +#define SPI0_NSS_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define SPI0_NSS_PB14 \ + GD32_PINMUX_AF('B', 14, AF3) + +/* SPI0_SCK */ +#define SPI0_SCK_PC0 \ + GD32_PINMUX_AF('C', 0, AF4) +#define SPI0_SCK_PE14 \ + GD32_PINMUX_AF('E', 14, AF4) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) + +/* SWCLK */ +#define SWCLK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* SWDIO */ +#define SWDIO_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) + +/* TIMER0_BRKIN2 */ +#define TIMER0_BRKIN2_PD9 \ + GD32_PINMUX_AF('D', 9, AF2) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PC0 \ + GD32_PINMUX_AF('C', 0, AF1) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) + +/* TIMER0_MCH0 */ +#define TIMER0_MCH0_PF5 \ + GD32_PINMUX_AF('F', 5, AF1) + +/* TIMER0_MCH1 */ +#define TIMER0_MCH1_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) + +/* TIMER0_MCH2 */ +#define TIMER0_MCH2_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) + +/* TIMER19_BRKIN1 */ +#define TIMER19_BRKIN1_PA7 \ + GD32_PINMUX_AF('A', 7, AF3) + +/* TIMER19_BRKIN2 */ +#define TIMER19_BRKIN2_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) + +/* TIMER19_BRKIN3 */ +#define TIMER19_BRKIN3_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) + +/* TIMER19_CH0 */ +#define TIMER19_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER19_CH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF2) + +/* TIMER19_CH1 */ +#define TIMER19_CH1_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER19_CH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) +#define TIMER19_CH1_PF0 \ + GD32_PINMUX_AF('F', 0, AF1) + +/* TIMER19_MCH0 */ +#define TIMER19_MCH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF1) + +/* TIMER19_MCH1 */ +#define TIMER19_MCH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER19_MCH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER1_CH1 */ +#define TIMER1_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) + +/* TIMER1_CH2 */ +#define TIMER1_CH2_PB14 \ + GD32_PINMUX_AF('B', 14, AF1) + +/* TIMER1_CH3 */ +#define TIMER1_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) + +/* TIMER20_CH0 */ +#define TIMER20_CH0_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) + +/* TIMER20_MCH0 */ +#define TIMER20_MCH0_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) + +/* TIMER20_MCH2 */ +#define TIMER20_MCH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) + +/* TIMER7_CH0 */ +#define TIMER7_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF1) +#define TIMER7_CH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF2) +#define TIMER7_CH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF2) +#define TIMER7_CH0_PE14 \ + GD32_PINMUX_AF('E', 14, AF1) + +/* TIMER7_CH1 */ +#define TIMER7_CH1_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER7_CH1_PE14 \ + GD32_PINMUX_AF('E', 14, AF2) + +/* TIMER7_CH2 */ +#define TIMER7_CH2_PB4 \ + GD32_PINMUX_AF('B', 4, AF1) + +/* TIMER7_MCH0 */ +#define TIMER7_MCH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF1) +#define TIMER7_MCH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF1) + +/* TIMER7_MCH2 */ +#define TIMER7_MCH2_PB3 \ + GD32_PINMUX_AF('B', 3, AF1) + +/* TIMER_ETI0 */ +#define TIMER_ETI0_PB13 \ + GD32_PINMUX_AF('B', 13, AF0) + +/* TIMER_ETI2 */ +#define TIMER_ETI2_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* TRIGSEL_IN0 */ +#define TRIGSEL_IN0_PA1 \ + GD32_PINMUX_AF('A', 1, AF7) + +/* TRIGSEL_IN1 */ +#define TRIGSEL_IN1_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) + +/* TRIGSEL_IN13 */ +#define TRIGSEL_IN13_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) + +/* TRIGSEL_IN2 */ +#define TRIGSEL_IN2_PE13 \ + GD32_PINMUX_AF('E', 13, AF7) + +/* TRIGSEL_IN3 */ +#define TRIGSEL_IN3_PE14 \ + GD32_PINMUX_AF('E', 14, AF7) + +/* TRIGSEL_IN4 */ +#define TRIGSEL_IN4_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) + +/* TRIGSEL_IN7 */ +#define TRIGSEL_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) + +/* TRIGSEL_OUT0 */ +#define TRIGSEL_OUT0_PC10 \ + GD32_PINMUX_AF('C', 10, AF7) + +/* TRIGSEL_OUT3 */ +#define TRIGSEL_OUT3_PC11 \ + GD32_PINMUX_AF('C', 11, AF7) + +/* USART0_CTS */ +#define USART0_CTS_PC11 \ + GD32_PINMUX_AF('C', 11, AF5) + +/* USART0_DE */ +#define USART0_DE_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RTS */ +#define USART0_RTS_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RX */ +#define USART0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define USART0_RX_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define USART0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF5) + +/* USART0_TX */ +#define USART0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define USART0_TX_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define USART0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF5) + +/* USART1_CTS */ +#define USART1_CTS_PF5 \ + GD32_PINMUX_AF('F', 5, AF5) + +/* USART1_DE */ +#define USART1_DE_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) + +/* USART1_RTS */ +#define USART1_RTS_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) + +/* USART2_CK */ +#define USART2_CK_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) + +/* USART2_RX */ +#define USART2_RX_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) + +/* USART2_TX */ +#define USART2_TX_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) diff --git a/include/dt-bindings/pinctrl/gd32a503r(b-c-d)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32a503r(b-c-d)xx-pinctrl.h new file mode 100644 index 0000000..7e4bf66 --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32a503r(b-c-d)xx-pinctrl.h @@ -0,0 +1,1039 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC0_IN0 */ +#define ADC0_IN0_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) + +/* ADC0_IN1 */ +#define ADC0_IN1_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) + +/* ADC0_IN10 */ +#define ADC0_IN10_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC0_IN11 */ +#define ADC0_IN11_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC0_IN12 */ +#define ADC0_IN12_PE12 \ + GD32_PINMUX_AF('E', 12, ANALOG) + +/* ADC0_IN13 */ +#define ADC0_IN13_PE11 \ + GD32_PINMUX_AF('E', 11, ANALOG) + +/* ADC0_IN14 */ +#define ADC0_IN14_PE10 \ + GD32_PINMUX_AF('E', 10, ANALOG) + +/* ADC0_IN15 */ +#define ADC0_IN15_PE9 \ + GD32_PINMUX_AF('E', 9, ANALOG) + +/* ADC0_IN2 */ +#define ADC0_IN2_PD10 \ + GD32_PINMUX_AF('D', 10, ANALOG) + +/* ADC0_IN3 */ +#define ADC0_IN3_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) + +/* ADC0_IN4 */ +#define ADC0_IN4_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) + +/* ADC0_IN5 */ +#define ADC0_IN5_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) + +/* ADC0_IN6 */ +#define ADC0_IN6_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) + +/* ADC0_IN7 */ +#define ADC0_IN7_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) + +/* ADC0_IN8 */ +#define ADC0_IN8_PB2 \ + GD32_PINMUX_AF('B', 2, ANALOG) +#define ADC0_IN8_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) + +/* ADC0_IN9 */ +#define ADC0_IN9_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) + +/* ADC1_IN0 */ +#define ADC1_IN0_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) + +/* ADC1_IN1 */ +#define ADC1_IN1_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) + +/* ADC1_IN10 */ +#define ADC1_IN10_PD4 \ + GD32_PINMUX_AF('D', 4, ANALOG) + +/* ADC1_IN11 */ +#define ADC1_IN11_PD3 \ + GD32_PINMUX_AF('D', 3, ANALOG) + +/* ADC1_IN14 */ +#define ADC1_IN14_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) + +/* ADC1_IN15 */ +#define ADC1_IN15_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) + +/* ADC1_IN2 */ +#define ADC1_IN2_PA9 \ + GD32_PINMUX_AF('A', 9, ANALOG) + +/* ADC1_IN3 */ +#define ADC1_IN3_PA8 \ + GD32_PINMUX_AF('A', 8, ANALOG) + +/* ADC1_IN4 */ +#define ADC1_IN4_PD0 \ + GD32_PINMUX_AF('D', 0, ANALOG) + +/* ADC1_IN5 */ +#define ADC1_IN5_PC12 \ + GD32_PINMUX_AF('C', 12, ANALOG) + +/* ADC1_IN6 */ +#define ADC1_IN6_PC9 \ + GD32_PINMUX_AF('C', 9, ANALOG) + +/* ADC1_IN7 */ +#define ADC1_IN7_PC8 \ + GD32_PINMUX_AF('C', 8, ANALOG) + +/* ADC1_IN8 */ +#define ADC1_IN8_PC7 \ + GD32_PINMUX_AF('C', 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_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_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_PC0 \ + GD32_PINMUX_AF('C', 0, ANALOG) +#define ANALOG_PC1 \ + GD32_PINMUX_AF('C', 1, ANALOG) +#define ANALOG_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) +#define ANALOG_PC8 \ + GD32_PINMUX_AF('C', 8, ANALOG) +#define ANALOG_PC9 \ + GD32_PINMUX_AF('C', 9, ANALOG) +#define ANALOG_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) +#define ANALOG_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) +#define ANALOG_PC12 \ + GD32_PINMUX_AF('C', 12, ANALOG) +#define ANALOG_PC13 \ + GD32_PINMUX_AF('C', 13, ANALOG) +#define ANALOG_PC15 \ + GD32_PINMUX_AF('C', 15, ANALOG) +#define ANALOG_PD0 \ + GD32_PINMUX_AF('D', 0, ANALOG) +#define ANALOG_PD3 \ + GD32_PINMUX_AF('D', 3, ANALOG) +#define ANALOG_PD4 \ + GD32_PINMUX_AF('D', 4, ANALOG) +#define ANALOG_PD6 \ + GD32_PINMUX_AF('D', 6, ANALOG) +#define ANALOG_PD7 \ + GD32_PINMUX_AF('D', 7, ANALOG) +#define ANALOG_PD8 \ + GD32_PINMUX_AF('D', 8, ANALOG) +#define ANALOG_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) +#define ANALOG_PD10 \ + GD32_PINMUX_AF('D', 10, ANALOG) +#define ANALOG_PD11 \ + GD32_PINMUX_AF('D', 11, ANALOG) +#define ANALOG_PE4 \ + GD32_PINMUX_AF('E', 4, ANALOG) +#define ANALOG_PE5 \ + GD32_PINMUX_AF('E', 5, ANALOG) +#define ANALOG_PE6 \ + GD32_PINMUX_AF('E', 6, ANALOG) +#define ANALOG_PE9 \ + GD32_PINMUX_AF('E', 9, ANALOG) +#define ANALOG_PE10 \ + GD32_PINMUX_AF('E', 10, ANALOG) +#define ANALOG_PE11 \ + GD32_PINMUX_AF('E', 11, ANALOG) +#define ANALOG_PE12 \ + GD32_PINMUX_AF('E', 12, ANALOG) +#define ANALOG_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) +#define ANALOG_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) +#define ANALOG_PF0 \ + GD32_PINMUX_AF('F', 0, ANALOG) +#define ANALOG_PF2 \ + GD32_PINMUX_AF('F', 2, ANALOG) +#define ANALOG_PF5 \ + GD32_PINMUX_AF('F', 5, ANALOG) +#define ANALOG_PF6 \ + GD32_PINMUX_AF('F', 6, ANALOG) +#define ANALOG_PF7 \ + GD32_PINMUX_AF('F', 7, ANALOG) + +/* CAN0_RX */ +#define CAN0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF6) +#define CAN0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF6) +#define CAN0_RX_PF0 \ + GD32_PINMUX_AF('F', 0, AF6) + +/* CAN0_TX */ +#define CAN0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF6) +#define CAN0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF6) +#define CAN0_TX_PC15 \ + GD32_PINMUX_AF('C', 15, AF6) + +/* CAN1_RX */ +#define CAN1_RX_PD0 \ + GD32_PINMUX_AF('D', 0, AF6) +#define CAN1_RX_PD7 \ + GD32_PINMUX_AF('D', 7, AF6) + +/* CAN1_TX */ +#define CAN1_TX_PC12 \ + GD32_PINMUX_AF('C', 12, AF6) +#define CAN1_TX_PD6 \ + GD32_PINMUX_AF('D', 6, AF6) + +/* CK_OUT */ +#define CK_OUT_PC13 \ + GD32_PINMUX_AF('C', 13, AF0) + +/* CK_OUT0 */ +#define CK_OUT0_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) + +/* CMP_OUT */ +#define CMP_OUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF7) +#define CMP_OUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF7) + +/* DAC_OUT */ +#define DAC_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF9) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF9) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF9) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF9) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF9) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF9) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF9) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) +#define EVENTOUT_PA9 \ + GD32_PINMUX_AF('A', 9, AF9) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF9) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF9) +#define EVENTOUT_PB1 \ + GD32_PINMUX_AF('B', 1, AF9) +#define EVENTOUT_PB2 \ + GD32_PINMUX_AF('B', 2, AF9) +#define EVENTOUT_PB3 \ + GD32_PINMUX_AF('B', 3, AF9) +#define EVENTOUT_PB4 \ + GD32_PINMUX_AF('B', 4, AF9) +#define EVENTOUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF9) +#define EVENTOUT_PB6 \ + GD32_PINMUX_AF('B', 6, AF9) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF9) +#define EVENTOUT_PB8 \ + GD32_PINMUX_AF('B', 8, AF9) +#define EVENTOUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF9) +#define EVENTOUT_PB13 \ + GD32_PINMUX_AF('B', 13, AF9) +#define EVENTOUT_PB14 \ + GD32_PINMUX_AF('B', 14, AF9) +#define EVENTOUT_PB15 \ + GD32_PINMUX_AF('B', 15, AF9) +#define EVENTOUT_PC0 \ + GD32_PINMUX_AF('C', 0, AF9) +#define EVENTOUT_PC1 \ + GD32_PINMUX_AF('C', 1, AF9) +#define EVENTOUT_PC7 \ + GD32_PINMUX_AF('C', 7, AF9) +#define EVENTOUT_PC8 \ + GD32_PINMUX_AF('C', 8, AF9) +#define EVENTOUT_PC9 \ + GD32_PINMUX_AF('C', 9, AF9) +#define EVENTOUT_PC10 \ + GD32_PINMUX_AF('C', 10, AF9) +#define EVENTOUT_PC11 \ + GD32_PINMUX_AF('C', 11, AF9) +#define EVENTOUT_PC12 \ + GD32_PINMUX_AF('C', 12, AF9) +#define EVENTOUT_PC13 \ + GD32_PINMUX_AF('C', 13, AF9) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF9) +#define EVENTOUT_PD0 \ + GD32_PINMUX_AF('D', 0, AF9) +#define EVENTOUT_PD3 \ + GD32_PINMUX_AF('D', 3, AF9) +#define EVENTOUT_PD4 \ + GD32_PINMUX_AF('D', 4, AF9) +#define EVENTOUT_PD6 \ + GD32_PINMUX_AF('D', 6, AF9) +#define EVENTOUT_PD7 \ + GD32_PINMUX_AF('D', 7, AF9) +#define EVENTOUT_PD8 \ + GD32_PINMUX_AF('D', 8, AF9) +#define EVENTOUT_PD9 \ + GD32_PINMUX_AF('D', 9, AF9) +#define EVENTOUT_PD10 \ + GD32_PINMUX_AF('D', 10, AF9) +#define EVENTOUT_PD11 \ + GD32_PINMUX_AF('D', 11, AF9) +#define EVENTOUT_PE4 \ + GD32_PINMUX_AF('E', 4, AF9) +#define EVENTOUT_PE5 \ + GD32_PINMUX_AF('E', 5, AF9) +#define EVENTOUT_PE6 \ + GD32_PINMUX_AF('E', 6, AF9) +#define EVENTOUT_PE9 \ + GD32_PINMUX_AF('E', 9, AF9) +#define EVENTOUT_PE10 \ + GD32_PINMUX_AF('E', 10, AF9) +#define EVENTOUT_PE11 \ + GD32_PINMUX_AF('E', 11, AF9) +#define EVENTOUT_PE12 \ + GD32_PINMUX_AF('E', 12, AF9) +#define EVENTOUT_PE13 \ + GD32_PINMUX_AF('E', 13, AF9) +#define EVENTOUT_PE14 \ + GD32_PINMUX_AF('E', 14, AF9) +#define EVENTOUT_PF0 \ + GD32_PINMUX_AF('F', 0, AF9) +#define EVENTOUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF9) +#define EVENTOUT_PF5 \ + GD32_PINMUX_AF('F', 5, AF9) +#define EVENTOUT_PF6 \ + GD32_PINMUX_AF('F', 6, AF9) +#define EVENTOUT_PF7 \ + GD32_PINMUX_AF('F', 7, AF9) + +/* I2C0_SCL */ +#define I2C0_SCL_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define I2C0_SCL_PC11 \ + GD32_PINMUX_AF('C', 11, AF3) +#define I2C0_SCL_PF6 \ + GD32_PINMUX_AF('F', 6, AF3) + +/* I2C0_SDA */ +#define I2C0_SDA_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) +#define I2C0_SDA_PC10 \ + GD32_PINMUX_AF('C', 10, AF3) +#define I2C0_SDA_PF7 \ + GD32_PINMUX_AF('F', 7, AF3) + +/* I2C0_SMBA */ +#define I2C0_SMBA_PB5 \ + GD32_PINMUX_AF('B', 5, AF3) + +/* I2C1_SCL */ +#define I2C1_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) +#define I2C1_SCL_PD6 \ + GD32_PINMUX_AF('D', 6, AF5) +#define I2C1_SCL_PE10 \ + GD32_PINMUX_AF('E', 10, AF5) + +/* I2C1_SDA */ +#define I2C1_SDA_PB8 \ + GD32_PINMUX_AF('B', 8, AF5) +#define I2C1_SDA_PD7 \ + GD32_PINMUX_AF('D', 7, AF5) +#define I2C1_SDA_PE11 \ + GD32_PINMUX_AF('E', 11, AF5) + +/* I2C1_SMBA */ +#define I2C1_SMBA_PB9 \ + GD32_PINMUX_AF('B', 9, AF5) +#define I2C1_SMBA_PD11 \ + GD32_PINMUX_AF('D', 11, AF5) +#define I2C1_SMBA_PE12 \ + GD32_PINMUX_AF('E', 12, AF5) + +/* I2S1_CK */ +#define I2S1_CK_PE5 \ + GD32_PINMUX_AF('E', 5, AF4) + +/* I2S1_MCK */ +#define I2S1_MCK_PC7 \ + GD32_PINMUX_AF('C', 7, AF4) +#define I2S1_MCK_PE6 \ + GD32_PINMUX_AF('E', 6, AF4) + +/* I2S1_SD */ +#define I2S1_SD_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) +#define I2S1_SD_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* I2S1_WS */ +#define I2S1_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) +#define I2S1_WS_PB5 \ + GD32_PINMUX_AF('B', 5, AF6) +#define I2S1_WS_PD10 \ + GD32_PINMUX_AF('D', 10, AF4) + +/* JTCK */ +#define JTCK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* JTDI */ +#define JTDI_PB7 \ + GD32_PINMUX_AF('B', 7, AF0) + +/* JTDO */ +#define JTDO_PB4 \ + GD32_PINMUX_AF('B', 4, AF0) + +/* JTMS */ +#define JTMS_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* MFCOM_D0 */ +#define MFCOM_D0_PB4 \ + GD32_PINMUX_AF('B', 4, AF6) +#define MFCOM_D0_PE5 \ + GD32_PINMUX_AF('E', 5, AF6) + +/* MFCOM_D1 */ +#define MFCOM_D1_PB3 \ + GD32_PINMUX_AF('B', 3, AF6) +#define MFCOM_D1_PE4 \ + GD32_PINMUX_AF('E', 4, AF6) + +/* MFCOM_D2 */ +#define MFCOM_D2_PC11 \ + GD32_PINMUX_AF('C', 11, AF6) + +/* MFCOM_D3 */ +#define MFCOM_D3_PC10 \ + GD32_PINMUX_AF('C', 10, AF6) + +/* MFCOM_D4 */ +#define MFCOM_D4_PA9 \ + GD32_PINMUX_AF('A', 9, AF6) +#define MFCOM_D4_PA11 \ + GD32_PINMUX_AF('A', 11, AF6) +#define MFCOM_D4_PC13 \ + GD32_PINMUX_AF('C', 13, AF6) + +/* MFCOM_D5 */ +#define MFCOM_D5_PA8 \ + GD32_PINMUX_AF('A', 8, AF6) +#define MFCOM_D5_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) +#define MFCOM_D5_PE6 \ + GD32_PINMUX_AF('E', 6, AF6) + +/* MFCOM_D6 */ +#define MFCOM_D6_PA9 \ + GD32_PINMUX_AF('A', 9, AF5) +#define MFCOM_D6_PF0 \ + GD32_PINMUX_AF('F', 0, AF7) + +/* MFCOM_D7 */ +#define MFCOM_D7_PA8 \ + GD32_PINMUX_AF('A', 8, AF5) +#define MFCOM_D7_PC15 \ + GD32_PINMUX_AF('C', 15, AF7) + +/* NJTRST */ +#define NJTRST_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) + +/* SPI0_IO2 */ +#define SPI0_IO2_PB3 \ + GD32_PINMUX_AF('B', 3, AF4) + +/* SPI0_IO3 */ +#define SPI0_IO3_PB4 \ + GD32_PINMUX_AF('B', 4, AF4) + +/* SPI0_MISO */ +#define SPI0_MISO_PB5 \ + GD32_PINMUX_AF('B', 5, AF4) +#define SPI0_MISO_PE13 \ + GD32_PINMUX_AF('E', 13, AF4) +#define SPI0_MISO_PF5 \ + GD32_PINMUX_AF('F', 5, AF4) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI0_MOSI_PB13 \ + GD32_PINMUX_AF('B', 13, AF4) +#define SPI0_MOSI_PD4 \ + GD32_PINMUX_AF('D', 4, AF4) + +/* SPI0_NSS */ +#define SPI0_NSS_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define SPI0_NSS_PB14 \ + GD32_PINMUX_AF('B', 14, AF3) +#define SPI0_NSS_PD3 \ + GD32_PINMUX_AF('D', 3, AF4) + +/* SPI0_SCK */ +#define SPI0_SCK_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) +#define SPI0_SCK_PC0 \ + GD32_PINMUX_AF('C', 0, AF4) +#define SPI0_SCK_PE14 \ + GD32_PINMUX_AF('E', 14, AF4) + +/* SPI1_MISO */ +#define SPI1_MISO_PE4 \ + GD32_PINMUX_AF('E', 4, AF4) + +/* SPI1_MOSI */ +#define SPI1_MOSI_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) +#define SPI1_MOSI_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) +#define SPI1_NSS_PB5 \ + GD32_PINMUX_AF('B', 5, AF5) +#define SPI1_NSS_PD10 \ + GD32_PINMUX_AF('D', 10, AF4) + +/* SPI1_SCK */ +#define SPI1_SCK_PE5 \ + GD32_PINMUX_AF('E', 5, AF4) + +/* SWCLK */ +#define SWCLK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* SWDIO */ +#define SWDIO_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) +#define TIMER0_BRKIN0_PF2 \ + GD32_PINMUX_AF('F', 2, AF1) + +/* TIMER0_BRKIN1 */ +#define TIMER0_BRKIN1_PD10 \ + GD32_PINMUX_AF('D', 10, AF2) + +/* TIMER0_BRKIN2 */ +#define TIMER0_BRKIN2_PD9 \ + GD32_PINMUX_AF('D', 9, AF2) + +/* TIMER0_BRKIN3 */ +#define TIMER0_BRKIN3_PC9 \ + GD32_PINMUX_AF('C', 9, AF1) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PB2 \ + GD32_PINMUX_AF('B', 2, AF1) +#define TIMER0_CH0_PC0 \ + GD32_PINMUX_AF('C', 0, AF1) +#define TIMER0_CH0_PC8 \ + GD32_PINMUX_AF('C', 8, AF1) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) +#define TIMER0_CH1_PE5 \ + GD32_PINMUX_AF('E', 5, AF1) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) + +/* TIMER0_MCH0 */ +#define TIMER0_MCH0_PB1 \ + GD32_PINMUX_AF('B', 1, AF1) +#define TIMER0_MCH0_PC7 \ + GD32_PINMUX_AF('C', 7, AF1) +#define TIMER0_MCH0_PF5 \ + GD32_PINMUX_AF('F', 5, AF1) + +/* TIMER0_MCH1 */ +#define TIMER0_MCH1_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) +#define TIMER0_MCH1_PE4 \ + GD32_PINMUX_AF('E', 4, AF1) + +/* TIMER0_MCH2 */ +#define TIMER0_MCH2_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) + +/* TIMER0_MCH3 */ +#define TIMER0_MCH3_PC1 \ + GD32_PINMUX_AF('C', 1, AF1) +#define TIMER0_MCH3_PD11 \ + GD32_PINMUX_AF('D', 11, AF1) + +/* TIMER19_BRKIN1 */ +#define TIMER19_BRKIN1_PA7 \ + GD32_PINMUX_AF('A', 7, AF3) + +/* TIMER19_BRKIN2 */ +#define TIMER19_BRKIN2_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) + +/* TIMER19_BRKIN3 */ +#define TIMER19_BRKIN3_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) + +/* TIMER19_CH0 */ +#define TIMER19_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER19_CH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF2) +#define TIMER19_CH0_PD6 \ + GD32_PINMUX_AF('D', 6, AF2) +#define TIMER19_CH0_PE5 \ + GD32_PINMUX_AF('E', 5, AF2) + +/* TIMER19_CH1 */ +#define TIMER19_CH1_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER19_CH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) +#define TIMER19_CH1_PD7 \ + GD32_PINMUX_AF('D', 7, AF2) +#define TIMER19_CH1_PF0 \ + GD32_PINMUX_AF('F', 0, AF1) + +/* TIMER19_CH2 */ +#define TIMER19_CH2_PC13 \ + GD32_PINMUX_AF('C', 13, AF1) + +/* TIMER19_MCH0 */ +#define TIMER19_MCH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF1) +#define TIMER19_MCH0_PE4 \ + GD32_PINMUX_AF('E', 4, AF2) + +/* TIMER19_MCH1 */ +#define TIMER19_MCH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER19_MCH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER19_MCH2 */ +#define TIMER19_MCH2_PE6 \ + GD32_PINMUX_AF('E', 6, AF2) + +/* TIMER1_CH0 */ +#define TIMER1_CH0_PE6 \ + GD32_PINMUX_AF('E', 6, AF1) + +/* TIMER1_CH1 */ +#define TIMER1_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) + +/* TIMER1_CH2 */ +#define TIMER1_CH2_PB14 \ + GD32_PINMUX_AF('B', 14, AF1) +#define TIMER1_CH2_PD4 \ + GD32_PINMUX_AF('D', 4, AF2) + +/* TIMER1_CH3 */ +#define TIMER1_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) + +/* TIMER1_ETI */ +#define TIMER1_ETI_PE6 \ + GD32_PINMUX_AF('E', 6, AF1) + +/* TIMER20_BRKIN0 */ +#define TIMER20_BRKIN0_PD11 \ + GD32_PINMUX_AF('D', 11, AF2) + +/* TIMER20_BRKIN1 */ +#define TIMER20_BRKIN1_PC7 \ + GD32_PINMUX_AF('C', 7, AF2) + +/* TIMER20_BRKIN2 */ +#define TIMER20_BRKIN2_PC8 \ + GD32_PINMUX_AF('C', 8, AF2) + +/* TIMER20_BRKIN3 */ +#define TIMER20_BRKIN3_PC9 \ + GD32_PINMUX_AF('C', 9, AF2) + +/* TIMER20_CH0 */ +#define TIMER20_CH0_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) + +/* TIMER20_CH1 */ +#define TIMER20_CH1_PD0 \ + GD32_PINMUX_AF('D', 0, AF1) + +/* TIMER20_CH2 */ +#define TIMER20_CH2_PA9 \ + GD32_PINMUX_AF('A', 9, AF1) + +/* TIMER20_CH3 */ +#define TIMER20_CH3_PD4 \ + GD32_PINMUX_AF('D', 4, AF1) + +/* TIMER20_MCH0 */ +#define TIMER20_MCH0_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) + +/* TIMER20_MCH1 */ +#define TIMER20_MCH1_PC12 \ + GD32_PINMUX_AF('C', 12, AF1) + +/* TIMER20_MCH2 */ +#define TIMER20_MCH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) + +/* TIMER20_MCH3 */ +#define TIMER20_MCH3_PD3 \ + GD32_PINMUX_AF('D', 3, AF1) + +/* TIMER7_BRKIN0 */ +#define TIMER7_BRKIN0_PD8 \ + GD32_PINMUX_AF('D', 8, AF2) + +/* TIMER7_BRKIN1 */ +#define TIMER7_BRKIN1_PB5 \ + GD32_PINMUX_AF('B', 5, AF2) +#define TIMER7_BRKIN1_PB15 \ + GD32_PINMUX_AF('B', 15, AF2) + +/* TIMER7_BRKIN2 */ +#define TIMER7_BRKIN2_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER7_BRKIN2_PE10 \ + GD32_PINMUX_AF('E', 10, AF2) + +/* TIMER7_BRKIN3 */ +#define TIMER7_BRKIN3_PE9 \ + GD32_PINMUX_AF('E', 9, AF2) + +/* TIMER7_CH0 */ +#define TIMER7_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF1) +#define TIMER7_CH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF2) +#define TIMER7_CH0_PC12 \ + GD32_PINMUX_AF('C', 12, AF2) +#define TIMER7_CH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF2) +#define TIMER7_CH0_PE14 \ + GD32_PINMUX_AF('E', 14, AF1) + +/* TIMER7_CH1 */ +#define TIMER7_CH1_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER7_CH1_PD0 \ + GD32_PINMUX_AF('D', 0, AF2) +#define TIMER7_CH1_PE12 \ + GD32_PINMUX_AF('E', 12, AF1) +#define TIMER7_CH1_PE14 \ + GD32_PINMUX_AF('E', 14, AF2) + +/* TIMER7_CH2 */ +#define TIMER7_CH2_PB4 \ + GD32_PINMUX_AF('B', 4, AF1) + +/* TIMER7_CH3 */ +#define TIMER7_CH3_PB2 \ + GD32_PINMUX_AF('B', 2, AF2) +#define TIMER7_CH3_PD7 \ + GD32_PINMUX_AF('D', 7, AF1) + +/* TIMER7_MCH0 */ +#define TIMER7_MCH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF1) +#define TIMER7_MCH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF1) + +/* TIMER7_MCH1 */ +#define TIMER7_MCH1_PE11 \ + GD32_PINMUX_AF('E', 11, AF1) + +/* TIMER7_MCH2 */ +#define TIMER7_MCH2_PB3 \ + GD32_PINMUX_AF('B', 3, AF1) + +/* TIMER7_MCH3 */ +#define TIMER7_MCH3_PB1 \ + GD32_PINMUX_AF('B', 1, AF2) +#define TIMER7_MCH3_PD6 \ + GD32_PINMUX_AF('D', 6, AF1) + +/* TIMER_ETI0 */ +#define TIMER_ETI0_PB13 \ + GD32_PINMUX_AF('B', 13, AF0) + +/* TIMER_ETI1 */ +#define TIMER_ETI1_PB6 \ + GD32_PINMUX_AF('B', 6, AF3) + +/* TIMER_ETI2 */ +#define TIMER_ETI2_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* TIMRE19_BRKIN0 */ +#define TIMRE19_BRKIN0_PF2 \ + GD32_PINMUX_AF('F', 2, AF2) + +/* TRIGSEL_IN0 */ +#define TRIGSEL_IN0_PA1 \ + GD32_PINMUX_AF('A', 1, AF7) + +/* TRIGSEL_IN1 */ +#define TRIGSEL_IN1_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) + +/* TRIGSEL_IN13 */ +#define TRIGSEL_IN13_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) + +/* TRIGSEL_IN2 */ +#define TRIGSEL_IN2_PE13 \ + GD32_PINMUX_AF('E', 13, AF7) + +/* TRIGSEL_IN3 */ +#define TRIGSEL_IN3_PE14 \ + GD32_PINMUX_AF('E', 14, AF7) + +/* TRIGSEL_IN4 */ +#define TRIGSEL_IN4_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) + +/* TRIGSEL_IN5 */ +#define TRIGSEL_IN5_PA9 \ + GD32_PINMUX_AF('A', 9, AF7) + +/* TRIGSEL_IN6 */ +#define TRIGSEL_IN6_PF2 \ + GD32_PINMUX_AF('F', 2, AF6) + +/* TRIGSEL_IN7 */ +#define TRIGSEL_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) + +/* TRIGSEL_IN8 */ +#define TRIGSEL_IN8_PE11 \ + GD32_PINMUX_AF('E', 11, AF7) + +/* TRIGSEL_IN9 */ +#define TRIGSEL_IN9_PE12 \ + GD32_PINMUX_AF('E', 12, AF7) + +/* TRIGSEL_OUT0 */ +#define TRIGSEL_OUT0_PC10 \ + GD32_PINMUX_AF('C', 10, AF7) + +/* TRIGSEL_OUT1 */ +#define TRIGSEL_OUT1_PE5 \ + GD32_PINMUX_AF('E', 5, AF7) + +/* TRIGSEL_OUT2 */ +#define TRIGSEL_OUT2_PE4 \ + GD32_PINMUX_AF('E', 4, AF7) + +/* TRIGSEL_OUT3 */ +#define TRIGSEL_OUT3_PC11 \ + GD32_PINMUX_AF('C', 11, AF7) + +/* TRIGSEL_OUT4 */ +#define TRIGSEL_OUT4_PC13 \ + GD32_PINMUX_AF('C', 13, AF7) + +/* TRIGSEL_OUT5 */ +#define TRIGSEL_OUT5_PE6 \ + GD32_PINMUX_AF('E', 6, AF7) + +/* USART0_CTS */ +#define USART0_CTS_PC11 \ + GD32_PINMUX_AF('C', 11, AF5) +#define USART0_CTS_PD8 \ + GD32_PINMUX_AF('D', 8, AF5) + +/* USART0_DE */ +#define USART0_DE_PB15 \ + GD32_PINMUX_AF('B', 15, AF5) +#define USART0_DE_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RTS */ +#define USART0_RTS_PB15 \ + GD32_PINMUX_AF('B', 15, AF5) +#define USART0_RTS_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RX */ +#define USART0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define USART0_RX_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define USART0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF5) + +/* USART0_TX */ +#define USART0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define USART0_TX_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define USART0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF5) + +/* USART1_CTS */ +#define USART1_CTS_PD4 \ + GD32_PINMUX_AF('D', 4, AF5) +#define USART1_CTS_PD10 \ + GD32_PINMUX_AF('D', 10, AF5) +#define USART1_CTS_PF5 \ + GD32_PINMUX_AF('F', 5, AF5) + +/* USART1_DE */ +#define USART1_DE_PD3 \ + GD32_PINMUX_AF('D', 3, AF5) +#define USART1_DE_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) + +/* USART1_RTS */ +#define USART1_RTS_PD3 \ + GD32_PINMUX_AF('D', 3, AF5) +#define USART1_RTS_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) + +/* USART1_RX */ +#define USART1_RX_PD0 \ + GD32_PINMUX_AF('D', 0, AF5) +#define USART1_RX_PD8 \ + GD32_PINMUX_AF('D', 8, AF4) + +/* USART1_TX */ +#define USART1_TX_PB15 \ + GD32_PINMUX_AF('B', 15, AF4) +#define USART1_TX_PC12 \ + GD32_PINMUX_AF('C', 12, AF5) + +/* USART2_CK */ +#define USART2_CK_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) + +/* USART2_CTS */ +#define USART2_CTS_PC1 \ + GD32_PINMUX_AF('C', 1, AF5) + +/* USART2_DE */ +#define USART2_DE_PF2 \ + GD32_PINMUX_AF('F', 2, AF5) + +/* USART2_RTS */ +#define USART2_RTS_PF2 \ + GD32_PINMUX_AF('F', 2, AF5) + +/* USART2_RX */ +#define USART2_RX_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) + +/* USART2_TX */ +#define USART2_TX_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) diff --git a/include/dt-bindings/pinctrl/gd32a503v(b-c-d)xx-pinctrl.h b/include/dt-bindings/pinctrl/gd32a503v(b-c-d)xx-pinctrl.h new file mode 100644 index 0000000..5c3e849 --- /dev/null +++ b/include/dt-bindings/pinctrl/gd32a503v(b-c-d)xx-pinctrl.h @@ -0,0 +1,1375 @@ +/* + * Autogenerated file + * + * SPDX-License-Identifier: Apache 2.0 + */ + +#include "gd32-af.h" + +/* ADC0_IN0 */ +#define ADC0_IN0_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) + +/* ADC0_IN1 */ +#define ADC0_IN1_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) + +/* ADC0_IN10 */ +#define ADC0_IN10_PA4 \ + GD32_PINMUX_AF('A', 4, ANALOG) + +/* ADC0_IN11 */ +#define ADC0_IN11_PA3 \ + GD32_PINMUX_AF('A', 3, ANALOG) + +/* ADC0_IN12 */ +#define ADC0_IN12_PE12 \ + GD32_PINMUX_AF('E', 12, ANALOG) + +/* ADC0_IN13 */ +#define ADC0_IN13_PE11 \ + GD32_PINMUX_AF('E', 11, ANALOG) + +/* ADC0_IN14 */ +#define ADC0_IN14_PE10 \ + GD32_PINMUX_AF('E', 10, ANALOG) + +/* ADC0_IN15 */ +#define ADC0_IN15_PE9 \ + GD32_PINMUX_AF('E', 9, ANALOG) + +/* ADC0_IN2 */ +#define ADC0_IN2_PD10 \ + GD32_PINMUX_AF('D', 10, ANALOG) + +/* ADC0_IN3 */ +#define ADC0_IN3_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) + +/* ADC0_IN4 */ +#define ADC0_IN4_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) + +/* ADC0_IN5 */ +#define ADC0_IN5_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) + +/* ADC0_IN6 */ +#define ADC0_IN6_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) + +/* ADC0_IN7 */ +#define ADC0_IN7_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) + +/* ADC0_IN8 */ +#define ADC0_IN8_PB2 \ + GD32_PINMUX_AF('B', 2, ANALOG) +#define ADC0_IN8_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) + +/* ADC0_IN9 */ +#define ADC0_IN9_PB1 \ + GD32_PINMUX_AF('B', 1, ANALOG) +#define ADC0_IN9_PC6 \ + GD32_PINMUX_AF('C', 6, ANALOG) + +/* ADC1_IN0 */ +#define ADC1_IN0_PA11 \ + GD32_PINMUX_AF('A', 11, ANALOG) + +/* ADC1_IN1 */ +#define ADC1_IN1_PA10 \ + GD32_PINMUX_AF('A', 10, ANALOG) + +/* ADC1_IN10 */ +#define ADC1_IN10_PD4 \ + GD32_PINMUX_AF('D', 4, ANALOG) + +/* ADC1_IN11 */ +#define ADC1_IN11_PD3 \ + GD32_PINMUX_AF('D', 3, ANALOG) + +/* ADC1_IN12 */ +#define ADC1_IN12_PD2 \ + GD32_PINMUX_AF('D', 2, ANALOG) + +/* ADC1_IN13 */ +#define ADC1_IN13_PD1 \ + GD32_PINMUX_AF('D', 1, ANALOG) + +/* ADC1_IN14 */ +#define ADC1_IN14_PB14 \ + GD32_PINMUX_AF('B', 14, ANALOG) +#define ADC1_IN14_PD15 \ + GD32_PINMUX_AF('D', 15, ANALOG) + +/* ADC1_IN15 */ +#define ADC1_IN15_PB13 \ + GD32_PINMUX_AF('B', 13, ANALOG) +#define ADC1_IN15_PD14 \ + GD32_PINMUX_AF('D', 14, ANALOG) + +/* ADC1_IN2 */ +#define ADC1_IN2_PA9 \ + GD32_PINMUX_AF('A', 9, ANALOG) + +/* ADC1_IN3 */ +#define ADC1_IN3_PA8 \ + GD32_PINMUX_AF('A', 8, ANALOG) + +/* ADC1_IN4 */ +#define ADC1_IN4_PD0 \ + GD32_PINMUX_AF('D', 0, ANALOG) + +/* ADC1_IN5 */ +#define ADC1_IN5_PC12 \ + GD32_PINMUX_AF('C', 12, ANALOG) + +/* ADC1_IN6 */ +#define ADC1_IN6_PC9 \ + GD32_PINMUX_AF('C', 9, ANALOG) + +/* ADC1_IN7 */ +#define ADC1_IN7_PC8 \ + GD32_PINMUX_AF('C', 8, ANALOG) + +/* ADC1_IN8 */ +#define ADC1_IN8_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) + +/* ADC1_IN9 */ +#define ADC1_IN9_PC6 \ + GD32_PINMUX_AF('C', 6, 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_PC0 \ + GD32_PINMUX_AF('C', 0, ANALOG) +#define ANALOG_PC1 \ + GD32_PINMUX_AF('C', 1, ANALOG) +#define ANALOG_PC2 \ + GD32_PINMUX_AF('C', 2, ANALOG) +#define ANALOG_PC3 \ + GD32_PINMUX_AF('C', 3, ANALOG) +#define ANALOG_PC4 \ + GD32_PINMUX_AF('C', 4, ANALOG) +#define ANALOG_PC5 \ + GD32_PINMUX_AF('C', 5, ANALOG) +#define ANALOG_PC6 \ + GD32_PINMUX_AF('C', 6, ANALOG) +#define ANALOG_PC7 \ + GD32_PINMUX_AF('C', 7, ANALOG) +#define ANALOG_PC8 \ + GD32_PINMUX_AF('C', 8, ANALOG) +#define ANALOG_PC9 \ + GD32_PINMUX_AF('C', 9, ANALOG) +#define ANALOG_PC10 \ + GD32_PINMUX_AF('C', 10, ANALOG) +#define ANALOG_PC11 \ + GD32_PINMUX_AF('C', 11, ANALOG) +#define ANALOG_PC12 \ + GD32_PINMUX_AF('C', 12, 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_PD4 \ + GD32_PINMUX_AF('D', 4, ANALOG) +#define ANALOG_PD5 \ + GD32_PINMUX_AF('D', 5, ANALOG) +#define ANALOG_PD6 \ + GD32_PINMUX_AF('D', 6, ANALOG) +#define ANALOG_PD7 \ + GD32_PINMUX_AF('D', 7, ANALOG) +#define ANALOG_PD8 \ + GD32_PINMUX_AF('D', 8, ANALOG) +#define ANALOG_PD9 \ + GD32_PINMUX_AF('D', 9, ANALOG) +#define ANALOG_PD10 \ + GD32_PINMUX_AF('D', 10, ANALOG) +#define ANALOG_PD11 \ + GD32_PINMUX_AF('D', 11, ANALOG) +#define ANALOG_PD12 \ + GD32_PINMUX_AF('D', 12, ANALOG) +#define ANALOG_PD13 \ + GD32_PINMUX_AF('D', 13, ANALOG) +#define ANALOG_PD14 \ + GD32_PINMUX_AF('D', 14, ANALOG) +#define ANALOG_PD15 \ + GD32_PINMUX_AF('D', 15, ANALOG) +#define ANALOG_PE0 \ + GD32_PINMUX_AF('E', 0, ANALOG) +#define ANALOG_PE1 \ + GD32_PINMUX_AF('E', 1, ANALOG) +#define ANALOG_PE2 \ + GD32_PINMUX_AF('E', 2, ANALOG) +#define ANALOG_PE3 \ + GD32_PINMUX_AF('E', 3, ANALOG) +#define ANALOG_PE4 \ + GD32_PINMUX_AF('E', 4, ANALOG) +#define ANALOG_PE5 \ + GD32_PINMUX_AF('E', 5, ANALOG) +#define ANALOG_PE6 \ + GD32_PINMUX_AF('E', 6, ANALOG) +#define ANALOG_PE7 \ + GD32_PINMUX_AF('E', 7, ANALOG) +#define ANALOG_PE8 \ + GD32_PINMUX_AF('E', 8, ANALOG) +#define ANALOG_PE9 \ + GD32_PINMUX_AF('E', 9, ANALOG) +#define ANALOG_PE10 \ + GD32_PINMUX_AF('E', 10, ANALOG) +#define ANALOG_PE11 \ + GD32_PINMUX_AF('E', 11, ANALOG) +#define ANALOG_PE12 \ + GD32_PINMUX_AF('E', 12, ANALOG) +#define ANALOG_PE13 \ + GD32_PINMUX_AF('E', 13, ANALOG) +#define ANALOG_PE14 \ + GD32_PINMUX_AF('E', 14, ANALOG) +#define ANALOG_PE15 \ + GD32_PINMUX_AF('E', 15, 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) +#define ANALOG_PF4 \ + GD32_PINMUX_AF('F', 4, ANALOG) +#define ANALOG_PF5 \ + GD32_PINMUX_AF('F', 5, ANALOG) +#define ANALOG_PF6 \ + GD32_PINMUX_AF('F', 6, ANALOG) +#define ANALOG_PF7 \ + GD32_PINMUX_AF('F', 7, ANALOG) + +/* CAN0_RX */ +#define CAN0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF6) +#define CAN0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF6) +#define CAN0_RX_PF0 \ + GD32_PINMUX_AF('F', 0, AF6) + +/* CAN0_TX */ +#define CAN0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF6) +#define CAN0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF6) +#define CAN0_TX_PC15 \ + GD32_PINMUX_AF('C', 15, AF6) + +/* CAN1_RX */ +#define CAN1_RX_PD0 \ + GD32_PINMUX_AF('D', 0, AF6) +#define CAN1_RX_PD7 \ + GD32_PINMUX_AF('D', 7, AF6) + +/* CAN1_TX */ +#define CAN1_TX_PC12 \ + GD32_PINMUX_AF('C', 12, AF6) +#define CAN1_TX_PD6 \ + GD32_PINMUX_AF('D', 6, AF6) + +/* CK_OUT */ +#define CK_OUT_PC2 \ + GD32_PINMUX_AF('C', 2, AF0) +#define CK_OUT_PC13 \ + GD32_PINMUX_AF('C', 13, AF0) + +/* CK_OUT0 */ +#define CK_OUT0_PA1 \ + GD32_PINMUX_AF('A', 1, AF0) + +/* CMP_OUT */ +#define CMP_OUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF7) +#define CMP_OUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF7) + +/* DAC_OUT */ +#define DAC_OUT_PA7 \ + GD32_PINMUX_AF('A', 7, ANALOG) + +/* EVENTOUT */ +#define EVENTOUT_PA0 \ + GD32_PINMUX_AF('A', 0, AF9) +#define EVENTOUT_PA1 \ + GD32_PINMUX_AF('A', 1, AF9) +#define EVENTOUT_PA2 \ + GD32_PINMUX_AF('A', 2, AF9) +#define EVENTOUT_PA3 \ + GD32_PINMUX_AF('A', 3, AF9) +#define EVENTOUT_PA4 \ + GD32_PINMUX_AF('A', 4, AF9) +#define EVENTOUT_PA5 \ + GD32_PINMUX_AF('A', 5, AF9) +#define EVENTOUT_PA7 \ + GD32_PINMUX_AF('A', 7, AF9) +#define EVENTOUT_PA8 \ + GD32_PINMUX_AF('A', 8, AF9) +#define EVENTOUT_PA9 \ + GD32_PINMUX_AF('A', 9, AF9) +#define EVENTOUT_PA10 \ + GD32_PINMUX_AF('A', 10, AF9) +#define EVENTOUT_PA11 \ + GD32_PINMUX_AF('A', 11, AF9) +#define EVENTOUT_PA12 \ + GD32_PINMUX_AF('A', 12, AF9) +#define EVENTOUT_PA13 \ + GD32_PINMUX_AF('A', 13, AF9) +#define EVENTOUT_PA14 \ + GD32_PINMUX_AF('A', 14, AF9) +#define EVENTOUT_PA15 \ + GD32_PINMUX_AF('A', 15, AF9) +#define EVENTOUT_PB0 \ + GD32_PINMUX_AF('B', 0, AF9) +#define EVENTOUT_PB1 \ + GD32_PINMUX_AF('B', 1, AF9) +#define EVENTOUT_PB2 \ + GD32_PINMUX_AF('B', 2, AF9) +#define EVENTOUT_PB3 \ + GD32_PINMUX_AF('B', 3, AF9) +#define EVENTOUT_PB4 \ + GD32_PINMUX_AF('B', 4, AF9) +#define EVENTOUT_PB5 \ + GD32_PINMUX_AF('B', 5, AF9) +#define EVENTOUT_PB6 \ + GD32_PINMUX_AF('B', 6, AF9) +#define EVENTOUT_PB7 \ + GD32_PINMUX_AF('B', 7, AF9) +#define EVENTOUT_PB8 \ + GD32_PINMUX_AF('B', 8, AF9) +#define EVENTOUT_PB9 \ + GD32_PINMUX_AF('B', 9, AF9) +#define EVENTOUT_PB10 \ + GD32_PINMUX_AF('B', 10, AF9) +#define EVENTOUT_PB11 \ + GD32_PINMUX_AF('B', 11, AF9) +#define EVENTOUT_PB12 \ + GD32_PINMUX_AF('B', 12, AF9) +#define EVENTOUT_PB13 \ + GD32_PINMUX_AF('B', 13, AF9) +#define EVENTOUT_PB14 \ + GD32_PINMUX_AF('B', 14, AF9) +#define EVENTOUT_PB15 \ + GD32_PINMUX_AF('B', 15, AF9) +#define EVENTOUT_PC0 \ + GD32_PINMUX_AF('C', 0, AF9) +#define EVENTOUT_PC1 \ + GD32_PINMUX_AF('C', 1, AF9) +#define EVENTOUT_PC2 \ + GD32_PINMUX_AF('C', 2, AF9) +#define EVENTOUT_PC3 \ + GD32_PINMUX_AF('C', 3, AF9) +#define EVENTOUT_PC4 \ + GD32_PINMUX_AF('C', 4, AF9) +#define EVENTOUT_PC5 \ + GD32_PINMUX_AF('C', 5, AF9) +#define EVENTOUT_PC6 \ + GD32_PINMUX_AF('C', 6, AF9) +#define EVENTOUT_PC7 \ + GD32_PINMUX_AF('C', 7, AF9) +#define EVENTOUT_PC8 \ + GD32_PINMUX_AF('C', 8, AF9) +#define EVENTOUT_PC9 \ + GD32_PINMUX_AF('C', 9, AF9) +#define EVENTOUT_PC10 \ + GD32_PINMUX_AF('C', 10, AF9) +#define EVENTOUT_PC11 \ + GD32_PINMUX_AF('C', 11, AF9) +#define EVENTOUT_PC12 \ + GD32_PINMUX_AF('C', 12, AF9) +#define EVENTOUT_PC13 \ + GD32_PINMUX_AF('C', 13, AF9) +#define EVENTOUT_PC14 \ + GD32_PINMUX_AF('C', 14, AF9) +#define EVENTOUT_PC15 \ + GD32_PINMUX_AF('C', 15, AF9) +#define EVENTOUT_PD0 \ + GD32_PINMUX_AF('D', 0, AF9) +#define EVENTOUT_PD1 \ + GD32_PINMUX_AF('D', 1, AF9) +#define EVENTOUT_PD2 \ + GD32_PINMUX_AF('D', 2, AF9) +#define EVENTOUT_PD3 \ + GD32_PINMUX_AF('D', 3, AF9) +#define EVENTOUT_PD4 \ + GD32_PINMUX_AF('D', 4, AF9) +#define EVENTOUT_PD5 \ + GD32_PINMUX_AF('D', 5, AF9) +#define EVENTOUT_PD6 \ + GD32_PINMUX_AF('D', 6, AF9) +#define EVENTOUT_PD7 \ + GD32_PINMUX_AF('D', 7, AF9) +#define EVENTOUT_PD8 \ + GD32_PINMUX_AF('D', 8, AF9) +#define EVENTOUT_PD9 \ + GD32_PINMUX_AF('D', 9, AF9) +#define EVENTOUT_PD10 \ + GD32_PINMUX_AF('D', 10, AF9) +#define EVENTOUT_PD11 \ + GD32_PINMUX_AF('D', 11, AF9) +#define EVENTOUT_PD12 \ + GD32_PINMUX_AF('D', 12, AF9) +#define EVENTOUT_PD13 \ + GD32_PINMUX_AF('D', 13, AF9) +#define EVENTOUT_PD14 \ + GD32_PINMUX_AF('D', 14, AF9) +#define EVENTOUT_PD15 \ + GD32_PINMUX_AF('D', 15, AF9) +#define EVENTOUT_PE0 \ + GD32_PINMUX_AF('E', 0, AF9) +#define EVENTOUT_PE1 \ + GD32_PINMUX_AF('E', 1, AF9) +#define EVENTOUT_PE2 \ + GD32_PINMUX_AF('E', 2, AF9) +#define EVENTOUT_PE3 \ + GD32_PINMUX_AF('E', 3, AF9) +#define EVENTOUT_PE4 \ + GD32_PINMUX_AF('E', 4, AF9) +#define EVENTOUT_PE5 \ + GD32_PINMUX_AF('E', 5, AF9) +#define EVENTOUT_PE6 \ + GD32_PINMUX_AF('E', 6, AF9) +#define EVENTOUT_PE7 \ + GD32_PINMUX_AF('E', 7, AF9) +#define EVENTOUT_PE8 \ + GD32_PINMUX_AF('E', 8, AF9) +#define EVENTOUT_PE9 \ + GD32_PINMUX_AF('E', 9, AF9) +#define EVENTOUT_PE10 \ + GD32_PINMUX_AF('E', 10, AF9) +#define EVENTOUT_PE11 \ + GD32_PINMUX_AF('E', 11, AF9) +#define EVENTOUT_PE12 \ + GD32_PINMUX_AF('E', 12, AF9) +#define EVENTOUT_PE13 \ + GD32_PINMUX_AF('E', 13, AF9) +#define EVENTOUT_PE14 \ + GD32_PINMUX_AF('E', 14, AF9) +#define EVENTOUT_PE15 \ + GD32_PINMUX_AF('E', 15, AF9) +#define EVENTOUT_PF0 \ + GD32_PINMUX_AF('F', 0, AF9) +#define EVENTOUT_PF1 \ + GD32_PINMUX_AF('F', 1, AF9) +#define EVENTOUT_PF2 \ + GD32_PINMUX_AF('F', 2, AF9) +#define EVENTOUT_PF3 \ + GD32_PINMUX_AF('F', 3, AF9) +#define EVENTOUT_PF4 \ + GD32_PINMUX_AF('F', 4, AF9) +#define EVENTOUT_PF5 \ + GD32_PINMUX_AF('F', 5, AF9) +#define EVENTOUT_PF6 \ + GD32_PINMUX_AF('F', 6, AF9) +#define EVENTOUT_PF7 \ + GD32_PINMUX_AF('F', 7, AF9) + +/* I2C0_SCL */ +#define I2C0_SCL_PA10 \ + GD32_PINMUX_AF('A', 10, AF3) +#define I2C0_SCL_PA14 \ + GD32_PINMUX_AF('A', 14, AF3) +#define I2C0_SCL_PC11 \ + GD32_PINMUX_AF('C', 11, AF3) +#define I2C0_SCL_PF6 \ + GD32_PINMUX_AF('F', 6, AF3) + +/* I2C0_SDA */ +#define I2C0_SDA_PA11 \ + GD32_PINMUX_AF('A', 11, AF3) +#define I2C0_SDA_PA13 \ + GD32_PINMUX_AF('A', 13, AF3) +#define I2C0_SDA_PC10 \ + GD32_PINMUX_AF('C', 10, AF3) +#define I2C0_SDA_PF7 \ + GD32_PINMUX_AF('F', 7, AF3) + +/* I2C0_SMBA */ +#define I2C0_SMBA_PA12 \ + GD32_PINMUX_AF('A', 12, AF3) +#define I2C0_SMBA_PB5 \ + GD32_PINMUX_AF('B', 5, AF3) + +/* I2C1_SCL */ +#define I2C1_SCL_PB7 \ + GD32_PINMUX_AF('B', 7, AF5) +#define I2C1_SCL_PD6 \ + GD32_PINMUX_AF('D', 6, AF5) +#define I2C1_SCL_PE10 \ + GD32_PINMUX_AF('E', 10, AF5) + +/* I2C1_SDA */ +#define I2C1_SDA_PB8 \ + GD32_PINMUX_AF('B', 8, AF5) +#define I2C1_SDA_PD7 \ + GD32_PINMUX_AF('D', 7, AF5) +#define I2C1_SDA_PE11 \ + GD32_PINMUX_AF('E', 11, AF5) + +/* I2C1_SMBA */ +#define I2C1_SMBA_PB9 \ + GD32_PINMUX_AF('B', 9, AF5) +#define I2C1_SMBA_PD11 \ + GD32_PINMUX_AF('D', 11, AF5) +#define I2C1_SMBA_PE12 \ + GD32_PINMUX_AF('E', 12, AF5) + +/* I2S1_CK */ +#define I2S1_CK_PC6 \ + GD32_PINMUX_AF('C', 6, AF4) +#define I2S1_CK_PE5 \ + GD32_PINMUX_AF('E', 5, AF4) + +/* I2S1_MCK */ +#define I2S1_MCK_PC7 \ + GD32_PINMUX_AF('C', 7, AF4) +#define I2S1_MCK_PE6 \ + GD32_PINMUX_AF('E', 6, AF4) + +/* I2S1_SD */ +#define I2S1_SD_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) +#define I2S1_SD_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) +#define I2S1_SD_PD14 \ + GD32_PINMUX_AF('D', 14, AF4) + +/* I2S1_WS */ +#define I2S1_WS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) +#define I2S1_WS_PB5 \ + GD32_PINMUX_AF('B', 5, AF6) +#define I2S1_WS_PD1 \ + GD32_PINMUX_AF('D', 1, AF4) +#define I2S1_WS_PD10 \ + GD32_PINMUX_AF('D', 10, AF4) +#define I2S1_WS_PD13 \ + GD32_PINMUX_AF('D', 13, AF4) + +/* JTCK */ +#define JTCK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* JTDI */ +#define JTDI_PB7 \ + GD32_PINMUX_AF('B', 7, AF0) + +/* JTDO */ +#define JTDO_PB4 \ + GD32_PINMUX_AF('B', 4, AF0) + +/* JTMS */ +#define JTMS_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* MFCOM_D0 */ +#define MFCOM_D0_PB4 \ + GD32_PINMUX_AF('B', 4, AF6) +#define MFCOM_D0_PE5 \ + GD32_PINMUX_AF('E', 5, AF6) +#define MFCOM_D0_PE7 \ + GD32_PINMUX_AF('E', 7, AF6) + +/* MFCOM_D1 */ +#define MFCOM_D1_PB3 \ + GD32_PINMUX_AF('B', 3, AF6) +#define MFCOM_D1_PE4 \ + GD32_PINMUX_AF('E', 4, AF6) +#define MFCOM_D1_PE8 \ + GD32_PINMUX_AF('E', 8, AF6) + +/* MFCOM_D2 */ +#define MFCOM_D2_PC11 \ + GD32_PINMUX_AF('C', 11, AF6) +#define MFCOM_D2_PE3 \ + GD32_PINMUX_AF('E', 3, AF12) + +/* MFCOM_D3 */ +#define MFCOM_D3_PC10 \ + GD32_PINMUX_AF('C', 10, AF6) +#define MFCOM_D3_PE2 \ + GD32_PINMUX_AF('E', 2, AF6) + +/* MFCOM_D4 */ +#define MFCOM_D4_PA9 \ + GD32_PINMUX_AF('A', 9, AF6) +#define MFCOM_D4_PA11 \ + GD32_PINMUX_AF('A', 11, AF6) +#define MFCOM_D4_PC13 \ + GD32_PINMUX_AF('C', 13, AF6) + +/* MFCOM_D5 */ +#define MFCOM_D5_PA8 \ + GD32_PINMUX_AF('A', 8, AF6) +#define MFCOM_D5_PA10 \ + GD32_PINMUX_AF('A', 10, AF6) +#define MFCOM_D5_PE6 \ + GD32_PINMUX_AF('E', 6, AF6) + +/* MFCOM_D6 */ +#define MFCOM_D6_PA9 \ + GD32_PINMUX_AF('A', 9, AF5) +#define MFCOM_D6_PE1 \ + GD32_PINMUX_AF('E', 1, AF6) +#define MFCOM_D6_PF0 \ + GD32_PINMUX_AF('F', 0, AF7) + +/* MFCOM_D7 */ +#define MFCOM_D7_PA8 \ + GD32_PINMUX_AF('A', 8, AF5) +#define MFCOM_D7_PC15 \ + GD32_PINMUX_AF('C', 15, AF7) +#define MFCOM_D7_PE0 \ + GD32_PINMUX_AF('E', 0, AF6) + +/* NJTRST */ +#define NJTRST_PB3 \ + GD32_PINMUX_AF('B', 3, AF0) + +/* SPI0_IO2 */ +#define SPI0_IO2_PB3 \ + GD32_PINMUX_AF('B', 3, AF4) +#define SPI0_IO2_PE15 \ + GD32_PINMUX_AF('E', 15, AF4) + +/* SPI0_IO3 */ +#define SPI0_IO3_PB4 \ + GD32_PINMUX_AF('B', 4, AF4) +#define SPI0_IO3_PB10 \ + GD32_PINMUX_AF('B', 10, AF4) + +/* SPI0_MISO */ +#define SPI0_MISO_PB5 \ + GD32_PINMUX_AF('B', 5, AF4) +#define SPI0_MISO_PE13 \ + GD32_PINMUX_AF('E', 13, AF4) +#define SPI0_MISO_PF5 \ + GD32_PINMUX_AF('F', 5, AF4) + +/* SPI0_MOSI */ +#define SPI0_MOSI_PA2 \ + GD32_PINMUX_AF('A', 2, AF4) +#define SPI0_MOSI_PB13 \ + GD32_PINMUX_AF('B', 13, AF4) +#define SPI0_MOSI_PD4 \ + GD32_PINMUX_AF('D', 4, AF4) + +/* SPI0_NSS */ +#define SPI0_NSS_PA1 \ + GD32_PINMUX_AF('A', 1, AF4) +#define SPI0_NSS_PB14 \ + GD32_PINMUX_AF('B', 14, AF3) +#define SPI0_NSS_PD2 \ + GD32_PINMUX_AF('D', 2, AF4) +#define SPI0_NSS_PD3 \ + GD32_PINMUX_AF('D', 3, AF4) + +/* SPI0_SCK */ +#define SPI0_SCK_PB6 \ + GD32_PINMUX_AF('B', 6, AF4) +#define SPI0_SCK_PC0 \ + GD32_PINMUX_AF('C', 0, AF4) +#define SPI0_SCK_PE14 \ + GD32_PINMUX_AF('E', 14, AF4) + +/* SPI1_MISO */ +#define SPI1_MISO_PD15 \ + GD32_PINMUX_AF('D', 15, AF4) +#define SPI1_MISO_PE4 \ + GD32_PINMUX_AF('E', 4, AF4) + +/* SPI1_MOSI */ +#define SPI1_MOSI_PA9 \ + GD32_PINMUX_AF('A', 9, AF4) +#define SPI1_MOSI_PB6 \ + GD32_PINMUX_AF('B', 6, AF5) +#define SPI1_MOSI_PD14 \ + GD32_PINMUX_AF('D', 14, AF4) + +/* SPI1_NSS */ +#define SPI1_NSS_PA8 \ + GD32_PINMUX_AF('A', 8, AF4) +#define SPI1_NSS_PB5 \ + GD32_PINMUX_AF('B', 5, AF5) +#define SPI1_NSS_PD1 \ + GD32_PINMUX_AF('D', 1, AF4) +#define SPI1_NSS_PD10 \ + GD32_PINMUX_AF('D', 10, AF4) +#define SPI1_NSS_PD13 \ + GD32_PINMUX_AF('D', 13, AF4) + +/* SPI1_SCK */ +#define SPI1_SCK_PC6 \ + GD32_PINMUX_AF('C', 6, AF4) +#define SPI1_SCK_PE5 \ + GD32_PINMUX_AF('E', 5, AF4) + +/* SWCLK */ +#define SWCLK_PB8 \ + GD32_PINMUX_AF('B', 8, AF0) + +/* SWDIO */ +#define SWDIO_PB9 \ + GD32_PINMUX_AF('B', 9, AF0) + +/* TIMER0_BRKIN0 */ +#define TIMER0_BRKIN0_PA8 \ + GD32_PINMUX_AF('A', 8, AF1) +#define TIMER0_BRKIN0_PD5 \ + GD32_PINMUX_AF('D', 5, AF7) +#define TIMER0_BRKIN0_PF2 \ + GD32_PINMUX_AF('F', 2, AF1) + +/* TIMER0_BRKIN1 */ +#define TIMER0_BRKIN1_PD10 \ + GD32_PINMUX_AF('D', 10, AF2) +#define TIMER0_BRKIN1_PF1 \ + GD32_PINMUX_AF('F', 1, AF1) + +/* TIMER0_BRKIN2 */ +#define TIMER0_BRKIN2_PD9 \ + GD32_PINMUX_AF('D', 9, AF2) +#define TIMER0_BRKIN2_PF4 \ + GD32_PINMUX_AF('F', 4, AF2) + +/* TIMER0_BRKIN3 */ +#define TIMER0_BRKIN3_PC9 \ + GD32_PINMUX_AF('C', 9, AF1) +#define TIMER0_BRKIN3_PF3 \ + GD32_PINMUX_AF('F', 3, AF2) + +/* TIMER0_CH0 */ +#define TIMER0_CH0_PB2 \ + GD32_PINMUX_AF('B', 2, AF1) +#define TIMER0_CH0_PC0 \ + GD32_PINMUX_AF('C', 0, AF1) +#define TIMER0_CH0_PC8 \ + GD32_PINMUX_AF('C', 8, AF1) + +/* TIMER0_CH1 */ +#define TIMER0_CH1_PA4 \ + GD32_PINMUX_AF('A', 4, AF1) +#define TIMER0_CH1_PC6 \ + GD32_PINMUX_AF('C', 6, AF1) +#define TIMER0_CH1_PE5 \ + GD32_PINMUX_AF('E', 5, AF1) + +/* TIMER0_CH2 */ +#define TIMER0_CH2_PA2 \ + GD32_PINMUX_AF('A', 2, AF1) +#define TIMER0_CH2_PD14 \ + GD32_PINMUX_AF('D', 14, AF1) + +/* TIMER0_CH3 */ +#define TIMER0_CH3_PA0 \ + GD32_PINMUX_AF('A', 0, AF1) +#define TIMER0_CH3_PD12 \ + GD32_PINMUX_AF('D', 12, AF1) + +/* TIMER0_MCH0 */ +#define TIMER0_MCH0_PB1 \ + GD32_PINMUX_AF('B', 1, AF1) +#define TIMER0_MCH0_PC7 \ + GD32_PINMUX_AF('C', 7, AF1) +#define TIMER0_MCH0_PF5 \ + GD32_PINMUX_AF('F', 5, AF1) + +/* TIMER0_MCH1 */ +#define TIMER0_MCH1_PA3 \ + GD32_PINMUX_AF('A', 3, AF1) +#define TIMER0_MCH1_PD15 \ + GD32_PINMUX_AF('D', 15, AF1) +#define TIMER0_MCH1_PE4 \ + GD32_PINMUX_AF('E', 4, AF1) + +/* TIMER0_MCH2 */ +#define TIMER0_MCH2_PA1 \ + GD32_PINMUX_AF('A', 1, AF1) +#define TIMER0_MCH2_PD13 \ + GD32_PINMUX_AF('D', 13, AF1) + +/* TIMER0_MCH3 */ +#define TIMER0_MCH3_PC1 \ + GD32_PINMUX_AF('C', 1, AF1) +#define TIMER0_MCH3_PD11 \ + GD32_PINMUX_AF('D', 11, AF1) + +/* TIMER19_BRKIN0 */ +#define TIMER19_BRKIN0_PC14 \ + GD32_PINMUX_AF('C', 14, AF2) + +/* TIMER19_BRKIN1 */ +#define TIMER19_BRKIN1_PA7 \ + GD32_PINMUX_AF('A', 7, AF3) +#define TIMER19_BRKIN1_PF1 \ + GD32_PINMUX_AF('F', 1, AF2) + +/* TIMER19_BRKIN2 */ +#define TIMER19_BRKIN2_PA6 \ + GD32_PINMUX_AF('A', 6, AF2) +#define TIMER19_BRKIN2_PE8 \ + GD32_PINMUX_AF('E', 8, AF2) + +/* TIMER19_BRKIN3 */ +#define TIMER19_BRKIN3_PA5 \ + GD32_PINMUX_AF('A', 5, AF2) +#define TIMER19_BRKIN3_PE7 \ + GD32_PINMUX_AF('E', 7, AF2) + +/* TIMER19_CH0 */ +#define TIMER19_CH0_PB0 \ + GD32_PINMUX_AF('B', 0, AF1) +#define TIMER19_CH0_PB7 \ + GD32_PINMUX_AF('B', 7, AF1) +#define TIMER19_CH0_PC5 \ + GD32_PINMUX_AF('C', 5, AF2) +#define TIMER19_CH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF2) +#define TIMER19_CH0_PD6 \ + GD32_PINMUX_AF('D', 6, AF2) +#define TIMER19_CH0_PE5 \ + GD32_PINMUX_AF('E', 5, AF2) + +/* TIMER19_CH1 */ +#define TIMER19_CH1_PB0 \ + GD32_PINMUX_AF('B', 0, AF2) +#define TIMER19_CH1_PB7 \ + GD32_PINMUX_AF('B', 7, AF2) +#define TIMER19_CH1_PC4 \ + GD32_PINMUX_AF('C', 4, AF1) +#define TIMER19_CH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF2) +#define TIMER19_CH1_PD7 \ + GD32_PINMUX_AF('D', 7, AF2) +#define TIMER19_CH1_PF0 \ + GD32_PINMUX_AF('F', 0, AF1) + +/* TIMER19_CH2 */ +#define TIMER19_CH2_PC3 \ + GD32_PINMUX_AF('C', 3, AF1) +#define TIMER19_CH2_PC13 \ + GD32_PINMUX_AF('C', 13, AF1) + +/* TIMER19_CH3 */ +#define TIMER19_CH3_PB10 \ + GD32_PINMUX_AF('B', 10, AF2) +#define TIMER19_CH3_PE3 \ + GD32_PINMUX_AF('E', 3, AF0) + +/* TIMER19_MCH0 */ +#define TIMER19_MCH0_PC5 \ + GD32_PINMUX_AF('C', 5, AF1) +#define TIMER19_MCH0_PC11 \ + GD32_PINMUX_AF('C', 11, AF1) +#define TIMER19_MCH0_PE4 \ + GD32_PINMUX_AF('E', 4, AF2) + +/* TIMER19_MCH1 */ +#define TIMER19_MCH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF1) +#define TIMER19_MCH1_PC15 \ + GD32_PINMUX_AF('C', 15, AF1) + +/* TIMER19_MCH2 */ +#define TIMER19_MCH2_PC2 \ + GD32_PINMUX_AF('C', 2, AF1) +#define TIMER19_MCH2_PE6 \ + GD32_PINMUX_AF('E', 6, AF2) + +/* TIMER19_MCH3 */ +#define TIMER19_MCH3_PE2 \ + GD32_PINMUX_AF('E', 2, AF2) +#define TIMER19_MCH3_PE15 \ + GD32_PINMUX_AF('E', 15, AF2) + +/* TIMER1_CH0 */ +#define TIMER1_CH0_PE6 \ + GD32_PINMUX_AF('E', 6, AF1) + +/* TIMER1_CH1 */ +#define TIMER1_CH1_PA7 \ + GD32_PINMUX_AF('A', 7, AF2) + +/* TIMER1_CH2 */ +#define TIMER1_CH2_PB14 \ + GD32_PINMUX_AF('B', 14, AF1) +#define TIMER1_CH2_PD4 \ + GD32_PINMUX_AF('D', 4, AF2) + +/* TIMER1_CH3 */ +#define TIMER1_CH3_PA3 \ + GD32_PINMUX_AF('A', 3, AF2) +#define TIMER1_CH3_PB11 \ + GD32_PINMUX_AF('B', 11, AF2) + +/* TIMER1_ETI */ +#define TIMER1_ETI_PE6 \ + GD32_PINMUX_AF('E', 6, AF1) + +/* TIMER20_BRKIN0 */ +#define TIMER20_BRKIN0_PD11 \ + GD32_PINMUX_AF('D', 11, AF2) +#define TIMER20_BRKIN0_PD12 \ + GD32_PINMUX_AF('D', 12, AF2) + +/* TIMER20_BRKIN1 */ +#define TIMER20_BRKIN1_PC7 \ + GD32_PINMUX_AF('C', 7, AF2) +#define TIMER20_BRKIN1_PD5 \ + GD32_PINMUX_AF('D', 5, AF12) + +/* TIMER20_BRKIN2 */ +#define TIMER20_BRKIN2_PC8 \ + GD32_PINMUX_AF('C', 8, AF2) +#define TIMER20_BRKIN2_PE0 \ + GD32_PINMUX_AF('E', 0, AF1) + +/* TIMER20_BRKIN3 */ +#define TIMER20_BRKIN3_PC9 \ + GD32_PINMUX_AF('C', 9, AF2) +#define TIMER20_BRKIN3_PE1 \ + GD32_PINMUX_AF('E', 1, AF1) + +/* TIMER20_CH0 */ +#define TIMER20_CH0_PA11 \ + GD32_PINMUX_AF('A', 11, AF1) +#define TIMER20_CH0_PA15 \ + GD32_PINMUX_AF('A', 15, AF1) + +/* TIMER20_CH1 */ +#define TIMER20_CH1_PA13 \ + GD32_PINMUX_AF('A', 13, AF1) +#define TIMER20_CH1_PD0 \ + GD32_PINMUX_AF('D', 0, AF1) + +/* TIMER20_CH2 */ +#define TIMER20_CH2_PA9 \ + GD32_PINMUX_AF('A', 9, AF1) +#define TIMER20_CH2_PB12 \ + GD32_PINMUX_AF('B', 12, AF1) + +/* TIMER20_CH3 */ +#define TIMER20_CH3_PB10 \ + GD32_PINMUX_AF('B', 10, AF1) +#define TIMER20_CH3_PD4 \ + GD32_PINMUX_AF('D', 4, AF1) + +/* TIMER20_MCH0 */ +#define TIMER20_MCH0_PA10 \ + GD32_PINMUX_AF('A', 10, AF1) +#define TIMER20_MCH0_PA14 \ + GD32_PINMUX_AF('A', 14, AF1) + +/* TIMER20_MCH1 */ +#define TIMER20_MCH1_PA12 \ + GD32_PINMUX_AF('A', 12, AF1) +#define TIMER20_MCH1_PC12 \ + GD32_PINMUX_AF('C', 12, AF1) + +/* TIMER20_MCH2 */ +#define TIMER20_MCH2_PA8 \ + GD32_PINMUX_AF('A', 8, AF2) +#define TIMER20_MCH2_PB11 \ + GD32_PINMUX_AF('B', 11, AF1) + +/* TIMER20_MCH3 */ +#define TIMER20_MCH3_PD3 \ + GD32_PINMUX_AF('D', 3, AF1) +#define TIMER20_MCH3_PE15 \ + GD32_PINMUX_AF('E', 15, AF1) + +/* TIMER7_BRKIN0 */ +#define TIMER7_BRKIN0_PD5 \ + GD32_PINMUX_AF('D', 5, AF12) +#define TIMER7_BRKIN0_PD8 \ + GD32_PINMUX_AF('D', 8, AF2) + +/* TIMER7_BRKIN1 */ +#define TIMER7_BRKIN1_PB5 \ + GD32_PINMUX_AF('B', 5, AF2) +#define TIMER7_BRKIN1_PB15 \ + GD32_PINMUX_AF('B', 15, AF2) + +/* TIMER7_BRKIN2 */ +#define TIMER7_BRKIN2_PB6 \ + GD32_PINMUX_AF('B', 6, AF2) +#define TIMER7_BRKIN2_PE10 \ + GD32_PINMUX_AF('E', 10, AF2) + +/* TIMER7_BRKIN3 */ +#define TIMER7_BRKIN3_PE0 \ + GD32_PINMUX_AF('E', 0, AF2) +#define TIMER7_BRKIN3_PE9 \ + GD32_PINMUX_AF('E', 9, AF2) + +/* TIMER7_CH0 */ +#define TIMER7_CH0_PB8 \ + GD32_PINMUX_AF('B', 8, AF1) +#define TIMER7_CH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF2) +#define TIMER7_CH0_PC12 \ + GD32_PINMUX_AF('C', 12, AF2) +#define TIMER7_CH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF2) +#define TIMER7_CH0_PE14 \ + GD32_PINMUX_AF('E', 14, AF1) + +/* TIMER7_CH1 */ +#define TIMER7_CH1_PB8 \ + GD32_PINMUX_AF('B', 8, AF2) +#define TIMER7_CH1_PD0 \ + GD32_PINMUX_AF('D', 0, AF2) +#define TIMER7_CH1_PD2 \ + GD32_PINMUX_AF('D', 2, AF1) +#define TIMER7_CH1_PE12 \ + GD32_PINMUX_AF('E', 12, AF1) +#define TIMER7_CH1_PE14 \ + GD32_PINMUX_AF('E', 14, AF2) + +/* TIMER7_CH2 */ +#define TIMER7_CH2_PB4 \ + GD32_PINMUX_AF('B', 4, AF1) +#define TIMER7_CH2_PE8 \ + GD32_PINMUX_AF('E', 8, AF1) + +/* TIMER7_CH3 */ +#define TIMER7_CH3_PB2 \ + GD32_PINMUX_AF('B', 2, AF2) +#define TIMER7_CH3_PD7 \ + GD32_PINMUX_AF('D', 7, AF1) + +/* TIMER7_MCH0 */ +#define TIMER7_MCH0_PC10 \ + GD32_PINMUX_AF('C', 10, AF1) +#define TIMER7_MCH0_PE13 \ + GD32_PINMUX_AF('E', 13, AF1) + +/* TIMER7_MCH1 */ +#define TIMER7_MCH1_PD1 \ + GD32_PINMUX_AF('D', 1, AF1) +#define TIMER7_MCH1_PE11 \ + GD32_PINMUX_AF('E', 11, AF1) + +/* TIMER7_MCH2 */ +#define TIMER7_MCH2_PB3 \ + GD32_PINMUX_AF('B', 3, AF1) +#define TIMER7_MCH2_PE7 \ + GD32_PINMUX_AF('E', 7, AF1) + +/* TIMER7_MCH3 */ +#define TIMER7_MCH3_PB1 \ + GD32_PINMUX_AF('B', 1, AF2) +#define TIMER7_MCH3_PD6 \ + GD32_PINMUX_AF('D', 6, AF1) + +/* TIMER_ETI0 */ +#define TIMER_ETI0_PB13 \ + GD32_PINMUX_AF('B', 13, AF0) + +/* TIMER_ETI1 */ +#define TIMER_ETI1_PB6 \ + GD32_PINMUX_AF('B', 6, AF3) + +/* TIMER_ETI2 */ +#define TIMER_ETI2_PC15 \ + GD32_PINMUX_AF('C', 15, AF0) + +/* TIMRE19_BRKIN0 */ +#define TIMRE19_BRKIN0_PF2 \ + GD32_PINMUX_AF('F', 2, AF2) + +/* TRIGSEL_IN0 */ +#define TRIGSEL_IN0_PA1 \ + GD32_PINMUX_AF('A', 1, AF7) + +/* TRIGSEL_IN1 */ +#define TRIGSEL_IN1_PA2 \ + GD32_PINMUX_AF('A', 2, AF7) + +/* TRIGSEL_IN10 */ +#define TRIGSEL_IN10_PB11 \ + GD32_PINMUX_AF('B', 11, AF7) + +/* TRIGSEL_IN11 */ +#define TRIGSEL_IN11_PB12 \ + GD32_PINMUX_AF('B', 12, AF7) + +/* TRIGSEL_IN12 */ +#define TRIGSEL_IN12_PA15 \ + GD32_PINMUX_AF('A', 15, AF7) + +/* TRIGSEL_IN13 */ +#define TRIGSEL_IN13_PA11 \ + GD32_PINMUX_AF('A', 11, AF7) + +/* TRIGSEL_IN2 */ +#define TRIGSEL_IN2_PE13 \ + GD32_PINMUX_AF('E', 13, AF7) + +/* TRIGSEL_IN3 */ +#define TRIGSEL_IN3_PE14 \ + GD32_PINMUX_AF('E', 14, AF7) + +/* TRIGSEL_IN4 */ +#define TRIGSEL_IN4_PA8 \ + GD32_PINMUX_AF('A', 8, AF7) + +/* TRIGSEL_IN5 */ +#define TRIGSEL_IN5_PA9 \ + GD32_PINMUX_AF('A', 9, AF7) + +/* TRIGSEL_IN6 */ +#define TRIGSEL_IN6_PF2 \ + GD32_PINMUX_AF('F', 2, AF6) + +/* TRIGSEL_IN7 */ +#define TRIGSEL_IN7_PA7 \ + GD32_PINMUX_AF('A', 7, AF7) + +/* TRIGSEL_IN8 */ +#define TRIGSEL_IN8_PE11 \ + GD32_PINMUX_AF('E', 11, AF7) + +/* TRIGSEL_IN9 */ +#define TRIGSEL_IN9_PE12 \ + GD32_PINMUX_AF('E', 12, AF7) + +/* TRIGSEL_OUT0 */ +#define TRIGSEL_OUT0_PC10 \ + GD32_PINMUX_AF('C', 10, AF7) + +/* TRIGSEL_OUT1 */ +#define TRIGSEL_OUT1_PE5 \ + GD32_PINMUX_AF('E', 5, AF7) + +/* TRIGSEL_OUT2 */ +#define TRIGSEL_OUT2_PE4 \ + GD32_PINMUX_AF('E', 4, AF7) + +/* TRIGSEL_OUT3 */ +#define TRIGSEL_OUT3_PC11 \ + GD32_PINMUX_AF('C', 11, AF7) + +/* TRIGSEL_OUT4 */ +#define TRIGSEL_OUT4_PC13 \ + GD32_PINMUX_AF('C', 13, AF7) + +/* TRIGSEL_OUT5 */ +#define TRIGSEL_OUT5_PE6 \ + GD32_PINMUX_AF('E', 6, AF7) + +/* TRIGSEL_OUT6 */ +#define TRIGSEL_OUT6_PE3 \ + GD32_PINMUX_AF('E', 3, AF12) + +/* TRIGSEL_OUT7 */ +#define TRIGSEL_OUT7_PE2 \ + GD32_PINMUX_AF('E', 2, AF7) + +/* USART0_CK */ +#define USART0_CK_PA12 \ + GD32_PINMUX_AF('A', 12, AF5) + +/* USART0_CTS */ +#define USART0_CTS_PC11 \ + GD32_PINMUX_AF('C', 11, AF5) +#define USART0_CTS_PD8 \ + GD32_PINMUX_AF('D', 8, AF5) + +/* USART0_DE */ +#define USART0_DE_PB15 \ + GD32_PINMUX_AF('B', 15, AF5) +#define USART0_DE_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RTS */ +#define USART0_RTS_PB15 \ + GD32_PINMUX_AF('B', 15, AF5) +#define USART0_RTS_PC10 \ + GD32_PINMUX_AF('C', 10, AF5) + +/* USART0_RX */ +#define USART0_RX_PA4 \ + GD32_PINMUX_AF('A', 4, AF5) +#define USART0_RX_PA11 \ + GD32_PINMUX_AF('A', 11, AF5) +#define USART0_RX_PB14 \ + GD32_PINMUX_AF('B', 14, AF5) + +/* USART0_TX */ +#define USART0_TX_PA3 \ + GD32_PINMUX_AF('A', 3, AF5) +#define USART0_TX_PA10 \ + GD32_PINMUX_AF('A', 10, AF5) +#define USART0_TX_PB13 \ + GD32_PINMUX_AF('B', 13, AF5) + +/* USART1_CK */ +#define USART1_CK_PD5 \ + GD32_PINMUX_AF('D', 5, AF12) + +/* USART1_CTS */ +#define USART1_CTS_PD4 \ + GD32_PINMUX_AF('D', 4, AF5) +#define USART1_CTS_PD10 \ + GD32_PINMUX_AF('D', 10, AF5) +#define USART1_CTS_PE3 \ + GD32_PINMUX_AF('E', 3, AF12) +#define USART1_CTS_PF5 \ + GD32_PINMUX_AF('F', 5, AF5) + +/* USART1_DE */ +#define USART1_DE_PD3 \ + GD32_PINMUX_AF('D', 3, AF5) +#define USART1_DE_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) +#define USART1_DE_PE2 \ + GD32_PINMUX_AF('E', 2, AF5) + +/* USART1_RTS */ +#define USART1_RTS_PD3 \ + GD32_PINMUX_AF('D', 3, AF5) +#define USART1_RTS_PD9 \ + GD32_PINMUX_AF('D', 9, AF5) +#define USART1_RTS_PE2 \ + GD32_PINMUX_AF('E', 2, AF5) + +/* USART1_RX */ +#define USART1_RX_PC3 \ + GD32_PINMUX_AF('C', 3, AF5) +#define USART1_RX_PD0 \ + GD32_PINMUX_AF('D', 0, AF5) +#define USART1_RX_PD8 \ + GD32_PINMUX_AF('D', 8, AF4) + +/* USART1_TX */ +#define USART1_TX_PB15 \ + GD32_PINMUX_AF('B', 15, AF4) +#define USART1_TX_PC2 \ + GD32_PINMUX_AF('C', 2, AF5) +#define USART1_TX_PC12 \ + GD32_PINMUX_AF('C', 12, AF5) + +/* USART2_CK */ +#define USART2_CK_PA7 \ + GD32_PINMUX_AF('A', 7, AF5) + +/* USART2_CTS */ +#define USART2_CTS_PB10 \ + GD32_PINMUX_AF('B', 10, AF5) +#define USART2_CTS_PC1 \ + GD32_PINMUX_AF('C', 1, AF5) +#define USART2_CTS_PC5 \ + GD32_PINMUX_AF('C', 5, AF5) + +/* USART2_DE */ +#define USART2_DE_PC4 \ + GD32_PINMUX_AF('C', 4, AF5) +#define USART2_DE_PE15 \ + GD32_PINMUX_AF('E', 15, AF5) +#define USART2_DE_PF2 \ + GD32_PINMUX_AF('F', 2, AF5) + +/* USART2_RTS */ +#define USART2_RTS_PC4 \ + GD32_PINMUX_AF('C', 4, AF5) +#define USART2_RTS_PE15 \ + GD32_PINMUX_AF('E', 15, AF5) +#define USART2_RTS_PF2 \ + GD32_PINMUX_AF('F', 2, AF5) + +/* USART2_RX */ +#define USART2_RX_PA6 \ + GD32_PINMUX_AF('A', 6, AF5) +#define USART2_RX_PE1 \ + GD32_PINMUX_AF('E', 1, AF5) +#define USART2_RX_PF4 \ + GD32_PINMUX_AF('F', 4, AF5) + +/* USART2_TX */ +#define USART2_TX_PA5 \ + GD32_PINMUX_AF('A', 5, AF5) +#define USART2_TX_PE0 \ + GD32_PINMUX_AF('E', 0, AF5) +#define USART2_TX_PF3 \ + GD32_PINMUX_AF('F', 3, AF5) From 3b9a5a867149fa700d84a7d752fb349d2c25c6ef Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sat, 3 Dec 2022 20:27:38 +0800 Subject: [PATCH 5/8] common_include: add GD32A503 support Update common_include headers (using gd32headers.py) Signed-off-by: YuLong Yao --- common_include/gd32_adc.h | 4 +++- common_include/gd32_bkp.h | 4 +++- common_include/gd32_can.h | 4 +++- common_include/gd32_cmp.h | 4 +++- common_include/gd32_crc.h | 4 +++- common_include/gd32_dac.h | 4 +++- common_include/gd32_dbg.h | 4 +++- common_include/gd32_dma.h | 4 +++- common_include/gd32_exti.h | 4 +++- common_include/gd32_fmc.h | 4 +++- common_include/gd32_fwdgt.h | 4 +++- common_include/gd32_gpio.h | 4 +++- common_include/gd32_i2c.h | 4 +++- common_include/gd32_mfcom.h | 9 +++++++++ common_include/gd32_misc.h | 4 +++- common_include/gd32_pmu.h | 4 +++- common_include/gd32_rcu.h | 4 +++- common_include/gd32_rtc.h | 4 +++- common_include/gd32_spi.h | 4 +++- common_include/gd32_syscfg.h | 4 +++- common_include/gd32_timer.h | 4 +++- common_include/gd32_trigsel.h | 9 +++++++++ common_include/gd32_usart.h | 4 +++- common_include/gd32_wwdgt.h | 4 +++- 24 files changed, 84 insertions(+), 22 deletions(-) create mode 100644 common_include/gd32_mfcom.h create mode 100644 common_include/gd32_trigsel.h diff --git a/common_include/gd32_adc.h b/common_include/gd32_adc.h index 684e80a..43ee038 100644 --- a/common_include/gd32_adc.h +++ b/common_include/gd32_adc.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_bkp.h b/common_include/gd32_bkp.h index b315f15..38aec16 100644 --- a/common_include/gd32_bkp.h +++ b/common_include/gd32_bkp.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_can.h b/common_include/gd32_can.h index 9310901..91d8066 100644 --- a/common_include/gd32_can.h +++ b/common_include/gd32_can.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E50X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E50X) #include #elif defined(CONFIG_SOC_SERIES_GD32F403) #include diff --git a/common_include/gd32_cmp.h b/common_include/gd32_cmp.h index ee45a12..45356e6 100644 --- a/common_include/gd32_cmp.h +++ b/common_include/gd32_cmp.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E50X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E50X) #include #elif defined(CONFIG_SOC_SERIES_GD32F3X0) #include diff --git a/common_include/gd32_crc.h b/common_include/gd32_crc.h index 14ba14f..6b5671d 100644 --- a/common_include/gd32_crc.h +++ b/common_include/gd32_crc.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_dac.h b/common_include/gd32_dac.h index 3b0aa4d..29c8415 100644 --- a/common_include/gd32_dac.h +++ b/common_include/gd32_dac.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_dbg.h b/common_include/gd32_dbg.h index f5ee6ba..c0410e9 100644 --- a/common_include/gd32_dbg.h +++ b/common_include/gd32_dbg.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_dma.h b/common_include/gd32_dma.h index b7d3446..2ad8f6c 100644 --- a/common_include/gd32_dma.h +++ b/common_include/gd32_dma.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_exti.h b/common_include/gd32_exti.h index eed9eb4..dbca3aa 100644 --- a/common_include/gd32_exti.h +++ b/common_include/gd32_exti.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_fmc.h b/common_include/gd32_fmc.h index 46967e3..8794d39 100644 --- a/common_include/gd32_fmc.h +++ b/common_include/gd32_fmc.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_fwdgt.h b/common_include/gd32_fwdgt.h index c1f6558..376e0a4 100644 --- a/common_include/gd32_fwdgt.h +++ b/common_include/gd32_fwdgt.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_gpio.h b/common_include/gd32_gpio.h index 6c4c4f5..585e815 100644 --- a/common_include/gd32_gpio.h +++ b/common_include/gd32_gpio.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_i2c.h b/common_include/gd32_i2c.h index f0884a1..94cbfd9 100644 --- a/common_include/gd32_i2c.h +++ b/common_include/gd32_i2c.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_mfcom.h b/common_include/gd32_mfcom.h new file mode 100644 index 0000000..4c61730 --- /dev/null +++ b/common_include/gd32_mfcom.h @@ -0,0 +1,9 @@ +/* + * NOTE: Autogenerated file using gd32headers.py + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#endif diff --git a/common_include/gd32_misc.h b/common_include/gd32_misc.h index 664b5f6..632b216 100644 --- a/common_include/gd32_misc.h +++ b/common_include/gd32_misc.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_pmu.h b/common_include/gd32_pmu.h index 36c1897..3ee8a92 100644 --- a/common_include/gd32_pmu.h +++ b/common_include/gd32_pmu.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_rcu.h b/common_include/gd32_rcu.h index 0a81344..8f2c83e 100644 --- a/common_include/gd32_rcu.h +++ b/common_include/gd32_rcu.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_rtc.h b/common_include/gd32_rtc.h index 2e17c25..c168203 100644 --- a/common_include/gd32_rtc.h +++ b/common_include/gd32_rtc.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_spi.h b/common_include/gd32_spi.h index 2286fdf..4b7d78e 100644 --- a/common_include/gd32_spi.h +++ b/common_include/gd32_spi.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_syscfg.h b/common_include/gd32_syscfg.h index 4acda46..b2d9f3f 100644 --- a/common_include/gd32_syscfg.h +++ b/common_include/gd32_syscfg.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32F3X0) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32F3X0) #include #elif defined(CONFIG_SOC_SERIES_GD32F4XX) #include diff --git a/common_include/gd32_timer.h b/common_include/gd32_timer.h index 6964588..3ff90ac 100644 --- a/common_include/gd32_timer.h +++ b/common_include/gd32_timer.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_trigsel.h b/common_include/gd32_trigsel.h new file mode 100644 index 0000000..70a6944 --- /dev/null +++ b/common_include/gd32_trigsel.h @@ -0,0 +1,9 @@ +/* + * NOTE: Autogenerated file using gd32headers.py + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#endif diff --git a/common_include/gd32_usart.h b/common_include/gd32_usart.h index d27da2b..47fc55b 100644 --- a/common_include/gd32_usart.h +++ b/common_include/gd32_usart.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include diff --git a/common_include/gd32_wwdgt.h b/common_include/gd32_wwdgt.h index 7c5bd5f..66164f8 100644 --- a/common_include/gd32_wwdgt.h +++ b/common_include/gd32_wwdgt.h @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_SOC_SERIES_GD32E10X) +#if defined(CONFIG_SOC_SERIES_GD32A50X) +#include +#elif defined(CONFIG_SOC_SERIES_GD32E10X) #include #elif defined(CONFIG_SOC_SERIES_GD32E50X) #include From c8faa498ce0155fe1ff070ceecc3e88ba32b0af5 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Sun, 4 Dec 2022 08:03:58 +0800 Subject: [PATCH 6/8] support: gd32a50x: add device pack for pyocd add device package for pyocd origin: https://www.gd32mcu.com/download/down/document_id/405/path_type/1 Signed-off-by: YuLong Yao --- .../support/GigaDevice.GD32A50x_DFP.1.0.0.pack | Bin 0 -> 469054 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 gd32a50x/support/GigaDevice.GD32A50x_DFP.1.0.0.pack diff --git a/gd32a50x/support/GigaDevice.GD32A50x_DFP.1.0.0.pack b/gd32a50x/support/GigaDevice.GD32A50x_DFP.1.0.0.pack new file mode 100644 index 0000000000000000000000000000000000000000..58f81f643a07ea2f95be36c831e9670c0870f111 GIT binary patch literal 469054 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

lzYTAW)@$_XX1#u4 zU)XKfg2N)aV3}2rB*S~1h0I;7H#?Sn351s}u2rm<8Iv%0z$$vf8F&MK$={|};@LA* zx*g@iYf&P@S`)KXzvuzaHEY)xs%e0EjaA|!)ozGoh_1t8a7qh1wC z7rR|V0a5NaHZ50(9fzytogQ_hXkUb&_UOygwYz(6XIzONxn|_H|LTHc%L6t)Hc#>0Y`JWA%y=$jeyXCY4o6F3MQ-xUvcviN zJU^$)3d6+73m97qS2O6{Y?%y^6a8j^O+W`aSsDFM?UWohY&r+eOriA#)C6zDsm6p$>ls7iiY4_hahn0cNTJu0NvyI1_~`{-D!Vz^&FgdiWkV+9@zCstzuN(iACeMdbR+ zBxi;e$XY;#GmzFr#hgjlU5SVbkV%OzTPt$`5y^;O8X9qpho$N?#uI^84vyPQSwJ^q z{Ht};D0{)0qS3NMwWp|NvZ;ZsVlQ}Ef2R>xE-d5b#jqnWSbyv0E~62+{yVI}TJ5lL zhaK>n=Hr&62Q!YERa~aWjF+;;4OG-)x>yrqC;gP0yYUWYo2Pn>5p9Zyo`h32LFoUE zg;TC8D17dmJJz2A_dF`baFSq)9znip?wVi@@b`lkviPuZz?$Ey?QhrS>tzv|ZSE!u z@i8?kF#bc#29XoWfL>1Rpg@u#zrWa+lCWMKC!|N|hWIB83s-Zi8tOr%FD{ofg{TVu z91j^f(nwpYbcM15K0%+jNA9=Fp43|*ywi=njV6v2c@6_A*l=aC770MNr4C;=0xmii zZc&6hh)C~`%ic}N*7S~z9g$!#e58!sQdUubTi9|uZhY94kMIlUKohI*a%A>T zxPDi`>7;w!9g<%!>+-(n&0ZFdrK8XM1Na&w?&p(!yUM5zVR;lKM}jd-8+pPy_`MIo zjt9XG+BP{k#AFKvB~S-$E&-3ppL^kP()6A?QeD_;u3uSx&9XMSl|5!LtrE5EpQ z0PbCz{Z&o`2rqCbo?^KXHT|CZB zE9~Gsm8Sa|-|tLl4`Y}^l{ujWp(6>UfMj?t4uJLtetWHZ-GN$s(!H>Qfb6ySvDkRx z`(Wwrn;wzxk0dxQd|1r>gN9;_O<;>OO_A`dolg5B5>+d%=D$#*p|?vcIVKoW^biQr z!F16*k`&K4=!~VTWs1gyOR)s=Nl-Qr;>#)oW{{bAhn$&dXC-{5)Fueok=jaBrKf+c znQidMPu|0e*=v_bO_O5dlEJA<3HwXR>SYmeb&Hpa-7A0D1sL%17OhWPzk7!ytl`TA z*5=v7si_L>ss){7S$5PCKcpP>B14BkdJ7Y-V>(1)abT6WW+IkoeTe0w?7YcEDK2+n3!kZWVJ{YGU5gb=t{=P& z!p%@MyJniFWqfSVS`{dw)x+Vp!QQvm9e;|yDwc|-Komz%;;uFDFZ+y7>R=GfBq(^i*?xPmc zBRZed)e`9yS^}SF)72= zUddLHV_Wv){wcHU7#W_3BhFrM)L=uI0h?&7CC7GT-M1u8q8z=YWFHe(KDL)UojN$Q zFe)%k&X7naiH#sCa;muT53)Z8gk%pW&RKBO%) z8Qzo_Vex&I;q)78MVTxMXh7>@2??EC# z&uB%6hJ8v<#Ih*pHHGcwKn!AZyn4cA>=Xb^Gl(b=#~d=+e7}v3{M=>(f={*gU;&_} zV*_{@FMp-k#t2m#kKHmLsS*k2913%x_3w{s>lL#RNhjC&dCOx!b4$M+(zZ>V>+Gm9 zrB!p=rv1GfDvWaLfRutaUItU?%SFnLf-_ScZQW8q_sWY4#Os8LL&TwRD)(`!@#H^) zR271gz+hAr6w0cIRh9W78lpNTs3GH2{V9KvsVi0s>m!*=P^Ty>losrAbX&ZZfv92q zwBR%N+$bI&&;G1kUX~o%x|H9&qx0}kkMH*OGuP3mQx=yFV{gT%yT3!s{M~h^e6d`e zphlxwf-WcgH~@r39%k&NyJgUQ9@edTe0mA2Wn}=bQ4U{;7`%XG$%czoW0+9Lwr$zK z&o!Xfmn8gKlQk|juT7H-0dJorr@b*3&33NyDHv?U;|G8lI-RX(*BnpE2Oa3e?Fecl z&h*S}72|2t$T)!aS#T|Ns-@u~tnZ<0$fw_@b)TVyLgi}KAcd;RHeBs;GKsQminzTg z@=AJVaD#>a#iKF+7mq-Ey;sYxA{&?8hC*KPRe33%4}KC_?eTyex&&Qz3Z=j4`$ReSUPB^Y^Y1u9F~Zw4YuDJIYO-fZ-U(&S^j zsLF2HpG-R>J)e*&BJ-WtKW4}V+{Njd8ZqbELfQ_At5W?4YnPB98~)6a&b$Ff=Aqb&A`%io?4}?RLIIf*gW^AdNokg~#%Pp(uS^YCI{`K08k$r;@! zw8iF((WIhLtUlI}Xw-MgjTi-El$tQ$@^gk$=5z9@nnxSy5(#Myg~>$${U}Fg7K)%N zTQ^fCRDXh3R5(|J8g{+Acl)cIScITE*~rC>Roj)?HJ6$Sx0MacP*>oZ_SZw6HA{!w zj~hnvU6qw?4#i&n^@Zb&>T``!7#szoRgOEyv@CrRdBIYCEJPsYeoG zoz%j>7GrHSRfMh1%EMx86O)b4VIG^lNcyz|iIR&ilLtpdi=E!I0v{GYS$V|E$1ziTX>ZdYsur)`Xb&?txW?aZD|m;HQULAQtK#< zU20g=Ua7z}{-9P#?w@Y(eONr}_uG!6n;OTfc-G0xft^G8n~gC87DB2{;Z`~{;ZimP zl;xYMFyk!cFw`*KNmVv{Vv~iRFe%T(?`7>fn45ur*OQ6QQ#k$cdK^{eYZlDa-@T`3 zrb>&Z-mjXS4{juy{|JRC>nXs{*~#35L1HZ1sV?i?s%IMa=@GQlx%PG6#M(aQ5B5MCb-ue^rE+;--+PRFc_`b_GzQt8rGOy4xmh!Xu&i{YCoruo;DtA;!*>u0W zbKu`>6o&tax6{Tu+hRI!p#WkQ+`IT(hDa3GE&GH^up z?D-@B4MT#cl2h`jLzyIvJQ(H20tj&GJ&4j_G?1o@O6Mm-V1iz$IT@s>E~Sc*!7$!q zk14Z6g*g+0`~j%K!@a+V_A_LZ8IAS!PnF;pCCCLM;UkT>VycZfOb-)Dnt~JNWeUaH z^uU)$R~jW)#=Qf#5#}FAOzI?nF{xH}iP{I}i4YBvi5{VrjfFgxXHepURnm(gR(?&M zeJt_Jh-yuSU&ZXT?a8T|*dkFRQGYobZ$&+xE8yyA)(u$FXGGG=E9nU&pD>%rq{tC+ zK+D2S7-Z41@}6bR=)sdfJ=9H_;|t43`t`|n)3MM6W%ADufDBY1%5oAcgb2+iDd?Es z=)3Eo1uKPA5Rvx~CIn)~Dm0Rzij%+q2qvV%V`}pnl0*uUNB<^O`O9{P1J1#%Cyrtu zZwbkE2E#1`?te!dG0s@L^9~%r9K>E^Yml+8-EpFET5;q!tyt!~UJhDhZ9b(NWTiLx ztZ-ew!;#@(;j!TN^Q6{#Prru6PVmNY(ly9&+d%)iJYhFlTGb3vx6IvSCv5*<5Tswd zR@&rf@(p^I2$?#u>eHbBt{9hW+GOu8aWt=|`c-FJXm-mkXEK=8#_qkV7HqI-FQ2vJ zjvPb_G1Jz}u~jPDssdWB)sDYnw)h<9U|c;{)%E`@NyKsDu*Pm=TmO=!Ts#J9C?t4Q z_XvY->vRls!`NxCZs9*0flH>TG0R7G+z5k3O|eSEpzl&tk%4EM7H6+n+UfX1h)f19 z@VvT@+)?-T?m!I50*}Q{f{x@3+AHmAm_B z)nsr-*m1W6&_vl}t?sUfW3Tn(*XFrKrtsK>9E*z1z-0tR+An;Jhnr; zxpRk=Vtv{yOC_+THN(bSN-u~r$v1w>EW8CVG)^=9cygqH@;IR{CCpl})g65pPs#o< z9?|_=D)Mmj@zPDXHEBIy*TCKeO{Z?cg0=d|*AlTlYc*?j@@P0nZU zCi>eJZ_*C!s9(}YxC8ol!_LVk5x+g+Ulyt=>(y>aAJV(D{UtCZvkI%iY11FJvZf{2 z!sRG_QWt!p{dWC~EsW!$Z%W@Pn19SbfSM>Zo2ZajZmnldBbiA!6BU`fA{D7!288ePM}nl8~^e!jnd zANK1T{*D?Il?30AHPp~+`TqeX{V-vtH&Qy zMrHNF1JfvxNA9Ldz3XA4gmV>T2}37xRUz@WYKo?wMY&9y0@0JbaL~1~*juB}cOSDO zed6;v8U3W$I=0wb=s7fXH)QKNvmW4$4WNw%yRfY$A@(|GkBH}1dC>JEjMMw`y_#N5>tYB${LF7~E6!xVW&8eHjb++g#3TW%pdzG*D?Tv91Ay$PNGZX{EwcPx zZa0s+He=Pyv0A1ABU{(ob}!GaH~-Y=`MlnPdr#6JA1Kg@50Z>tTz+NJcKyCN3X3in z%p8G#TkJASaBHZrfB7WW^Kj~V$w!(F4$_+5Cz3KnwwL29#c#7~?Z2mCDKkI_Ev(2# zpu&CM4~M7^eV>FR6oQ6aMvEKLRmA?#i4obbxv+W;i6yT(Pm2Zc>&6-)7`_%1G+IT) zYM_K&I${z7tl%e^h(JC_qR4qu^AAfgGwBp zArH3a?PU)!;wFh=XxA~K>}OyPz@P7V^l=}{Lkby=q9Gb*E~v{nEXAqjK_==a>H~E% zD$p0C2eY_l%nY@s^`Wwugx&^WsHEk^h=K%1#(@(lDs8h`wgy1I<9g6#E!;{l;Mo-f z=&DU7<^$UFjXome!9a_vq9I5&;(`|(Wxq4Fc#&uQ?c^u}3{SKnHS}Tw2jCxycpIzZ{DTrQML0$SM_D;c%vTFg1^oAo zktygHUV1Dj6TyH50Wfw6HA*&1P>BqhgptGV(yVRWm`Ci)y=!_JP1v4Ak3-)-mfY6r zWV$-YrZwGWcm^`=GvRGz-Y%AjK3j^sbg8E<_AyClW-7iwn?=D3Yv~nh!U7%(i8_OV z&GA?8Wfo)#UF4_E?yOl>CJJNAcLczJU`NR__TL5)qo<`=9%fgwhyci02HY8j&Hy0O zNOJ8)GOV#_G(oj!dwWrCpI(uLGt5a~kOih3yqA@r8`K$fs!?fBtYN};?|D|UoC51q z?NY3vv&$7kFc$A=%BkH`uJ9#u(ZX68^{(DZV;QhQ(b`-c{UXYsX8XB>b|Hn+Q*WSu z9Wi1@O$8X*BmR>uzJQKIgo@UW0f5M?1WQpxqhQZ?yMe%IsD-`rVnC5w0AiH^d}gx| z2e3G~&B9`9pUsx1RcX7A6j$+-4O^`X?+67?ng83kooT zmZE=A`~|%XF%2Kj%Y{oTxy!rm}nH84?(d ziG)vE(s8OZE)0i@saGoU@Uy}a{G;}mN-r%7u=Z0vyO~A3tP_D&Xn-Zxz$K|bC8?k# zzw0aDk`$nl6wne>z>*u_k~E-_G|&=sz?F6I>OWB06*R5Ofc8dQ4r#hHH@085k7Hq7 zcZ{NO&<36rrxJJ~?jnua;2B0_(8muw_@JA$R+jIxr%&LqFjku(t7@|Yzg-9?FUYeY zjFdE4HMqMEd+5{CJpSH$3xtvUS-Oq>vkrawHRjpS{6px(kUb363EQEx+V-)MYmf z(_I7@;&!ipgb9^sXZJl;)2V6&vh_odHC29~O)`UZ+14mtNa5Fub z3ML;0Mhob6Y>K`3xTXz}+k#_GG?yh@Jhln^P99n+R(I6YpPZ#RFuEI0d$6bz`j&H` zk~qL4>7((g+8Us@`}fQm3TZwE>Jk0OxcYjI z3nV$>YS2GlAyWztCw znzu6Kqi5lcHed43h%F$<5!=~#u5-Ug>;wrEzQEfeT68z2v};iJe7nN1FMf5@44G42 z7_?7}htTY2Fsirg(WJCm)i+}_g1@82l7Sizdh_PtxvEZ4dA$(bXeA76$8C`B^6UVM zQRaZpCl!||J&FMfDG-?=S7)w^)8w#JNg{R(&xxjtJP5QglSkL7f$YroZy=pe?%Z3( z@uExihIKU9_D|(_W!+$O4yxXo?qbt-<0kiPsQl8LTJS~Ww`vfrFglb#v+U!kHyp0 zw=x|z3`;r9tCPjrR#!_+He$=0+U44}bj^4QFvBe+ArDozC3@2c7{%vqM-B8$#w0!^ zw^qaRjH)T40d97*qK$T~wb(yR@7WHjAWtJd$FVZuz*H=xSZCqjLicf$-B*kr_9Gwxc<>nnnWQHb>h}=|9@!86k&*x)bc=)JC?ypVYA4<4{{A{_(axJg zaKU_^@Ib>6cqLgtsCLsIK~$_g0@=BSxo;sKc@3;pCl+UxI*7|h+Z=$ms(os&#qIJ6 zFQr2s@qZz-N_1aNI$1gUu}kcCxQb6d@Drbm=$taesQ~xr24VdGbB5`0A!*rj(;tA& zeiF8>F%eXe4&QURwv}e>Xv29T_)%l(Tv-LSeXTOxX2NX)|;S2y>43mm-W%kw;DUR5%vLT>yY!8pymD}$fmuA3AF0)({E}0!>-w>X=n4LNfNTltmBc4 z9`FF}$SiA|yfB2ecE(R4Xye&Ask}SL(v<<)tM9bsM}8RJ9srm<Utg$?B#Ojg!&7 zvu4TC2bY)!4&$vghmO7u3 z==3^!tZ( zX65V9emgU@#2uuOR3yEcPUGEu^?AOIiX}_6#4UQh4|Bh`-jfqp&qv`+nhR3_?$E7))i^?1^idw&cI!EEl z{yW}`FyG~BU^oL@)~obTMIqdugJ#O3Yc^)(F_R0Rcg=}pcrrsS-F>qlU8emF-2uri z#wR%kBil~UiUb2?dJFbMrU2~+WMX|GmTDc&<3(`A&s)buvEK^*)(LjS-_Q_Z)t+U< z!eMcpg8^=2iQCW)AE02gz369%;N)rWofYE>xTu)BjhS2UI(!6!a+$}~-HMKWfR56J z`QY{WW%$hgUQb#XXX|PSx8Bv63QfelyySsM*@b@}EJ?7-GT|T|+?U${uoCdkgQfn< zf;EI`|GLO!Mj3}x5%*lNBoOr-GX}l_4Eq9Ota+>sK!1;WKSHf_UO*6${rdRjjD{4J z=vbZ*YzgX8e|S+__Qjs*#yv`#hm|wb$jeUDR@3HW!-w$}TPx#tF}AmR$h-?DQC_Yu zVgndhgm?CUvk2%MGkyXfEC>t%PNec->F8+;+uK9*{{UnH(y^Lv7-8YT?M7(~*gFHO z1kla_61>BsbD>20L#?ESYBC5~=}?!A9D$K)Vls{i@ZVtnT3#xQ&JfBz_0!)8SLa3< z>O%Vh{AK~3G9_VC6v$d9wQPf2$Qh@@m%V^RJROdx6@vRRR(FgnFLWVtdcw`Z<+bg2 zv;qe{IoK&>`HvUCvtoce;pqTFpR2I@@?iZ)SD%w0yPS9@fI&CFK9NPYq+@3Dbe2Qy@VutJL{Y`~NQ=6M#N71OPtC_NX6dS#V9 z+}sFb9C2K#d>5`^r!V)`GRm|HWo*CS%Hs=?`5vAG5I;GR&=FM$wVuynir}m1L9IEB zD=2{}DNOaXIMo;CX}k&x-i;QaR#RbUN-zqDB;b~q=nQaHcRSu4OJyky5_F@-2-)&< zCGw@7sOFOdt}J-F{D}SCZqxq%X&;Hx zj@^J-LZ^=&4YlFwsVd>*HbX5&uyV)EHOjp>+c4DpN#rgIv~~OV07FvMHBe}?doz9x zJ$n!yL!N;GD~B3`P`B|qc`ev9!`dPdOum5ja>R#pAZqZlF?Az5Aij1xki~3-bY^0Z z)|em!p5Wz(f_H6rct=qX6`5RxjvuoS9!jVrNCigHQ$Y@j2=p7Ue)EPlFnKXtYHTWb zn5qU263-FtQ*lOIjaizPk9?*Fh&k-LAiw zcFQCWrx|PXedG*)U|Jf`R2>jwxeMPsm~yAFAUzQ5FDK1ww;}E^Yjf8+mQs<)9U;t3 z+60Ii^Y#YUR^yAvE4Sd-raW5Ox+7&e1oyKjJm0AkD7#YZC&Gei3+|%10Nd-tE=92G zut(!f`8A~mt6pB!kgpzB=YVIC#rB+jYfZ-?1; zDrZP~At@7C&w_X|UTtNlQQcy;+kZ(p)eAD$#Vmr0sF|egh8omcf*RQEr+2{&O}xeJ z?lM=m>eJ#fn_ldWrVM=A_93;!puOC!5OTe_iZ^_L?WX~+tTGPy2#%gFYLUL?M+aU6 zfG`V-8UcQxP3SOpX3jW!^}~y}@{n{GGG99epwz)i>YS3Bhcj~a_(|N%@9}W!@eD@g z8xf?a+60Juapa^`AMd-H?X_B>Q*AGQcQs{nS-Ri%jY-7GPm<6g1U$CB-In~XGyyj5 z{l%LA@Wz0H`&XILhF28> z8Ou(K^=&ksJFwG&`Yn`?>@}kB$W`E_Ehyb`R(WR2QQvWK2X_R*XH7k_jif;PHY9mw z-jG&kzO^!1uKF&{@2sTcrsHw_3UQRI{`rzJoq-G5>Ujj*7|7;IP%0PAdjv zk}hVPD`5LSnj{*DJZy@9r#2_!$_NQQYOhB*ux0d%p#5F(MB%ddWKOyd7U625F2 zC_dx3VzemBW$(x}P@b=85DTK0hQyeP#wf|Tor2P(O&um<@AgiQ&#ZakO{DT-W_{_@ zr#=}!3eh5ietKh-k7G!6q_Q&6C+$(Dtyeky##zLS)5sU~BuM#@a;u~mI7y9$co=_< zkp;B6Ax&q4Q@JV(PCM_q@8SB(ZTiPL0Jn8365GFG_{)+A?ZloD8B*H;Uc!!`Vo8{W zw2Yo`{zI>tJL1`Z9EgV25ZpGRgVNsRLl*->y9COr#au^(vA^C05f$ZLO<9Uz_ne0z z`FA})ccIrW57E@Fo05iry1-qrKK&lO*nZ!Iu4P}(*<{gfwN|`J^!r0^-I0*_bj9gT z-9g>0K(zLbRx6+=aBZuOPZ;Wvd1cCiz-dmkxOBx3-a&7% zietRXMH#F#rBpltvx2LR&Cyw7zTOPQh;hPtXv^4(XCx)5>ZaR|D9a*V#4D?uVVL)< z?iM!A^U^wr$(CZQHJ{KkDw`A7$huV&x#$x^efp z=PY>U1Nso4Uh@g#E}K9wY3*N{J!J!vH=e@b@CIci!IuW7Lt>|wPhjk?C-R+3Vh%B{ z27{P(FyZ^$hZ)@d$YgCoH7 zuYB$4ppau6d|#8|lzI6;nJa=Kue4~(s_E8u3a3G@jMqF=o7!uF+Kq3E0KG0<$z7rA zAW0ND?NZ5=CT@{Wtdv=kOD@SolDl$d4TU7ba33?0Ij5Jpc)y#^d7OsfIVeLtxF=FZ zXjVDoe2=Hq!`K#*cXtOGPvvOH99NFCLmB5vQ8q(UHltGDpek`F z<=;2P4@!eV)j?5q|9ded453G*=%y>a=MpzegA_v$1#Sjq<(x}u*>0&Q>#;1gYf8!) zBTd1VcPcI^eTjZ6H$L2z3tCiWep9u^QgSu!u++jy|BKMXTDxlQlZMZm^LKJ~Y@!J~ zh%hUQs~>7h$^rpm8X0V(NKb&w%uY!x3ekwKA!+*yk_;k^KURPo7A>gQw2u2m-``O6 z(v@4dZ--KxV-xCtBFI4{;NFQkI1Mv64HcrURmeR>&|Nj){zMHz-wdIbMqHr;Uf#(C zNm^zC0HR5{c(lNEgY4KYKa~KzzblBBK@J@U1XgK=rhHKn#T(KfjA8RXneLDyYO$ zv&uO?5L5dgf(HC$@aWRD%K)#G#1WH2*yuF}&P`s=8Y4j#(YriY0Y}-?UnYIJuaq&V z&cLBE`a<2B2t(C;g8NFt?~;NL=RU!cn2(iIJ;u>sufv1h18(T_&PKWSn<(oxEGZSi zX$>kg3FIlxjk{6e4VQ9a#Es&x{3)e*RTR;zzwV zBvEy|yGm+^thRi-qCIP4@vnhG^M3?Rx-jI>2w0c%RZ9p-zyW}>?;SbHa&Xr~RFX|% zMCBex^>H9v%GcVsilZ&QJJaxRF0er*2#UA@(4?ZeK+&?fQyR)?T|WyY%xZn-Yy+J& zmQYKDY<|H1M5VYIXf!p2 zUk?M(LlF}oog&XLLTAarX-zk1Y5=*PX{No(Ea1z<$EG)*jU_f48_5B!p=1P$I7U7? zBkhxlZn1lS!s;J61f^-{M+af$bFZVs{R@?Q$h+aql=)a8OvFK*qz^A98E`Ch+JD#h zcTXaO?DXVio?CE~9xSy?pFfkgCRB5-z~JEHE?FKN;y?9brhH6SJqT zGUOPjl}xlgK#N==t}ZoGR7R;e#xKD9qA6Qq=Op&$AZ$*IP?^7aLynGxl-nbBvV4w( zYK2fHs5gZDYp^To19KNMTCcE#v?w@U|9QWHJX^V@ddx8 zpxA@QI7C7_48dzg07Z3>dtaF9um@A5bf zdyuEUTw%6$M~bAPuCD$!Yr$9wS*m6NibgwDMj25Ho@TXQjor^(<9y;u-xJE`TICBp z0Ez0A+$G+AO6F``sAGe{!dPGkg12DE4*u^vVw)i+oo`*A0ktm~6`7Xo;`z%9l4qOm zFkbUunaur8`1K1Vqs#BHDvK!@M2wM0s@ zMa!gx3xN70Smg&6eK>s@Fm?YUOkrfaFl7w!omyT{Cs=K)JhpduhBqrH~q6Uy%mu+!rAMlH*o zUj%rc?7-O|ZS?u{b{~G4yQc%zpnLpzzHa)|-C$h@9#GN&B1~eCJ*4hP!`%q*RuQ*G z(DYadSXP}a${Kj|vQyZloi3}()$*WTmft0M4gb}<;vrZl0em@|agP;=uWe?7VUt=& zk_B24&c%bkuY=~~56WY#H3sTzdbO#WM3%Y0 z6G`5K17Loof|zkrD@&E3q5?g_2y%t6T>n9Gyal_&1U(fN#Tdxwb?zk5(w(> zOy=ip**E_RhVBK^%N!j@da1$p+P*`lgG+8495kTtsm&6#smE_M&fnm;HbM;qe>^LT zeO{zu|1LEh`1vk=?3Jk_yYun&&{Wsz$R)h(WT|OPeq+RS{{{R1ggA*tEyDoeU&f#H zf2q#0H8Zxi{nsJWv9x~@LHLy^`3(alSuUJUlBN@#JZMGhsLyFr@h4(;)Dkulk6m)= zzTe8&(9OFt&S@?YJr=%lH#f`6$;rsUt^4zS5!S^G!pA?8-4TQCwzPzN6;-r18nrR3 zjU(g!RCBk^+?d|IPy>X!!)XmMu!R7y#c}$<@ zpIXN(SDuc$jC_VZ)^~m9;~Aj?p5GK{bNA70ucHfoeAgr|(lTE9Z1!>;es-8Fw8w!g zms?jJ2%)eeDX89hCzq?L-_33f5U75eQnSwHu-)XO#>e1alPuQyqmS5sq*4$sXFt~; z6#8& zX(<+L;mg*JqWG0Q8$>w4Pk>~nmOOL7G!9GsRy?eUSTwUIP(ZjG|OStJ86ni4%kQ0w{KspPW^-80JM>3>9-? zVOs%wGvqF?0s;^fFp&EiRwfn|JbyM-U3^$s+xfk)2mK%?0CVJYZk4GZzV9M7#(8@I zn*GBh|DwKLr2nujX8+;T?GBK&oOH=hOl`mUVZE%VcE#_q(7IIzY zcoAb=efEMqL|hJqgZh0Y+W}avGLbHVnOW}mMaYP-eCU`0fB_Yk8|vEkAcukXbw~0i z*5J7~rmN*2aU0$bh8DerIQzP5e_EYxN6U}ZL-Dbn3;_~{n`Pbm#k?dpLJ@wAKi$P{ znDO9q8AzKC?pEBj$kzusKRY@6m}>`R6MB%13M5G{7(CmWyK$CJ>#j9h9X(}j;>J=H z*r&gmfV9EgI){CcV0hyARQs5tc&-A7X3qVge0Ev7kH0*>Ol-A)ZJYd4NIp(-zi8#_ z_fX*D%VQ}#+Fi&xaJh!r)%YC`3)G?A2<$Q^Qvl|;BjZoWdhlFW+|?7a_-uDX{iZ%L z2OEGo1D!BYhDIf==Bu7~2>l(c>Klwq0ojs*q3z(Q*a{yciSjyIxppPURPk>Tj&T*h zX)&iuB$LT$K^ws5GtP*iA;tG|y|4s|9m0BEcEI))TBTrDm+Q;)ur1tpRzF2eNV_HM zZ3G4Hy2p5MoyHK~o7^tmpi>sP@g+yGgs7REZkDdsEk2H%tDi#&n*HO7QPG5#K)nzR zZC!gYG1NDMB7`2( z7&uMQ@m>|D?QzuZc+hX!jtV`3;x(U!?A{m*w8rd;CwW|BH_Bk{{LpU(nnV42g zc?*w0JaXfAR2l=?{jvy`3*~y{A3p4i-} z4@#5G1$j(*3(BUv2~rca(}6{dK%}BKwdifp$w=D2xCePE5FfU8ZBIo(LCW^>vW|IdtppGY=a6m@6Kgw^kG{3n@U`o1KFm93#NErN3BZ${u%W_VZ~Vw zzz{2H9$k8zD#Nr?UF0=1;7{HAS=DF#Nk*4CoY5w?}M*C$_;OeOa=K<8GrD zgQOgE-V%1KJA9LpAlwW*ShS%om_j;SJ91CffMvu_xoUtq6}d(bXucwL z6vY%O^~!@N1@s3Gx{4@*$sUU~8CJWi(q-$JnNw9JQHgFXqf`ipe2v_}bbweL8)1**CnxvdMg4J!+;wh`<-Xu~m ztPr5AIZt^`ohy4ysCmss89Y7_ChazGp>0%+iCu-$P_?^hAGny{Fn9?Dt9Y^Tk1v-R za|N~Do82GIMeZE**e+UpD-c0`>CIDTSXK!?Ua0>AeaRjZyj@Y(h|xrk}lu@(XUGtryeg^>5dnXbQ)KAwph%lzTmYL z==#r^ZTpoA+wa&=`OpTaUBD;mW#6Ck&qr%y1 zHBGdeRHGO?Czt7*Ccll|UZ63Ewj$Q``XUJ%edt=(=uN|I^doPwR+uTS&`@JQ`hpF` zMxY-gr2=#~rb+@uR#h~|!nZ+YD={7PsQX&hShm#DjW4WVGoqp6R4soN3{2v;5y|j> zDMaUdDN2UPNaA|nPn3Pl-O88>U_C~X+4B5nvt_8V4vNr(KPsPQ3dxlvv;~>i{1m=c zGAtu=;wmFa8hkeC#)_dc;!PjBU>h%%_Bp-|x+RsXraxe0J}`>X*GWKlWqn7vrD&JK z?oGeGr~992@WdyEZr+5ptfgifBX}W-1|Bl->dk^5eL!MHQ;ZTRgOF%Rraw(GilT)K zr*{`!4?uyT>3ukg`CPoSa^sp#aj@&k$6fs`!;t9zd=QnX8B9Q#WJDrC9TT-e!Aye~ zDpmV7I-x0EMa^BLj3)PnVyZbll4lKY>;#kk{A5nYNv~~z-qcFaw&vvx=H{@7SUKuc zr-8ycDJH>>qcQ=t7alOd@ykdK4Q%B;ol%2lTN<29_|;pYHc5p?p=>eo=Xyeq=2MV59u;-5ZrT8kFu(p z*bt%rFSGldno9OYky$Rl*c~-(Wx*+*xVD#->SAQO+3M;*bIBC3=I#e*#@0rRw>1 zSD8#DdEKF6UV!%a0tQUwtbow=x`Si7(#U0ZMW3-Ml;%tu*H#jdcCaxACPTw6GTK=} zKe6O#<85@Ek0f%r9VfJy=fLwSoD;0cLzWz$HPI{S-2dA)7yD4Ff=Kp93Svb1xgVys z_4ytqk%$zRoX}fMrgOK*+5VeD=|scf&lz|6^AVbl+02={rTpD7cq;FQN?+Ce8uGh> zCYT3&UnoHgp`&-DO}mb7sI6&Zb94N* z4(+fH8O~sN!&pG=Vusjz@tNrx>-U8c6o`df>0pWnNJ%i)mKa(nph^q@u-~Zh?G7jM z`c^Wa3QkVc**Vvh`s5rAVXNX4nW?wgpKkbAlj|cJRppU!YCjW zNjE<{W1eZA_{wJKeq5PJ+k4y92F!0yIk()p3XT7E>2C*sF3|w@-1vA4L(h+}L?6n!gT%6!u&*oHVFDmNmQ5EQtAG~#!5lb>D znt`;$P9Iu-&B^pvg=;+sss z#OR1tF?7hWg77(`Lhbp}I&;Qaovd{Pj59jn)y3$UfdEmPAh>nvgB=?{dFD3J@(d*c z?M8wR=shXlD}B;~WUd|R@Y26wlTwaz7*ruGGTVD&4ai?;LgtRuGGoh4H%H{J^hc(k z2T8nZJabWnEPz^!*) z_C9zHFj+HT-}U>}=`d;x1Ash!53d)?aR!geaBow|cCS$00GRp;7Z1vg?^ktc1K4kY z7C20~2rb1OSPyQ$@#$B|zcUC!lLVN{=?H?ZLjI+%q#z=qsrsu5#R#)QFGd63t6KJr=_Ux?$tJ84Y zyo9-g+p{d>e7I&zS98`b10-=Jb3#l;UxH&fbT#UBvH=R4Au)6G{$LXa3d8)3u^{#N zr(BK1gK?J%>3Q%ct>Jm0OnEysO1%cW9Uo?k(3+pvg4JFO4R(~CP5%8qF30~#luiy} z=(mIb00_qUFZJxUmVf@qc~&$p?Ed8h{KgG)!w?jpgs^}^pim?p*=R+P!0|z$5==?5 z-9-M=@+>Ji@^CYE@g<&8Bnu-5UR}?6@9A)NUET7x|M^1OKid(J;pEMZ#di7Y_>#nq z{7}v$WgeEWkL-Pp*$Q_gk^OZ3TH_3tXN(A@P`7#oU)2&8V}%)Ooni&*CojU%bx#bJ z#1J^-T2xE;e4`EjD(Uq%KxlsG!<0mB4v8Y>l|%*;Zlq%G^vq~@;FOsWD(Jx|nIIf7 znhLXJWQ<6Th*5{c#2-J}5b+NJ;P3&FkSZ2tWPcppgukXvD0D(L;Nbk7Lqb0dPE-WO z2Z%!GR@?Y0XPg<4C(LrNSOc`q*7EsvKf!1nd=IbbSY(m zL*izzr*X30Fr*02gD8RFkD+_4vIjvRgW%c}2f2}e!b=7b2_fq8@d0XAyc^5QNVGU= ziH3d~m}c5wqGr&pQTzv8kdtDRYF$%<>kc62S31de-!%%rRhn6Fxu$*d$ zUPylsqa3l5h}z6xa1az05J4k{cmt$d`T6hxNx|V%;r4TfFxKaCr3l{5HWb{v|W}ao5c@X>?`h+MMrD| zup28j>m3oV+`%(sJv(sJ23tBBMvvf{0LO4!bFVQ&7mS$xU8il4p9Wa4fA59B+Bqg% zB&S)11vBgLG%8{(Ft6E#_`9k#rtT1D!l*M$nY;~d@sdHlW^6&1?o42SHLOe)V8`m{ z?BYr^p0zr{@;Nbez45ABKi^{KPE2p%PgQO!23BQDXLS3xa&SxfZ8B-GXX>pX$ik={ z<~86Ftfzs!hP}U7PO`E}R*#b+1bIQtOSABET{9L2NDmU$WbCb0byy?{?3V3D>_IzR zknobtl>gQ=7n`#ge^9OERC)&+HE~!GB5NQKL?{gCz4lZKEEFEr4a1ZZc&y>;+x*`( z44h_V;gi|erAEJl{h7HbSFcJp#%;U3Mt&;s8-p z{u)S^03p$G5CkMQy{rzQXBu9h;ZVe#px->)O*+Bf3hUi?t;oyA zyWZ^^NdLpJ*IV}@U7hhO%D zs=02&4oA@rH|+`4VBLuyifD&dP!EOvIrr?Kotm>l{b}V>yW}q`2?gu`=2UFqbDBQHhOrTAKKArJ!GHP{R)0uCFC0({eNzg-(4=(%Xjl zOYo()9)h4*>J(PfhWYX}-BC8)TA0P2>FlR?lP>=OVZYMMS#E$@&PHvpU_#`3UHTrv z&8iMYjoz(4Z#?6=-J`3GyMy)jP|q#MmXx(V8TeG08XT0g6>n+MNv5YYaqxjhk9#O6 zcOMpye#bo|?44=UyReIKE@$*o9XPSQtV`XP9QUh)fI>^YG1)@nQ}^9u%0pUC+Ps$c zb?Q6EIQ)E)zKHGFczb5lm?Waj1phBNo>Uc5eKX$98@KKZpVq>zD?~~dV>f_T`3A|0 zt(JFDDv6bl`Q@1Tng+HU*|`OBY)TLur$kVn`>^7}qe=IwT%D-<!d&+n-}VHf#CZwN`EZ^m7b-vJ-pn`w`^nA!xjXtDYBPikT_P zxYDdED$4B@kg{Bl9l^P#u4q`E*HH(aq1McH(ZO??=nl^(VI9-K8MQ?Io_l)Z{bfn0 z+8J;m(}8=WcXFMCfeO!}V4ALL%OcLjQft|ceq0$$BJn?>l3h`UEw70lHOTOLqweo) zM%0RUdMD%K@aL$TqVIrvMKkPOGP|Ev#;V+*JPu|#wHEykuv1*NG#Q2}%Nw%|S}^KT z>#H>@x^ANG=7wV5{FJhl;F?x{)pUOsGGT%)OtsRpd}bz5cVwd;=TMA>{Yp{pj46G$ zl%o09$rALV`T8xe4&^`4BVLH6i@O(|gODukRO#qeQQjDKvulvC^*?%_pKqnNoN04B z#NXGqVJM7LHAo(h4D_}*d_RH1zvTT0|4cDz?qIH!ntncFKbmD7>>KF9r`}0_!MmE( zI!Nb~Ey3d@;h^}u3%OO(z0}P-PqEizIo$H^40!%EP%n)9Li_!K`(MVgCjAfdUryn; z{|iVGp!_d2$PTtH{|F1#*T4Dq_czind^uSd=5QYGL*k3gEgKN6EhZML%vxSC&|MXL!_PIBs{_ehmbS(XLCbFd6S1nL4>8SyDWMbBq2&r9>9kxjer0}72xlOUq;M=S&;lgB~11tH~)Qw{|KWpNl5fGZf_ z6e#`4Wk~ddIS**?gR@WuDDI8;U>WG1d#c{YqEC;41Rv%rH4M%`E9FEt#zdX4H!y*9nyh-c!mhrrCiJ3%u+Tv zGwJ3I)w%yB9HxShKP+ysfJ>ofO(=zU1*@Q*IGzkqmx)Fd51u6G+*o)`Mrxixl=UQ_ z7_I^+wTd`i@*EOZbJ&{>7EBu!^k!{_r#QdVnIoS9>IS41ETx9bNd`Z}cAt0NVVQDaTxZSr>)w9UZaxIr*XAgq>QEUdId%Q!00 zSXMc>N!BX6oQV}bDZmUWEJk({1Ti%@@$JnYynV_W245h&qVPz-Gzx1}qfN!u8DLbt zpEqxt(%wQn|Q@lAM1;BJtHe1gol% zpM1NlZ|+BTihMY>?>U&XMf%!W=;E~}7hi1+EcrvE#xzp4(!KNP*t|GXb_g=(6T9zw ztN=X3#wHcYdDn{S`Sh8bf1DBP%4zl&9^ggm*!R3V);lK8BWFp+A8S#TLTJ23Yq{OI)7X{$RE?&=>2H9Y*N%EQIsU<81JVKco57r1d19xc9@q zZ5NUI+tSzd@cz*Bcwl+^_{2b%9HPT6LKfi}BsLSwdpU^zz}*+H%pOKQL7&0vYQ(IQ zt3e7a1PX0YC` zN=hsqx`|zXHbexC6V%ZclTuajFc9qp&e};rSXXke`K9gs=Oar{vW$iXRZm1u=~Hdu zOpQ2H^25>>%00~{1fAZ*OPVVl+?YSU74J8DE1s?TRR_3fM^e4Ar28F}=wKTPWE~yS zO`?S5R-{OkD#_+Q!?dlaV0AReJw1}mTcQQJnc5YigT8zT_Z*^%t4}FrCpUrET{-zV z_j?p_)wqU{8xH@!Mi*t+5JbumY>o161SJ(KH_{cD>HPMKBlotW6|IV;gs|Ku1N{E1 z-dsPpqr(D=4IvWo@5X{cE;Ev4y^;rcjpe@4mz&E!KZcijlrlS?WIwG8E_E2CIcyQR zKLO%*3z@i~#S9=Ff9}@qz{$ibY2j1&cCYur+kZ0V4n8fp>2ya*IB!w6a~-84^cQvZjlIeY$zCUnIUE;X0n4p`yS?D%#T3OTFE{GAOZ$JY$T? z909J_XtqxMm2?C6y)gR5n9b<8pK2WtYKIggFjs_f`E5<`$mH{CvBmh(23lViQTwZpQWNrKW)oW~~DIxE6sw^L#R#{7KHB9YSzH;892q=NVY&V&XK>`ZeA zY{7)Y_os!XbC++>Y1T)4^JSge*_c*A{gwE~eOCBC-hX7}7Re$D27A(E#ob5N_SPMX zZQCs}SaFo=gQv!Bc$UO8?Ae1L{%S#MH+5K0X>iFV`cWZ)rZ)10nWXgCVR1Y}XFHzL z0hyC>hCOn~&T^PGY`DVwOHyXr#J_7jxGHk(^6>|5zjlq8O(M_fGWDX?wswN@zP|!j z;nPsTPsO6%j-<4}g<}oz*4$vT2KKpO#>Le+uau;;ym2P=hR(MIF9oahqvY{SIGW2q zATYmDc^@e7x6tBX58x^q0DLC&=-oW9A6(!>@_-=hPG z=1Ka|AGF^Qs^H}f$+P)-+RJrpm5csphYX>A7N6qo?3w8OP={iH-XV`hs1#`I;uhatVp&a?=|mBe-EwwbQkE$0qT!EKTH))F|rOHW18*k;{w(~*6NJ< zyiWv%$d2aU$AdKoN7fS=V-qQ;k=7c>M8WEN$ZR zxy*hV8Pkg#m>tHEhs<-!$2eE1a0`Oi=8|DL=F;$^tiM#!43T@QqV{9>b|24TwQCGd zyBMh%YDYR;q&l3n){Ah)q(A*SQZ^4#Vk=35uOLBZZCG{SWpParT-Xauk$nH38ty-H zWT4#AOt_c;07r%YWew+K{GS?5_sWS%6yeuC<&MEB1+-IaT_k4M0+9gH3^`tUSt*Lh zgs}<)AvJq=Yw8`1FGqiF`t~|!L*S5hnbXkC{4?t|_cnK<q_^}yWoXyJw}b|zi?HngLPvaXDc7q9*5iOk*m515*_-SjpPi{CGR>FU;8$b`l&}b zOYl8obH^{M_WBL?Rs-@E-6p90HGQu$pF-cixB&`TGx%t;Z|ro`(UCZ#2IRAEL!CZn z(Kf3s_BjhSo;_F{0G4v%+WGCJ7DJ-D53LYT8@ez5jmMkay^B@o@*)ImDvg-OmQHp(Mu=HEF zW9-sexT-yNTQdcKy~{iotl2ujto4?weS16{jTi{(qtxOwXP(U9H#}*Bq+Z7L{AS94 zHyOF@ovq5+Yw%cW%{Yp|ckY_Ccfg1TE@$j!D%s|+ zT_kq91v07~H`>n|ZY@_Dkw8J;3>o9F44OPmSj#CAk;`+$YRnM|+m9Osz4qssG}?B` zSuYA7RFAr0Q+wG+EZQDK@iXGbFIS!}A&aSl|AlK=Bep1vEPv*Va-K_|?))mYtzEx( z!MZM5t#mYY#mt&Et)AmCRIQvqUAbX{MV_lx9IxpEgDtP{_QOJ5ut_=^bgZ2_f8OXd zxhMwT>kBdOH$rW4tvOr)>2G6c<MUa=ZxSWbXYGg~x-MI~Qi?01e4C<{yml;)i!dE9*>r%_$*uC3t$dOS zT&p)8=t{QC{nwQp1|y~nHxcb!U$CZGVHW)zB?pGqzG_T7!mt(r=>b=s>q{~(%E zl*gG>RZKw~(qHIGh|YD z5Ix*Bkf41(tTt{`+~hSKyuhQF-GwHl#LPE-CyY&QxOX@202GNZ?xO@*{XF@$v2)b9 z&Iy^`JQYq-kOWn_cyHT27vkJ{M)x3Et$dtqx|YU9QSJg#tZg`ykCQq~c7Hd~&1(>JGml{0eyCcwZg8W%d9i(2B+%?(tm?S*9 zHA%g{5VxRgc7zw0ZFDmv3nHu<=Hh#8P!TjukjQf{#FYM~odM<{cD8p%pU)`b7u1bk zFk$;-JcVSE4uOI)V<#9&=OSXZOC&NikXLW>5BD}(ngIUI=Ll?(yj^gR%84!EZ4f^X zNGyo4!*HRnGpm~)(j`LWt%?MHy>WQp_3=c&TASqBG{RYqB`!8ojtzT+kv(tBmPfm7%I5KQMQ2qrIQ)hcI=h7$%D>T3 z`JyF2?3|X77xoq_Zs={`ZQ*T_%+EHBRPM2f1-LmQ;OLx|)3+yDb%<^r7|O3H?Bc6q zouiKNSBn^qOKvAr)$q|MMyd)O@b-d^+iwYm3f;~6(eK0br&!(ao0|J<0h0>duklaI z+}FS3tgE}BrbhCvb#m~W4&ugJ1c}Lga))3<6evZE0-`YrVV^NAvSH||)C5ZvyWEzq zAMWGs06(Smlo+XF7qAzl3A`Xp=mV}v<82w^2`hQH5*5uK6$_%@P>TX+XoF$hZ#4*z z2^t(qDRSA%T{?Rdbds1NU5U861D2y4v{bgMI1u|53k7wKQQlW4=Y~iq8i`8K;vtf| zZ5%5^L;i(p+}EVw8#3zvKMO=9hRGDpgqLdxK$IAw-3!ElA}XNPL^gUpLj)ZpJ_y7$ zS~|6W0u`68y89oq4%anXAb@d#_O?6{6Fh#u!=3J#WD_Cbb@!vgV;9UPp@FEzCd=ha z=5Mq}M@G>bK9JJ%29KoGzv~zxHdsVCCUk~lgN#-;a1RrEO_GO@xAK-@>U#~f8NfYz zKRmqSB%!0}5j!-TmeeToqHA7QbEr&%Nw{=9;J+l|;5_jLbiWx^#!U@p>Bf z=I$5;1gGcZ$$n1+)XYig{&2v%ybwJp>qK^@M<}toH zdlfx>;}}Z+85SZ|r-3dE8(OevZ7($yyp=%<$l$}L10Ke3s zEv4}R;}w6e$ipwr8MuX?0vp;K z;|;pOuKq3<;M*Q*i@<&Y-u6*obFpQ)eI;qGPHAsaJ`A0OGu+(K>g=0RTKv%kDDLPc znKMPdDPo$k#CWQ55{jULIhiXW}HsXhB z$ipuDHbg1?T_52`Xpa9s(Y}z$cr!!8iN2>&4H| z@&mjwJi#q~2jSsw0yfcq7L7l~MW?{3c^CMnr@w}^5Ae)O{L?SLhNlnk=P*}1YrU%i zF(m^|jFlvaJWblmv;6=)qB_lVSg0yR2BY9Q(qXgbdKcGm{3C6AxcWq2V|mejS4j`M zac^?(5PB8RK0zlx&DD69g}%=yp4o%ZmW<~nOv8!4-R+I+KAGw$&gmV{le!9;g+ZFn3E3qeL!%ksu6=_2 z`#PgWpng)fM(>J36G!6l5?I^o+Ut~f)sUn@4X{%P>Im85sOK%d8N0%&-HMHelh9m; z5gJKXW4Lt`!5Dut)Gh8Y>ATVqazW1P0tWq5Mb9ABDF{iQ-3N`!=7wEP!?}(KZ%U*v zh;n4yDT=oJ%yEPtdc(xG%pX*m=f}x0QMS$YN5(AQb+M#$=oR!xC8Op_;s-qTi2ky= zxwVat~{4;Tx|{D!dS#2^OgH85*~bznm^M&4}>t0&SlD{#hVf= zh-^DlRkw3vgLq$bG8!BF3kKE(u2$u`TBe$I!$+*z*Om$GySkveN=@KCa%+a{ z_Rf1b?JBCXOk}@Y&jRn4PMJyQ)sRlxOi{B+i8}436FFWYxvFMjD~)7pAXFGAyhQ5T z4Y6XsUfwU=<_gvXb+YgniQc3o{fo~`z3eU5Rp?%2tC64>?hvc%~=`T z#BUCt?;2XT62+%qV}sQ-Iy)O1@GB79G)^FJ(AzF}BJh69?k7)+Y5!YkervgfPb!A_ zPyqNu@Bq4p10fYsfpCP16!`lxZ;YG-V|`%6J-;l*BsFEI@e6hBj?RTQpi^N;A6Zl4 zYh*3_5QiZauae4+OIjRzq=6<5OWO{cb2mGp7+vK3E zL#}p`S!C`V$v4py9DQNm)&OK|Y{}QXoJKR^cMV@UlK8OtJy|QHS<=KNeJuaw0=Hxs_JfEeGY&FGyJ6FVAP_^>gUiF)h&&Etj?5fd^t@@5%OO_e9s?1hqg5bZ*kZkk zDMt6PmOAf#H!|ey2VFj}Umf#WK7YO9!NZ^&2{mY8W%@ijCG>9sN^M%!{Z%S{+$Vi&VFoFgCqMXX zi*jJ=biVqpMZj9#e6(MHIhENarCXab2sN}|Yo=Ahz%M5r_;?yzaMTf-lU$drmP2EB}H)JgImYz8wENY?vqnNm1p;$0K;SofU! zQ(4xW$?!t+KvWJMIpn9Q;uuT&ra{X?KnHsqPp1js(Pi>+mNgtsVtud~_AiYUWDhp= zyYRNC%OkT^nwv>m}J}$`LQ!{*r*UE9~9||a$ z8%rk}W{1}nEBu}p^}qDo)d%WAswGVqpSu+7tHzm9nC?AWV>ZH7Ya+ zAt(`vg8J5#8@;|Hsn<&lpGOe%)K2fsqg9aOpX9bSd$<`bum=8a84-VzN z$zs;}b9mQZ*1s%=)tO+8-2^b?;NoE#!MkN6w*sC%`=9&pRzyU0Hj13EXh#2*1TeSka)Q^^9hB?pJy@CqAA z7ENVsl;TAcUz^b##j3p7Qc(@!wP0(hf7e(lh9x z|3sqquLCk0gpp&zfWu5ub4knUW_~Lvh_S(y02cvO#u@82HP~UncM7rF6Fc4`t^NCdkru+p=xjwr$&1mu=g&ZFkwWZM(}hZ=KP9 zr{5qmpPc3-BKEs;EpV!&J28Y$0RlhLtk9!kGgT#nC@C3cOKAExiD*WRcfuh$>K zZ@=K5kJlfEpVlA*j#UKl-G6%-29iUjbVha%E)ka&W}%^JU&MCy>8xkTs+fpIK`A)2 zElN_DQ0{vXEH6i7W;;72YPE| z;E@V;`I8}-G-1&#nQB?mgYjD!p82{6ZCn&?C5Ya*p9^$v4~Pp94CJwRGu5x(Q$XyB z9{xBuny@@{D#+#29g@G)&1$>_@m2MiDVIyXjQUhAIj0ke6Cx-F4$%e{R@6<1MkVR9*sij*tBymCL1)$s}J@tg$Qi(oeftWl7vW@j1M?6Y2pdURg%72-X z%pls4-#3bk!lfDURA~H7SE4Q6(@Y{~=9fQa`o1A!`a{O>$C8m$Ew6&_jAn!@-a^-?1g5M@*AsC<{ByP8@SfEl)L2@t}@B6h_^>V>64iLr;54}(@l zBTni4w8*DzA2_M z+d}1794lp`pqy@zRf#M{;dJeSKc=4-l{=1kr0n1%A@p74lBWnUD?`khFA6a$*NE@( z2RT|JFXtbFk&kWeaQM@@hZeD3Cyf~G&Wl0w2x5D8SZleM7}D@q*;*?Ww&+nDb(}zC zwOf(dZ0izj)AU$YV4U6JG=ciZ!x2RmK&B1>bP6;6Rqo)K>jj`#%oE@4cEtT;R~=0HA29%DU- z0%#W%V>$mx#|(g1lJJ*@KQ=hZ`LJ_b4IF*eGZ&xd{Us&OgH}Glp$PpwX&0ZH(^2_; zX4t(=`5t(wo%)WM$JUoUSajC94aPt0yl*LVntNpe5Am9M!#$q#RN2>KU76KNoi&5n zBSL^l#^7d^U2}3QJc`|uanL1vHUiWj>>T!<&#umsG46UQF?#s{h@IW44`{PQEx}eb z-C1jcpuZ)YY_pQunpw^w2#5HJIb3@6X|B<@A=s_?RfntjE6QEyMvZA*5C1P4DdWiK zz;>x@l3#%9@5Goh3!S%HZ3x|;xd)AIq0|Np&0?J$7`o{p%c)fB3pT(!M3&ToR6&mb z>x$HuEf|nH;h}vC_1lx;jVM3T3)Mp^5`sKJah_gicr@M0esm%_i7!%a=yCo)F{zB# z>L?f_^5ZFhv?MK8Ltk1^L~Cw8!q4m!bE!I3?G@3n8ua9v#K8q9fs6)T2uY2c#9|;9 ztZf-mF0;;N5?B|%l!cH|12JE&Zy^}O49C&ubOGd1lV^JP;N2i~4*70Rh&Q3lswAZL zNC9P+<%;~A-dL{UQbRydave9<{nUNOyfvY5mLDS>!8K?x8ZxNX%n~b+wiqL@WWtbG(wnVeh1V~#6vMxqG&muiNac- zhPGDHT1e&I_3NCqmWB=^ctt~gv%hpP&CT#IbzKVyd$HT@5_IpzofNn=V)FF9j1lI>G-XsAs9-nBAIGCKLGd35+Zx7H|ETztrgJkf^t5wVrCFV%u z69-u7`~Wt}g?=YfT7fao6H9jt5#@Yd@;c}NBIryy29d(LS7#PkVmEeiWlz|}7s16_@My2Z%x_S_(&wqO)Gt@kF z>&}eju3PX26Se_#+(=zOl!mH77`TvUQ}Kx2lt>2k0+b|+PsF0o8EQErEmFf%PzgnF zS!Vq&SrYkMn;0+Qx{^ikjtl`qGhI@;SU&`mp$b*S#2Cvy3e&G20#h6X|5V6covt8D9Y(v;dTsr|P7%7C^V)7Z9^!Ky2mU3vb% zcGP~XUh6u;^dk6oi!2vYx>KCw1mR+-@#VB>?xu6DVXEAUyWlCybJgDBz+_L$(^kV- z*9H56Am}ake$i9I4X4S5x!q#{0QcIm;sm>0kvMOa9#lGSr4EU()TqN0Q@bxT-CTL; zY5_JifM8F1e(qWn~Jvxbc?~Nmoe5o(ZOWEn%N(;g>u`wSZb>& zBVM0ASIp1ln3-tB9$4?4s=nH@y22{>`!iAO^(F-vGk8F3EZca^xxrSc3x1msfIC<+ z*ixm|;O(f$YdmurAgb$u%zRfD2^#^E8OsSH-0W3WQex6BWR?k7(4~Cr4U826)D_mwk4OBa zxo;&#BO-&Nbp3cS$wXfxUF|vCW3%!8| zBGmDVl>M-Mq9l7RLBCbvoj&M@J_<(|wVxi2*M&*>@v2sA_c%-v+BXk{T`iuaPn|R@ z+VpgN7)iUb=t?_Fr8)gu4EUqn(Do77bDcGkl2(T3E?HTMCw8WDv>yG3B8gIdt}jc0 zXkj;3(;hWubdcJP7}L`|FOVX0kx1r`z)8lkuqA@_a@PY<3a5bIV!c)d4A9<^y(Ex2LflA**p3UPDP z97mh}*?`nRu|!^-a`@3H=<16y(~eAryeQeBPm?G(LQF$dlK1NooA8#lVOhK`z@~eNgiyJX-Td>_d_cc>S#Tblkax_Lwd;+G? zuk`$-D(Y)C0g zE^TOE?*bi>#7LMB`fweu70Ly;V@IEVSr6*W z&$grA}s-QbTB-WU!@;o{wuCX94;NGL7$N+_WxU`|7*4CUt!)mBLe_joBxjs zwUfQYZzDqILV5F7E%8g%h5uDc1Sx~p@)xAV;ZLt`2E5^&fqvXNGt_K}kY{$b;|yuQ5~^5ZnB-_z=yHN~5k z4G&k02jKU;9>rU{hbr3L)4ld&Pvnl`iKWOiWzK@iEk z9iwUWJOwGV+pZZ#;eR|c##I+_nAoTNArL8Vi?e#qpARsZFT2CNj|=!8Geo%I(R5}j zLknV#EYB~rq1M{(EVzJ|n0mL<&GeS6t5N7R$dd+b$7{5klp-<61W>TB1os!A#??tV zuYqodHxA;=eA*2sbg)@)+=jB!ad%xn$ryYQlJAMVk?jva;YAC8l)z!N#6XUIn?pxq zX7SM(tw1FOtfOoiQSzT+!Zk-Af<~o57L+KVh1sq{Z^KriCRc#y3=bv-eMfM$1a+gw zm^RP^;WSZMb^}1ja2P@qL$PTaYVRUB1Fersrv=!JAJZE0q z%_-v$lp_NPot+LP=d_6VP*y$(vJ2m;i24r!{MZ>Q%S16hmcG@*TZkZ?*tx)p^8z;9 z-r3w-@?r#IAo#2&mjWN~^RH)ORm7Kj#YC5!IEEt4SQU_?Z`D&+IN^y+G1SL}Ng?!~ z4G@9}2UB>Z4i%U)vzUzub`qee5QM$ikm@g#^UHif7D6=mAJ0lGj6p*`t+3J*)T@4WJ|lCI!)b!izB#0IzOpQDgW zplY(07`70Tn+i_@!FWX*VV+g^ z77nhj2r_*jLM`FE?DJ3~8JLXhI5A*Ld)<}Vi;SQsFlp)tO^M{gD;K!Y)PU_K@phN-kGLj0<+&J??@?VR{wl z9aG*m+0kSQvtsr(pk%=<511B(bQAy?+11`~m|kr1XnI_?4h`W~?@&pqaYeUT^TVlJ z?%Ej42@vTRmIt7z!U=A{sN2=4kB7f6Zt>@?T(qe{@dok<&J7LT(1jeZ%5o3|qi;c= z1n)Qtdu>jt}DN`TnW>)jUOL;J@AjPk0dm30M{(Q>??fVByf(b z@=DJ1Xw^5`;RpkQkjC@^{pAh1xbgHD`UcKLom z&vq9e7TfF(MQ|ov_eD1cQ<%#T-airUkPI`HfDxSIm(2fmASXhB1Gr4}ai8?Feub;r z%0d;!1(Yr!I39EhWIAvUIwXR0h)I(XQen;W%ndpiN!fty(~;g_6Dbh*M=D22xG5&q zy<;jdkH?z3TG5#l#}RC$ zgd+PPnz^7GiLmh7*)01GGj8DJ%fZD;0pWYM&CSJ&$_l z_@nc9tQS!;{HFNTOx1J1lCR6!wS>6M*@e1x3KFWQNGA(t7s0v$Tza&0v_B{#Nca~d zG}$Gw@|MEOVv0oN;6u{o25{y9PXGCM`2bWM4zQtp5s`+*i^h>tavZs;ou2VqrPEKYz(lq%)xa6Z`C0Za@khUH6x+cfzfy*jTn^+ z->qa15FtSoOCYRs2D zM-9A{N_5m&hBCd>+w=^?GqwbnAW zOH}s71|y0CoZ&}U4Q5ALVLbyq7Iy?8nxNN-u>*N|Bin5ZffjWYRm_X%FDSMPv>7Ui zqjKU9hMDrc7=!>UivW|LrKepsm&%4s+OArKNneC+5eD~gnAlRx3$%rL%yjd3w5OL?O3$@)oN zDDVKjIqG@D#*Nn1$~W9ot7#ZCpU5Y-|rcC;(7aHMEP#tazQe`m}1%6hjN)A-seL)OlqS z&-*2(C2soPP-%$u-J+BTR^~6F_(cG?a;Spk#8D1ZNr$KfAtWmU<4FX=gQUWN6~hMy zslo?^6~l|9Am$O@S{AZ*BQqNxY)TmODS;^8*>$7$Q30tGzA{rCmF4iQ% z;)cL5j@C`$LDo^Ap3b<(*3XQXCmwH|o8j_?xamIr?n7X?w%?)&lu#%x*Z>4jLpD>~ zdD=!*{y~+IO-%-|OjBvur+xF7(0)z79SoKs&fXS$PA0SY+?#&0MY#cc?}643PRQLL zvJF0=$oT2V-QHlZcXh-jC*^=68&bWBu_%k8OGzvKDA6forlvm-B9y$ovi zbIlu0S=GP9|B#OBe%oj|FwcBCwpo`dvggUIHMF(y6t1?f&QU|7hE!np>BuyiBl0Vq zy~mO-Ey|t8IF9W%#$Jo+o9Sc26Gb;HA)@(6!yBfTgWyHI%*$~bbCTMY8cE24=!mbc zlsf*m98o~b}@z>pBnjdJdF{{+Iuk&FC%$Gs3RTc5A9 zCc?x++h2~{)4CtIf*2E(Gbl0?ovy#{94Vtx$A=EW5s0pknC?L9MCmn=-3-%IsyR}m z>^-@2+=Y4_09(s7E*oDg&(zykI=h*>OSsp<5AxtE%H<5eAx_a$b`gSFN^S5Eathb za^CuBbj71SJs?RUBrA&sJ-Db$l#s6ijsykDlz>%$)Xz5P z>p~H!%eTRQD>-Q@V0Bq@4OkZ)cxVvR0K8IlSzg zBCy*;1p?%R5}@8~*GD|o+}JV&Pi-4H9N1*&jC+U_pFi=n|78!aodUD@2ndg!RW~SZy)yRVHH*hcI{o;>>vN(tl0T7dsRzeT9hZ0aWq!{P=#iUZw3 zgHl<_UfEdZ)H~AkS&7e*Au^*BVz1%SPOd8~qY&LbZ)pXQSNe9j3XW6A+$Q^*f2xR) z>me3VsJSZ6!5UbklvIz5r#)A(=q|L<&kYTHC1q~FU$Zk%B!_Cp#}TFa7x!M|U&>+W z^AMzWq+Hv2!L;&vpq{N$O-MuoM2665@*`|Hg*BMQ`Hy-vKp{^b1gGCvrXU9p44qee z52268_}eycnaF}eOH&8q^CC`J;dS3s^o@+-^SA}sWb_3<6~(D4Fv9Lp;bT3gKD z7Y13R*RnQ~_$|$O)L|Zqf(L2=fZV%iHyccbzv!qCg@19{M(Vbimp0wlcI;JXe8Xx>vw!}8q3~kM&>^!q#A|zd1 z=>!KkLk1_`CPy>cXQs)$J+yvI{}f0xQZj=F(k!p)sT=uSXBaOly2P&6H+T6=qW?S6 z+u|5q=tvP2cvO*9;L{v48jHJW`qWxr44o`K+9)BiEA&P&usx=ONal9JemjLCyMrDh zcx@^%dUw>6v9jI3$D8C6N953}(D$}cDS-$2!O3J6gcY>Bq>(<2j&R>#&-y!l@33~e zU&uDLI^Vp#wPC7d&Z4PNiLL1#HE!_7yD!X zQ>r~jt84)0QyCeNi&MJuU#BdLz&@NAm`lf1i7Ct%`Ke($&tWRN_`Jj|Fq5Y6I6`Wf z^nlRPJBjYv#|e!kt=TT0sRB#aIhw4lDzs7HA+PYp)bvtcNjX8DvEGrk=F&^i8hvq#VK?4Z0h11?-vlA9Vx% ze-$9`RlR{+@PDF#SkZP8OSvB}L~n~b@2dR%6bq)*-%9vNb>sVuDY_I8{@B>;!`r_V z>dzD<;HvD3IUG^)tnjno(HX-(fX{2`sO(Z#GH+dB2`vgm8HKAs$KA=HTuGX)gR(Rp!B zk!#XsS9Ciqa-?*6*Vs4a9)fjt>xAH!^E5YYoFRl4kqV1Mt6 zsJ?Y_b!Gi7ME+SXKSg(SYJ?GIXC`c0Dr_t~5TNWw>`+a9+%X}|LV&EX{(d?B@$s|+7H76}`Y91RoIY!p%pI&X;SUguDIA=saA*BUFD5PXGI+}B9)w z{A~;Y5tJ^{phXF-s9@bzaA*w6{{9Dr7W6VBRn2;;760}`zr}PzpsR)!k4e9$c(=f8 zVc~Dt!|Z}_js2uFr7v$<=k2rTlIbvMZj|x}8EUDA9kO_Xp&c{tY+=r{AHe_RcmECA zehyVecVGbkWW)gg82=Y9yOW2Lv8maA5#E{YAsfOsKEX|2i+}-rQ$*ah=@knoil*Gs zdnL&Yn>loUf`xWDEoNf2?A+lxxA1wBw}fjZkPYlm!r1<(U8u05gkq2T!|)ko!0art zmE4^XSM93U4Yhpe%VkE=Sv%$te;Zm(Ux@2p$t!Ip*BbHj++2`$`zy^@S<4iyE1Qz{ z7CpqV(Q}VuoNsv=w>ys`B_;II+;?(`XpRwSn(}>_i&c5$84ihNNb*6BM+my_y$_W9Ox9ssANP2K)J(uP?*yFy?`hx} z-pt^_Ay8JM-)rUrEvMhcv=m;l(X0QA3zR?>1)B(HGB9orlNS%TqaF(b>5j&>Ybk7+ zk-;O@AAzz&9nK0kGTv8M#hmCZ0abTv+!a#=L_Rq!6rrV>AU&H42B3Gws-|;3FhZ=! z(F|n{-}5f{8*|y3*b>~y;8Ad)oE{-q#u1|X>yk9vdrP$q=kow)#}Tjvz}RBXX1t!h z6y%AP?<8iP+AFLHu{+N%T38aY@I6JQ1G?}Op8~p{X;MG;N4fVuF>OoTRW3fft%YXrmkAR-HK$F5}&`p zOlc{6scT?cB1;S?KaXU&45z|`Sr*h!f}~neVyPge(rpLLq~fY$%2fAEVE(HQ+T^Lkwq&Ck3TH!au$SpxA~6EGPS603jSB zp{=Lh33M%KQk9cmnF@p@hE;8cKAuC_xD{JO^(mh`YT318G`4DZS4=RuigbR*VqQ~7 z0xcIpuRmEt?gMbLP`3w8F^9r}qqu0OgahwbxJeOwlQ+OLpcGn1YqakL|4CSl)T6~{qRYtAZtN_2<(2rF ztd@GUY89$q%d@=s$$X^AVCXxzk1zg!8q1i)I1UU$SWXs;P9)SPe}Uow{( zsZh=q=}@lf=wQAIZC`$D2lZNo!T!~=bJcp}-_I2WA1zeE2ZQutAI=C10!wLqr%u6s zSKhlSSD*2I)k1cWb*b{#gc9tP{<2|{bBPb-$i8hhl%xS?2ldE4c+r+zky@fKeRTy^ z7PYg1WZbB#1dL^+y9FvHAxi|T2>}+?v=UnsKD>Iq99M!EV0ppkG-|0K*hdFS0b>o6 zBAy{c08x!Bfab!EU-OwBL`Wd3REd!9gERvwfHQtzk^q(3*SVT;KPir}G}Y#fR3?z~ zj$LnxReb~rsQ-A%z#7If4)3I?SV}l3Nr|=FyIB-tU}Jj0&w3HFXeEMGx1GnN7nj1P zp~(RCNKmDSx)>NXRW+CIEw$cRrx!E0aJKr<*@6=!$)gLJAsldcl`odpFO)tLqjxGH z#-Ty{-_j$aQl92Xv;ho{6CW||SjeydGsuU>ksL6KT13H9SS1N|d7tuGgbuP|8zM;o z>6lRGmI)JMFD+KU0cD7L1!wx6stX21cNr3$iz4Qo*=LX8F4Bi>y&Xh^!sNu8$5Xd} z(3xwpCng0h>zTvM#AQ$_L)&0*HJoTtFktP;~T)H`hMYf&{HaBl;araFFPYlbb>@-631gp zoTUb+1}jclM?Mv`c5U93)I7~IBSyf=*Z@Firgl}dlU7;F{~v9CdD zz?y%r<+OiEFNZl&TW_Bi0irb&5N}(q&^8DYRl4?{_D#k0j)DQg7{Sg3lG~6!_H2=N zYdE7Kad`v)eFmj4#Hr@irWJSIbuHFFe&M99VpIrQpS$HhDn)^J(9P$VQ_-YgR>kLkoUQUbDFd(-hu>3*JIpHu(?RpUE%tBbq?8Sbg7ZoOtPIGcvCFyD^AMF zg{+jIY#lwZ?xLt>tD_kINbF#%ytGN z%VI(tG8e6!Tbs)HAR1y1j{@$Pl6sNT4vQ3LSm=9?b+r9DP1`A%WEf4A$H$8`E4?UMr& zs@U31(2e?H-Ij-BN{GTrHKc34eIfA2pJgKLFg zqqmyE+3ND`gc*8)4!jLJ%B@TCym-iSGk>Sm>HJ+2Gcv1XFzp%P=RxUAzNX?O?tuBt z=mLSI6?G)@_7oD#cpC=2XGkb4?HLIjHV3_2%M*Y>iL@)@pod**N_zd#L2LTwYv8p8!{)w zDR*=5P_)rmqNs(#~V+yy%w-r@1p#*0&X$-$@0#{MiJiv{~>^BlbGc?1#~lL zlGA_B^?@}EQVbMtcs#Rd)gza1X(rj5&UcZap5wPjkkkhr99}X7R)@!>U_9(_tOdcX6Kysm79mzX)JD9+pw9E zlpC+-Njm)3G23lV;BF|{Ws-ybIN5ylA@xFmpgIV<>=6__j~uR{_NlW3nDk>`xA9bNF$J>n94SLg){-^m%f88ne8vP)VexCtgTXAe03t>Vhj}^0nIV zYuGk3{f`14`Imw>_{WwHN0GRz%vcp@+Drv7`c8o$hYE`ER9I$Lbi1?MNI+fJM?dlU z^AY2c)owM^yXYo(_C2QYgWC;;Oc46y6zZckcJ49<+{ZeE=T_Dq08C+$ns^XxtH;+^U^8HRy7nlqxKSa8eE)!yhhb23dFB|ub%0IpEy&%Q zDYBgu@K{Y7Wj}#*w;1lUgG!bvj;`o0ui;nLH+}3PPnfZ$)CJ8su|4YHa#@@I zC099ijq~{ryVGjy)@B;{O=Lnvp4?R=XUw>EJ86MYU;E9o)*b$TtxV3)WfcyUqrz8a z0DuWHAOME{<*?{%Ve`k4&iGQ-!|qT7<;Sn&3l8j869Z5$i!PyATz%Mr*dCswi;zDi zyR|~(AQjs%`P)x+^01DJ!`vK4o0sZzxyso6g=KS(Jik83^SOV^1m)$~eU^m5*`k;3 z=d$k3xPDJ;{^A|e{<8PD0fQ&m?&4WR#r*8q~WWNDKAS-EnD z|K3`}u{)k!?Kk4z1(aY<_ZyLj>kjGNw)wpHf@9nRgSP2?V&R`_x%dL>C}dvs-Lu^x z1XJ4#eeUe-Tm%67(z|inuaKcD^x`xxL-O6db+dgK)0p!tZ^HM>fDtyaeyY*f|ZiU!N0r%cF zrW@GyZ1)H2&txAMJh*9*019m13I0#2Y_W>RL=kUM&{*sOKK6JrkZ4qW#G zFm1aBG(YX?(S2sVLo$fbYIHb!peac z6ZW?gx3j4G9g%J$lNINS<62KowyDbSuW=l14ex2+dcVn*4{Hw0{!o|=xTo*yC#Ft7 z6~E;(d{O-s$A*2i%SVwO`W%4o7M@H;%i>%Ia25NNGk6*-EJ9Piec@Bb*EL9{Y$&Wq zii_7b%_X=wI@T-b1=P27@A-2_5gVkdy5jm;9Ce8)=DDxOu*nLCTKH7w-H z8JF5$Sl<%hL^p5&`HM($NxYgF9c)izJEl#yhp>S$zOZC_SMhjxedHldI3TaMoegKGNQ7GUv z@|Sn+T$#>cLCOf+ZGqx?Wrb)w(^B7RPP216M05p0?h&~WB5 zSs^zO+XW+%!qYeUdM;h)uLAxQRS5^*mtL%u8HgX&25C7%?z7wEa}6sA6O$n0jL^0Q zgehO>nP1IV0i4y15G#nJG2DG(s%5!|x_o0sA>hCDd$)s!y%`cQZ2L$6LBvS-?%gzb zxdA76hJB4btHTm{H{IHP_APD@%=BG9hT(dx*m3V#B;+L}b>m;k7`JfS^w=Eap--Pt z_J9H2XE`HXFZ6=$4MT0UOUz=)&CeMw3I~Nnm@Y0xolUQP0DS4aV%xj&Nw@vy`(9HjU*Mk85(C|bbAW3-Q8h;;w_nKqj^{w-^ zO?`BtSv)=;T}_$_+hw!-x2;Ow zm{`l26~C=zWas{K_Mc1LJ@hoiDhEzss2%?$;GqK@#AKNq8^``Y-yUkYD?ZA|;zC zAiZFQ`7(FhLWQ+WUP8TG`L4K303_ zKb;SyHZ*(*xO*44NWw&TC(BwQs|71E=SN10Gkm?0?AuTS72_*y zIQ~-O??C-SVLDT-bSzioy3aOXBqS|44NyDrPub>#$dK8%qNhd+RV#S^wQjmSv6O=8MT#4Xpz`5n)IRtGopdfm-k`niM`fQwE@Cl`aeb0#|zqG^H+ z-4jz15?sGtE12N0E>ZcdYXLz%559#PsiixlX?xWplh zDDHR*NWuas(DOJwv@#qUo>@6qkIu>PUA^?6Q4{w>d$UP0>P%KJFufUwe^#oh9ZkRp z4Uh3hnRfh;QWo1Ma0*0F%|^cQ(yGq|OVQ%`RXTg~LUfX!F$(dIRVxbB;=g#nx(WC! z=U~<(DTi+xK;4Y0D4T1^P3ht8m+9*lUF8-M&B?t_%Jnc-;!KS@*{$77gZ8t~pa!$? zgM%@EOrFhWZj=-d_BN2Yv19o5P~7d@=JWM!#`#HDh=cS_4+r4vW7&=e1Fe-T3t+WL z^!1`tZY;1uxv~}^tS+TetoCKIj&Sxu*l>2gu8oa|E7ra0rFV%XLa`6t@s_^TETC z?bW%Q;T~`(#cmo>m}!O$m^qVAY%W>WDA^ct?ZUBm>-kd0R#4_h7=f!s9_a`F)%e_U z@;{kvN0Wt~Sj1Uv#E0~0J2jn0WQ`%61f&asiT+9IVCO7;ft!*0_>+&4fJ{y!E0+!I z-pkjFY_GV*7jEU2Vw1F|h;R}mcQFG`WN2fnw>{&q@$cUFG-HUK^n%}E12$>bz!~&M zcR#E!xHI6Z6$xzB4yl1h=X7rp+5kZW`%dbDh*A-c`JKDZIwOH*PpW+L^q4 zb{y60rzw!m8sp*RILs5=-H6HtvS=2U{#zfk#&MZE%O%kgd77!lqhcyh zu>5TC5pG(gLS;~sSk{(3myWc?{CR^xl9Otb3*wId@|6|NP|~y{ds?FFFWmg$={YsO zAfHduV_TDkLebTv`inAvlx)3|7xuC+DavI=(sXTLGq;v0JSJUEgg&G}V(SY1M3_da7Syr{F{Y^gxP( z7fmsJIqgBEi4YAJ%&zf(K&QZ)>#}lhHM10@YvHJ1 zDZ~MsEA}P2i-F9R1I|Y8Wh~#lBL|b80BepVw(S)Fq>&XeRwKzgk2Cz;BXq|n@AMv` zZh#!~gwZrQElG&MXb47>AkJbmfpk*P9g&Pd+mk(gzzJal%nSt#XpG$f!9DWOS(1M* zh&|+z$@jkE^Oz!!dplyx<0*|C1sPRroRsM?@%KETlVf%$8c6)Ze3>uBGp=|lYL+Y` z9pE~>tk=O9J--4mV-ou8fw9KhB`r)nvh_}O#7Us4Q8(C($uEmXm5-W^!>g1*kr2h# zr(o8Mj)~XuEtX7WTvTmVy)&7FCRJzNYw3a!kC1lQFw(-~(Zob9*_+E1U$aQUgbe|1 zTi30q6|x9TcGBD#;$a&uPysf)z z=%KFE;-(t(WQZUfnXH(yWS}Hr#!w*vV!MQnASg?P6c82+6`oI~8qs&PB}6qxCMA|L zrn=~+^hIFBliZG%gSWA_hgfT^->O7dF6vI&tY( z@|-n+It_P#Y zA=IYY%s7BhibB}vzD!5slU5h+xC&*p^97cwzqfUDea*YnwQ_j{(t_tgcga{+`(vD& zLk8j-75QliFGN%UnY*+}ed=tT;GcH_MMBLlnNiFp6am-ptR5+6fZK?`)q^aStnCle zKBbHBhkJ8jbbCOx#YXmm1_OrwM({oCaST;#S-+7tw{^7ZZ}95yoRiflFaG;p-k4?u zw+tZ*R7+aIhfLoKFOO=Bh|r6SK)z6<<(|~=Gz9D6-qI8V>%-jA-doYqrZy1b zFg7D0q;uH?Q`e#@`3*u7V7fJz27afH(ZuJqB50Lbanq)yVIw z2Wm$#jsF(w$=@x|b+{c}yud;_g(Y~Ic?1e9@KSRql<7zmX)-~RMOd^zvt*S!T+J=` zKipE>0{eQF+=@nFs;-U7TbN(lk%h~hXOy8Rt$Zd3&Dw z-%m_CgB(QFjc&XW0vw zt?OOVq)(RCt-V<>p|^Cv)^z+Au)E@;Kw{Ky%CW&ji zWPeUB;+fah{g|-zbW9`$R8nan4+YLhxuSJVi^xydspQgL<%dS{od(LssDWW=2iF#E z+u9xaY{3lF!QwOYsJ(&pUL)3ViK#NRh`%OKy?cpZQ#J|FL$UFZfB(;wN3czXkZu|X zwQr!zT^LptE0q%JXx?ARUbvjv=Y*smC-0e(dS6WoS8_rur5fX}i&3sp^$0fVcTK!F4r2Srnci}-| z^KW(vX(_Y!UU2?w%~ZAL!b8fjB^Q0EE95+$+7}Tw*Le=;@()KHe=w-J)&oFm92>q# zbDnsWO6q|2U8cY(@~vFgY<_-HuZE`#oLu?l*?RG#U`T`n!Y5rIT3eT-$o?V1Y4_cmd zwKEF2F`HOC2xd4%5Dx~QqBdq@6Jf4+5-~0f!aSI!JuqaKeP&BTsVngnP-$|%A=D88 zvQs=r4Kp9guIA{6>bxGTETQ+@?8kg>`Y)gv%w>PaS5qA|pS^l{OP-VO6Cuedi9vvj5sV|>p~QnacTGCwH~MH}5;c4>FC}Vu*ASW+HT`@l3f1sXOcE?Iqs=8CfI|V6>}|0))d9o^=@As%hcqu` zIf<}^z$rO=W@0K#&&=(aVJSem+mI#rL?u(M{uyyrg6*+CsT@fSsz^4drolAK6uKW3 z`L-LSSL(??X@6*H`Bf>}=uVP&FU1Z8oL+$=7fB)qt)BvcHaQKPp1ihaCd0~}b-6f= zVt6beA&%{KMjsiX0z>t_P>SgaYKZgz1{rV}t8c0bVkAf2jHG6Qhce##D7%Y5dHENxj-$MofYyV_4Nykt+?#%8V=* zMRhqLv7$>V$}knZBsSr~Os3NJqWWTTlgI|D_kAcasES4R`)Darr(A-dJCNTcM$_>( zwpkee;3|6m#B%?fF(iXiT>1g8eHPmhuM=6tFIN)q&-3`n{6X9NmD zE-v+|xFQ|ONPT#gv?-dyI-EZ?0bwvUnUfxfm=1-f)ex*|Ra%R*o5ixUCJ{cy86*Z-GmL_L@g1=e%Fe(+=bD=->5v0eTenk zt42}l_r(TqlNFc@^@n+7MjvG~QF?mm<|VVh3i^49lk&z%OmE0!2zAr#`X%!UlJ1Ft z^y82Uv*smcD~+gVx*#McK(N__)Tt@Xb_bzvgXgQ4^c5&jX;gFw6u1;{ zCU?bU7|~=(Qxp%AImH%fm`{Wjm_mX_!0;(WFkqe)$q}lwFQtm3pl3#?jKs!l2t!IU zwb63JYR3q_j07%sL?y*kEYS;d)Myo^Z8f~QB2)$w(n^b^SjBF2Ql)RjBG=@Dl4{|~ zBG>kbkZ$jL`n`w4WRm{&I`1tzmW)d%?3_HVKOVGWJ#9fR6E~Wjw`;&q1hjIISyfXMK z*jFowu%Lze%ldcw-qc_Y_hL+k-qd7{_^AkZgpBjiv^i6JIr@-sa3hW6vSVS;uF>{v zab8FT4huND)fM=0aC|6yY=7Q?McCn4#;2m<_LJg@!XJ-WN}PiT5EdlVog$&_xO==D zL;L^WyqRp5UiVeTw&0uysy^C^~h2JtA{%QonOLY zznke*J{It~UV@-@IbY84M(?!VO6}PnU>4gi`*w;>$7Lx*_gAS3b8tG%244z3pIXZkg^P%5de3OUBHSm9CYotPTC{YwVZ0`WS>xu&iZc8 z@V7mCb?quye;7Mf%wv@L(NYPxF0QJzOhZIjXRGxtxi&*15>2K(O3=)#*j5lfVe_mb=!93=Jr9-x~Xa z%e^5x7+HOJbjyqZ$O}04@$EOTeGo69RyMaGs|nou$^F5`b;|z8)i>NNL@6&CLHJ#y zKMaVQXgjGa%vGq&K)9wLF$Q2$n8OpxkXZdqV6am7#Y}@~tLhk#7oiFH0vHCwl>wvb zkEw=j)dKim30QoMx)J*?6wqrr#qNQfQ6)f;p4;+$VGuYK;RIJvE%A(JW0}yzc+P}H zNEvK=N4zws0mAH;@d0xVXhbnZs%XR|$~56?4@y!6_9PRc#rBvck;qFdXvs`vZHSHL zl1-MP1Xkd4cwp0GxEf-`bEDYDboIKA2XH1R^;NhX-9AEY zrgIny**a^kg9_vf>=LBns;HBQJJ6uW!VZN6fV&)cR-vDvhT$rEc(=_)?aD9962zlq>Z4Tlqsvfh%dsCnqk$jvl8n~$<+n7dkL7xFnkGx= z4!YVv0|(xrF(ICq;N(kfE)Rdamc$Obd!9%=iV0B&fByU(&19KqGY zlI_Xeq1Tq-Ui(LZUdu}MTF~3w(5gJz>CtPLw!m2jeS`!&VGvf2kGT7~OOo(e06qkg z^6Q))ejA4H9FTfh0!o#B&ZYlz#L0)3$?aFCi;OVJxX8tLOnAP09NnSJeXDFc)BJGX zupHo#{1$fj_)h!i8adV?Yl|ywIjGV)DxSmkmdg>zNv$|y+AJC|%b&V(n zp~uZA4p;QbXJwJH0o}4I-zpt_jPzLfTQ)QE#!9q)oLG@tHLh`Cpo0ee_Ua4>p6YdI zW^!WP|77K41Cxv{08Y0wM2TJelBgKV5Rfm2J^KbWk5Tyx%chA-#%~X^z6_>tXNGM~ zMv+>Y2=lUWvPJFQRKdhhzZu+y8x=j4OCGX|AEJsMs-%v&B~Vc$P?giD>eHyGaMTrW ziK!j2G!^#OA}=ts6Bf@Rp~BRZN8ci|!PJ#G1`4@C)r0YkN_df;L-{jhPALW_=}smb zX}sG{Gkred?6tVW<$1~$FTgga)nr+Wu_39krX=pCl%&;%4$X1kJc|oRknwMn;6;{D zaVMF;j{VTPNq8_CW|Q${v(Xe{u9-4Jp|?#zDx|shHP&@AM$yDcT;XXektv03niQ9e zP;2tbOL1ESxexIyEhH%z$4GH&%{$jxbAM0TnC}gm*?%z(3Y? z7oq^D%|x+c9MLIWGJAm4RSm_Ll%AC2)LU{^iXK`$hHIPxkPKh5+2cAqb}X?H%+iHH zgewFP77^o99_F@m9i#u#7hML4z58VxPI3d7l!P()qoS<A&!}`{R@#EU( zTnNm)W9*h?Q&X{=Sw&ryE9*&VN#WHdQxNj(x*Kfj8UjtKT+>5tDXRWK9i}>7oM?6J(7%(> zKK&OV$L$8Ooi!nOHo61Wbe}28yq4^<+8<*@(9DIharyUW?K->5#>?ZU>ON^jWoAMk z;w^_qdR+|@TOpjeRt|Z+ok$4kJM1Q)eD4*A%KGKm|3zhe`7uT1C{yEQrwtBz{|&RQj_7OM!g(ALZX!r_ z4cRIME+gtW5{q_ciqZu->tdSCG>sfk_N^KWoE9Jpkgx-eeJpUbuGT3~8?e9ofWP}_ zy(?Uzu)phZjM+VNac)F8C;eLz_)&Vj+zXLCryj_?aZ1Ml3>{y{DH{!2-o}kkw9CV@ zz1X1DwZT~LiIvida5J61J8&XpCyN7Vaj$q;UY*Kd$z^RQpt?;B$3A;SW1pXUq^R@Zp}^uQe(hP5H!vZ1ihpipYog6BmW z&7*&W%KTtya0E=OH(5So8hG+zgNoJkJwJ%7Y3T)x|QPrfi z4LHQs_vq=!n+`l%_S$wNKJgHDTnf1yY6pOfettf9Eo7FUTi2_{BRFeqXPb)`zFfx! zM4=+V#qc${k|d>?>|n={5jgVH%LzxvoF=?wG}KKN{u$lA3v%y|2#*ua9Y_b7f>HT5 z==NnC&|5-!0nW<;g&7MgfjuP%6=As&@Yc5b%}C?aU^SSaU=_W2GjM7Bc+V!ChWQ;3 zhcK8U+p-p47q;Mrr2xRcachg8m5ut@ez{AV6<%$6R^?Gaa-bQozriE#3X%UR3ane6 zl|1NDV=ZjNZ-e%}WuR>z)t;Ebwx9aT0#CLMEUml8{={x&Giz6UaAULG_*epblpo4w z@f@M0!NM%eQdNJsg5-Arh{!w1rQ(9!UXq<~)6CCecY!dHB~29b(bhP^o_tG169A8@ z;RCK6xzc-2b2wRKvC3>)br(C2q>QHM>A2~%-caA(dMyvrCpNky;bASW$|V;9@!(C zosq+es)gZ?k`^sbUU6KLGa7pwwLeO^02*~K-OAhN%={ukm1QU_N_5-nQ1NU6dL-2i23}~ z6eI{%VuD@j!}ToZz@q#%qPKI=DVg)Gxrpw_%v}wRC7kvVpR^iE2)~hoENQk2Th8<} z$nWr73wG{f)!0-e(A5iRR3)sG_al$+%iD~a@5HEY`5q_bL}?JyMa9}g(~yYopK;w( zdWx}=StFUpv)hKrb>wT=)QuBY`?6{|`JlpVFBDmI0QqF!yCW90)LF+Gw)J*78Mts- zLwmvl;c&rx{*DyW&K65t0EB1re#5k=)a8y3lrU+OnVLLxVO-XJwbfk8-xD6*e>J2E zv$Y4%Wkc{NnkRX>EpgE+S*d1_h=+)ZIbKOCsXaS5O0CWHhgsEY7;$FqpnpEHuBN=6 z#sc|g(TJJS_Xb4P@~7+XTVr$5;Fkev;TV704?iPNIfb+=&94OGc3m(ikt4_=C~^=8AzBA9D@bf&y* zKbM?y5-?(iEsGX(pV{?@W;5;eDc7~qhLTH?f)5%|fKAe9{Nw9Yo7-f^zKg2go917k zqK`3WV9Eu7juR7fAT|M7cL1&7^|cCe__XSudHL!^3N_$_x{1;aPZhGjD>OZ`Avfo8 zwFHDxjA{MUcj$LE$;+RWamtE6OzE!oBE<$C?^!a3>d1>6@_bMTJtb~OZNic-y7X)i zK4$#0dOs z$IKE4D~yg?ya6bPq(1p};pm2invC_=VV@JhHSPQj@kguA3*h_1+U5!lVEEkWCiVP4 zElX6^P=WUTZZVkP?NUOya98P#yJ-f_q(=DX1188R7xcO?hoG~wPj1I1>u%eK%VtX+ z(iK1!-O5p*D&5PU+Kk^oTr-=%2e*Z^bM--0ioGZ_VW1eIq;Lbj?=+r@nF7-cn%Y9l zRfRO?~n; zCHAG(1s-00ym#>S*v8jkqp&kwa{&Db|FQ0xCtpo#iig=Bf9C1Ik|VZ9d#nTP6ZY&? zC$@m8JGp-@mRmMJL7Gp}$ir(VpFA#mMFW`~<H^K74NpwMVp0$hR^K64zU-SR zPBR*S^NCA+4&qm&s$u-AbAo2=kjuR(?N%!62Ip~8Y`gb&LN~R93i;op7D0t+lFfAT z)ePZkjw*N^i(Z~C$MiH{fz>4VgUw%#WR-exG@AgDAP z>OHFJ`hi<&`mw+kNkJ;UEUFpKnfCS?P}F#07vFB4j!4<%%V=$F4z*O?nuvTp0fmZ1 zDU17~I1&R3J9mrpkcjtg1!a?uisIx6epj%&R7u9Rs=SNKSYmdE{qG(E+se??VIYS% z4{^CkSGq=xM%scu^KOaTcG9lV#AAG5vW?)ZW4aeV{e0mOq=*$LLU51cqfB}6HE7<44}}8)bS`x znW6j~m#576do3wkn^K`GDdT2iCO;@#g(G{ejhCY7U*KV*x#-y44zadrr4IL+JScH1 z)3|?`c^7*2BcU$vC7>vKQoEtvr2f(zL)pNcWFqGy!G_Yxyb~!YkuE(`5V?OSsWqd( zFp~@|54Y%V{WN&z*a8h5sY`(A2M;fA*Faes?^io{7g6*x&W309%z2{B9{YKwi7Kmx zz50^5Y#p0jEl>Q~`u zj(5=BvvH5NV}W19`Upxh}rfp*_d*teARnOpHnVUTfoyY1HI%fBw#; zl55SfIAml`e~LppgF*Ev-aHY*LN#u11@vCL(Mwj`5h@EGA8{2$nd_%b9cm6ruvCyM zyYtUEGI{aOY3_xw@lk=E-ilwAFRknzFDt=+USDAxIH9Wk8;1_xF-*?<`mj{IwM#JTejuyVbOdOef*qX+v zkqAQBy+Ws}295ELgKqA>=5jbs1qr^{J%rMfqi^)3;U~*BXefvQwB+%Jwi+^xMIG8) zwAs6qz+NG0;)S@LSyJAEKV(wg(-oDD&m~mYR*gNlGeXv%7X7WV;>QOp~<;F zhp1$Cg|gwXv$OPe-9!=Wt!q4WX_JoTe_n1*di+Ruq|H=duW6?^h>sOjxF7gez2nm| zH)V|)e7VoEB=}x#dc5^%wLV94rv_91YTFKrZ8vR&HJ`lAP1&Q*;@k=`KkoGDxb*2f z52{27sD?izap_RcZ)sBMsW#2y}v%_zD zggs4~12H0+fP*-`rO(`m;F-(deCVeS_8ZlZ9>0nlV0og5gu2PDoMcbA$)0eNFVatN zQgF}BjC0J4W6X>bagp1(!O3E$+SxeC-f)w@<|JLBALAtBnx7uwoF2iP9wFusZ{!f) z%^=#$Aoe%~-{KVLB|FKx=I0P|%pk&?LZmujbQ{D)T{tXFE`Qyp5KuQ2B^A+cA1Lm_ zPCAG5?zJZhqQSDZ$v>Kx4+x?r$k#1n`2@<`m34q-w`YwuB@j2Z!Q~|{0alfrS`;Vf-@w%E2++Su&MVi}bRvE!lCe+uwd^E%H;sz?11>+p&cW$P*o5-C zgJfx+S&%M0Eaj&k<<{_J@KoZFBF>TS{+IdytS@{rXvs*wqh&hr4U?*FKsmh%R{@D9 zrqs3A0qpnzUlvL{gK{Oa}aqzqwS8r3$44$xv9vV(9SYsupK?TgK)F5V+>V zo7}g-qhQNqtq2_Uq<)A2{7LQVS_ykVqp7%nkyIQX2tyEW1?OlF>fKB`rk#eN7Eun(tVta)-wBvpjPV$hgq44VvD;D8|mf+=h;7`BB6PP_fsVNZ}Q z4jA2)5htLbEl_m#QVrhxHzIw>{3cyA-U=qojP=~2L5WjlFTD+a|3-lRw|0gjeAR%`W6Y249HsO5UBxWJ7 zdbY7hpE0o|Fd4Q2DZ_fWr$OIL9*-B3+}|cY$w!AGvSy`}r6iHdx{nTUHcUtak775gUcimze1M zu(G^@ag710L(9mDhE~6W)-L#;HKW$HyHNuMjaX#=^!_&jyNw4jUzn91EwTXs_Vjv_ zD@HzjhxX|FO83(o{PuY>gFd3#hB#j)BY(tygC+xL`$KsjMrr_-R}Z8Hmlf!=UnKWr zS1eF`Z^#_trnW$S!h9!>cfZWj3b^WY-rU28rPW(^{r55vpfjV zTEN|)3EfdJnwyE5qO9RHp4^b5lOgCN6&F^;<(}A~WYVVc&iiD#N1c!Ee<04&OP*(4 zO_#?<053gy$}>_SwnD%|OGdL~rv~0Zpg{IZ<++%Ak)r5~rx-RU;8eX$Z+Z4r=Bna7 z`a$S`IgwOp2ZoF?esP5x{{cqI>aTJfBkK;slTsaN3#WQ@!5|~ux}%9>Qa|3 zZHeL@EuFslNq7`&f&m)^uKKrSjY;eJ21SP@eG9MK-^Js)=Fq#yM3ZIFjn=gpwC>5_ z{Bbv;G98+!R^ZVNlBUOac-+Tio%Kv>>I#mFY~R<`oNI*T8k6y-o7p;}+cgF-@c9Go zGF@jez)-fAEOWXF&`Af;UaZ zYOW2ItYd}Arn@LZr^p3Bz6rdB>G1EoQ@T&J3m4xt^;+-tq7X35G8}iPxzrO%eQE)B z3rYrV*)}j}|A=hNI=&Vx^UVrVq0Mpu>{zl)FbaNtCJF$vFriJ9 zgMj&11C7A|qZcogvwzSC;8#oej?^lDcZ2*YTmEuoM)d?USeLyuCsY|5Z1nc9*0<9tL)3BT0{|V2@cnmeKIOR7#3;@p!OjQHeQ|0(}A^i~OG1UILTu<=k>9Uj6@|9(4VKsWiP>d{( zgBtg}QF~Hf|4`OPz$nOtrfW7j9%tqX>$R%F& z9M1IDGej%#7@G9Y898;H$1=#RIltMLT2nsSjkd(r0*FoM8W*6Aq@bBvc%Yf+TDX#~|6BAmZJEq}zirxAP+} zj)y;78p8=HBpO!d&k4sIs-HkNr3kTOjKZ;Gtt>vqzkCVwM77Wc;jxfe^&ex-Q_$r1 zr6>{O3evKMR1~FxhHUavV7VUVe^|XBL>3)EWF)i$Yf0z?w2;ti>N>#vR9^S$F7Uoo zwu5>rn;nSEB@d9CNgW_J65Gvv-toRtZu|BAx9~_}lXq8$(C=y#X3*6o!l-FzjFSmy zjMMooHowIuKu{ZjvLmq%#YRFuvWJ90^U%+&?wF)*c-x9|+`{2iGxmA?CSm6`c5mFc zC2MnIuwM7>1EfX{6GT@Oww#IXvyS?9)Xa=d7Nq&S_3L%ioJL!!1X>tY;%&co!)dxNdgC#^|_^SA>w$Pupzh@eku+U zS96fY03pM$Qr?S$;VXrFbxsNS>U%}|I=962K`TC zTPLNXQ_{^%<>H2Fdt0TVv&z{`t>mV5;eXw5a0~AqSKT37-&dj#6KtT%6GSCJxqPB* z4hS~f&Sfw0oy~F{J(a0AeI(m{_E5U`?2>Tv-AVT3vs>8CV=wuc%}R#M7k_1k@(C&u zcjJKai7FC*{S`^SSDa8jSw&;7oD=lc&M5D)V(%d}u|&I<6utH93P+u|$LOuxk>0&U z@oYS9C0(5;TYo5T@Q~6(@P@rQc_?WURs^M|U}L2m!YTjuQ!3&ZGTGY0Qo=F9(u(0* z#BXhG0|s4A<#f&ig*C#C71-$XMgB=Zqz|*1Y3K1B9S7v0i`%>B32uu37J7T5g(k@C z^hEC|1u)QaNbkuaJ@ke6hSVb6js5DAqk5M>v%~Y~cWlTxQP)bFtrm|$0h(E!OzSb8 z7Nn}23(XO(i2GxvVam&T0V7z)LiP2$mQp) zVzc>Aq||)jJ2jn1)JfeEj(k`7uiI%5VbIefMz6F>hy8MdOHBiooJj&HHIoKVekAsp z$Nbyw{S@Mk~J#1wkNa~j?;EEES;FhxdSrlq}gU-@at3% zDxrVW`jHv{)gw6p0kgW1T#iCvv?YY#kO?aCMGr+ErC_}Yal}QwJ(@VxVTdU)KTeGDFe%9Xnb{7)11tFlz35J6Hdw(YM`E#Mu(18*#~K3&4RV zF**^E^*XIWWO(QhE;)R~1;9r(<}Aav=~EMJu$zfK9n5y2_{smo=Qr*LFWcFW4CVjv zezm}EFg%UU|A4(g3(MzsX&*u)jPt;IYij zr`+woN{l~{3`3ZA-hz0;a zTm|rdm!j|DWZ>xhJGIvFa=Q3U(ci`F9js)Aqp<8>P0=)S4`w5#PqMEnk|iT8Fopq1 zn%lU)U;ksqK8^%59tvQBGrzfT)b-kCmbdQxGVgWUBeeH8Ips?8^Ghg(N9O%%<0gTn7BfPw_AJNSTba=IELX=Hvdg@w z#eN!~>cef+ne&=XIQIUy6Yp=qKx<1DDOip@dEF_3j8uEN% z12DdhK9f$I7*4f2Av{_kRF`8!3(G#6_{&^n2)24KC@hG-@h9Y%seO>hsGAvJARiDm z`ej`;1`2qT7dJ_)P=%w(f1)PjgT7L6&O9S1{F;soy3y5Xp|;#)ZK zWNZ_@;hA46G7>L%G*i5*IObj$EmkQ!*HT;U`a$bK;KB!5@PN>abY8=<6z;it@#^*g z^+Nu~MoQnjYCBCH-4n_XwW4UbT>K@c0~`?q`;)aWwj?%MuNc3iA0zss0!>n-1fPr_ zgk7SI)qFe9FU44&|4h}q-kA$o1Pg#zR4AueMP`L8Q`lClhz_=$iqh^lwpcgmN4$hF zt6UM**_>7xR!{&U7zSdm?nO9-(OtipjB>)bdc4R0^{Y2*&p(G&|7L+AF7z(S(6IOm z#IV1%9%1hDlN<7ef*@3+IwU}z&=EHVS@9b|+-6XTDcSb(p@!v3+}$l$@y0}@k|-NR zLj)^2hs(ne2(@lQ`kNxl`_Grc-aS9u>h zSFB^fXPJCEci8HCR{J~|fiFW~tD!O1)~xi4(gR`!z}T2zSZXpFTmw&TI{kV-XLdj3 zW3HE{e6_s_f{yytvxb=SMSy-umWxIA5-s>b{HAz<{x!t*=$@*!K%mF@M^+rl`Tj4aACMu>^olS;FMuRr3CpbgrPr_wkm`Lat5)xVhKrHuM~Hl z8w8h0mM{|HE4Wo187V?4Nb(ZLNVGup4nS|MViYNZqCth?D8uba{#|REa(-Ep9y`A9H@Q5d%RzrLK%^Q8R6tXHCyjOV zo@^)uglj%|ahA0QVRp+i(7qnj!I&CeencPik_L0(nF}i_SPE{&&y1JgzHrSNVwFME zykcOBcs8aLx+tWTF9b9saz@MBLZg7Aw+b4FL}0t08p7E7R9b|6FKbN5(N|XJjt!B) zoxEd9A9t6>cFT|Z0w`KI7#IbP)cSD)Z%Gi}#=|*a2~VlJs>8-hxFj<7bN!RVvGTx} zo)-GWJZ4dPoQwPL>hmq5wUT)ROIs;DU`Mgfo?MUOJ#Uc1NwX9(pr3=-`Re1WAWhQ? zi5O{ODnPDxqsP8=vSm51r?Ghd`Vx#mCK~Qd6@^d390FmvtxkFELTq=fi}~ zCPOB%lnxhkXHq>!>A9E_NPSV}Po6L9+U;2|N2-a#8QPzrU zsc}g^Oe0iNc?ZkTx)zJgX0E-VHb2-D2{a@p0*r#Q@MpY27pOxcAhHbBjX8P-IrAj) zZF2}2%4L(s%2H!qEC2^Ry1n%B`W#plK;oC`1{ijmNeHym`xoO}JG-`^MtTS%qDY1t z!$k5nh0#Y;{uHu6h6M;18rm%5iJA2B36P$ijUSu*X1n(lcnM(p9lq(b_(=u>Sf(de zIY@T`KIafHNo+RVs@4F(C50%5gh4n+L6YUz!d?MyC*G@QwUP3^n}v8KkPk6Sm%L_E z8h|Cm;zGG$;GG~c74*qrAFRn9?FOeN{R{}ZdW9GEDKpKFz3`(k=ajtlOXIo*m(=6o z!Y`Z5^=Jc6w9T9^3AGocE#R>!nf;3)7zHG7av&Im1aR^%(#fsXp?dE>>*~Ik*>nQF zEb5i0%2xGB84UR*r^P-tOZGk;E^1*^I3ys?u=hV3{{YZ^J{=%m{GK!nV?wLsXhKUH zW^7MLA${YRPHWLdo&}V_;{a9@dnv~G{pzVRbOnelEy!)v< z>Z$813~9;>gUQQ}L8>MU)Hu?^To**}?Yc>to*g57HkhVO=eJNV=(xw@b8^$~lJm~- zq==QQfzfbNY*oyE4jK!+3ddo2?_Kr1i!_IesMltr1}D{MXmN&b@@b5);PyooF(OF^m z8Qmu1gtY$^{3U$R7FPyMLyy06l6>=cKdwWthCgVsL&!lks4;)cZ>?H=r-Z*k%{YrQ zGXq*vyRMa*PC%gz7H^wzM%M)yJBPFktO7ts4J?c?|5H~~89|R|4G#1WZ6+Y%I&q3d zkFtKmZCT6PU-##uqQtprCI03ytozE@=?@G!zCS?E{taHMQ?)jlxCo!CIt#V1uT5HX z;Wa(_hun~+fYLcS*=Dj(JuSpFookI(3q~5lwyRiGId*G zsZdpg=$=$qttk87o`4u9B3Ll!g(V%DXp{FY2A%Z&$q7qQAjmJ5T3&mzx#i`T*Sji6 zLw^vAo>k}HHJ1dENco}Y=Vs^{i4BTn+ht_Vfjja?0&XzP|oS? zgV_{o0$Jd1XfE&fKsY@|ajzubJjL0SSS8;sWCNxb9q`={@J*UP^nir`2>v#8gv=?> z0yMZp&v%R5LeOAIiwqQ85R=_JdE4>IRdA zW!FI1{0s-g1tF*z<`0D>_OVwfqb_{yhFTZzAsu5!`e**)7Z;O*3v;xZbpDw{5tqvI zv$kL#g%Niu#1!dZv#0~tCvACIs)U}_D8t+uqZ_cdbJKT!v1D_ZKI><=mM+z7((8K) zahq(s96c__wB+tnch18&3Ln@yJZRVo|1NOu`?@)#w|oL=JA9w;tj!kTLAX4ggff2) zX%8~>;hWXnmuFS@9#>~{t9q`YPGzDaO{&f0eX7~IbA;qel(o)c3RT{v6r}6)bMHb6 z-lrJ8PRwm)DS5mFiwW;Pn$l06Z#kviY?P^FvKRVhoHc6bZ6tGt;`0+@;3n5=a{v4t z`GadtyXG{KH8E%*W{I)esfpPaNG)FG1qX;jt&QPCX>jVbrIt}7iiM`os3gGUU*$pL zY@1DQeaPLt^WHQ5V#o}LhPGi~1CVlFnlY&QBc4N(Ghx_}>R;ZmM*#&=u`Zi$EO0R?i&zSks(%$&s&k5a~id zjWy;S;YbUIQ63Xl;rq9PjXRl+*=f|(4-kv=zUTQ3c4ASazEMdDigCr?c0qa`otO3nVs;O5xlysNHnSHcO){u#xO=pvHDwg z#(D4Koui!q82Iuve$%xJZ@;Z4MW%YG!{t%Vb#>gxSSLE>W^}kMgBu145IXB`7hO8~ zk)>)P0yy^XCoW4Ym#*w0Xlr;NL=eRMrhprT#aw5 zeOOv}jsdO}ps}E)rX#7B+KLEJHAuYdz)hXa@2~6Htfgk^uf6bVd?@DDD;F&@Il)#l zthC*KDX9It!_=el3=VnJ;f(0;MRzz}n%tw3rIQ{~)CP4csIh=)D@CK#$CEbS3RwHHW~(HHU5)-EBf zm-G$`memX5ukonrxNk6MER{Zw&r5CcI9Oz@03O@uN_s%!t~U-NrM6+FxqVjwPjYY6 zJ7?EMTl7x}sukh}G|7-UmoRRQ4zUvVGQ##LbW~7ArOgOlnS!<)?^y^qLwC0iHp{XO zBiPvh#Wi53`o*hsJX7#I`*-jPmj$0JWh8A2ME$|P_1sUo6!SkG@CP5r(jMf@^8|L8 zpP!t@4db0t>jjc2^?ysgGyQ;pqbtNwM-S~wdb8W3iXuB;@$FTaP;zuao)1wj7SFRQ zx9*ueCxFZx`x_wN`xCY!!VfQbkWwG!QA_eBFAVtg!~2G?$kwsp)gTeb?l? z+h{(P!TI~^z_Y1ORAI=Bh>nNSZ>a-dSb0|s#AgzQHE3x6)F=O7w$_1S$!Qkl#TPL{ z+n)C{-~d8_$U6+MrUKj3(gv~@TrHNTH({!}A!Lz-T89hFDKca4!Mn~@?M?uEgU1&C z7kx7;<){ylor5$Pt%z4u?j~je;IBDni03{k7IT~Y!{l~D#S_TullCters7sEZAJ?1 zZ4>lP&}kV`kI;hFp$E0tTFhTQ6b&qm-~rpmT7r-xF5)^Aj`LfYgZy3}h3W)PBOtz> zG0yY2-rNjYt`xr=rxT1gnUBZp)6eIR8ZC@~=7YzVgYn06JE_<8elhS01x_Ls1jM)o zxMT;uh>aedn5uXPP~)M|Vq2)gGO%ND`OPeF+{iO)*w)xjL<7qzzW&Lb)t@Mc1`xJ+ zz@O-wRMbYv`OJz(Lyg3OB+mB$RNfd+SjfIuJvG*y6-jf$*V znJZWBwf!+cMwQz>z#c8p{qoLGoOPTDF(tE`d~N znQcb$P3iY9mE;xDc2nqbIxgL>Uh|iKLYwzC#MB9iFS|8*qoYYWG5>v8fH-5uLXMOD zcmp(9Y5$vG+-NPFu}rRbTgKV)j0Y#-rMpM-mUldr*At#r&#P&9n+G@2s1HQ!OGRSS zFV(9JIMG>B_Ukbl6Jsz%Dr7TJrZ;CyA(=g;K@@YLMLwCiO`3+rLf;J)^;eo9dw&14 z!^|fM6PdYrIch7l)Yd)@_XY(-B!$1*2EC0K3legPILu`{Doj95zgegd{JcK>WksN! zsnphjqMRi~%7wAvn)K_&BF*K9|J`QZ+}P2fw-QAk{gYS6xAVz&$Nl%_tN)eH=O!fP zSpCpbc9$=kh5&$-c)8mtCB1Y=esb~pPXGl;J^bD5>mQYQ6e=>4z zxF+wJn3+IP(oH@TMn)@IxPvexLub}52VDa!K0=4$zeyCGD8CR^HppxGc@#+)`ZR$% zLdgQ4QZgB3eC3 zLe!ixHGIECe0hYu@C@X;QHNV7o=yY@Gqjc1sG^@C40dzmBhwzgtXbxJ}0NV+-9$uZ+TPJj8IL0N-e>BFY2v%&U7xfJlp%+&9A4welrDU(A6<>W>H&&$mW!S z`f@_kI8q7&=4y;G$QBZ*q=%3jVh6kCQxj!W$>^a(0f0z?h|&p={VEd;D`0UZOd{wa z1BmVhrLH&*usqE{gF>?;DPw}65QN4=TrL?!Q=&v1V3MXc4FP6_NBKgC=a5rp$^aBh zL`ek(r48ZII^eR{2~g`SUVuU#7CqHHgkmZH$~bKv5cP^IjYW{G{N)90%S4_tK|Y+E zTtO!b$h{-v%C+7BN&=9 zFM|!Vx$Vx;2=UH9q<2_&!gD=O=By9g-^*FkT<|#P4;PNzbh!JjuuJFTmVk|80~5!t z9UvLN)`Q;xc~1CSK4qe&D~9RL$Ps5=4&yraApEh$e7j#AU<(JmvP)hX(*Xs0Z<{!< zFz8{#?x!9w5t&20&IUKiW-W}AZ4FfQ%x3SqIT*nM>>Wg3wxuI5fmkEJVl5GrrLGxg zZ7$rIB`7kTZHBr z9e0+84rBI&Z;TPsa`&YUH zR0?}MQs()m5{16}DNRHR=8CAjFpUPca%A`bGf^ToQ~P{h4$f%sw-W@V1-Y~ZdZkQ2 zu(n8$84^qR8OPf>@}??iXvmv?ojCI>e2^1B&>Jk;k1YzXHCOJl==%<$%XZjv`h3)b zbwD*M0-waEe{63q_zkr0R?W20a?-y5e#%_@WGn_x@d5T|;+tUb5k&}X6xCD6wtPX; zO9yZ~gDXwj`iR7MCzqwzQK!Sen*x?#ae%j;T^+(VILGJo~houFc;A+CsCl^|!> zeLMgjM?zvf>()rV&jk@gQx)cWjptysEJMrpvlF zdxcN+l{C>iT>Gxvo=?;t!D%U}UwuITb&UW3NR*OR`4K7p=i}!x0U%=PW@&6nFKK6N z<7#61U*wJdRA3J?upJeDP@-Z00GR(1Y;MBLWXQ_kL1$5u{cgW6hA`q^xA<*%O{Kaw zepK%nqEnZGV;rQa*COjw)+z*+`iHAN!PY6Q^|{a8?DJ{eKqz4y$@};{V@>xu+I6SL z^YPOigwMaW26l)ZzN*xs6J@(*+S&`gT$iy(|hr4aZ27RftbFTe%!E+aTV9?*cxw;p7bL8j~ zSVgD(}e24=vz37`?C)G4HE-%lE1aiH8amTodZ`B;VyNJ5g-ka3yMt@tp z-Ox`OH#zodJOK~<8Z;6tqkY^FcZ5ub+Zy6 znRGj%`6t9=yaGbh7%MYaI_qQwJ_#-pi9CldW}=7+V#PH`PzkhW4*M zlSGP}Hvs`}NXBSPY4nCuf@H>JC3A?}%AlcWqnaEcSk>*aQFLJ}E#Fc?LcxLvta$-7 zv2H?0jW{p!v3->{kT!0|(KW0EwuQ#d4IP_-!_NE;r?lH27FdepJHviXEJb+XTOxC} zl0Qqxl6O!hyfb-|RJI2P!;}f*6i1ljid11>@Na+Q^HzbF8H7 zlq17Z6kjNSa>}ohG!|BU;8Gm9b68d$X>$caGT~tyRluzPOUF#&G9qT5jlmVHl^2U5 zgWr`u6T__>CP$OeXC0Qf0G1bw}2A# ztqia1ynBa<*(E!ZBtApC>l#Iai8zh|vlh>_9EZSZV0l=JwJRTDi3ox~!Nlm-XJ^(O8Vt^d67S4&W{`Jj^0{4e9&^bQk z&IIP$(AKEX7f3ULx*BBi%P+ql7uF;QDXE^og@SWU0tOQwYF@%rYIyuop+|MNG02^~ z+^Ozd3N|aL^xUEl?9>~wojH|5!%*vnbtCAaS}t;(Tn zWx}HWWk73#0Y?;gY~&T7w&6Civ^F%=f+LUKJ*y}DyZ=C>PbkeOY30uP4nDpAw@r)xvm@0J2Go_D<6DH8^`&w_8hpA0EAPE}AGkavgq=|yD6hV5WM zs80WoNjWLU+p^w>V7IsMlN%l4zBV@!Y%)prtBKuHwXt^y9Bdb2Kkb(JOnBh>ZR)a_ z@jij)Pdj%_S6Bkf7g&N$RLEBDj^ytQq%?y!qQIGI?Z~g&rdigBk6*79#&7f%bRH(_I&6cHwv%^wpl%ENko+G_z9s? z0Zo=(wzr!KRe8EJG0z+zB8rJCh;jKOX32`oP27}a3lIMC9xO>FDP6kCc^534?-;Dg zL@7-q@bmC3el7k>J1Puz9lE-l*?_v-8!mnRn!9zt@TetZaCqhh;F*bE zy!50E;cc(8!4p1*vbU8Bvf^-5y z;Q(8wvZ%5-aK{W{=L`nZ;)z_tZa_7{5M2%YnS(^cWh$txX=pkT2cR}jc*!d^(1{~U%3c}P2Bm3k_Dj6i+yK(5x z;qW3hOJ5;@&ml8?==ViKaDzf8-{@$H?eF{-R!%i&EVep^)ivQg6J#KBFO=N1@_oIy ztXb`e8cH+4=0NA5)xjy{Ey1j?bitMWjj|$OmmQ^>M?V&}0cCQ>?DZ59)moa{>8{bM)piD)6J&)p3#L)jG86t} z!fzt%+m73~+K1DR<}>xFd8W%2(dY4R?L=r054W>3brsQ?VR|GkO+f;1cW+DQ@RNE< zsXTRM@>Mtee{uAzFyO@O-23i-H$-E;%y36Zqd=_~VBK_me!ACFK;8`X0DX2AbGMEm zoqG_Vw8!9jn|S3-4TV*<@{4zHWa^J<7pTgcn*F}-0ljE5$OTcSoQPm&*izluv~MgA zS&_NN8+f_Is*w*a@gVMW-8@OK%z}53E`mYMO+Rj#|LN1nHNoy8W5n6r`pe7LgCZ|+ zzizp0be(YCA=aG%K1V7Nw<2-RWx0*VON~sN>qnlIB|ABOzyA1;L;zu#|16Tas|}dC z|9EQj&ERAMZRW$sy4TXk!#Jf~K)nXm3;D=k59OQgr=FRYe$>J=gWYbFNPdLw=8gEP zs*k2Fhf+QrQF)aClO)dI@NA9n^0>(*S9dr09v!kMdMA)Z9>hp!8J+bT?7Gb`AYcmfEnX9Q8 zm%gf06~H=vu0PhM9u_`K6nS|(-2K+(9u||OF^!H)?1v3j7Rjw?a;a&Hn#6mmS^1@& zLX_8)G3435k)=Jim~uVf>NLl@=nhzC_FAMo_g)6>wdju?#gvTc_%mB&*&VwiJu=|p zF_TOUWU$Ct=ZJFq@BcXEI79u3RFJbDzlLSpbXw{e_&BMj?v2g2GvX`4oBMx+NVUt|r!%gB4KoPp)>Xw_ zapFxz+?H4f(LnLQ6O5dMhkN=i+#{Q1lHYZ+Vj%CZ z+R}fFwJL#N<`$Tcqe9k=-4Z3kFR-kH zP&`*ayD!pEEaK8=XHEEaDE51b1&DL0#%KEu)gmD27y1~Ch4KvU^P%3<9Ei{_{il%>`r~q{P72 zr~zJ!0^5bTtFq-;w0LeWNzYH*jvph}$N^rHo|UYK7p;xVKP8^&3mr(km3)?w4Zvj* zO>`y-AnUPj`1{QtebL?%?h5gw``J;%V2o^7^L*pT!e6c&EsIwJOhLU*lyr{`e9pK% zdFJs5HhDO)^}Zs=*;5xWUzYG*OAf^F%}{&btydF16)&_xFn5~}=A5ANz?an&L9dr7 z^!6y5Ql8&*^y|xK~HmI69~cVjx}aSsfKDTrP?oKF4dzDInWNfayOk?Zy8uP zb6p==rSY5+dEcSmDA`&RU-9iX8o(tzIQ!7 z1Rw9;rihn--E(EUCDkjujGT!Iid%zJp?5HvQeKd`*|0~FY22ZHk3H3d;Z&;6qIWg$ zaXFoL`#BtzS$!1ZT!6=o99-uW?#QIb_hs_^%~Ye$GgIO_)hO|CKyPsRs8Oq)!J+@&+)b&7o#x z3)VeSMJ-(FtkReD2cPp8!{=kZ-Rnb1sqa*yr)4kNfA#Q&)~nmeA!NWeZZI88Tnxjd zTB&q^k2a|yKkp&G;9!mo_5`MCgr4L!*ti4_Xj)cn1$}{dvRo@`S#DN7)?imdGOxxu zW8Be~aH$k{1ZHoMO?`c4OKwS0k)MTQeui5gVpE&|W$?Y2R-fzHvk#-0G zSg9}-3!)FBG!Os)-=B^gg8#|Gf96-anA+<9n~t}rDgGpK5&XpW`EhQ5${AMwKobFsl$j9BA%k%N;!7f8vKO}x+Bu0I#x4zvMt&Kr~dYMDXI@?aUmDu)@)ls-C zD5UFKN-O82y>OYHn%V}sdXNo_H9Y?v+u#kGmzdk^eY`n+s@Z6Z!y}q{8qb_im41!} zclkIxWAq%05#mg$fY|+GvF#;0T|rodZR_6Y^A{$PPIf`dd9J0jmZDDT980#eu=I-N z?sht~!pVDRk!>o1FT+i=#dXJZg)3cFH?xG&2@F%wj@7nhE4_7z)Yi6#nH24k%KmnM zwRYu^Tv=C1QN3g@e;Cx(<$ZIHw^Oj1ePtpL(MZa}O*UF-eNzRFsju9f;j#sTr1~5! zGj`VyOA9#O5RS8>Jr9D=vSE5kY-6O4FerrmVHH_0!BqY9`%mZ_6?kzYU1x0Vy3bA{ zu}e|d);yWLBj25?b4{mp5^%5PaBsT=cAWDQ)sBV3{sM4gIB!{xB{tax@M5cADRt+p zkH&bQns!pH)M|hc=Xa?c>*F9nCrAVC3ytBasKvSId*p^6hvWx~w(gCgQ2Cy**(-+X zXP{N)4>8*^=Nif?-CuZ^lm;>6mEUJ)LI8|KXMnmpcqK|mvXoljfDtJijRyKFW=S-n ziDi6HTZZ77cDowU2O8OSFG3;eDCEQjPYRGgcw49f#Y%+vYKS&!!9*0GfKv939yjmt zCld2=MFAjpUWVigg}+Zm*xUr$G$^#5)^myS(7v>k{;pyOlM`Ui7rx7ti9*Kzb8dy(Cm@7qs3xk&!k*}5U z-~Zw^hD?V<4?l`G_d0x&zDw@jg>?uTSR0rsi2B=c(>nffHXF1D`t3gR=$mv`bzvu1 zmA1~tLmq}*XUQ1jq#bu-WzPUU@r)72QxSHSo3=_5wVsM$&qGgk%!Gf{Vr1G1`>1)9 zVXC^1rwW}Cwf6c2#gjJ};;Ve7FDr}_o|A{Z;kt6ObE*BtOlI_x>+E_!#p@gtU3ym= z>I5!GlZEEGJXosg?ccL2Gtx!JXQ+7?ky9T+-2%7Yy5<9zu|9+wARjrQr9?mZJz-vk z4!qe|1;t)29cyW~HG3?SGpABI)Xt{AImK9fWxr>e(PsB-Zm@oYaf@#4n>19*cCv)L0^ofAY;prHUZ?iwsxr z`zCbiPIkYjGrxd(PGvO^E6az29Hc-(i0J*wOyKhkMuGdnb8=-+Z8vz?f!|{(UE^j6 z`=ff(6blfMF)Oe4JDH_rCo_Ev(6t{jB5n2(jI9v5CpF4j7QlL9qPP7K$c#v|sfOTA z_bDPEe8+nh1np-A`*SHAVL8DrDOTNEued&M( zM`Z--ym}}|#70W|tIph~w=q|`Ox^tq_#IW4i@>e|4_a>t(MBVHzzW{_fNbGWtAYjm z@uMoMv7O26I$g?400kZ5VWtAZTU2;~hUplo{g>9ig_i5BcPdNccJD`VwlQ#fg4f*@ zDu``4I+Yjie{r1(ob|KCKCR*j4LnzZ()N*K3E(d75Psf|F4987%9=cg z^8&vJ1XRG;2)9v5>w% zKI@AG1W73`dRn5cztLT04|(k8Eskz(sCX_Qb&O!O({444x5d?k4aYrqk!H7tk!_<> zw6{=fi>2)W60%7dC9CcSvI7S3v5lt<=0I3%bzQ)Tw=w4MfTwE*{SGLlYQ9pChX;2k zA~v?z2BfD*brA`5TWWz*CA;~fryNO7bCYX!{j1?|SH^orgJrhPYdD2()&kAIH~)DT8lg?M$2$NK%0=|$uf%#gBs`x ztY3v4=);!j{32FGCfu{i%?5i?WZNB)$CvCNYs7}8_a)Z_k+J0wbS$Z?TkCObO+#$Y z@)F{Nn$ZYxg2Q!)9SuzjH>*$CAGp3716)2b%v=qV_0t-k6kpz}He-3yx_kKg?ohiB zI~^>khnz<)zs%qBwbNz_m_(4i9Q16-5-kT6m>Zlp4_8hOcOsK+#-j#QJ)5K1HBY>4i|?FWe@_;+y>nKl+qP)8)mUBRtJxtqh1E@)X$T=@BB{Y@46k=0tcCznh>_ zi|r`A_grjg?L$kC5`gOL^6mqtsRS@QD~x^5Sr1e%1b5CCxe(u2U96Y7s*^sVx^*yU zLzgk4x^a-WrlX3d?i*h60?mfW2+dVHtX+Y3NvNyOcu`V z3`%WTLI$s6V0;YU$_ijepzmKHG~n5k+PZ`cCN^onUViN{*ah!XK38BkkO+pa_pb#3 zDnbY8A>I%Z`AeQo;R_Wh6A4A&f%u1iik&h?4*SLP%mr2;i+DVxHmQh8&8?j+Vhj5< zL&p%2#4~G7)PsC2(Z!2xUx`6Zw5U0D4n`T)n5^a*F$1|>_ef+F{#=&bQqU8l239~2 zyf183L#x|6sAEN;meY&(to^BO)N9ODtpB`gD;WFMO$=FER(jSX(LsLjDn7PPw z7&%2jmxA%HYHm3}%;SrNL}a}(eueDQ`E0)wj5n-y=HI0PLh?pEJE%XApSR|2=5pNQ`G>*dq{6Ls%L ztrxLj{cgS#4&}2JQ~=Z!F{5jN2y>wTh`5T6lHyBH-pv`41zfn(0f+Uhs|VE?G8tgb z?MB;it&-158aCq5p4{tZDUFer7L4}d8`X+z4Y;(&mlj#B<7BNxL*2NxO@eD6Zp}o- z)oUmi#t03@dImeiU4$P}fxHF#wu)KkD*I>JDw7+9tt3j=DXfqdc`2 zQ)MFc&HrPimLf&nBs$bhYgHv?n%yaS8TTSyQqu{|)Tbs~P){P7evH-z zYKg`;b!QfEYW$Xy^6+^=6V&wXPjz!AATHlj@R07GX4SLJJ;pyuKCez3#gt35HbURl z`F0j>O!dS?)&qWnwN5{ed^NbVND79a$N7#V;qOqckjOl0+U>et|5{a;=ZW{$JPanK0$v5e^>HrCfFW- znULQqf0JLJksr%1$K<{9Yc`Qg`8Qg9s6)!B#k!pN_)jXS>K(C$Xm}^AAQ)XnV~FT+ z8Zbw6!}XgXcwz=j5!_J$WC%4AUX)^9 zlxAj;GukcNU4tRAbSDhk%ovJx<=|oP=s+Eb!_^!9#Vf@zlw@WZ7K~hz#(1MV69h9> z&NGzsk==j+Osq>Y`HNjx1>7%HJ!XJrBtZHiVB)NQW*3TK*9qohvj#!9f^lqS)eljl z%d+w5aBXU4rV&#lu~7%ij!rFk@1bK%z5t3T*<<|HInM?xp_x2OkfdeI3}KAV5Al{{ z>LI7o?Y_xd|HU^@dZfACMJD=x?IwnrKe96sgx5Tf(&ES+&;GrOCV%xLWeb*2qm*sd zfyz$C$&KjtMb2|5-Z{9Bdhl+``^3v5E#5gB6Q~6_kvi0oWK~z1NH%dB4`pqy7o)4L zKwCz!R-mu8G_i8y9&EPok4~$SFw?5#$>s0Z-zpwePngT4XK@Za!y~6Pz0y|tGkxr% zx@>Xm8v@K`mo&edNhFExBrJjM`}FqG@;EXk4ovHiR{mylfUyhU>-j#Bn}uzCe2*Cm zGUPA!5PmzfiG8-JM6;i+iLr-V&p`_A`TkQhm2TgA{C}}G2!MZNB)@4?8Vbc+5w! z+s`hv13lLmK4WuUC3Z}izP_%{4i~Sn)AvY&?P5Kb8G9}FtTEGct#>B#IQEj!mh1V~ z7QyM>BCy&WXAQno3;GZ{VwhPGt@|CNJF>JA2eyfKBqC)g35r6e^(Nq^Jbj z%`mA6Mo4QQc`XU>E?{5r{lL-FZz#Hr7PtxhZj7@Ylq$;ix zbNr?S5zhFt@!iZz-y5b`=Cb8!oi%UhUdP5oc9m<%wA?n4vY}Jiduv&4?%Ch!g=%Wv z*rj#X;?~DpulW^jiI?uug5#4A@r;-ER7(5KAH9i2*~p?=TLlmT?SqxAu4*%o@`h8B zzWPQPC>X->)#+S_u~*s8#DsM(RRA^(>9aBO7cFkZtje#{wl#%Eww4uvVAkcDM;FyA zc5B|{%jZs9*?vXzi%K$fYb)sresJjK$z++H+rB!?GN?oGd+MuanAZ3-Ri;x%SJqOeFzouUH5K7?^Myp1cRv6d4Mb zo#hn0x}BvZIc|9E?yv+enc4!coUG!7VfZV;oNaA@;2aFNhrf>*K@WHW5YifTVq|j$ zqMGtiPH+sBy|enuYI0fU74xa6Pdk~das7j*ub=DSL@?->Li<~@k?=FGy z^vc-PYW(1Gyfl-0o%K;v?Fx;{X)}X_5achPzD7NBmgi2W4}S|TUs1?~hVFquh!?O? z7+OXmf`j!Da43~R=eBSN<{C@40rq0|hbo*c!#d4kvomHysP#FJCvu8zP8#~-_)ai^ zy-#Iq%rLCvYg;w$#%@6le&&}_d$!&H8k+~@a|E8MXOG_|eH8d@OeF({3{;TuY2crR|fhk?(AD5hChG_qNT@`bvaf5D%_yQhf`-s1wS|;aLU!)Es@XekK1p_`J&q&ye#xWMIa@Z-0qxylrv!hu zy_Bl6+wrB1TPh{5?kE>-y$TH-fX&$OMn(f3kxh7K0VF)HNrRnBV6+rzUW0CzOuz%s zYsdci-AiTz%NsN>n-K?6hj$ot4)WJ1cS|WUz`(j!u+}3Yu3FThqvhF-Y;U6s_CGYG z;E1K!gr|1d8S;4|A?d?&^{@@5a30+agL4bye6*yrZmh0gbJJnU43);eZ>!Ha#5FyW zKL*`$2$4&%>NjgUvUkEIHSXQSlss)Fb=>K-j?Q&0Q>rL`w)cff3HK7!1f}^(iT8yd z^qmy+%2JZB#H{qKL0Or>9*SG6uJo8%!WBwcWUn(^ix5`(GUT^sz2@qSVngdb8KW!a+K~z z*N{r~tWE|UZ&-y$-f8Ht+FV@z`@NTkOb4_2Ntu zeP0Zdg*AF96oD+?>zj9nc9Qqs8ROIm+^4L+UDp~Fqq&TfGhZf-Qjukc@fzi;PUxZe zQyv0(##dn{t|DYuf6}YX#ff&3-my!#)0Nmbi#gqc>w#hkX?u)uqz>%@wzfl&MKnXK zM!k@IBk*GDF=8E*iXF8~^zoYd3hBehti`EmI(Dp>E)TQrs0C0kHaXuU`8}u}b(2wb zK2({y3v@)n)kArUu7QYO@d!yN8RJ8nkF8h-Xz-r{;p$(mMqG3o%I=SwQ0=HZ!HO=G zixmHq#jiVl;gy1ldc}k-vYM42%8FJ7m_%nGD$0%F^+GVoF>(ZEpOO%mz(f` zt#N+;7FOWXs|IyrJ9l@n>1Xy3%<+0K>RUc5zkc6NhhkCwEF zyu+qN!~#ojUMVI78&-;EiD;R(>g5MJp<=@_$OTGW^e^>t$_f7=exm~`~q z3tKun*3b!#khXd|HWZ(zP^{(7(YfQcbtbCB$c%$t@>`j8w2yjkO&>7m%vVxe>3yS` zOD>^1+6Vn$(wF5Q8=;PWCf12P`g2ZLLCaQ|HRj`n(~_;P75IB0tn{FkuEYIKLn|dj zM~cT*mt;t|h!ney^<4J_B-cMu{3Bt*E4OugE=@;KL8gT*-b=_EnI&M1fL*`lvZ-*K zA|!_x3e)wmJNfS$0966orM;9kwKCzNSi$3Z2}_IgM2l$0ixTYv&w@U0v}D`2o~68t z^2M0Zs-3Hw+yI`9HJ?*Q2&nd9{?VFwx8|293uJu6*6!~dp+uEqMo7fu%r-GXY5s=f zVESn7<@YF^vtk(+<{?3Aw7-o8X+*1YS0&qqyS!Q84&>|%^tOJt^54&~aCc9zQ4f&nilCP2BAI3w=wa>8#J@hfTZVswe$ z#ohvh33?_%cOIc3J2*SC{2oi->L7lOp9Dfbbzm<-)YYqS9(R7iT~$0e2o4`B!rc;l z5eSYuenOD%1#g|kYv4araNbo-JJ#JqtG>i)9-MEC3Dy@q^dlc6&^tF|?9lF-?Oi(# zBWs`GD@}#|;D1x0*O3Iypue}W-Z}uf+m7gdoYOgC?!3lY?D({S__s+NI^O1jlxq37 z1S!>-1;;>0A8YK$C@z8$b(ZVU6jw`2 zIk~>Skd$OfjuWS%=*;^xmjWEjMM80yRwhxyR*uCM?yl1P!;l(bIo#l zx&Blg3)t?z0e$1dL&Go`eWvMVuyTl{zp4xK<<+hVa_81TMF&R??Y9!D>n}ai*;UT! zs|_Rbw@3^Wrmuf8I0dPL;&65mtocy!dWA!NjyDRl{ZOW2sOX1-uGTT2hptvKSOR)K z78VJ93p?M)KA@mF1X-pCZ*+)@_&U~~O4d(E`(s1fUFdq$M%O1B^!8RYjJB=cm2Zab zAv#tkKH=zD7v>q81AC9u#=2>HwL&u<9!mxw9Zd{4q>qmOWOWXSEz+RtBjgV}BYU3? zPF|7`B1zbF;rRH%0TLDN2+scC;<%UOBV@17u5|~Q;~QvCxu=apm1wTNM{6pMT>u{^ z9Kv#~ye7iaut)Y`Dozagx2`wd9Mm7D*LWOCU)XA%T3$`uf(PWLq7a+h1KWMkF*8_I zMhGXR7VQh_SQBH$wZVkHemdK?2`E8y>NCvRBw4xw7B%=6v0|6*M%C)8Yzf*L0@Ntny0`3RZ{UDVP5g{`~JKY zQUNdO`%l3H005QD|K8<*@NdScVruJPW9ahl>LLWdA2kM55Uu#P<{xCp9%{^!kW2~r1*s%HFex>d+5Q%<%rb4G>O zik0)Cn1GU*gAGYJQs%jaak*!sBI&XL2uds{ywo)S<8c$06-A}Y5tS@VKURFqVsJHd zNz3G}g8DPn@6c^htnUn_r}uNg6m5p6WtJZR1H)+6)6$nHVgiU&B}Xpspm()Z&=;7h-jJ$Y%)lovyw zKozpaM~Wn&!dkb_su10lnc0GBKhBnoLKkDI({xo|OZF&_kXRPrP*zof378s)+Su~K zd8E!bL!O`|-p(V7Q?CV;4mM~1+$QK2&e25}958C;u$GMG#;lHEoT3SbXwswp-yIrj zF#xs1Xxj>D?F`yQ2?5Ar)?(<=fD^OMkOv0fbbPQNMNJwZFS{jEjCV&KA!yCDftzA6 z4se9P=i+#xSo;~c5K`@+EDqhPB?E&%BmxLfH|6r6osqLlnlpw6bEI&V&NqCznsYm4M`YI4AnkcVL)Kri!8-P=Nn zpZ84WAg1fg@#!k1a>Y#h5EBSprrOwU@TgvBHxV3*G^4b)#L3OAatd<2!>1u)4z@db z2Cj8^?xs9%HMC~N+3AS*2Qt(iJO@Eh8VDL81siNx$Zo>8gZ#nhcddquMei#9!G>2Ak|s~xpjxiT^x zUVWTu+_(d$2i)ut_H%QHZ9pzXV#IAXvX3fGlI~$|rH)L=?(e4@y-(&eF(SK2GjBSm zj`B+BYGt0qKMH)uKsuZ&_Z3oJk``p#=;bwpS=rLkeLD^YV-8kV<#6eF3w)BRvMO?ZE#Qh{JsdnlHwIxGVBgU{pbLeiMA`$Lnz8r;rW{GK=<` zHRDD&-1y8V!UQ8~3wlaCgs%xJIQH{TyE8IKJEnFgd{cy9Q-cqtCBk}YYz0?^6`r&7 z547T{7x2Fd@uROCU8ux>_VE^zi?e09pIr#21MF4tc6BmNu3ymZr}CMNjchXK~9!D#IZJ z06-@0{}v(t4gX&ulG#n))Xnh6)_zD+(|$n!!SAOZtiB(Z7ODhRNQeM$(UJk%?J*-bOn5eYcrEAE?091>L-%B?$U7VyrBIK$7t!WM0xZYUWF)KSQ4bgDpM;{- z3nZiHG-!!;NQkU?{f#692}0|TsZRXkm8iciNSCq-Pzd>W35|ypm8JfC1qJHgb-)?s ziYOyQBxy;|L8D`eYTGR#6q9cm?;9yl$z?C`L2_ntT0F# zl4q`@^0m8+mN5QRo*-Lqhc7Z7nV-=e2?%`8gw1@0hc^H-tAq44*II0iG(_|@fpZlA z_K?Qr=4#;&rdq3}t6^A{WmeL4z~R?7`qF1yoC0FqQ( z7uyUd;=X8hbYl>Urjwp)J%@Noi2DE0^-e*e1nsiu*tTukw!Oy28r!yQ+qT!(wr$(K zvtyt8pZ%~;MR!zpM@4i*zjWqTUuL#=+HiLqa3#UO6w;5ilsgx{lzk<@z-l2KuQvgc z;lR@3;{kxpn)C$G>klr+bJ(rrryOO(*hIw=zP9$lxc#~@=rLJE?Fs)4G|&O2YWqV2 z5cK_=&>sX!5kU*9QRm;BqdZpL<}Xr;NQSx4r+`0eAG=@WPhsnvi6@Mw(GiW*!StyL zTv-!^6~sX1W@Tz4PDegRAGX{B6z4-}1%%k)uzxEszuZZ~!B5FO2#g1=2nYJ`t@)9$ zqXrAoIyWBL)pnn+FGIAtP?m1s3@I^fbk}qN$;9A1z)Uy}FT5VhAOC)X`UWO!s!KXY zc-y7r`}2)Na|N(C0=i8`AV)>vW#L~Wc-`l7GSNP=@8yrXbOEd9>nHC=C3u?5_83uq z#kX7Z0Jmqk)Z#%~kKNaS+~?tH3Lyc`r8%egpdiQUwuL)y=~0~miN|K(X=EFK&Lq3a9SDvYRo1%&Qe|jUU_&0@jk+1>Hfdq}K0Vh(xEKi3 z6Jj%!vU)WKOO(Sd@oY8F?9p`eLgq%Rv9`+9ZeCIH&)Ph-T&kgEF{5)L&ZaB;Mq3*s zF`+p8xeQ3H^yJ+w%GXT-;*CcB$X@-g7h&V0vhSULphlLzv!|ldo0j{0*y5W(zeNzG zg_I6|cCydD%^KsjwMM|fAUVg#U=>ENBT15oS5jexOAQiVFmq2;3SQgpU0Niu7ecEv zn@Rp;UB3av`Js3^Xtyrr}n<*2lpwU=SAA|IV-%L`VP+2+aMRGK5ir&2MP zll7t;^Ax?kG=Y!p#)Y|~k1MevOjgJ3jUZmKTDC=ji;rm>WOuAYkQ#a#L%?kTfity6 z7{*;`q@Pd{>HSV+nR=5n-{=~KPin8=y&nP^m=}}F+Cw#_Owr4kQ=zaQrM{#i-ZKX< zU;mm4r@hWt*aADdYzmx>%5|d^Me8%r_B;MYukeaal0TImfH5C;SW6)=>u(1W_(-#A@DfB6EbRBoh-fKLTUqp}UWEe{R3m`Kr=Wy__nZ@Sa zD86Zk`tnaKZe~Zq^)%TDam&V>ZG{JWk2$!tJWu{1=V1KktsXU|dK+DlfKoPWBM!|e zJYvW0|0Z3VNAEvFN>;dw__mh`CLGnv6+3$e3Ih=D&;NKz#!B`nB$7T!!TyVr$ye{n zt6Qy5C1IyQJ_iLyZ#6-&VBCw&8Cjqwr9En|jw!xy87+^*TW*OAN)Ws70`lY_2o&Ac z3~AV)fiTte&Qq1aug3ME?z9wNdNR?`t7##poiI}}`Fla3tCb+UwAB3yw{q`aO1Ba` zg;iy^3Qg<_=05c4#O+r8{$=`y)}+BU!hH+En8U5;Z;$rTG0p2Iywv73kRsP3LnSj{ z$$fzt3VV?1R$ROXb4!<-%2W}V^p!w6WfvrRUPn7DyX#s`SFu-Nw;b;{jqd1~2<-~V z-9oiWs_T>NnYZMoqDdcc^28D?mY9W0Mj>8VS3vbf6>YJeg0@1DhEfKV$ubg}Nfo6d z^N9k)+##XQA=RTLkZ1Y#z*TcbRV?(F9K>zwWVO(;8K4sCKK=W8rn;tu2Ss6fMoB zd%AY(-9qOf<~HfeUI%K=)5x7x4^q#Q=kJ8}bN!^IxI&}SS1!wB(m-Uu>%NAQ`})T6 z6da{(ozvK8y0xI(N}JN)*H_CrrBedqamx+3RJ;4gJiLRnu1WNC0ONzUS#aDtL%{Zl zRVQ1!`bMGK6!B_bho>{VH}JMuBS;ws8Q1;r#k3zC~X$}>iT!tWqwdHlMeyXE1lDHTKiJxWuQ}S z3(kLMMxu%%ho*mS_GcB}ny33tt;@u^djceOm*g;BLWFRhgj_Kr9u?j(_;Vkg^DZ&Y z>^SLn%WQOPex`rNXIOIhp=lB*$CaCPCB&2yA;!)pisAN~`n1MlgRr(Ki?8nH}5 z?9-gW*J{s=%eJ?`W2h@?U`h=>Q@uLcq3o^dJcTh0TK6G1uJL}&AWYFd(}@U4(LBY?X87O?o`L{O`4`$y0st)DLIZ(4R)hoy9}>kDoRrQ3 z4Vq}5aKrR`G{jz!`a9@nsCkv@nQc4`1XTre=&znN7h5B6o7f~-8fz&506oAp9bI9p zA3eP2>1G}_t;Jbl9*9Y;m&{?e%7?3Dw4usGH+j|(Yjr55V-w-Lm^IC$_*(1HH;YrwG@>6 z&kz9opdqjgB1Xmfp}ETLCc9&c$vicBe2`#(_P;7~^&%lf-PLgaD^mtoRupKNT&vs7l>@@hCYNE7Wy|5x8!-n-9y6wK z4CPe@I5H^8cH|!t0%V@%^Dv+uKvW|wVgjO;$|qqfz@cD+R~;)DdGh&Bo!}B|k~0=d zc6983i078dxk4_tFV%`SI4Pjn#2jh4Kygy~UFfYtIctQ+R#}`itTHuMWD1|r4bxg^ z(kzuhg*d3hu3h|q$4z|wp&<;JX>cT5%1qiFL(>~u<33?kz*H*ymP~@DFmVo9(w1rK z0;)OyOL8 zR`9x1VQqoX+8ypvip2;=9|E2#ChzoG2X6L~6XKw+0zLuZ-7-W~-pKkYg4FIsyOg$H zQqY(7MP7MpykB4WtM*L%6K-MJ-Iay~Nbpqx&w=lgACs?+5a__|-q2T+Ylq#!-hdXx zCA;UeZp6OCw%Uu84JQLkHqo{ze<U?xh9 zD);1j?(*FpGmw<}P(b1S`vxpy>gCA+FdzA3J=mxxNICXk{R_{^BfqYX|0rZW@KD@W zb`+e8dPoP2F7`8LoAONlRpM+yCT{tu?Nxk1jEwALc@`aG12kCvuE z?wQn&z4-0I>FwTtZSIJ7-$iNeKf#B?E4~W5z-R%`)-*`?2n+hN^*VH{%le5WXyKgK zKWRSLw`I;(aBO+R3@6|zSLGw$>I@eei@U~6TM{iJ4OcsdPnYU8jOR;d=v)|GvEs=Z z^eTV9=uH?n6w^T*tc2k3Wz#=}`n|!i>;s7EDVSq2p&*k}WT}K+$5V4(@NC%a9=CC> zxejLK109@97dNYnjBz6CO0jtDWa- zs9<4Ou!Kn3fM1b4_j)>E?Ht7j=J!-Jhu^^e|0Wv%0IrZUuFj4O0084ZYs5vEnFN1rT=W>3IHZN>#AIZzG%OXgL{YZ8*gcUU zU?s~VBGOjFY8@Z}{R@^zNLK~wk`%0(vq|Ex142m100kAbv@Azn93Ml`^s?<2?JK_P z&MBV0RP7e;te4))ULh9Gc3*oNJspJyIlBLT?iri9%y91bcurrhb#2sj&7Ro|V-OeH zothP?bE6R_X-*0#MMhQ0$410kYX%p7z?iMD^w(fU;VfW1KC*`rq2dNQU1xObhBOaeL=)A$$HIs->?^@#!qCu zQIjX-o66IZ^|}p4Dr7j6u-DGF6`iKo?1>5(rg|w^Z@Cs2$y;Q`?zW-J*c|0&ES}qD zEMDO(iF8W?j2&JMWf|d6POExJ-*NY*KPT$`yR+JztcHvBF6RBZx<`1UHj_=%0UOEo!tx(`7qewh-{cPF}ORr8=#)k5c<D*y!G;uGM#Z-f1O_V*zY!XNNRDtYM{5aT6JcyL#t;a z=$63jU8nZPpM1&1ASn|iX1CQo(IV6XMIOp$wnJ|%63s9-@Tiof3Hn|cDt!$#QOhRF zZ~@s;|K>M6iyHQfkl#YUy4*qKd_Zg}W~5t2#~)=3YPghTN&RX>Dxcw7KwCEs5swt#jYSV zYfuQgf!d{Zlk-3xxM=e!gp2`+6$=4n`e2SFHEGK%qA0bD0tBD*(P!zZpGg#;F~tz( znbb77Jbb)>btw)r2DAbGFlNGW=0NTVApDbaDMn+&wWaQwv#*Q7b!K=1S|AMLmIyg5 z17eUqnG{0&>f^ZbiWNDd9CssG90Ee5B#vf4)}aMSyP&Q4g4OWFsG!UDSutBlSn#un zOKee))RZJM7m(whD%;Hli#?4%^V3Oc_SVsO#wv?!xMWxqNa2NJg;>gJ!QM47!(JrI zzLWC8bfxV1;|#e*q+PXLWq)b~k!*0}ED?MZTJ-)X0j_e5V^&e-K(e=UqMvF(nOM+z zZV$T#GM?z9LQBLR;N^cl;%HnNu%aX4;{Ta+{**b!9kE@P>{WCsO;4Un?QyVlNFCR- zk6c5JQF>>>ju>5#>%=@4$S3N&Q7y3w6_KIb11a>t$ATTlAmyxWM~-T-$0?-%`GHaP z4Jxwtao^bN0$H+(q*TFCD>7JgS^%Xwc;D!MWJ+1`7B1+Cw0csk_ityvcL9#!eC^dK z2XC0A#DY`b7?dRdJfpQd@ZdG|kPoU7sEHnGYNW}QvAlGbf#vfgO;(K)!0ijh#LCyN zAB88SknG4(W;P775x`X)6&R=qU0f^PPnW3h znz|qwB+amzU>XFL35mPH!lJwwGmv=SrvS9mef+`Lrr)p!p$f=-SV1N2w(vM+$-DX> zb-;22%7$<=c4Q!*h+t*N&0>Lr1EM7n{~h0M2`P|o@K1<2RV6g_YDWvyxsG{@+5jSd zel`gys8*{AqM=Mlz$?%hP(r1KAQW{F9~>_{lG_)%*tmVEb$Hc_ET}?l^JX)R3&wDPc{mPGm2Xc20#rJ4mR~lAwgnIVd}RHqXzW zOXt0jOOJbJ8wCQ1_GXX znddTrR|fGjJ;1TZ%j6%y#Uq~faWWKwx#xti;wUq9?aXY3in^7>1UT-ALlsKHsqL(w zcF@p~OP6Rwh00aN6LFweK@%j^s~*KHx7~ZDh32eyM^_RhsA7#(d>(4PVDUSVn>P-# zyi1bFtZ1hR@^nC;Sb7wwurbJyqejzsB*c_hG;THmiG)^BIcnlv#flOuk*t|Dxi(>z zuc4>x4|CObOs`@_hhRs4yZOqm;-9hR*n1IBIIn2YTr}F^n;vjUcfGC&Z@lohJmiSu ze_hUREH9~7r<^;ZRjyvzXqlFyCI9$omQtkOdGjKjC+tJAAV@wwi52-VB1Q}+LUhPI zy-1glAI1{bu58a4=v_Ru$+>!Pue5M?=}MjA#7L^F1KXp-^nWt(y%R|$aiDkPS--qU zl?hAb3Hq+C;Y-8K1RG8#&ON&|p$9Qv%S%uYK9LmOfxtX6z^(!Nw^fZNraTSyNa1J? z{jk_?F-X?(pG5dt3Md;rkmm(i11o}n%*4t{;n zgtC~)ztW&YJ?0hlaG%tWOp9&-3ofQUxPJ3U`#oFB)pP#snVHgoh4yt+l$pX~o8jY{ zSawuyj4d^CB7DCyctja(RzNSlLKl1%hAp~c7myQxExFnvNNv!AZ1{5a;A=hK17|7~ zVxBCiFP|EyT`e*bJodv#{oM28Kbu+KxV#x)oJEIQO&oL6dl68QN}I~2UjIiI>s`0J zX=B6Gnt}T_wmpAp^O|J?drS4g!qxi8qP2PbU&)+~j`cIZKHwm5*ux99zU5y1pt1AaD?BCL@ zJ*=kruODpB+^6=xa(NE^7e};peQLKGxZe}4(rxq(DWB1=Uys=JBOhBR6;(0<%N_}N zL51G{Ah3g7U*Bo1^hi-a5L8DnFRtPPkh4JE-@3Mj1Za`c;e!pu(v}seZ5I|aBf@I( zR{CoWZR$n&<1HCjj7U#lNKSSLcJeG~mligqitk8cCi@-9z+;o(Cni6pbmRF2z+M;BE(sW89x|VRb^FRyT+nF4n8M(LJSCUXZL0T1r6bNI;$Hc zBJw!lfaRWfD;GD{G17q%s6j>qlwdj$1q1sMCcBMJJRsUa=0r{D;w0k1Nn}YJ}D+<1g|h6x~qsJbYVv zgVf$VC*~CNyry6Hw=hzhFtO7=FaH8hw&J;W>F?)Y7*<>tdA7%a5wOPWXO^cAx@VxMBrwAi

biiVImyUqjVR!s*97O(f2T*lHOwi%BMb!}A%ydPIAT*<|K|=z4G$Bl>R+ibs zU!<>w@O}!x|L4o%Cp>|mvqH>ud+Fo3*7za42Fu)c5mlfmcLenesIG?9nL*mr?oDy_ zTyp-9ULv#GkmIpt<-Xc!SRk{WwqJriD!SSKY7>jrOfeGIKelfrT&yYPLjkHKb{N7R zbRr&s#~;+8`@HYj3Pwt&!=zMsX?wc}l0AI&r@}#YH@TPBPo{GoKU|yUko&1EHkGF4 z+m*7GNvd`9t|B6-s-fESt+nVItE(+Tkki5d!U35g9?%P*Ghd2F97XLI+yR!gF zYo)Q@5n_xd&woCqKC^!v_8jRPsbG`|p|S%bDwGA;YO%tM@lMa>lD490|rScJH|ua`(VjqRqFO zo0H#EgKsr!Ck~N6H{RruiX@dzf9sTN7H^jD7k^$OWu&lf#09hnwB6c0bEQ2n?6C6| zl{xV@*5hhGI(_w!my{UXnxaO;cjlzxG7sHaBVpIN48;11qnipsTp6#HZL|Nsbey@_S6x{#Skt?bqSL)}E^EwCazsG!>)b%*k{N zwslJ%^Q-bX97i)z>j)a2j0dH7 zT|9NiF&B)C;6Xa-u!5i`J2BRyI){+oKOfCD%u{I>)+~<~ihezhyb?O|KLb1aO6wpS z182M^wZ^q=CdjZqIiy>p0S3S@x}}38T0zTGqSBo1Uo@`IqJSpC@0w`5q$-Qn%L^*w zyM#s%s6_QtZtgcB=T=MIT1rm1V82lf-3kmkWg)*QmI@jhwd-VPvohF<6#XU@REB4} z05KcHaFfn>2d*&4e?yZ39%s_^tyvU7z*MP_g!4v#L6A(4PLPVRpiiCY9F84f{)Sx@+FR2H`XY_Q~va(MYZTjTp;m~(@nNFx%VI5S$cvELi z2p3gvUK?s(dQj)g$6cM;&aPXQEv4G@){i+KTL$e%YZTp8tPOE;VTcAjNRZM_7t{eE z_r>?g_stXw-Ha2rTw)Msl}C1MbKTR>kcAv1Rc(yl0IkK_o8eemJy-6;JE;_2Sz+s# zQ=2<1-E#ZhI?nJt(@CwF7A2>}rzP0MZB{#}2c9~z5bLFhZF-^rE_{^mg}~|^uFun( zDC75Bg<|RsT}waON+fqmjqK5nJrI=;vB@foLYTic=8 zlqWXj^S!c=U`4IIs5_v8=v#g8=gF$taxRB97bqMSStNqJHW|a(Mmly*C=dTO$afhv;o~S| z@g0Sas{JrhC#b=|8LIR*PEQeNyEu_SQ>AH=Dcuh8&l&5~sZO=4?K=T_~4&I6{tskWyqaXRz(NK_z zDoiZc5%K`RvkHi_kdNgYeJZH0nBOrH#3;`Kqn~`)PYYt?QibUqaNNUL4N_5aHbjzg zwblgW-1ppnzb{I@-S4-mgct*JZZkxFYy1o&uR@6P0C&<~w@An%=Vqu%oeser|M%un z*m?gcE;7L>pJS&qay4m$Jd%xns(*riihmLo8zB|x%}T#rZZ?GgmRDpxw96i`oL{0m z4Aps3@x_qGo`D>UJTF0dxqM_T@@|j@2O*E0hhZU?)pU^5h9}>RU@B+*pbkVE(9Lk< zsvl8GH3w8^dS7;*cHf5au>Y4Y^q)G!SYZ5je?U-IAVg%Se_=P@}Oa`2V&M zX*sBlZM9z)MqYg)h?8Qz!f3kp&j0TH4y^Il|M_JIVp;hCQC9vR7Hkj;$hyB+F2?`f zwEpI{$3Df$@;`RD#QWC!hWnPkwf^l84|2Q@l*?WhD0!LxNnUT>^|4SYL6EP_yF5U4Xh=0cb-2@hiE|Y zC3J&xg?k=)NqzBWO{WK^0o}RmYIt{QOj|pR6)T;R*{M-9Fh%{$oG~&f<3Fs0nXv(D zo`6W-H9>`%CwjHO&J&a-*a2zxh{tn$b`8Hxy+saJ$ zZ1x)!51Orb7GQ@BG*wLtv^nGRd9_oDUc{9XKH#yp$WNH33NG$4ewV!_GEc@wA|hz>fucZ_gwI*0c00if`(Js zXV%m7{VN-z&P-<$%gBNze_}S}ZQJxd$_J9rvT1Mo9IM3Mfn#|(5&E)>6*JZ>nCuym z1Bi0wbSD$ZG|tl;?W|Gmw*eGr?ZD;F+^NQTfD_@x6{0nkWYijrS~Q&6^d80j1)_#_ z^-Go6G*r0M8J~WJr&J`3yvv74yctKzT!uWdJi0upJSOJi+87n-N$+iKT)@@TBs1&N zAoATcqlroAP7u)*{|}?4;*Q=oacmss8tVG$JLEqxb{(zPt+CT4^C>}JbmiBcY;Qg` z_hkNP)gIYf=`A9ap!OoZhF$6zsLXWhL!1%zEPSc4Z!CE?U7GaCtd6P^ilNRSDsJ$o zx3IPSgasZWIOMoY(#HNd*|Mj(vL6v&$T;p(=yw~rghnyo=4KM#KjJYU4_0B$2 zr03IlC5NNdyMkTPB%WDP3~#?KMo@kh3g~(H@WU#Guu9vvu9RqlVKwOAvOor}jE9+( z6YLtdwY6#&%jb|AseP3}i!cYcT`Yf+H{0jX8<~BLL5I*?xIXN6k~gL2q#KKU=0Std zKDYqvchWbN=d>G#ec{1?&=0uZ)Py926oh1iRD`62l!WAj)Hx(M6ggx$R5_$MlzKFJ z40@z`pvX3V3= zBh6#%D|$4%)t_TsEU4i~ecXC#6W8jw8SM>XZOvIap)0xf9c-x;6tY3{a9yqBCzBrY zX3V*;sm)J^lG3Fi91`p~jNdjK(F~(?L|~rU5O3#Rw!8P4)Y{@_wooT=3OaTlTICIA zL0}BABO6~mH-~L>M^N9@5`nS01J~-Za3q*GeFXxqP4wBUCJ6O z{5f;7N^eQo?epS(+S1n#zDCeWtll;P`OW`Ow|A3*_N*kJw|@J%RaAyKST2(^o=2dSJ-|^LC$E(3eRNFuhGU3iTEi8F4;Xq$3hmX3*dW!Qcw*+ceMMW%UV0}X< z5)rX9S#}Ux4d*MGnFM0i4GkVzmtQACDaVe6cXz0339oI&M7 zc7%2iZVE_t>MbSos|`ZnwY3o5$k;7`4W1a{Q#98soUI5&5Qkmp0~UEXUs>O{wl^~6 zv%Qr0T&Ixi%zeg25y(p(PS$YB`@dJ$jjcGrFU%We#HCWXwl{(yui%F!fGQjc{hFr3 zV#qg!taDmfvJ*H_7#`%hc3;rZF@q;|U@U83Pd0Zwu zwa{1dU28aOoxqC8bNl+_&mR10u-`e5jcnv+Cgb^Jtu;3AFqk;IYU8Hk&g%|%2Xz;E zCw4b-M|oFrXLfgdhk2KBr*^k|$9dOs=XUpSSLR)fqO-rxByed0C?O{?;&L^Xot*O# zoHw)lJf_Zhy^gM9vF|`&0tGqj3)35@X#XgiTzIuMJf}GO>$=wn^h>3LbCchR4PFK0 z^3&Qhmp5ZFY*EBnZ!Pnn-dc)ALKLABo9z26hxqyaz_dv2R2S;}0v9wbY*S}fX+OjE zhVdsk3qbop$=4_Qm_I8mVGb7-S<|B6_YyeXGZ91&BC~Q>J+;X3viBCtSMhHvzSs)` zLJG1zMm8TN)fSefD2`Gbt1FG}T4G?Ar&`+Ds}@yxSi{m@MlG_@*v)k>-Wd*u(&hCs z!k(LsLDm;j>{*8SUyAsu^Po?-_3EZQZ$VQ&Or*cHP|rr>7nVbim}=09d(=4$Th4-w zh%^iGVT-@MNO*a2a%x|MKPGij&fw&H>F9ua2!W^?MJOuP&t`?dUwUQvh zi_6erH8)4E594R|`RPdEXkOcsKUgK%XTR@{S#d26qym})v4HA8E}%OQ87L2A@}hbm zMC`rMMPBPJ^g121b3tFL79Kg|gMk$5;^*6R8Dv;hCLTC=i=;m|gsZLtI9OT4uA%fk zs1=xG-S4wn%TPL{%zLMh3}eDQZY&Gl>7C1Xj!zP4$*I;W4p6$RKdD_P_2^oxhSg{l z3=GZiMPe9)X?};cPW1&tYpKTN;jgjG1m;%WCZ7+teuwC>tSC__t7s{BJu+DuVX?}# znLYo;_Pg@Nyk)K1YnY7Mhhb760Cxb8G3aidyVe^TXo-u7)t#DU@1fRzz`dVXZrss2 zyIc}qc8#Wh-(}OH<;B)?p1J`9rpUVXO4ddl{pxOpIRYU`2%1=7d^fFR( zl6FBOaOfy^->H{~Kx_{ZQYnMXppg(E+lp0AdkO%TMny8B5%?W+-iB3ICMhYyv1!Ud z>}#0<6OTR~psMKyMxPmV(l??)(N;D@zZ(BRi(l@+|Z!Ea3vsrv% zJw(i}k7^|)Isuz7FKR~+t`A9?wz$2u8;BuRh?y->S8ulS+?iNOwfUhp}$juH_?>Ht9gJe4OFP zWJP>=3McsSYRVDc$!D8b;5#F)<`iuj4ZgmG%bqXB(Wc&4thCtazcQ{pN(U*RTsF;-v_jO{SLyEqezt^iuMe8& zKIc0+yiph5LLr}8;Yr*mYTGHAu?f%fRT+}O*ZxNo!=$&%jR_oS^(~+D6`saA-@LW5 zT;`z!!zU?XhP;w0Om!!-vy%W-e_4NBe-VFWe`$Yhe{p|xe|dj>|F8Z^{!;#0{$l=W z{&N0${@?sn{AK)g{3ZM~{1t@s|LD(NxHa2&^;}CQTPl<_VK3HrxeLg!F>ALgs8*j% z$3ArKM|)erx)33##H#(hm6KZKXnK zkxzq*%3f;aT0PV2F=O3T(U)FGdc0M0!S;1(;6qRXJZ1!oULfBTF^G*eZE}6x&_bxk zjj5~Gi7UN!SR}KdUinO$=sLXhJNBAmDJut7(e)P#vH?>-SttHCg@N5>W_fj!+gfn% zpP@6syf6fVd2k`GB)aW08yO0NyDK&@_nat#T5y7AB4dk#1qrv?UeAS=h7BoznW>lI zm5#@5FJBEfVWWc~%08v%_GAczF%K&6{A;89QM>Y6>2jyta(44{*uc)ZAiSo6QM!Ur z-=Z0gq=--DF!<$>NNN=!mCxcxp|X&=x>o~=MRV(RVFqGWh;5)>@MydpsI(5xn_xo` zu(wAbcS~Pky`4E=c=pgE?{PhopZ!W@40K`Ngl$xr`#=sf0ipv{fb2jQAOcVZNbkk< zV0wh@g6ElM1Yk=mIDCtu=x3&F0k`O9{VLlIh%CkH|5JJ%(u=FV>pf3K*QW3e2fHm!&$~HKF?wDa_tKT7*dO*IU zms0r3;1MF;PYv$SS4O|9e$JLR-}BT8yKt^%iCvs*ag%uPgei7*183RjfEiBu`ld znEm5x)-}h+r(4C-%%}pAo7nRRyc=6ZDnj`5p$0#3yYgxt{}u5ieTG2q zE37|+X-AnY)2WvJ>Ww<65C6=%EC?btiQwYxr?CsW%sr`B8gLAHcsMNC~6 zc_vH!8Y(B4SLvWL^8nM!-KX=5mXmrQoco_1L7T4kYeL+YR%Tw#YND2l-^p4Yt?T!r zsMnr;K}t4T)i!kKXXvd+9ltB|QE)=8*MP*$!iBcS{K`&s{K~9|cUu*fdEULzlIgYY z`qJU4+l3+ee@<~vnR?#wfjU5bpbroRC;_AfS^%+u8bEHK2dJ-%yqKBx0crDm1gO!1 z`l7dVrP_s}Magd$*-3}`eD*S*fpU%%Yr`M4eG$8Wq=#m2f|K_-b%9sY-Ri7k8U}`i z-f#}4mT6w@%vro*aM8< z*QCje_vDYn55?WlZspVf1BQ81rZs`k+~`;b766 zd9?J5{fr4Le9Nk*k%lvS_g}<7jR#2rlbe1o>TKWCH_*&W;Z|{3T|^gQP4zp3hU#qC zCxzcekZa7AT|7g#hAztA62ui;fAQHFKZg8Jj?Kl{v$mu)J6=+Dt;F46cFy3-;!2w} zRyUPm^E2f0Anv6u+QHOXyB9zp8(e+X(@$!es_Rv*0DJoIQ1}#eDO1-?=A)+1tAcbW zB*xs`=p8x-t*gq^EkYiO(m*96%~_}>nS<^%e^FI!yOXI>Xs`csRinVkxUQse6vL6N zXz)qeM)9JYplaoiFFZv_3fG{HayvPhzDR^zG~1e5>qvo^*fE7MtugDRrXMzflyvme z##F?ZXJq4^GGL607e3g3sMSGVM|djGTrUddY3WQ4CA3U{A)d;P=*?wUni@k)gEkq0 z3`QI|l7N7h!a4PYG;E%sOJ!GgXR4HnMJ0-dz5zO7^OE_D-Jd-NiT)8a5JPqz^^ZQ3v3ldk&BPrpWoSV({NJo-sRg~g%cw;a*MtjTO zwxO%*5$CRt_eLbHqDSV!Ion5VO(uf{94cSqjp@RnI9k@Me_!I%HDy&Ut}p%wno~+} z`Qz%IwL24wAh93|^)<4B1Z!^TVBv8l7Qok4!xKak?_QGdQok12Tsi~o^>{Wv2Jk|WLP^TL9{N7>jI zH)DTG*pwCGVpSSUGNOutU}=4e?qk92#Mf2wUlb$S)8cxsiF=bH>Ax2BTK>K?*SGku zVhd3$W#Ix3E>d&uHI+|F`^wBZ6^R_Yg)Jkt{^GF1)1{t-L_GEYxA$F5*c{CD6@@%> zk+yH#V(p2RjFO4fP#u9QSZN;j9fKEu{{1Xa<;keXuWZS#I3Wj0QO6(ltoz!9EhJKn zSV!R6I=U0{r`_4wHhVNPtH1ygQrFx*A!DIpW~` z1mb81qeN}KCYmyiLp8U0rWMU%>gQ?D<|@!*iExWv0~Swv54{+ux}}@3D5O?`b-&m| zrSZQAj9vi#OH?|J`5&T@Q11T`r74j&=H;hf;we<43A>HPyCIR+_8NBzx3BkaMg#^x zc@xm}`LB^#eSft-Y4FFtdfMxXW|O*w>eL1D!tiRr!fS6Gm}GR zRhYA7=m-U`Zx5iX?=ZYc{@ZN3SRsd#|I7M)U>yKZ{o9i$4!&=pdYOWD#riKTwUaMf zwvmgcYM|~D89MhZVHwnYKq!q6;eWkRa{9Yl|JT0+$)b0vp(%Wip^KtpgYT9x)+voX z?&oj~gD&C4X{XwB_k6b|% zvu2x>*{-I#?P!#h@sMfF>ghLD@9|(Qo>)Ks1kUMA+Yfg73h-~Q)cxES1cFN+o@WI3 z_9Dk@@Lt$dSJP=a7L$MPcB_Yjf`9P5T}j9QUon4S)_NUawqf^bXf5T#jvZr2Of@@1 zr8eTW(yH;t4P{L*4#8pLH7=2^6omh{A4({(owx*M1f^)n#ALCnbt7`h!+Q%F9F~^X zU~&{pC>3*{U1Pp87y#{%s^3hR?b!e(31j36qPfumm|lE$6)#}DukZy!zG!Mv-t+N} zp|mG(4`HculGB7sX$D@xhm+5quMbIYPb8{UEg`A3S`|a+wa6A&o9ZOKf0}1XC2!4w z1z}%pO}`KhxP5YUAd+EA(+cM3c)`kp!X5g#wIcS3{*zFY&qEMSJ1mbP;qXf(zDdQl zX-A7hlHb)nc0&Q!C)fUBZ?M{0e*XP=aRzED9gphYAy=kR(F=`5s%xoeM2cBjZ_Hns z;XR99K$R&EQwXH3Ofs(vs5Z?iu$47tUtV5WyueNcsAloOY44PRn&0r1q zW2I0L>={|Z&UN_fBe8kEHj+66&x$T8j_7wV=4O-wk{j=r*Y>7hOZN+RwTmaad;hqv zl#;o}wx})2CVj^aH>1!Pm7#Y(_%ZfAypS^Rim2r{FM19Kg`<)W28AA)4U~%4sIImf z^@ID7nQ56a>&8e2GodP1syIY9biWN7PAFHhSx4bw9FNRlDDKz2uSaW;)rspz36yc2 zbz!z3>5d(J3*rm7hST$L$EQHTf{j(asQ={8#IZF{gK<{*s9+ODRx-=H`+it;-e<8q zuCfG$c(<}Le!~IcS=_BVCjzPhW_Mt=B8krr9M(Ns>H_l zTDx8z4e_6ZgE&Z%`+jhKadrO2NGIvxNW9{BtYkT@SWE@DeC2|+i%j8qy!0{KNTw}_ zxw+%-!;M@r)ej_A#T3_(EwlSJDc!+l(?Dx9t+8OgPz@!!p;s#%-O@gz-3FxbHCs6F zmqe#^_Y^`_0LlKjOMZ)e`hgWqO8}s;E}<1r@`oR5LdqX+&@C*lE_t?c#-KI!?mM{} z=TGn;|1E~aO;reK_HN(kEioA9(f%WuY)U5vh@VNS2&KH7-M5Lfk(dnJ6xVT-xW&xu-b+DWz;eJ7Oaf?mO);U^w*h1;Ql+Hn^t$7Y7>A*@j%thB z+zDL4n9YRH>2|VkgiaR`KC}~aedD$GD%J*8`lC_kj0s~k> zS%;WlGJX?-`c18L#KQj9;2qG&bHx3IC## z9COmr?bK5uM&dXLUqF2#A4BG&8C$eFjp_^QdKo(%~Bme?g& zNqhwsSGb5tE6^z${uRt5LtpM7aG)XPYA)ie=V{01_kZ7zeO!Fh$~M=N_A-bCax*p^ z%zHbw|G4U$I5pXjz~p{$kEvYed~dphM;3UPux||d(GC$8f$s@E!C6JM`Zk+L&vUax z*#QTW8?zlm9f#)$-Z8B)ZKqGuhHIK%9#lrOKKxnW%69Ko`v^(E`@X+u6iI-z<9qZl zp66Vtvin0eIENEiGs2g)G~|+i zLeho0G7L!oGkLgJ(IZx77m7e&2UP$^IGrl-fo+MZ0&x$KC)O6kS*ifHU5v0ypJbnOpOnpB<@BCvmUU3`nA)aTyEVJW zau~#&Mpkqc7rCb0c=+40d&QR)+;ZzCmdzx!O%wZ;iY;sQ_aW;jS)D`Tg}eoWg8a^z$z|wRXZM%fEF{yWpn5%B;16)4SB3`E_5|JtP}T%$}6n44QCL^ z$A3uvJC1*+(QZBIQYqK;1^S@UPFT0)_}kw~Ha~;*!~BN@8Kb;apmKv@D#&!%Jwe9~ zuWjS*!>C29wC0usXb40BDguo_%Y<_(HBW)O+#$4{jo2Y`e?qCfDB79@fxzHAiXv#yEcEne;4*E8fPuK+^#}iRlFC;RP@+v zxZFjY#*pgL@TSzev`j7dx-GwOfDj7?I5igl?c;@~mr zgBT4{MC?Ep<4q7a!jGRAv*(+Y{9;BuYvatfS@}4;yLhZ zB0oa}Z3V=H)P&@O^n?`h1LbVNPHB!}C*YsWg21^Npb+0F==WA{p=^y2aJHn>`_bqA z-s~R0y796HJ8g%uU8x9UES6mx8f8CjI%+z0ITD0|=ZRx9j1jrctqvr{pxF}uDabR0 zdZXzL1gwEWdn97s?EV6uF+srji-y%6%w`LGX7&GQ07rmhgd>FGMhzCey1)lxQ~CRF zsoYFDO8UJg!GLH-F!DdFH}5wH&n9(&(~4l^+pM?OHwd1nb%B5ZaB=UXHh7$4Ia4r$ z<1C1(ZeB;F=D_8j;O3GU%I$&7smuw?Da=V0|JapM9hmp8UH+*5*d;)u_qTKSwqSYt z(?K0jwoCsfkp77Nxaz3tm=h9yZ5YcjR^*Y2eyQ3rn)pb{Lkna5*zB@{&2!~cr=3dD(C<0PyooGmgm16 z`pa|TB80yTy@A&0@A7gn1lj%%i`?Dx9phcioyX&Pq{+%POEA9ZTa;x zWqkq|){u`J{HkG_O=Vs8vvC=nNjk-tFx#XXdztkvzBglSYJwJrlMA_DBrI$as3HlE z#dp&{mE*|n4@lGJxM89G+dXBp@-=qkqlwOo`@}b4guK$! zRyAb{p@+`Y8hsWxb#s<Q?Jngm<1RU~qBi^^ers*d z%4p5iF&UD#9@m0=DS3d|65o|Tm-%eH&n#Hyk-N7Bb4(@^q@jt-EK9c9Y4U~V$;U=c z#b~*84i3TD$(@?bVmdG2Hfv9_p2)7(r;0#4-QJls%d#dG|1(pANKRJ<==M)$vzJ6I zbIqqZSI`Z1Ijh8tb$Y$<%j5mYi#Z~{MGu0@-xuqPwKF;9vv`*4H5Q{cu@g<01Ynti zzq$G%5b1RK)B~Eb>i>MKl$c$Gw0NZU5KdLfqho2QU48!pp~wHF@-i9G?Kex5Ke~Kw z_3c}1J@N$KmwJ2x;*@IkD=-sTo7WAq6my$O{v38Pmll&%MUTnHCX1O%B3D2$)vW5t z2Tj$;2T-EAnoTL=rI%x7T6Ja;gHXHam+Ubad&-34P;mzw@y191&G+%?Iq7}BDN=wTQ=VHiCYvtU0PkFirx`r=gE1PK`>Omt7%x#PpcPG2=DQ7zlk#M9*G z@y|a$PngK46v$}Ve4nx6*vi;BNYgzYj(xxGU71t-xX)#>$@`Y)Q_QP^rwBeY;|m_E zw$sp6vZi#&&}x@4Su27LyBLvgUi8t&Q^LvlC|_G#^UIzk=EiP~sL>;|lK}03OwTBf zW6t!)C4T@LzM3G^$B|7~3N^oA{ODPa-nVapu4Hoy%MxjLDcr^UvM(>M>ct;s%UiM+ zZ`PXL!*R3v9*|$_lb~5j1OHxRkjh{_nPGnB2OK?bbNcx>ZoJyReLEi%gKggGur`#;kQq-G4_ z_1!+N@A2hoQ#;N=C8me=h<5$SWV& znEYFI_@58~nZQvIff#G+YMz*c&!LPc1L{S$@NweH3gl!$Y2uicN8W;E84gLPafn|J zRqm+3Ij|0`rb;qLtfGBsY=dB1@nXijI8NR;$PQerrodu!>rOcUc5DX;q?W$oOnX+U zO}8A@6>tX};zAg$Um$g2M$rZFIE7=vpLOv#^Aj!}vdw$t#0A(OV`eA3!0>oYigGh) zV!XaKozkwbOaa zXDiX+(*?^<|DO;kBI>`vDpBE!I6%cUa8z4PJbpnux&P>p`~P&*jT`J)O*xH@`c{hl z%iUffVY2hLC!+#$;}72dkFBqcifdWE#@&Ov!{F}jZb5^)OVFUf-Q9g4!F2+`B{+iy z_kj>BH~|9Wo7{Wf@7=f7$KsFEJypA^ckiw<(`%-W2Jbc_9VJQl$nyRSqQib-Qq-c( zzXqwFG7?^*AQ!}ug!n(;?qi%NvtuM=Ox4*0)!bKQO^CEBPJA_#Ng2<7F<6Mf=h;*I zXCcNaMwec)KWO}-Ew0*o16%@Oo$G5<&?*Uew=2E3Iw|S(LVu2{xBn&mt70yZ^799T z7uNO}p~)|pyRy${Js&T4V58wmj<=a_*ZaRX;cO>kn*m-%u<|JEn?iVE^rKFyxdwVutaPIBNje zG1+9kKgnK$cNqcK)9GtR10+oM02p^Zc0O@Fem+SxMm2$+;~Q$_&e`&_Mun<;&T%sO zpgemW{#%8?wc7PDm#Y4S#zwS*0rW%&d!d;WcEdXAKLU$#N==2gP9YXtsM&l zM(}_XhGlK_5JI$#;YrL94ty+KS$IB7L-%aErf#1~Qc_PadJ{m>Jz~>aoD3OI1R_N$ zB~w{%9yXF<75>uaXtL)){Sn`F5lI+}gLXR9(zco;X&8;N_o~@8oS^-D;6xiZ!~c&mrQ{7YdQ~6WNQ_a)or>ZB= zQ`%GBQ__?6k-T3%#WG-@FQ4un$0-T8VE@5>V$;P!xDQ%r5{vm`dWj+`qaAfero~c*_muP%tH#+I(MD9Z3aDa2iyX9 z><}wVs()AX%VZSA{uFqIfBtIq>N~pVL=oR0u#B?~BN3zBRj|#SWF~Gs@4< zS^SMCr_EmW>91}+p~9km-tEPNUjsVrH4Q~2XScf)&41SwH<;NMB__z1u`G{GeK8-P zT$Vch9a9)W>v`MJE@0R2p`Dv|g|;=>M_?5+J&E)cTR~Sq_}1lM{u?3+}~p8{9eL28Ur%1ye%%jT~$HraG7+#h_Lxmpg3oNhl6mB!;{ zsGE&^FEIAf7#;3u@00ItPm&y$oa`Ixn?G=Fl>NCe@>u=VnpT$;S^JHd_|T2I_2A;R z-YUCBENSq)fMr4?WM+)3=}_SlDbr^GQBsh|8l{maaZUwC$Ibaw<7v#u9j0o*5C%7+ zm`I0Myb{sxQT+y?t)$nJz5TcX5b63-(*?_xC zwz8kx-MMR8*UyGPjH~OjfRc3H8qFi~@dE^0rS76@TPcftKrgiZmhHjCcPoI_z`(Pp zoTbMDKpQgg8ZKgy20R|Td0dz#X87UWK(+5JSPfxo7DfsB6GI*B(8h&1*qu{*5_Za< zqJe=IX?*COw)6tV8C;6VR|bQWA)So0^%WFi7?C|D1D|W>;Xy_w!3q}~oyH<*n? zL`{t!x!j?{{jDLMdN~_GY#lJ2>guz6vZ8Zzf`{qGu|pFKbbhCX{V=nzlAXeWeHqr4 z85yE(!U| zZ@+(KCjNzhzpm;ye(&mrgd@e?gfF|q&-vvIo116&VIDHnx0Yi-+FP7ZTzKF{bx{}l znOAZkU$F@{fkWyd=vsOm!wuT{flI#r`e+=bmj&e3`YDj+acY`4GMU41UiaA^j6RrxFsm=R&g@h zs-7%0EbCp{CQf}Zxk>hmX1_@?WPtYf*st{Gv6p=qPio;9V__u3?)!c{B9lghLsm@uch+)QbM2a;#9RpB<;W;m-I$ zt^%61a)&buTHmLqG0>|Z65gA#f~<2787TOVk*ETMrG5{ym_*`4+Fnn%SWyyh%aahl z8$ZsfV~dx6zu)9UE5ac|pH=nPpRH`3Jt>VeL*x2UM`hL_Ffp|ZOe4$6Q{bBfU z!UaEs5n=)RG6?%rm>}7SS5k|heGeHCHVoZ1SzC{3>}>3*(G%&{V_`=AmN$wR(W%f6 zyXi%3egxyknB-~k@<74mu~QZbAAKUlQI62bE1n6TVFK+c4u!8el#;{rw5Mf8#{U8f zkKDkH83F%#)6b*jOo}1oYsr;IKPDy?3XCKrjJ~M_@7;kaoS0oAJY2tDrd?qF#ZvuX z2wYt7SvqwJ)p;q*6)ddHwCs}g_9yzWYw!uQ!vn_XXR5X0J8{%2ICLTA&a&}kPv+{)rUA6DpSw%r4a*On(c{~ZOMbYY-dwU5*WTj&S>ScTIrx^SWGAdQpI z6+)>+@!^$SBO+-N4{4}{2}7tuM{MWHAh#Tj?W!XM&Mi#&5zUBxG9bL;Vi4-l;qCv0 z@441iZLaEJ--5xak{n@HMcdE>{5*2vFI)8S$!g})u2BY+f~^WehehL~74Oq^4`h4nV5+p^fnP z%p$`4h|TAkf{QGpu`X!nyxGpY@(5$65av4D^UFhZIgunnU&b#~FB0dC!8z7*g!qss zI2>rX86gfY`UV~2AtaH+dMKRkjib4T4XKxnX`qYR=~&$lqvwdgiy{XnIHmQt!&5KZ zf;B-`=d(hU9>awnkBkd+VvyK74Ij*dP<9mbdnwZ$@@=C|W{d@tZKUM1$JZWj4fkP- zM>DfS<XHD{7r$nq?FeIcM*q-k!*Pl3@A_^T}mV>PjS^R#Q>~EUm28PE5zGM@&f+myyf4 zOJDT{KPMMMT;Iw`DDETS7Y4?Nl&su(U=chXFY?73e6gp`=`fts0M0K;D)EFgfCnWB zkz_oSDgA^^qg}N-MKcHz7!Q z-0X^2xwD53pw|m+)28eA&@)K-WOwu%Ub?0$LpNhz?>k;$_-BhL7Bg|C5{;|w+g_nP zV6g+djGzwnc5fmXY}-fg1>n+k-qHgnaxyzpkF`3}=Y3OV0x00+l_r+Q^5D{Wsw)_P zPM<#MF7A`rL)p{lRh00e2gavm3X97%G*y!8%~fwxFQY0=n1nF_^t$qFJLmM;hYV>d z$c#qQGFcRK=D&w;peavi6Zk)}^B^(++FcSWr&blwp-(D1^hnp4j8|2Orep;ej3}$H zvvL4Pg6b+wUNHgM*<^Hhx(${6X%uvH+EA3o6|a;hrnR9Co(v2T@fn$-5PD#?Jd1Fn z4Gkiawnn+)Tp=8hSNW>a$^KK%HGPw7TR>4LnW1vW45ah{eyuADcdq(W+!YGSD@TvM+3UR~f-YUZ0X zCV-bOZ|#3HEO^yL2k;_RR<1zzWTgiv>g^x7kB>4de>~w%*NNC|=GV~K3eU*=%mF1d zpsuno@}KKJ1}K20Q^vHeQ=dO3a6)+h^U%a)ZGh=(;xiYN4}zah6r=}TPhUMqtj4&jD(aO=~s-$XRR3ysQ$U$v1YL4)zBeD zjI6YI*PQMN14S6?$qb?|sWc&F0ANDDW{E_=1h|HpTYTaQ_`4o-l^IaWKltfmNu}5uB^}c6z<(D2Oju<{lyhKPPouWZQf}2}rHMoB^m(aM;9sgW z*-FcVijY($5a6SzbM@Lj4n2`zn=!9aOi9>KSWZ}1SWVbOSVmY!SVj1au!6AuDl$6& zbJ$E})5(tY|72UZr=(KE2}nvkp8a=CfMmUeOP?P;2QHr7ffDkAAg5gVW8*)^(2^?` zxzp#TqQ?lbGb>mgZ{ncG+5*&nKvCW7kOV*1_!6_)c+p;dr)!0fMzU_ScyH4+sops!z9jGSdT^n49IzqjfJ8R2pO&I^`72qS(E!V3j*RhF0>uIt3z71wgClSJK_} zMNJ*TD0(2EBWM1uS3%jxI{%m!kV24}S#@Eivi^&d!8XaUCZSRcfdQZnrRFYuRB7UE zawXq=`aJ%cs-w{VDE8xoc?|HQ)tq6#WI;5xP^Gy3aPXj5g~ z9r3n;ln$Pv4r!2b9`;A92v&gW&-=P%Zmr15ZY6(1DV=YZfdI^|p4|`Qf?zD`sKTI> zpkpN!csjs!KN^eW!#tB3n zg7m&k_w*~QWTRhE{Y$Zv(4*p&nsU+yMpY&>JSS?_rgVc76c)&g_!+6%4*Y=OEE-Ul0oWKZRB_ z3zbZ*On{_TTqK>{7pXH#OpcN!C5>sUcHifU(Z3)_x|eo4^?YpG#@zP(fz*M}0m1?O z0seu^fz^S|f#(6?fxrRQ0mnhkJWkgD0SCmq=;Ol9LGg|Gq+X|B)B7sFc#bYL1s{$( zm%7Jr*M+JML_d~1{<>|zaGHeZ@Kvr{|+q?sQYb&>YrK0+v* zltHraq1;b`Dm_2=8$ugld-daH@N0#3pt}So7#_nABOm{zSC@5HsbplZNFJYVuIoOF zktzFs3%BP9{j#(EBv#8YV`o*|d2c-eLp=0;ex~*Ks&Mpr3em+We2HWybkqxc(3u*0 zNRI7)Y8VQ;kzR6GIC;HaDdsgWnq+NwdR5;;GK0}O=7y-I#JI;hXD@rB`0lJ{DX4f6!7(oTnjc{a(}Zh3*m##WWm;Z|eh13gSAJ{AXV=!eGJJ zKbf3REhGz=j|czoK%>Y-g2F6TFn?J{_Nn#V0Ou3C46s|joh#zt&^S9&nU zj@%$vW?XGx@uG(LkOBGCN>?S;`4Y*oXIkIpcLCB7xNr)3|M}rs#e@3gZvJNwV)jLix#B({V>Yob1 z;-RFj+lH25a^Y_t*-Xk(V4+ybF=P11YaX160dma&_(B&qps@#8_0#VRY64_t(dO`K99^D`9e?Nh_RH*t zk*+sxkMkfM-}T#H^G{H|=}qj*Uzw~jr1PhUN~04l^xzy_x|t`ML13+v2ZTgCKg<9{T-%7gJu)7e6YZazh<@9BrM-m6!!53bJa6T3YYFadHM%Ev zNc()%)(}U6WKDmp$X?_QVHXn}n@gEX#BmRKuSKyp#l4SXKUE8M2A_b*zy)Aq@H$u& z+yxE<{{ka}y$@v%=?<+AUmdvbu?tZuABT07|V=z;7EHkeY4kp#}7K0brWunI{szFy_m13{a^Ika|Lg+gloR8^` zV(1G=a1u}VwsiE{A5535l;`i>+ecSblp@Lw>frSbTB|LXx87XCCp{r_UeaqxzJHRK( zeySn-nlVX~jiHbIPI_GCO`VCB2zh7ezQLzT!r$#nnXaK|Or~0&yBh0j7;Zf;eH8%P zofiS~Z69AV8c;Z#wBozjrD{KNkN=h7eSg}2I(^!6N!XIV z^4Y8=v0f7H+}!6#Kc2a<#`r<|5WGFIS?!}K#w_{v!?m}X`tMQyxe~@Z-|^7M>`=ndAysOp2*MOXH)18&JBRrT{1_=|xR)q+cJac16X& zops0%{=={T5W6x_F_wY^!aJ2XQ=!N>IU8txJI3sREpZXBSVr8OWtl5o4qj+A+0U~c z`3}UX58vT5C?PwE}5Vf z_|~iklK^ADcV^cE!zul5UZ^g>euK4%KwM*^KD~BI<(8}yDG*P|!kP*!uqDgb5`^~y zhl0pMJcY$L4@#|CBoUc-9E-7kTv$Dys~*MMF<@I(660J-vpws2q6<*D_Bc0K1xlSd zlsXY4C{k^67Ew_+9li_L}qVY66DgPtiZV;r!r>q#nH zR45Imw@+&w-)O3z`W0Y2F3L={KB4fwiptu8m8xMyMe}bq;eGy*>B@xHc-|j2rOs4L z|HY<<=OXYQHh=uZ=JmJ_G(jpUP|LiC5t-Exlyt7)uqYPLysV2Yv6aO}NI-Uih!>3! zR!dfIBUGAMP&Um{R#mp4A^%A8iLf=Rw`5BnO+>|57|LvK$=}lKhK9La*ZU*QRZOV) z^50}STR_Rg`-jX2{(nic;*T`Dpwg`QKWR=N|6#N1Uu;63E^_pXA2e@qOT03X>DX+= zS`zL8JU?*--fOYC9P|xUo)Ook$pG*w^tS=`1vnZlE_v zs~zXxf8$BW>*zo6>)@*%|c&yE+km+?7>c1ZA^09@>aH*GCgjF@8X^V?`(I{ac$%x%F)H z4{m>HlkSf;ZU55dwKS-u^tT%@RA+U^R>dVplQ`RbmE#@k3=;J)1+H@%U=hpS5oVUHeF@ z6L1%sDwk#YD--Ojp!vVp46d)QD`2qW`Kyw;9Q^-xLQWM5*_Z2*O|NCwk05k(3o~*x<;R^ZcIii0^aveX(2KgHA$o+&m*W2T_ z74YlhYv1BF>~+qZ;8~6?O=FLFfoD<8g0{2D`c+B&JMxOj%%wN)E2fu?6M|m_-M(dK zFY*zfw5}DPL|=3h+sW$>b3x}366)C{vCNN)!}h~q$)W!a&MPZ zHzPOw)@t56by%}!ur)TA`kimrKOrwvMc#SNuvfcT=YHyZN$K{%AU$wx2=MP}+K=)l zBW(EWQ~9Fs#q(Rhh5V<<%yHvrGSi{9q@{DOGH6&a*Z28n?-ZB&N=8HKi-HaFKF%ai zwae-dK0KCXwkCSra;|dYSe}=#oK2YLxo~NO*LMvYtXG&IcNA&Bhz1D_?R-e_;4C>a zF6gPol|+b-6tPXYn4SV(vXb%=78PM+q}`YC37C8=I_M*jw0x?$d}AB9C1SF)7JSvF z+@R7B-zbJveolHS{nFSc1sA4-}R2eL4Sn=d{Sgx@gW-=s|{wjfmWW|GdD{vl|@% z1PvfM2`*A-rd5yg?i*c^`xkdhE%7fHNk)M`TjHDvcxTTb>?dKn6oWZjOIt&9iVmb# zW{p_=TgzHUNsj7Dl70gc-+d*n`pFH{%7EMVq5a_6c#`*`pS+ z_Vtz1(cloQ6BpdCMhe2~AD31|rHa@GMOZDeL;_z`wSL(bVKw~VeHTnu#LoEdRL;}9 zm*BlY4zKO~g;K$5N@>mDUimG?|Jx(%oK&-qz!xdNjv#iFwSQ2P+Pd%mcI1)}21Zi$ z$wsz>hTeyUcC)N(m8LB^;Qm9CBb26@0THrNkx6EI#TuVGG%b60Lwm$J9ed6}Zvmx- z*6=75`x3$VRq8VERaAzWJ$oIvQY0{~vejS89=;#I1kM3cYBdh|(M!F|xba&awhb!)jcqKv>SYEKs+6Zu73 z)5;Mf@h6#&K6mg9y^$mQS3 z1X9(tUOcc>6jD?ytvX8;eVO^2m?3Y0FAsGVW%H{!N!|kglL?cuh%t=!((wZuHuAg? z8GvVLm1f5NXGFgY&zH% zUc~t}C_4uJs4fYg+sIDh~{upfl8n+?isv?HB zz$G;K{|MJ~Mae#+Xy%I8<$GOL+v@DqOz zQO_jQqj=`OTIouvY!wd$zY#Av*p(7-rjs8L3B(c4rIf)2#>@>J;ogMM72VE5XJ?3- zu&t~$h>_Yo$l}`j?yZS^&+uWZ7z&w)GlRQ;w=egrqTBR;=ki*s=yvBCx`?_;-`I2Z zdoKL@A$AH9Bj3^!Dam0G#;zUt+n7 zmS(g1?=m`NM-urT>4I%5TgSowDlTD7;K9SzL{DGbc5pG)FUA02netgV(9O_EJ=r0RS*rd^m5k!r>-8ZOMELe7O~*89sm{N;UTu`9 zEJzLLQ7kU)7MhyWcdTbt$;2B6>l7e-Qt=dIrHE8&Sk-2ilU>@dR#}wt!UQ{|eR*x* zeJQD+Se3Rp`YU@XvwCL%z7P8VDBdU!hZaRdm5{8)*keD}dL(>f5I)@|+fi7P$Hf*JfH~9{v5YwPEGrVt{;wJK% z;*Yb&+FSX`fWn=OoddSy2Rv0n58<2kS9ii1GK;n7e8(-2xNQ?>&b?>gg4IVm+}N7Y zYWY;9@)STDB0jyl41am@eaD5kuZKQl6Swcjw~LeLdrY#CRjv?Zr6)ApJ{hlj0_u=e zHv6G_3YN=jx{wgB`v;u9J6~}0rRbZzoRs^6f+0@qOK0a-E-SUZaV12T*ZD&;5%=vN zG=WnXnY}}Wr+gqSPM?}Wlcm81Lr7<=c?LehtJG}5foRjGbJ0&v?nPGKc{{`JW^`hJ zo-=soyd>)mli^LI{scYwX0naI<++n1%o~M(S3P-KGVZ|hEH{)_D}ObH9V7CNK`o0<}YBwo`3 zoy(^+W{s=5Uu`Q-VT|yb4d8 zZ8ZgG+kPy_3)(LC$n9@$L-9;>58T$tbEtTg`QV1^gg_R&am7Y(?(gkFkS8UJLvp+0EB)=HEDK-iEw~C|TTb&+Zh|=d1){L@0gx zD+FmAZKMm>LmU(L)c)(rD$poqQ0^tObkY{>0<01Jr5~Fu$qL!|)o9~H)9Uf15zr|# z#f;^(xcwb!ZOAy*Z+0Or6S@Ut=#OKri21jwdQQQ+61Vi#^t&gPhdiz1a*vrYNfj+I7)f- z?sb+cWqeYLD?^~b#GSjv>Rm>*>)eup9>{!P0(wLQ2(hEa{gIJ9=+4(zeY!N|P+ zbjiTFPPn8r-y$x{vQDW5N~mc$BY`H2p$l@QAM0@GlQOU5oXa_4^)||Ap{Qh8e>7UX6pM_lq1g_d&*-vWh1a9ab(`^!4JVA9Dl2v``7n8r&2S#&Nll;@Vm8&v1$FTRYJ*mahi4S@VRko|BW;MU715FKUCa)U>%E%3z1yz08TRsa*61{+Mw$~C<40HIsuPTdv z8Qm$=f#!xU3tAl~;+$p{?Ha=SMe4>&-4KpR!#=;6Ra2nmn)R~L;)J_RloDrmaITfI zD6JkZeL&%JN623ehZYkAq=0aYW5v>5+z*Y2uI@xA7&pu$Z8%|siBjlqW?l550J1i- zKTz7%QQC~rMO<>B2)`yv#c>@{p#Owz6|ztZaobrdgg1O}>`v06qKI(tn|erRNm7B( z|Mt?M7<2@r&vd_KOqhOuk7oEdre)fizki&dV_<+72`j0KcskM_?W1g-tC091lxruj zCbWlmrB0ypagWc_25Pabk64%zHhr8?%c<2mtq*J2FQ^Oqi@V7v$@5m;>28&k8sol( zWk&|XMZel4xGdi~84U%#w-T*G6iJ{~uc6m4iBu2jbf^dWbGYB`cH%2h-CV^Vr$m+= zE2vYeN$_007Z~a!@e!><5b9*y(CabHZ-6iuG9!(2w>NQ+r^lgb-Z_#OC+%d=emK%^ zmj!(cLqjKBYFX{twUtHd#K95kve@-7b$jjFgL$SxWP386FTp!srK8U9+HZHK({H1G9eWGaTQtR-mnd>JWNSL`2@&vI*G! z#_JLBIXy(auWEbN{mAbo@Dctw?M3c=Ro|@nk^7C`Bl2^`i~R4Z-?Q(JFamTObmfHDHwHn>Fn z*)rSKAh&2xP2>_qna_~JrV5{(_WcHit2}BwlgvrjT!6O&1qIYXKXW!7_YJNBE6ZFi zVAqS6PgCY3X*R&J&5VNdS9^RsiBV14D=(?tJ}%BZULm4J#s*NKw@=&=$=(1@IT;

e49?FC+#X`wMwSLpT_QQ4%04!5EcOA~!PWq3n-VCYo?v%PlUuA+5kR9Q!WnZ99WqvheT?##=IyW>JOV+QeFR-U%8*U-4j8MuMga@~6!Yw5hpCRPE_hUqvx9pB!)o4#!0 zx1S>Beok#a?u5qmdZGKl)=yVeCKU3yiv;5n2*a=AE+BeHpsgulD7dN28eU*y^Z)*e z_8C+?O&xVO$by2Xf{gD%e!r~uGIBaXl)S*+Y~8=#_>gPp&Il*-9jZx+V@m#b<8xK` zq1cPu5u9gjWue%$e&_FDzgVv|~ay5tZP*NiyZp=gwwS0k`P@bRw{ki)}uXLqEw zMz&>UW-X|!&8;P^-$P&^QV?p01q2781>u5tKu{n`5N3!2gcxE75rVvfAVB0G^bi{e zKICo7Sf%4F|JbZW)J_>}-OHMjO>G(bN+g~d{lgMAhWigHt~xB)&eMBXc$}l!qj01G z$0o8xi%Gs=h*V|c4LT`#)qtZ`1l>Za5)Q3HuJ&xIJ?Ryu)7T^*eMTe-X%!(~hg!sX zDUv}IO%|=(>@1@LGZ$tQ5Aa&10;YO+H0^?xi7WR0q53K-;OFCt3I2KjVJ7qw95q+-OOL3*$5Vibv9P%#4a zX_af{)Ere`+p3~RrCYXs82Tnc3eJWey11rNW+TOZ?9q{|z+1(xp6BX{uM)jho-DRJ z=djcUbZqS@k{PEqS={xcNV3x~&KIf94VM{*K9W~^M}%~`7{nK>AU9j zhvB69+CdQ++M%JX7ywFuI!IaTtI4`03{x#Npe1T`A8tx*hxcrP^n6c(+3f7~ZQp7T$e8tg+n9$Y>d%ln=AgZ`zi{3h)G&gz~P?Woz77@Mspz=vqXYQFerbQ58@5M zfT%&(ATAJchzUdt5(I&R$UtZzRuDXh4ul8d2|ms9r}y_ZtBYCG z#(uK~cMq-G#7it#ti)nJ$fyQ_vIH-EY*QXemo_d)O-@WBm3ogtI&w%(C@J2hfW^Oi}{v^tdq_6g;^NnpkFD+ye#qOk3I(BWMso zR9Y4_IiNOf77ngAjyyCC(sP)1W4k5&)K0eP^`ziD5T7HcO^bzOGeO3Mqw=yFpk7#C zpQ#dkUyc)l?kME9How2Rr0~(EkP~g(iw5&h(>PyheI1a6aVJm1K{W4y)ecnljt4Mj zCEm-^AaYdhiaDviI?8;l!-Dc4hp)3QLkb3h`0{+cwOCO6HSu-!pdHm9zA_Dd0$_Nm zpd1YW)W_RS^?H?WL5szoT^48WLTrz(P?6k`GA~*Cc{vv10S$|*n6EhdE?x)P&NzfZ z&?WPwl)@4K9~*H;5B_OS3DE)PbF97%(A6A_#X9j@$`Mpm+9$lE(hvaAWm%-PjAv6- z{#yB|$0Cpb2ogjA!U(a05JL1J0uWya7DNNW0da#+Ld+l%kPrwgL>fW^v4r4Sv$w#j zR)Ox~#hot?${~diQ>XizaxXmDZvXs|Id4>4R zgF17uhKlj(^vv*0#j(@8E)ui?oL?9-GGSK^_W|^34wV^68dF(;i6(0wh;nxi>by+Qq-z$|h zueG%8W!|ZN?ia7K4swdyUf=znw~4&TmM}dst`bjMXpTj7fr=8DJp|T67jnc{9wKDe zvGF3|NC;?2mFh3+sXN?|w-8i_G6Vo|gpfdtAi@xT2qHut!T_;_5J2=G{16`qCPW>= z4snH0Skt+S2bJr5b$co;IyWDIceph3vG_ohRJb#QeBYUmc<|M&t<5XwoGOYAd-1^N zT|v|*+ugH^i%TIa?X8ae7U$#SBD~$L_~2mUoaTm z>%6;HLxLhOqMO_8PPSYeTwJWOK||VG?6R^2$rJYCQTBF{Kn-5|lkHv{ISJmR5K;fk zy6J6a5Oh;TmqQpPB)9a6eA;Rs!mY2z!NmzC-}Q*Rd1){5kTWKOzWhj@c8GE$?h>;x zTuFqE3){@7*g;Oylj16f0NbM%ixO*=%nWrf1IfDC&9g?uh8m{P#X}8BT*omt=U{PR z=f2=FB&TjIfcC43omij_3_|6DxbtK)Se@5O?s&9tgLWvRb|{Jg=0d(gRw8(FejMa6 zbd^7&Ad%Fieki!XhlAr@kvF{_GC$Dg(IaDfy>|a3z)3Dh4z1?UjDc@>kAKr^ciC8R zmz59=;(YeW9C-A`5OLLt(O4>f`5Exp^PJ?IjEb0wl!}Cktc19Pw1lLD%$(Sq)SSee zY@2wSbem+GOp;iVRFXuJtdICx&4P7A6VkrM!ggz+lZmsKQ@8Vz6Wd8J)le6((e&hv z52jl-!tADc<(wt}FCG5A1TwYDijc_+nKAYyNJk|2LZX zyUZu~vBo%`zR2KdT!#U3uMOW*QWGpYWI}q=x>DJOA6!kd-{30>T*v#Wg{zp=8RClA zVwKJ-F}cbezx?2^m{Kjil}>Evod%I>#cgk>4W^ah!`GP^N5H!L+D3(*K#!3a4Ri52 zHxj|u*zD4U;72}zfPl&5U z$i9Xj-oHDfxvD7oL{5Bc0(71R!v>)ydEZrxJaNh(>{V0c$SPi}_lLIF-`eUM^#pDj znrwi2mpO5t4~~0ky_dAC_Z7^4H(d0z;?RcZBz-~J%Gp}#H_pB!f9yuvV_z3+`D&Nu z@mgJ8=Jf{a)?H{Vk4evXJNvy<<}a?a;}pe|Bot)hd4qbf?j_(+Pa;(X={8?2g#c z`EDu@^P7**e&JkNCkGbwVxOF;!i$x!{xii?gWKnm@BJu=>xjyZHOi;o6D@ZiSEkmB zHV|0XbtmTc0hIf1I+E3YMT3soY@ZyfZP~8QGD3Eim+G}8DE8K+gSdMpq!yY>Zz2o> z2h|jRdS))D3u){_PS45CPBzGSY+@1SDJq0MOZgLdE-io1K~z34qN$AEwB|VlDbDu-%=0FAtLw+SJwWbTg%NmMETXy1R-{MEAT>Ff z3(8IZ+yof-mxS0nJ1em_>B2b0Q9YAu`-e(jJmnDI&&KMesBMl082|!34$FZ`^9F( z#>7^{hQ$`ero=YH2F2#ZCdAgnM!LrWUrBboX8l>0a7WJm`=q!+1FMfSEXt>T*XM^2 zpHTOzz}{|k(}mqrAU=R-5=lJKdhmm7BjFKMq(CX1#644goHr6hAR$HI_0~{(^~F&P zb)1~EXQXpF-MXEHfv>l4kT1}Q=`3__G|y|c-O?d+uJ!S_7g)51yGvjsiiw?k=gJ*Q zWmSNMfpwmU1UzWJa45$<^G-;1Hx?-**>Y*6@FOPaN^o*!YgNF?dW=E=?s)ipWky7hVpu$PI{MQl;iiQl`y1ux zm!QsrrlqpoxhUKD{QM7CEI-J229BCrt5#CboTzvb$Dk!xyAuSUoMkihV zo?666wuKCXZn+^G=F!Cm-e2@434=|C0fH_DmNLTVNL|W2`iLJkM0JK#i6^p8 zNV!5fNJRn5z5UB9$l-z*w@?i(I=!S~+r5TEvmeVpBr23{4-XZuAaQB+?b0x$ZODV} zo^@BY0CUmnz(7|_gWEgia(Xx5jqfxmrR3TZ`Zri2k)!fK^-qwo1{TG*moI6sK5}Q* z!~r7Gua7_6dtY5U^;Y9f8p1WPfA^<%f3+6QSRecoi$wZIyJkPi6~eXLHT|{CHU72k zHQ%-Owbab8C@}Tc@`+LVOWbK9>)npOtphsb3Oo>2#;)+`)LS6mkF7t*y5N*=K~bM$ z3HL%tCI6z&#*5;O{wu-dG=)^YQq2>iELG>}dfkloyhTYpLpzKS@R8!LhaceQNb>C+ zDJduzj|lM2#`>vM`1pPewxbH?92$f$A0=PjlEGDH#B_y{XFgl-wX&r_5XLX<4So~D zJ!ay)GbWRss|JG*dPPW7vQWf`P)7Zp-qV2Eq=IC+6X=Vo4xF5IFO&IIVVlVjOn~mS zGy&J{9QtYBQMIY)*5nB~^NxH!=wSeX4dL(BM7d$WVkE9P&eG_?V8w~6e(1mS4?7?bDX zPwVF^Es;Ia3v*NbzFtPD3-8@s9zO3*T~eSv=p%<@ER0%cCi6Qk(cXP5OSdjK?0x7u zjiE+LwZCLO}C2olTQ$NxYCRhd}+B1Je`d z6Z;F~!s1-kd1j{6`yrBonp1A2MJ1BLSo(}F`X#J!;Jw&bk6)d*IxDV#$Z+{S&N7COyMTn3 zPG^R%+$F1;YCHa}fNp$~wIgRY{@YAXz~EQoco@fYo#6u&Ac{ddKI~Yk&TzF85anlI z7Hue{e!QVtGybjun>>tA8~)qMH-JGs7I_$sI{djh!*~z6Y+4xdH}M^YAMtla<+b7)DN?@qcUo=JW0L8|Js9Z$!ANxKU$3 z6j6QGCVX7tfn|$572N7~uPtL*-kBl*6lTjmzm`Jklt%grl2Zni)K!)`>dj@5K!1~? zk;?jhxct;t%$g1{KRg>Qi9*#t7M;(1PHm;@^q4X`gURzs+H-ho59@p91~R-VYJE@9 zFr#|{OLhd>?=o_Pizd%m?f8Sza3^7uSj&S_)1IOaozB+?b4F?Jj3q(3ih_c#a7uq` z)yfgj8kC2U>&LCltfv~36T-OwP(%r_RkYD?%;NJk>hbkrwc_C{3;|AF?#KZwUgA%< zW+=j0-aza!MK0bVMx4)UZr&IPXF#u)1~`F7BQ+ojQvXQ+9gM;kuJ7^b@?2q#Wd#jw zWnVsxAs4FQp?Ngw03HY`86-vF%$XnRt97nel~hBtzsrofE0ygVps+nWGx2af1i$_j zmHp(RJl@!^8q(WaaD&=qP|y}PC@XX~W!T(ue;zm*E!!g z&$+-k_c{ML@3|lq7Zo2B&x`@*Zvs-l@6~4hMHP(Q_q*>9aKm2 zZ~d}iSd+}+*XEx0GRySo#DyIXL#K#)L!22XH@-~u&fkI#o<3Hyq6A`8EDp4=p#INaf!vqV7`MXaj+EIT{i z3t}L%_Y!c)+_`n{#m`n^5z3t37&vN>c@ z>8sT|sL88GXO?qiANnHLQwl$0s%~)QjVbq>^_9j=MY*3u@r5FuhCcDD%zT!flh^6v zXboq!RI@?2Uk)bmC-5gJr(-PjdefH-Ki9s1Z|^OnF-7`>h1cbjO8IVe*9o4#q+Z>MId2Zc59dWJAQm?ygR{c>|91#jQpeHYT#(s;rBPX`FkRqfk;omLV;mF=i^ zEB#|3i+)q8&yzgm{WY)9Q*{M|HX?ep_^ri_S%|gugl2NN(2V={GA_HvHWSzP&iVym z9oq=fb5Kevo`gy?swqm7t_w;?6<3T1_j1#=9a7egz3m;Jw$0W=`WF!1q)dBzvLN)? zAV8B&T z+7$I&T1oy`VlFijweev`O{5y}Vd~z-=oZy+iw%>7c@86)iz-m*EtnJTH|0?+8{_SQ z4CbFZoq#@11_8WMjNiqiz3=-GiRNf1lQyJg+ONiuuA5Pa7ROi0a9Pj1R=1uyLZ7|m zUYxUZY=xS0<~Iu#)CZE~!0rwu}Box9*DjfZMZBGP=QAXy^$dA?J~x^Qn2Bw4B_T zN!1xtG{G!C?( zc{5BKODY6xyZg*pb+*oLU>d(ca{IE)DzHlXevnQyyz)L$ngHAG3viJqW@mD(tbjlh%(jAgN79ypZZ<~56l3i(dG_uV zq>1+9*>!ax6h^4-Hc4FW-?9V*TFPND2J*54$~hK#kjMz}K?bqXAI3r_C;3G$$jo{< zchadZzq*<5#_zzKb9`pvFk!%IpgFMS#31J#u8b2HJx9*&-zCukV(`PQ5y zIjc}fDSARR>chGtGtQ5MNS7XV-xx@?vq#8g*sdWDe0+8|IuM3%+Pv2;TbA-04Hj^) z1uNm)ODY>e0XDMe`^H@Qojn3J!zc}T_9lYiXh-e0TAK`Vc8JdS5gv%Io0QmlcMiRT zlDv}6y4UWfGZ(iAjq~1U+tWHr3Bpsdg?wswI*#e*3uX`I4(1Hz4dw{u3FZpsdtra! ze&KxKy=%H{yKT9>-H#k0>T7$`F-Y^;pl?(j?tOz6hL}FicDxT`G<~t)^_I2ZX8i z=pk`=`1Q_m$kF-H7M9JOr4KUa<2AHS%yot7UBwDQ2F%-EDvrNiO9wi>{OwqTbOfxq zuD_nB{f*e8Fm{5(w3W-fY6(?d^=}43`o$ z@MW0O9Jj|!e8kDBCp0w3qJz}aslC@*I2Km!bn5JSmd!)~VrBko^)*Mp$El*E>!RJ+Et zJ5iJV^AWqE9K)GaH%eP~g(R(NhZ<5OKdI;u{SfJNfM(U;(XB!;Lgf%0DJ}n5nj|bl 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 z%0A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 literal 0 HcmV?d00001 From 4040618ab2d20ee29631e7b2bdf7b0fa8e42f1a3 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Wed, 14 Dec 2022 05:09:35 +0800 Subject: [PATCH 7/8] hal: gd32a50x: fix pllmf calc error in hal Fix bug in hal. Signed-off-by: YuLong Yao --- gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c | 2 +- gd32a50x/standard_peripheral/source/gd32a50x_rcu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c b/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c index 9b0ad76..435329e 100644 --- a/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c +++ b/gd32a50x/cmsis/gd/gd32a50x/source/system_gd32a50x.c @@ -809,7 +809,7 @@ void SystemCoreClockUpdate(void) /* PLL multiplication factor */ pllmf = GET_BITS(RCU_CFG0, 18, 21); pllmf += ((RCU_CFG0 & RCU_CFG0_PLLMF_4) ? 15U : 0U); - pllmf += ((0xFU == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); + pllmf += ((RCU_CFG0_PLLMF == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); SystemCoreClock = ck_src * pllmf; diff --git a/gd32a50x/standard_peripheral/source/gd32a50x_rcu.c b/gd32a50x/standard_peripheral/source/gd32a50x_rcu.c index b4fa5be..0c3a242 100644 --- a/gd32a50x/standard_peripheral/source/gd32a50x_rcu.c +++ b/gd32a50x/standard_peripheral/source/gd32a50x_rcu.c @@ -938,7 +938,7 @@ uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) /* PLL multiplication factor */ pllmf = GET_BITS(RCU_CFG0, 18, 21); pllmf += ((RCU_CFG0 & RCU_CFG0_PLLMF_4) ? 15U : 0U); - pllmf += ((0xFU == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); + pllmf += ((RCU_CFG0_PLLMF == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); cksys_freq = ck_src * pllmf; break; /* IRC8M is selected as CK_SYS */ From afbf04e34ff1685fab38061b106dd437a92503d9 Mon Sep 17 00:00:00 2001 From: YuLong Yao Date: Mon, 9 Jan 2023 21:01:33 +0800 Subject: [PATCH 8/8] README.md: add pllmf and pack exception for gd32a50x - gd32a50x have pllmf calculate error, explain how to fix it. - gigadevice not upload pack to mdk website, explain how to storage pack - update arm library structure Signed-off-by: YuLong Yao --- README.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index aff0f54..3721f48 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,11 @@ Each ARM firmware library is organized in the following structure:    ├── cmsis    │   └── gd    │   └── gd32xxx -    └── standard_peripheral -    ├── include -    └── source +    ├── standard_peripheral +    │ ├── include +    │ └── source + └── support (optional) + └── GigaDevice.GD32xxx_DFP.1.0.0.pack (Only for packs not in [Keil MDK5 Software Packs](https://www.keil.com/dd2/pack/)) ``` ### RISC-V @@ -125,3 +127,19 @@ conflict resolution. See below list with the proposed solution: - i2c have different implement than current gd32 i2c driver. no need to patch upper i2c speed requirement. + +- gd32a50x + + - `SystemCoreClockUpdate` function contain an `pllmf` calculate error. + Fix by change `0xFU` to `RCU_CFG0_PLLMF`: + ``` diff + /* PLL multiplication factor */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf += ((RCU_CFG0 & RCU_CFG0_PLLMF_4) ? 15U : 0U); + - pllmf += ((0xFU == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); + + pllmf += ((RCU_CFG0_PLLMF == (RCU_CFG0 & RCU_CFG0_PLLMF)) ? 1U : 2U); + ``` + - For debug this board, `pyocd` need a pack file from Gigadevice, + But Gigadevice don't upload pack file to [keil packs repo](https://www.keil.com/dd2/pack/). + Fix: Storage pack as `gd32a50x/support/GigaDevice.GD32A50x_DFP.1.0.0.pack` + (Download from https://gd32mcu.com/cn/download/7?kw=GD32A5 -> GD32A50x AddOn)

+1dWsV@j1Ji`|*tlHGBv*$HbeG~o2UT?*$)p^# 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